IPv6-Support (ferm / iptables)

Running a Trellis-project on v1.23.0 and am having trouble regarding the IPv6-connectivity – I couldn’t find anything with regards to IPv6-support in the docs or here on the Discourse, only much older posts where it is stated that support is not available…?

Checking the entries for ip6tables-legacy I can see that there is a default DROP policy on INPUT, and there’s no rule allowing TCP port 443. Only port 22 (SSH) is allowed.

I was naiively thinking that this would be handled by default via Trellis and re-provisioning would “fix” any older setup / config-rules.

My questions would be:

  • Does Trellis support IPv6 by default? Since when?
  • What could be the issue for my project not being correctly configured?

Thanks a lot for chipping in…!

Some additional info (AAAA-records verified):

  • I have a project running on Trellis >= 1.23.0 & Ubuntu 22.04.5 which is available via IPv6
  • Another project running on Trellis >= 1.22.1 & Ubuntu 22.04.5 is not available via IPv6
  • Yet another project running on Trellis >= 1.23.0 & Ubuntu 24.04.3 is also not available via IPv6

So there is no real pattern to be made out here and running a diff of the projects doesn’t yield any clues to me…

I eventually found the culprit – Ubuntu 22.04 ships with two iptables backends side by side:

  • iptables-nft / ip6tables-nft – the modern backend backed by nftables (what ip6tables points to by default)
  • iptables-legacy / ip6tables-legacy – the old backend using the legacy kernel API

Both backends are evaluated by the kernel independently. A packet must pass through both rule sets. This means even if the nft rules are wide open, the legacy rules can still block traffic.

The Trellis/ferm setup writes rules via the nft backend (that’s what ip6tables -L -n shows – empty/ACCEPT). But ip6tables-legacy has a restrictive rule set with INPUT policy DROP that only allows:

  • ICMPv6 (hence ping6 works)
  • SSH on port 22
  • IPsec (UDP 500 + ESP)
  • Already-established connections

Ports 80 and 443 are not permitted in the legacy rules, so all inbound IPv6 HTTP/HTTPS traffic is silently dropped.

These legacy rules may come from Hetzner’s default server image or an initial provisioning script that ran before Trellis took over. Re-provisioning with Trellis doesn’t help because ferm only manages the nft backend and never touches the legacy tables…

Flushing the legacy rules and setting relevant policies to ACCEPT did the trick…!