Linux服务器(aws ec2) 上 firewalld 端口转发不生效的解决方案

2026-02-11 3点热度 0人点赞 0条评论

Linux服务器 上 firewalld 端口转发不生效的解决方案

问题描述

在 AWS EC2 服务器上使用 firewalld 配置端口转发时,遇到了一个令人困惑的问题:

  • 需求:将本机 5001 端口的流量转发到另一台服务器 1.2.3.4 的 5001 端口
  • 现象:从外部 telnet 到 EC2 的 5001 端口失败,但直接 telnet 目标服务器 1.2.3.4:5001 是通的
  • 配置:firewalld 的规则看起来完全正确,端口也已开放,masquerade 也已启用

排查过程

1. 检查 firewalld 配置

首先检查 firewalld 的配置,发现一切看起来都很正常:

$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: dhcpv6-client mdns ssh
  ports: 80/tcp 443/tcp 22/tcp 55555/tcp 5001/tcp
  protocols:
  forward: yes
  masquerade: yes                    # ✅ masquerade 已启用
  forward-ports:
    port=5001:proto=tcp:toport=5001:toaddr=1.2.3.4  # ✅ 转发规则存在
  source-ports:
  icmp-blocks:
  rich rules:

配置看起来完美:

  • ✅ 5001 端口已开放
  • ✅ masquerade 已启用
  • ✅ 端口转发规则已配置

2. 发现关键问题

但是当检查实际的 iptables NAT 规则时,发现了问题所在:

$ sudo iptables -t nat -L -n -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

NAT 表是完全空的! 这说明 firewalld 的规则根本没有被应用到 iptables 中。

3. 根本原因分析

在较新的 Linux 系统(如 Amazon Linux 2023、RHEL 9、Rocky Linux 9 等)中,firewalld 默认使用 nftables 作为后端,而不是传统的 iptables。

虽然 nftables 是新一代的包过滤框架,但在某些场景下(特别是涉及 NAT 和端口转发时)可能存在兼容性问题,导致规则无法正确生效。

解决方案

核心:切换 firewalld 后端为 iptables

1. 修改 firewalld 配置文件

# 编辑配置文件
sudo vi /etc/firewalld/firewalld.conf

# 找到 FirewallBackend 这一行,修改为:
FirewallBackend=iptables

或者使用命令直接修改:

# 方法一:sed 替换
sudo sed -i 's/^FirewallBackend=.*/FirewallBackend=iptables/' /etc/firewalld/firewalld.conf

# 方法二:如果该配置项不存在,直接添加
echo "FirewallBackend=iptables" | sudo tee -a /etc/firewalld/firewalld.conf

2. 重启 firewalld 服务

sudo systemctl restart firewalld

3. 验证规则是否生效

重启后再次检查 iptables NAT 表:

sudo iptables -t nat -L -n -v

现在应该能看到完整的 NAT 规则了:

Chain PRE_public_allow (1 references)
 pkts bytes target     prot opt in     out     source               destination
    1    60 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:5001 to:1.2.3.4:5001

Chain POST_public_allow (1 references)
 pkts bytes target     prot opt in     out     source               destination
   14   888 MASQUERADE  all  --  *      !lo     0.0.0.0/0            0.0.0.0/0

完整配置步骤

如果你从头开始配置,以下是完整的步骤:

1. 切换 firewalld 后端(关键步骤)

# 修改配置
sudo sed -i 's/^FirewallBackend=.*/FirewallBackend=iptables/' /etc/firewalld/firewalld.conf

# 如果配置项不存在,添加它
sudo grep -q "FirewallBackend" /etc/firewalld/firewalld.conf || echo "FirewallBackend=iptables" | sudo tee -a /etc/firewalld/firewalld.conf

# 重启 firewalld
sudo systemctl restart firewalld

2. 配置端口转发

# 启用 masquerade(NAT 地址伪装)
sudo firewall-cmd --permanent --add-masquerade

# 添加端口转发规则
sudo firewall-cmd --permanent --add-forward-port=port=5001:proto=tcp:toaddr=1.2.3.4:toport=5001

# 开放端口(允许外部访问)
sudo firewall-cmd --permanent --add-port=5001/tcp

# 重载配置
sudo firewall-cmd --reload

3. 启用 IP 转发

# 检查当前状态
cat /proc/sys/net/ipv4/ip_forward

# 如果返回 0,需要启用
sudo sysctl -w net.ipv4.ip_forward=1

# 永久生效
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf

4. 配置 AWS 安全组

别忘了在 AWS 控制台配置安全组:

  • 源服务器(13.229.229.33)安全组

    • 入站规则:允许 TCP 5001 端口(来源:0.0.0.0/0 或特定 IP)
  • 目标服务器(1.2.3.4)安全组

    • 入站规则:允许 TCP 5001 端口(来源:13.229.229.33/32 或 0.0.0.0/0)

5. 验证配置

# 查看 firewalld 规则
sudo firewall-cmd --list-all

# 查看 iptables NAT 规则
sudo iptables -t nat -L -n -v

# 查看 IP 转发状态
cat /proc/sys/net/ipv4/ip_forward

# 测试端口转发
telnet 你的服务器IP 5001

常见错误提示及含义

在测试过程中,你可能会遇到不同的错误提示,它们代表不同的问题:

错误提示 含义 可能原因
Connection timed out 请求被丢弃,无响应 防火墙阻止、安全组未配置、服务未监听
Connection refused 端口可达但拒绝连接 端口未开放、服务未运行
No route to host 网络不可达 目标服务器防火墙拒绝、路由问题

为什么 nftables 会有问题?

nftables 是 Linux 的新一代包过滤框架,相比 iptables 有很多优势:

  • 更好的性能
  • 更简洁的语法
  • 更灵活的规则处理

但是,在某些情况下,nftables 可能存在以下问题:

  1. 兼容性问题:某些内核版本或系统配置下,nftables 的 NAT 功能可能不稳定
  2. 工具链问题:部分旧的网络工具或脚本只支持 iptables
  3. 调试困难:nftables 的规则检查和调试不如 iptables 直观

因此,对于需要稳定的端口转发功能的场景,使用 iptables 后端是更保险的选择。

总结

在 AWS EC2 上配置 firewalld 端口转发时,如果规则看起来正确但不生效,关键是检查并切换 firewalld 的后端为 iptables

# 核心命令
sudo sed -i 's/^FirewallBackend=.*/FirewallBackend=iptables/' /etc/firewalld/firewalld.conf
sudo systemctl restart firewalld

然后通过 iptables -t nat -L -n -v 验证规则是否真正生效。

这个问题在较新的 Linux 发行版上比较常见,希望这篇文章能帮助遇到类似问题的朋友快速解决!

参考资料

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论