Ubuntu – Forwarding external to internal port on azure: not accepting external connections

azureiptablesUbuntu

I have a service running on localhost:8111 on an Ubuntu 16.04 VM in Azure, and I'm trying to forward external traffic on port 80 to localhost:8111. However, external traffic is being rejected and I can't see what I've done wrong.

On the Ubuntu VM I edited /etc/sysctl.conf and uncommented this line:

net.ipv4.ip_forward=1

After rebooting, I added the following to iptables so that I could access port 80 port internally and externally:

$ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8111
$ sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8111

After doing that, I can verify that the port works from within the Ubuntu VM with curl http://localhost:80 and using the external address via curl http://example.org.

However, I can't access http://example.org from the internet.

I have an Azure Network Interface attached to the VM, set to 10.0.1.5, and it has a static Public IP, and IP Forwarding set to enabled. It is attached to a NSG that allows traffic on port 80 with any source and any destination

I think this should work—I can't see what I've done wrong.

Here's the output of iptables -t nat --list:

~$ sudo iptables -t nat --list
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8111

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8111

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Best Answer

There is one additional change we need to make:

sysctl -w net.ipv4.conf.all.route_localnet=1

By default this value is 0, which instructs the kernel to not route external traffic destined to 127.0.0.0/8. This is just for security as such traffic is not normal.

The iptables rule like this:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8111

Here is my test:

Ubuntu 16.04:

Private IP address: 10.0.1.4
Public IP address: 104.41.185.158
apache2 listen on localhost port 8111

root@jasonvm:/etc/apache2# netstat -ant | grep 8111
tcp        0      0 127.0.0.1:8111          0.0.0.0:*               LISTEN  

Here is the result:

enter image description here

Hope this helps.