I use LXD to create virtual servers on my main system to experiment around with stuff I might not want to install directly. It’s simple, fast and works well.
I was curious if I could use it to do the same thing on a cloud server at Hetzner. The only problem was how to access the LXD container from outside. They are assigned IP4 addresses but those aren’t routable. However, the IPv6 address are routable.
Starting with that idea, I created a new Hetzner Ubuntu 20.04 server.I use a script to do this but you can create one any way that works for you.
I logged into the cloud server and ran the following to get everything set up:
sudo apt update
sudo apt upgrade
sudo apt install snapd
sudo snap install lxd
sudo usermod -a -G lxd demo
sudo lxd init
This updates the system, installs snap, uses snap to install lxd and then assigns the lxd group to my user called demo. You can just follow the defaults in the lxd init dialogs to get a basic lxd configuration.
After that,
lxc launch ubuntu:20.04 c1
lxc list
creates a new container running Ubuntu 20.04. From the list output, you can see the IPv6 address for the container.
The next thing is do a routing from the IPv6 address of the server to the container using ip6tables. It’ll look something like this:
sudo ip6tables -t nat -A PREROUTING -d 2a01:4f9:c010:e67b::2 -j DNAT --to-destination fd42:6a31:6326:d3db:216:3eff:fe60:86f6
The first address is the IPv6 address of the server the second address is the IPv6 address for the container.
Now, you can add the ssh keys from the server to the container and restart ssh:
cat ~/.ssh/authorized_keys | lxc exec c1 -- sh -c "cat >> /home/ubuntu/.ssh/authorized_keys"
lxc exec c1 -- systemctl restart ssh
Now, you should be able to connect to the container from the outside with ssh -i ~/.ssh/<your key here> ubuntu@2a01:4f9:c010:e67b::2
The ip6tables configuration you made above is only good until a restart and you have to use iptables-persistent to make it stick across reboots of the server. That can be done with
sudo apt install iptables-persistent -y
This will ask you if you want to persist the rules for both v4 and v6. Answer yes and you should have a durable path to the container.