新安装的 Linux 服务器,任何服务打开的端口都会直接对外响应,因此主机防火墙是最先要设置的项目之一。本文说明如何在 Debian / Ubuntu 用 UFW 设置 Linux 防火墙,以及在 CentOS、Rocky Linux、AlmaLinux 使用 firewalld:先放行 SSH、开放网站端口、把敏感服务限制为特定来源 IP、同时保护 IPv6,以及不小心把自己锁在外面时如何恢复访问。JUSTG 位于东京、首尔、莫斯科的云服务器都免费提供 IPv6,所以 IPv6 规则和 IPv4 一样重要。
步骤 1:检查已打开的端口与 SSH 端口
写规则之前,先确认实际有哪些服务在监听,以及 SSH 使用哪个端口。如果您已把 SSH 改到自定义端口,以下所有 SSH 规则都要改用该端口,而不是 22。
# Which ports are services actually listening on?
ss -tulpn
# Which port does SSH use?
sshd -T | grep -i '^port'
步骤 2:启用防火墙前先准备安全网
一条错误的规则就可能切断 SSH 连接。在后台设置一个计时器,时间到就自动关闭防火墙,等于替自己留一条退路。从新的终端确认仍可登录后,再取消计时器。
# Safety net: turn the firewall off again in 10 minutes unless you cancel it
nohup sh -c 'sleep 600; ufw disable' >/dev/null 2>&1 & # UFW
nohup sh -c 'sleep 600; systemctl stop firewalld' >/dev/null 2>&1 & # firewalld
# Everything works? Cancel the timer:
pkill -f 'sleep 600'
步骤 3:在 Debian / Ubuntu 设置 UFW 防火墙
UFW(Uncomplicated Firewall)是内核防火墙的简易前端。先把默认策略设为拒绝所有入站流量,接着优先放行 SSH,最后才启用防火墙。ufw limit 会允许 SSH,但若同一地址短时间内连接过多次,就暂时封锁。
apt update && apt install -y ufw
# Make sure IPv6 rules are managed too
grep '^IPV6' /etc/default/ufw # should print IPV6=yes
ufw default deny incoming
ufw default allow outgoing
# SSH FIRST (use your real SSH port if you changed it)
ufw limit 22/tcp # allow + basic brute-force rate limit
# Web server
ufw allow 80,443/tcp
ufw enable # answer "y"
ufw status verbose
步骤 4:用 UFW 限制来源 IP(IPv4 与 IPv6)
数据库、管理后台与监控代理程序绝不应对整个互联网开放,只允许已知地址连接即可。UFW 依顺序比对规则,因此拒绝规则必须插入在范围较大的允许规则之前。
# Allow MySQL only from one office IPv4 and one IPv6 network
ufw allow from 198.51.100.25 to any port 3306 proto tcp
ufw allow from 2001:db8:10::/64 to any port 3306 proto tcp
# Block an abusive network (insert at the top so it is matched first)
ufw insert 1 deny from 203.0.113.0/24
# List rules with numbers and delete one
ufw status numbered
ufw delete 4
步骤 5:在 CentOS / Rocky Linux / AlmaLinux 设置 firewalld
firewalld 以“区域(zone)”工作,网络接口通常属于 public 区域,默认已允许 SSH。加上 --permanent 的规则重启后仍会保留,但必须运行 --reload 才会生效。
dnf install -y firewalld # CentOS 7: yum install -y firewalld
systemctl enable --now firewalld
firewall-cmd --get-default-zone # usually "public"
# SSH FIRST (or: --add-port=2222/tcp for a custom port)
firewall-cmd --permanent --add-service=ssh
# Web server
firewall-cmd --permanent --add-service=http --add-service=https
# Close what you do not use
firewall-cmd --permanent --remove-service=cockpit
firewall-cmd --reload
firewall-cmd --list-all
--add-port 加入该端口,再移除 ssh 服务。在 Rocky 与 AlmaLinux 上,该端口也必须在 SELinux 中允许。步骤 6:用 firewalld Rich Rule 限制来源 IP
Rich rule 可以在一行中同时指定来源地址、端口与动作。每条规则只适用一种地址族,所以 IPv4 与 IPv6 要各写一条。
# Allow MySQL from one IPv4 address and one IPv6 network only
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.25" port port="3306" protocol="tcp" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address="2001:db8:10::/64" port port="3306" protocol="tcp" accept'
# Drop all traffic from an abusive network
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" drop'
firewall-cmd --reload
firewall-cmd --list-rich-rules
步骤 7:确认 IPv6 也有被防火墙过滤
常见错误是 IPv4 规则写得很完整,同样的服务却在 IPv6 上完全敞开。UFW 只有在 IPV6=yes 时才管理 IPv6(ufw status 会出现“(v6)”规则);firewalld 的区域与服务则自动涵盖两种地址。请从另一台机器测试:
# Your server's IPv6 address
ip -6 addr show scope global
# From ANOTHER machine: test a port over IPv4 and IPv6
nc -vz 203.0.113.50 443
nc -vz 2001:db8:50::10 443
nc -vz 2001:db8:50::10 3306 # should fail from a non-allowed address
步骤 8:注意 Docker 对外发布的端口
Docker 会自行写入 iptables 规则,因此用 -p 8080:80 发布的端口,即使 UFW 或 firewalld 应该挡下,仍可能被外部访问。建议把容器发布在 127.0.0.1,前面再加反向代理,或自行管理 DOCKER-USER 链。
# Publish a container port on localhost only, then proxy it with Nginx
docker run -d -p 127.0.0.1:8080:80 nginx
步骤 9:被防火墙锁住时如何恢复访问
修改后 SSH 没有响应时,可先等待步骤 2 的计时器。否则请打开 VNC 控制台:登录 JUSTG 客户中心 → My Services(我的服务)→ 打开该 VPS(Product Details 页面)→ 在“Server Information”标签页的 VPS 面板中点击“VNC”。同一个 VNC 控制台也可在 Enduser Panel 中打开(Manage 卡片 → Virtualizor → “Enduser Panel”)。如找不到控制台可提交工单。以 root 登录后重新放行 SSH:
# Debian / Ubuntu (UFW)
ufw allow 22/tcp # or: ufw disable
# CentOS / Rocky / AlmaLinux (firewalld)
firewall-cmd --panic-off 2>/dev/null
firewall-cmd --add-service=ssh # runtime only; add --permanent once fixed
# last resort
systemctl stop firewalld
常见问题
UFW 和 firewalld 可以同时使用吗?
不建议。两者管理同一组内核规则表,会互相冲突。Debian/Ubuntu 用 UFW,CentOS/Rocky/AlmaLinux 用 firewalld,另一个若有安装请停用。
为什么重启后 firewalld 规则不见了?
因为添加时没有加 --permanent,只修改了运行中的设置。可运行 firewall-cmd --runtime-to-permanent 把目前规则存成永久设置。
可以封锁正在攻击服务器的 IP 吗?
可以:UFW 用 ufw insert 1 deny from 203.0.113.66,firewalld 则用带 drop 的 rich rule。若是大流量攻击,主机防火墙无法单独处理,请联系技术支持。
如设置 Linux 防火墙时仍遇到问题,请至 https://www.justg.com/submitticket.php 提交工单,JUSTG 技术支持团队会协助您处理。