如何配置防火墙规则:完整技术指南
防火墙规则是一种策略条目,它指示防火墙引擎根据源/目标 IP 地址、端口号、传输协议和流量方向等定义标准来允许、拒绝或记录网络流量。正确配置的防火墙规则构成了您的基础设施与公共互联网之间的主要执行层,使其成为任何服务器或网络设备上最具决定性意义的安全控制措施。
本指南涵盖防火墙规则架构、Linux 上的 UFW、firewalld、Windows Defender 防火墙、nftables,以及将强化环境与错误配置环境区分开来的操作实践。
防火墙规则实际控制的内容
防火墙规则集中的每条规则都会针对五个核心数据包属性进行评估,通常称为 5 元组:
- 源 IP 地址 — 发起主机或子网(例如,
192.168.1.0/24) - 目标 IP 地址 — 目标主机或范围
- 源端口 — 发起方的临时端口
- 目标端口 — 接收方的服务端口(例如,HTTPS 使用
443,SSH 使用22) - 协议 —
TCP、UDP、ICMP或协议编号
除 5 元组外,有状态防火墙还会跟踪连接状态(NEW、ESTABLISHED、RELATED、INVALID),这使它们能够在不为每个响应编写明确入站规则的情况下,允许出站连接的返回流量。
有状态防火墙与无状态防火墙
| 功能 | 有状态 | 无状态 |
|---|---|---|
| 跟踪连接状态 | 是 | 否 |
| 自动允许返回流量 | 是 | 否 — 需要明确规则 |
| 性能开销 | 中等 | 极低 |
| 典型使用场景 | 主机防火墙、NGFW | 核心路由器、高吞吐量 ACL |
| 防欺骗能力 | 高 | 低 |
| 规则复杂度 | 较低 | 较高 |
| 示例工具 | iptables(conntrack)、UFW、Windows Defender | AWS NACL、Cisco IOS 上的基本 ACL |
对于几乎所有服务器部署——包括 VPS 托管和独立服务器——有状态的基于主机的防火墙是正确的默认选择。
防火墙规则处理:顺序问题
错误配置最常见的原因之一是误解了规则顺序。大多数防火墙从上到下评估规则,并应用第一条匹配规则,然后停止。这意味着:
- 放置在特定
DENY规则上方的宽泛ALLOW规则将悄无声息地覆盖它。 - 链顶部的
DENY ALL会阻止所有内容,无论后面跟着什么。 - 重复或被遮蔽的规则会浪费处理周期并造成审计混乱。
最佳实践:始终将特定规则放在通用规则之前。将针对已知恶意来源的明确 DENY 规则放在顶部附近,然后是针对受信任服务的特定 ALLOW 规则,并以默认 DENY 策略终止每条链。
在 Linux 上使用 UFW 配置防火墙规则
UFW(简单防火墙)是 Debian/Ubuntu 系统上 iptables 和 nftables 的前端。它将低级链语法抽象为人类可读的命令,同时保留对端口、协议、IP 和接口过滤的完全控制。
第 1 步:安装并启用 UFW
UFW 已预装在 Ubuntu 上。启用前请验证其状态:
sudo ufw status verbose如果未激活,请启用它:
sudo ufw enable重要警告:如果您通过 SSH 连接且尚未允许端口 22,启用 UFW 将使您无法访问。在远程服务器上启用防火墙之前,请务必先允许 SSH。
第 2 步:设置默认策略
默认策略定义了与任何明确规则都不匹配的流量的处理方式。安全基准为:
sudo ufw default deny incoming
sudo ufw default allow outgoing这会丢弃所有未经请求的入站连接,同时允许所有出站流量。如果您的安全策略需要出口过滤(例如,防止数据泄露或 C2 回调),请更改出站默认设置:
sudo ufw default deny outgoing然后明确只允许您的应用程序所需的出站目标。
第 3 步:允许特定服务和端口
UFW 支持来自 /etc/services 的服务名称或明确的端口号:
# Allow SSH by service name
sudo ufw allow ssh
# Allow HTTP and HTTPS
sudo ufw allow http
sudo ufw allow https
# Allow a custom application port
sudo ufw allow 8080/tcp
# Allow a UDP service (e.g., DNS resolver)
sudo ufw allow 53/udp允许端口范围(例如,被动 FTP):
sudo ufw allow 49152:65535/tcp第 4 步:将访问限制为特定源 IP
将管理端口暴露给 0.0.0.0/0 是导致暴力破解的主要原因。将 SSH 锁定到已知的管理 IP:
sudo ufw allow from 203.0.113.50 to any port 22 proto tcp允许整个管理子网:
sudo ufw allow from 10.0.0.0/8 to any port 22 proto tcp第 5 步:拒绝来自特定 IP 或子网的流量
阻止已知恶意 IP:
sudo ufw deny from 198.51.100.77阻止整个子网(例如,地理封锁或滥用 ASN 范围):
sudo ufw deny from 198.51.100.0/24边缘情况:UFW deny 规则会发送 TCP RST 或 ICMP 端口不可达响应,这会确认主机的存在。使用 reject 来静默丢弃数据包:
sudo ufw reject from 198.51.100.0/24第 6 步:检查活动规则
sudo ufw status numberednumbered 标志为每条规则分配一个索引,这是进行针对性删除所必需的:
[ 1] 22/tcp ALLOW IN 203.0.113.50
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere获取包含默认策略和接口绑定的完整详细输出:
sudo ufw status verbose第 7 步:删除规则
按规则编号删除(首选——避免歧义):
sudo ufw delete 3按规则规范删除:
sudo ufw delete allow 8080/tcp第 8 步:重新加载并持久化规则
UFW 规则会自动在重启后持久保存。批量更改后,在不断开现有连接的情况下重新加载:
sudo ufw reload完全重置所有规则并从头开始:
sudo ufw resetUFW 高级功能:应用程序配置文件
UFW 支持存储在 /etc/ufw/applications.d/ 中的命名应用程序配置文件。这允许您在单个名称下定义多端口规则:
sudo ufw app list
sudo ufw allow 'Nginx Full'
sudo ufw app info 'Nginx Full'为 Node.js API 创建自定义配置文件:
[NodeAPI]
title=Node.js API Server
description=Custom Node.js application
ports=3000,3001/tcp然后应用它:
sudo ufw allow NodeAPI使用 firewalld 配置防火墙规则(RHEL/CentOS/Fedora)
firewalld 使用基于区域的模型而非扁平规则集。每个网络接口被分配到一个区域(例如,public、internal、dmz),规则按区域应用。这对于多宿主服务器在架构上更加灵活。
基本 firewalld 操作
# Check status
sudo firewall-cmd --state
# List all active zones and their interfaces
sudo firewall-cmd --get-active-zones
# List rules in the public zone
sudo firewall-cmd --zone=public --list-all允许和移除服务
# Allow HTTPS permanently
sudo firewall-cmd --zone=public --add-service=https --permanent
# Allow a custom port
sudo firewall-cmd --zone=public --add-port=8443/tcp --permanent
# Remove a service
sudo firewall-cmd --zone=public --remove-service=http --permanent
# Reload to apply permanent changes
sudo firewall-cmd --reload针对特定 IP 策略的富规则
firewalld 富规则以更易读的语法提供了 iptables 的精细度:
# Allow SSH only from a specific IP
sudo firewall-cmd --zone=public
--add-rich-rule='rule family="ipv4" source address="203.0.113.50" service name="ssh" accept'
--permanent
# Block all traffic from a subnet
sudo firewall-cmd --zone=public
--add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" drop'
--permanent
sudo firewall-cmd --reload使用 nftables 配置防火墙规则
nftables 是 iptables 的现代替代品,为 IPv4、IPv6、ARP 和桥接过滤提供了统一框架,具有显著更好的性能和原子规则替换。
基本 nftables 规则集
# Flush existing ruleset
sudo nft flush ruleset
# Create a basic filtering table
sudo nft add table inet filter
# Add input, forward, and output chains
sudo nft add chain inet filter input { type filter hook input priority 0 ; policy drop ; }
sudo nft add chain inet filter forward { type filter hook forward priority 0 ; policy drop ; }
sudo nft add chain inet filter output { type filter hook output priority 0 ; policy accept ; }
# Allow established and related connections
sudo nft add rule inet filter input ct state established,related accept
# Allow loopback
sudo nft add rule inet filter input iif lo accept
# Allow SSH from a specific IP
sudo nft add rule inet filter input ip saddr 203.0.113.50 tcp dport 22 accept
# Allow HTTP and HTTPS from anywhere
sudo nft add rule inet filter input tcp dport { 80, 443 } accept要使规则集持久化,请将其保存到默认配置文件:
sudo nft list ruleset > /etc/nftables.conf
sudo systemctl enable nftables在 Windows 上配置防火墙规则
具有高级安全性的 Windows Defender 防火墙提供了 GUI 和命令行(netsh、PowerShell)界面用于规则管理。
使用 GUI
- 通过
wf.msc打开具有高级安全性的 Windows Defender 防火墙。 - 在左侧面板中选择入站规则或出站规则。
- 在右侧面板中单击新建规则。
- 选择规则类型:
- 端口 — 按 TCP/UDP 端口号过滤
- 程序 — 按可执行文件路径过滤
- 预定义 — 使用内置 Windows 服务定义
- 自定义 — 完全控制所有参数
- 指定端口或程序,选择允许或阻止,选择适用的配置文件(域、专用、公用),并为规则命名。
使用 PowerShell(推荐用于自动化)
# Allow inbound HTTPS
New-NetFirewallRule -DisplayName "Allow HTTPS Inbound" `
-Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
# Allow inbound SSH (Windows OpenSSH)
New-NetFirewallRule -DisplayName "Allow SSH Inbound" `
-Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow `
-RemoteAddress 203.0.113.50
# Block inbound traffic from a specific IP
New-NetFirewallRule -DisplayName "Block Malicious IP" `
-Direction Inbound -RemoteAddress 198.51.100.77 -Action Block
# View all inbound rules
Get-NetFirewallRule -Direction Inbound | Select-Object DisplayName, Enabled, Action
# Remove a rule by name
Remove-NetFirewallRule -DisplayName "Allow HTTPS Inbound"使用 netsh(旧版但广泛支持)
:: Allow inbound port 443
netsh advfirewall firewall add rule name="Allow HTTPS" protocol=TCP dir=in localport=443 action=allow
:: Block a specific IP
netsh advfirewall firewall add rule name="Block IP" dir=in remoteip=198.51.100.77 action=block
:: Delete a rule
netsh advfirewall firewall delete rule name="Allow HTTPS"关键防火墙规则陷阱和边缘情况
已建立流量的隐式允许
在有状态防火墙上,如果未在输入链中明确允许 ESTABLISHED 和 RELATED 连接,即使输出链设置为 ACCEPT,所有出站发起的会话(例如,apt update、curl、DNS 查询)也会中断。这是原始 iptables 或 nftables 设置中最常见的错误配置。
# This rule MUST appear before any DROP rules in the input chain
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTIPv6 对等性
许多管理员精心配置 IPv4 规则,却完全忘记了 IPv6。如果您的服务器有 IPv6 地址且 UFW 的 IPv6 支持未启用,攻击者可以通过 :: 连接绕过所有 IPv4 规则。验证 /etc/default/ufw 包含:
IPV6=yes回环接口
始终明确允许回环接口(lo)上的流量。许多本地服务(数据库、消息队列、内部 API)通过 127.0.0.1 或 ::1 进行通信。阻止回环会悄无声息地破坏进程间通信。
sudo ufw allow in on lo
sudo ufw allow out on lo速率限制以防止暴力破解
UFW 原生支持连接速率限制,这对于 SSH 和其他身份验证服务至关重要:
sudo ufw limit ssh这允许单个 IP 在 30 秒内最多进行 6 次连接尝试,超过后触发自动临时封锁——对于基本部署来说,这是 fail2ban 的轻量级替代方案。
ICMP 和诊断流量
阻止所有 ICMP 是一种常见但适得其反的做法。它会破坏 ping、traceroute、MTU 路径发现和某些路由协议。正确的方法是允许特定的 ICMP 类型:
- 类型 0(回显应答)和类型 8(回显请求)— 用于
ping - 类型 3(目标不可达)— 用于路径 MTU 发现
- 类型 11(超时)— 用于
traceroute
阻止类型 17(地址掩码请求)和类型 18(地址掩码应答),这些在现代没有合法用途。
防火墙规则与托管环境
正确的防火墙策略在很大程度上取决于您的基础设施层。
在共享虚拟主机上,防火墙由提供商在平台级别管理。租户通常配置应用层访问控制,而非内核级数据包过滤器。
在带 cPanel 的 VPS 上,cPanel/WHM 包含 ConfigServer Security & Firewall(CSF),它以高级界面、自动暴力破解检测和端口敲击支持封装了 iptables。CSF 是 cPanel 环境的标准防火墙解决方案,在这些系统上应优先于原始 UFW 使用。
在非托管的 VPS 托管或独立服务器上,您对内核防火墙拥有完全控制权。这是 UFW、firewalld 和 nftables 的适用场景。强化基准应包括:
- 默认拒绝入站策略
- SSH 限制为已知管理 IP 或 VPN 网关
- 所有非必要端口关闭
- 对身份验证端口进行速率限制
- 为被拒绝的流量启用日志记录
如果您在 GPU 托管上运行 GPU 工作负载或 ML 推理服务,请特别注意 Jupyter notebooks、TensorBoard 和模型服务 API 暴露的端口——这些端口经常成为扫描开放高编号端口的加密挖矿机器人的目标。
防火墙规则审计和维护清单
定期规则审计与初始配置同样重要。规则会随时间积累并变得陈旧,造成不必要的攻击面。
每季度执行的审计任务:
- 运行
sudo ufw status numbered或等效命令,并对照当前服务清单审查每条规则 - 删除已停用服务、旧 IP 地址和从未清理的临时例外的规则
- 验证默认策略仍为
deny incoming - 检查 IPv6 规则是否与 IPv4 规则一致
- 确认日志记录已启用,且被拒绝流量的日志正在被您的 SIEM 或日志聚合器摄取
- 从外部主机使用
nmap测试规则,以验证攻击面符合您的预期
# Scan your own server from an external host to verify exposed ports
nmap -sS -sV -p 1-65535 --open YOUR_SERVER_IP- 验证
ESTABLISHED/RELATED规则是否存在且顺序正确 - 审查速率限制规则,并根据观察到的流量模式调整阈值
决策矩阵:选择正确的防火墙工具
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| Ubuntu/Debian 服务器,简单规则集 | UFW | 人类可读语法,默认持久化 |
| RHEL/CentOS/Fedora 服务器 | firewalld | 原生集成,区域模型适合多网卡设置 |
| 高性能或复杂过滤 | nftables | 原子更新,IPv4/IPv6/ARP 单一框架 |
| 旧版 RHEL/CentOS 6 | iptables | 旧内核上的唯一选项 |
| Windows Server | Windows Defender + PowerShell | 原生、可通过 GPO 管理、可脚本化 |
| cPanel VPS | CSF(ConfigServer 防火墙) | 专为 cPanel 构建,包含 LFD 守护进程 |
| 云虚拟机(AWS/GCP/Azure) | 云安全组 + 主机防火墙 | 纵深防御;云安全组有状态且免费 |
实用关键要点
- 在编写任何允许规则之前设置默认拒绝入站。这确保您忘记编写的任何规则都会导致连接被阻止,而不是开放。
- 切勿在生产服务器上将 SSH 暴露给
0.0.0.0/0。将其限制为管理 IP、VPN 子网,或使用端口敲击。 - 尽可能具体地编写允许规则。优先使用
from 203.0.113.50 to any port 22 proto tcp而非allow 22。 - 在 IPv6 中镜像 IPv4 规则。只过滤 IPv4 的防火墙只是半个防火墙。
- 在所有身份验证端口上启用连接速率限制作为基线暴力破解缓解措施。
- 记录被拒绝的流量。没有日志记录的静默丢弃使事件响应几乎不可能。
- 按计划审计规则。陈旧的规则是一种负担,而非安全网。
- 从外部测试。每次重大规则更改后,使用
nmap或外部端口扫描器确认有效攻击面。 - 使用
ufw reload而非ufw disable && ufw enable,以避免在规则更新期间断开活动连接。 - 在
nftables和iptables上,始终将ESTABLISHED/RELATED接受规则放在输入链顶部,以避免破坏出站发起的会话。
常见问题
防火墙规则与云环境中的安全组有什么区别?
安全组(AWS、GCP、Azure)是在虚拟机管理程序级别应用的有状态、云管理的数据包过滤器,在流量到达您的虚拟机之前生效。基于主机的防火墙规则(UFW、firewalld)在操作系统内核内运行。两者应同时使用以实现纵深防御——云安全组作为外部边界,主机防火墙作为内部执行层。
为什么 UFW 显示规则处于活动状态,但流量仍被阻止?
最常见的原因是规则顺序。链中较早的 DENY 规则在您的 ALLOW 规则之前匹配。运行 sudo ufw status numbered 并检查顺序。如果客户端通过 IPv6 连接,还要验证 IPv6 规则是否存在;如果服务器是多宿主的,请确认目标接口是否正确。
出于安全考虑,我应该完全阻止 ICMP 吗?
不应该。阻止所有 ICMP 会破坏路径 MTU 发现,导致 TCP 会话在具有非标准 MTU 的网络上挂起。它还会破坏 traceroute 并使网络诊断变得更加困难。只阻止没有合法操作用途的 ICMP 类型(类型 17 和 18)。允许回显请求/应答、目标不可达和超时。
重新加载 UFW 时,活动的 SSH 连接会发生什么?
sudo ufw reload 在不刷新现有 conntrack 状态条目的情况下重新加载规则集。活动的 SSH 会话保持连接,因为内核的连接跟踪表仍保存其 ESTABLISHED 状态。只有 sudo ufw disable 后跟 sudo ufw enable 才会刷新状态并可能断开活动连接。
如何防止防火墙规则在系统重启后丢失?
UFW 通过 /etc/ufw/ 配置文件自动在重启后持久保存规则。对于 firewalld,在每条规则上使用 --permanent 标志并运行 sudo firewall-cmd --reload。对于原始 nftables,使用 sudo nft list ruleset > /etc/nftables.conf 保存规则集,并确保 nftables systemd 服务已启用。对于 iptables,使用 iptables-save > /etc/iptables/rules.v4 并安装 iptables-persistent 软件包。
