linux的防火墙功能IP tables详解之一

一、iptables简介
Linux的2.4版内核引入了一种全新的包过滤引擎,称为Netfilter。
控制Netfilter的工具iptables是Linux 2.2版内核中比较老的命令ipchains的兄弟。
iptables把有次序的规则"链(chains)"应用到网络包上。
链的集合就构成了"表(tables)",用于处理特殊类型的流量。

例如,默认的iptables表名叫"filter(过滤器)"。网络数据包都使用这个表里的规则链来过滤。
过滤器表包含3个默认链。
对于每个包来说,内核都会选择三个链中适合的一个进行处理:
. FORWARD链规则, 用于从一个网络接口输入,再转发到另一个网络接口输出的包;
. INPUT链规则,   用于以本机为目的地的包;
. OUTPUT链规则,  用于从本地主机发出的包;

这3个标准链通常能够满足两个网络接口之间防火墙的全部需要。
如果必要,您还可以定义一个定制的配置,支持更复杂的记账或者路由场合。

除了filter表之外,iptables还包含"NAT"和"mangle"表。
. NAT表包含的规则链控制着NAT(Network Address Translation,网络地址转换,这里的“nat”就是iptables表名,
  "NAT"是一般地址转换机制的叫法)。
  12.4.6节讨论了NAT,本节给出一个正在起作用的nat表的例子。
  在本节后面的内容里,我们会使用nat表的PREROUTING链来做反IP欺骗的包过滤。
. mangle表包含了链可以修改或者改变在NAT和包过滤之外的网络包的内容。
  虽然mangle表对于做包的特殊处理很方便,比如重新设定IP包的ttl值,但是在大多数工作环境中一般不会用到它。
  我们在这一节里只讨论filter和nat表,而把mangle表留给读者自己去探索。

图1比较完整地展示了一个数据包是如何经过防火墙的,考虑到节省空间,该图实际上包了三种情况:
. 来自外部,以防火墙(本机)为目的地的包,走图1中 "自上至下左边" 路径;
. 由防火墙(本机)生成并输出的包,        走图1中从"本地进程"开始,自上至下左边的路径;
. 来自外部,目的地是其它主机的包,      走图1中"自上至下走右边"的路径;
图1:

如果我们从上图中略去比较少用的mangle 表的图示,就有图2所显示的更为清晰的路径图.
图2:
linux的防火墙功能IP tables详解之一_第1张图片
构成一条链的每条规则都有一个"target(目标)"子句,它决定了如何处理匹配的包。
一旦某个包匹配了一个规则,那么它的结局就确定了,不再用其他规则来检查它。
虽然iptables内部定义了许多target,但是还可以指定另一条链作为规则的target。


在filter表中的规则可以使用的target子句有
  ACCEPT、DROP、REJECT、LOG、MIRROR、QUEUE、REDIRECT、RETURN和ULOG。
. 当一条规则落在了ACCEPT上的时候,匹配这条规则的包就可以继续通过。
. DROP和REJECT都会把它们的包丢弃。DROP是默默地丢弃,而REJECT会返回一则ICMP错误消息。
. LOG提供跟踪包匹配规则情况的简单办法,ULOG提供了范围更广的日志记录信息。
. REDIRECT把包分流到一个代理,而不是直接让它们通过。
  您可能会用这个功能来迫使站点上的所有Web流量都通过一个Web高速缓存,比如Squid。
. RETURN终结用户定义的链,类似于子例程调用中的return语句。
. MIRROR目标在发送包之前交换IP源和目的地址。
. QUEUE通过一个内核模块把包交给本地用户程序。

Linux防火墙通常是由rc启动脚本中的一系列iptables命令来实现的。
各个iptables命令通常采取下列形式之一:
 iptables -F chain-name
 iptables -P chain-name target
 iptables -A chain-name -i interface -j target
. 第一种形式(-F)把之前所有的规则都从链中清除掉。
. 第二种形式(-P)给链设置一条默认策略(也就是target)。我们建议您使用DROP作为链默认的目标(target)。
. 第三种形式(-A)把当前的说明追加到链上。
  除非使用-t参数指定了表(table)名,否则命令被默认应用到filter表上。
  -i参数将规则应用到有名字的接口上,-j则标识出目标(target)。

iptables还接受许多别的子句,表1给出了其中的一部分。
表1
linux的防火墙功能IP tables详解之一_第2张图片

二、IP 规则的保存与恢复

1. 规则保存 
"iptables-save"命令 把规则保存到文件中
再由目录"/etc/rc.d"下的脚本(/etc/rc.d/init.d/iptables)自动装载.
使用命令iptables-save 来保存规则,
一般用命令:
#  iptables-save > /etc/sysconfig/iptables

生成保存规则的文件为: /etc/sysconfig/iptables;
也可以用命令:
#  service iptables save

它能把规则自动保存在/etc/sysconfig/iptables 中。

2. 规则恢复
当计算机启动时,rc.d 下的脚本将用命令iptables-restore 调用这个文件,从而就自动恢复了规则。

3. iptables服务操作
检查:
#  service --status-all
...
Table: filter
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    DROP       all  --  10.0.0.0/8           0.0.0.0/0           
2    DROP       all  --  172.16.0.0/12        0.0.0.0/0           
3    DROP       all  --  192.168.0.0/16       0.0.0.0/0           

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x16/0x02 limit: avg 1/sec burst 5 
2    ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:0x17/0x04 limit: avg 1/sec burst 5 
3    ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 8 limit: avg 1/sec burst 5 

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination  
...

启动:
# service iptables start
Applying iptables firewall rules:                          [  OK  ]
Loading additional iptables modules: ip_conntrack_netbios_n[  OK  ]

停止:
# service iptables stop
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy ACCEPT: filter                    [  OK  ]
Unloading iptables modules:                                [  OK  ]

重启:
# service iptables restart
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy ACCEPT: filter                    [  OK  ]
Unloading iptables modules:                                [  OK  ]
Applying iptables firewall rules:                          [  OK  ]
Loading additional iptables modules: ip_conntrack_netbios_n[  OK  ]

4. 彻底清空规则
# iptables -F
# iptables-save > /etc/sysconfig/iptables

三、iptables 指令语法
1. 语法
iptables [-t table] command [match] [-j target/jump]
. [-t table] 指定规则表;
    内建的规则表有三个,分别是:nat、mangle 和filter,
    当未指定规则表时,则一律视为是filter。
    三个规则表的功能如下:
      nat:此规则表拥有PREROUTING 和POSTROUTING 两个规则链,
           主要功能为进行一对一、一对多、多对多等网址转换工作(SNAT、DNAT),
           这个规则表除了作网址转换外,请不要做其它用途。
      mangle:此规则表拥有PREROUTING、FORWARD 和POSTROUTING 三个规则链。
           除了进行网址转换工作会改写封包外,在某些特殊应用可能也必须去改写封包(TTL、TOS)
           或者是设定MARK(将封包作记号,以进行后续的过滤),这时就必须将这些工作定义在mangle 规则表中;
           由于使用率不高,我们不打算在这里讨论mangle 的用法。
      filter: 这个规则表是默认规则表,拥有INPUT、FORWARD 和OUTPUT 三个规则链,
           这个规则表顾名思义是用来进行封包过滤的处理动作(例如:DROP、LOG、ACCEPT 或REJECT),
           我们会将基本规则都建立在此规则表中。

2. command 常用命令列表
命令:  -A, --append
范例:  iptables -A INPUT ...
说明:  新增规则到某个规则链中,该规则将会成为规则链中的最后一条规则。

命令:  -D, --delete
范例:  iptables -D INPUT --dport 80 -j DROP
       iptables -D INPUT 1
说明:  从某个规则链中删除一条规则,可以输入完整规则,或直接指定规则编号加以删除。

命令:  -R, --replace
范例:  iptables -R INPUT 1 -s 192.168.0.1 -j DROP
说明:  取代现行规则,规则被取代后并不会改变顺序。

命令:  -I, --insert
范例:  iptables -I INPUT 1 --dport 80 -j ACCEPT
说明:  插入一条规则,原本该位置上的规则将会往后移动一个顺位。

命令:  -L, --list
范例1: iptables -L INPUT
说明:  列出某规则链中的所有规则。
范例2: iptables -t nat -L
说明:  列出nat 表所有链中的所有规则。

命令:  -F, --flush
范例:  iptables -F INPUT
说明:  删除filter 表中INPUT 链的所有规则。

命令:  -Z, --zero
范例:  iptables -Z INPUT
说明:  将封包计数器归零。封包计数器是用来计算同一封包出现次数,是过滤阻断式攻击不可或缺的工具。

命令:  -N, --new-chain
范例:  iptables -N allowed
说明:  定义新的规则链。

命令:  -X, --delete-chain
范例:  iptables -X allowed
说明:  删除某个规则链。

命令:  -P, --policy
范例:  iptables -P INPUT DROP
说明:  定义过滤政策。也就是未符合过滤条件之封包, 默认的处理方式。

命令:  -E, --rename-chain
范例:  iptables -E allowed disallowed
说明:  修改某自定义规则链的名称。

3. [match] 常用封包匹配参数
参数:  -p, --protocol
范例:  iptables -A INPUT -p tcp
说明:  匹配通讯协议类型是否相符,可以使用! 运算符进行反向匹配,例如:
           -p !tcp
       意思是指除tcp 以外的其它类型,如udp、icmp ...等。
       如果要匹配所有类型,则可以使用all 关键词,例如:
           -p all

参数:  -s, --src, --source
范例:  iptables -A INPUT -s 192.168.1.1
说明:  用来匹配封包的来源IP,可以匹配单机或网络,匹配网络时请用数字来表示子网掩码,
例如:
       -s 192.168.0.0/24
       匹配IP 时可以使用! 运算符进行反向匹配,例如:
       -s! 192.168.0.0/24。

参数:  -d, --dst, --destination
范例:  iptables -A INPUT -d 192.168.1.1
说明:  用来匹配封包的目的地IP,设定方式同上。

参数:  -i, --in-interface
范例:  iptables -A INPUT -i eth0
说明:  用来匹配封包是从哪块网卡进入,可以使用通配字符+ 来做大范围匹配,例如:
         -i eth+
      表示所有的ethernet 网卡
      也可以使用! 运算符进行反向匹配,例如:
         -i !eth0

参数:  -o, --out-interface
范例:  iptables -A FORWARD -o eth0
说明:  用来匹配封包要从哪块网卡送出,设定方式同上。

参数:  --sport, --source-port
范例:  iptables -A INPUT -p tcp --sport 22
说明:  用来匹配封包的源端口,可以匹配单一端口,或是一个范围,例如:
          --sport 22:80
       表示从22 到80 端口之间都算是符合条件,如果要匹配不连续的多个端口,则必须使用
          --multiport 参数,详见后文。匹配端口号时,可以使用! 运算符进行反向匹配。

参数:  --dport, --destination-port
范例:  iptables -A INPUT -p tcp --dport 22
说明:  用来匹配封包的目的地端口号,设定方式同上

参数:  --tcp-flags
范例:  iptables -p tcp --tcp-flags SYN,FIN,ACK SYN
说明:  匹配TCP 封包的状态标志;
       参数分为两个部分,
         第一个部分列举出想匹配的标志,
         第二部分则列举前述标志中哪些有被设置,未被列举的标志必须是空的。
       TCP 状态标志包括:
          SYN(同步)、ACK(应答)、FIN(结束)、RST(重设)、URG(紧急) 、PSH(强迫推送) 
       等均可使用于参数中,
       除此之外还可以使用关键词ALL 和NONE 进行匹配。
       匹配标志时,可以使用! 运算符行反向匹配。

参数:  --syn
范例:  iptables -p tcp --syn
说明:  用来表示TCP 通信协议中,SYN 位被打开,而ACK 与FIN 位关闭的分组,即TCP 的初始连接,
       与iptables -p tcp --tcp-flags SYN,FIN,ACK SYN 的作用完全相同,
       如果使用!运算符,可用来匹配非要求连接封包。

参数:  -m multiport --source-port
范例:  iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
说明:  用来匹配不连续的多个源端口,一次最多可以匹配15 个端口,
       可以使用! 运算符进行反向匹配。

参数:  -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
范例:  iptables -A INPUT -p icmp --icmp-type 8
说明:  用来匹配ICMP 的类型编号,可以使用代码或数字编号来进行匹配。
       请打iptables -p icmp--help 来查看有哪些代码可用。

参数:  -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
范例:  iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
说明:  用来匹配封包来源网络接口的硬件地址,
       这个参数不能用在OUTPUT 和POSTROUTING 规则链上,
       这是因为封包要送到网卡后,才能由网卡驱动程序透过ARP 通讯协议查出目的地的MAC 地址,
       所以iptables 在进行封包匹配时,并不知道封包会送到哪个网络接口去。

参数:  --mark
范例:  iptables -t mangle -A INPUT -m mark --mark 1
说明:  用来匹配封包是否被表示某个号码,
       当封包被匹配成功时,我们可以透过MARK 处理动作,将该封包标示一个号码,号码最大不可以超过4294967296。

参数:  -m owner --uid-owner
范例:  iptables -A OUTPUT -m owner --uid-owner 500
说明:  用来匹配来自本机的封包,是否为某特定使用者所产生的,
       这样可以避免服务器使用root或其它身分将敏感数据传送出,可以降低系统被骇的损失。
       可惜这个功能无法匹配出来自其它主机的封包。

参数:  -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
范例:  iptables -A OUTPUT -m owner --sid-owner 100
说明:  用来匹配来自本机的封包,是否为某特定连接(Session ID)的响应封包,使用时机同上。

参数:  -m state --state
范例:  iptables -A INPUT -m state --state RELATED,ESTABLISHED
说明:  用来匹配连接状态, 
       连接状态共有四种:
          INVALID、ESTABLISHED、NEW 和RELATED。
       INVALID     表示该封包的连接编号(Session ID)无法辨识或编号不正确。
       ESTABLISHED 表示该封包属于某个已经建立的连接。
       NEW         表示该封包想要起始一个连接(重设连接或将连接重导向)。
       RELATED     表示该封包是属于某个已经建立的连接,所建立的新连接。
       例如:FTP-DATA 连接必定是源自某个FTP 连接。

4. [-j target/jump] 常用的处理动作
-j 参数用来指定要进行的处理动作,常用的处理动作包括:
   ACCEPT、REJECT、DROP、REDIRECT、MASQUERADE、LOG、DNAT、SNAT、MIRROR、QUEUE、RETURN、MARK,

分别说明如下:
动作:  ACCEPT 
说明:  将封包放行,
       进行完此处理动作后,将不再匹配其它规则,直接跳往下一个规则链(natostrouting)。

动作:  REJECT 
说明:  拦阻该封包,并传送封包通知对方,
       可以传送的封包有几个选择:
           ICMP port-unreachable、
           ICMP echo-reply 或是
           tcp-reset(这个封包会要求对方关闭连接),
         进行完此处理动作后,将不再匹配其它规则,直接中断过滤程序。
范例:  iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset

动作:  DROP
说明:  丢弃封包不予处理,进行完此处理动作后,将不再匹配其它规则,直接中断过滤程序。

动作:  REDIRECT
说明:  将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续匹配其它规则。
       这个功能可以用来实现透明代理或用来保护web 服务器。
范例:  iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

动作:  MASQUERADE
说明:  改写封包来源IP 为防火墙NIC IP,可以指定port 对应的范围,
       进行完此处理动作后,直接跳往下一个规则链(manglepostrouting)。
       这个功能与SNAT 略有不同,当进行IP 伪装时,不需指定要伪装成哪个IP,IP 会从网卡直接读取,
       当使用拨号接连时,IP通常是由ISP 公司的DHCP 服务器指派的,这个时候MASQUERADE 特别有用。
范例:  iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000

动作:  LOG
说明:  将封包相关讯息纪录在/var/log 中,详细位置请查阅/etc/syslog.conf 配置文件,
       进行完此处理动作后,将会继续匹配其规则。
范例:  iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"

动作:  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

动作:  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

动作:  MIRROR
说明:  镜射封包,也就是将来源IP 与目的地IP 对调后,将封包送回,
       进行完此处理动作后,将会中断过滤程序。

动作:  QUEUE
说明:  中断过滤程序,将封包放入队列,交给其它程序处理。
       通过自行开发的处理程序,可以进行其它应用,例如:计算连接费用等。

动作:  RETURN
说明:  结束在目前规则链中的过滤程序,返回主规则链继续过滤,
       如果把自定义规则链看成是一个子程序,那么这个动作,就相当于提前结束子程序并返回到主程序中。

动作:  MARK
说明:  将封包标上某个代号,以便提供作为后续过滤的条件判断依据,
       进行完此处理动作后,将会继续匹配其它规则。
范例:  iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2

你可能感兴趣的:(linux的防火墙功能IP tables详解之一)