firewalld 是 AlmaLinux 9 和 Rocky Linux 9 默认的防火墙管理器。在您的 VPS Linux Infrawire 上,它让您只开放所需的服务,把 SSH 限制为您自己的 IP,并转发端口,而无需直接操作原始 nftables 规则。
最大的风险是切断自己的 SSH 会话。本指南围绕这一点设计:每个有风险的改动都先在 runtime 配置中测试,然后再设为永久。
📋 前提条件
- 运行 AlmaLinux 9 或 Rocky Linux 9 的 VPS
- root SSH 访问权限(IP 和 root 密码可在客户区找到)
- 编辑规则期间保持打开的第二个 SSH 会话
1. 安装并启动 firewalld
Bashdnf install -y firewalld systemctl enable --now firewalld firewall-cmd --state
最后一条命令必须输出 running。默认区域是 public,它已允许 SSH、Cockpit 和 DHCPv6 客户端,并丢弃其余入站连接。
2. 理解区域、服务和端口
区域是应用于网络接口的一组规则。服务是有名字的端口组(ssh 为 22/tcp,http 为 80/tcp,https 为 443/tcp)。
Bashfirewall-cmd --get-default-zone firewall-cmd --get-active-zones firewall-cmd --list-all firewall-cmd --get-services | tr ' ' '\n' | head -20
有两套配置。Runtime 立即生效,重新加载或重启后消失。永久配置(--permanent)保存在磁盘上,但只有执行 firewall-cmd --reload 后才生效。
3. 开放服务和端口
Bash# 服务 firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https # 自定义端口 firewall-cmd --permanent --add-port=8080/tcp # 端口范围 firewall-cmd --permanent --add-port=30000-30100/udp # 应用永久配置 firewall-cmd --reload
要关闭某项,使用对应的 --remove-service 或 --remove-port 选项。如果不使用 Web 控制台,请移除 cockpit 服务:firewall-cmd --permanent --remove-service=cockpit。
4. 用 rich rule 只允许您的 IP 访问 SSH
Rich rule 可以表达来源地址等条件。在证明受限规则可用之前,切勿删除通用的 SSH 规则。
Bash# 1. 仅在 runtime 中添加规则(替换为您自己的公网 IP) firewall-cmd --add-rich-rule='rule family="ipv4" source address="YOUR_IP/32" service name="ssh" accept' # 2. 打开一个新终端,确认从 YOUR_IP 仍可通过 SSH 登录 # 3. 设为永久,然后移除对所有人开放的 SSH 服务 firewall-cmd --runtime-to-permanent firewall-cmd --permanent --remove-service=ssh firewall-cmd --reload
如果您的 IP 发生变化,就会失去访问权限:请保留客户区中的 VPS 控制台作为恢复途径。对于 IPv6 地址,请写 family="ipv6" 和对应的 IPv6 地址。
5. 转发端口
把进入 80 端口的流量转到本机上监听 8080 的应用:
Bashfirewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080 firewall-cmd --reload
若要转发到另一台机器,在 forward-port 选项中加入 toaddr=TARGET_IP,并用 firewall-cmd --permanent --add-masquerade 启用地址伪装。内核也必须允许转发,firewalld 在启用伪装时会处理这一点。
6. 验证配置
Bashfirewall-cmd --list-all firewall-cmd --list-rich-rules firewall-cmd --permanent --list-all ss -tlnp
对比 runtime 与永久列表:重新加载后两者必须一致。在另一台机器上用 nc -zv VPS_IP 80 测试端口。正在监听的服务(ss -tlnp)只有在防火墙放行其端口时才能被访问。
🛠️ 故障排查
FirewallD is not running:用 systemctl enable --now firewalld 启动,并通过 journalctl -u firewalld 查看错误。
新规则没有效果:使用了 --permanent 但没有重新加载。执行 firewall-cmd --reload。
INVALID_SERVICE 或 INVALID_ZONE:名称拼写错误。用 firewall-cmd --get-services 和 --get-zones 列出有效名称。
自定义端口的 SSH 被拒绝,尽管端口已开放:SELinux 必须认识该端口。执行 semanage port -a -t ssh_port_t -p tcp 2222(先安装 policycoreutils-python-utils),在 firewalld 中开放端口,然后重启 sshd。
被锁在外面:使用客户区中的 VPS 控制台,然后执行 firewall-cmd --permanent --add-service=ssh 和 firewall-cmd --reload。避免使用 firewall-cmd --panic-on,它会丢弃所有流量,包括您的会话。
🔒 您的 VPS 现在只暴露您选择的内容,而且 SSH 始终触手可及!