要让 CentOS 7 真正充当路由器,首先必须开启内核转发功能,也就是 ip_forward。这一步是基础中的基础——若未开启,后续所有 iptables 或 firewalld 规则都将失效,因为数据包根本无法进入转发流程。

CentOS 7 如何开启转发功能
确认并启用内核 IP 转发
内核中有一个参数 net.ipv4.ip_forward,默认值为 0,即关闭状态。如果只修改配置文件而不执行生效命令,或者仅用 echo 临时写入(重启后失效),都无法持久生效。因此需要同步采用两种方式:临时激活与永久配置。
- 临时启用(立即生效,重启后失效):
echo 1 > /proc/sys/net/ipv4/ip_forward - 永久启用:编辑
/etc/sysctl.conf,确保包含如下行:
net.ipv4.ip_forward = 1
然后执行sysctl -p重新加载配置 - 验证是否生效:
sysctl net.ipv4.ip_forward应返回net.ipv4.ip_forward = 1
或执行cat /proc/sys/net/ipv4/ip_forward应显示1
firewalld 中必须开启 masquerade
即便 ip_forward 已经打开,firewalld 默认仍会阻止转发流量。尤其在 NAT 场景下,--add-masquerade 不是“可选”步骤,而是必要的操作。
- 首先确认当前区域(通常为
public):
firewall-cmd --get-default-zone - 开启伪装(缺一不可):
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload - 检查状态:
firewall-cmd --query-masquerade应返回yes才算成功 - 常见误区:忘记添加
--permanent参数,或在 reload 前未加入 permanent,导致重启后配置丢失
避免 iptables 与 firewalld 混用
CentOS 7 默认采用 firewalld,如果手动编写 iptables 规则却没有停用 firewalld,两者规则就会相互冲突,通常会导致转发静默失败。
- 方案一:停用 firewalld:
systemctl stop firewalld
systemctl disable firewalld
随后改用 iptables 配置(需确保已安装iptables-services) - 方案二:坚持使用 firewalld:所有端口转发、DNAT/SNAT 操作都通过
firewall-cmd --add-forward-port完成,避免直接操作 iptables 的 nat 表 - 检查冲突:执行
iptables -t nat -L -n,若看到大量 firewalld 自动生成的链(如FORWARD_direct),说明 firewalld 仍在控制,此时手写的 iptables 规则很可能被忽略
转发不生效?重点检查这三个环节
很多“配置完成但无法连通”的问题,往往卡在更底层的网络连通性或策略上。
- 源主机路由:内网客户端的默认网关必须指向这台 CentOS 7 机器的内网 IP,仅配置 IP 而不设置网关是不够的
- 目标主机响应:被转发的目标服务(例如 192.168.1.100:80)必须真正在监听,并且其自身的防火墙未拦截该流量
- FORWARD 链默认策略:firewalld 默认将
FORWARD链设为REJECT,仅靠 masquerade 并不够;若要实现端口转发,还需显式放行对应协议与端口,例如:
firewall-cmd --permanent --add-port=80/tcp
或使用更精确的 rich rule 来放行转发路径
真正棘手的往往不是开启某个开关,而是多层策略叠加后产生的隐式拒绝。可以将整个流程简化为:ip_forward 是门,masquerade 是钥匙,firewalld 的 FORWARD 策略是门锁,而客户端与服务端的网络可达性则是门前的路。缺少任何一环,流量都无法到达目的地。
