Skip to main content
2 of 13
Formatting.
Giacomo1968
  • 56.1k
  • 23
  • 167
  • 214

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.

Which address should I bind to? The usual IPv4-style wan IPv6 IP + 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.

On IPv4, I would bind the socket to an IPv4 address on the LAN, either statically configured or from a DHCP reservation. I would then push my router's WAN IPv4 into dynamic DNS, and use NAT to forward ports. IPv6 gives so many more options.

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 trying to do it without 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 public IPv6 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 extensions are random and 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). So static configuration on the host it is it seems. )

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?

init_js
  • 375
  • 2
  • 7
  • 17