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服务,等等。其它类似。

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

二、旧版本

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

[cpp]  view plain  copy
  1. iptables -t nat -A PREROUTING -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to-destination 100.100.100.144:23  
  2. 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出去了。命令如下:

[cpp]  view plain  copy
  1. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23  
  2. 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段来简化。得到最终版本如下

[cpp]  view plain  copy
  1. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23  
  2. iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44  

下面是工作站的iptables表:

[cpp]  view plain  copy
  1. root@latelee:~# iptables -L -t nat  
  2. Chain PREROUTING (policy ACCEPT)  
  3. target     prot opt source               destination           
  4. DNAT       tcp  --  anywhere             172.18.44.44         tcp dpt:2324 to:100.100.100.144:23  
  5.   
  6. Chain INPUT (policy ACCEPT)  
  7. target     prot opt source               destination           
  8.   
  9. Chain OUTPUT (policy ACCEPT)  
  10. target     prot opt source               destination           
  11.   
  12. Chain POSTROUTING (policy ACCEPT)  
  13. target     prot opt source               destination           
  14. SNAT       all  --  anywhere             100.100.100.0/24     to:100.100.100.44  

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

[cpp]  view plain  copy
  1. iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23  
  2. 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表如下:

[cpp]  view plain  copy
  1. root@latelee:test# iptables -t nat -L  
  2. Chain PREROUTING (policy ACCEPT)  
  3. target     prot opt source               destination           
  4. DNAT       tcp  --  anywhere             172.18.44.44         tcp dpt:2324 to:100.100.100.144:23  
  5.   
  6. Chain INPUT (policy ACCEPT)  
  7. target     prot opt source               destination           
  8.   
  9. Chain OUTPUT (policy ACCEPT)  
  10. target     prot opt source               destination           
  11.   
  12. Chain POSTROUTING (policy ACCEPT)  
  13. target     prot opt source               destination           
  14. SNAT       all  --  172.18.0.0/16        anywhere             to:100.100.100.44  

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

五、小结

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

“内网访问外网”:
[cpp]  view plain  copy
  1. 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值