文章目录
iptables的原理与配置详解
简介
linux的包过滤功能,即linux防火墙,它由netfilter (内核)和 iptables(用户空间) 两个组件组成。
linux防火墙工具变化如下:ipfirewall—>ipchains—>iptables
- Linux 2.0版内核中,包过滤机制为ipfw,管理工具是ipfwadm。
- Linux 2.2版内核中,包过滤机制为ipchain,管理工具是ipchains。
- Linux 2.4版内核中,包过滤机制为netfilter,管理工具是iptables。
- Linux 3.1版内核中,采取daemon动态管理防火墙,管理工具是firewalld。
CentOS的变化
- centos6:防火墙由netfilter和iptables构成。其中iptables用于制定规则,又被称为防火墙的用户态;而netfilter实现防火墙的具体功能,又被称为内核态。简单地讲,iptables制定规则,而netfilter执行规则。
- centos7:防火墙在6.X防火墙的基础之上提出了新的防火墙管理工具,提出了区域的概念,通过区域定义网络链接以及安全等级。
以上两者的区别在于:
- centos6的防火墙模型(system-config-firewall)是静态的,策略被修改后需要重新加载策略配置才能生效;
- centos7的firewalld工具则可以动态管理防火墙,不需要重新加载防火墙配置,直接生效。
注: 本文介绍的是iptables,firewalld不在本篇的范围。
基本原理
iptables由netfilter/iptables组成,其中netfilter位于内核心起到真正的防火墙作用,iptables位于用户空间作为命令行修改工具。
-
所有访问都经过链(钩子),每个链里面有多个规则(rules),这些规则根据功能类型汇聚存放于表中(功能)。
-
当一个数据包到达一个链时,iptables就会从链中第一条规则开始检查,看该数据包是否满足规则所定义的条件。如果满足,系统就会根据 该条规则所定义的方法处理该数据包;否则iptables将继续检查下一条规则,如果该数据包不符合链中任一条规则,iptables就会根据该链预先定义的默认策略来处理数据包。
注意:
- IPTables中的规则是从上到下匹配的,一旦匹配成功(accept/reject)就不再继续往下匹配。
- IPTables链的默认规则是所有的规则执行完才会执行的。
概念
iptables规则由五张表五条链和规则组成。
tables(五张表):
-
filter 用于过滤,大多数是防火墙功能,不要用来修改。
-
nat 用于网络地址转换, 如SNAT, DNAT等。
-
mangle 给数据包做标记以修改分组数据的特定规则,如QoS,打tag等,其中Mark标记是记录于skbuf而不在包本身。
-
raw 独立于Netfilter连接跟踪子系统
-
security:表在Centos6里是没有的,它用于强制访问控制(MAC)的网络规则,用于security。
说明:
- tables由chains组成,而chains又由rules组成
- 表是有优先级的,由高到低的顺序是==raw --> mangle --> nat --> filter==
chains(五条链,亦称hook勾子):
-
每个表都有自己的一组内置链,用于还可以对链进行自定义。
-
对filter表来说,最重要的内置链是INPUT/OUTPUT/FORWARD。
-
对于NAT来说,最重要的内置链是PREROUTING和POSTROUTING。
包含关系: Netfilter -> iptables -> tables -> chains -> rule/policy
各个链会用到的表:
注: 自上而下顺序 | prerouting链 | input链 (本地) | output链 (本地) | forward链 (转发) | postrouting链 |
---|---|---|---|---|---|
raw表 | √ | √ | |||
mangle表 | √ | √ | √ | √ | √ |
nat表 | √ (DNAT,DMZ端口映射) | √ (CentOS7 Only) | √ | √ (SNAT) | |
filter表 | √ | √ | √ |
说明: 按表优先级进行处理,即顺序是raw --> mangle --> nat --> filter
数据包流向视图:
说明:
- 进入本机的包经过的链: PREROUTING -> INPUT
- 转发出去的包经过的链: PREROUTING -> FORWARD -> POSTROUTING, 注意要打开ip-forward。
- 从本机出去的包经过的链: OUTPUT -> POSTROUTING
- 以进入本机的包经过的链为例 ,实际依次会经过raw表的PREROUTING、mangle表的PREROUTING、nat表的PREROUTING、mangle表的INPUT和filter表的INPUT的规则(rules)。
- 注:CentOS的nat表里有INPUT链,而CentOS6没有。
iptables配置视图:
- 一般来说,运维最常用到的是filter表(用于过滤包),其次是nat表(用于端口映射或NAT),raw表和mangle很少用于。
- 配置时,需要先指定要修改哪个表,然后指定该表中的哪条链,再指定该链中的哪条规则。
- 例如,常用的表链使用如下:
- 入口的过滤是修改filter表INPUT链的rules(iptables里不需加-t参数,默认就是filter表)。
- 出口的过滤是修改filter表OUTPUT链的rules(iptables里不需加-t参数,默认就是filter表)。
- 转发的过滤是修改filter表FORWARD链的rules(iptables里不需加-t参数,默认就是filter表)。
- DNAT是修改nat表的PREROUTING链的rules(iptables里需加-t nat参数,指定修改nat表)。
- SNAT是修改nat表的POSTROUTING链的rules(iptables里需加-t nat参数,指定修改nat表)。
rules的写法
rules:
- rules包括一个条件和一个目标(target) 。
- rules是存放于某个表的某个链里面。
- iptables执行规则时,是从从规则表中从上至下顺序执行的,如果没遇到匹配的规则,就一条一条往下执行,如果遇到匹配的规则后,那么就执行本规则,执行后根据本规则的动作(accept, reject, log等),决定下一步执行的情况。
- 通常地,链的最后一条规则是拒绝所有包,也就是说拒绝所有其他不符合上述任何一条规则的数据包。需要确保该规则位于最后一行。
target:
- ACCEPT – 允许防火墙接收数据包 ,停止在执行本链或本表的执行。
- DROP – 防火墙丢弃包,不给任何回应。
- REJECT - 拒绝数据包通过,必要时给发送端回一个响应的信息,客户端可收到拒绝的信息。
- SNAT - 源地址转换,解决内网用户同一个公网地址上网的问题。
- MASQUERADE - SNAT的一种特殊形式,适用于动态的、临时会变的IP上。
- DNAT - 目标地址转换。
- REDIRECT - 在本机做端口映射。
- LOG - 在/var/log/messages中记录日志,然后把数据包传递给下一条规 。
- RETURN – 防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。
contrack
-
conntrack是一种状态跟踪和记录的机制,本身并不能过滤数据包,只是提供包过滤的依据。 有状态是一种过滤依据,无状态实际也是一种过滤依据。
conntrack共可以为连接标记五种状态,分别如下:
- NEW:新建连接请求的数据包,且该数据包没有和任何已有连接相关联。判断的依据是conntrack当前“只看到一个方向数据包(UNREPLIED)”,没有回包。
- ESTABLISHED:该连接是某NEW状态连接的回包,也就是完成了连接的双向关联。
- RELATED:匹配那些属于helper模块定义的特殊协议的网络连接,该连接属于已经存在的一个ESTABLISHED连接的衍生连接。简而言之,A连接已经是ESTABLISHED,而B连接如果与A连接相关,那么B连接就是RELATED。
- INVALID:匹配那些无法识别或没有任何状态的数据包。这可能是由于系统内存不足或收到不属于任何已知连接的ICMP错误消息,也就是垃圾包,一般情况下我们都会DROP此类状态的包。
- UNTRACKED: 这是一种特殊状态,或者说并不是状态。它是管理员在raw表中,为连接设置NOTRACK规则后的状态。这样做,便于提高包过滤效率以及降低负载。
-
说明:
- tcp握手中(syn, syn/ack, ack),当反方向也出现包的时候,即认为是ESTABLISHED。因此第二次握手之后就是ESTABLISHED了。
- 作为客户端时的应用程序所使用的端口多为动态端口,如果能够到达服务器,那么发送和接收双方向的udp/tcp/icmp数据包状态都是ESTABLISHED。
过程:进入本机的包
以本机为目标的包:
Step(步骤) | Table(表) | Chain(链) | Comment(注释) |
---|---|---|---|
1 | 进入接口 (比如, eth0) | ||
2 | mangle | PREROUTING | 这个链用来mangle数据包,比如改变TOS等 |
3 | nat | PREROUTING | 这个链主要用来做DNAT。不要在这个链做过虑操作,因为某 些情况下包会溜过去。 |
4 | 路由判断,比如,包是发往本地的,还是要转发的? | ||
5 | mangle | INPUT | 在路由之后,被送往本地程序之前,mangle数据包。 |
6 | filter | INPUT | 所有以本地为目的的包都要经过这个链,不管它们从哪儿 来,对这些包的过滤条件就设在这里。 |
7 | 到达本地程序了(比如,服务程序或客户程序) |
过程:从本机出去的包
从本机以出去的包(以本地为源):
Step | Table | Chain | Comment |
---|---|---|---|
1 | 本地程序(比如,服务程序或客户程序) | ||
2 | 路由判断,要使用源地址,外出接口,还有其他一些信息。 | ||
3 | mangle | OUTPUT | 在这儿可以mangle包。建议不要在这儿做过滤,可能有副作用。 |
4 | nat | OUTPUT | 这个链对从防火墙本身发出的包进行DNAT操作。 |
5 | filter | OUTPUT | 对本地发出的包过滤。 |
6 | mangle | POSTROUTING | 这条链主要在包DNAT之后进行实际的路由,离开本地之前,对包 mangle。有两种包会经过这里,防火墙所在机子本身产生的包,还有被转发的包。 |
7 | nat | POSTROUTING | 在这里做SNAT。但不要在这里做过滤,因为有副作用,而且有些包是会溜过去的,即使你用了DROP策略。 |
8 | 离开接口(比如:eth0) |
在OpenStack的网络管理中,通常一个虚拟机会有一个外网IP(如:115.100.XX.XX)和一个内网IP(如192.168.1.10),那么节点的iptables规则里面就会有类似这样的语句:
# 目标地址为115.100.XX.XX(外网IP)的数据包重定向到192.168.1.10(内网IP)
iptables -t nat -A PREROUTING -d 115.100.XX.XX -j DNAT --to-destination 192.168.1.10
# 从192.168.1.10发出的数据包,iptables会将其源地址修改为100.100.XX.XX
iptables -t nat -A POSTROUTING -s 192.168.1.10 -j SNAT --to-source 115.100.XX.XX
过程:转发的包
被转发的包:
Step | Table | Chain | Comment |
---|---|---|---|
1 | 进入接口(比如,eth0) | ||
2 | mangle | PREROUTING | mangle数据包,,比如改变TOS等。 |
3 | nat | PREROUTING | 这个链主要用来做DNAT。不要在这个链做过虑操作,因为某 些情况下包会溜过去。稍后会做SNAT。 |
4 | 路由判断,比如,包是发往本地的,还是要转发的。 | ||
5 | mangle | FORWARD | 包继续被发送至mangle表的FORWARD链,这是非常特殊的情况才会用到的。在这里,mangle发生在最初的路由判断之后, 在最后一次更改包的目的之前。 |
6 | filter | FORWARD | 包继续被发送至这条FORWARD链。只有需要转发的包才会走到这里,并且针对这些包的所有过滤也在这里进行。注意,所有要转发的包都要经过这里,不管是外网到内网的还是内网到外网的。 |
7 | mangle | POSTROUTING | 这个链也是针对一些特殊类型的包。这一步mangle是在所有更改包的目的地址的操作完成之后做的,但这时包还在本地上。 |
8 | nat | POSTROUTING | 这个链就是用来做SNAT的,当然也包括Masquerade(伪装)。但不要在这儿做过滤,因为某些包即使不满足条件也会通过。 |
9 | 离开接口(比如: eth0) |
维护命令
service iptables start ##启动
service iptables stop ##关闭
service iptables restart ##重启
service iptables status ##查看状态
service iptables save ##保存iptables配置到/etc/sysconfig/iptables
iptables -nvL ##查看规则
注意:
- Iptables服务配置文件: /etc/sysconfig/iptables-config
- Iptables规则保存文件: /etc/sysconfig/iptables
- 打开iptables转发: echo “1”> /proc/sys/net/ipv4/ip_forward
命令参考
查看规则
iptables -nvL --line #默认是filter表的链和规则
iptables -nvL --line -t nat #查看nat表的链和规则
#INPUT表默认策略是ACCEPT
:INPUT ACCEPT [0:0]
#FORWARD表默认策略是ACCEPT
:FORWARD ACCEPT [0:0]
#OUTPUT表默认策略是ACCEPT
:OUTPUT ACCEPT [0:0]
#允许进入的数据包只能是刚刚我发出去的数据包的回应,ESTABLISHED:已建立的链接状态。RELATED:该数据包与本机发出的数据包有关。
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#在INPUT表和FORWARD表中拒绝所有其他不符合上述任何一条规则的数据包。并且发送一条host prohibited的消息给被拒绝的主机。
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
命令格式
table | command | chain | Parameter | target | |
---|---|---|---|---|---|
iptables | -t filter nat | -A/-D 增加/删除规则 -I num 插入L -R num 替换 -P 默认策略 -F 清空 -X: 删除自定义空链 -Z 清空链和计数器 -n 用数字显示 -v 详细显示 -L 列出所有规则 | INPUT FORWARD OUTPUT PREROUTING POSTROUTING | -p tcp -s -d -i -o –sport –dport -m tcp state multiport | -j ACCEPT DROP REJECT DNAT SNAT |
命令参数
命令:
iptables [ -t 表名] 命令选项 [链名] [条件匹配] [-j 目标动作或跳转]
1. 表名
表名: filter, nat, mangle, raw
起包过滤功能的为表Filter,可以不填,不填默认为Filter
2. 命令选项
选项名 功能及特点
-A 在指定链的末尾添加(--append)一条新的规则
-D 删除(--delete)指定链中的某一条规则,按规则序号或内容确定要删除的规则
-I 在指定链中插入(--insert)一条新的规则,默认在链的开头插入
-R 修改、替换(--replace)指定链中的一条规则,按规则序号或内容确定
-L 列出(--list)指定链中的所有的规则进行查看,默认列出表中所有链的内容
-F 清空(--flush)指定链中的所有规则,默认清空表中所有链的内容
-N 新建(--new-chain)一条用户自己定义的规则链
-X 删除指定表中用户自定义的规则链(--delete-chain)
-P 设置指定链的默认策略(--policy)
-n 用数字形式(--numeric)显示输出结果,若显示主机的 IP地址而不是主机名
-v 查看规则列表时显示详细(--verbose)的信息
-V 查看iptables命令工具的版本(--Version)信息
-h 查看命令帮助信息(--help)
--line-number 查看规则列表时,同时显示规则在链中的顺序号
3. 链名
可以根据数据流向来确定具体使用哪个链,在Filter中的使用情况如下:
INPUT链 – 处理来自外部的数据。
OUTPUT链 – 处理向外发送的数据。
FORWARD链 – 将数据转发到本机的其他网卡设备上。
4. 条件匹配
条件匹配分为基本匹配和扩展匹配,拓展匹配又分为隐式扩展和显示扩展。
a)基本匹配包括:
-p 协议: tcp, udp,icmp, all
-s 源地址,可以使IP地址、网络地址、主机名
-d 目的地址
-i 输入接口
-o 输出接口
b)隐式扩展包括:
--sport 源端口
--dport 目标端口
--tcp-flags TCP标志: SYN,ACK,RST,FIN SYN
--syn SYN包
--icmp-type 8:echo-request 0:echo-reply
c)常用显式扩展
-m state --state NEW,ESTABLISHED,RELATED,INVALID 连接的状态检测(老版)
-m conntrack --ctstate ESTABLISHED,RELATED 连接的状态检测(新版)
-m multiport --source-ports 多个源端口
-m multiport --destination-ports 多个目的端口
-m multiport --ports 源和目的端口
-m limit --limit 3/minute 限速,每分钟3个数据包
-m limit --limit -burst 100 限速,最大不能超过100个数据包
-m connlimit --connlimit-above 10 多于10个表示满足条件取反要在选项前加!
-m iprange --src-range ip-ip 源ip范围
-m iprange --dst-range ip-ip 目的ip范围
-m mac --mac-source mac地址限制
-m string --algo [bm|kmp] 匹配算法
-m string --string “Pattern” 要匹配的字符串
-m recent --name 设定列表名称,默认为DEFAULT
-m recent --rsource 源地址,此为默认
-m recent --rdest 目的地址
-m recent --set 添加源地址的包到列表中
-m recent --update 每次建立连接都更新列表
-m recent --rcheck 检查地址是否在列表
-m recent --seconds 指定时间内,必须与—rcheck或—update同时使用
-m recent --hitcount 命中次数,必须与—rcheck或—update同时使用
-m recent --remove 在列表种删除相应地址
5. 目标值(-j)
数据包控制方式包括四种为:
ACCEPT:允许数据包通过。
DROP:直接丢弃数据包,不给出任何回应信息。
REJECT:拒绝数据包通过,必须时会给数据发送端一个响应信息。
LOG:在/var/log/messages 文件中记录日志信息,然后将数据包传递给下一条规则。
QUEUE:防火墙将数据包移交到用户空间
RETURN:防火墙停止执行当前链中的后续Rules,并返回到调用链(the calling chain)
LOG日志例子:
iptables -I INPUT 1 -j LOG
tail -f /var/log/messages
实际命令例子
##查看iptables规则
iptables -nvL --line
设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
增删改规则
## 删除iptables现有规则
iptables -F
##增加一条规则到最后
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
##增加一条规则到最后到指定位置
iptables -I INPUT 2 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
##修改一条规则
iptables -R INPUT 3 -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
##删除一条规则
iptabels -D INPUT 2
IP的屏蔽等操作
##屏蔽某个IP地址
屏蔽具体IP地址:
iptables -A INPUT -s xxx.xxx.xxx.xxx -j DROP
##解封某个IP地址
要解封对IP地址的屏蔽,可以使用如下命令进行删除:
iptables -D INPUT -s xxx.xxx.xxx.xxx -j DROP
##在规则中使用IP地址范围
iptables -A OUTPUT -p tcp -d 192.168.100.0/24 --dport 22 -j ACCEPT
##屏蔽指定MAC地址
iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP
##限制ping 192.168.146.3主机的数据包数,平均2/s个,最多不能超过3个
iptables -A INPUT -i eth0 -d 192.168.146.3 -p icmp --icmp-type 8 -m limit --limit 2/second --limit-burst 3 -j ACCEPT
端口相关
##阻止特定的传出连接:
iptables -A OUTPUT -p tcp --dport xxx -j DROP
##阻止特定的传入连接:
iptables -A INPUT -p tcp --dport xxx -j DROP
##使用Multiport控制多端口
使用 multiport 我们可以一次性在单条规则中写入多个端口,例如:
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --sports 22,80,443 -j ACCEPT
http相关
##允许HTTP请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
##屏蔽HTTP服务Flood攻击,将连接限制到每分钟100 个,上限设定为 200。
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/minute --limit-burst 200 -j ACCEPT
ssh相关
##允许远程主机进行SSH连接
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
##允许本地主机进行SSH连接
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INTPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
##限制SSH连接速率(默认策略是DROP)
iptables -I INPUT 1 -p tcp --dport 22 -d 192.168.146.3 -m state --state ESTABLISHED -j ACCEPT
iptables -I INPUT 2 -p tcp --dport 22 -d 192.168.146.3 -m limit --limit 2/minute --limit-burst 2 -m state --state NEW -j ACCEPT
conntrack相关
##允许建立相关连接, 随着网络流量的进出分离,要允许建立传入相关连接,可以使用如下规则:
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
##允许建立传出相关连接的规则:
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
##丢弃无效数据包,很多网络攻击都会尝试用黑客自定义的非法数据包进行尝试,我们可以使用如下命令来丢弃无效数据包:
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
nat相关(nat表)
##SNAT(网域网主机隐藏内网IP,换为公网IP访问互联网,固定公网地址)
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source <公网IP>
##MASQUERADE(网域网主机隐藏内网IP,换为公网IP访问互联网)
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
##DNAT(公司只有一个公网IP但有多台服务器,需要从外面访问各个服务)
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination <私网IP>:<端口号>
#进来时做DNAT
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source <公网IP> #出去时能走公网
##在本地进行目标端口映射(外面访问本机80端口,重定向到本机8080上)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
PING相关
##禁止PING
iptables -A INPUT -p icmp -i eth0 -j DROP
##允许本机 ping 别的主机;但不开放别的主机 ping 本机;
iptables -I INPUT -p icmp --icmp-type echo-request -j DROP
iptables -I INPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -I INPUT -p icmp --icmp-type destination-Unreachable -j ACCEPT
其他
##限制并发连接数
iptables -A INPUT -p tcp --syn --dport 22 -m connlimit --connlimit-above 3 -j REJECT
##周一不允许访问
iptables -A INPUT -p tcp --dport 80 -m time ! --weekdays Mon -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT
##web包含admin字符串的页面不允许访问,源端口:dport
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --string 'admin' -j REJECT
##在工作时间,即周一到周五的8:30-18:00,开放本机的ftp服务给192.168.1.0网络中的主机访问;
iptables -A INPUT -p tcp --dport 21 -s 192.168.1.0/24 -m time ! --weekdays 6,7 -m time --timestart 8:30 --timestop 18:00 -m connlimit --connlimit-above 5 -j ACCET