在 Internet 中,企业通过架设各种应用系统来为用户提供各种网络服务,如 Web 网站、电子邮件系统、FTP 服务器、数据库系统等。那么,如何来保护这些服务器,过滤企业不需要的访问甚至是恶意的入侵呢?
Linux 系统中的防火墙 netfilter 和 iptables 为了实现该目标而生。Linux 的防火墙体系主要工作在网络层,针对 TCP/IP 数据包实施过滤和限制,属于典型的包过滤防火墙(或称为网络层防火墙)。Linux 系统的防火墙体系基于内核编码实现, 具有非常稳定的性能和高效率,也因此获得广泛的应用。
IP 信息包过滤系统,它实际上由两个组件 netfilter 和 iptables 组成。主要工作在网络层,针对 IP 数据包,体现在对包内的 IP 地址、端口等信息的处理。
netfilter:
iptables:
iptables 的作用是为包过滤机制的实现提供规则,通过各种不同的规则,告诉 netfilter 对来自某些源,前往某些目的或具有某些协议特征的数据包应该如何处理,为了更加方便的组织和管理防火墙规则,iptables 采用了表和链的分层结构,所以它会对请求的数据包的包头数据进行分析,根据我们预先设定的规则进行匹配来决定是否可以进入主机。其中,每个规则表相当于内核空间的一个容器,根据规则集的不同用途划分为默认的四个表,在每个表容器内又包括不同的规则链,根据处理数据包的不同时机划分为五种链。
规则表
规则表的作用:容纳各种规则链
表的划分依据:防火墙规则的作用相似
规则链
规则链的作用:容纳各种防火墙规则
链的分类依据:处理数据包的不同时机
规则
规则的作用:对数据包进行过滤或处理
总结
表里有链,链里有规则
规则表 | 说明 |
---|---|
raw | 主要用来决定是否对数据包进行状态跟踪。包含两个规则链 OUTPUT、PREROUTING |
mangle | 修改数据包内容,用来做流量整形,给数据包设置标记。包含五个规则链 INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING |
nat | 负责网络地址转换,用来修改数据包中的源/目 IP 或端口。包含三个规则链 OUTPUT、PREROUTING、POSTROUTING |
filter | 负责过滤数据包,确定是否放行该数据包。包含三个链 PREROUTING、POSTROUTING、OUTPUT |
注:在 iptables 的四个规则表中,mangle 表和 raw 表的应用相对较少
规则链 | 说明 |
---|---|
INPUT | 处理入站数据包,匹配目标 IP 为本机的数据包 |
OUTPUT | 处理出站数据包,一般不在此链上做配置 |
FORWARD | 处理转发数据包,匹配流经本机的数据包 |
PREROUTING | 在进行路由选择前处理数据包,用来修改目的地址,做 DNAT。相当于把内网服务器的 IP 和端口映射到路由器的外网 IP 和端口上 |
POSTROUTING | 在进行路由选择后处理数据包,用来修改源地址,做 SNAT。相当于内网通过路由器 NAT 转换功能实现内网主机通过一个公网 IP 地址上网 |
raw -> mangle -> nat -> filter
入站数据(来自外界的数据包,且目标地址是防火墙本机)
PREROUTING -> INPUT -> 本机的应用程序
出站数据(从防火墙本机向外部地址发送的数据包)
本机的应用程序 -> OUTPUT -> POSTROUTING
注:
主机型防火墙主要使用 INPUT、OUTPUT 链,设置规则时一般要详细的指定到端口
网络型防火墙主要使用 FORWARD 链,设置规则时很少去指定到端口,一般指定到 IP 地址或者到网段即可
转发数据(需要经过防火墙转发的数据包)
PREROUTING -> FORWARD -> POSTROUTING
注:按第一条规则、第二条规则的顺序进行匹配处理,遵循 “匹配即停止” 的原则,一旦找到一条匹配规则将不再检查后续的其他规则,如果一直找不到匹配的规则,就按默认规则处理。
默认规则用 iptables -L 查看,规则链后面出现(policy ACCEPT)即是默认放行
默认策略不参与链内规则的顺序编排
-F 清空链时,默认策略不受影响
CentOS7 默认使用 firewalld 防火墙,没有安装 iptables。若想使用 iptables 防火墙,必须先关闭 firewalld 防火墙,再安装 iptables。
#关闭 firewalld 防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service
#安装 iptables 防火墙
yum -y install iptables iptables-services
#设置 iptables 开机启动
systemctl start iptables.service
systemctl enable iptables.service
iptables 防火墙的配置方法:
使用 iptables 命令行
使用 system-config-firewall,centos7 不能使用 centos6 可以使用
格式:
iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 控制类型]
注意事项:
不指定表名时,默认指 filter 表
不指定链名时,默认指表内的所有链
除非设置链的默认策略,否则必须指定匹配条件
选项、链名、控制类型使用大写字母,其余均为小写
对于防火墙,数据包的控制类型非常关键,直接关系到数据包的放行、封堵以及相应的日志记录等。在 iptables 防火墙体系中,最常用的几种控制类型如下:
ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给出任何回应信息
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应信息
LOG 在 /var/log/messages 文件中记录日志信息,然后将数据包传递给下一条规则
SNAT 修改数据包的源地址
DNAT 修改数据包的目的地址
MASQUERADE 伪装成一个非固定公网 IP 地址
注意:防火墙规则的 ”匹配即停止“ 对于 LOG 操作来说是一个特例,因为 LOG 只是一种辅助动作,并没有真正处理数据包。
匹配条件 | 说明 |
---|---|
-p | 指定要匹配的数据包的协议类型 |
-s | 指定要匹配的数据包的源 IP 地址 |
-d | 指定要匹配的数据包的目的 IP 地址 |
-i | 指定报文仅能够从指定的接口流入 |
-o | 指定报文仅能够从指定的接口流出 |
--sport | 指定源端口号 |
--dport | 指定目的端口号 |
管理选项 | 用法示例 |
---|---|
-A | 在指定链末尾追加一条新的规则 iptables -A INPUT |
-I | 在指定链中插入一条新的规则,未指定序号默认作为第一条 iptables -I INPUT |
-P | 设置指定链的默认策略规则 iptables -P OUTPUT ACCEPT |
-D | 根据规则编号删除规则 iptables -t nat -D INPUT |
-R | 修改、替换某一条规则 iptables -t nat -R INPUT |
-L | 列出指定链中所有的规则,若未指定链名,则列出表中的所有链 iptables -t nat -L |
-n | 所有字段以数字形式显示(比如任意 IP 地址是 0.0.0.0 而不是 anywhere,比如显示协议端口号而不是服务名)iptables -L -n,iptables -nL,iptables -vnL |
-v | 查看时显示更详细信息,常跟 -L 一起使用 |
-F | 清除指定规则链中所有规则,若未指定链名,则清空表中的所有链 iptables -F |
-X | 清空用户自定义链的规则,不影响其他链 iptables -X |
-Z | 清空链的计数器(匹配到的数据包的大小和总和)iptables -Z |
-S | 显示指定链的所有规则,某个具体规则后面跟编号 iptables -t nat -S,iptables -t nat -S POSTROUTING 1 |
--line-number | 列出规则时,显示其在链上的相应的编号 iptables -t nat -L -n --line-number / iptables -t nat -L --line-number |
添加新的防火墙规则时,使用管理选项 “-A”、"-I",前者用来追加规则,后者用来插入规则。
例如:若要在 filter 表 INPUT 链的末尾添加一条防火墙规则,可以执行以下操作(其中 “-p 协议名” 作为匹配条件)。
iptables -t filter -A INPUT -p icmp -j REJECT //不允许任何主机 ping 本主机,REJECT 拒绝
iptables -I INPUT 2 -p tcp --dport 22 -j ACCEPT //允许主机 ssh 端口流量经过
iptables -t filter -A INPUT -p tcp -j ACCEPT //允许任何主机 tcp 流量
iptables -I INPUT -p udp -j ACCEPT //允许任何主机 udp 流量
查看已有的防火墙规则时,使用管理选项 “-L”,结合 “–line-numbers” 选项还可显示各条规则在链内的顺序号。
例如:若要查看 filter 表 INPUT 链中的所有规则,并显示规则序号, 可以执行以下操作
iptables -t 表名 -n -L 链名 --line-numbers
#注意:不可以合写为-Ln
示例:
[root@localhost ~]# iptables -L INPUT --line-numbers //不指定表名默认 filter
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
2 ACCEPT all -- anywhere anywhere
3 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
4 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
5 REJECT tcp -- anywhere anywhere reject-with icmp-port-unreachable
当防火墙规则的数量较多时,若能够以数字形式显示地址和端口信息,可以减少地址解析的环节,在一定程度上加快命令执行的速度。
例如:若要以数字地址形式查看 filter 表 INPUT 链中的所有规则,可以执行以下操作
[root@localhost ~]# iptables -nL INPUT //"-n -L" 可合写为 "-nL"
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
[root@c7-1 ~]#iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 46283 packets, 117M bytes)
num pkts bytes target prot opt in out source destination
1 24 2016 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)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 33563 packets, 1381K bytes)
num pkts bytes target prot opt in out source destination
删除一条防火墙规则时,使用管理选项 “-D”。
例如,若要删除 filter 表 INPUT 链中的第五条规则,可以执行以下操作
iptables -D INPUT 5
[root@c7-1 ~]# iptables -L INPUT --line-numbers //剩四条规则
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
2 ACCEPT all -- anywhere anywhere
3 ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
4 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
清空指定链或表中的所有防火墙规则,使用管理选项 “-F”。
例如:若要清空 filter 表 INPUT 链中的所有规则,可以执行以下操作
[root@localhost ~]# iptables -F INPUT
[root@localhost ~]# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
注意:
若规则列表中有多条相同的规则时,按内容匹配只删除的序号最小的一条
按号码匹配删除时,确保规则号码小于等于已有规则数,否则报错
按内容匹配删数时,确保规则存在,否则报错
使用管理选项 “-F” 时,允许省略链名而清空指定表所有链的规则。
例如:执行以下操作分别用来清空 filter 表、nat 表、mangle 表
iptables -F
iptables -t nat -F
iptables -t mangle -F
注意:
-F 仅仅是清空链中的规则,并不影响 -P 设置的默认规则,默认规则需要手动进行修改
-P 设置了 DROP 后,使用 -F 一定要小心!可能会导致主机失连,此情况如果没有保存规则可重启主机解决
如果不写表名和链名,默认清空 filter 表中所有链里的所有规则
iptables 的各条链中,默认策略是规则匹配的最后一个环节。当找不到任何一条能够匹配数据包的规则时,则执行默认策略。默认策略的控制类型为 ACCEPT(允许)、DROP(丢弃)两种。
例如:执行以下操作可以将 filter 表中 FORWARD 链的默认策略设为丢弃,OUTPUT 链的默认策略设为允许。
iptables -t filter -P FORWARD DROP
iptables -P OUTPUT ACCEPT
#一般在生产环境中网络型防火墙和主机型防火墙时都要设置默认规则为 DROP,并设置白名单
需要注意的是,当使用管理选项 “-F” 清空链时,默认策略不受影响。因此若要修改默认策略,必须通过管理选项 “-P” 重新进行设置。另外,默认策略并不参与链内规则的顺序编排,因此在其他规则之前或之后设置并无区别。
在编写防火墙规则时,匹配条件的设置起着决定性的作用。只有清晰、准确地设置好匹配条件,防火墙才知道要对符合什么条件的数据包进行处理,避免 “误杀”。对于同一条防火墙规则,可以指定多个匹配条件,表示这些条件必须都满足规则才会生效。根据数据包的各种特征,结合 iptables 的模块结构,匹配条件的设置包括三大类:通用匹配、隐含匹配、显式匹配。
通用匹配也称为常规匹配,这种匹配方式可以独立使用,不依赖于其他条件或扩展模块。 常见的通用匹配包括协议匹配、地址匹配、网络接口匹配。
协议匹配:-p 协议名
地址匹配:-s 源地址、-d 目的地址 #可以是IP、网段、域名、空(任何地址)
接口匹配:-i 入站网卡、-o 出站网卡
例:
iptables -A FORWARD ! -p icmp -j ACCEPT //感叹号表示取反
iptables -I INPUT -p icmp -j DROP
iptables -A INPUT -s 192.168.80.11 -j DROP
iptables -I INPUT -i ens33 -s 192.168.80.0/24 -j DROP
要求以特定的协议匹配作为前提,包括端口、TCP 标记、ICMP 类型等条件。
--sport 源端口 --dport [目的端口] #可以是单个端口,也可以是端口范围
--sport 1000 匹配源端口是1000的数据包
--sport 1000:3000 匹配源端口是1000-3000的数据包
--sport :3000 匹配源端口是3000及以下的数据包
--sport 1000: 匹配源端口是1000及以上的数据包
注意:
--sport 和 --dport 必须配合 -p <协议类型> 使用
示例:
iptables -A INPUT -p tcp --sport 1000:3000 -j REJECT
iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT
iptables -I FORWARD -d 192.168.80.0/24 -p tcp --dport 24500:24600 -j DROP
iptables -A FORWARD -s 192.168.4.0/24 -p udp --dport 53 -j ACCEPT
iptables -A FORWARD -d 192.168.4.0/24 -p udp --sport 53 -j ACCEPT
iptables -A INPUT -s 192.168.4.0/24 -p tcp --dport 53 -j ACCEPT
--tcp-flags [TCP标记]
#丢弃 SYN 请求包,放行其他包
iptables -I INPUT -i ens33 -p tcp --tcp-flags SYN,RST,ACK SYN -j ACCEPT
--icmp-type [ICMP类型] #可以是字符串、数字代码
"Echo-Request"(代码为 8)表示请求
"Echo-Reply"(代码为 0)表示回显
"Destination-Unreachable"(代码为 3)表示目标不可达
关于其它可用的 ICMP 协议类型,可以执行 "iptables -p icmp -h" 命令查看帮助信息
示例:
iptables -A INPUT -p icmp --icmp-type 8 -j DROP #禁止其它主机 ping 本机
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT #允许本机 ping 其它主机
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT #当本机 ping 不通其它主机时提示目标不可达
iptables -A INPUT -p icmp -j REJECT #此时其它主机需要配置关于 icmp 协议的控制类型为 REJECT
要求以 " -m 扩展模块 " 的形式明确指出类型,包括多端口、MAC 地址、IP 范围、数据包状态等条件。
-m multiport --sports [源端口列表]
-m multiport --dports [目的端口列表]
示例:
iptables -A INPUT -p tcp -m multiport --dport 80,22,21,20,53 -j ACCEPT
iptables -A INPUT -p udp -m multiport --dport 53 -j ACCEPT
-m iprange --src-range [IP范围]
#禁止转发源地址位于 192.168.80.100-192.168.80.200 的 udp 数据包
iptables -A FORWARD -p udp -m iprange --src-range 192.168.80.100-192.168.80.200 -j DROP
-m mac --mac-source [MAC地址]
#禁止来自某 MAC 地址的数据包通过本机转发
iptables -A FORWARD -m mac --mac-source xx:xx:xx:xx:xx:xx -j DROP
-m state --state [连接状态]
常见的连接状态:
状态 | 说明 |
---|---|
NEW | 与任何连接无关的,还没开始连接 |
ESTABLISHED | 响应请求或者已建立连接的,连接态 |
RELATED | 与已有连接有相关性的(如 FTP 主被动模式的数据连接),衍生态,一般与 ESTABLISHED 配合使用 |
INVALID | 不能被识别属于哪个连接或没有任何状态 |
#禁止转发与正常 TCP 连接无关的非 --syn 请求数据包(如伪造的网络攻击数据包)
iptables -A FORWARD -m state --state NEW -p tcp ! --syn -j DROP
iptables -I INPUT -p tcp -m multiport --dport 80,22,21,20,53 -j ACCEPT
iptables -A INPUT -p udp -m multiport --dport 53 -j ACCEPT
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
#对进来的包的状态进行检测,已经建立 tcp 连接的包以及该连接相关的包允许通过
#比如我和你做生意,我们谈成了生意,到了支付的时候,就可以直接调用与这笔生意相关的支付功能
iptables -P INPUT DROP
局域网主机共享单个公网 IP 地址接入 Internet(私有 IP 不能在 Internet 中正常路由)。
源地址转换,根据指定条件修改数据包的源 IP 地址,通常被叫做源映射。
临时打开:
echo 1 > /proc/sys/net/ipv4/ip_forward
或
sysctl -w net.ipv4.ip_forward=1
永久打开:
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1 #将此行写入配置文件
sysctl -p #读取修改后的配置
注:还有一种方式静态路由,这个就比较麻烦
//配置 SNAT 策略,实现 snat 功能,将所有 192.168.100.0 这个网段的源 ip 改为 10.0.0.1
iptables -t nat -A POSTROUTING -s 192.168.100.0/24(内网IP或地址池) -o(出站) ens33(外网网卡) -j SNAT --to 10.0.0.1(外网IP或地址池)
或
iptables -t nat -A POSTROUTING -s 192.168.100.0/24(内网IP或地址池) -o(出站) ens33(外网网卡) -j SNAT --to-source 10.0.0.1-10.0.0.10(外网IP或地址池)
注意:括号内容为解释说明
iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o ens33 -j MASQUERADE
TIPS:
一个 IP 地址做 SNAT 转换,一般可以让内网 100 到 200 台主机实现上网。
在 Internet 中发布位于局域网内的服务器。
目的地址转换,根据指定条件修改数据包的目的 IP 地址,保证了内网服务器的安全,通常被叫做目的映射。
DNAT 需要配合 SNAT 使用,才能实现响应数据包的正确返回。
#把从 ens33 进来的要访问 web 服务的数据包目的地址转换为 192.168.100.20
iptables -t nat -A PREROUTING -i(入站) ens33(外网网卡) -d 10.0.0.1(外网IP) -p tcp --dport 80 -j DNAT --to 192.168.100.20(内网服务器IP)
或
iptables -t nat -A PREROUTING -i(入站) ens33(外网网卡) -d 10.0.0.1(外网IP) -p tcp --dport 80 -j DNAT --to-destination 192.168.100.20(内网服务器IP)
iptables -t nat -A PREROUTING -i ens33 -p tcp --dport 80 -j DNAT --to 192.168.100.20-192.168.100.30(地址池)
回包
iptables -t nat -A POSTROUTING -s 192.168.100.20(内网IP) -o(出站) ens37(外网网卡) -j SNAT --to 10.0.0.1(外网IP)
发布局域网内部的 OpenSSH 服务器,外网主机需使用 250 端口进行连接
iptables -t nat -A PREROUTING -i(入站) ens37(外网网卡) -d 10.0.0.1(外网IP) -p tcp --dport 250(外网远程端口) -j DNAT --to 192.168.100.20:22(内网IP和远程端口号)
在外网环境中使用 SSH 测试
ssh -p 250 [email protected]
ifconfig ens33
iptables -t nat -vnL #查看
iptables-save > /opt/ipt.txt
iptables-restore < /opt/ipt.txt
将 iptables 规则文件保存在 /etc/sysconfig/iptables 中,iptables 服务启动时会自动还原规则
iptables-save > /etc/sysconfig/iptables
systemctl stop iptables #停止 iptables 服务会清空掉所有表的规则
systemctl start iptables #启动 iptables 服务会自动还原 /etc/sysconfig/iptables 中的规则