当前位置: 首页 > GNU/Linux系统, 网络方面 > 正文

iptables学习笔记:端口转发命令的优化

大约一年前,在一个x86板子系统上实现端口转发。现在又出现问题,又要抽空整理整理。虽说是另一同事在另一项目中遇到的,但中秋节前我出差之前老大叫我帮忙协助该同事排查,出差时该同事又call我,出差后老大又叫我继续协助,所以是我的锅,最终还是逃不掉的。这也使得自己对自己做(过)的事不敢懈怠,因为不知道哪一天又回到自己手中。甩锅能力,还有待提高。

一、应用场合

一台X86板子安装linux系统,作为“工作站”,既提供telnet服务(23端口)、web服务(80端口)、ssh服务(22端口),又提供h.264编码、h.264解码,又提供jpeg编码、jpeg解码,还提供大容量硬盘数据存储、视频显示,而且还提供无线AP接入。该工作站有2个网卡,eth1连接设备,外部PC通过eth0访问工作站和设备。设备既提供telnet服务(23端口)、web服务(80端口)、ssh服务(22端口),又提供视频源,还有其它socket端口提供内部工具通信使用。工作站需要接入若干台设备。

简化网络拓扑图如下:

PC <———–>[工作站 eth0]-[工作站 eth1] <—–(交换机)—–> [设备 eth0]-[设备 eth1] <——> (无连接)
172.18.44.142  172.18.44.44  100.100.100.44                   100.100.100.144  172.18.44.X

PC的IP为172.18.44.142,工作站eth0的IP是172.18.44.44,两者处于同一网段:172.18.0.0/16。

工作站eth1的IP是100.100.100.44,通过交换机连接到设备的eth0,设备eth0的IP为100.100.100.144,两者网段为100.100.100.0/24,设备默认网关为100.100.100.44(即工作站的eth1的IP地址)。图中列出三个设备,但这里只选择第一个做说明。

另外,设备还有另一个网卡eth1,有实际用途,但这里连接任何网络,但该网卡IP却和PC、工作站eth0处于同一网段。——是的,现实就这么残酷!虽然我想不明白为何PC和设备都处于同一网段了,还要通过一个“工作站”来做转发访问。但就技术层面而言,还是可以研究一下的。

当初实施时,使用“端口转发”这一机制实现。即对外只提供工作站eth0的IP(因为只有该IP对客户可见),通过不同的端口号对不同的设备(不同端口)进行访问,但又要排除工作站本身的端口。比如工作站172.18.44.44的80端口是工作站web服务,81端口转发到第一台连接设备的web服务,82转发到第二台的web服务,等等。其它类似。

这一应用场景,类似于在外网环境中通过某一方式访问内网数据。

二、旧版本

以前版本使用的命令如下:

iptables -t nat -A PREROUTING -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to-destination 100.100.100.144:23
iptables -t nat -A POSTROUTING -d 100.100.100.144 -p tcp --dport 23 -j SNAT --to 172.18.44.44

如上所述,该命令可以在PC端通过工作站的IP地址外加一个指定的端口号2324,对100.100.100.144这台设备进行访问telnet访问。

三、遇到问题

旧版本命令存在一个问题。当设备存在另一个网口,且该网口和PC端IP网段相同的情况时(如文中网络拓扑所示),就会出现问题,无法访问。因为设备端收到的数据包源地址为172.18.0.0/16网段,恰好这个设备存在一条172.18.0.0/16网段的路由(eth1),无法向eth0发送数据(因为eth0走的是100.100.100.0/24网段)。如果不存在这种情况,则一切正常。为什么呢?因为设备有默认网关,而设备默认网关为100.100.100.0/24网段,当数据包没有路由匹配时,就走默认网关,所以,在没有eth1设备或者eth1网段与PC端网段不相同情况下,都会走默认网关——所以一直没有问题,直到现在。

四、改进版本

其实,旧版本的源IP并没有进行转换(或称“伪装”),还是172.18.0.0/24网段的,只要在设备上将来自eth0的数据包源IP地址修改为工作站的eth1地址,就是100.100.100.0/24网段,就能通过eth0出去了。命令如下:

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.144 -p tcp --dport 23 -j SNAT --to 100.100.100.44

与旧版本命令对比,只是将PSTROUTING链的SNAT改为工作站的eth1网卡的IP地址,其它没变化。——这是当初没有继续深入研究导致的。现将命令翻译成白话(可与下文iptables表做参照),如下:

第一条命令:插入一条PREROUTING链(用于改目的地址,即DNAT),如果是从eth0进来(-i eth0)的IP为172.18.44.44(因为用-d,所以是目的IP)且是tcp协议端口为2324的数据包,则把它的目的IP转换为100.100.100.144:2323。

第二条命令:插入一条PSOTROUTING链(用于改源地址,即SNAT),如果是从eth1出去(-o eth1)的IP为100.100.100.144(因为用-d,所以是目的IP)且是tcp协议端口为23的数据包,则把它的源IP转换为100.100.100.44。

第二条命令指定了具体的IP地址及端口号,由于此时端口已经一致不须转换,可以去掉。另外可以使用IP段来简化。得到最终版本如下

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44

下面是工作站的iptables表:

root@latelee:~# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             172.18.44.44         tcp dpt:2324 to:100.100.100.144:23

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  anywhere             100.100.100.0/24     to:100.100.100.44

另外,iptables参数使用-d指定目的地址/网段,用-s表示源地址/网段。所以,在POSTROUTING链中可以用-s指定源IP网段,其它参数不变,如下:

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23
iptables -t nat -A POSTROUTING -o eth1 -s 172.18.0.0/16 -j SNAT --to 100.100.100.44 // 用-s将“源IP”为172.18网段的转换为100.100.100.44

命令对应的iptables表如下:

root@latelee:test# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             172.18.44.44         tcp dpt:2324 to:100.100.100.144:23

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  172.18.0.0/16        anywhere             to:100.100.100.44

这两个iptables表,一个是匹配destination,一个是匹配source,但都可以达到相同的目的。这也体现了iptables语法自由的一面。

五、小结

这里给出经过测试的内外网互访iptables命令示例。
“外网访问内网”:
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -j DNAT --to 100.100.100.144
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44
“内网访问外网”:
iptables -t nat -A POSTROUTING -o eth0 -s 100.100.100.0/24 -j MASQUERADE

此处仅做命令备份,不展开讨论。可以参考后续文章。

六、其它

本文为“外网”访问“内网”这一应用场合做了实践,所有命令都通过测试,测试方式是在PC上使用telnet命令连接工作站的eth0地址的2324端口来访问设备的telnet服务,同时在工作站上抓包分析,有一定事实依据。

网上有很多资料介绍iptables,有部分存在误导性,做参考时注意甄别。

由于应用场合特殊性(见本文开头介绍),无法实现纯粹的IP级别的转发。但这缺点也是经常被领导点评的。我认知中,交换机只做二级交换功能,路由器是做路由功能的。一个大而全的东西,看看什么时候可实现吧。

参考资料:

《鳥哥的 Linux 私房菜》,第九章、防火牆與 NAT 伺服器:http://linux.vbird.org/linux_server/0250simple_firewall.php

李迟 2016.9.24 周六

本文固定链接: http://www.latelee.org/using-gnu-linux/iptables-note-ipforward.html

如无特别说明,迟思堂工作室文章均为原创,转载请注明: iptables学习笔记:端口转发命令的优化 | 迟思堂工作室

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter