一、概念
iptables只是Linux防火墙的管理工具而已。真正实现防火墙功能的是netfilter,它是Linux内核中实现包过滤的内部结构。
1. 链
链是一些按顺序排列的规则的列表。
默认情况下,任何链中都没有规则。可以向链中添加自己想用的规则。链的默认规则通常设置为 ACCEPT,如果想确保任何包都不能通过规则集,那么可以重置为 DROP。
默认的规则总是在一条链的最后生效,所以在默认规则生效前数据包需要通过所有存在的规则。
- 5种链说明如下:
PREROUTING链——对数据包作路由选择前应用此链中的规则(所有的数据包进来的时侯都先由这个链处理)
INPUT链——进来的数据包应用此规则链中的策略
OUTPUT链——外出的数据包应用此规则链中的策略
FORWARD链——转发数据包时应用此规则链中的策略
POSTROUTING链——对数据包作路由选择后应用此链中的规则(所有的数据包出来的时侯都先由这个链处理)
2. 表
表由一组预先定义的链组成。
filter表——用于存放所有与防火墙相关操作的默认表。通常用于过滤数据包。
nat表——用于网络地址转换
mangle表——用于处理数据包
raw表——用于配置数据包,raw 中的数据包不会被系统跟踪。
3. 链和表的关系及顺序
PREROUTING: raw -> mangle -> nat
INPUT: mangle -> filter
FORWARD: mangle -> filter
OUTPUT: raw -> mangle -> nat -> filter
POSTROUTING: mangle -> nat
4. 实际使用中是从表作为操作入口;表和链的关系
raw 表:PREROUTING,OUTPUT
mangle表:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat 表:PREROUTING,OUTPUT,POSTROUTING
filter 表:INPUT,FORWARD,OUTPUT
5. target
ACCEPT: 允许数据包通过
DROP:直接丢弃数据包,不给任何回应信息
REJECT:拒绝数据包通过,需要时会给数据发送端一个相应信息
SNAT:原地址转换,解决内网用户用同一个公网地址上网的问题
MASQUERADE:是 SNAT 的一种特殊形式,适用于动态的、临时会变的 ip 上
DNAT:目标地址转换
REDIRECT:在本机做端口映射
LOG:在/var/log/messages 文件中记录日志信息。然后将数据包传递给下一条规则。也就是只记录不做任何操作。
- REJECT 其他参数
--reject-with
:可以设置提示信息,拒绝时的提示信息
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable,
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited
当不设置任何值时,默认值为icmp-port-unreachable。
用法:
# iptables -t filter -I INPUT 2 -j REJECT --reject-with icmp-host-unreachable
- LOG
只记录匹配到的报文信息。
在配置文件 /etc/rsyslog.conf 中加入下面一行。重启服务即可。
kern.warning /var/log/iptables.log
# service rsyslog restart
- LOG 参数
--log-level
选项可以指定记录日志的日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug。
--log-prefix
选项可以给记录到的相关信息添加"标签"之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤。
示例:
比如,我想要将主动连接22号端口的报文的相关信息都记录到日志中,并且把这类记录命名为"want-in-from-port-22",则可以使用如下命令
# iptables -t filter -I INPUT -p tcp -m state --state NEW -j LOG --log-prefix "want-in-from-port-22"
- SNAT
配置SNAT,可以隐藏网内主机的IP地址,也可以共享公网IP,如果只是共享IP的话,只配置如下SNAT规则即可。
示例:
# iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 123.43.11.2
如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作。
# iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
6. 数据通过防火墙流程
二、表相关操作
1. 表查看
查看表中规则 iptables -t table_name -L [chain_name]
示例:
root@kvm:~# iptables -t filter -L
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
上面示例可以看到有哪些链是支持过滤的
在不指定表时默认查询 filter 表 iptables -L [chain_name]
(注意大小写)
示例:
root@kvm:~# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
2. 其他参数说明
参数 | 说明 | 示例 |
---|---|---|
-L |
列出规则 | 如下 |
--table -t |
要操作哪个表(不写-t, 默认表:filter) | iptables -t raw -L |
--verbose -v |
查看链详细信息;详细信息中字段对应的意思:pkts : 对应规则匹配到的报文个数;bytes : 对应匹配到的报文包的大小总和;target :规则对应的target,表示规则对应的『动作』,即规则匹配成功后要采取的措施;prot :表示规则对应的协议,是否针对某些协议应用此规则;opt :表示规则对应的选项;in :表示数据包由哪个接口(网卡)流入,可以设置通过哪块网卡流入的报文需要匹配当前规则;out :表示数据包由哪个接口(网卡)流出,可以设置通过哪块网卡流出的报文需要匹配当前规则;source :表示规则对应的源头地址,可以是一个 IP,也可以是一个网段;destination :表示规则对应的目标地址。可以是一个 IP,也可以是一个网段;第一行信息意思: policy : 表示当前默认策略,如:polict ACCEPT ;类似黑白名单的东西,默认是所有都可以通过;packets :表示当前链默认策略匹配到的包的数量,0 packets 表示默认策略匹配了0个;bytes :表示当前链默认策略匹配到的所有包的大小总和; |
iptables -vL INPUT |
--exact -x |
显示上面packets 和bytes 的详细大小 |
iptables -nvxL |
--numeric -n |
不对 IP 地址进行名称反解析,直接显示 IP | iptables -nvL |
--line-numbers --line |
查看的数据前面加上序号 | iptables --line-numbers -vL INPUT |
3. 表的增删改查
* 在表的开头添加规则 iptables -t table_name -I chain_name -s address/mask -j target
示例:
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.132 -j DROP
root@kvm:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 34 packets, 2706 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
* 在表的尾部追加一条数据 iptables -f table_name -A chain_name -s address/mask -j target
root@kvm:~# iptables -A INPUT -s 192.168.55.132 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 52 packets, 3722 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
这个时候在192.168.55.132这个主机上 ping 测试机是不通的。此时在表的首部在添加一个允许的操作
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.132 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 17 packets, 1738 bytes)
pkts bytes target prot opt in out source destination
2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
这个时候在192.168.55.132这个主机上 ping 测试机发现可以 ping 通
所以规则的顺序很重要
* 在指定位置插入规则 iptables -t table_name -I chain place_num -s address/mask -j target
示例:
root@kvm:~# iptables --line -vnL INPUT
Chain INPUT (policy ACCEPT 65 packets, 5684 bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
3 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
root@kvm:~# iptables -t filter -I INPUT 2 -s 10.0.0.1 -j ACCEPT
root@kvm:~# iptables --line -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 0 0 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3 11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
4 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
* 删除规则 iptables -t table_name -D chain_name line_number/rule
- 根据参数
--line-numbers
获取的序号删除
root@kvm:~# iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 1045 packets, 123K bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 0 0 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3 11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
4 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
- 删除指定编号的规则
root@kvm:~# iptables -t filter -D INPUT 3
root@kvm:~# iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 0 0 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
- 也可以根据规则匹配删除对应的规则
root@kvm:~# iptables -t filter -D INPUT -s 192.168.55.132 -j ACCEPT
- 删除链中所有规则
root@kvm:~# iptables -t filter -F
* 规则的修改iptables -t table_name -R INPUT chain_name rule_num rule
示例:
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 61 packets, 5450 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
root@kvm:~# iptables -t filter -R INPUT 1 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
关于链默认规则说明
当链的默认规则为 ACCEPT 时,设置的规则应该是
DROP
或REJECT
。因为不管报文是否被匹配到都会匹配ACCEPT,所以就是去了意义。
因此当链的默认规则是 ACCEPT 时,链中规则应该使用DROP
或REJECT
,表示只有匹配到规则的报文会被拒绝,没有匹配到的默认是放行的。也就是“黑名单”机制。
反之,当链的默认规则为 DROP 时,链中规则应该使用ACCEPT
,表示只有匹配到规则的才会放行,没有匹配到的将被禁用。也就是“白名单”机制。谨慎将链的规则改为 DROP,如果链内没有规则所有请求都将被拒绝
不能省略 -s
如果省略效果如下
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 61 packets, 5450 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
root@kvm:~# iptables -t filter -R INPUT 1 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
9 738 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
source 变为0.0.0.0/0 表示所有网段都被 ACCEPT
* 修改链的默认规则 iptables -t table_name -P chain_name target
示例
root@kvm:~# iptables -vnL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
root@kvm:~# iptables -t filter -P FORWARD DROP
root@kvm:~# iptables -vnL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
* 保存规则
默认情况下添加的规则都是临时的,当重启 iptables 或者重启系统时规则将丢失
ubuntu系统保存 iptables
iptables-save
centos 系统保存 iptables
service iptables save
;centos6需要提前安装iptables-services
* 自定义链 iptables -t table -N customize_chain_name
示例:
root@kvm:~# iptables -t filter -N TEXT
root@kvm:~# iptables -t filter -vnL
Chain INPUT (policy ACCEPT 9 packets, 738 bytes)
pkts bytes target prot opt in out source destination
20 1680 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 5
32 2688 REJECT icmp -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6 packets, 524 bytes)
pkts bytes target prot opt in out source destination
Chain TEXT (0 references)
pkts bytes target prot opt in out source destination
- 重新命名自定义链
iptables -E TEXT TEST
- 在其他链中引用自定义链
iptables -t filter -I INPUT -p tcp --dport 80 -j TEXT
- 删除自定义链
iptables -t filter -E TEST
;前提是没有引用自定义链且自定义链中规则为0 - 向自定义链中添加规则和默认相同;
* 参数说明
参数 | 说明 | 示例 |
---|---|---|
--flush -F chain |
删除某个链或所有链的规则 | iptables -F INPUT |
--inster -I chain [rulenum] |
插入规则(表第一行插入) | iptables -t filter -I INPUT -s 192.1.68.12.23 -j DROP |
--source -s address[/mask] |
指定条件(例中 -s 指定的是源 ip 地址) | iptables -t filter -I INPUT -s 192.1.68.12.23 -j DROP |
--jump -j target |
当-s 条件满足时要做的动作;常用动作如下;ACCEPT : 允许数据包通过;DROP :直接丢弃数据包,不给任何回应信息;REJECT :拒绝数据包通过,需要时会给数据发送端一个相应信息 |
iptables -t filter -I INPUT -s 192.1.68.12.23 -j DROP |
--append -A chain |
添加一条规则(在表的尾部) | iptables -A INPUT -s 192.1.68.12.23 -j DROP |
--delete -D chain rulenum |
删除规则 | iptables -t filter -D INPUT 3 |
--flush -F [chain] |
删除链中所有规则 | iptables -f filter -F INPUT |
--replace -R chain rulenum |
修改规则 | iptables -t filter -R INPUT 1 -j ACCEPT |
--policy -P chain target |
修改链的默认规则 | iptables -t filter -P INPUT DROP |
--destination -d address[/mask] |
指定目标ip或端口等规则 | iptables -t filter -I INPUT -s 10.1.1.1 -d 10.1.2.2 -j ACCEPT |
--protocol -p proto |
指定协议(示例,拒绝 tcp)默认所有协议均可使用 | iptables iptables -t filter -I INPUT -s 10.1.1.1 -d 10.1.1.2 -p tcp -j REJECT |
--in-interface -i input name |
定制网卡接口 | iptables -t filter -I INPUT -i eth2 -p icmp -j DROP |
--match -m match |
指定模块 | |
--new -N chain |
自定义链 | iptables -t filter -N TEST |
--delete-chain -X chain |
删除自定义链,前提没有引用且自定义链中规则为0 | iptables -t filter -X TEST |
--rename-chain -E old-chain new-chain |
修改链名 | iptables -t filter -E TEXT TEST |