Skip to main content
9 of 13
added 98 characters in body
init_js
  • 375
  • 2
  • 7
  • 17

Which address should be used to bind server sockets on IPv6 behind home router?

I'm trying to run a personal web service from my lan, on IPv6. I want it to be visible on the public internet, and behind a AAAA record. I need to balance ease of setup, and graceful reconfiguration when the IP prefix from my ISP change.

Which address should I bind to? A local IPv6 address + NAT, or should I embrace globally routable options pushed down to the host via prefix delegation?

My hosts are behind an OpenWRT router, IPv4 + IPv6. OpenWRT gets a /56 prefix delegated by my ISP. I’m using a SLAAC + DHCPv6 combo setup (aka stateless+stateful). The router runs iptables with a layer of config porcelain on top, and for ipv6 only allows wan-to-lan traffic of already-established connections.

I’m willing to give this no-NAT thing on IPv6 a go. I’m okay with punching ports/IPs open in the stateful firewall, but I would like to avoid address translation.

On my stateless+stateful IPv6 setup, my hosts on the lan do autoconfiguration, and also do DHCPv6 to get addresses on a ULA prefix (fd00:cafe::), so they get the following set of addresses:

2001:2:3:4:a8a8:efcf:d96d:1315/64   # slaac+privacy global
2001:2:3:4:22f:bcff:fe12:1234/64    # slaac+EUI64 (macaddr)
fd00:cafe::a8a8:efcf:d96d:1315/64   # slaac+privacy local
fd00:cafe::22f:bcff:fe12:1234/64    # slaac+EUI64 (macaddr)
fe80::21f:bcff:fe08:c07a/64         # link local

The 2001:2:3:4: addresses are routable on the public internet. The fd00:cafe:: are routable only locally on my subnet (ULA). The fe80: of course isn't routable.

The v6 IP I pick for my service will have to end up in an AAAA DNS record somewhere, so it would be preferable if it didn't change every hour or so.

  • The prefix delegated by my ISP doesn't seem to change, ever, until I reboot the router. So the globally routable prefix is usable with a little bit of dyndns goop.
  • The slaac+EUI addresses say a bit about my mac address, and I don't like that.
  • The slaac+privacy addresses are privacy-preserving, but rotate every few half-hours, and that is less desirable. Addresses stick around if they are still in use, but they would be released everytime I started the service (and dns would need to be updated).
  • Another option is to just statically pick a suffix I like for my service (e.g. ::d00d), with the same globally routable prefix and statically assign that to my nic, like so:
$ sudo ip -6 addr add 2001:2:3:4::d00d/64 dev eth0

(NOTE: I’m using OpenWRT, and I haven’t found a way to add a dynamic DHCP lease reservation for something like this (i.e. take global prefix, and slap "d00d" at the end). So static configuration on the host is perhaps necessary. )

Then in my applications, I could bind to that address only.

# ./myserver -l 2001:2:3:4::d00d/64 -p 8080

Now, once I’ve got a listening socket bound to a publically routable IP on the host, what's the best way to inform the router to let the SYN packets flow in for it? I need a hole punched here. UPnP, NAT-pmp?

Am I thinking about this the wrong way around? What’s the typical setup on IPv6?

Also, any opinions on binding on a device vs a single address? The indirection might allow addresses from ISP to change without needing a server restart.

init_js
  • 375
  • 2
  • 7
  • 17