Building a Mostly IPv6 Only Home Network
varunpriolkar.com
varunpriolkar.com
I have my router set up to advertise two /64 prefixes on each LAN subnet: one from fddd:deca:fbad::/56* that I use for all internal communication, and one from 2001:5a8:xxxx:xxxx::/56 that is only used for talking to the internet. Every device I've ever tested supports this configuration flawlessly, including linux/apple/windows laptops, apple/android mobile devices, an IoT vacuum, and a 10+ year old VoIP phone.
My router is a Linux PC, so I can configure radvd however I want (no GUI, I just edit the configs over SSH). Maybe home routers won't let you do this.
* You're really supposed to pick a random prefix in fd00::/8, but uniqueness only matters if you intend to merge networks with somebody else later, I care more about it being easy to remember.
In my experience the ISP generally fixes a /64 for each customer. So if in the future you change your ISP, you might want to keep the remaining addresses same while just using a script to replace the preceding /64 address.
Their are people like OP who do this via a VPS provider that supports BYOIP and then tunnel to the VPS network, so there is a demand.
Also, I very much don't want all my outbound internet traffic to come from a permanent address range I am publicly known to own. I'd still want an ephemeral /56 for outbound traffic that changed from time to time.
Use SLAAC. It just works.
interface enp2s0f1 {
AdvSendAdvert on;
AdvManagedFlag off;
AdvOtherConfigFlag off;
IgnoreIfMissing on;
prefix ::/64 {
AdvOnLink on;
AdvAutonomous on;
};
RDNSS fddd:deca:fbad:1::10 {
AdvRDNSSLifetime infinity;
};
DNSSL internal.domain {
AdvDNSSLLifetime infinity;
};
};
I haven't yet found a way to specify a local NTP server though, which is a drag. So everything not manually configured (like the voip phone) talks to the local NTP over ipv4.Mine is all static. I run a bind9 forwarder for DNS, and KEA for dhcp4. I have a little list of machines/macs/addresses as the source of truth, and a pair of python scripts that generates kea-dhcp4.conf and a bind9 zone file from that table.
When I enabled IPv6, I just put all the SLACC addresses in that table, and made the python script generate AAAA records too. But this is honestly really stupid, I need to actually use mdns...
I thought about writing a little systemd oneshot that used rfc2136 dyndns updates for home. But it feels like reinventing the wheel a bit...
> When I enabled IPv6, I just put all the SLACC addresses in that table, and made the python script generate AAAA records too.
Er, isn't that just manual static assignment, then? Not SLAAC? Don't get me wrong, static addresses do make DNS easy...
Haha no, much dumber than that: I boot the machine, get the permanent SLAAC address it comes up with, put that in the static table, and re-run the script to generate the zone files. The downside is the address changes if you reinstall the OS, but I do that so rarely it honestly hasn't been a problem (and you can force the older MAC-based address generation if you want it to be stable). I wouldn't recommend this setup though...
I do also have some static addresses, like that DNS server address.
P.S. thanks for the funniest HN comment I've read in a while
[0] <https://datatracker.ietf.org/doc/html/rfc4861#section-4.6.2>
[1] <https://datatracker.ietf.org/doc/html/rfc4861#section-4.2>
Odd.
option dhcp6.name-servers <ADDR>;
option dhcp6.sntp-servers <ADDR>;
work to get my Linux systems an IPv6 DNS and NTP server (respectively) when I'm using ISC DHCPd and 'dhcpcd'. Perhaps your DHCPd and/or your DHCPc were either misconfigured or badly broken?It is a little weird to be using the 'sntp' option, but on the systems I have access to, the address passed back to the client is treated exactly the same as the DHCPv4 NTP information. ~Thirteen years ago, one of the ISC DHCP bigwigs seemed to be of the opinion that the DHCPv6 NTP Server Option was "badly broken" [0]. Perhaps that's why the 'sntp' option is used instead.
[0] <https://lists.isc.org/pipermail/dhcp-users/2013-June/016882....>
Well. From TFA:
So I decided to use Free Range Cloud service provider to lease a /48, which cost me around C$10/year. I also used their tunnel service to then route this over to me.
The link embedded in the pull quote is [0], which isn't maximally helpful, but it's useful. Approximately 60 seconds of poking around there brings us to [1], which quotes a "ARIN - /48 IPv6 lease ... Use on our network or yours" for $8/year with a $2 setup fee. That sounds a lot like what's mentioned in TFA.So. You tell me?
$ whois 2602:fed2:7e02::
...
NetRange: 2602:FED2:: - 2602:FED2:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
CIDR: 2602:FED2::/32
NetName: 10VPN-PRIMARY
NetHandle: NET6-2602-FED2-1
Parent: NET6-2600 (NET6-2600-1)
NetType: Direct Allocation
If that VPN provider goes out of business, he probably loses those addresses.There's another sense in which he owns the allocation... the one you constructed in your original question:
Do you actually own that /48? The problem with using the globally routable addresses internally is that your public /48 might change in the future, and and that will force you to change a bunch of internal stuff.
He's paying his money to get a statically assigned /48.It's not too surprising that you can't get this information out of a whois invocation. It is -however- a bit surprising that you weren't aware that whois couldn't tell you this.
[0] <https://www.arin.net/resources/fees/fee_schedule/#rsp-servic...>
[1] See section 4(c) of <https://www.arin.net/about/corporate/agreements/rsa.pdf>
If you don't care about collision resistance, why didn't you pick fd00:: ? That's way easier to remember than that jumble of letters you selected. It's actually my go-to subnet when someone claims that local-only IPv6 addresses are "hard to remember". fd00::1 is notably shorter than 10.0.0.1.
Without consulting documentation or otherwise querying external memory, tell me what is 10.1.1?
I find it much simpler for troubleshooting etc to have simple IPv4 addresses. But cool that it can be done :)
I've switched off IPv6 on my router anyway, I haven't yet needed it. My provider didn't offer it last time I checked but when they do enable it I don't want it suddenly popping up against an untested router configuration.
NAT is the devil.
If anyone replies to this with the myth that NAT is a security mechanism I will firmly, yet politely, point them to a network development course because they don't know what they're talking about and I'm sick of hearing it. It's not true, I will not entertain this falsehood anymore.
And yes I know that NAT has the same effect as a "deny all inbound" on IPv6. Which is something I would set there too if I did use IPv6 so I'd still have to do hole-punching anyway.
Conntrack is not always your friend, and even when it is: it's adding a lot of overhead.
https://www.tigera.io/blog/when-linux-conntrack-is-no-longer...
> For most workloads, there’s plenty of headroom in the table and this will never be an issue.
And yes, if you're doing thousands of connections per second then you should evaluate things more carefully for performance, but again... That's rather a lot.
Connection table of a single IP is as high (by default) as 16,383[0].
I've hit this limit personally, and due to limitations in stateful firewalling we had to move to stateless filters inside our network equipment instead.
[0]: https://learn.microsoft.com/en-us/troubleshoot/windows-clien...
I'm not contesting that it's completely possible to hit the limits in play, but 16k connections (per IP) is high enough that I don't think that's a common problem, even in public-facing web services. Granted, I suspect the services I've run professionally all dealt with it by making it the problem of a load balancer in front of the application and internal network, but... you probably have that anyways, so I'm still not seeing the problem.
NAT in general where if you need/want peer-to-peer (P2P) you're suddenly in the realm of STUN/TURN/ICE infrastructure. Depending on your ISP, there's also CG-NAT, in which case (double) hole punching is basically impossible.
If you're 'just' a user, then that may have been dealt with the for you by whatever app/service you're using (e.g., video game companies), but if you're the one having to push out the good/service, it's an entire layer of complexity that has to be dealt with.
https://lore.kernel.org/netdev/20260319151230.655687-1-ralf@...
I had the vendor publish their GPL drop, and their upstream vendor did not even have IPv6 support in the product ( the firmware init scripts & admin UI) . So the IPv6 support in the finished product was a rushed copy-paste of IPv4 setup.
I encourage full black box testing of your IPv6 setup, as IPv6 is not in the critical path for QA or consumers, so vulns can persist for years.
Either, NATv6 would become a thing, or instead I hope SLAAC would get deprecated and dhcpv6 would become mandatory so we could give out smaller than /64s
It's weird having a subnet size equal to a complete IPv4 Internet worth of IPv6 Internets but I believe the rationale was that you would never in practise run of out IPs in your subnet. A lot of Enterprise IPv4 headaches are managing subnets that are not correctly sized (organic growth, etc.). IPv6 is always routable for the same reason (companies reusing RFC1918 making connecting networks a pain).
There are different headaches with IPv6 - such as re-IPing devices if they move subnet - i.e. move physical location, or during a failover etc.
I'm not sure what the best practise there is as many enterprises don't use IPv6 internally. In my experience anyway.
Incidentally, if you find yourself experiencing an RFC1918 clash, one simple way of fixing it is to use NAT64 to map the remote side's RFC1918 into a /96 from your v6 allocation. You can write the last 32 bits of a v6 address in v4 format, so this leads to addresses like 2001:db8:abc:6401::192.168.0.10 and 2001:db8:abc:6402::192.168.0.10, which don't overlap from your perspective.
(If you wanted something simpler to type you could put them at e.g. fd01::192.168.0.10... but then you do start running the risk of collisions with other people who also thought they could just use a simple ULA prefix.)
One is quantitative: you have to remember that 2^48 is a much much bigger number than 2^32. With 2^32 IPv4 addresses, you have about 0.5 addresses per human being on the planet, so right away you can tell that stringent allocation policies will be needed. On the other hand, with 2^48 /48 ranges, there are about 8,000 ranges per human being.
So even if you hand a few /48s out free to literally everyone who asks, the vast majority will still be unallocated. A /48 is only about 0.01% of what could be said to be a "fair" allocation. (And yet, a /48 is so huge in absolute terms that even the vast majority of organizations would never need more than one of them, let alone individuals.)
The other is that unlike, say, the crude oil we pump out of the ground, IP address ranges are a renewable resource. If you hand out a free /48 to every person at birth, then long before you start running out of ranges, people will start dying and you can just reclaim the addresses they were using.
Really, just adding 2 bytes to IPv4 would have fixed everything and made it a lot simpler to move over. IPv6 is overkill and I think that really hurt its adoption. I remember being at uni and being told "this is the next big thing". In 1993. And it's not even a big thing now. Not on the user side anyway, I can still access everything from IPv4.
Considering how hard deploying a new L3 protocol is, we're only going to get one shot at it so it's a lot better to end up with too many addresses rather than too few.
L3 has nothing to do with MAC addresses anyway so I've always found that a pretty weird decision anyway. Sure, it avoids having to implement ARP but we need that again now anyway with the randomisation. And ARP is like a one-time in a few minutes kinda thing anyway.
I'm pretty sure that if we'd just gone for "a couple bytes extra" we'd have long been completely over. It's the whole L3 transition itself that suffers from the complexity. I remember it well in the 2000s, nobody in telecoms wanted to touch it. And when IPv6 was invented in '93 or so, the installed base was extremely small. It'd have been a piece of cake to get it over with then.
The aggregation necessarily "wastes" L3 addresses, so if you think you'll have enough machines to justify an L2 address size of n bits then that also implies needing an L3 address size of n+m bits, where m is a number that represents how densely packed your L3 address space is. Anything smaller than that will be too small to handle the full extent of your L2 address space.
RFC 3194 (https://www.rfc-editor.org/rfc/rfc3194.html) suggests we'd want something like 80 bits to handle EUI-64. 128 bits is the next power of 2 up from there.
> It was a pretty arbitrary decision to accommodate the MAC address inside the IPv6 address [...] Sure, it avoids having to implement ARP
You're thinking of SLAAC, which picks the address by slapping the MAC/EUI-64 into the right-hand 64 bits, but this is just a convenient way of picking the address bits. There's no special significance to those bits and you still need to do ARP.
> I'm pretty sure that if we'd just gone for "a couple bytes extra" we'd have long been completely over.
We still can't get people to stop hardcoding socket(AF_INET, ...) or manually crafting sockaddr_in structures. This is the minimum amount of work that will always be needed, regardless of how many extra bits are involved, and even this part hasn't been quick.
You now can have these devices connected to network called Internet.
Unlike IPv4 were the number of devices on the Internet in home network is one (the main router) or zero (in case if CGNAT) and the others just pretend.
Until the place you're VPNing to happens to use the same RFC1918 network address as your LAN (that is, your LAN is 192.168.10.x and the network on the other side of your work's VPN is also 192.168.10.x). Or either of them use the same RFC1918 network address libvirt is using for its virtual network. Or you want to route between several LANs (for instance, after a company merger) and some of them (but not all) were using the same RFC1918 network addresses.
All of this is avoided by using public addresses for LANs, but address scarcity makes that hard with IPv4 (unless it's a legacy LAN from the 1900s which happens to still use public addresses form the pre-NAT era).
There are indeed only a few private-reserved IPv4 ranges, and almost everyone prefers to keep things memorable and easy to type; you get a lot of 10.0.0.0/24, 192.168.0.0/24, 192.168.1.0/24 as a result. That, and common household routers tend to default to one of these three /24 subnets. (Hardly anyone seems to remember that 172.16.0.0/12 exists, feel free to use that if it happens to work for you.)
IPv6 does solve this issue in a few major ways, one of which is the greater expectation to rely on globally routable addresses, of which every one of your devices will have at least one such address. There's also fc00::/7 which is fairly equivalent to the IPv4 private ranges, though to avoid conflicts in random VPNs you should generate a random /64 prefix inside of this, otherwise you run the risk of everyone picking fc00::/64 because it's easy to remember/type (I'm guilty of this myself, but the VPNs I've configured just go into a random 172.16.0.0/12 subnet and no v6 assigned. I have the liberty that I currently don't need/use any VPNs that I haven't personally configured, and that may not hold true in the future.)
Many ISPs are pushing v4 users into CGNAT so they're easier and cheaper to manage.
This is a big reason why Netflix and YouTube are on v6. To avoid the cost of service over v4.
ipv6 headers are 40 bytes! routers have less thinking.
this visualisation might help to dive deeper - https://vectree.io/c/ipv6
It’s probably not a big deal and NAT etc. is no protection but it gave me the heebie jeebies.
Bad generalization. I'm sure policy about this differs a lot, but my consumer ISP definitely reassigns my home's v4 address periodically. I don't track it closely, but it seems that when my ONT power cycles more often than not it pulls a new v4 address.
Now, basing my privacy/security on this would be bad, but to GP's point, if I was using a static v6 block, not only would this address never change, each device in my LAN would have an extra identifier attached to it. External hosts wouldn't merely be able to identify "my house", but traffic from "my phone", "my kid's switch", and "my spouse's phone" would all have distinct addresses.
Of course, my ISP doesn't do v6 at all, so there's no dilemma :')
But it does seem like it would be far more likely de facto for an ISP to not randomly rotate v6 networks, except maybe to discourage hosting on consumer connections?
This is not true.
IPv6 stack allocates at least 3 addresses:
- Link-local - "Permanent" Address derived from the subnet and MAC - Temporary address that changes several times per day
The default address for new connections is always the temporary address. So IP-based tracking from outside your network will be no better than it was before from one day to the next—the /64 will be the only constant here, just as your router's WAN IPv4 is for v4 connections.
My understanding is v6 has two different autoconf schemes, DHCPv6 and a more "native" solution. Do these both always result in interfaces having multiple (routable) addresses?
Most of my IPv6 experience has been setting it up on aforementioned VPS, and being rewarded with slow OS updates, since NetBSD's default CDN, Fastly, blackholes PMTUD, so I had to drop the MTU on the interface just to get v6 TCP connections to work at all[0]. And for point-to-point networking in an overlay VPN, where I just discovered that Chromium has an 11-year outstanding "bug" where it refuses to perform AAAA lookups if you don't have public IPv6 routing.
[0] I could switch mirrors, but the bandwidth drop isn't quite bad enough for me to bother...
> My understanding is v6 has two different autoconf schemes, DHCPv6 and a more "native" solution. Do these both always result in interfaces having multiple (routable) addresses?
The answer to that is "yes," but only insofar as DHCP is _not_ the norm for IPv6 networks. If you're planning to use DHCP to assign network addresses in an IPv6 range, you would run it in addition to using automatic configuration, and DHCPv6 would be responsible only for the "permanent" IPv6 address. Automatically-configured addresses (via RA with SLAAC or whatever) would still create the temporary address that you'd use for outbound internet connectivity, and the DHCP address hangs around for your use in DNS and for hosting "permanent" services like a webserver or whatever.
You've hit on one of the subtler problems of IPv6 being that it requires more things being let through the edge firewall[0], but given a stateful IPv6 firewall on the client side, the onus is on the hosting service's admin to ensure that works correctly (AFAIK).
Also, v6 supports "privacy extensions", essentially randomizing the host portion of the address and periodically rotating it, so it is not accurate to say your address would never change.
> This is where DHCPv4 Option 108 comes into the picture. This simply tells the client that IPv6 only mode is preferred. Clients that do not honor this will get a IPv4 address as normal. Those who do have an option can setup 464XLAT to handle IPv4 literals and disable IPv4 addresses.