Reference: Forward port to LXC guest using UFW, answer by Steve Zahn. March 17, 2014.
The lxd service can be used to manage lxc system containers on Linux hosts, very much like Docker does for application containers. One Docker feature that LXD lacks is a native parameter for routing container ports so they can be accessed on the network beyond the lxd host. Routing using the iptables command
On an lxd host protected by the standard iptables kernel firewall, the following command will route external traffic to a specific port of a specific container:
$ sudo iptables -t nat -A PREROUTING -i ens3 -p tcp --dport 8080 -j DNAT --to 10.1.0.5:80
In the example above the lxd host's address is assigned to an interface named "ens3", the container has an address of 10.1.0.5 and the target service is using port 80 at that address. The port external traffic will be routed through is 8080. If the host's address were assigned to a bridge called "br0", then "-i" would be set to that name instead:
$ sudo iptables -t nat -A PREROUTING -i br0 -p tcp --dport 8080 -j DNAT --to 10.1.0.5:80
Note that routing can be done for any port not already being used by another service on the lxd host.
Esto es iptables, pueden usar todos los otros parámetros que conocemos, por ejemplo, si solo deseamos redireccionar tráfico de una IP en específica, sería agregando -s … por ejemplo redireccionaré solo el tráfico que venga desde 10.10.0.51:
iptables -t nat -A PREROUTING -p tcp -s 10.10.0.51 --dport 80 -j DNAT --to-destination 10.10.0.2:443
O bien una red entera (/24):
iptables -t nat -A PREROUTING -p tcp -s 10.10.0.0/24 --dport 80 -j DNAT --to-destination 10.10.0.2:443
También podemos especificar la interfaz de red con -i :
iptables -t nat -A PREROUTING -p tcp -i eth1 --dport 80 -j DNAT --to-destination 10.10.0.2:443
Directly invoking the iptables command will not work when the host firewall is controlled by ufw. Instead, some configuration changes to ufw need to be made. To configure ufw:
First, be sure to allow access to the port to be exposed:
$ sudo ufw allow 8080
Next, edit /etc/default/ufw to set MANAGE_BUILTINS=yes (the default is "no").
Then edit /etc/ufw/before.rules to insert the following lines at the top of the file before the *filter section:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -i ens3 -p tcp --dport 8080 -j DNAT --to 10.1.0.5:80
COMMIT
If the interface were a bridge named "br0", use the following instead:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -i br0 -p tcp --dport 8080 -j DNAT --to 10.1.0.5:80
COMMIT
Finally, restart ufw:
$ sudo ufw disable && sudo ufw enable
Testing rule iptables command
This command will list all nat rules, of which your new rule is part:
$ sudo iptables -L -n -t nat
Reference: How to check PREROUTING list. Answer by Yuriy Zhigulskiy. January 5, 2017. nmap port scan
I like to use nmap for quickly scanning to see what ports are open on a host. First, check the container:
$ sudo nmap -p 80 10.1.0.5
Then the lxd host:
$ sudo nmap -p 8080 mylxdhost
Removing the rule without rebooting
Where ufw is managing iptables, you'll need to edit before.rules to remove the PREROUTING directive and then restart ufw. Otherwise, first list all nat rules by line number:
$ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 DNAT tcp -- anywhere anywhere tcp dpt:http-alt to:10.1.0.5:80
Then delete by rule number:
$ sudo iptables -t nat -D PREROUTING 1
Reference: SvennD, Remove iptables PREROUTING NAT rule. March 14, 2017.
Here are the commands to run on the host. You only need the name of the container to perform the setup. In my example I’ll use mycontainer.
lxc config device add mycontainer myport80 proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
lxc config device add mycontainer myport443 proxy listen=tcp:0.0.0.0:443 connect=tcp:127.0.0.1:443
What we do here is:
We add a proxy device on container mycontainer, giving it an arbitrary name (myport80).
We set it up to listen on all (0.0.0.0) network interfaces on the host, port 80. You can change the IP address to something more specific, if you want to.
We set it up to make connections to the container mycontainer on the 127.0.0.1 (localhost) interface at port 80. PREVIOUS GUIDES SUGGESTED TO USE localhost. DOES NOT WORK ANYMORE; PLEASE USE 127.0.0.1 INSTEAD!
To verify that LXD is listening on port 80 (http), run
$ sudo lsof -i -n | grep http
lxd 2157 root 5u IPv6 668213 0t0 TCP *:http (LISTEN)
lxd 2157 root 8u IPv6 668213 0t0 TCP *:http (LISTEN)
To remove a proxy device, run
lxc config device remove mycontainer myport80