Linux firewalld 在生产环境的使用建议

27次阅读

生产环境是否启用 firewalld 取决于网络策略管理主体:若已有硬件防火墙、云安全组或 eBPF/iptables 工具(如 Calico),则 firewalld 冗余且易引发冲突;仅推荐用于无集中管控的中小规模物理机/虚拟机场景。

Linux firewalld 在生产环境的使用建议

firewalld 服务是否该在生产环境启用

生产环境是否启用 firewalld,不取决于“该不该用”,而取决于“谁在管网络策略”。如果已有专用硬件防火墙、云平台安全组(如 AWS Security Group、阿里云 ECS 安全组)或主机侧 eBPF/iptables 直接管理工具(如 Calico、Cilium),firewalld 往往是冗余层,反而增加策略冲突风险。它适合中小规模、无集中网络策略管控的物理机或虚拟机场景,尤其是管理员需频繁增删端口且不熟悉 raw iptables 规则时。

  • 不建议在 kubernetes 节点上同时启用 firewalld 和 kube-proxy 的 iptables 模式,二者会竞争 FORWARD 链规则,导致 Pod 网络不通或 Service 访问异常
  • 若使用 cloud-init 或 ansible 自动化部署,确保 firewalld 启动顺序早于应用服务,否则服务可能在防火墙就绪前监听成功,造成短暂暴露
  • 默认的 public zone 允许 sshdhcpv6-client,但禁止所有入向新连接——这点常被误认为“已锁死”,实则只是没显式放行业务端口

zone 切换与 runtime/permanent 模式的坑

firewall-cmd--runtime-to-permanent 不是“保存当前配置”,而是把当前 runtime 规则覆盖写入 permanent 配置。若你只临时加了一条端口、未 reload,又执行该命令,之前通过 firewall-offline-cmd 或手动编辑 /etc/firewalld/zones/*.xml 写死的规则就会丢失。

  • 修改 zone 建议始终用 firewall-cmd --permanent --set-default-zone=trusted + firewall-cmd --reload,避免仅 runtime 切换导致重启后回退
  • 给网卡绑定 zone 时,不要依赖 firewall-cmd --change-Interface=eth0 --zone=internal,该操作仅 runtime 生效;应改用 nmcli connection modify "System eth0" firewall.zone internal(配合 NetworkManager)或在 /etc/sysconfig/network-scripts/ifcfg-eth0 中加 FIREWALL_ZONE=internal
  • firewall-cmd --list-all-zones 输出中,每个 zone 的 services: 行只显示“预定义服务”(即 /usr/lib/firewalld/services/ 下的 XML 文件),自定义端口必须看 ports: 字段,否则容易漏检

如何安全地批量开放端口而不留后门

直接 firewall-cmd --permanent --add-port=8080-8090/tcp 是高危操作:范围端口难以审计,且一旦某端口被恶意进程监听,即自动获得通行权。生产环境应坚持“最小端口+明确协议+绑定 zone”。

  • 优先用服务名而非端口号:firewall-cmd --permanent --add-service=http,因为 /usr/lib/firewalld/services/http.xml 明确定义了 80/tcp,语义清晰且防错
  • 如需开放非标端口(如 java 应用的 8761/tcp),先建自定义服务:
    cat > /etc/firewalld/services/eureka.xml <<'EOF'  Eureka Server   EOF

    ,再 firewall-cmd --reload && firewall-cmd --permanent --add-service=eureka

  • 永远避免 --add-port=0-65535/udp 类操作;UDP 端口尤其危险,因无连接状态跟踪,firewalld 默认仅靠 timeout 控制,易被放大攻击利用

排查 connection refused 却能 ping 通的问题

ping 通只说明 ICMP 和网络层可达,connection refused 多数情况是 TCP 连接被拒绝,原因常不在 firewalld,但在排查路径上它最容易被冤枉。

  • 先确认服务真在监听:ss -tlnp | grep :8080,若无输出,问题在应用未启动或绑定错了地址(如只绑 127.0.0.1
  • 再查 firewalld 是否放行:firewall-cmd --list-portsfirewall-cmd --list-services,注意输出中的 zone 是否匹配网卡实际所属 zone(firewall-cmd --get-active-zones
  • 最后验证规则是否生效:用 firewall-cmd --direct --get-all-rules 查看是否有 direct rules 干扰,或用 iptables -t Filter -L input -n -v 看底层链是否含 REJECTDROP —— firewalld 的 default_zone 若设为 drop,未匹配任何 rule 的包会被静默丢弃,此时 telnet 会超时而非 refused

真正麻烦的是 multi-zone 场景下 interface 绑定漂移,比如 DHCP 重获 IP 后 NetworkManager 重载配置,导致网卡 zone 回到 default。这种问题不会报错,只会让某批请求突然失联,得盯住 journalctl -u firewalld -f 里 zone change 日志。

text=ZqhQzanResources