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:

    fd00:cafe::4/128                    # ULA local (by dhclient -6)
    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.