Skip to content

🛡️ firewalld 进阶配置

Rich Rules 详解

Rich Rules(富规则)是 firewalld 最强大的功能——它能在一个规则里组合端口、来源、动作、日志等条件。

bash
# 富规则语法结构
firewall-cmd --add-rich-rule='
  rule family="ipv4"
  source address="192.168.1.0/24"
  port port="3306" protocol="tcp"
  accept'

# 带日志的拒绝规则
firewall-cmd --add-rich-rule='
  rule family="ipv4"
  source address="10.0.0.100"
  port port="22" protocol="tcp"
  log prefix="SSH-BLOCK: " level="info"
  reject'

# 限速规则(防暴力破解)
firewall-cmd --add-rich-rule='
  rule family="ipv4"
  source address="192.168.1.0/24"
  port port="22" protocol="tcp"
  accept
  limit value="5/m"'

# 端口转发(DNAT)
firewall-cmd --add-rich-rule='
  rule family="ipv4"
  source address="192.168.1.0/24"
  forward-port port="8080" protocol="tcp"
  to-port="80" to-addr="10.0.0.50"'

# 查看所有富规则
firewall-cmd --list-rich-rules

# 永久添加(重启不丢失)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="9090" protocol="tcp" accept'
firewall-cmd --reload

端口转发(Port Forwarding)

bash
# 先开启 IP 转发
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload

# 将外部 8080 端口转发到内网 10.0.0.50:80
firewall-cmd --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=10.0.0.50
firewall-cmd --permanent --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=10.0.0.50

# 将外部 3306 转发到内网数据库
firewall-cmd --permanent --add-rich-rule='
  rule family="ipv4"
  source address="192.168.1.0/24"
  forward-port port="3306" protocol="tcp"
  to-port="3306" to-addr="10.0.0.100"'

# 验证转发规则
firewall-cmd --list-forward-ports

# 从外部测试
curl http://your-server:8080
# 应该看到内网 10.0.0.50:80 的内容

与其他服务集成

bash
# firewalld 会自动加载服务的预定义规则
# 查看某个服务定义了什么端口
cat /etc/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <port protocol="tcp" port="22"/>
</service>

# 自定义一个服务
cat > /etc/firewalld/services/myapp.xml << 'EOF'
xml version="1.0" encoding="utf-8"?

  MyApp
  My Custom Application

EOF

# 现在可以直接用服务名
firewall-cmd --permanent --add-service=myapp
firewall-cmd --reload

# Docker 与 firewalld 的冲突
# Docker 会绕过 firewalld 直接操作 iptables
# 解决方案:在 /etc/docker/daemon.json 中设置
# { "iptables": false }
# 然后手动管理 Docker 的端口转发