如何通过Iptables让Server2经Server1转发特定域名的SFTP流量(无需修改代码)
我完全理解你的痛点——不想动应用代码,又得让没权限的Server2通过Server1访问那个硬编码域名的SFTP服务。下面我分两种场景给你详细讲纯网络层的实现步骤,全程不用碰业务代码。
首先明确前提:Server1必须能正常访问目标SFTP服务器(x.x.x.x:22),且两台服务器之间网络连通。
场景一:目标域名对应固定IP(x.x.x.x不会变更)
这种情况最直接,用基础的iptables转发就能搞定。
第一步:在Server1上开启IP转发
Server1得具备流量转发权限,先临时开启(重启后失效):
echo 1 > /proc/sys/net/ipv4/ip_forward
要让配置永久生效,编辑/etc/sysctl.conf,找到net.ipv4.ip_forward这行,修改为:
net.ipv4.ip_forward=1
执行sysctl -p让配置立刻生效。
第二步:给Server1配置转发规则
假设Server2的IP是y.y.y.y,Server1自身的IP是z.z.z.z,目标SFTP IP是x.x.x.x,执行以下命令:
# 允许转发Server2发往目标SFTP的22端口流量 iptables -A FORWARD -s y.y.y.y -d x.x.x.x -p tcp --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # 允许目标SFTP的回程流量返回给Server2 iptables -A FORWARD -d y.y.y.y -s x.x.x.x -p tcp --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT # 做SNAT伪装,让目标SFTP看到的是Server1的IP(确保回程流量能回到Server1) iptables -t nat -A POSTROUTING -s y.y.y.y -d x.x.x.x -p tcp --dport 22 -j SNAT --to-source z.z.z.z
第三步:在Server2上把SFTP流量定向到Server1
让Server2上的应用访问目标域名时,流量自动转到Server1,执行:
# 把访问目标SFTP IP的22端口流量转发到Server1 iptables -t nat -A OUTPUT -d x.x.x.x -p tcp --dport 22 -j DNAT --to-destination z.z.z.z:22 # 允许和Server1的22端口建立连接 iptables -A OUTPUT -d z.z.z.z -p tcp --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
场景二:目标域名IP可能动态变化
如果目标域名对应的IP会变动,静态iptables规则会失效,这时候用ipset配合dnsmasq动态跟踪IP。
第一步:在Server2安装必要工具
# Debian/Ubuntu系统 apt update && apt install ipset dnsmasq # RHEL/CentOS系统 yum install ipset dnsmasq
第二步:创建ipset集合存储目标域名的IP
ipset create sftp_target_hash hash:ip
要让这个集合重启后保留,执行:
ipset save > /etc/ipset.conf
然后把ipset restore < /etc/ipset.conf加到开机启动脚本里(比如/etc/rc.local,或者对应系统的systemd服务)。
第三步:配置dnsmasq自动更新IP集合
编辑/etc/dnsmasq.conf,添加以下内容(把your-target-domain.com换成实际的硬编码域名):
# 解析目标域名时,自动把IP加入ipset集合 ipset=/your-target-domain.com/sftp_target_hash # 指定DNS服务器,比如谷歌的8.8.8.8 server=8.8.8.8
重启dnsmasq服务:
systemctl restart dnsmasq
第四步:让Server2用本地dnsmasq解析域名
编辑/etc/resolv.conf,把默认DNS改成本地:
nameserver 127.0.0.1
如果是用systemd-resolved的系统,修改/etc/systemd/resolved.conf,设置DNS=127.0.0.1,然后重启systemd-resolved服务。
第五步:给Server2配置iptables规则,针对ipset集合转发流量
# 把ipset集合里所有IP的22端口流量转发到Server1 iptables -t nat -A OUTPUT -m set --match-set sftp_target_hash dst -p tcp --dport 22 -j DNAT --to-destination z.z.z.z:22 # 允许和Server1的22端口通信 iptables -A OUTPUT -d z.z.z.z -p tcp --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
第六步:Server1的配置和场景一完全一致
依旧需要开启IP转发,配置那三条iptables规则,确保能转发Server2的流量到目标SFTP。
测试验证
在Server2上执行sftp -v your-target-domain.com,然后在Server1上用tcpdump抓包验证:
tcpdump -i any host y.y.y.y and host x.x.x.x and port 22
如果能看到流量交互,说明配置成功。
额外注意
- 如果Server1开了防火墙(比如ufw、firewalld),需允许转发规则:ufw执行
ufw allow forward,firewalld添加对应的富规则即可。 - 若不想用Server1的22端口做转发,也可以在Server1上开个其他端口(比如2222),配置端口转发到x.x.x.x:22,然后Server2的规则改成转发到z.z.z.z:2222就行。
备注:内容来源于stack exchange,提问作者Aidvi

