防火墙加固

1. 概述

本文介绍防火墙的知识，包括防火墙的作用，分类，性能，iptables 和 firewalld。其中的重点为 iptables 和 firewalld。由于本文较长，阅读需要一定时间。

2. 防火墙

2.1 防火墙的作用

在计算机领域中，防火墙是用于保护信息安全的设备

防火墙会按照默认配置或用户自定义规则，允许或限制数据的传输

用于保护内网安全的一种设备

依据规则进行防护

用户定义规则

允许或限制外部访问

2.2 防火墙的分类

逻辑上：

主机防火墙：针对单个主机进行防护（服务个人）

网络防火墙：针对网络进行防护，处于网络边缘，防火墙的背后是本地局域网（服务集体）

物理上：

硬件防火墙：在硬件级别实现防火墙功能，另一部分基于软件，性能高，成本高。如：思科，华为，天融信

软件防火墙：应用软件处理逻辑运行于通用硬件平台上的防火墙，性能相较于硬件防火墙低，成本较低，对于 Linux 系统已自带，直接使用即可。如：WAF（主要用于截获所有 HTTP 数据或仅仅满足某些规则的会话，多见于云平台中）

2.3 防火墙的性能

吞吐量

并发连接

新建连接

时延

抖动

3. iptables

3.1 什么是 iptables

netfilter/iptables 可简称为 iptables，为 Linux 平台下的包过滤防火墙，是开源的，内核自带的，可以代替成本较高的 企业级硬件防火墙

iptalbes 能实现什么功能？

数据包过滤，即防火墙

数据包重定向，即转发

网络地址转换，即可 NAT

iptables 不是防火墙，是防火墙用户代理

用于把用户的安全设置添加到 “安全框架” 中

“安全框架” 是防火墙

netfilter 就是 “安全框架”

netfilter 位于内核空间中，是 Linux 系统核心层内部的一个数据包处理模块

iptables 是用于在用户空间对内核空间的 netfilter 进行操作的 命令行工具

注意：iptables 并不是防火墙的服务，真正的服务是由内核提供的，netfilter 才是真正的防火墙

3.2 iptables 工作原理

iptables 是按照规则 (rules) 来办事的，而规则就是运维人员所定义的条件

规则一般定义为 “如果数据包头符合这样的条件，就这样处理这个数据包”

规则存储在内核空间的 数据包过滤表 中

这些规则分别指定了源地址、目的地址，传输协议 (TCP、UDP、ICMP) 和服务类型 (HTTP、FTP) 等

当数据包与规则匹配时，iptables 就根据 规则所定义的方法 来处理这些数据包，比如放行 (ACCEPT)、拒绝 (REJECT)、丢弃 (DROP) 等

注意：配置防火墙主要工作就是对 iptables 规则进行添加、修改、删除等

3.3 iptables 中链的概念

netfilter 才是真正的防火墙，属于内核的一部分，要想让 netfilter 起到作用，我们就需要在内核中设置 “关口”，进出的数据报文都要通过这些关口，经检查，符合放行条件的准允放行，符合阻拦条件的则被阻止，于是就出现了 input 和 output 关口，在 iptables 中我们把关口叫做 链

根据上图，如果用户发送的报文中请求的服务器地址不是本机，而是其他服务器，就应该进行报文转发，这个转发就是内核所支持的 IP_FORWARD 功能 ，这个时候我们的主机类似于路由器功能，对应的还有 “路由前”，“转发”，“路由后”， 对应的英文就是：“PREROUTING”，“FORWARD”，“POSTROUTING” 。这就是 5 链

INPUT：处理入站数据包

OUTPUT：处理出站数据包

FORWARD：处理转发数据包 (主要是将数据包转发至本机其它网卡)。当数据报文经过本机时，网卡接收数据报文至缓冲区，内核读取报文 ip 首部，发现报文不是送到本机时（目的 ip 不是本机），由内核直接送到 forward 链做匹配，匹配之后若符合 forward 的规则，再经由 postrouting 送往下一跳或目的主机。

PREROUTING：在进行路由选择前处理数据包，修改到达防火墙数据包的目的 IP 地址，用于判断目标主机

POSTROUTING：在进行路由选择后处理数据包，修改要离开防火墙数据包的源 IP 地址，判断经由哪一接口送往下一跳

我们知道，防火墙的作用在于对经过的数据报文进行规则匹配，然后执行对应的 “动作”，所以数据包经过这些关口时，必须匹配这个关口规则，但是关口规则可能不止一条，可能会有很多，当我们 把众多规则放在一个关口上 时，所有的数据包经过都要进行匹配，那么就形成了一个要匹配的规则链条，我们也把 “链” 称作 “规则链

3.4 iptables 中表的概念

每个 “规则链” 上都设置了一串规则，这样的话，我们就可以把不同的 “规则链” 组合成能够完成某一特定功能的集合分类，而这个集合分类我们就称为表，iptables 中共有 5 张表。

filter：过滤功能，确定是否放行该数据包，属于真正防火墙，内核模块：iptables_filter

nat：网络地址转换功能，修改数据包中的源、目标 IP 地址或端口；内核模块：iptable_nat

mangle：对数据包进行重新封装功能，为数据包设置标记；内核模块：iptable_mangle

raw：确定是否对数据包进行跟踪；内核模块：iptables_raw

security：是否定义强制访问控制规则；后加上的

3.5 iptables 中链表的关系

我们在应用防火墙时是以表为操作入口的，只要在相应的表中的规则链上添加规则即可实现某一功能

那么我们就应该知道哪张表包括哪些规则链，然后在规则链上操作即可

filter 表可以使用哪些链定义规则：INPUT,FORWARD,OUTPUT

nat 表中可以使用哪些链定义规则：PREROUTING,OUTPUT,POSTROUTING,INPUT

mangle 表中可以使用哪些链定义规则：PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

raw 表中可以使用哪些链定义规则：PREROUTING,OUTPUT

注意：iptables 中表的优先级：raw->mangle->nat->filter (由高至低)

3.6 数据包流经 iptables 流程

3.7 iptables 规则匹配条件

3.71 基本匹配条件

源地址，目标地址，源端口，目标端口等

基本匹配使用选项及功能

Copy
-p 指定规则协议，tcp udp icmp all
-s 指定数据包的源地址，ip hostname
-d 指定目的地址
-i 输入接口
-o 输出接口
! 取反

基本匹配的特点是：无需加载扩展模块，匹配规则生效

3.72 扩展匹配条件

扩展匹配又分为 隐式匹配 和 显示匹配

扩展匹配的特点是：需要加载扩展模块，匹配规则方可生效。

隐式匹配的特点：使用 - p 选项指明协议时，无需再同时使用 - m 选项指明扩展模块以及不需要手动加载扩展模块；

显示匹配的特点：必须使用 - m 选项指明要调用的扩展模块的扩展机制以及需要手动加载扩展模块

隐式匹配选项及功能：

Copy
-p 匹配协议，如：tcp，udp
--sport 匹配报文源端口，可以给出多个端口，但只能是连续的端口范围
--dport 匹配报文目标端口，可以给出多个端口，但只能是连续的端口范围
--tcp-flags mask comp 匹配报文中的tcp协议的标志位
--icmp-type
0/0： echo reply 允许其他主机ping
8/0：echo request 允许ping其他主机

显式匹配选项及功能：（-m）

multiport：多端口

Copy
iptables -I INPUT -d 192.168.1.111 -p tcp -m multiport --dports 22,80 -j ACCEPT
//在INPUT链中开放本机tcp 22，tcp80端口
iptables -I OUTPUT -s 192.168.1.111 -p tcp -m multiport --sports 22,80 -j ACCEPT
//在OUTPUT链中开发源端口tcp 22，tcp80

iprange：多 IP 地址

Copy
iptables -A INPUT -d 192.168.1.111 -p tcp --dport 23 -m iprange --src-range 192.168.2.11-192.168.2.21 -j ACCEPT
//在INPUT链中开发多源IP地址
iptables -A OUTPUT -s 192.168.1.111 -p tcp --sport 23 -m iprange --dst-range 192.168.2.11-192.168.2.21 -j ACCEPT
//在OUTPUT链中开发多目的IP地址

time：指定访问时间范围

Copy
iptables -A INPUT -d 192.168.1.111 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 --time-stop 18:00:00 -j ACCEPT

iptables -A OUTPUT -s 192.168.1.111 -p tcp --sport 901 -j ACCEPT

string：字符串，对报文中的应用层数据做字符串模式匹配检测 (通过算法实现)

Copy
--algo {bm|kmp}：字符匹配查找时使用算法
--string "STRING": 要查找的字符串
--hex-string “HEX-STRING”: 要查找的字符，先编码成16进制格式

connlimit：连接限制，根据每个客户端 IP 作并发连接数量限制

Copy
--connlimit-upto n 连接数小于等于n时匹配
--connlimit-above n 连接数大于n时匹配

limit：报文速率限制

state：

追踪本机上的请求和响应之间的数据报文的状态。状态有五种：INVALID, ESTABLISHED, NEW, RELATED,UNTRACKED

Copy
--state state
NEW 新连接请求
ESTABLISHED 已建立的连接
INVALID 无法识别的连接
RELATED 相关联的连接，当前连接是一个新请求，但附属于某个已存在的连接
UNTRACKED 未追踪的连接

3.8 iptables 规则中的动作

iptables 规则中的动作常称为 target，分为基本动作和扩展动作

ACCEPT: 允许数据包通过

DROP: 直接丢弃数据包，不给任何回应信息

REJECT: 拒绝数据包通过，发送回应信息给客户端

SNAT: 源地址转换

解释 1：数据包从网卡发送出去的时候，把数据包中的源地址部分替换为指定的 IP，接收方认为数据包的来源是被替换的那个 IP 主机，返回响应时，也以被替换的 IP 地址进行。

解释 2：修改数据包源地址，当内网数据包到达防火墙后，防火墙会使用外部地址替换掉数据包的源 IP 地址（目的 IP 地址不变），使网络内部主机能够与网络外部主机通信

MASQUERADE: 伪装，类似于 SNAT，适用于动态的、临时会变的 ip 地址上，例如：家庭使用的宽带。用发送数据的网卡上的 IP 来替换源 IP，对于 IP 地址不固定场合使用

DNAT: 目标地址转换

解释 1：数据包从网卡发出时，修改数据包中的目的 IP，表现为你想访问 A，但因网关做了 DNAT，把所有访问 A 的数据包中的目的 IP 地址全部修改为 B, 实际最终访问的是 B。

解释 2：改变数据包目的地址，当防火墙收到来自外网的数据包后，会将该数据包的目的 IP 地址进行替换（源 IP 地址不变），重新转发到内网的主机

REDIRECT: 在本机做端口映射

LOG: 在 /var/log/message 文件中记录日志信息，然后将数据包传递给下一条规则

注意：路由是按照目的地址进行路由选择的，因此，DNAT 是在 PREROUTING 链上进行的，SNAT 是在数据包发出的时候进行的，因此是在 POSTROUTING 链上进行的

3.9 iptables 规则策略 / 思路

黑名单

没有被拒绝的流量都可以通过，这种策略下管理员必须针对每一种新出现的攻击，制定新的规则，因此不推荐

白名单

没有被允许的流量都要拒绝，这种策略比较保守，根据需要，主机主机逐渐开放，目前一般都采用白名单策略，推荐

制定 iptables 规则思路：

选择一张表，此表决定了数据报文 处理的方式

选择一条链，此链决定了数据报文 流经哪些位置

选择合适的条件，此条件决定了对数据报文 做何种条件匹配

选择处理数据报文的动作，制定相应的防火墙规则

3.10 iptables 基础语法结构

Copy
iptables [-t 表名] 管理选项 [链名] [条件匹配] [-j 目标动作或跳转]

不指定表名时，默认表示 filter 表，不指定链名时，默认表示该表内所有链，除非设置规则链的默认策略，否则需要指定匹配条件

3.11 iptables 常用命令

参数 | 作用
-P | 设置默认策略 -P INPUT (DROP|ACCEPT)
-F | 清空规则链
-L | 查看规则链
-A | 在规则链的末尾加入新规则
-I num | 在规则链的头部加入新规则
-D num | 删除某一条规则
-s | 匹配来源地址 IP/MASK，加叹号 "!" 表示除这个 IP 外。
-d | 匹配目标地址
-i 网卡名称 | 匹配从这块网卡流入的数据
-o 网卡名称 | 匹配从这块网卡流出的数据
-p | 匹配协议，如 tcp,udp,icmp
--dport num | 匹配目标端口号
--sport num | 匹配来源端口号

3.11.1 iptables 链管理

Copy
-N, --new-chain chain：新建一个自定义的规则链
-X, --delete-chain [chain]：删除用户自定义的引用计数为0的空链
-F, --flush [chain]：清空指定的规则链上的规则
-E, --rename-chain old-chain new-chain：重命名链；
-Z, --zero [chain [rulenum]]：置零计数器，注意：每个规则都有两个计数器（packets：被本规则所匹配到的所有报文的个数
bytes：被本规则所匹配到的所有报文的大小之和）
-P, --policy chain target 制定链表的策略(ACCEPT|DROP|REJECT)

3.11.2 iptables 规则管理

Copy
-A, --append chain rule-specification：追加新规则于指定链的尾部
-I, --insert chain [rulenum] rule-specification：插入新规则于指定链的指定位置，默认为首部
-R, --replace chain rulenum rule-specification：替换指定的规则为新的规则
-D, --delete chain rulenum：根据规则编号删除规则
-D, --delete chain rule-specification：根据规则本身删除规则

3.11.3 iptables 规则显示

Copy
-L, --list [chain]：列出规则
-v, --verbose：详细信息
-vv 更详细的信息
-n, --numeric：数字格式显示主机地址和端口号
-x, --exact：显示计数器的精确值，而非圆整后的数据
--line-numbers：列出规则时，显示其在链上的相应的编号
-S, --list-rules [chain]：显示指定链的所有规则

3.12 iptables 应用例子

iptables-services 安装 / 配置：

Copy
sudo apt-get install iptables* //安装

sudo systemctl start iptables.service //启动

sudo systemctl enable iptables.service //设置开机自启

sudo rpm -ql iptables-services //查看配置文件

iptables-save > /etc/sysconfig/iptables //保存规则

iptables-restore < /etc/sysconfig/iptables //重载

基本配置：

Copy
iptables -F
//删除现有规则

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
//配置默认链策略

配置白名单：

Copy
iptables -t filter -F
iptables -P INPUT DROP
iptables -t filter -I INPUT -p tcp --dport=22 -j ACCEPT
iptables -t filter -I INPUT -p tcp --dport=80 -j ACCEPT

配置黑名单：

Copy
iptables -P INPUT ACCEPT
iptables -F
iptables -t filter -A INPUT -s 192.168.2.20/24 -p tcp --dport 80 -j DROP

通过 lo 访问本机数据：

Copy
iptables -I INPUT -d 127.0.0.1 -p tcp --dport=9000 -i lo -j ACCEPT
iptables -I INPUT -i lo -j ACCEPT
//允许通过本地回环网卡访问本机

允许连接态产生衍生态：

Copy
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

3.12.1 filter 表应用案例

Copy
yum -y install httpd vsftpd sshd
systemctl start httpd vsftpd sshd
iptables -t filter -F
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j REJECT

iptables 标准流程：

Copy
iptables -F
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -s 192.168.2.0/24 -j ACCEPT #允许内网任何访问
iptables -A INPUT -p tcp --syn --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --syn --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --syn --dport 21 -j ACCEPT
iptables -A INPUT -j REJECT
modprobe nf_conntrack_ftp
iptables-save > /etc/sysconfig/iptables
vim /etc/sysconfig/iptables-config
// IPTABLES_MODULES="nf_conntrack_ftp

4. firewalld

4.1 什么是 firewalld

FireWalld 仅仅替代了 iptables service 部分，其底层还是使用 iptables 做为防火墙规则管理入口

动态防火墙

用于管理 netfilter 用户空间的工具

调用了 iptables 命令

4.2 zone 概念及作用

区域 (zone) 是 firewalld 预先准备好的防火墙策略集合，即 可策略模板 ，可以根据不同的应用场景进行切换

4.3 FireWalld 中 zone 分类

FireWalld 不同区域之间的差异主要是每个区域对待数据包的默认行为不同
Firewalld 默认共 9 个 zone，分别为：

block（拒绝）

dmz（非军事化）

drop（丢弃）

external（外部）

home（家庭）

internal（内部）

public（公开） Firewalld 默认区域

trusted（信任）

work（工作区）

4.4 Firewalld 语法

Copy
firewall-cmd [--zone=zone] 动作 [--permanent]

注意：如果不指定 --zone 选项，则为当前所在的默认区域，--permanent 选项为是否将改动写入到区域配置文件中

4.5 Firewalld 常用命令

参数 | 作用
--get-default-zone | 查询默认的区域名称
--set-default-zone=<区域名称> | 设置默认的区域，永久生效
--get-zones | 显示可用的区域
--get-services | 显示预先定义的服务
--get-active-zones | 显示当前正在使用的区域与网卡名称
--add-source= | 将来源于此 IP 或子网的流量导向指定的区域
--remove-source= | 不再将此 IP 或子网的流量导向某个指定区域
--add-interface=<网卡名称> | 将来自于该网卡的所有流量都导向某个指定区域
--change-interface=<网卡名称> | 将某个网卡与区域做关联
--list-all | 显示当前区域的网卡配置参数，资源，端口以及服务等信息
--list-all-zones | 显示所有区域的网卡配置参数，资源，端口以及服务等信息
--add-service=<服务名> | 设置默认区域允许该服务的流量
--add-port=<端口号 / 协议> | 允许默认区域允许该端口的流量
--remove-service=<服务名> | 设置默认区域不再允许该服务的流量
--remove-port=<端口号 / 协议> | 允许默认区域不再允许该端口的流量
--reload | 让 “永久生效” 的配置规则立即生效，覆盖当前的

4.6 Firewall 的状态

Copy
firewall-cmd --state
running
//查看状态
firewall-cmd --reload
success
//重新加载防火墙，中断用户连接，临时配置清除掉，加载配置文件中的永久配置
firewall-cmd --complete-reload
success
//重新加载防火墙，不中断用户的连接（防火墙出严重故障时使用）
firewall-cmd --panic-on
//紧急模式，强制关闭所有网络连接

4.7 FireWalld 中动作

4.7.1 动作中查看操作

Copy
firewall-cmd xxx
--get-icmptypes //查看支持的所有ICMP类型
--get-zones //查看所有区域
--get-default-zone //查看当前的默认区域
--get-active-zones //查看当前正在使用的区域
--get-services //查看当前区域支持的服务
--list-services //查看当前区域开放的服务列表
--list-services --zone=home //查看指定域开放的服务列表
--list-all //查看默认区域内的所有配置，类似与iptables -L -n
--list-all-zones //查看所有区域所有配置

4.7.2 更改区域操作

Copy
firewall-cmd xxx
--set-default-zone=work //更改默认的区域

4.7.3 新建规则

Copy
firewall-cmd xxx
--add-interface=eth0 //将网络接口添加到默认的区域内
--add-port=12222/tcp --permanent //添加端口到区域开放列表中
--add-port=5000-10000/tcp --permanent //将端口范围添加到开放列表中；
--add-service=ftp --permanent //添加服务到区域开放列表中（注意服务的名称需要与此区域支持的服务列表中的名称一致）
--add-source=192.168.1.1 //添加源地址的流量到指定区域
--add-masquerade //开启SNAT（源地址转换

4.7.4 删除规则

Copy
firewall-cmd xxx
--remove-service=http //在home区域内将http服务删除在开放列表中删除
--remove-interface=eth0 //将网络接口在默认的区域内删除
--remove-source=192.168.1.1 //删除源地址的流量到指定区域

4.7.5 改变规则

Copy
firewall-cmd xxx
--change-interface=eth1 //改变指定的接口到其他区域

4.7.6 查询规则

Copy
firewall-cmd xxx
--query-masquerade //查询SNAT的状态
--query-interface=eth0 //确定该网卡接口是否存在于此区域

4.7.7 端口转发

端口转发可以将指定地址访问指定的端口时，将流量转发至指定地址的指定端口。转发的目的如果不指定 ip 的话就默认为本机，如果指定了 ip 却没指定端口，则默认使用来源端口

Copy
//通过firewalld实现SNAT
firewall-cmd --add-masquerade --permanent
firewall-cmd --reload
//将80端口的流量转发至8080
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
//80端口的流量转发至
firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.2.20
//删除
firewall-cmd --remove-forwardport=port=80:proto=tcp:toaddr=192.168.2.20 --permanent
//将80端口的流量转发至192.168.2.20的8080端口
firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.2.20:toport=8080

5. iptables 与 firewalld 对比

firewalld 是 iptables 的前端控制器

iptables 静态防火墙，任一策略变更需要 reload 所有策略，丢失现有链接

firewalld 动态防火墙，任一策略变更不需要 reload 所有策略 将变更部分保存到 iptables, 不丢失现有链接

firewalld 提供一个 daemon 和 service，底层使用 iptables

firewalld 在使用上要比 iptables 人性化很多，即使不明白 “五张表五条链” 而且对 TCP/IP 协议也不理解也可以实现大部分功能

firewalld 使用区域和服务而不是链式规则

firewalld 默认是拒绝的，需要设置以后才能放行

iptables 默认是允许的，需要拒绝的才去限制

6. 总结

本文记录了防火墙的一些内容，包括防火墙的概念，iptables 和 firewalld，重点介绍了 iptables 和 firewalld，命令较多，不用全部记住。