Files
sixnix/README.md
2025-09-30 18:18:38 +00:00

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 /64s 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 and modules/wireguard.nix for all available options