之前一直在学习转发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