4.6 KiB
sixnix
IPv6 WireGuard tunnels with optional BGP failover.
Motivation
My ISP gives me a single /64
and it's dynamically assigned. Can't have multiple networks with functional autoconfiguration. Tunnel brokers like Hurricane Electric would work but my ISP uses CGNAT which makes that setup tricky if not impossible. They also do not have any exit nodes in the region I want.
Linode provides a routed /56
and 1TB traffic at 1 Gbit/s for with their cheapest $5/month VPS. That's 256 /64
subnets.
Solution 1: Simple WireGuard tunnels
Just a plain WireGuard tunnel to route the /56
to your home network.
With a /56
you can carve out a /60
for WireGuard endpoints and you're left with 15 /60
subnets. Share it with friends!
Client subnet | WireGuard subnet | |
---|---|---|
2001:db8::/60 | 2001:db8:0:f0::a/127 | 1 |
2001:db8:0:10::/60 | 2001:db8:0:f1::a/127 | 2 |
2001:db8:0:20::/60 | 2001:db8:0:f2::a/127 | 3 |
2001:db8:0:30::/60 | 2001:db8:0:f3::a/127 | 4 |
2001:db8:0:40::/60 | 2001:db8:0:f4::a/127 | 5 |
2001:db8:0:50::/60 | 2001:db8:0:f5::a/127 | 6 |
2001:db8:0:60::/60 | 2001:db8:0:f6::a/127 | 7 |
2001:db8:0:70::/60 | 2001:db8:0:f7::a/127 | 8 |
2001:db8:0:80::/60 | 2001:db8:0:f8::a/127 | 9 |
2001:db8:0:90::/60 | 2001:db8:0:f9::a/127 | 10 |
2001:db8:0:a0::/60 | 2001:db8:0:fa::a/127 | 11 |
2001:db8:0:b0::/60 | 2001:db8:0:fb::a/127 | 12 |
2001:db8:0:c0::/60 | 2001:db8:0:fc::a/127 | 13 |
2001:db8:0:d0::/60 | 2001:db8:0:fd::a/127 | 14 |
2001:db8:0:e0::/60 | 2001:db8:0:fe::a/127 | 15 |
Basic configuration
{
inputs.sixnix.url = "git+https://code.planet-express.in/konarak/sixnix.git";
outputs = { nixpkgs, sixnix, ... }: {
nixosConfigurations.tunnel-server = nixpkgs.lib.nixosSystem {
modules = [
sixnix.nixosModules.default
{
sixnix = {
enable = true;
hostname = "tunnel-server";
domain = "example.com";
};
wireguard.interfaces = [{
interface = "wg0";
serverPort = 51820;
serverAddress = "2001:db8:a7c4:0:f0::a/127";
clientAddress = "2001:db8:a7c4:0:f0::b/127";
clientSubnet = "2001:db8:a7c4::/60";
serverPrivateKeyFile = "/run/secrets/wg0-server-private";
clientPublicKeyFile = "/run/secrets/wg0-client-public";
}];
}
];
};
};
}
How it works:
- Your router uses the ISP-provided IPv6 to connect to the WireGuard server
- Interfaces get
/64
s from the delegated/60
with router advertisement enabled - All traffic from clients goes out to the internet via Linode
Solution 2: WireGuard tunnels with BGP for failover
Want redundancy? Run two Linodes in the same datacenter and use BGP to share a single /56
between them. If one server goes down, BGP automatically fails over to the other.
Cost: $10/month + tax for two Linodes with pooled 2TB traffic quota.
BGP configuration
{
sixnix = {
enable = true;
hostname = "tunnel-primary";
domain = "example.com";
bgp = {
enable = true;
peers = [
"2001:db8:9f2b::1" # BGP peer addresses (e.g., Linode route servers)
"2001:db8:9f2b::2"
"2001:db8:9f2b::3"
"2001:db8:9f2b::4"
];
advertisedSubnets = [ "2001:db8:a7c4::/56" ];
routeMap = "primary"; # or "secondary" for the backup server
};
};
wireguard.interfaces = [{
interface = "wg0";
serverPort = 51820;
serverAddress = "2001:db8:a7c4:0:f0::a/127";
clientAddress = "2001:db8:a7c4:0:f0::b/127";
clientSubnet = "2001:db8:a7c4::/60";
serverPrivateKeyFile = "/run/secrets/wg0-server-private";
clientPublicKeyFile = "/run/secrets/wg0-client-public";
}];
}
The BGP setup creates:
- A shared dummy interface with a VIP that both servers announce
- Route servers configured automatically based on datacenter ID
- Blackhole routes for the advertised subnet
- Primary/secondary route maps for failover priority
Notes
- BGP peers and advertised subnets are fully configurable
- The FRR configuration template may need adjustments for providers other than Linode (AS numbers, communities, etc.)
- For Linode: use route servers
2600:3c0f:<dcId>:34::{1,2,3,4}
where<dcId>
is your datacenter ID (e.g., 25 for in-maa) - See Linode's BGP documentation for more details
- See
modules/network.nix
andmodules/wireguard.nix
for all available options