The Problem
Have been hunting this down for quite some time now: several virtual hosts weren’t able to connect to security.debian.org. First I thought it was me, even though I had all the ingredients for IPv6-forwarding to work (this is the host):
*filter :FORWARD DROP [0:0] -A FORWARD -p ipv6-icmp -j ACCEPT -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Of course, net.ipv6.conf.*.forwarding was set on the host. That should be enough to forward all outgoing connections and drop incoming, right? And it does, for pretty much any host, except security.debian.org (AKA as lobos.debian.org and villa.debian.org). There may be more, but that one caught my attention, because apt update hung just there (ftp.de.debian.org worked, btw).
First I thought that it was the MTU, but that was pretty much a red herring. After a while I realized that it was working when the FORWARD policy was ACCEPT, but of course that wasn’t a viable solution. So I dug deeper: Strangely enough, with the policy back to DROP and this rule:
-A FORWARD -d <VM-IPv6> -p tcp -m multiport \ --sports 80,443 -j ACCEPT
it also worked, but this wasn’t enough:
-A FORWARD -s <VM-IPv6> -j ACCEPT
WTF? Fortunately I had a working virtual machine (also debian 8.6, same kernel), so I ended up comparing the IPv6-sysctl values (sysctl -a | grep ipv6).
The solution
As it turned out, the only difference was that the working virtual machine had net.ipv6.conf.*.forwarding enabled. So I added
net.ipv6.conf.all.forwarding=1 net.ipv6.conf.default.forwarding=1
to /etc/sysctl.conf of the failing virtual machine, rebooted and then it finally worked ™! I don’t have the slightest clue why this is necessary, though. The VM is the final receiver, the end of the chain, but certainly not a router! Maybe it’s a kernel bug, I don’t know… I’m just glad it works 🙂
Just calling sysctl -w doesn’t do it, btw. You have to take the interface down and up again to take effect, hence the reboot…