How do you port forward a privileged sub-1024 port to a non-privileged 1024+ port with firewalld?

The Question

How do you port forward a privileged sub-1024 port to a non-privileged 1024+ port with firewalld?

The Reason

Why we are doing this? We want to be able to switch the non-privileged 1050 port on the gateway and use a different upstream mail server. For example, to test a different spam solution, use port 1051 to send mail to a different mail server with a different spam filtering solution.

The mail servers automatically connect to the gateway when they start. The automatic connect can only happen on non-privileged ports that are 1024+.

The Layout and Setup

Layout

+--------+         +---------------------+         +----------------+
|  WAN   |         |                1050 | <-      |                |
| Client |         |       Gateway       |    \    |   Mail Server  |
|        |  <--->  | 25                  |      -> | 25             |
+--------+         +---------------------+         +----------------+

Setup Firewall

Clear the firewall, open the port, set the port forward, and add a few services.

root@gateway:~# firewall-cmd --reload
root@gateway:~# firewall-cmd --zone=public --add-port=25/tcp
root@gateway:~# firewall-cmd --zone=public --add-forward-port=port=25:proto=tcp:toport=1050
root@gateway:~# firewall-cmd --add-service={http,https,smtp}

Verify Firewall

Confirm the firewall settings...

root@gateway:~# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: etho0
  sources: 
  services: dhcpv6-client http https smtp ssh
  ports: 25/tcp
  protocols: 
  masquerade: no
  forward-ports: port=25:proto=tcp:toport=1050:toaddr=
  source-ports: 
  icmp-blocks: 
  rich rules: 

This is what we expected to see in firewall rules.

The Result

This is what we get when we telnet the upstream mail server on the gateway...

root@gateway:~# telnet localhost 1050
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 debian10email.debian10email ESMTP Postfix (Debian/GNU)

This is what we get from a remote client machine...

client@client123:~$ telnet gateway.example.org 25
Trying <IP_of_gateway>...
Connected to gateway.example.org.
Escape character is '^]'.

We are expecting to also see the 220 debian10email.debian10email ESMTP Postfix (Debian/GNU) line, but are not.

Sanity Check...

The Test

Just to confirm the port forward rules are being written correctly, we...

  • Open port 1025 on the firewall.
  • Port forward 1025 to 1050
  • And then check what we see on the remote client.

Adjust firewall

Clear the firewall, open the port, set the port forward, and a few services.

root@gateway:~# firewall-cmd --reload
root@gateway:~# firewall-cmd --zone=public --add-port=1025/tcp
root@gateway:~# firewall-cmd --zone=public --add-forward-port=port=1025:proto=tcp:toport=1050
root@gateway:~# firewall-cmd --add-service={http,https,smtp}

Verify Firewall

root@gateway:~# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: etho0
  sources: 
  services: dhcpv6-client http https smtp ssh
  ports: 1025/tcp
  protocols: 
  masquerade: no
  forward-ports: port=1025:proto=tcp:toport=1050:toaddr=
  source-ports: 
  icmp-blocks: 
  rich rules: 

The Result

client@client123:~$ telnet gateway.example.org 1025
Trying <IP_of_gateway>...
Connected to gateway.example.org.
Escape character is '^]'.
220 debian10email.debian10email ESMTP Postfix (Debian/GNU)

We have the expected 220 debian10email.debian10email ESMTP Postfix (Debian/GNU) line, so the firewall is port forwarding as expected.

Conclusion

Forwarding between privileged and non-privileged ports is different from forwarding between non-privileged ports.

How do we port forward a privileged sub-1024 port to a non-privileged 1024+ port with firewalld on Debian 10 Buster? If there is an answer somewhere, please point it out. We have not been able to find it.


Your firewalld configuration looks correct. Is the machine you tested from allowed to make outgoing connections to port 25? Try from some other machine.