How to bind IPv6 server sockets behind home router using dynamic prefix delegation?

2

1

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 an AAAA record. I need to balance ease of setup, and graceful reconfiguration when the IPv6 prefix from my ISP changes.

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 (Telus in Canada). However, this prefix is not static. It changes once in a while, in the order of days. I can expedite change sometimes by doing resets.

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 leased addresses. On my ubuntu box:

192.168.1.4
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. fd00:cafe:: is a prefix I've configured in OpenWRT (ULA) for just my internal network. The fe80: of course isn't routable. OpenWRT does not lease out a 2001:2:3:4::4 in this configuration, by design (I would very much like that however).

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 slaac+EUI addresses say a bit about my mac address, and I don't like that.
  • The slaac+privacy addresses are a tad more privacy-preserving, but rotate every few hours, and that is less desirable. Addresses stick around if they are still in use, but they would be released every time I started the service (and dns would need to be updated -- which takes minimum 5min).
  • 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

Then in my applications, I could bind to that address only (or to "::" on the device holding that ip).

# ./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?

Update

I tried using the hostid dhcp setting in my OpenWRT leases /etc/config/dhcp. It supposedly allows specifing the last 32bits of a dhcpv6 reservation. I was hoping I to receive an extra IPv6 with the wan prefix and my chosen suffix, but no luck. The dhcp6 client on my host still doesn't receive that extra IP. Probably related to this odhcpd issue 61.

init_js

Posted 2016-09-05T20:49:26.677

Reputation: 275

Why bother? Just bind to the unspecified address, like everyone else does. – Michael Hampton – 2016-09-06T02:40:37.497

Binding to :: is a way to receive connections on all IPs in the list above, plus addresses of all other interfaces on the host. It will not open the router's firewall automatically. Which address would you use to populate DNS then? – init_js – 2016-09-06T04:36:03.387

Also of note: Telus does block ports 80/443 even on IPv6 (not sure how they handle business plans though) – jtl999 – 2016-12-29T08:11:44.443

Answers

2

If you are intending to configure an AAAA record, then configure that address as a static IP address on the host that requires a static IP address. DHCP can be used to serve static IP addresses, but it is a poor second choice solution.

OpenWRT has used dnsmasq for DHCP (v4 and v6) and DNS. dnsmasq can be configured to supply a static IPv6 address if the client using DHCPv6. It might be appropriate use these as a destination for a proxy or VIP (Virtual IP. The latest version of OpenWRT appears to use odhcpd for some if not all DHCP services.

Use the firewall to open ports from the Internet to the server. (The address you assigned will be its address from the Internet as well as your LAN.) You should be able to connect locally to the server without opening any ports on the firewall.

odhcpd does support static IP address by adding a host section to its configuration. I haven't my router to the lastest OpenWRT version, so I am using dnsmasq which can also provide RA and DHCPv6 services. You should be able to specify the static IP address at the bottom of the DHCP and DNS configuration page.

IPv6 should not require NAT, although they may be the destination behind a Proxy or VIP (Virtual IP). Build a /64 from the /56 delegated to you, and assign an address from that /64 to your web server. This is the address you should use. Your web server will need a Dynamic IP client that can update your DNS whenever it's address change. Until you get DHCP static IP addresses working, the MAC based address will be your stable address.

Address in the network block with fc00:/8 should not be used for communications with the internet. These are intended for use as unique local addresses, similar to the IPv4 private addresses.

You may need to develop your own dynamic IP address scripts. On the router you will need to update the firewall when the /56 changes, and may need to make some other changes. On the web server, you will need to update DNS, and possibly assign a new static IP address. (I think assignment on IP address prefix change may be simpler than DHCP static IPv6 address assignment.)

BillThor

Posted 2016-09-05T20:49:26.677

Reputation: 9 384

My version of OpenWrt (v15.05.1 chaos calmer) uses odhcpd to provide the dhcpv6 service to the network. dnsmasq is used, but only as a local DNS resolver I believe. In the stateless+stateful mode, odhcpd will only serve a single ipv6 address to the hosts ( https://github.com/sbyx/odhcpd/issues/61 ) -- I can't add a static entry. Adding a DHCPv6 reservation statically on the router is difficult given that the prefix (e.g. 2001:2:3:4:/64) is not known until odhcpc completes the DHCPv6-PD handshake with the ISP. I feel that's easier from the host because of all the available ip update hooks.

– init_js – 2016-09-05T22:39:37.547

I just noticed I'd missed my ULA address from the list. Adding it. – init_js – 2016-09-06T04:12:22.153

@init_js Just don't use DHCP if you want a static IP address. odhcp does support static address assignment. See the update to my answer. – BillThor – 2016-09-06T21:14:04.100

I don't think would be advisable to hardcode a full /128 host entry (manual: https://wiki.openwrt.org/doc/techref/odhcpd ) in the config if the network prefix is dynamic. There is however a hostid setting which might allow me to control the last 32 bits of the ipv6 address (a caveat on that: https://github.com/sbyx/odhcpd/issues/27 ). I suspect any hostid I pick will be appended only to the ULA prefix, not the wan prefix. But I'll give it a shot!

– init_js – 2016-09-06T22:54:27.183

@init_js Public web sites are usually behind static IP addresses, See if you can get a static allocation for your network. You should not bind to the WAN prefix. You should be getting a separate prefix for your LAN that you should bind to. You may want to consider running a web proxy on the OpenWRT router if you want to bind to the WAN prefix. This wwill work better with Dynamic DNS servers. – BillThor – 2016-09-07T02:08:24.050

My ISP, Telus, only gives static IPs to its business customers ($$$), sadly. They do delegate a whole /56 of public ipv6 addresses to my router however (via dhcp6c-pd), and that prefix changes infrequently. My hosts receive IPs from that prefix too (i.e. "wan prefix"). I'm trying to make the best with what I have. I meant public as in "on the public internet". The service is for personal uses (e.g. accessing my stuff remotely).

I have a local (ULA) prefix on my network, yes, fd00:cafe::/64. If I bind sockets to that, then I need a NAT in the router, which is what I was trying to avoid. – init_js – 2016-09-07T20:21:50.243

2@init_js Telus should assign a static /56 to you which would solve your issue. IPv6 adoption in Canada is years behind. There is no need for ISPs like Telus to not provide static IPv6 addresses to everyone, It may be worth it to send a letter to the CRTC. – BillThor – 2016-09-08T13:42:59.190

Ugh. agree. agree. agree. I had a feeling I was working with only second choice solutions from the get go. I'll develop my scripts and post them (or pointers to them) here. There might be another stackexchange site to help write this letter for effect. Thanks for all the help! – init_js – 2016-09-08T20:10:34.313