Iptables
# 防火墙介绍
在计算机领域,防火墙是用于保护信息安全的设备,其会依照用户定义的规则,允许或限制数据的传输。
- 用于保护内网安全的一种设备。
- 依据规则进行防护。
- 用户定义规则。
- 允许或拒绝外部用户访问。
# 防火墙分类
逻辑上防火墙可以大体分为主机防火墙和网络防火墙。
网络防火墙主要面向服务集体,针对网络进行防护,处于网络边缘,防火墙背后是本地局域网。主机防火墙主要面向服务个人,针对于单个主机进行防护。
物理上防火墙可分为硬件防火墙和软件防火墙。
- 硬件防火墙即是在硬件级别实现防火墙功能,另一部分基于软件实现,其性能高,但硬件成本高。
- 例如:三层路由:H3C、华为、Cisco、深信服。
- 参考图:

- 软件防火墙则是应用程序级别的防火墙,其性能相低于硬件防火墙,但成本较低。
- 例如:iptables、firewalld、ufw (ubuntu fire wall)。
- Web应用防火墙(WAF):Web应用防火墙属于软件防火墙,它是针对Web网页防护的安全防护服务,主要用于截获所有HTTP数据或仅仅满足某些规则的会话,多见于云平台中,用于处理七层攻击、SQL注入等。
# iptables
iptables不是防火墙,是防火墙用户代理,用于把用户的安全设置添加到安全框架中,它是可以在用户空间对内核空间的netfilter进行操作的命令行工具。
netfilter即是安全框架(防火墙),它位于内核空间中,是Linux操作系统核心层内部的一个数据包处理模块。
# netfilter/iptables
netfilter/iptables可简称为iptables,为Linux平台下的包过滤防火墙,它是开源且内核自带的,可以代替成本较高的企业级硬件防火墙,能够实现如下功能:
- 数据包过滤,即防火墙,实现封端口、封IP。
- 数据包重定向,即转发,端口映射(转发)、IP映射。
- 网络地址转换,即NAT,实现NAT功能、共享上网。
平常我们使用iptables并不是防火墙的"服务",服务是由内核提供的。
# iptables执行过程
- 用户请求服务器的某个端口。
- 然后数据包会经过iptables防火墙。
- 防火墙会根据配置的规则,按顺序从上到下进行过滤。
- 如果规则匹配成功,即得到明确的允许或者拒绝,数据包就不会再向下匹配新规则了。
- 如果上面的规则没有匹配,会接着向下进行规则匹配,直到匹配到符合的规则。
- 如果配置的所有规则都没有匹配,则会根据默认规则决定是允许还是拒绝。
- iptables默认的默认规则是允许(accept)。
# 连接追踪机制
iptables具有追踪连接状态功能,也就是跟踪并记录连接状态的功能。
iptables默认规则为拒绝时,当用户访问一个iptables允许的端口,服务器如果想要回复该客户端则还需要为其设定一个放行的规则,如果有多个就要多个规则。
而连接追踪,就是为了实现当防火墙允许客户端向某端口通信时,与之相对的通信(例如服务端返回响应)都应该是可靠的,可以对其放行。这样就可以实现一条规则放行所有可信的通信,而不用多条规则。
# 四表五链
# 相关名词
表(table)
- 用于存放"链"的容器。
链(chain)
- 用于存放"规则"的容器。
规则(policy)
- 允许或拒绝等防火墙规则,防火墙中的最小单位。
# 四表
# filter表
负责主机防火墙功能,过滤流入或流出主机的数据包,一般用于允许或拒绝IP、端口。
对应的链:
- INPUT:负责过滤所有目标地址是本机地址的数据包,也就是处理进入到主机的数据包。
- FORWARD:负责转发流经过主机的数据包,起转发作用。
- OUTPUT:负责过滤所有源地址是本机地址的数据包,也就是处理从主机发出去的数据包。
# nat表
负责网络地址转换,即源IP或目的IP、源端口或目的端口的转换。一般用于实现共享上网(内网服务器通过NAT转发上网)、端口映射、IP映射等。
对应的链:
OUTPUT:用于改变主机发出的数据包的目的地址。
PREROUTING:在路由判断之前执行的规则,作用是改变数据包的目的地址、目的端口等。
- 例如:做IP端口映射时,将公网访问的80端口的数据包,通过端口转发到某主机的8080端口去。
POSTROUTING:在路由判断之后执行的规则,作用是改变数据包的源地址、源端口等。
- 例如:通过NAT上网时,将源地址转化为公网地址。
# raw表 (不常用)
有限级最高,设置raw时一般是为了不再让iptables做数据包的链接跟踪处理,提高性能。
- iptables是有状态的,即iptables对数据包有连接追踪(connection tracking)机制,而row是用来去除这种追踪机制的。
- RAW表只使用在PREROUTING链和OUTPUT链上、因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。
RAW表可以应用在那些不需要做nat的情况下,以提高性能,如大量访问的web服务器,可以让80端口不再让iptables做数据包的链接跟踪处理,以提高用户的访问速度。
# mangle表 (不常用)
一般用来修改IP数据包头信息,比如修改TTL值,同时也用于给数据包添加一些标记,从而便于后续其它模块对数据包进行处理,可以作用在所有链上。
# 五链
五链指INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING。
# 表链对应关系
表的处理优先级:raw > mangle > nat > filter
,优先级决定在同一链上,哪些表的更优先过规则。
表 | 链 |
---|---|
raw | PREROUTING、OUTPUT |
mangle | PREROUTING、POSTROUTING、INPUT、OUTPUT、FORWARD |
nat | PREROUTING、OUTPUT、POSTROUTING、INPUT |
filter | INPUT、FORWARD、OUTPUT |
# iptables安装
- 安装iptables管理程序。
# 安装iptables
yum install -y iptables-services
# 查看是否安装成功
rpm -ql iptables-services
2
3
4
5
- 加载防火墙相关模块到内核。
# 写添加内核模块命令到启动脚本(永久添加)
cat>>/etc/rc.local<<EOF
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
EOF
# 立即生效(临时添加)
modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state
# 查看是否生效
lsmod |egrep 'filter|nat|ipt'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- 启动iptables。
systemctl start iptables && systemctl enable iptables
# iptables动作
动作是指每条规则匹配时,需要执行的动作,iptables中常用动作有以下:
ACCEPT:允许通过防火墙。
DROP:不允许通过防火墙,直接丢弃该数据包,不返回拒绝信息。
REJECT:不允许通过防火墙,会返回拒绝信息。
LOG:记录日志信息,然后传给下一条规则继续匹配。
SNAT:源地址转换,需要配合 --to-source 参数使用,一般定义在POSTROUTING链中。
- 例如:
-j SNAT --to-source 地址或网段
- 例如:
DNAT:目标地址转换,需要配合--to-destination参数使用,一般定义在PREROUTING链中。
- 例如:
-j SNAT --to-destination 地址[:端口]
- 端口转发:
iptables -t nat -A PREROUTING -s [地址或网段] -p [协议] --dport [端口] -j SNAT --to-destination [目标地址:端口]
- IP转发:
iptables -t nat -A PREROUTING -s [地址或网段] -j SNAT --to-destination [目标地址]
- 端口转发:
- 例如:
# iptables命令
iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
# 查看参数
-L [链名]
- 列出指定的链的规则列表,如果没有指定链名则列出表中所有链的所有规则。
-n
- 不以服务名显示,而是直接显示IP端口。
--line-num
- 显示规则序号。
# 管理参数
# 链
-P [链名] [动作]
- 为指定的链设置默认策略,默认动作只能为ACCEPT和DROP。
只有内置的链才允许有策略,用户自定义的是不允许的。 如果是要从允许修改为拒绝,则该操作之前应当先添加SSH远程连接的允许规则,再修改默认规则,否则可能会把自己关在外面。
-F [链名] 清空指定的链上的所有规则,如果不指定链名则会清除当前表所有链
-N [自定义链名]
- 创建自定义链。
-E [原自定义链名] [新自定义链名]
- 修改自定义链链名。
-X [自定义链名]
- 删除自定义链,需要满足以下条件:自定义链没有被引用、自定义链中没有任何规则。
# 规则
-I [链名] [序号] [规则参数]
- 在指定链的指定序号位置插入指定规则,如果没有指定序号则默认插入到链最上面。
-A [链名] [规则参数]
- 在指定链的末尾插入指定规则。
-D [链名] [序号/规则参数]
- 在指定链中通过指定规则或指定序号删除规则。
# 动作
-j [动作名]
- 规则匹配时跳转到指定目标,也就是满足条件时执行什么样的动作。
# 匹配参数
-p [协议名]
- 指定要匹配的数据包协议类型,例如:TCP、UDP、ICMP等。
以下参数前面如果有**"!"**号则表示排除。
[!] -s IP地址[/mask]
- 匹配的源地址或网段。
[!] -d IP地址[/mask]
- 匹配的目标地址或网段。
[!] -i 网络接口名
- 匹配从指定网络接口流入的数据包。
[!] -o 网络接口名
- 匹配从指定网络接口流出的数据包。
[!] --sport 端口号
- 匹配的源端口号,必须同时使用-p参数指定协议名,且-p参数必须指定在-sport参数之前。
[!] --dport 端口号
- 匹配的目标端口号,必须同时使用-p参数指定协议名,且-p参数必须指定在-sport参数之前。
# 其他
-t [表名]
- 指定要操作的表名,如果没有指定则默认是filter。
-m [模块名]
引用指定模块。
常用模块:
multiport:使支持一次指定多个端口。
- 例如:
-m multiport --dport 10,20
表示匹配10和20的端口-m multiport --dport 10:20
表示匹配10到20的端口
- 例如:
state:使能够匹配连接状态。
-m state --state [连接状态]
连接状态
- NEW:已经或即将启动新的连接。
- ESTABLISHED:已建立连接。
- RELATED:正在启动的新连接。
- INVALID:非法或无法识别。
例如:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
limit:使能够限制数据包频率。 *
-m limit --limit n/{second,minute,hour}
每second/minute/hour允许请求n个数据包数,不指定则n默认是5个数据包。
例如:
iptables -A INPUT -m limit --limit 10/minute -j ACCEPT
# 配置保存与恢复
保存:iptables-save > [配置文件保存路径]
恢复:iptables-restore < [配置文件路径]
# 配置永久生效
iptables-save > /etc/sysconfig/iptables
将配置保存到 /etc/sysconfig/iptables 即可永久生效,重启会自动恢复规则。
# 注意事项
修改之前导出备份一份。
修改时小心,别把自己关外面,可以先在定时任务中添加一条定时清空的规则,等测试没有问题再取消定时任务。
# 端口测试命令
nc -kl 端口号
- 用于开启一个端口。
# 自定义链
# 介绍
自定义链类似于分组,主要用于解决不同服务的规则过多导致的阅读困难。
自定义链创建后,我们还需要在默认链中创建引用规则,自定义链才会生效。同时自定义链也可以引用其他自定义链。
# 使用方式
# 创建自定义链。
iptables -t filter -N CHAIN_HTTP
# 默认链中引用自定义链,这样当数据包匹配该引用规则后,便会跳转到自定义链中进行其中的规则匹配。
iptables -t filter -A INPUT -p tcp --dport 80 -j CHAIN_HTTP
# 删除自定义链
## 删除引用自定义链的规则。
iptables -t filter -D INPUT -p tcp --dport 80 -j CHAIN_HTTP
## 清空自定义链规则
iptables -t filter -F CHAIN_HTTP
## 删除自定义链
iptables -t filter -X CHAIN_HTTP
2
3
4
5
6
7
8
9
10
11
12
13
# 使用例子
# 允许SSH端口并禁止其他端口
# 先添加SSH端口的放行规则
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
# 再将默认规则改为DROP或REJECT
iptables -t filter -P INPUT DROP
2
3
4
# 禁止别人Ping自己
# "--icmp-type 8"表示请求包,如果不指定则所有ICMP相关的包都会拒绝,自己也就无法正常ping其他主机
iptables -t filter -I INPUT -p icmp --icmp-type 8 -j DROP
2
# 匹配网络状态(TCP/IP连接状态)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
2
# 限制并发及速率
iptables -A INPUT -m limit --limit 10/minute -j ACCEPT
# 实现共享上网
# iptables服务器开启forward内核转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# iptables开启SNAT转发,-s用于指定内网网卡的IP或IP段,--to-source用于指定出口网卡的IP
iptables -t nat -A POSTROUTING -s 192.168.20.0/24 -j SNAT --to-source 192.168.10.10
# 然后其他局域网主机将网关地址改为iptables服务器即可
2
3
4
5
6
7
8
局域网主机请求外网地址时,将请求发给iptables服务器,然后iptables服务器会根据SNAT转发规则,将数据包的源地址端口修改后再发出,响应数据包回来时再发送回对应的局域网主机。 NAT上网通过维护一张映射表来找到对应的主机。当数据包到达进行NAT的设备时,除了私有IP地址会被替换成公网IP地址外,端口号也会被替换成NAT随机生成的端口号。同时NAT设备维护一张随机端口号和源主机一一对应的映射表。当外网服务器返回数据到NAT设备时,NAT设备通过返回数据包中的端口号找到局域网中的源主机并将数据包发到对应主机的对应端口。
# 实现端口转发
# iptables服务器开启forward内核转发
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
# iptables开启DNAT转发
# iptables -t nat -A PREROUTING -s [地址或网段] -p [协议] --dport [端口] -j DNAT --to-destination [目标地址:端口]
iptables -t nat -A PREROUTING -s 192.168.10.0/24 -p TCP --dport 80 -j DNAT --to-destination 192.168.20.110:80
# 然后访问iptables服务器的指定端口,就会如同访问[目标地址:端口]一样了
2
3
4
5
6
7
8
9