NAT port forwarding

I’m trying to forward some ports of the NUC Balena is running on to other devices using iptables. However I’m not able to make it successful. (I’m just using the local IP of the device so nothing has to go via the internet).

What I used to do before we were running Balena was:

iptables -t nat -A PREROUTING -p tcp --dport 1011 -j DNAT --to-destination 10.39.46.11:22
iptables -t nat -A POSTROUTING -j MASQUERADE  # Enable port forwarding

Here 10.39.46.0/24 is a LAN where all the devices are connected to (e.g. sensors, NUC, PLC). This rule would allow me to ssh into a sensor using the (W)LAN IP of the NUC and port 1011. Are the rules Balena sets by default in the iptables conflicting with these rules? Is there something else I should take into account?

Hi, iptables works in the same way under balenaOS and nothing should be conflicting with enabling port forwarding.

A few things you may check:

  1. if you are running the iptables command from a container in a multicontainer application (with a docker-compose.yml file), then you will need to add to the following service configuration to the container in the docker-compose.yml file:
        network_mode: "host"
        cap_add:
            - NET_ADMIN
  1. Make sure IP forwarding is enabled in the kernel: sysctl net.ipv4.ip_forward should return 1.

  2. Run ip route to make sure 10.39.46.0/24 is a routing entry. You may also try to ssh to 10.39.46.11 directly from the host OS to make sure access is available.

Please let us know whether any of this was of help.

Thanks,
Zahari

Thanks for the reply.

  1. I’ve added the cap_add since I was missing this
  2. This is enable in the kernel
  3. 10.39.46.0/24 is indeed a routing entry

However still no luck.
Relevant entries in the NAT table of iptables:

-A PREROUTING -i wlan0 -p tcp -m tcp --dport 1003 -j DNAT --to-destination 10.39.46.2:1954
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 1011 -j DNAT --to-destination 10.39.46.11:22
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 2111 -j DNAT --to-destination 10.39.46.12:2111
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 10.114.101.0/24 ! -o balena0 -j MASQUERADE
-A POSTROUTING -s 10.114.104.0/25 ! -o supervisor0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o br-3116f98c1556 -j MASQUERADE
-A POSTROUTING -s 10.114.101.2/32 -d 10.114.101.2/32 -p tcp -m tcp --dport 8081 -j MASQUERADE
-A POSTROUTING -j MASQUERADE

Should there also be entries in the default table? Since the FORWARD rules are default on DROP as far as I can see.

iptables -S
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT

I should try this out myself and see what results will I get. I can do it on Monday though as it is almost evening here at my location. Will that work for you?
Thanks,
Zahari

1 Like

Would be great if you could test this out!

Hi,
It is because of the default forward policy is set to drop.
Can you please try adding iptables -P FORWARD ACCEPT and let me know if that works for you.
Thanks,
Zahari

If I apply that change, it works. So to keep it more closed, I should add FORWARD rules for the ports that I want to expose for port-forwarding?

Hi, yes, this is correct. You may narrow the scope of the rule indeed.
Thanks,
Zahari