Show pageBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ===== Setting up IPv6 NAT in Docker ===== Yes, I know NAT on IPv6 is evil. But Docker's IPv6 implementation is so flawed that this is the only feasible way to get egress traffic from containers working somewhat reliably. If you want your containers to be able to establish egress connections over IPv6 using the same source address as non-containerized services on the host - such as the reverse proxy - using NAT on IPv6 does make some sense. ---- \\ ==== Configuring Docker to use IPv6 ==== First, install Docker: <code bash> sudo apt install docker.io docker-cli </code> Then configure Docker to enable IPv6: <file json /etc/docker/daemon.json> { "ipv6": true, "fixed-cidr-v6": "2001:db8:db8::/64" } </file> Restart Docker: <code bash> sudo systemctl restart docker </code> You should now see an ''inet6'' address for the ''docker0'' interface: <code bash> $ ip addr show dev docker0 docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:35:12:16:5c brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 2001:db8:db8::1/64 scope global valid_lft forever preferred_lft forever </code> ---- \\ ==== Configuring the firewall to forward packets ==== By default, Linux does not allow packet forwarding, and Docker only manipulates the IPv4 forwarding rules when started, even when IPv6 is enabled. So you'll have to configure everything yourself. \\ === sysctl values === Create a file called ''/etc/sysctl.d/packetforwarding.conf'' and add these lines: <file bash /etc/sysctl.d/packetforwarding.conf> net.ipv6.conf.all.forwarding=2 net.ipv6.conf.all.proxy_ndp=1 </file> Then load them: <code bash> sudo sysctl -p /etc/sysctl.d/packetforwarding.conf </code> In some cases you have to reboot for this to actually delegate to your network interface. It can also help to set it manually once: <code bash> sudo sysctl -w net.ipv6.conf.ens3.forwarding=2 sudo sysctl -w net.ipv6.conf.ens3.proxy_ndp=1 </code> (Change ''ens3'' to the interface your server uses to connect to the internet.) \\ === Firewall rules === Start by installing UFW: <code bash> sudo apt install ufw </code> By default, UFW changes your iptables/nftables rules to deny all ingress traffic, allow all egress traffic and disable routed traffic. Keep that in mind when you enable it. Edit ''/etc/ufw/before6.rules'' to allow masquerading for the Docker subnet (or even a larger one if you want). Add these lines at the top of the file: <file bash /etc/ufw/before6.rules> # Docker *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 2001:db8::/32 -o ens3 -j MASQUERADE COMMIT </file> (Change ''ens3'' to the interface your server uses to connect to the internet.) To allow IPv6 NAT on the interfaces dynamically generated by ''docker compose'', set the default routing policy to ''Allow'': <code bash> sudo ufw default allow routed </code> Finally, you have to allow (some) ingress traffic to avoid locking yourself out when you enable the firewall. You have two options: 1. Allow all ingress traffic: <code bash> sudo ufw default allow incoming </code> 2. Allow ingress traffic on the ports you actually use: <code bash> sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp </code> This example allows only SSH, HTTP and HTTPS. Of course, add all the ports you want to be able to reach from the outside. All that's left is to enable the firewall: <code bash> sudo ufw enable </code> Your Docker containers should now, hopefully, be able to access the internet over IPv6. ----