why firewall-cmd --add-forward-port does not forward

Hi, I have standalone leap server in my lan with just one eth1. I have ports forwarded from public IP to this server. I’d like to forward some port to other machine in lan.

What I did:


sudo firewall-cmd --add-forward-port=port=55555:proto=tcp:toport=5900:toaddr=10.0.0.163 --permanent
sudo firewall-cmd --add-port=55555/tcp --permanent
sudo firewall-cmd --reload

This is my setup:


me@server:~> sudo sysctl -a |grep -i eth1.forwarding
net.ipv4.conf.eth1.forwarding = 1
net.ipv6.conf.eth1.forwarding = 0

me@server:~> sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth1
  sources: 
  services: dhcpv6-client samba ssh
  ports: 55555/tcp
  protocols: 
  forward: no
  masquerade: no
  forward-ports: 
        port=55555:proto=tcp:toport=5900:toaddr=10.0.0.163
  source-ports: 
  icmp-blocks: 
  rich rules: 

I don’t know if I should, but I see nothing listening at 55555 via sudo netstat -tunlp

When I forward using other tool, like socat, I see it listening and it works, it will connect me to remote ip:


me@server:~> socat TCP-LISTEN:55555,fork TCP:10.0.0.163:5900

I’d like to use firewall-cmd, because it will eat less memory, I don’t have to create a service to have socat started on startup, etc. So what is the deal with firewall-cmd? I think I do everything by the book, yet it does not work. I have virtualbox installed on server, apache, samba, nothing unusual.

I came across some thread, that libvirt can interfere with firewall-cmd, but I don’t know, if virtualbox uses it.

Btw. is it possible to forward port somehow and still retain the original ip for the remote machine? When I socat forward I (naturaly) see the connection coming from server ip, not the originating ip, but on server I still see the real originating ip, not the ip of router from my ISP, which made the forward. And sorry for the typo in title, but I don’t know how to edit the thread title.

Thank you.

That is correct.

Btw. is it possible to forward port somehow and still retain the original ip for the remote machine?

This is exactly what netfilter port forwarding (which is configured using firewalld) does.

Anyway - your title says “does not forward” but you did not show any evidence of that. What is source address from which you are trying to connect? Is your host in the same network as 10.0.0.163? You really need to provide more complete description of your topology.

Hello and thank you for your time. Leap server ip is 10.0.0.2, my pc (which I’m connecting from) is 10.0.0.100 and I want to connect to 10.0.0.163:5900 (vnc) via 10.0.0.2. Directly I can connect, when I run socat on server, I can connect too. But when I try to connect via firewall-cmd forward, I cannot connect to target 10.0.0.163. Why I don’t know. What kind of evidence would help? Socat way works, firewall-cmd does not. I’m using vnc viewer on 10.0.0.100, and vnc server on 10.0.0.163, but it would be the same for any other service.

When I want to run socat, I have to remove the firewall-cmd forward first, using:

sudo firewall-cmd --remove-forward-port=port=55555:proto=tcp:toport=5900:toaddr=10.0.0.163 --permanent
sudo firewall-cmd --reload
socat TCP-LISTEN:55555,fork TCP:10.0.0.163:5900

Now I can connect vnc client on 10.0.0.100 to 10.0.0.2:55555 and it connects me to 10.0.0.163:5900. When I stop socat, add forward again, reload firewall, I cannot connect to 10.0.0.2:55555.

This is what I’m doing in short: 10.0.0.100->10.0.0.2:55555->10.0.0.163:5900

Why? They are all in the same network. They have direct access to each other. Why you want to jump through the third host?

But when I try to connect via firewall-cmd forward, I cannot connect to target 10.0.0.163. Why I don’t know.

This is well known issue with port forwarding in the same network. Your host 10.0.0.163 sees incoming connection request from host 10.0.0.100 and answers directly to the source address. But host 10.0.0.100 does not have any pending connection to the host 10.0.0.163 - it tried to establish connection to the host 10.0.0.2. So host 10.0.0.100 ignores reply to connection request and attempt to establish connection fails. This is documented e.g. in Linux 2.4 NAT HOWTO: Destination NAT Onto the Same Network

You need additional SNAT rules as per above link, but firewalld does not support it, the only possibility is direct rules.

I see, thank you, I had no idea about this not-that-well-known-issue-to-me :shame: Of course I don’t need to do this in local lan when they see each other directly :slight_smile: I tried this from remote location first, but it behaved the same, so I started to experiment on local lan.

When I try this from remote location, and I connect to the public IP:55555, which has ports forwarded to leap server, where is running firewalld and firewall-cmd should forward, it does not work too :frowning: When I run socat on the leap server, it works fine also from remote. So this “well known issue” applies also when I connect from remote? Sadly I have no experience in iptables, I have looked at the netfilter page you mentioned, but it looks so complicated. So I will have to learn iptablest, right? Would you mind giving me an exaple to my situation?

Yes. The critical piece is where you forward. Host 10.0.0.163 has direct route (likely default route) to remote client and has no reasons to answer back via host 10.0.0.2.

Both forward and return traffic for this connection must pass via the host 10.0.0.2 for this port forwarding to work. If this host were actual gateway between two networks, this would be automatic.

Based on netfilter link, it would be something like

firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -d 10.0.0.163 -p tcp --dport 5900 -j SNAT --to 10.0.0.2

But note, that if this works it means 10.0.0.163 will never see actual source address and that is what you want to avoid.

I still do not understand why you need it. You still need to somehow forward port 55555 from external interface to 10.0.0.2 host; what prevents you from forwarding directly to 10.0.0.163 which is in the same network?