iptables remote port forwarding


iptables remote port forwarding
 
今天再一次需要用到iptables的port forwarding功能,半年前用过一次,忘得差不多了,今次重新学习,写到博客上来加深记忆。iptables的remote port forwarding即用linux自带的iptables实现NAT功能。当然iptables已实现该功能,我们需要做的只是配置(写iptables的配置文件)。
1.什么时候需要用到该功能
当你需要NAT功能,但此时的NAT功能需要跑在一台linux机器而非路由器上。路由器都有专门的界面让你配置NAT,但是普通的linux没有那么友好的路由管理系统,只有iptables供我们使用。
 
如果你不知道NAT是什么,基本上就不用往下看了,不过为了有助于理解我还是稍微描述一下场景。今天的情况是公司在外网有一台服务器A,希望使用公司已有的ldap服务。可是跑ldap的服务器B存在于公司内网中。为了A能联上B,我们希望借助服务器C作为gateway或者说路由或者说跳板。因为C有内网和外网两个网卡,所以它是内网和外网的gateway,或者说纽带。我们希望C能转发来自A的去向C服务器的389号端口(ldap服务的默认端口)的连接到B服务器的389号端口。
这个转发操作其实可以分为两部分工作:
  1. 当C接收到A发来的tcp连接请求时,更改目标地址C.public_ip为B.ip,并发往内网
  2. 当C接收到B发来的对A的回复时,将源地址B.ip改为C.public_ip,并发往外网
 
2.如何配置iptables
使用/sbin/iptables往iptables系统里添加或者插入或者删除路由规则。
转发操作只有两步,但是系统管理员的工作要比两步多:
  1. 确认操作系统中的转发功能已开启
$ /sbin/sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
返回值为1则已开启,为0则未开启。默认状态为未开启。
如果未开启,编辑
/etc/sysctl.conf
文件,找到net.ipv4.ip_forward=0这一行,改为1,然后执行命令
$ /sbin/sysctl -p /etc/sysctl.conf
  2. 使用/sbin/iptables添加路由规则
 
[html] 
/sbin/iptables -P FORWARD DROP  
/sbin/iptables -P INPUT DROP  
/sbin/iptables -A INPUT -p tcp --dport 389 -j ACCEPT  
/sbin/iptables -t nat -P PREROUTING ACCEPT  
/sbin/iptables -t nat -P POSTROUTING ACCEPT  
/sbin/iptables -A FORWARD -o eth0 -i eth1 -s A.ip -d B.ip -j ACCEPT  
/sbin/iptables -A FORWARD -o eth1 -i eth0 -s B.ip -d A.ip -j ACCEPT  
/sbin/iptables -t nat -A PREROUTING -i eth1 -p tcp -s A.ip --dport 389 -j DNAT --to-destination B.ip:389  
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE  
核心规则在第8行和第九行。第八行执行上文提到的转发第一部分,第九行执行上文提到的转发第二部分。
 
1行2行指定默认policy,即若任一路由规则都不适用于某个请求,则执行这里的默认行为DROP。
3行指明允许目的端口为389的请求。
4行5行指明允许做NAT的PREROUTING 和POSTROUTING
6行7行指明允许针对A和B之间的转发。即外网往内网转时,源必须是A,目的是B。为什么目的不是C呢?因为FORWARD的规则在PREROUTING之后进行检验,所以那时的目的地址已经改成了B的ip。内网往外网转时,源必须是B,目的是B。为什么源不是C呢?POSTROUTING不是要把源覆盖为C自己的公共ip吗?这是因为POSTROUTING是在FORWARD之后进行的。看了下面这幅图,就能明白iptables的机制
PACKET IN --->---PREROUTING---[ routing ]--->----FORWARD---->---POSTROUTING--->--- PACKET OUT
                         - mangle        |              - mangle        - mangle
                         - nat (dst)     |              - filter        - nat (src)
                                         |                                 |
                                         |                                 |
                                       INPUT                            OUTPUT
                                        - mangle                         - mangle
                                        - filter                         - nat (dst)
                                        |                                - filter
                                        |                                 |
                                        `---->----[ application ]---->----'
3. 最后保存现在的iptables的规则到硬盘,以便下次重启机器后,还能记住这次的更新。切记切记,这个地方你肯定会出错的,发现怎么规则乱变啊,花几个小时疯狂实验都没明白怎么回事。最后才发现iptables-save工具用错了,没给参数,或者参数给错了。记住下面的方法,就这么简单。
/etc/init.d/iptables save
因为往往初学iptables的时候,都会发现在同一个目录里面还有一个工具叫iptables-save,人们往往会自信的使用它来保存或者叫持久化之前更改过的iptables规则。一旦重启机器后,就抓狂了,更改都没了。后来仔细专研才发现iptables-save需要给参数指定保存到哪个文件!

但是保存到文件的话,每次重启,都得手动载入这个文件到iptables,那么网络就总有一段时间处于非正常状态。有没有一个iptables默认读取的配置文件呢?有,在/etc/sysconfig/iptables 。你可以手敲这个命令 /sbin/iptables-save /etc/sysconfig/iptables,但还有个更方便的方法,就是/etc/init.d/iptables save

相关内容

    暂无相关文章