4

I'm trying to setup a firewalld rule to forward 80/tcp to 8080-8081, the rule was setup correctly, but seems only partially working.

The problem is that the traffic is always forwarded to 8080 not 8081, is anything wrong ?

Below is my env:

  • create two http servers on 192.168.30.30, listening on 8080 and 8081
  • setup a firewalld rule to do the port forward

    firewall-cmd --add-forward-port='port=80:proto=tcp:toport=8080-8081' --permanent

  • from a client, curl http://192.168.30.30:80 (which always forward to port 8080)

below is my firewalld settings:

firewall-cmd --list-all

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources: 
  services: ssh dhcpv6-client
  ports: 80/tcp
  protocols: 
  masquerade: yes
  forward-ports: port=80:proto=tcp:toport=8080-8081:toaddr=
  source-ports: 
  icmp-blocks: 
  rich rules:

sysctl -a | grep ip_forward

net.ipv4.ip_forward = 1
net.ipv4.ip_forward_use_pmtu = 0
Feng Xi
  • 1,005
  • 2
  • 11
  • 30
  • If I stop firewalld and setup a iptables rule, both 8080 and 8081 port will be forwarded to. Does anyone know why ? iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --random --to-ports – Feng Xi Jun 20 '18 at 04:53
  • Can you use `port=80-81` and see if `81` goes to `8081`. The documentation doesn't say about range being randomly chosen. So as per my understanding it lets you map a range to another range. For some reason firewalld doesn't seems to work in my VM, so may be you can confirm if my understanding is correct – Tarun Lalwani Jun 21 '18 at 11:21
  • Thanks Tarun for your comment. However it does not work. curl http://192.168.30.30:80 and http://192.168.30.30:81 will always be forwarded to port 8080, never goes to 8081. firewall-cmd --add-forward-port='port=80-81:proto=tcp:toport=8080-8081' --permant – Feng Xi Jun 22 '18 at 01:21

1 Answers1

0

tl;dr Firewalld does not specify random when using a DNAT range.

The port range is passed to iptables/nftables which in turn makes use of connection tracking in the kernel. Connection tracking is what's actually doing the DNAT (forward port). It selects a port from the range. By default it searches through the range linearly. So if connection tracking does not currently have an entry for the tuple (dip, sip, dprot, sport, etc), then 8080 will be used. Only if all pairs of (8080, sport) are already in use, only then will dport 8081 be considered.

You should file an upstream firewalld issue. I think using random in the generated DNAT rule will give the expected results.

erig
  • 131
  • 1
  • 3