之前一直在学习转发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添加路由规矩


/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

文章结束给大家分享下程序员的一些笑话语录: 一程序员告老还乡,想安度晚年,于是决定在书法上有所造诣。省略数字……,准备好文房4宝,挥起毛笔在白纸上郑重的写下:Hello World