链(chains)是数据包传播的路径,每一条链其实就是众多规则中的一个检查清单,每一条链中可以有一条或数条规则。当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。
五个链:INPUT ,OUTPUT ,PREROUTING ,POSTROUTING ,FORWARD
Iptables采用“表”和“链”的分层结构。在REHL4中是三张表五个链。现在REHL5成了四张表五个链了,不过多出来的那个表用的也不太多,所以基本还是和以前一样。
iptables传输数据包的过程 ,如图
① 当一个数据包进入网卡时,它首先进入PREROUTING链,内核根据数据包目的IP判断是否需要转送出去。
② 如果数据包就是进入本机的,它就会沿着图向下移动,到达INPUT链。数据包到了INPUT链后,任何进程都会收到它。
本机上运行的程序可以发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出。
③ 如果数据包是要转发出去的,且内核允许转发,数据包就会如图10-4所示向右移动,经过FORWARD链,然后到达POSTROUTING链输出。

iptables的规则表和链:
下面罗列一下这四张表和五个链。注意一定要明白这些表和链的关系及作用。
规则表:
1.filter表——三个链:INPUT、FORWARD、OUTPUT
作用:过滤数据包 内核模块:iptables_filter.
2.Nat表——三个链:PREROUTING、POSTROUTING、OUTPUT
作用:用于网络地址转换(IP、端口) 内核模块:iptable_nat
3.Mangle表——五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS内核模块:iptable_mangle(别看这个表这么麻烦,咱们设置策略时几乎都不会用到它)
4.Raw表——两个链:OUTPUT、PREROUTING
作用:决定数据包是否被状态跟踪机制处理 内核模块:iptable_raw
(这个是REHL4没有的,不过不用怕,用的不多)
规则链:
1.INPUT——进来的数据包应用此规则链中的策略
2.OUTPUT——外出的数据包应用此规则链中的策略
3.FORWARD——转发数据包时应用此规则链中的策略
4.PREROUTING——对数据包作路由选择前应用此链中的规则
(记住!所有的数据包进来的时侯都先由这个链处理)
5.POSTROUTING——对数据包作路由选择后应用此链中的规则
(所有的数据包出来的时侯都先由这个链处理)
规则表之间的优先顺序:
Raw——mangle——nat——filter
规则链之间的优先顺序(分三种情况):
第一种情况:入站数据流向
从外界到达防火墙的数据包,先被PREROUTING规则链处理(是否修改数据包地址等),之后会进行路由选择(判断该数据包应该发往何处),如果数据包的目标主机是防火墙本机(比如说Internet用户访问防火墙主机中的web服务器的数据包),那么内核将其传给INPUT链进行处理(决定是否允许通过等),通过以后再交给系统上层的应用程序(比如Apache服务器)进行响应。
第二冲情况:转发数据流向
来自外界的数据包到达防火墙后,首先被PREROUTING规则链处理,之后会进行路由选择,如果数据包的目标地址是其它外部地址(比如局域网用户通过网关访问QQ站点的数据包),则内核将其传递给FORWARD链进行处理(是否转发或拦截),然后再交给POSTROUTING规则链(是否修改数据包的地址等)进行处理。
第三种情况:出站数据流向
防火墙本机向外部地址发送的数据包(比如在防火墙主机中测试公网DNS服务器时),首先被OUTPUT规则链处理,之后进行路由选择,然后传递给POSTROUTING规则链(是否修改数据包的地址等)进行处理。
管理和设置iptables规则


在linux中【】中的内容表示可有可无,这里再强调下
iptables的命令格式较为复杂,一般的格式如下:Iptables 【-t table】 command chains (NUM) match condition -j action
命令选项:
--append -A append 在规则表的最后追加一条规则
--insert -I 【n】 插到第n条规则之前
--replade -R n 替换第n条新规则
--delete -D n delete第n条规则
--flush -F 清空表中所有规则
--policy -P ACCEPT|DROP 默认策略动作
--new-chain -N z自定义新链
--rename-chain -E 重命名用户自定义的链
--zero -Z 清零计数器
1.所有被本规则匹配到的数据包的个数
2. 所有被本规则匹配到的数据包的数据之和
--list -L list链中的所有规则 默认保存在/etc/sysconfig/iptables
-x 显示-Z选项中的数据时,不作单位换算,显示精确值
-n 不作名称解析,以数字的格式显示ip
-v | -vv |-vvv|-vvvv | 显示详细的信息
--line-numbers 显示行号
-S 同-L ,print出来
匹配选项
匹配分为通用匹配和扩展匹配
A.通用匹配
--proto -p protocol协议类型
--source -s src-address数据包匹配的源地址
--destination -d dst-address数据包匹配到目标地址
--in-terface -i in_interface数据入口
--out-interface -o out-interface数据出口
B.扩展匹配
扩展又分为隐含扩展和显式扩展
隐含匹配 显式扩展
tcp --source-port -m tcp
--dport -m state --state NEW|ESTABLISHED|RELATED| INVALID
--sport -m limit --limit n/days |minute
--limit-burst N 峰值
--type-flags -m string --string
--syn -m mac --mac—source
-m multiport --source-ports
--destination-ports
--tcp-flags mask comp
Udp --sport
--dport
Icmp --icmp-types
8 echorequest
0 echo-reply
3 destination unreachable
Action 动作
-j DROP 丢弃数据包(“悄悄地“)
REJECT 丢弃数据包(明确的)
ACCEPT 接收数据包
SNAT 源端口转换
DNAT 目的端口转换
LOG 记录日志
REDIRECT 端口转换
MASQUERADE 端口伪装(动态获取网关时用,耗系统资源)
保存iptables规则 ,默认是不保存的,重启后,规则就会消失
[root@localhost ~]# service iptables save 默认保存在/etc/sysconfig/iptables下
[root@localhost ~]# iptables-save > /etc/iptables.save 自定义保存
Iptables的实例演示
下面我们来简单接触下ipitables的用法,然后再慢慢深入
[root@song ~]# iptables -t filter –L 查看filter表的规则
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.1.0/24 192.168.0.0/24 tcp dpt:http state NEW,ESTABLISHED
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere icmp echo-request
ACCEPT icmp -- anywhere anywhere icmp echo-reply
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.0.0/24 192.168.1.0/24 tcp spt:http state ESTABLISHED
[root@song ~]# iptables –F 清除表中所有规则
[root@song ~]# iptables –L 可以看出和 –t filter –L 效果一样,默认查询filter表
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[root@song ~]# iptables -P INPUT DROP -P设置表的默认策略
[root@song ~]# iptables -P OUTPUT DROP
[root@song ~]# iptables -P FORWARD DROP
[root@song ~]# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
下面我们以一个简单的实例来联系下测试下我们的功力到“第几段“了 呵呵
实验环境
内网: ftp http telnet 10.0.2.100
外网 : 10.0.3.100
Firewall : ssh eth0 10.0.2.1 eth1 :10.0.3.1
要求:内外网之间可以相互ping通,外网可以访问内网的httpd,ftp服务 ,其中的ftp服务只能在有请求时服务器才相应。只允许内网无限制访问firewall的ssh服务。
我们来一条一条的实现
配置firewall
1外网可以访问内网的httpd,ftp服务
[root@song ~]# vim /etc/sysctl.conf 开启firewall路由功能
[root@song ~]# sysctl –p 重读配置文件,临时开启路由功能
net.ipv4.ip_forward = 1 为1时表示开启路由功能
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 4294967295
kernel.shmall = 268435456
设置默认规则为DROP
[root@song ~]# iptables -P INPUT DROP
[root@song ~]# iptables -P OUTPUT DROP
[root@song ~]# iptables -P FORWARD DROP
[root@song ~]# iptables –L 查看设置
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
1使相互之间可以ping 通
[root@song ~]# iptables -A FORWARD -p icmp --icmp-type 8 -j ACCEPT
[root@song ~]# iptables -A FORWARD -p icmp --icmp-type 0 -j ACCEPT
测试
[root@station7 shared]# ping 10.0.2.100
PING 10.0.2.100 (10.0.2.100) 56(84) bytes of data.
64 bytes from 10.0.2.100: icmp_seq=1 ttl=63 time=130 ms
[root@congtou pub]# ping 10.0.3.100
PING 10.0.3.100 (10.0.3.100) 56(84) bytes of data.
64 bytes from 10.0.3.100: icmp_seq=1 ttl=63 time=176 ms
64 bytes from 10.0.3.100: icmp_seq=2 ttl=63 time=3.33 ms
2外网可以访问内网的httpd服务
[root@congtou ~]# service httpd status 查看httpd服务状态
httpd (pid 4238 4237 4236 4235 4234 4233 4232 4231 4229) is running...
[root@congtou ~]# cd /var/www/html/
[root@congtou html]# ls
[root@congtou html]# vim index.html
[root@congtou html]# elinks 127.0.0.1 自己先测试下看httpd服务是否运行正常

显示出测试页面表示正常
在配置iptables前先在10.0.3.100客户端测试下看下是什么结果
下图可以看出不行。无法连接到httpd服务器

[root@station23 ~]# iptables -A FORWARD -s 10.0.3.0/24 -d 10.0.2.100 \ 从10.0.3.0网段来到10.0.2.100的基于tcp协议目标端口是80的全部接受
> -p tcp --dport 80 -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -d 10.0.3.0/24 -s 10.0.2.100 -p tcp --sport 80 -j ACCEPT与上面的相对应
[root@station23 ~]# iptables -L -n
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 8
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 0
ACCEPT tcp -- 10.0.3.0/24 10.0.2.100 tcp dpt:80
ACCEPT tcp -- 10.0.2.100 10.0.3.0/24 tcp spt:80
Chain OUTPUT (policy DROP)
target prot opt source destination
客户端测试

3外网可以访问内网的ftp服务, ftp服务只能在有请求时服务器才相应
这里我们要用到基于状态的扩展匹配
服务器自己测试
[root@congtou pub]# service vsftpd status 查看服务器ftp服务的状态
vsftpd (pid 4307) is running...
[root@congtou pub]# lftp 127.0.0.1
lftp 127.0.0.1:~> ls
drwxr-xr-x 2 0 0 4096 Mar 05 10:16 pub
lftp 127.0.0.1:/> cd pub
lftp 127.0.0.1:/pub> ls
-rw-r--r-- 1 0 0 0 Mar 05 10:16 aa
-rw-r--r-- 1 0 0 0 Mar 05 10:16 bb
-rw-r--r-- 1 0 0 0 Mar 05 10:16 cc
lftp 127.0.0.1:/pub> exit
客户端测试结果如下
[root@station7 shared]# lftp 10.0.2.100
lftp 10.0.2.100:~> ls
`ls' at 0 [Connecting...] 这里我们会发现虽然可以lftp进去但是却无法ls
在配置ftp状态规则是,我们需要添加以下ip_conntrack_ftp模块。如想开机挂载模块,需要编辑/etc/sysconfig/iptables-config这个文件,将所需要的模块名添加到 IPTABLES_MODULES=""中
[root@station23 ~]# vim /etc/sysconfig/iptables-config
# Load additional iptables modules (nat helpers)
# Default: -none-
# Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES=""
#
#
#
[root@station23 net]# modprobe ip_conntrack_ftp
[root@station23 ~]# iptables -A FORWARD -s 10.0.3.0/24 -d 10.0.2.100 -p \
> tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -s 10.0.2.100 -d 10.0.3.0/24 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -s 10.0.3.0/24 -d 10.0.2.100 -m \
> state --state ESTABLISHED,RELATED -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -d 10.0.3.0/24 -s 10.0.2.100 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@station23 ~]# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere icmp echo-request
ACCEPT icmp -- anywhere anywhere icmp echo-reply
ACCEPT tcp -- 10.0.3.0/24 10.0.2.100 tcp dpt:http
ACCEPT tcp -- 10.0.2.100 10.0.3.0/24 tcp spt:http
ACCEPT tcp -- 10.0.3.0/24 10.0.2.100 tcp dpt:ftp state NEW,ESTABLISHED
ACCEPT tcp -- 10.0.2.100 10.0.3.0/24 tcp spt:ftp state ESTABLISHED
ACCEPT all -- 10.0.3.0/24 10.0.2.100 state RELATED,ESTABLISHED
ACCEPT all -- 10.0.2.100 10.0.3.0/24 state RELATED,ESTABLISHED
[root@station23 ~]# iptables -A FORWARD -s 192.168.2.0/24 -d 192.168.3.100 \
> -p tcp --dport 80 -j ACCEPT
[root@station23 ~]# iptables -A FORWARD -d 192.168.2.0/24 -s 192.168.3.100 -p tcp --sport 80 -j ACCEPT
[root@station7 shared]# lftp 10.0.2.100
lftp 10.0.2.100:~> ls
drwxr-xr-x 2 0 0 4096 Mar 05 10:16 pub
lftp 10.0.2.100:/> ls
lftp 10.0.2.100:/pub> ls
-rw-r--r-- 1 0 0 0 Mar 05 10:16 aa
-rw-r--r-- 1 0 0 0 Mar 05 10:16 bb
-rw-r--r-- 1 0 0 0 Mar 05 10:16 cc
4.只允许内网访问firewall的ssh服务,
这里测试时会发现内外网均无法进入
[root@station7 shared]# ssh root@10.0.3.1
[root@congtou netfilter]# ssh root@10.0.2.1
[root@congtou netfilter]# ssh root@10.0.2.100
配置防火墙规则
[root@station23 ~]# iptables -A INPUT -s 10.0.2.100 -d 10.0.2.1 -p tcp --dport 22 -j ACCEPT
[root@station23 ~]# iptables -A OUTPUT -d 10.0.2.100 -s 10.0.2.1 -p tcp --sport 22 -j ACCEPT
[root@station23 ~]# netstat -tnulp | grep 22
tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 3696/hpiod
tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 3701/python
tcp 0 0 :::22 :::* LISTEN 3731/sshd
测试结果如下10.0.2.100可以ssh到firewall内,但10.0.3.100仍然无法进入
10.0.2.100的测试结果
[root@congtou netfilter]# ssh root@10.0.2.1
The authenticity of host '10.0.2.1 (10.0.2.1)' can't be established.
RSA key fingerprint is 93:e3:85:43:4f:43:9a:7b:71:2f:97:fb:3f:e9:f6:92.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.2.1' (RSA) to the list of known hosts.
root@10.0.2.1's password:
Last login: Fri Mar 5 17:37:12 2010
[root@station23 ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:54:4C:91
inet addr:10.0.2.1 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe54:4c91/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:133497 errors:0 dropped:0 overruns:0 frame:0
TX packets:322 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:24273511 (23.1 MiB) TX bytes:38337 (37.4 KiB)
Interrupt:67 Base address:0x2024
10.0.3.100的测试结果
[root@station7 shared]# ssh root@10.0.3.1
………..
好的,这里我们只是简单的讨论了下iptales的用法,其中有很多的用法我们都还没说,例如非常重要的SNAT ,DNAT转换,字符匹配过滤,同是定义多端口,最大连接数限制,访问时间限制,匹配速率限制,还有就是现在企业中经常要用到的l7layer应用层过滤!!我们会在下次讨论这些非常重要有用的东东.