1、iptables概述: iptables是基于内核的防火墙,一个强大的IPv4包过滤和NAT的管理工具。它可以用来设置、维护和检查Linux内核中的IPv4包过滤规则表。用户通过iptables,可以对进出你的计算机的数据包进行过滤。通过iptables命令设置你的规则,来把守你的计算机网络──哪些数据允许通过,哪些不能通过,哪些通过的数据进行记录(log)。我们可以定义一些不同的表。每种表包含一系列内建的链或用户自定义的链。每个链是一组规则以匹配一组数据包。每条规则指定了对所匹配的数据包所执行的动作。iptables的使用格式如下:
iptables -t [tables] option chain [rulenum] rule-specification
rule-specification = [matches...] [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]
-t参数用来指定规则表,内建的规则表有四种,分别是filter、nat、mangle和raw,当未指定规则表时,则默认为filter。
(1)filter:iptables默认的表,主要用于包过滤。它有INPUT、FORWARD和OUTPUT三种内建的链。INPUT匹配目的地IP为本机的数据包,FORWARD匹配路由经过本机的数据包,OUTPUT匹配本机产生的要发送出去的数据包。filter规则表顾名思义是用来进行封包过滤的动作,例如DROP、LOG、ACCEPT或REJECT。
(2)nat:nat表的主要用处是网络地址转换。做过NAT操作的数据包的地址就被改变了,当然这种改变是根据我们的规则进行的。属于一个流的包只会经过这个表一次。当本机遇到一个创建新连接的数据包时nat表就会被检查。它拥有PREROUTING、OUTPUT、POSTROUTING三种内建的链,主要功能为源地址转译(SNAT)或目的地址转译(DNAT)。PREROUTING用来当数据包进来时修改其目的地址,OUTPUT用于修改本机产生数据包(在路由之前),POSTROUTING用于当数据包出去时修改其源地址。注意由于转译工作的特性,需进行目的地网址转译的封包,就不需要进行来源网址转译,反之亦然,因此为了提升改写封包的速率,在防火墙运作时,每个封包只会经过这个规则表一次。如果我们把封包过滤规则也定义在这个数据表里,将会造成无法对同一包进行多次比对,因此这个规则表除了作网址转译外,请不要做其它用途。
(3)mangle:该表主要用于流量整形,即对包进行特定的修改。因为某些特定应用可能需要去改写数据包的一些传输特性,如更改数据包的TTL和TOS、或者是设定MARK(将封包作记号,以进行后续的过滤),这时就必须将这些工作定义在mangle规则表中,不过在实际应用中该表的使用率不高。直到2.4.17的内核,mangle表有两个内建链PREROUTING和OUTPUT。从2.4.18的内核开始,增加了另外三个链INPUT、FORWARD和POSTROUTING。
(4)raw:结合NOTRACK动作(通过-j选项指定),可以配置数据包不经过连接跟踪。在iptables中raw表的优先级最高。总的来说4个表的优先级由高到低的顺序为raw-->mangle-->nat-->filter,例如如果PRROUTING链上,既有mangle表,也有nat表,那么先由mangle处理,然后由nat表处理。raw表只使用在PREROUTING链和OUTPUT链上,一但用户使用了raw表,在某个链上,raw表处理完后,将跳过NAT表和ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了。raw表一般应用在内网访问DMZ区域的情况,能加速防火墙的处理速度。例如 iptables -t raw -A PREROUTING -i eth2 -o eth1 -p tcp --dport 80 -j NOTRACK。
主要的命令选项:
-A:向链中添加规则,默认被添加到末尾。范例 iptables -A INPUT ...。
-D:从链中删除规则,可以输入完整规则,或直接指定规则编号加以删除。范例 iptables -D INPUT --dport 80 -j DROP。又如iptables -D INPUT 1。
-I:插入指定的规则,默认被插入到首部。范例 iptables -I INPUT 1 --dport 80 -j ACCEPT。
-R:替换现行规则。范例 iptables -R INPUT 1 -s 192.168.0.1 -j DROP。
-L:列出指定链中的所有规则。范例 iptables -L INPUT。
-S:打印链上的所有规则。
-F:清空链上的所有规则。范例 iptables -F INPUT。
-Z:将链上的包和字节计数器清零。封包计数器是用来计算同一封包出现次数,是过滤阻断式攻击不可或缺的工具。iptables -Z INPUT。
-N:创建用户自定义的规则链。范例 iptables -N allowed。
-X:删除用户自定义的规则链。范例 iptables -X allowed。
-P:把整个链的过滤策略设置成指定的动作。范例 iptables -P INPUT DROP。只有内建的链才能进行此项设置。
-E:修改自定义链的名称。范例 iptables -E allowed disallowed。
主要的参数:下面的参数主要用于规则rule-specification中,对数据包的规则进行设置,结合上面的add、delete、insert、replace和append命令选项一起使用。
-p:用来指定数据包所用的通信协议,可以是tcp, udp, udplite, icmp, esp, ah, sctp或者all,也可以是这些协议相对应的数字值(0代表all)。可以使用!运算子进行反向比对,例如-p ! tcp ,意思是指除tcp以外的其它类型。范例 iptables -A INPUT -p tcp。
-s:指定数据包的源地址。可以比对单机或网络,比对网络时请用数字来表示屏蔽,例如-s 192.168.0.0/24,比对IP时可以使用!运算子进行反向比对,例如-s ! 192.168.0.0/24。
-d:指定数据包的目的地址。设定方式同上。范例 iptables -A INPUT -d 192.168.1.1。
-i:数据包流入的网卡接口。可以使用通配字符+来做大范围比对,例如-i eth+表示所有的ethernet网卡,也以使用!运算子进行反向比对,例如-i ! eth0。
-o:数据包流出的网卡接口。设定方式同上。范例 iptables -A FORWARD -o eth0。
--sport:指定数据包的源端口。端口必须和协议一起来配合使用。可以比对单一端口,或是一个范围,例如--sport 22:80,表示从22到80号端口之间都算是符合条件,如果要比对不连续的多个端口,则必须使用--multiport参数,详见后文。比对端口号时,可以使用!运算子进行反向比对。
--dport:指定数据包的目的端口。设定方式同上。范例 iptables -A INPUT -p tcp --dport 22。
--tcp-flags:比对TCP封包的状态标志号,参数分为两个部分,第一个部分列举出想比对的标志号,第二部分则列举前述标志号中哪些有被设,未被列举的标志号必须是空的。TCP状态标志号包括SYN(同步)、ACK(应答)、FIN(结束)、RST(重设)、URG(紧急)、PSH(强迫推送)等,均可使用于参数中,除此之外还可以使用关键词ALL和NONE进行比对。比对标志号时,可以使用!运算子行反向比对。范例 iptables -p tcp --tcp-flags SYN,FIN,ACK SYN。
--syn:用来比对是否为要求联机的TCP封包,与iptables -p tcp --tcp-flags SYN,FIN,ACK SYN的作用完全相同,如果使用 !运算子,可用来比对非要求联机封包。范例 iptables -p tcp --syn。
-m multiport --source-port:用来比对不连续的多个来源端口号,一次最多可以比对15个端口,可以使用!运算子进行反向比对。范例 iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110。
-m multiport --destination-port:用来比对不连续的多个目的地埠号,设定方式同上。范例 iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110。
-m multiport --port:这个参数比较特殊,用来比对来源端口号和目的端口号相同的封包,设定方式同上。范例 iptables -A INPUT -p tcp -m multiport --port 22,53,80,110。注意在在本范例中,如果来源端口号为80目的地端口号为110,这种封包并不算符合条件。
--icmp-type:用来比对ICMP的类型编号,可以使用代码或数字编号来进行比对。请打iptables -p icmp --help来查看有哪些代码可用。范例 iptables -A INPUT -p icmp --icmp-type 8。
-m limit --limit:用来比对某段时间内封包的平均流量。范例 iptables -A INPUT -m limit --limit 3/hour。这个例子是用来比对每小时平均流量是否超过一次3个封包。 除了每小时平均次外,也可以每秒钟、每分钟或每天平均一次,默认值为每小时平均一次,参数如后/second、/minute、/day。 除了进行封包数量的比对外,设定这个参数也会在条件达成时,暂停封包的比对动作,以避免因黑客使用洪水攻击法,导致服务被阻断。
--limit-burst:用来比对瞬间大量封包的数量。范例 iptables -A INPUT -m limit --limit-burst 5。这个例子是用来比对一次同时涌入的封包是否超过5个(这是默认值),超过此上限的封
将被直接丢弃。使用效果同上。
-m mac --mac-source:用来比对封包来源网络接口的硬件地址,这个参数不能用在OUTPUT和POSTROUTING规则链上,这是因为封包要送出到网络后,才能由网卡驱动程序透过ARP通讯协议查出目的地的MAC地址,所以iptables在进行封包比对时,并不知道封包会送到个网络接口去。范例 iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01。
--mark:用来比对封包是否被表示某个号码,当封包被比对成功时,我们可以透过MARK处理动作,将该封包标示一个号码,号码最不可以超过 4294967296。范例 iptables -t mangle -A INPUT -m mark --mark 1。
-m owner --uid-owner:用来比对来自本机的封包,是否为某特定使用者所产生的,这样可以避免服务器使用root或其它身分将敏感数据传送出,可以降低系统被攻击的损失。可惜这个功能无法比对出来自其它主机的封包。范例 iptables -A OUTPUT -m owner --uid-owner 500。
-m owner --gid-owner:用来比对来自本机的封包,是否为某特定使用者群组所产生的,使用时机同上。范例 iptables -A OUTPUT -m owner --gid-owner 0。
-m owner --pid-owner:用来比对来自本机的封包,是否为某特定行程所产生的,使用时机同上。范例 iptables -A OUTPUT -m owner --pid-owner 78。
-m owner --sid-owner:用来比对来自本机的封包,是否为某特定联机(Session ID)的响应封包,使用时机同上。范例 iptables -A OUTPUT -m owner --sid-owner 100。
-m state --state:用来比对联机状态,联机状态共有四种:INVALID、ESTABLISHED、NEW 和 RELATED。范例 iptables -A INPUT -m state --state RELATED,ESTABLISHED。INVALID表示该封包的联机编号(Session ID)无效或编号不正确。ESTABLISHED表示该封包属于某个已经建立的联机。NEW表示该封包想要起始一个联机(重设联机或将联机重导向)。RELATED表示该封包是属于某个已经建立的联机。例如FTP-DATA联机必定是源自某个FTP联机。
-j:用来指定要进行的处理动作,常用的处理动作包括:ACCEPT、REJECT、DROP、REDIRECT、MASQUERADE、LOG、DNAT、SNAT、MIRROR、QUEUE、RETURN、MARK,分别说明如下:
(1)ACCEPT:将封包放行,进行完此处理动作后,将不再比对其它规则,直接跳往下一个规则炼(natostrouting)。
(2)REJECT:拦阻该封包,并传送封包通知对方,可以传送的封包有几个选择ICMP port-unreachable、ICMP echo-reply 或是tcp-reset(这个封包会要求对方关闭会话),进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。 范例 iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset。
(3)DROP:丢弃封包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。
(4)REDIRECT:将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续比对其它规则。这个功能可以用来实现通透式proxy或用来保护web服务器。例如 iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080。
(5)MASQUERADE:改写封包来源IP为防火墙NIC IP,可以指定port对应的范围,进行完此处理动作后,直接跳往下一个规则(mangleostrouting)。这个功能与SNAT略有不同,当进行IP伪装时,不需指定要伪装成哪个IP,IP会从网卡直接读取,当使用拨接连线时,IP通常是由ISP公司的DHCP服务器指派的,这个时候MASQUERADE特别有用。范例 iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000。
(6)LOG:将封包相关讯息纪录在/var/log中,详细位置请查阅/etc/syslog.conf组态档,进行完此处理动作后,将会继续比对其他规则。例如 iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"。
(7)SNAT:改写封包来源IP为某特定IP或IP范围,可以指定port对应的范围,进行完此处理动作后,将直接跳往下一个规则(mangleostrouting)。范例 iptables -t nat -A POSTROUTING -p tcp-o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000。
(8)DNAT:改写封包目的地IP为某特定IP或IP范围,可以指定port对应的范围,进行完此处理动作后,将会直接跳往下一个规则链(filter:input 或 filter:forward)。范例 iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10:80-100。
(9)MIRROR:镜射封包,也就是将来源IP与目的地IP对调后,将封包送回,进行完此处理动作后,将会中断过滤程序。
(10)QUEUE:中断过滤程序,将封包放入队列,交给其它程序处理。透过自行开发的处理程序,可以进行其它应用,例如计算联机费等。
(11)RETURN:结束在目前规则链中的过滤程序,返回主规则链继续过滤,如果把自定义规则链看成是一个子程序,那么这个动作就相当于提早结束子程序并返回到主程序中。
(12)MARK:将封包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则。范例 iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2。
概括一下,iptables总共有5个链PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING。4个表filter,nat,mangle,raw。注意所有链名必须大写,表名必须小写,动作必须大写,匹配必须小写。
2、使用实例。
(1)初始化工作:
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
以上每一个命令都有它确切的含义。一般设置你的iptables之前,首先要清除所有以前设置的规则,我们就把它叫做初始化好了。虽然很多情况下它什么也不做,但是保险起见,不妨小心一点吧! 如果你用的是redhat或fedora,那么你有更简单的办法 service iptables stop。
(2)接着开始设置规则:iptables -P INPUT DROP。这一条命令将会为你构建一个非常“安全”的防火墙,我很难想象有哪个hacker能攻破这样的机器,因为它将所有从网络进入你机器的数据丢弃(drop) 了。这当然是安全过头了,此时你的机器将相当于没有网络。如果你ping localhost,你就会发现屏幕一直停在那里,因为ping收不到任何回应。
(3)接着上文继续输入命令:iptables -A INPUT -i ! ppp0 -j ACCEPT。这条规则的意思是接受所有来源不是网络接口ppp0的数据。我们假设你有两个网络接口,eth0连接局域网,loop是回环网(localhost)。ppp0是一般的adsl上网的internet网络接口,如果你不是这种上网方式,那则有可能是eth1。在此我假设你是adsl上网,你的internet接口是ppp0。此时你即允许了局域网的访问,你也可以访问localhost,此时再输入命令ping localhost,结果还会和刚才一样吗?到此我们还不能访问www,也不能mail。
(4)我想访问www:iptables -A INPUT -i ppp0 -p tcp -sport 80 -j ACCEPT。允许来自网络接口ppp0(internet接口),并且来源端口是80的数据进入你的计算机。80端口正是www服务所使用的端口。好了,现在可以看网页了。但是,你能看到吗?如果你在浏览器的地址中输入www.baidu.com,能看到网页吗?你得到的结果一定是找不到主机www.baidu.com。但是,如果你再输入220.181.27.5,你仍然能够访问baidu的网页。为什么?如果你了解dns的话就一定知道原因了。因为如果你打入www.baidu.com,你的电脑无法取得www.baidu.com这个名称所能应的ip地址220.181.27.5。如果你确实记得这个ip,那么你仍然能够访问www,你当然可以只用ip来访问www,但用IP访问www非常麻烦,我们要打开DNS。
(5)打开你的dns端口,输入如下命令:iptables -A INPUT -i ppp0 -p udp -sport 53 -j ACCEPT。这条命令的含义是接受所有来自网络接口ppp0,upd协议的53端口的数据。53也就是著名的dns端口。此时测试一下,你能通过主机名称访问www吗?你能通过ip访问www吗?当然,都可以!
(6)查看防火墙: 此时可以查看你的防火墙了,用命令iptables -L。如果你只想访问www,那么就可以到此为止,你将只能访问www了。不过先别急,将上面讲的内容总结一下,最好写成一个脚本。
(7)到此iptables可以按你的要求进行包过滤了。你可以再设定一些端口,允许你的机器访问这些端口。这样有可能你不能访问QQ,也可能不能打网络游戏,是好是坏,还是要看你自己而定了。顺便说一下,QQ这个东西还真是不好控制,用户与服务器连接使用的好像是8888端口,而QQ上好友互发消息使用的又是udp的4444端口(具体是不是4444还不太清楚,可以通过Wireshark抓包来分析)。而且QQ还可以使用www的80端口进行登录并发消息。所以如果你是公司的网管,需要禁止员工使用QQ,还是要费一番心思的。
(8)如果不巧你的机器是服务器,并且要提供www服务。显然,以上的脚本就不能符合我们的要求了。但只要你撑握了规则,稍作修改同样也能很好的工作。在最后面加上一句 iptables -A INPUT -i ppp0 -p tcp --dport 80 -j ACCEPT。这一句也就是将自己机器上的80端口对外开放了,这样internet上的其他人就能访问你的www了。当然,你的www服务器得工作才行。如果你的机器同时是smtp和pop3服务器,同样的再加上两条语句,将--dport后面的80改成25和110就行了。如果你还有一个ftp服务器,如果你要打开100个端口呢?我们的工作好像是重复性的打入类似的语句,你可能自己也想到了,我可以用一个循环语句来完成,对,此处可以有效的利用shell脚本的功能。
(9)用脚本简化你的工作。阅读下面的脚本:
这个脚本有三个部分,第一部分是定义一些端口,访问你机器的"Open_ports"端口的数据,允许进入的来源是"Allow_ports"端口的数据。第二部分是iptables的初始化,第三部分是对定义的端口具体的操作。如果以后我们的要求发生了一些变化,比如,你给自己的机器加上了一个ftp服务器,那么只要在第一部分"Open_ports"的定义中,将ftp对应的20与21端口加上去就行了。到此你也一定体会到了脚本功能的强大的伸缩性,但脚本的能力还远不止这些!
(10)使你的防火墙更加完善:看上面的脚本init部分的倒数第二句iptables -P INPUT DROP,这是给防火墙设置默认规则。当进入我们计算机的数据,不匹配我们的任何一个条件时,那么就由默认规则来处理这个数据,即drop掉,不给发送方任何应答。也就是说,如果你从internet另外的一台计算机上ping你的主机的话,ping会一直停在那里,没有回应。如果黑客用namp工具对你的电脑进行端口扫描,那么它会提示黑客,你的计算机处于防火墙的保护之中。我可不想让黑客对我的计算机了解太多,怎么办,如果我们把drop改成其他的动作,或许能够骗过这位刚出道的黑客呢。怎么改呢?将刚才的那一句(iptables -P INPUT DROP)去掉,在脚本的最后面加上:
iptables -A INPUT -i ppp0 -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -i ppp0 -p udp -j REJECT --reject-with icmp-port-unreachable
这样就好多了,黑客虽然能扫描出我们所开放的端口,但是他却很难知道,我们的机器处在防火墙的保护之中。如果你只运行了ftp并且仅仅对局域网内部访问, 他很难知道你是否运行了ftp。在此我们给不应该进入我们机器的数据一个欺骗性的回答,而不是丢弃(drop)后就不再理会。这一个功能在我们设计有状态的防火墙中(我这里讲的是静态的防火墙)特别有用。你可以亲自操作一下,看一看修改前后用namp扫描得到的结果会有什么不同?
其他应用实例:
(11)配置SSH规则:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
注意如果你已经把OUTPUT设置成DROP了,就需要加上这个规则,否则SSH还是不能登录,因为SSH服务职能进但不能出。
只允许192.168.0.3的机器进行SSH连接:iptables -A INPUT -s 192.168.0.3 -p tcp --dport 22 -j ACCEPT。如果要允许或限制一段IP地址,可用192.168.0.0/24 表示192.168.0.1-255端的所有IP。
(12)允许loopback回环通信:
IPTABLES -A INPUT -i lo -p all -j ACCEPT
IPTABLES -A OUTPUT -o lo -p all -j ACCEPT
(13)目的地址转换,映射内部地址:
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 81 -j DNAT --to 192.168.0.2:80
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 81 -j DNAT --to 192.168.0.1-192.168.0.10
(14)源地址转换,隐藏内部地址:
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1-1.1.1.10
(15)地址伪装,动态IP的NAT:iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE。注意masquerade和snat的主要区别在于,snat是把源地址转换为固定的IP地址或者是地址池,而masquerade在adsl等方式拨号上网时候非常有用,因为是拨号上网所以网卡的外网IP经常变化,这样在进行地址转换的时候就要在每次都要修改转换策略里面的ip,使用masquerade就很好的解决了这个问题,他会自己去探测外网卡获得的ip地址然后自动进行地址转换,这样就算外网获得的ip经常变化也不用人工干预了。
(16)开启转发功能:
iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT # 只允许已建连接及相关链接对内转发
ptables -A FORWARD -i eth1 -o eh0 -j ACCEPT # 允许对外转发
(17)过滤某个MAC:iptables -A FORWARD -m mac --mac -source MAC地址 -j DROP。报文经过路由后,数据包中原有的MAC信息会被替换,所以在路由后的iptables中使用mac匹配没有意义。
(18)数据包整流:
iptables -A FORWARD -d 192.168.0.1 -m limit --limit 50/s -j ACCEPT
iptables -A FORWARD -d 192.168.0.1 -j DROP
(19)多端口匹配:iptables -A INPUT -p tcp -m muliport --dport -s 21,22,25,80,110 -j ACCEPT。
(20)丢弃非法连接:
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables-A FORWARD -m state --state INVALID -j DROP
(21)存储和恢复iptables规则:
iptables-save > somefile
iptables-restore < somefile