Debian Linux 防火墙实战:nftables、UFW、端口开放与规则管理
一、Debian 防火墙基础知识
防火墙是 Linux 服务器网络安全的重要组成部分,主要用于控制进入和离开服务器的网络流量。
例如:
-
允许外部用户访问网站的 80 和 443 端口。
-
只允许指定 IP 访问 SSH 管理端口。
-
禁止公网直接访问 MySQL 的 3306 端口。
-
限制 Redis、MongoDB 等服务的网络访问。
-
阻止未经授权的网络连接。
-
配置端口转发,实现不同网络服务之间的流量转发。
Debian 常见的防火墙管理方式包括:
| 工具 | 作用 | 特点 |
|---|---|---|
| nftables | Linux 内核防火墙框架及规则管理工具 | 功能强大、灵活,适合精细控制 |
| UFW | 简化防火墙管理工具 | 命令简单,适合日常服务器管理 |
| iptables | 传统防火墙规则管理工具 | 仍然存在于大量旧教程和系统中 |
现代 Debian 系统通常使用 nftables 作为底层防火墙框架。
UFW 则是一个更容易使用的管理工具,可以帮助用户通过简单命令管理防火墙规则。
需要注意:nftables 和 UFW 不应随意同时管理同一套防火墙规则,否则可能出现规则冲突、重复规则或管理状态不一致。
本文将分别介绍两种方式,实际部署时建议选择一种作为主要管理入口。
二、检查 Debian 当前防火墙状态
在修改防火墙之前,先了解系统当前的网络和防火墙状态。
1. 查看 Debian 版本
cat /etc/debian_version
2. 检查 nftables 是否安装
sudo nft --version
如果提示命令不存在,可以安装:
sudo apt update
sudo apt install nftables -y
3. 检查 UFW 是否安装
sudo ufw version
如果没有安装:
sudo apt install ufw -y
4. 查看当前 nftables 规则
sudo nft list ruleset
如果没有任何规则,可能会看到空输出。
5. 查看 UFW 状态
sudo ufw status verbose
可能出现:
Status: inactive
表示 UFW 当前未启用。
6. 查看监听端口
sudo ss -lntup
例如:
Netid State Local Address:Port
tcp LISTEN 0.0.0.0:22
tcp LISTEN 0.0.0.0:80
tcp LISTEN 0.0.0.0:443
tcp LISTEN 127.0.0.1:3306
这里表示:
-
SSH 监听 TCP 22。
-
Web 服务监听 TCP 80 和 443。
-
MySQL 只监听本机 IPv4 地址。
注意:防火墙规则和服务监听是两回事。即使开放了某个端口,如果没有服务监听,外部用户仍然无法正常访问该服务。
三、nftables 防火墙实战
nftables 是 Linux 内核 Netfilter 框架的现代规则管理工具。
它支持:
-
IPv4 和 IPv6。
-
TCP、UDP、ICMP 等协议。
-
IP 地址过滤。
-
端口过滤。
-
连接状态跟踪。
-
NAT 和端口转发。
-
速率限制。
-
集合和动态规则。
1. 安装 nftables
sudo apt update
sudo apt install nftables -y
查看版本:
nft --version
启动服务:
sudo systemctl enable --now nftables
查看服务状态:
sudo systemctl status nftables
2. 备份现有防火墙规则
修改防火墙前,建议先备份现有规则:
sudo nft list ruleset > ~/nftables-backup.nft
查看备份文件:
cat ~/nftables-backup.nft
如果需要恢复,可以在确认规则内容安全后执行:
sudo nft -f ~/nftables-backup.nft
注意:这条命令会将备份中的规则重新加载到当前规则集中。若备份与当前状态不一致,可能改变现有防护策略。
3. 创建基础防火墙规则
编辑 nftables 配置文件:
sudo nano /etc/nftables.conf
写入以下基础配置:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter;
policy drop;
# 允许本机回环流量
iifname "lo" accept
# 允许已建立和相关连接
ct state established,related accept
# 丢弃无效连接
ct state invalid drop
# 允许 SSH
tcp dport 22 ct state new accept
# 允许 HTTP
tcp dport 80 accept
# 允许 HTTPS
tcp dport 443 accept
# 允许 IPv4 和 IPv6 的必要 ICMP 流量
ip protocol icmp accept
meta l4proto ipv6-icmp accept
}
chain forward {
type filter hook forward priority filter;
policy drop;
}
chain output {
type filter hook output priority filter;
policy accept;
}
}
配置说明:
| 配置 | 作用 |
|---|---|
flush ruleset |
清空当前 nftables 规则集 |
table inet filter |
创建同时支持 IPv4 和 IPv6 的过滤表 |
chain input |
处理发往本机的流量 |
chain forward |
处理经过本机转发的流量 |
chain output |
处理本机发出的流量 |
policy drop |
默认拒绝未匹配的流量 |
accept |
允许匹配的流量 |
特别注意:flush ruleset 会清除整个 nftables 规则集。如果服务器上还运行 Docker、VPN、容器网络或其他防火墙管理工具,不要直接套用这份配置,否则可能破坏其依赖的规则。
另外,这是一份基础示例,不是所有生产环境的通用模板。实际使用时需要根据服务器的网络接口、VPN、IPv6、容器和转发需求调整。
4. 检查 nftables 配置语法
不要直接重启服务,先检查配置:
sudo nft -c -f /etc/nftables.conf
如果没有错误输出,通常表示语法检查通过。
加载配置:
sudo nft -f /etc/nftables.conf
查看当前规则:
sudo nft list ruleset
5. 放行指定端口
例如,放行 SSH 22222:
sudo nft add rule inet filter input tcp dport 22222 ct state new accept
放行 HTTP:
sudo nft add rule inet filter input tcp dport 80 accept
放行 HTTPS:
sudo nft add rule inet filter input tcp dport 443 accept
放行 UDP 端口,例如 51820:
sudo nft add rule inet filter input udp dport 51820 accept
查看规则:
sudo nft list chain inet filter input
注意:通过 nft add rule 添加的规则通常只是当前运行时规则。若希望重启后仍然生效,需要同步更新 /etc/nftables.conf,然后重新加载配置。
6. 只允许指定 IP 访问 SSH
例如,只允许 203.0.113.10 访问 SSH 22222:
sudo nft add rule inet filter input ip saddr 203.0.113.10 tcp dport 22222 accept
如果希望 IPv6 地址访问,需要使用对应的 IPv6 地址匹配规则,例如:
sudo nft add rule inet filter input ip6 saddr 2001:db8::10 tcp dport 22222 accept
上面的 IP 均为文档示例地址,实际使用时需要替换。
如果需要限制 SSH 来源,应确保没有其他更宽泛的规则提前允许所有来源访问 SSH。
7. 限制 MySQL 端口
如果 MySQL 只需要本机访问,优先让 MySQL 监听:
127.0.0.1
如果确实需要允许某个私网地址访问,例如:
10.0.0.10
可以添加:
sudo nft add rule inet filter input ip saddr 10.0.0.10 tcp dport 3306 accept
如果没有远程访问需求,不要添加这条放行规则。
还应检查数据库本身的用户授权和监听地址。防火墙放行并不代表数据库自动允许该用户登录。
8. 删除 nftables 规则
查看规则及句柄:
sudo nft -a list chain inet filter input
可能看到:
tcp dport 22 ct state new accept # handle 5
tcp dport 80 accept # handle 6
tcp dport 443 accept # handle 7
删除指定规则:
sudo nft delete rule inet filter input handle 6
这里的 6 是示例句柄,应替换成实际查询到的句柄。
删除前务必确认规则对应的端口,避免误删 SSH 放行规则。
9. 查看 nftables 完整规则
sudo nft list ruleset
以数字方式显示:
sudo nft -n list ruleset
查看指定表:
sudo nft list table inet filter
查看指定链:
sudo nft list chain inet filter input
10. 设置规则持久化
编辑配置:
sudo nano /etc/nftables.conf
将需要长期生效的规则写入文件。
检查配置:
sudo nft -c -f /etc/nftables.conf
重新加载:
sudo nft -f /etc/nftables.conf
设置开机启动:
sudo systemctl enable nftables
查看服务状态:
sudo systemctl status nftables
四、UFW 防火墙实战
UFW 是 Debian 上比较容易上手的防火墙管理工具。
如果不想直接编写 nftables 规则,可以使用 UFW 管理常见的端口和 IP 访问策略。
需要注意:UFW 本身会通过系统防火墙后端实现规则管理。使用 UFW 时,应避免再用另一套独立配置频繁覆盖其底层规则。
1. 安装 UFW
sudo apt update
sudo apt install ufw -y
查看版本:
sudo ufw version
2. 设置默认规则
默认拒绝进入连接:
sudo ufw default deny incoming
默认允许发出连接:
sudo ufw default allow outgoing
查看规则:
sudo ufw status verbose
3. 放行 SSH 端口
默认 SSH 端口:
sudo ufw allow 22/tcp
如果 SSH 已修改为 22222:
sudo ufw allow 22222/tcp
一定要先确认实际 SSH 端口。
4. 放行 Web 端口
HTTP:
sudo ufw allow 80/tcp
HTTPS:
sudo ufw allow 443/tcp
也可以使用应用配置:
sudo ufw app list
查看可用配置。
例如:
sudo ufw allow 'Nginx Full'
前提是系统已经安装并提供对应的 Nginx UFW 应用配置。
5. 放行指定端口
开放 TCP 8080:
sudo ufw allow 8080/tcp
开放 UDP 51820:
sudo ufw allow 51820/udp
开放 TCP 和 UDP 端口:
sudo ufw allow 9000
如果服务只使用 TCP 或 UDP,建议明确指定协议。
6. 限制指定 IP 访问端口
只允许某个 IPv4 地址访问 SSH:
sudo ufw allow from 203.0.113.10 to any port 22222 proto tcp
只允许某个私网网段访问 MySQL:
sudo ufw allow from 10.0.0.0/24 to any port 3306 proto tcp
只允许某个 IP 访问管理后台:
sudo ufw allow from 203.0.113.10 to any port 8080 proto tcp
这些示例地址需要替换成实际地址和网段。
7. 拒绝指定端口
拒绝访问 TCP 3306:
sudo ufw deny 3306/tcp
拒绝访问 UDP 6379:
sudo ufw deny 6379/udp
注意:UFW 规则存在顺序和匹配关系。配置允许规则和拒绝规则时,应检查完整规则集,避免宽泛规则与精确规则互相覆盖或造成预期之外的结果。
8. 启用 UFW
在启用之前,先确保 SSH 端口已经放行。
查看规则:
sudo ufw status numbered
确认无误后:
sudo ufw enable
查看详细状态:
sudo ufw status verbose
9. 删除 UFW 规则
查看规则编号:
sudo ufw status numbered
例如:
[ 1] 22222/tcp ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
删除第二条规则:
sudo ufw delete 2
也可以按规则内容删除:
sudo ufw delete allow 8080/tcp
10. 禁用和重置 UFW
临时关闭 UFW:
sudo ufw disable
重置规则:
sudo ufw reset
注意:ufw reset 会删除 UFW 管理的规则,并可能导致服务暴露范围发生变化。生产服务器不要随意执行。
五、IPv4 与 IPv6 防火墙规则
很多服务器同时拥有 IPv4 和 IPv6 地址。
只配置 IPv4 防火墙而忽略 IPv6,可能造成安全策略不完整。
1. 查看 IPv4 地址
ip -4 addr
2. 查看 IPv6 地址
ip -6 addr
3. 查看 IPv6 路由
ip -6 route
4. 检查 UFW 的 IPv6 支持
编辑:
sudo nano /etc/default/ufw
检查:
IPV6=yes
如果启用 IPv6,应确保相关防火墙规则也覆盖 IPv6。
修改后需要重新加载 UFW 规则,并检查最终生成的规则。
5. nftables 使用 inet 表
nftables 的 inet 地址族可以同时匹配 IPv4 和 IPv6。
例如:
table inet filter {
chain input {
type filter hook input priority filter;
policy drop;
iifname "lo" accept
ct state established,related accept
ct state invalid drop
tcp dport 22222 accept
tcp dport { 80, 443 } accept
}
}
这段规则中的 TCP 端口匹配同时适用于 IPv4 和 IPv6。
但需要注意,实际部署仍应根据服务器的网络环境检查 ICMP、IPv6 邻居发现和路由相关流量,不能简单地把所有 ICMP 都禁掉。
六、nftables 端口转发实战
端口转发可以将访问某个端口的流量转发到另一个地址或端口。
例如:
公网访问服务器 8080
↓
Debian 防火墙
↓
内网服务 10.0.0.20:80
端口转发通常需要:
-
开启 IP 转发。
-
配置 NAT 规则。
-
配置 FORWARD 链放行规则。
-
根据网络拓扑配置返回流量路由。
-
确认上游路由器或云安全组允许相关流量。
1. 开启 IPv4 转发
临时开启:
sudo sysctl -w net.ipv4.ip_forward=1
永久开启:
sudo nano /etc/sysctl.d/99-ip-forward.conf
写入:
net.ipv4.ip_forward=1
应用配置:
sudo sysctl --system
检查:
sysctl net.ipv4.ip_forward
2. 配置 NAT 端口转发
假设:
-
外部访问端口:8080。
-
内网服务器:10.0.0.20。
-
内网服务端口:80。
-
公网流量进入网卡:eth0。
添加 DNAT 规则:
sudo nft add rule ip nat prerouting iifname "eth0" tcp dport 8080 dnat to 10.0.0.20:80
配置前需要先创建 NAT 表和对应链。例如:
sudo nft add table ip nat
sudo nft 'add chain ip nat prerouting { type nat hook prerouting priority dstnat; policy accept; }'
sudo nft 'add chain ip nat postrouting { type nat hook postrouting priority srcnat; policy accept; }'
3. 配置 FORWARD 放行规则
假设已经存在:
table inet filter
chain forward
可以添加:
sudo nft add rule inet filter forward ip daddr 10.0.0.20 tcp dport 80 ct state new,established,related accept
同时还需要确保返回方向的连接可以通过。
例如:
sudo nft add rule inet filter forward ct state established,related accept
如果已有这条规则,不要重复添加。
4. 配置源地址转换
如果内网服务器没有返回公网客户端的路由,可以考虑 SNAT 或 masquerade。
例如:
sudo nft add rule ip nat postrouting ip daddr 10.0.0.20 tcp dport 80 masquerade
注意:这里的 masquerade 会使内网服务器看到的来源地址变成转发服务器的地址,可能影响日志记录和基于来源 IP 的访问控制。
如果内网服务器已有正确的返回路由,应根据实际网络拓扑决定是否需要 SNAT。
5. 检查转发规则
查看 NAT 规则:
sudo nft list table ip nat
查看 FORWARD 链:
sudo nft list chain inet filter forward
端口转发不仅需要 NAT,还必须确保转发路径上的防火墙允许流量。
如果云服务器使用安全组,还需要在云安全组中放行对应端口。
七、UFW 日志与防火墙监控
防火墙日志可以帮助管理员判断哪些流量被允许或拒绝。
1. 启用 UFW 日志
sudo ufw logging on
设置日志级别:
sudo ufw logging medium
常见级别:
| 级别 | 说明 |
|---|---|
| off | 关闭日志 |
| low | 记录基本信息 |
| medium | 记录更多信息 |
| high | 记录更详细信息 |
| full | 记录大量信息 |
日志级别越高,产生的日志可能越多。
2. 查看 UFW 日志
sudo journalctl -k -n 100
也可以查看:
sudo grep -i UFW /var/log/ufw.log
如果日志文件不存在,可以检查 journald 和 rsyslog 的配置及运行状态。
3. 实时查看日志
sudo journalctl -k -f
4. 关闭 UFW 日志
sudo ufw logging off
如果服务器流量较大,不建议长期使用过于详细的日志级别,以免产生大量日志。
八、nftables 与 UFW 应该如何选择?
两者并不是完全相同层级的工具。
| 对比项目 | nftables | UFW |
|---|---|---|
| 配置方式 | 规则语法 | 简单命令 |
| IPv4/IPv6 | 支持 | 支持 |
| NAT | 支持 | 支持,但配置更受限 |
| 复杂规则 | 非常灵活 | 相对有限 |
| 学习难度 | 较高 | 较低 |
| 适合场景 | 精细控制、复杂网络 | 常规 VPS、网站服务器 |
建议:
普通 VPS 和网站服务器:
可以优先使用 UFW。
常见规则:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
如果 SSH 使用其他端口,必须将上面的 22 替换为实际端口。
需要复杂网络管理的服务器:
可以直接使用 nftables。
例如:
-
多网卡服务器。
-
VPN 网关。
-
路由器。
-
NAT 转发服务器。
-
复杂 IPv4/IPv6 策略。
-
多个网络区域的访问控制。
不要在没有明确管理方案的情况下,让 UFW 和自定义 nftables 配置同时修改同一套规则。
九、常见防火墙故障排查
1. SSH 无法连接
可能原因:
-
SSH 端口没有放行。
-
SSH 服务没有运行。
-
云服务器安全组没有开放端口。
-
防火墙规则设置错误。
-
SSH 配置文件存在错误。
-
SSH 只监听本地地址。
检查服务:
sudo systemctl status ssh
检查端口:
sudo ss -lntp | grep ssh
检查防火墙:
sudo ufw status verbose
sudo nft list ruleset
检查 SSH 配置:
sudo sshd -t
如果已经无法远程登录,优先使用云平台提供的 VNC、串口或救援控制台恢复配置。
2. 网站无法访问
检查 Nginx:
sudo systemctl status nginx
检查端口:
sudo ss -lntp | grep -E ':80|:443'
检查 UFW:
sudo ufw status
检查 nftables:
sudo nft list ruleset
本机测试:
curl -I http://127.0.0.1
如果本机访问正常,但外部无法访问,应进一步检查云安全组、路由、DNS 和上游网络。
3. 端口开放了却无法访问
需要逐层检查:
-
服务是否正常运行。
-
服务是否监听正确地址。
-
Debian 防火墙是否允许连接。
-
云安全组是否放行。
-
上游路由是否允许流量。
-
目标 IP 和端口是否正确。
可以使用:
sudo ss -lntup
以及:
sudo ufw status numbered
4. nftables 重启后规则消失
检查配置文件:
sudo cat /etc/nftables.conf
检查服务:
sudo systemctl status nftables
检查启动日志:
sudo journalctl -u nftables -n 100
确认规则已经写入配置文件,并且服务已启用:
sudo systemctl enable nftables
5. Docker 容器端口被防火墙规则影响
Docker 可能会自行创建 NAT 和过滤规则。
因此,不能假设 UFW 的普通规则就一定能完整控制 Docker 发布的所有端口。
如果使用 Docker,应同时检查:
sudo nft list ruleset
docker ps
docker port 容器名称
对于需要限制公网访问的容器服务,应结合 Docker 的网络规则、宿主机防火墙和云安全组进行设计。
不要为了修复容器网络问题直接执行:
sudo nft flush ruleset
这可能清除 Docker、VPN 和其他服务所依赖的规则。
十、生产环境防火墙配置建议
正式部署服务器时,建议遵循以下原则:
1. 只开放必要端口
普通网站服务器通常只需要:
-
SSH 管理端口。
-
HTTP 80。
-
HTTPS 443。
其他端口应根据实际业务需求决定是否开放。
2. 数据库尽量只允许内网访问
MySQL、Redis、MongoDB 等服务不应默认暴露公网。
3. SSH 使用密钥认证
不要只依赖修改默认端口。
建议同时使用:
-
SSH 密钥认证。
-
禁止 root 远程登录。
-
禁用密码登录(确认密钥可用后)。
-
来源 IP 限制。
-
Fail2ban。
4. 云安全组和系统防火墙同时配置
云安全组位于云平台网络层,Debian 防火墙则负责操作系统内部的流量控制。
两者可以形成额外的防护层。
5. 修改规则前做好备份
保存现有规则:
sudo nft list ruleset > ~/firewall-backup.nft
保存 UFW 状态:
sudo ufw status numbered > ~/ufw-backup.txt
注意:UFW 的状态输出只是便于查看的记录,不是完整可恢复的配置备份。需要完整备份时,还应保存 /etc/ufw/ 中的相关配置文件。
6. 修改规则后必须验证
不要只看命令是否执行成功。
还应该从另一台设备测试:
-
SSH 是否正常。
-
网站是否正常。
-
不必要的端口是否无法访问。
-
IPv4 和 IPv6 是否都符合预期。
-
端口转发是否正常。
-
重启后规则是否仍然生效。
十一、Debian 防火墙常用命令速查表
| 操作 | 命令 |
|---|---|
| 查看 nftables 版本 | nft --version |
| 查看 nftables 规则 | sudo nft list ruleset |
| 查看 UFW 状态 | sudo ufw status verbose |
| 启用 UFW | sudo ufw enable |
| 关闭 UFW | sudo ufw disable |
| 开放 TCP 80 | sudo ufw allow 80/tcp |
| 开放 TCP 443 | sudo ufw allow 443/tcp |
| 删除 UFW 规则 | sudo ufw delete 编号 |
| 添加 nftables 规则 | sudo nft add rule ... |
| 查看 nftables 规则句柄 | sudo nft -a list ruleset |
| 删除 nftables 规则 | sudo nft delete rule ... handle 编号 |
| 检查 nftables 配置 | sudo nft -c -f /etc/nftables.conf |
| 重载 nftables 配置 | sudo nft -f /etc/nftables.conf |
| 查看监听端口 | sudo ss -lntup |
| 查看防火墙日志 | sudo journalctl -k -n 100 |
| 查看 nftables 服务 | sudo systemctl status nftables |
十二、总结
Debian 防火墙是服务器安全体系中的重要组成部分。
对于普通网站服务器,UFW 已经能够满足大多数基础需求;对于需要复杂访问控制、NAT、端口转发和多网卡管理的服务器,nftables 更加灵活。
实际部署时,建议重点做好以下工作:
-
了解服务器当前开放的端口。
-
默认拒绝不必要的外部连接。
-
只开放业务真正需要的端口。
-
限制 SSH 和管理后台访问来源。
-
不要将数据库直接暴露在公网。
-
同时检查 IPv4 和 IPv6。
-
配置规则持久化。
-
修改防火墙后从外部实际测试。
-
注意 Docker、VPN 等软件对底层防火墙规则的影响。
-
保留云平台控制台等备用管理方式。
防火墙并不能代替系统更新、身份认证、应用安全和数据备份。只有将网络访问控制与其他安全措施结合起来,才能建立相对完整的服务器防护体系。
- 点赞
- 收藏
- 关注作者
评论(0)