iptables 理论与实践总结
一. 简介
iptables 是 Linux 下优秀的地址 nat+防火墙管理工具, 底层是 linux 内核通过 netfilter 模块来实现。 对linux而言 tcp/ip 协议栈是在内核当中, 意味着报文的处理是在内核中处理的, 也就是说防火墙必须在工作在内核中, 防火墙必须在内核中完成 tcp/ip 报文所流进的位置, 用规则去检查, 才真正能工作起来。 网络中传输的包在到达目的地后会被重新组装, 防火墙会检查每个包的报文头部字段, 采取如下动作,这些动作会记录在log中, 后面会说明 iptables 的日志配置。
- 允许进入系统
- 进行转发
- 拒绝包(给源IP发送一条信息)
- 丢弃(不发送返回信息)
Iptables采用“表”和“链”的分层结构,数据包到达网卡(eth0),然后会经过几条“链路”,首先是PREROUTING链,所有的数据包进来的时侯都先由这个链处理,决定是否被状态跟踪机制处理 、数据包被标记、被转发出去,决定路由选择后如果是被转发了,就进入FORWARD链进行标记或过滤,如果是想要进入了localhost,则进入INPUT链进行标记或过滤,后面详细说明。
二. 对链的理解
链(chains)是数据包传播的路径(过滤点), 每一条链其实就是众多规则中的一个检查清单, 每一条链中可以有一条或数条规则。 当一个数据包到达一个链时, iptables 就会从链中第一条规则开始检查, 看该数据包是否满足规则所定义的条件。 如果满足, 系统就会根据该条规则所定义的方法处理该数据包; 然后 iptables 将继续检查下一条规则, 如果该数据包不符合链中任一条规则, iptables 就会根据该链预先定义的默认策略来处理数据包。
三. 对表的理解
表相当于一个类, 一个具有相同功能的集合, 统一取了一个名字,比如raw表,它的功能是跟踪处理数据的, 比如mangle表, 它的功能是给数据包设置标记的, 比如nat表, 它的功能是做地址转换的等等。
四. 数据包传输的过程
- 当一个数据包进入网卡时,它首先进入PREROUTING链,应用PREROUTING链的规则,然后内核根据数据包目的IP进行路由选择(判断该数据包应该发往何处)。
- 如果数据包的目的主机就是进入本机的(比如访问web服务),那么内核将其传给INPUT链进行处理(决定是否允许通过等),允许通过后再交给系统上层应用程序(比如Apache服务器)进行响应。数据包通过了INPUT链后,任何进程都会收到它,但是只有指定的进程才会响应。本机程序响应则会发送数据包,这些数据包会经过OUTPUT链,然后到达POSTROUTING链输出,在OUTPUT链和POSTROUTING链上也可以做相应的规则限定。
- 如果数据包的目标地址是其它非本地地址(比如没有公网IP的内网机器),且内核允许转发,数据包就会经过FORWARD链,应用FORWARD链规则,然后到达POSTROUTING链,应用POSTROUTING链规则,最后从网卡流出。
五. 链和表的关系
tables由chains组成,而chains又由rules组成。比如看iptables的文件 /etc/sysconfig/iptables 的内容。
*filter # filter表
:INPUT ACCEPT [0:0] # 这些是filter表的链
:FORWARD ACCEPT [0:0] # 这些是filter表的链
:OUTPUT ACCEPT [2048900196:1861095639663] # 这些是filter表的链
-A INPUT -s 61.233.17.0/255.255.255.0 -j ACCEPT # 这些是INPUT链的规则
六. 四个表(优先级由高到低)
规则表之间的处理优先顺序:Raw—》mangle—》nat—》filter
表定义
- raw:数据跟踪处理(RAW表可以应用在那些不需要做nat的情况下,以提高性能。如大量访问的web服务器)
- mangle:给数据包设置标记,高级修改
- nat:地址转换
- filter:设置过滤包的规则
表解释
- raw:两个链: PREROUTING、OUTPUT
- 作用:决定数据包是否被状态跟踪机制处理
- 内核模块:iptable_raw
- mangle:五个链:PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD
- 作用:修改数据包的服务类型、TTL、并且可以配置路由实现QOS
- 内核模块:iptable_mangle(设置策略时几乎都不会用到)
- nat:三个链:PREROUTING、POSTROUTING、OUTPUT
- 作用:用于网络地址转换(IP、端口)
- 内核模块:iptable_nat用来对数据包的IP地址进行修改。分为三种:SNAT(修改数据包中的源IP,通常用于伪装内部地址,常说的nat)、DNAT(修改目标IP,通常用于跳转)、PNAT(修改端口)
- filter:三个链:INPUT、FORWARD、OUTPUT
- 作用:过滤数据包
- 内核模块:iptables_filter
七. 五个链
- INPUT 依据链中的规则检查所有流入数据包,可用的表:mangle、filter
- OUTPUT 依据链中的规则检查流出数据包,可用的表:Raw、mangle、nat、filter
- FORWARD 依据链中的规则检查转发数据包,使用此链的策略,可用的表:mangle、filter
- PREROUTING 对数据包作路由选择前应用此链中的规则,注意:所有的数据包进来的时侯都先由这个链处理,可用的表:raw、mangle、nat
- POSTROUTING 对数据包作路由选择后应用此链中的规则,注意:所有的数据包出来的时侯都先由这个链处理,可用的表:mangle、nat
八. 数据包连接的四种状态
iptables是一个有状态的防火墙,可以根据状态来对数据包进行规则限制, iptables上一共有四种状态NEW、ESTABLISHED、INVALID、RELATED。这四种状态对于TCP、UDP、ICMP三种协议均有效
- NEW
NEW说明这个包是接收的第一个包, 比如一个SYN 包。 第一个包也可能不是SYN包, 但它仍会被认为是NEW状态。 - ESTABLISHED
ESTABLISHED状态在两个方向上都有数据传输,是一个已经建立连接的状态。只要发送并接到应答,这个连接就是ESTABLISHED的了。一个连接要从NEW变为ESTABLISHED,只需要接到应答包即可,ICMP的错误和重定向等信息包也被看作是ESTABLISHED,因为是所发出的信息的应答。 - INVALID
INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP错误信息。一般地,我们DROP这个状态的任何东西,因为防火墙认为这是不安全的东西。 - RELATED
RELATED比较复杂。当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED的了。换句话说,一个连接要想是RELATED的,首先要有一个ESTABLISHED的连接。这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是 RELATED的了, 当然前提是conntrack模块要能理解RELATED。ftp是个很好的例子,FTP-data 连接就是和FTP-control有关联的,如果没有在iptables的策略中配置RELATED状态,FTP-data的连接是无法正确建立的,还有其他的例子,比如,通过IRC的DCC连接。有了这个状态,ICMP应答、FTP传输、DCC等才能穿过防火墙正常工作。注意,大部分还有一些UDP协议都依赖这个机制。这些协议是很复杂的,它们把连接信息放在数据包里,并且要求这些信息能被正确理解。
九. TCP标志位
syn、syn+ack、ack、 fin、urg、psh、rst
iptables 命令的参数:
-A(append) # 在某一条链结尾附加一条规则。
-I(insert) # 插入规则,需要指定插入的位置(第几条),不指定时默认插入第一条。
-D(delete) # 从链中删除一条规则(通过规则的行号,通过)。
-X(delete-chain)# 删除自定义链。
-R(replace)# 替换规则列表中的某条规则(通过规则的行号)。
-L(list) # 列出当前配置规则。
-F(flush) # 清空所有规则。
-P(policy )# 定义默认策略。
-t(table) # 指定表(raw、managle、nat、filter)的规则,不写默认是filter。
-n(number) # 以数字形式显示地址、端口等信息。
-Z(zero) # 将指定表中的数据包计数器和流量计数器归零。
-v # 以更详细的方式显示规则信息,-vvv等,与-L他命令一起使用显示更多更详细的信息。
--line-numbers # 查看规则时,显示规则的行号,也就是第几行,在使用-R、-I参数时常用到。
十. 五个基本处理动作
-j
DROP: # 丢弃(不返回信息)
REJECT: # 拒绝(返回错误信息)
ACCEPT: # 允许
DNAT: # 目标地址转换 --to-dest IP
SNAT: # 源地址转换 --to-source IP
RETURN: # 返回主链继续匹配
REDIRECT: # 端口重定向
MASQUERADE: # 地址伪装
MARK: # 打标签
LOG: # 自定义链
十一. 数据包的模式检查
源IP、目的IP、使用接口、TCP,UDP,ICMP协议、端口号、TCP连接状态:NEW, ESTABLISHED, RELATED, INVALID
-s ip # 检查包的源ip
-d ip # 检查包的目的ip
-p tcp # 指定协议
--dport 80 # 目的端口
--sport 80 # 源端口
-i eth0 # 从eth0接受到的
-o eth1 # 从eth1发送的
! -s 192.168.0.1/24 # 某个网段取反
十二. iptables常用命令
- 用来配置iptables的规则(添加、删除等)
iptables
- 用来打印出当前正在使用着的规则(包括没有保存到iptables文件的部分),可以使用重定向的方式来保存到临时文件, 然后备份保存出来的文件。
iptables-save
iptables-save > /tmp/iptables.txt
- 重新加载服务
/etc/init.d/iptables reload
/etc/init.d/iptables restart
/etc/init.d/iptables stop
/etc/init.d/iptables start
- 将/tmp/iptables.txt文件中的规则都加载到内存中,但是还没有保存到/etc/sysconfig/iptables里面,所以还需要/etc/init.d/iptables save 来保存。
iptables-restore < /tmp/iptables.txt
十三. 常用技巧
- iptables命令是基于链(chain, 即过滤点)的方式的,防火墙规则的链按顺序应用于每一个网络包,链里面的规则做两件事:指定包匹配的条件、如果匹配则接下来的动作是什么。
- 保存的防火墙配置规则在/etc/sysconfig/iptables文件中,如果使用命令配置错误,可以reload配置文件来清空用命令配置的规则(/etc/init.d/iptables reload)
- 如果没有指定-t nat,则默认要创建filter规则。按照数据包的模式顺序逐条匹配,如果有匹配的,后面出现相同的则不再匹配了。如果没有规则,则使用默认动作(每个链拥有各自的默认动作)
- 用命令配置好了一条命令后,需要保存规则、重新加载才会永久生效。
1、/etc/init.d/iptables save
2、/etc/init.d/iptables reload 或者 /etc/init.d/iptables restart - 在iptables文件中的-m参数表示模块的意思,会自动添加进iptables文件中,比如用命令添加了规则 " iptables -A INPUT -p tcp --dport 22 -j ACCEPT ",则默认会生成这一条配置 " -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT "
- 所有的扩展模块匹配表示要使用-m来指定扩展模块的名称来引用,而每个扩展模块一般都会有自己特有的专用选项,在这些选项中,有些是必备的
- 端口之间必须是连续的,比如 -p tcp --sport 21-80
- 取反,非21-80的端口,比如 -p tcp --sport !21-80
- 检测报文中的标志位,比如 --tcp-flags SYN,ACK,RST,FIN, SYN
- icmp报文,--icmp-type:0 8 0:响应请求 8:回答请求
- -m comment --comment 给这条规则添加一个注释,例如
iptables -I INPUT 11 -p tcp -m tcp --dport 10050 -m comment --comment "zabbix_agentd listen " -j ACCEPT
- centos操作iptables
sudo yum -y install iptables-services
sudo systemctl enable iptables.service
sudo systemctl restart iptables.service
# 保存规则
service iptables save
- ubuntu操作iptables
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
sudo apt-get -y install iptables-persistent
# 保存规则
ptables-save > /etc/iptables/rules.v4
netfilter-persistent save
netfilter-persistent start
# 保存规则
sudo netfilter-persistent (start|stop|restart|reload|flush|save)
十四. 添加iptables的默认配置
添加任何配置前清空所有的配置
iptables -t raw -F
iptables -t raw -X
iptables -t raw -Z
iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -Z
iptables -t nat -F
iptables -t nat -X
iptables -t nat -Z
iptables -t filter -F
iptables -t filter -X
iptables -t filter -X
iptables -t raw -P PREROUTING ACCEPT
iptables -t raw -P OUTPUT ACCEPT
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P INPUT ACCEPT
iptables -t mangle -P FORWARD ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
iptables -t mangle -P POSTROUTING ACCEPT
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t filter -P FORWARD ACCEPT
iptables -t filter -P INPUT ACCEPT
iptables -t filter -P OUTPUT ACCEPT
配置默认策略之前,需要把特定的策略放开(ssh),--state RELATED,ESTABLISHED表示即便你设置策略路由的时候忘记了打开ssh的端口,只要不关闭终端,会话则不会断掉。
iptables -I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s 192.168.211.0/24 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 192.168.211.0/24 -p tcp --sport 22 -j ACCEPT