完整教程:【运维基础】Linux 防火墙管理
Linux 防火墙管理
防火墙介绍
防火墙( FireWall ),工作在网络或主机边缘,对进出网络或主机的数据包基于一定的规则检查,并在匹配某规则时由规则定义的行为进行处理的一组功能的组件。基本上的实现都是默认情况下关闭所有的通过型访问,只开放允许访问的策略,将希望外网访问的主机放在 DMZ(demilitarized zone)网络中。
防火墙类型
按保护范围划分:
- 主机防火墙:服务范围为当前一台主机。
- 网络防火墙:服务范围为防火墙一侧的局域网。
按实现方式划分:
- 硬件防火墙:在专用硬件级别实现防火墙功能,例如华为、华三、天融信等产品。
- 软件防火墙:运行于通用硬件平台之上的防火墙的应用软件,例如iptables,firewalld。
按网络协议划分:
- 网络层防火墙:工作在OSI 模型下四层,又称为包过滤防火墙。
- 网络层对数据包进行选择,选择的依据是系统内设置的过滤逻辑,被称为访问控制列表(ACL),通过检查数据流中每个数据的源地址,目的地址,所用端口号和协议状态等因素,或他们的组合来确定是否允许该数据包通过
- 优点:对用户来说透明,处理速度快且易于维护。
- 缺点:无法检查应用层数据,如病毒等。
应用层防火墙/代理服务器:工作在OSI 模型七层或者承担proxy 代理网关。
- 异常检测协议:Web应用防火墙会对HTTP的请求进行异常检测,拒绝不符合HTTP标准的请求。它也可以只允许HTTP协议的部分选项通过,从而减少攻击的影响范围。
- 增强的输入验证:可以有效防止网页篡改、信息泄露、木冯植入等恶意网络入侵行为。从而减小Web服务器被攻击的可能性。
- 及时补丁:修补Web安全漏洞,是Web应用开发者最头痛的问题,没人会知道下一秒有什么样的漏洞出现,会为Web应用带来什么样的危害。现在WAF(Web Application Firewall)可以为我们做这项工作了:只要有全面的漏洞信息WAF能在不到一个小时的时间内屏蔽掉这个漏洞。当然,这种屏蔽掉漏洞的方式不是非常完美的,没有安装对应的补丁本身就是一 种安全威胁,但我们在没有选择的情况下,任何保护措施都比没有保护措施更好。
- 基于规则的保护和基于异常的保护:基于规则的保护可以提供各种Web应用的安全规则,WAF(Web Application Firewall) 生产商会维护这个规则库,并时时为其更新。用户可以按照这些规测对应用进行全方面检测。
- **状态管理。**WAF能够判断用户是否是第一次访问并且将请求重定向到默认登录页面并且记录事件。通过检测用户的整个操作行为我们可以更容易识别攻击。状态管理模式还能检测出异常事件(比如登陆失败),并組在达到极限值时进行处理。这对暴力攻击的识别和响应是十分有利的。
- **其他防护技术。**WAF还有一安全增强的功能,可以用来解决WEB程序员过分信任输入数据带来的问题。比如:隐藏表单域保护、抗入侵规避技术、 响应监视和信息泄露保护。
- 优点:提供应用层保护。
- 缺点:处理速度慢等
Netfilter 子系统
Netfilter子系统是Linux内核中一个强大的网络过滤子系统,对进入系统的每个数据包,在到达用户空间组件或应用之前进行检查,通过编程方式来修改、丟弃或路由数据包。
Netfilter子系统工作在内核态,用户使用以下命令配置防火墙规则,告诉Netfilter子系统如何处理数据包:
iptables,用于过滤 IPv4 协议的数据包。
如果 Linux 系统连接到LAN或因特网, 则iptables可用于在 Linux 系统上更好地控制 IP 信息包过滤和防火墙配置。
ip6tables,用于过滤 IPv6 协议的数据包,效果等同iptables工具。
arptables,用于过滤 arp 协议的数据包。
arptables既能防止别的机器对自己进行arp欺骗,又能防止本机病毒或错误程序向其他机器发起arp攻击。如果善于运用的话,不失为一个优秀的arp防火墙。
ebtables,用于过滤数据链路层数据包。
ebtables 过滤数据包比 iptables 更靠前,获得的数据更“原始”,ebtables 多用于桥模式,比如控制 VLAN ID 等。
[root@server ~ 21:48:25]# ls -1 /sbin/*tables
lrwxrwxrwx 1 root root 17 8月 5 2025 /sbin/arptables -> xtables-nft-multi
lrwxrwxrwx. 1 root root 17 8月 5 2025 /sbin/ebtables -> xtables-nft-multi
lrwxrwxrwx. 1 root root 17 8月 5 2025 /sbin/ip6tables -> xtables-nft-multi
lrwxrwxrwx. 1 root root 17 8月 5 2025 /sbin/iptables -> xtables-nft-multi
Nftables 子系统
Nftables子系统是netfilter的增强版,其仍保留了netfilter的架构。
nftables优点:
- 更快的数据包处理
- 更快的规则集更新
- 使用单个 nft 用户空间实用程序,通过一个接口来管理所有协议,消除了以往不同前端和多个netfilter接口引起的争用问题。
静态防火墙和动态防火墙
静态防火墙
用户管理防火墙规则时,为了让规则永久保存,防火墙服务会重新加载所有防火墙规则,哪怕只修改一条规则也要重新读取所有规则,这种载入模式称为静态模式。静态模式加载规则时,会导致网络连接丢失。
我们称使用静态模式载入规则的防火墙为静态防火墙。例如iptables,用户执行 service iptables reload
命令将变更的规则保存到配置文件里,并重新加载所有防火墙规则。
动态防火墙
用户管理防火墙规则时,为了让规则永久保存,防火墙只需要将变更部分保存并更新到运行中的 iptables 即可,而不需要对整个防火墙规则列表进行重新加载,这种载入模式称为动态模式。
我们称使用动态模式载入规则的防火墙为动态防火墙,例如 firewalld。
Firewalld 防火墙
Firewalld 介绍
Firewalld 是 Red Hat 公司开发的防火墙软件,默认后端为 nftables。
- 在 RHEL 7 之前的发行版中,默认使用 iptables 命令来管理防火墙。
- 在 RHEL 7 之后的发行版中, firewalld 取代 iptables 成为了默认防火墙软件。
- 用户可以同时使用 iptables 和 firewalld 两个防火墙软件,但容易搞混规则。建议将一个防火墙关闭或默认允许所有流量,只使用另一个防火墙。
- Firewalld 防火墙的另外一个特点就是动态加载防火墙规则。
Firewalld 和 iptables 之间的关系
- firewalld 提供了一个 daemon 和 service,还有命令行和图形界面配置工具,它仅仅是替代了 iptables service 部分,其底层还是使用 iptables 作为防火墙规则管理入口。
- firewalld 和 iptables 一样,他们的作用都是用于维护规则,自身并不具备防火墙的功能,而真正使用规则干活的是内核的 netfilter,只不过 firewalld 和 iptables 的结构以及使用方法不一样罢了。
Firewalld 区域
firewalld 防火墙为了简化管理,将所有网络流量分为多个区域(zone),每个 zone 就是一套过滤规则集。
Firewalld 提供的区域
firewalld 防火墙提供了如下zone:
- trusted(信任区域):允许所有的传入流量。
- public(公共区域):允许与ssh或dhcpv6-client预定义服务匹配的传入流量,其余均拒绝。是新添加网络接口的默认区域。
- external(外部区域):允许与ssh预定义服务匹配的传入流量,其余均拒绝。默认将通过此区域转发的IPv4传出流量将进行地址伪装,可用于为路由器启用了伪装功能的外部网络。
- home(家庭区域):允许与ssh、mdn3、samba-client或dhcpv6-client预定义服务匹配的传入流量,其余均拒绝。
- internal(内部区域):默认值时与homel区域相同。
- work(工作区域):允许与 ssh、dhcpv6-client预定义服务匹配的传入流量,其余均拒绝。
- dmz(隔离区域也称为非军事区域):允许与ssh 预定义服务匹配的传入流量,其余均拒绝。
- block(限制区域):拒绝所有传入流量。
- drop(丢弃区域):丢弃所有传入流量,并且不产生包含ICMP的错误响应。
Firewalld 配置
Firewalld 配置方法
- 直接编辑 /etc/firewalld/ 中的配置文件
- firewall-config 图形工具
- firewall-cmd 命令行工具
Firewalld 配置文件
Firewalld 配置配置文件存放在:
- /usr/lib/firewalld/目录,Firewalld软件包自带配置位置。
- /etc/firewalld/目录,目录结构与/usr/lib/firewalld/一致,管理员自定义配置保存在该位置。
**提示:**我们不建议大家通过修改/etc/firewalld/目录配置防火墙。
查看zone配置
[root@server ~ 21:51:16]# cd /usr/lib/firewalld/
[root@server firewalld 21:51:19]# ls
helpers icmptypes ipsets services zones
# 查看zone配置
[root@server firewalld 21:51:22]# ls zones/
block.xml drop.xml home.xml public.xml work.xml
dmz.xml external.xml internal.xml trusted.xml
[root@server firewalld 21:51:44]# cat zones/trusted.xml
<?xml version="1.0" encoding="utf-8"?>
<zone target="ACCEPT">
<short>Trusted</short>
<description>All network connections are accepted.</description>
</zone>
[root@server firewalld 21:51:49]# cat zones/block.xml
<?xml version="1.0" encoding="utf-8"?>
<zone target="%%REJECT%%">
<short>Block</short>
<description>Unsolicited incoming network packets are rejected. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.</description>
</zone>
[root@server firewalld 21:51:56]# cat zones/drop.xml
<?xml version="1.0" encoding="utf-8"?>
<zone target="DROP">
<short>Drop</short>
<description>Unsolicited incoming network packets are dropped. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.</description>
</zone>
查看服务配置
[root@server firewalld 21:52:02]# ls -1 services
amanda-client.xml
amanda-k5-client.xml
amqps.xml
amqp.xml
apcupsd.xml
........
[root@server firewalld 21:52:55]# cat services/http.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>WWW (HTTP)</short>
<description>HTTP is the protocol used to serve Web pages. If you plan to make your Web server publicly available, enable this option. This option is not required for viewing pages locally or developing Web pages.</description>
<port protocol="tcp" port="80"/>
</service>
[root@server firewalld 21:53:19]# cat services/https.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Secure WWW (HTTPS)</short>
<description>HTTPS is a modified HTTP used to serve Web pages when security is important. Examples are sites that require logins like stores or web mail. This option is not required for viewing pages locally or developing Web pages. You need the httpd package installed for this option to be useful.</description>
<port protocol="tcp" port="443"/>
</service>
firewall-cmd 命令行工具
两个基本概念
配置防火墙必须知道两个基本概念:
防火墙的配置有两个状态:
runtime(运行时),防火墙的默认状态,该状态的配置立刻生效。
permanent(永久),通过选项
--permanent
指定,该状态下的配置不会立刻生效,而是写入配置文件,需要通过选项--reload
重新reload才会生效,重新reload将导致运行时状态下未保存的配置丢失,但会保留当前连接状态。如果使用选项--complete-reload
重新reload永久配置,将导致当前连接状态也丢失。配置防火墙建议:一次性写两条规则:第一条使用选项
--permanent
永久生效;第二条不使用选项--permanent
立刻生效。说明: 后续防火墙配置,如不做单独说明,默认都是在运行时下配置。
配置防火墙的规则必须一个区域内(直接规则除外),如果不使用选项
--zone
明确指明区域,则使用默认区域。默认区域是public。
zone 管理
# 查看zone清单
[root@server firewalld 21:55:49]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
# 查看激活的zone清单,也就是分配了interface和source的zone
[root@server firewalld 21:55:59]# firewall-cmd --get-active-zones
public
interfaces: ens33
# 查看默认zone
[root@server firewalld 21:56:17]# firewall-cmd --get-default-zone
public
# 设置默认zone,例如设置为trusted,该操作同时设置永久态默认zone
[root@server firewalld 21:56:37]# firewall-cmd --set-default-zone=trusted
success
[root@server firewalld 21:56:56]# firewall-cmd --get-default-zone
trusted
# 再次设置回来
[root@server firewalld 21:57:02]# firewall-cmd --set-default-zone=public
success
# 如果有需要还可以创建新zone,必须配合--permanent
[root@server firewalld 21:57:20]# firewall-cmd --permanent --new-zone=myweb
success
[root@server firewalld 21:57:40]# firewall-cmd --permanent --get-zones
block dmz drop external home internal myweb public trusted work
[root@server firewalld 21:57:46]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
# 使用--reload选项重新加载所有防火墙规则,再次查看zone清单
[root@server firewalld 21:57:51]# firewall-cmd --reload
success
[root@server firewalld 21:58:16]# firewall-cmd --get-zones
block dmz drop external home internal myweb public trusted work
# 查看zone target
[root@server firewalld 21:58:21]# firewall-cmd --permanent --zone=myweb --get-target
default
# 设置zone target,可用target值为:
# default,默认值,也就是拒绝数据包进入用户空间。
# ACCEPT,允许数据包进入用户空间。
# DROP,丢弃数据包,不对客户端做出任何响应。
# REJECT,拒绝数据包进入用户空间。
[root@server firewalld 21:58:47]# firewall-cmd --permanent --zone=myweb --set-target=REJECT
success
[root@server firewalld 21:59:13]# firewall-cmd --permanent --zone=myweb --get-target
REJECT
# zone不需要的时候,也可以删除,必须配合--permanent
[root@server firewalld 21:59:22]# firewall-cmd --permanent --delete-zone=myweb
success
[root@server firewalld 22:00:08]# firewall-cmd --permanent --get-zones
block dmz drop external home internal public trusted work
[root@server firewalld 22:00:13]# firewall-cmd --reload
success
[root@server firewalld 22:00:21]# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
# 查看所有zone中的规则
[root@server firewalld 22:00:27]# firewall-cmd --list-all-zones
block
target: %%REJECT%%
icmp-block-inversion: no
interfaces:
sources:
services:
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
dmz
target: default
......
drop
target: DROP
......
external
target: default
......
home
target: default
......
internal
target: default
......
public (active)
target: default
......
trusted
target: ACCEPT
......
work
target: default
......
# 查看默认zone中的规则
[root@server firewalld 22:00:52]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens33
sources:
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
# 查看特定zone中的规则
[root@server firewalld 22:01:48]# firewall-cmd --list-all --zone=home
home
target: default
icmp-block-inversion: no
interfaces:
sources:
services: dhcpv6-client mdns samba-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
source 管理
# 来源于特定source的数据包交给特定zone处理
[root@server firewalld 22:02:07]# firewall-cmd --add-source=192.168.1.0/24 --zone=home
success
# 查看source清单
[root@server firewalld 22:03:22]# firewall-cmd --list-sources --zone=home
192.168.1.0/24
# 查看source属于哪个zone
[root@server firewalld 22:03:43]# firewall-cmd --get-zone-of-source=192.168.1.0/24
home
# 查看source是否添加
[root@server firewalld 22:04:14]# firewall-cmd --query-source=192.168.1.0/24 --zone=home
yes
# 变更source到其他zone
[root@server firewalld 22:04:31]# firewall-cmd --change-source=192.168.1.0/24 --zone=public
success
# 删除zone中source
[root@server firewalld 22:04:49]# firewall-cmd --remove-source=192.168.1.0/24 --zone=public
success
interface 管理
# 查看zone中interface
[root@server firewalld 22:05:06]# firewall-cmd --list-interfaces
ens33
# 查看interface属于哪个zone
[root@server firewalld 22:06:15]# firewall-cmd --get-zone-of-interface=ens33
public
# 查看interface是否添加
[root@server firewalld 22:10:31]# firewall-cmd --query-interface=ens33
yes
# 将interface变更到其他zone
[root@server firewalld 22:10:51]# firewall-cmd --change-interface=ens33 --zone=home
success
# 删除zone中interface
[root@server firewalld 22:11:17]# firewall-cmd --remove-interface=ens33 --zone=home
success
# 如果interface不属于任何zone,使用以下命令将interface绑定到特定zone
[root@server firewalld 22:11:28]# firewall-cmd --add-interface=ens33 --zone=public
success
service 管理
准备httpd服务
yum install -y httpd
systemctl start httpd
# 查看系统中预定义了哪些服务
[root@server firewalld 22:17:14]# firewall-cmd --get-services
RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
# 添加放行服务
[root@server firewalld 22:17:33]# firewall-cmd --add-service=http
success
# 查看放行服务列表
[root@server firewalld 22:17:56]# firewall-cmd --list-services
dhcpv6-client http ssh
# 查看服务是否放行
[root@server firewalld 22:18:18]# firewall-cmd --query-service=http
yes
# 删除服务
[root@server firewalld 22:18:37]# firewall-cmd --remove-service=http
success
firewall-cmd命令行还可以定义新的服务。
常用选项如下:
--permanent --new-service=service
Add a new permanent and empty service.
--permanent --delete-service=service
Delete an existing permanent service.
--permanent --service=service --set-description=description
Set new description to service
--permanent --service=service --get-description
Print description for service
--permanent --service=service --set-short=description
Set short description to service
--permanent --service=service --get-short
Print short description for service
--permanent --service=service --add-port=portid[-portid]/protocol
Add a new port to the permanent service.
--permanent --service=service --remove-port=portid[-portid]/protocol
Remove a port from the permanent service.
--permanent --service=service --get-ports
List ports added to the permanent service.
--permanent --service=service --add-protocol=protocol
Add a new protocol to the permanent service.
--permanent --service=service --remove-protocol=protocol
Remove a protocol from the permanent service.
--permanent --service=service --get-protocols
List protocols added to the permanent service.
--permanent --service=service --add-source-port=portid[-portid]/protocol
Add a new source port to the permanent service.
--permanent --service=service --remove-source-port=portid[-portid]/protocol
Remove a source port from the permanent service.
--permanent --service=service --get-source-ports
List source ports added to the permanent service.
port 管理
# 添加放行端口
[root@server firewalld 22:18:55]# firewall-cmd --add-port=5900/tcp
success
# 查看端口放行列表
[root@server firewalld 22:19:38]# firewall-cmd --list-ports
5900/tcp
# 查看端口是否放行
[root@server firewalld 22:19:59]# firewall-cmd --query-port=5900/tcp
yes
# 删除端口
[root@server firewalld 22:20:22]# firewall-cmd --remove-port=5900/tcp
success
masquerade 管理
SNAT,为了让内网中主机公用一个公网ip地址上网。 DNAT,为了让外网中主机访问内网的服务器。
SNAT 实验: client通过server访问Internet
# client设置网关为10.1.8.10
# 环境配置
[root@client ~ 22:33:03]# nmcli connection modify ens33 ipv4.gateway 10.1.8.2
[root@client ~ 22:33:11]# nmcli connection up ens33
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)
[root@client ~ 22:33:15]# yum install -y mtr
[root@client ~ 22:33:17]# nmcli connection modify ens33 ipv4.gateway 10.1.8.10
[root@client ~ 22:33:21]# nmcli connection up ens33
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)
[root@client ~ 22:33:28]# ip route
default via 10.1.8.10 dev ens33 proto static metric 100
10.1.8.0/24 dev ens33 proto kernel scope link src 10.1.8.11 metric 100
[root@client ~ 22:33:33]# mtr 1.1.1.1
# 现在mtr 1.1.1.1 没有转发
# 回到server端
# server防火墙启用masquerade功能
[root@server ~ 22:33:46]# firewall-cmd --add-masquerade
success
[root@server ~ 22:34:01]# firewall-cmd --query-masquerade
yes
# 现在mtr 1.1.1.1 可以转发
forward-port 管理
DNAT 实验: window通过 server的 1022 端口访问 client 22 端口
# 配置server启用masquerade功能
# SNAT 实验 已经配置完了
# 配置端口转发
[root@server ~ 22:34:14]# firewall-cmd --add-forward-port=port=1022:proto=tcp:toport=22:toaddr=10.1.8.11
success
# 此时新开一个窗口 输入root@10.1.8.10:1022可以进行连接
# 10.1.8.10:1022 -> 10.1.8.11:22
示例:
# 在上两个实验的前提下
# 先在client端配置
[root@client ~ 22:34:16]# yum install -y httpd
[root@client ~ 22:34:21]# systemctl start httpd
[root@client ~ 22:34:24]# echo Hello World From Client > /var/www/html/index.html
[root@client ~ 22:34:29]# curl localhost
Hello World From Client
# 回到server端
[root@server ~ 22:34:36]# firewall-cmd --add-forward-port=port=1080:proto=tcp:toport=80:toaddr=10.1.8.11
success
# 此时打开浏览器访问10.1.8.10:1080 就可以访问到网页,显示Hello World From Client(写入的内容)