本文介绍如何在 Linux 系统中开启内核转发, 并通过 iptables 实现多端口和单端口的端口转发。我们还将讨论在双网卡跳板机上配置端口转发的实例。
开启内核转发
首先, 您需要在系统中启用 IP 转发
vim /etc/sysctl.conf
# 在文件中添加或修改以下行
net.ipv4.ip_forward=1
# 保存并使修改生效
sysctl -p
端口转发
用户 –> 中转 IP –> 目标 IP
单端口转发
将中转服务器 (IP 2.2.2.2) 的特定端口 (如 4000) 转发至目标服务器 (IP 1.1.1.1) 的同一端口
# TCP 端口转发
iptables -t nat -A PREROUTING -p tcp --dport 4000 -j DNAT --to-destination 1.1.1.1:4000
# UDP 端口转发
iptables -t nat -A PREROUTING -p udp --dport 4000 -j DNAT --to-destination 1.1.1.1:4000
# 修改源地址为中转服务器 IP
iptables -t nat -A POSTROUTING -p tcp -d 1.1.1.1 --dport 4000 -j SNAT --to-source 2.2.2.2
iptables -t nat -A POSTROUTING -p udp -d 1.1.1.1 --dport 4000 -j SNAT --to-source 2.2.2.2
多端口转发
将中转服务器 (IP 2.2.2.2) 的 10000~30000
端口转发至目标服务器 (IP 1.1.1.1) 的 10000~30000
端口
# TCP 端口转发
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 10000:30000 -j DNAT --to-destination 1.1.1.1:10000-30000
# UDP 端口转发
iptables -t nat -A PREROUTING -p udp -m udp --dport 10000:30000 -j DNAT --to-destination 1.1.1.1:10000-30000
# 修改源地址为中转服务器 IP
iptables -t nat -A POSTROUTING -p tcp -m tcp -d 1.1.1.1 --dport 10000:30000 -j SNAT --to-source 2.2.2.2
iptables -t nat -A POSTROUTING -p udp -m udp -d 1.1.1.1 --dport 10000:30000 -j SNAT --to-source 2.2.2.2
按需要替换对应的 中转服务器IP 和 目标服务器IP
保存 iptables 配置
这部分未测试
查看规则
iptables --list-rule
导出和导入 iptables 配置
mkdir /etc/iptables
iptables-save > /etc/iptables.up.rules
iptables-restore < /etc/iptables.up.rules
由于这种方式并不是下次启动就会自动加载 iptables 规则
要确保在重启后自动加载 iptables 规则, 请执行以下步骤
# 编辑 /etc/rc.local
vim /etc/rc.local
# 在 exit 0 前加入下面代码
iptables-restore < /etc/iptables.up.rules
查看和删除 NAT 规则
查看 NAT 规则
iptables -t nat -vnL POSTROUTING
iptables -t nat -vnL PREROUTING
删除 NAT 规则
通过上面的查看规则命令, 查看规则后, 确定你要删除的规则的序号
根据规则序号删除特定规则 (例如删除第一个规则)
iptables -t nat -D POSTROUTING 1
iptables -t nat -D PREROUTING 1
双网卡跳板机上的端口转发
跳板机是双网卡, 有一个内网 IP 和一个公网 IP
内网 IP: 10.0.10.30
外网 IP: 58.68.255.123
内网机器: 10.0.30.88
, 可以和 10.0.10.30
通讯
内网机器 (10.0.30.88) 需要通过公网去连接 ssh, 由于这台内网设备没有公网 IP 所以需要跳板机通过 iptables 做端口转发
配置命令
最初的命令可能会因为缺少路由而无法生效
刚开始用的 Iptbales 做端口映射命令如下
iptables -t nat -A PREROUTING -p tcp -d 58.68.255.123 --dport 31688 -j DNAT --to-destination 10.0.30.88:22
iptables -t nat -A POSTROUTING -p tcp -d 10.0.30.88 --dport 22 -j SNAT --to-source 58.68.255.123
发现无法通过 58.68.255.123:31688
去 ssh 连接这台机器, 试了好几次都是如此, 开始想是不是因为双网卡原因
查看跳板机路由表后发现 58.68.255.123 并没有到内网 10.0.10.0 的路由, 大概就是这个原因了
iptables 把请求转发到内网 10.0.30.88 后, 10.0.30.88 跨网段了无法把包通过 58.68.255.123 转发回客户端 (就是连接这台机器的 ssh 客户端)
因为 10.0.30.88 无法回源, 必须通过 10.0.10.30 转发给 58.68.255.123 再转发给客户端, 大概明白这个道理就该知道怎么做了。
修正后的命令
要确保回复包能够正确返回, 需修改源地址
iptables -t nat -A PREROUTING -p tcp -d 58.68.255.123 --dport 31688 -j DNAT --to-destination 10.0.30.88:22
iptables -t nat -A POSTROUTING -p tcp -d 10.0.30.88 --dport 22 -j SNAT --to-source 10.0.10.30
--to-source 10.0.10.30
只是修改回源 IP 而已, 把回源地址更改为跳板机内网 IP, 这样就可以在跳板机上把请求转发给客户端了
替代命令
也可以使用 MASQUERADE
选项
iptables -t nat -A PREROUTING -p tcp -i em1 --dport 31688 -j DNAT --to 10.0.30.88:22
iptables -t nat -A POSTROUTING -j MASQUERADE
效果是一样的, 需要指定网卡, em1 为跳板机外网网卡
以上第一次命令不生效原因主要还是跨网段的原因, 10.0.10.0/24
跨到 10.0.30.0/24
, 导致这个问题, 如果公网 IP 转发端口的这台机器内网 IP也在 10.0.30.0/24
网段, 那么第一条命令是可以生效的。
相关文章
原文
nanopi neo利用iptables实现中继(中转/端口转发)
[网络管理] iptables -m参数的含义
双网卡Iptables端口转发