iptables学习03端口转发


iptables学习03端口转发
 
2个网络接口:Lan口:10.1.1.254/24 eth0,Wan口:60.1.1.1/24 eth1
 
Lan内web server: 10.1.1.1:80,Lan内ftp server: 10.1.1.2:21
 
目标:对内部 server进行端口转发实现internet用户访问内网服务器
 
首先,确认你的linux的各项配置正常,能够访问内外网
 
[plain] 
iptables -P FORWARD DROP  
[plain] 
iptables -A FORWARD -mstate --state ESTABLISHED,RELATED -j ACCEPT  
 
也需要加入确认包和关联包的允许通过
 
如果你要把访问 60.1.1.1:80的数据包转发到Lan内web server,用下面的命令
 
[plain] 
iptables -t nat -A PREROUTING -d 60.1.1.1 -p tcp --dport 80 -j DNAT --to 10.1.1.1:80  
 
ftp服务也同样,命令如下:
 
[plain] 
iptables -t nat -A PREROUTING -d 60.1.1.1 -p tcp --dport 21 -j DNAT --to 10.1.1.2:21  
 
现在还不能访问,为什么呢?我下面详细分析一下。对于iptables好像往外访问的配置较容易,而对内的转发似乎就有一些问题了
 
能引起这个配置失败的原因有很多,我们一个个的来说:
 
第一,本例中,我们的 FORWARD策略是DROP,那么也就是说,没有符合规则的包将被丢弃,不管内到外还是外到内,我们在这里依然不讨论那个确认包和关联包的问题,我们不用考虑他的问题,下面我会详细说一下这个东西,那么如何让本例可以成功呢?加入下面的规则。
 
[plain] 
iptables -A FORWARD -d 10.1.1.1 -p tcp --dport 80 -j ACCEPT  
iptables -A FORWARD -d 10.1.1.2 -p tcp --dport 21 -j ACCEPT  
 
有没有觉得有一些晕?为什么目的地址是10.xxx而不是60.xxx人家internet用户不是访问的60.xxx吗?呵呵,回到上面看看那个图吧, FORWARD链在什么位置上,它是在PREROUTING之后,也就是说当这个包到达FORWARD链的时候,目的地址已经变成10.xxx了,假如 internet用户的请求是这样202.1.1.1:1333-->60.1.1.1:80,在经过了我们的PREROUTING链之后将变成 202.1.1.1:1333-->10.1.1.1:80,这个时候如果你设置一个目的地址为60.xxx的规则有用吗?呵呵,这是问题一。这个时候应该可以完成端口转发的访问了,但是有一些时候还是不行?为什么?看问题二。
 
第二,内网server的ip配置问题,这里我们以web server为例说明一下(ftp情况有一些特殊,下面我们再详细讨论,说确认包和关联包的时候讨论这个问题),上面说到,有的时候可以访问了,有的时候却不行,就是这个web server的ip设置问题了,如果web server没有指定默认的网关,那么在作了上面的配置之后,web server会收到internet的请求,但是,他不知道往哪里回啊,人家的本地路由表不知道你那个internet的ip,202.1.1.1该怎么走。如果你使用截包工具在web server上面察看,你会发现server收到了来自 202.1.1.1:1333-->10.1.1.1:80的请求,由于你没有给webserver配置默认网关,它不知道怎么回去,所以就出现了不通的情况。怎么办呢?两个解决方法:一就是给这个server配置一个默认网关,当然要指向这个配置端口转发的linux,本例是 10.1.1.254,配置好了,就一定能访问了。有一个疑问?难道不需要在FORWARD链上面设置一个允许 web server的ip地址访问外网的规则吗?它的包能出去?答案是肯定的,能出去。因为我们那一条允许确认包与关联包的规则,否则它是出不去的。第二种方法,比较麻烦一些,但是对服务器来说这样似乎更安全一些。方法就是对这个包再作一次SNAT,也就是在POSTROUTING链上添加规则。命令如下:
 
[plain] 
iptables -t nat -A POSTROUTING -d 10.1.1.1 -p tcp --dport 80 -j SNAT --to 10.1.1.254  
ftp的方法相同。这条命令不太好懂??其实很简单,如果使用这条命令,那么你的web server不需要再设置默认网关,就能收到这个请求,只要他和linux的 lan ip地址是能互访的(也就是说web server和Linux的Lanip在一个广播域),我们在根据上面的netfilter流程图来分析这个包到底被我们怎么样了,首先一个请求202.1.1.1:1333--> 60.1.1.1:80被linux收到了,进入 PREROUTING,发现一个规则(iptables -t nat -APREROUTING -d 60.1.1.1 -p tcp --dport 80 -j DNAT --to 10.1.1.1:80)符合,好了,改你的目的地址,于是这个包变成了202.1.1.1:1333-->10.1.1.1:80,继续往前走,进入FORWARD链,okay,也有一条规则允许通过 (iptables -AFORWARD -d 10.1.1.1 -p tcp --dport 80 -j ACCEPT),进入route box选路,找到合适的路径了,继续进入POSTROUTING链,耶?又发现一个符合的规则 (iptables -t nat -A POSTROUTING -d 10.1.1.1 -p tcp --dport 80 -jSNAT --to 10.1.1.254), 原来是一个SNAT,改你的源地址,于是这个包变成了10.1.1.254:xxxx-->10.1.1.1:80。为什么用xxxx了,这里的端口是随机的,我也不知道会是什么。而整个的两次变化的过程都会记录在linux的ip_conntrack中,当web server收到这个包的时候,发现,原来是一个内网自己兄弟来的请求阿,又在一个广播域,不用找网关,把返回包直接扔给交换机了,linux在收到返回包之后,会根据他的 ip_conntrack中的条目进行两次变换,返回真正的internet用户,于是完成这一次的访问。
 
看了上面的两个例子,不知道大家是否清楚了iptables的转发流程,希望对大家有所帮助,下面我们就说说我一直在上面提到的关于那个 ESTABLISHED,RELATED的规则是怎么回事,到底有什么用处。说这个东西就要简单说一下网络的数据通讯的方式,我们知道,网络的访问是双向的,也就是说一个Client与Server之间完成数据交换需要双方的发包与收包。在netfilter中,有几种状态,也就是 new,established,related,invalid。当一个客户端,在本文例一中,内网的一台机器访问外网,我们设置了规则允许他出去,但是没有设置允许回来的规则阿,怎么完成访问呢?这就是netfilter的状态机制,当一个lan用户通过这个linux访问外网的时候,它发送了一个请求包,这个包的状态是new,当外网回包的时候他的状态就是established,所以,linux知道,哦,这个包是我的内网的一台机器发出去的应答包,他就放行了。而外网试图对内发起一个新的连接的时候,他的状态是new,所以linux压根不去理会它。这就是我们为什么要加这一句的原因。还有那个 related,他是一个关联状态,什么会用到呢?tftp,ftp都会用到,因为他们的传输机制决定了,它不像http访问那样,Client_IP:port-->server:80  然后server:80-->Client_IP:port,ftp使用 tcp21建立连接,使用20端口发送数据,其中又有两种方式,一种主动 active mode,一种被动passive mode,主动模式下,client使用port命令告诉server我用哪一个端口接受数据,然后server主动发起对这个端口的请求。被动模式下, server使用 port命令告诉客户端,它用那个端口监听,然后客户端发起对他的数据传输,所以这对于一个防火墙来说就是比较麻烦的事情,因为有可能会有new状态的数据包,但是它又是合理的请求,这个时候就用到这个related状态了,他就是一种关联,在linux中,有个叫 ftp_conntrack的模块,它能识别port命令,然后对相应的端口进行放行。
 
还有几个在实际中比较实用(也比较受用:-))的命令参数,写出来供大家参考
 
[plain] 
iptables -L -n  
 
这样的列表会跳过 linux的domain lookup,有的时候使用iptables -L会比较慢,因为linux会尝试解析ip的域名,真是罗嗦,如果你的 dns server比较不爽的话,iptables -L就会让你很不爽,加一个-n参数就好了。列表刷的就出来。当然了,如果你的linux就是做防火墙,建议把nameserver去掉,在 /etc/resolve.conf里面,因为有时候使用route命令也会比较慢列出来,很是不爽。
 
[plain] 
iptables -L -v  
这个命令会显示链中规则的包和流量计数,嘿嘿,看看哪些小子用的流量那么多,用tc限了他。
 
[plain] 
cat /proc/net/ip_conntrack  
查看目前的 conntrack,可能会比较多哦,最好加一个|grep "关键字",看看你感兴趣的链接跟踪
 
[plain] 
wc -l /proc/net/ip_conntrack  
看看总链接有多少条
 
[plain] 
iptables-save >/etc/iptables  
把当前的所有链备份一下,之所以放到/etc下面叫iptables,因为这样重起机器的时候会自动加载所有的链,经常地备份一下吧,否则如果链多,万一掉电重启,你还是会比较痛苦。
 

相关内容

    暂无相关文章