防火墙(RHCE)
一、什么是防火墙
防火墙作为内部网络和外部网络之间的安全屏障,依照系统管理员预先设定的规则,对进出的数据包实施控制。
1. 防火墙的分类
防火墙主要涵盖硬件防火墙和软件防火墙:
- 硬件防火墙:由厂商精心设计的主机硬件设备,其操作系统聚焦于提供数据包过滤机制,去除了其他冗余功能,以此确保过滤性能的高效与稳定。
- 软件防火墙:本质上是一套保障系统网络安全的软件或机制。像 Netfilter 和 TCP Wrappers,都归属于软件防火墙类别。本文将着重介绍 Linux 系统自带的软件防火墙 Netfilter,它构建起了功能强大的数据包过滤机制。
2. Netfilter 数据包过滤机制
Netfilter 通过对进入主机的网络数据包展开分析,提取数据包头部数据进行研判,进而决定对连接执行放行或阻挡操作。由于该机制能够直接解析数据包头部信息,涉及硬件地址、软件地址,以及 TCP、UDP、ICMP 等各类数据包信息,应用范围极为广泛,主要针对 OSI 七层协议中的第 2、3、4 层开展分析。具体来说,Netfilter 能够实现以下分析功能:
- 端口访问控制:禁止特定端口的网络访问,阻止 Internet 数据包进入主机的某些端口。
- 源 IP 地址过滤:基于源 IP 地址进行访问控制,拒绝特定来源 IP 的数据包进入。
- 标志位过滤:过滤特定标志的数据包,最为常见的是拒绝带有 SYN 主动连接标志的数据包。
- MAC 地址分析:通过分析硬件地址(MAC)来决定是否允许连接 。
3. Netfilter 的局限性
尽管 Netfilter 功能强大,但在某些场景下,无法确保网络的绝对安全:
- 病毒与木马防护不足:假设主机开放了 Web 服务,防火墙必须开放 Web 服务端口给客户端。若 Web 服务器软件存在漏洞,或者请求 Web 服务的数据包本身包含病毒,防火墙将难以阻止。
- 对内部网络攻击防范乏力:防火墙对内部网络的规则设置通常较少,这使得内部员工可能滥用网络资源,或发动内部网络攻击。
4. 防火墙管理工具与内核机制
Netfilter 数据包过滤机制由 Linux 内核内置。不同的内核版本,使用的防火墙策略设置软件有所不同。在红帽 7 系统中,firewalld 服务取代了 iptables 服务。然而,iptables 和 firewalld 本质上都只是防火墙管理工具,用于定义防火墙策略、维护规则,真正执行规则对数据包进行处理的,是内核中的 Netfilter。
二、iptables
1. iptables 介绍
iptables 中,防火墙会按照从上到下的顺序读取配置的策略规则,一旦找到匹配项,便立即终止匹配,并执行该匹配项所定义的操作,即放行或阻止数据包。若读取完所有策略规则后仍未找到匹配项,将执行默认策略。通常,防火墙策略规则分为 “通”(放行)和 “堵”(阻止)两类。当防火墙默认策略为拒绝时,需设置允许规则,否则所有访问将被阻断;当默认策略为允许时,则需设置拒绝规则,以发挥防火墙的安全防护作用。
2. 规则链分类
iptables 服务将用于处理或过滤流量的策略条目称为规则,多条规则构成一个规则链。根据数据包处理位置的不同,规则链可分为以下几类:
- input 链:负责处理目标地址为本机的数据包。
- output 链:处理本机产生的数据包。
- forward 链:处理经过本机转发的数据包,即源地址和目的地址都不是本机的数据包。
- prerouting 链:在路由判断之前处理数据包,常用于网络地址转换(DNAT)。
- postrouting 链:在路由判断之后处理数据包,常用于源网络地址转换(SNAT)。
3. 表的分类
为了对规则链中的规则进行分类管理,iptables 引入了表的概念,主要包括以下几种表:
- filter 表:用于过滤数据包,决定数据包的放行或丢弃,是 iptables 的默认表。该表主要应用于 input、forward 和 output 链。
- nat 表:负责网络地址转换,可修改数据包的 IP 地址和端口号,实现源网络地址转换(SNAT)和目的网络地址转换(DNAT)。nat 表主要应用于 prerouting、postrouting 和 output 链。
- mangle 表:用于修改数据包的头部信息,可拆解报文、进行修改后重新封装。mangle 表可应用于 prerouting、postrouting、output、input 和 forward 链。
- raw 表:用于决定数据包是否被状态跟踪机制处理,在匹配数据包时,raw 表的规则优先级高于其他表。raw 表主要应用于 prerouting 和 output 链。
4.iptables命令解析
iptables命令可以根据流量的源地址、目的地址、传输协议、服务类型等信息进行匹配,一旦匹配成功,iptables就会根据策略规则所预设的动作来处理这些流量
语法格式:iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源
、IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
参数说明:
启动 iptables 准备工作:
#1. 要停止 `firewalld`,请以 `root` 用户身份输入以下命令:
#2. 要防止 `firewalld` 在系统启动时自动启动:
#3. 要确保访问 `firewalld` `D-Bus`接口时未启动firewalld,并且其他服务需要 `firewalld` 时也未启动 firewalld :
[root@kittod ~]# systemctl stop firewalld
[root@kittod ~]# systemctl disable firewalld
[root@kittod ~]# systemctl mask firewalld
#系统不会默认安装这个iptables
systemctl status iptables.service
#firewalld是系统会默认安装的
systemctl status firewalld
#如果想用iptables需要安装
dnf install iptables-services -y
#运行iptable之前需要把firewall服务关掉
systemctl disable --now firewalld
#为了防止启动,把firewalld锁定.锁定之后就开不了了
systemctl start firewalld
#启动iptables
systemctl enable --now iptables.service
systemctl status iptables.service
5. 表(tables)—— 对链里的规则进行分类
iptables 通过不同的表对规则链中的规则进行分类管理,主要包含以下四种表:
5.1 filter 表
filter 表用于过滤数据包,决定数据包的放行或丢弃,是 iptables 的默认表。该表涵盖 INPUT、FORWARD 和 OUTPUT 链。
- 阻止特定 IP 地址的所有流量:
iptables -t filter -A INPUT -s 192.168.1.100 -j DROP
此命令默认向 INPUT 链添加过滤规则,且该规则位于 filter 表中。
- 允许特定子网的 SSH 连接:
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
- 拒绝所有传入的 TCP 数据包,仅允许已建立连接的数据包通过:
iptables -A INPUT -p tcp ! --syn -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
5.2 nat 表
nat 表用于网络地址转换,可修改数据包的 IP 地址和端口号,实现源地址转换(SNAT)和目标地址转换(DNAT)。该表包含 PREROUTING、POSTROUTING 和 OUTPUT 链。
- 将内部网络请求映射到公网 IP 的特定端口:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080
- 将所有传入的 HTTP 请求重定向到另一台服务器的 8080 端口:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
- 实现端口转发,将外部网络的 80 端口映射到内部服务器的 8080 端口:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080
- 使用 MASQUERADE 进行地址伪装:系统会选择一个合适的本地 IP 地址进行伪装。若所有本地 IP 地址均已分配,MASQUERADE 将无法工作,iptables 会拒绝相应数据包。
iptables -t nat -A POSTROUTING -j MASQUERADE
5.3 mangle 表
mangle 表用于修改数据包的头部信息,拆解报文、进行修改后重新封装,常被用于设置服务质量(QoS)。该表包含 PREROUTING、INPUT、FORWARD、OUTPUT 和 POSTROUTING 链。
- 为特定用户的流量设置更高优先级:
iptables -t mangle -A OUTPUT -m owner --uid-owner 1000 -j MARK --set-mark 1
- 为视频流数据包设置更高优先级:
iptables -t mangle -A OUTPUT -p udp --dport 1234 -j MARK --set-mark 1
- 修改数据包的 TOS 字段,实现不同的 QoS 策略:
iptables -t mangle -A OUTPUT -p tcp --dport 80 -j TOS --set-tos 0x10
5.4 raw 表
raw 表用于决定数据包是否被状态跟踪机制处理,在匹配数据包时,raw 表的规则优先级高于其他表。该表包含 PREROUTING 和 OUTPUT 链。
- 跳过特定服务的连接跟踪,减少资源消耗:
iptables -t raw -A PREROUTING -p tcp --dport 443 -j NOTRACK
总结:所有防火墙规则最终都会添加到这四张表中的某一张,实际操作就是对这些表进行配置。
6. 实验
实验一:禁止特定网段进行 ping 操作
[root@localhost ~]# iptables -D INPUT 3
[root@localhost ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@localhost ~]# iptables -I INPUT 3 -p icmp -j ACCEPT
[root@localhost ~]# iptables -L --line-number
[root@localhost ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
实验二:搭建 Web 服务器并配置防火墙
[root@server ~]# mkdir -p /www/web
[root@server ~]# echo "hello world" > /www/web/index.html
[root@server ~]# yum install nginx -y
[root@server ~]# vim /etc/nginx/nginx.conf
root /www/web;
[root@server ~]# systemctl start nginx
[root@server ~]# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
[root@server ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@server ~]# systemctl restart iptables
[root@server ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
实验三:禁止所有人使用 SSH 远程登录
[root@server ~]# iptables -F # 清空
[root@server ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
# 此时ssh已断开连接
# 恢复ssh连接
[root@server ~]# iptables -D INPUT 1 # 删除INPUT链中第1条规则,恢复ssh
[root@server ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
[root@server ~]# service iptables save # 保存服务
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@server ~]# systemctl restart iptables # 重启服务
实验四:禁止特定主机 SSH 远程登录,允许其访问 Web 服务
[root@server ~]# iptables -F
[root@server ~]# iptables -I INPUT -p tcp -s 192.168.48.131 --dport 22 -j REJECT # -I 表示在已存在的记录之前插入一条新纪录
[root@server ~]# iptables -I INPUT -p tcp -s 192.168.48.131 --dport 80 -j ACCEPT
[root@server ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 192.168.48.131 0.0.0.0/0 tcp dpt:80
REJECT tcp -- 192.168.48.131 ipt 0.0.0.0/0 tcp dpt:22 reject-with icmp-port-unreachable
[root@server ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ]
[root@server ~]# systemctl restart iptables
三、firewalld
1. firewalld 介绍
iptables service 在更新防火墙规则时,会先清空旧规则,再完整加载新规则。若配置需重新加载内核模块,还会执行卸载和重新加载操作,这在网络繁忙的系统中可能产生不良影响。而 firewalld 作为动态防火墙,解决了这一问题。它支持 IPv4 和 IPv6 防火墙设置,任何规则变更只需保存并更新,无需重新加载整个规则列表。
相较于传统防火墙管理工具,firewalld 支持动态更新技术,并引入了区域概念。区域是 firewalld 预设的几套防火墙策略集合,用户可通过选择不同集合,快速切换防火墙策略。
在 RHEL7 中,firewalld 服务是默认的防火墙配置管理工具,支持基于 CLI(命令行界面)和 GUI(图形用户界面)两种管理方式。firewall-config 和 firewall-cmd 通过直接编辑 xml 文件进行配置,其中 firewall-config 为图形化工具,firewall-cmd 为命令行工具。
firewalld 常见区域名称(默认为 public),各区域有相应策略规则。其默认提供的九个 zone 配置文件保存在 “/usr/lib/firewalld/zones/” 目录下,包括 block.xml、drop.xml、home.xml 等。
安装 firewalld 服务软件:
[root@localhost ~]# rpm -qa | grep firewall
firewall-config-0.3.9-14.el7.noarch
firewalld-0.3.9-14.el7.noarch
firewall-cmd命令的参数说明如下:
2. 实验
2.1 实验一:在 firewalld 区域中添加 http 服务
[root@server ~]# yum install nginx -y
[root@server ~]# systemctl start nginx
# 浏览器测试网页,被拒绝
[root@server ~]# firewall-cmd --get-default-zone
[root@server ~]# firewall-cmd --list all # 查看当前区域中开放的服务
[root@server ~]# firewall-cmd --permanent --zone=public --add-service=http
success
[root@server ~]# firewall-cmd --permanent --zone=public --add-port=80/tcp
success
[root@server ~]# firewall-cmd --reload
success
[root@server ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens32
sources:
services: cockpit dhcpv6-client http ssh
ports: 80/tcp
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
# 浏览器测试通过
# 放行服务格式:
firewall-cmd --permanent --zone=public --add-service=服务名
# 放行端口格式:
firewall-cmd --permanent --zone=public --add-port=端口号/传输协议
2.2 实验二:添加 nginx 服务
[root@server ~]# firewall-cmd --get-services # 查看所有区域支持的服务
[root@server ~]# yum install nginx -y # 安装nginx
[root@server ~]# firewall-cmd --add-service=nginx --permanent # 报错,需要编辑区域文件
[root@server ~]# vim /etc/firewalld/services/nginx.xml # 编辑服务配置文件,添加:
<service>
<short>Nginx</short>
<description>nginx</description>
<port protocol="tcp" port="80"/>
<port protocol="tcp" port="443"/>
</service>
# 再次添加服务
[root@server services]# firewall-cmd --add-service=nginx --permanent
# 重置
[root@server services]# firewall-cmd --reload
# 查看当前区域支持的服务
[root@server services]# firewall-cmd --zone=public --list-service
2.3 实验三:禁止特定网段进行 ping 操作
firewalld 富规则用于更精细的防火墙策略配置,可针对系统服务、端口号、源地址和目标地址等进行针对性配置,且优先级最高。
[root@server ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.48.131" protocol value="icmp" reject'
success
[root@server ~]# firewall-cmd --reload # 重置
success
public (active)
target: default
icmp-block-inversion: no
interfaces: ens32
sources:
services: dhcpv6-client mdns nginx ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="192.168.48.131" protocol value="icmp" reject
# 客户端输入ping 192.168.48.130 进行测试,发现无法ping,成功
# 注意:恢复客户端ping,不能在服务端添加一条放行富规则,应为禁止的富规则还在,ping还是无法通信,如:
[root@server ~]# firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.48.131" protocol value="icmp" accept'
[root@server ~]# firewall-cmd --reload
# 客户端测试ping 192.168.48.130 失败
# 注意:只需删除对应规则即可
2.4 实验四:紧急禁用所有流量
- 立即禁用网络流量,切换到 panic 模式:
[root@localhost ~]# firewall-cmd --panic-on
success
启用 panic 模式会停止所有网络流量,建议仅在可物理访问机器或通过串行控制台登录时使用。
- 关闭 panic 模式,使防火墙恢复到永久设置:
[root@localhost ~]# firewall-cmd --panic-off
success
- 查看 panic 模式的开启状态:
[root@localhost ~]# firewa11-cmd --query-panic
2.5 实验五:创建、删除、切换新的区域
- 创建新区域:
firewall-cmd --permanent --new-zone=haha_zone
- 使新区域可用:
firewall-cmd --reload
该命令将最新更改应用于防火墙配置,不会中断正在运行的网络服务。
- 验证新区域是否添加到永久设置中:
firewall-cmd --get-zones --permanent
- 切换新的默认区域:
firewall-cmd --set-default-zone haha_zone
- 修改默认区域的默认规则:
firewall-cmd --permanent [--zone=zone] [--policy=policy] --set-target=ACCEPT
2.6 实验六:为区域分配网络接口
- 列出活动区域和分配给它们的接口:
firewall-cmd --get-active-zones
- 将接口分配到其他区域:
firewall-cmd --zone=zone_name --change-interface=interface_name --permanent
- 将网卡接口划分到指定区域:
[root@localhost ~]# nmcli connection modify test connection.zone block
[root@localhost ~]# nmcli connection up test
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5