用了老久了的iptables,拿出来点心得写出iptables nat笔记供大家参考!
1.Java环境建立
尽量使用/etc/profile做全局配置
2.前置机中导入iptables时,注意iptables版本问题。
导入iptables后可以用service iptables save将配置自动保存。
修改/etc/sysctl.conf可以使ip_forward功能自动打开。
以上设置后,使用chkconfig将iptables服务选上,可以在默认运行级别下保证iptables的自动运行。
3.使用redhat 8版本的ifup(即服务器切割脚本中的ifrouteup)可以在调整网卡时自动修改默认路由
4.在IDC做服务器切割时,尽量使用mac地址模拟
操作命令ifconfig eth0 hw ether aa:bb:cc:dd:ee:ff
5.静态路由添加方式
/etc/sysconfig/network-scripts/routes-eth0
192.168.0.0/16 via 10.10.0.22
/etc/sysconfig/static-routes
eth0 net 192.168.0.0 netmask 255.255.0.0 gw 10.10.0.22
6.iptables做端口映射时,如果映射的服务器默认网关并非是前置机本身,则postrouting中SNAT必须指定为前置机内网地址
以电信机房为例,防火墙eth0 10.10.0.1 eth1 218.78.212.84
Client A :10.10.0.33 默认路由:10.10.0.1
-A PREROUTING -d 218.78.212.84 -p tcp -m tcp –dport 22 -j DNAT –to-destination 10.10.0.33
结果:除10.10.0.33不能连通外,都可以ssh,日志记录为正确来源IP
-A PREROUTING -d 218.78.212.84 -p tcp -m tcp –dport 22 -j DNAT –to-destination 10.10.0.33
-A POSTROUTING -d 10.10.0.33 -p tcp -m tcp –dport 22 -j SNAT –to-source 218.78.212.84
结果:包括10.10.0.33都可以ssh,但日志记录为防火墙外网IP 218.78.212.84
-A PREROUTING -d 218.78.212.84 -p tcp -m tcp –dport 22 -j DNAT –to-destination 10.10.0.33
-A POSTROUTING -s 10.10.0.33 -p tcp -m tcp –dport 22 -j SNAT –to-source 218.78.212.84
结果:包括10.10.0.33都可以ssh,且日志记录为正确来源IP
Clent B :10.10.0.138 默认路由:10.10.0.241
-A PREROUTING -d 218.78.212.84 -p tcp -m tcp –dport 22 -j DNAT –to-destination 10.10.0.33
-A POSTROUTING -d 10.10.0.33 -p tcp -m tcp –dport 22 -j SNAT –to-source 10.10.0.1
结果:只有此方式包括10.10.0.138可以ssh,但日志记录为防火墙内网IP 10.10.0.1
7.修改/etc/inittab,将Ctrl+Alt+Del的组合键屏蔽,防止误操作及杜绝安全隐患
8.SSH只使用key验证方式
9.使用/etc/hosts.allow及/etc/hosts.deny做IP地址访问过滤
以下脚本是通过log日志将非法连接的IP列入/etc/hosts.deny的黑名单
# !/bin/bash
# 为防止自身地址被列入黑名单,可以先将自身IP加入/etc/hosts.allow
# 查找***20条日志中非法连接和尝试连接失败的IP地址
tail -20 /var/log/secure|awk '$0~/Illegal|Failed/'|awk -Ffrom '{print $2}'|awk '{print $1}' >/tmp/badip
# 读取/etc/hosts.deny中有关sshd的地址定义
list=`grep sshd /etc/hosts.deny`
# 判断日志中非法连接IP的连接数超过5时列入黑名单
if [ "`wc -l /tmp/badip|awk '{print $1}'`" > "5" -a "`sort -u /tmp/badip|wc -l|awk '{print $1}'`" = "1" ]
then
blockip=`head -1 /tmp/badip`
if [ `grep $blockip /etc/hosts.deny|wc -l|awk '{print $1}'` != 1 ]
then
echo "$list $blockip" >/etc/hosts.deny
fi
fi
#p#
我们通过一个例子来大致理解一 下它是如何工作的。比如,我想通过Internet连接发布我们的网站,但是HTTP server在我们的内网里,而 且我们对外只有一个合法的IP,就是防火墙那个对外的IP——$INET_IP。防火墙还 有一个内网的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (这当然是内网的了)。为了完成我们的设想,要做的***件事就是把下面的这个简单的规则加入到nat表 的PREROUTING链中:
iptables -t nat -A PREROUTING –dst $INET_IP -p tcp –dport 80 -j DNAT \ –to-destination $HTTP_IP
现在,所有从Internet来的、到防火墙的80端口去的包都会被转发(或称做被DNAT )到在内网的HTTP服务器上。如果你在Internet上试验一下,一切正常吧。再从内网里试验一下,完全 不能用吧。这其实是路由的问题。下面我们来好好分析这个问题。为了容易阅读,我们把在外网上访问我们 服务器的那台机子的IP地址记为$EXT_BOX。
1.包从地址为$EXT_BOX的机子出发,去往地址为$INET_IP 的机子。
2.包到达防火墙。
3.防火墙DNAT(也就是转发)这个包,而且包会经过很多其他的链检验及处理。
4.包离开防火墙向$HTTP_IP前进。
5.包到达HTTP服务器,服务器就会通过防火墙给以回应,当然,这要求把防火墙作为HTTP到达$EXT_BOX的网关。一般情况下,防火墙就是HTTP服务器的缺省网关。
6.防火墙再对返回包做Un-DNAT(就是照着DNAT的步骤反过来做一遍),这样就 好像是防火墙自己回复了那个来自外网的请求包。
7.返回包好象没经过这么复杂的处理、没事一样回到$EXT_BOX。
现在,我们来考虑和HTTP服务器在同一个内网(这里是指所有机子不需要经过路由器而可以直接互相访 问的网络,不是那种把服务器和客户机又分在不同子网的情况)的客户访问它时会发生什么。我们假设客户 机的IP为$LAN_BOX,其他设置同上。
1.包离开$LAN_BOX,去往$INET_IP。
2.包到达防火墙。
3.包被DNAT,而且还会经过其他的处理。但是包没有经过SNAT 的处理,所以包还是使用它自己的源地址,就是$LAN_BOX(译者注:这就是IP 传输包的特点,只根据目的地的不同改变目的地址,但不因传输过程中要经过很多路由器而随着路由器改变 其源地址,除非你单独进行源地址的改变。其实这一步的处理和对外来包的处理是一样的,只不过内网包的 问题就在于此,所以这里交待一下原因)。
4.包离开防火墙,到达HTTP服务器。
5.HTTP服务器试图回复这个包。它在路由数据库中看到包是来自同一个网络的一台机子,因此它会把回 复包直接发送到请求包的源地址(现在是回复包的目的地址),也就是$LAN_BOX。
6.回复包到达客户机,但它会很困惑,因为这个包不是来自它访问的那台机子。这样,它就会把这个包 扔掉而去等待“真正”的回复包。
针对这个问题有个简单的解决办法,因为这些包都要进入防火墙,而且它们都去往需要做DNAT才能到达 的那个地址,所以我们只要对这些包做SNAT操作即可。比如,我们来考虑上面的例子,如果对那些进入防火 墙而且是去往地址为$HTTP_IP、端口为80的包做SNAT操作,那么这些包就好象是从$LAN_IP来的了,也就是 说,这些包的源地址被改为$LAN_IP了。这样,HTTP服务器就会把回复包发给防火墙,而防火墙会再对包做 Un-DNAT操作,并把包发送到客户机。解决问题的规则如下:
iptables -t nat -A POSTROUTING -p tcp –dst $HTTP_IP –dport 80 -j SNAT \ –to-source $LAN_IP
要记住,按运行的顺序POSTROUTING链是所有链中***一个,因此包到 达这条链时,已经被做过DNAT操作了,所以我们在规则里要基于内网的地址$HTTP_IP(包的目的地)来匹配包。
警告:我们刚才写的这条规则会对日志产生很大影响,这种影响应该说是很不好的。因为来自 Internet包在防火墙内先后经过了DNAT和SNAT处理,才能到达HTTP服务器(上面的例子),所以HTTP服务器 就认为包是防火墙发来的,而不知道真正的源头是其他的IP。这样,当它记录服务情况时,所有访问记录的 源地址都是防火墙的IP而不是真正的访问源。我们如果想根据这些记录来了解访问情况就不可能了。因此上 面提供的“简单办法”并不是一个明智的选择,但它确实可以解决“能够访问”的问题,只是没有考虑到日 志而已。
其他的服务也有类似的问题。比如,你在LAN内建立了SMTP服务器,那你就要设置防火墙以便能转 发SMTP的数据流。这样你就创建了一个开放的SMTP中继服务器,随之而来的就是日志的问题了。
一定要注意,这里所说的问题只是针对没有建立DMZ或类似结构的网络,并且内网的用户访问的是 服务器的外网地址而言的。(译者注:因为如果建立了DMZ,或者服务器和客户机又被分在不同的子网里, 那就不需要这么麻烦了。因为所有访问的源头都不在服务器所在的网里,所以就没必要做SNAT去改变包的源 地址了,从而记录也就不是问题了。如果内网客户是直接访问服务器的内网地址那就更没事了)
较好的解决办法是为你的LAN在内网建立一台单独的DNS服务器(译者注:这样,内网的客户使用网站名 访问HTTP服务器时,DNS就可以把它解析成内网地址。客户机就可以直接去访问HTTP服务器的内网地址了, 从而避免了通过防火墙的操作,而且包的源地址也可以被HTTP服务器的日志使用,也就没有上面说的日志问 题了。),或者干脆建立DMZ得了(这是***的办法,但你要有钱哦,因为用的设备多啊)。
对上面的例子应该考虑再全面些,现在还有一个问题没解决,就是防火墙自己要访问HTTP服务器时会发 生什么,能正常访问吗?你觉得呢:)很可惜,现在的配置还是不行,仔细想想就明白了。我们这里讨论的基 础都是假设机子访问的是HTTP服务器的外网地址,但这个外网地址其实就是防火墙对外的地址,所以当防火 墙访问这个外网地址时,就是访问它自己。防火墙上如果有HTTP服务,那客户机就会看到页面内容,不过这 不是它想看到的(它想要的在DNAT上了),如果没有HTTP服务,客户就只能收到错 误信息了。前面给出的规则之所以不起作用是因为从防火墙发出的请求包不会经过那两条链。还记得防火墙 自己发出的包经过哪些链吧:)我们要在nat表的OUTPUT链中添加下面的规则:
iptables -t nat -A OUTPUT –dst $INET_IP -p tcp –dport 80 -j DNAT \ –to-destination $HTTP_IP
有了***这条规则,一切都正常了。和HTTP服务器不在同一个网的机子能正常访问服务了,和它在一个 网内的机子也可以正常访问服务了,防火墙本身也能正常访问服务了,没有什么问题了。这种心情,套用 《大话西游》里的一句话,就是“世界又清净了”。(不要说你不知道什么是《大话西游》)
我想大家应该能明白这些规则只说明了数据包是如何恰当地被DNAT和SNAT的。除此之外,在 filter表中还需要其他的规则(在FORWARD链里),以允许特定的包也能经过前面写的(在POSTROUTING链和 OUTPUT链里的)规则。千万不要忘了,那些包在到达FORWARD链之前已经在PREROUTING链里被DNAT过了,也 就是说它们的目的地址已被改写,在写规则时要注意这一点。
通过文章的介绍,相信大家都学会了iptables nat的建立和应用,希望本文对大家有帮助!
【编辑推荐】
- iptables+NAT+端口映射
- 如何查看iptables关于nat的日志
- RedHat 9上用iptables做NAT网和记录日志
- iptables下开放ftp连接
- Linux iptables将nat中内网多台ftp服务器映射出去
- Linux Iptables 内核添加time模块
- Linux防火墙Iptables入门笔记