I'm running openvpn on CentOS 7 with firewalld. I've enabled masquerading on the public (default) zone, and it works fine. However, I occasionally need to run services on localhost/, and the masquerading is messing that up. The services properly bind to, but the client code which tries to connect to it seems to be mapping the destination IP address of to the IP address for eth0, where the server is not listening (it was configured for only).

How do I limit the masquerading to only a specific subnet so openvpn still works, but I can also access services locally on localhost without masquerading interfering?

Another way to word my question: How do I prevent masquerading of the loopback address(es)?

Some ideas I've had, but can't figure out how to do (or do without breaking something else):

  • Limit masquerading to only for openvpn
  • Limit masquerading by moving the IP address for eth0 to another zone
  • Tolerate masquerading by moving the loopback interface to the trusted zone, and adding the IP address for eth0 as a source in the trusted zone

1 Answer 1


I found a solution:

  interfaces: eth0
  masquerade: yes

  interfaces: tun0
  masquerade: no

public (default)
  interfaces:      # not used
  masquerade: no

  interfaces: lo
  masquerade: no

For this to work, I had to explicitly declare that lo was in the trusted zone, tun0 was in the internal zone, and eth0 was in the external zone. To do that, I used (for example):

firewall-cmd --permanent --zone=external --add-interface=eth0
firewall-cmd --permanent --zone=internal --add-interface=tun0
firewall-cmd --permanent --zone=trusted  --add-interface=lo
firewall-cmd --reload

For eth0, it was also necessary to add ZONE="external" to /etc/sysconfig/network-scripts/ifcfg-eth0 for it to continue to work across reboots. This wasn't necessary for the other interfaces.

The actual services/ports open in the trusted and internal zone, I left to their defaults. I made sure the default zone (public) had ssh on it (which is default) for emergencies (like if an update renames the eth0 interface) and added the services I want to expose to the external zone.

masquerade was already on by default in the external zone, and off in the others.

This setup works with firewalld-0.3.9-14.el7.noarch I'm not sure why putting them in separate zones was necessary for it to exclude the loopback interface from masquerading (turning masquerading on sets the rule: -A POST_external_allow ! -i lo -j MASQUERADE, which looks sufficient to me, but I'm no expert). However, I found this bug which might be related and the issue could be fixed in future versions.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .