日度归档:2023-02-20

Linux 端口转发

什么是端口转发?

准确来讲叫流量转发,因为流量是基于端口的,所以一般称为端口转发。

比如我有一台香港小鸡,去程回程仅对移动线路(CMI),电信联通均绕道日本NTT线路,我买了一台广州移动 NAT 机做中转,那么就是访问路径就是:本地电信 -> 广州移动IP:50001 -> 香港小鸡IP:49001,换言之,我本地电信访问广州移动IP:50001,就等于访问香港小鸡IP:49001。

为什么要转发?

有些小鸡,对你所在的运营商网络线路不太友好,造成晚高峰看 YouTube 卡顿,通过国内机房、数据中心中转,网速会有质的飞跃。比如电信CN2 GIA、联通9929、移动CMI等国际出口,都是极品线路,有关三大运营商国际出口线路的介绍,可点击这里。

其次,由于服务器上跑了web服务,443和80端口不能被某些不可描述的力量给和谐掉,故而可在本机另启一个端口,转发至本机的443上。

用什么转发?

推荐 iptables 或者 firewalld,都是内核级别的转发,性能损耗极少。
如果用 gost/brook 等第三方工具转发,流量大或者连接数过多的时候 cpu 和负载压力变大,对于 nat 小鸡特别不友好。

基于 firewalld 转发

CentOS 7 开始,系统默认防火墙工具为 firewalld,当然 Debian 也是可以安装 firewalld,firewalld 和 iptables 本质上都是用户空间中管理防火墙的工具,最终还是调用内核空间的 netfilter,firewalld 是没有“四表五链”的概念的。

以下为实验环境

服务器公网 IP私网 IP端口用途
广州移动1.1.1.1192.168.100.150001中转
香港小鸡2.2.2.2192.168.100.249001404

以下在 广州移动中转 NAT 机 上进行

安装 firewalld

# Debian 11
apt install firewalld -y

查看 firewalld 运行状态,显示绿色 active 说明服务运行正常

systemctl status firewalld

查看当前使用区域是否为 public

firewall-cmd --get-default-zone

开启内核转发

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.core.default_qdisc = fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control = bbr" >> /etc/sysctl.conf
sysctl -p

开启 public 区域中 ip 伪装,不开启 ip 伪装是不能设置端口转发的

firewall-cmd --zone=public --add-masquerade --permanent

将 广州移动 50001 端口 的流量转发至 香港小鸡 49001 上

firewall-cmd --zone=public --add-forward-port=port=50001:proto=tcp:toport=49001:toaddr=2.2.2.2 --permanent

允许 50001 端口被外部访问

firewall-cmd --zone=public --add-port=50001/tcp --permanent
firewall-cmd --zone=public --add-port=50001/udp --permanent

重载防火墙服务,使之生效

firewall-cmd --reload

以上 广州移动 NAT 中转机 就已经设置好了,如果你的 v2ray/trojan/ssr/web 服务均运行在 香港小鸡 443 端口上,接下来还要把 香港小鸡 49001 端口 流量转发至 本机 443 上,也就是本机内部的端口。

以下在 香港小鸡 上进行

firewall-cmd --zone=public --add-forward-port=port=49001:proto=tcp:toport=443 --permanent

同理,重载防火墙

firewall-cmd --reload

查询防火墙端口转发配置

firewall-cmd --zone=public --list-forward-ports

删除防火墙端口转发配置

firewall-cmd --zone=public --remove-forward-port=port=50001:proto=tcp:toport=49001:toaddr=2.2.2.2

基于 iptables 转发

iptables 是 CentOS 6 系统默认防火墙工具,CentOS 7 也可以使用,实验环境与上述一样。【注意:同一套环境,iptables 和 firewalld 二选一】

以下在 广州移动 上进行

开启内核转发

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

将 广州移动 50001 端口 的流量转发至 香港小鸡 49001 上

iptables -t nat -A PREROUTING -p tcp --dport 50001 -j DNAT --to-destination 2.2.2.2:49001
iptables -t nat -A POSTROUTING -p tcp -d 2.2.2.2 --dport 49001 -j SNAT --to-source 192.168.100.1

保存配置

iptables-save

下面设置 香港小鸡 内部端口转发,将 49001 端口流量转发至本机 443 上,在 香港小鸡 上进行

iptables -t nat -A PREROUTING -p tcp --dport 49001 -j REDIRECT --to-port 443

如果想删除本机端口转发,命令如下

iptables -t nat -D PREROUTING -p tcp --dport 49001 -j REDIRECT --to-port 443

查看 iptables 转发配置

iptables -t nat -nL --line

注意事项:

以上 广州移动 50001 端口 转发至 香港小鸡 49001 端口,是跨机房,没有专线联络的情况下进行的。如果同机房,不同机器的转发,命令需要用 内网 IP,比如

iptables -t nat -A PREROUTING -p tcp --dport 50001 -j DNAT --to-destination 192.168.100.2:49001
iptables -t nat -A POSTROUTING -p tcp -d 192.168.100.2 --dport 49001 -j SNAT --to-source 192.168.100.1

一些建议

个人不推荐什么一键脚本、面板什么的,虽然便捷,对小白很友好,但显得很冗余,小鸡配置都比较低,甚至有 1C + 387M + 10G HDD 的配置,跑个 CentOS 操作系统已经很不容易。当然如果是大盘鸡,当我没说XDD