This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

extra-container: add IPv6-only container bridge with NAT64

- Add extra-container and nix-hashlib flake inputs
- Create container-bridge.nix with ctr0 bridge and Jool NAT64
- Enable container bridge on xerxes
- Update virtulus container to use hostBridge with IPv6

Containers get deterministic IPv6 addresses derived from hostname
and access IPv4 internet via NAT64 translation.

+112 -1
+22 -1
flake.nix
··· 56 56 le_menu.url = "github:lassulus/le_menu"; 57 57 # le_menu.url = "git+file:/home/lass/src/le_menu"; 58 58 le_menu.inputs.nixpkgs.follows = "nixpkgs"; 59 + 60 + extra-container.url = "github:erikarvstedt/extra-container"; 61 + extra-container.inputs.nixpkgs.follows = "nixpkgs"; 62 + 63 + nix-hashlib.url = "git+https://git.clan.lol/clan/nix-hashlib"; 59 64 }; 60 65 61 66 outputs = ··· 182 187 flake.clanInternals = clan.clanInternals; 183 188 flake.darwinConfigurations = clan.darwinConfigurations; 184 189 flake.clan = clan; 190 + 191 + # Container configurations for use with extra-container 192 + # Auto-discovers machines with container.nix 193 + flake.containerConfigurations = nixpkgs.lib.mapAttrs 194 + (machineName: _: import ./machines/${machineName}/container.nix { inherit self; }) 195 + ( 196 + nixpkgs.lib.filterAttrs ( 197 + machineName: _: builtins.pathExists ./machines/${machineName}/container.nix 198 + ) (builtins.readDir ./machines) 199 + ); 185 200 perSystem = 186 201 { 187 202 lib, ··· 208 223 }; 209 224 }; 210 225 clan-cli = clan-core.packages.${system}.clan-cli; 211 - }; 226 + } // lib.mapAttrs' (name: containerConfig: 227 + lib.nameValuePair "container-${name}" (inputs.extra-container.lib.buildContainers { 228 + inherit system; 229 + nixpkgs = inputs.nixpkgs; 230 + config.containers.${name} = containerConfig; 231 + }) 232 + ) self.containerConfigurations; 212 233 devShells.default = pkgs.mkShell { 213 234 packages = [ 214 235 nixpkgs.legacyPackages.${system}.nil
+44
2configs/container-bridge.nix
··· 1 + { config, lib, pkgs, ... }: 2 + { 3 + # Bridge interface for containers 4 + systemd.network.netdevs."10-ctr0" = { 5 + netdevConfig = { 6 + Kind = "bridge"; 7 + Name = "ctr0"; 8 + }; 9 + }; 10 + 11 + systemd.network.networks."10-ctr0" = { 12 + matchConfig.Name = "ctr0"; 13 + address = [ "fd00:ctr::1/64" ]; 14 + networkConfig.ConfigureWithoutCarrier = true; 15 + }; 16 + 17 + # Exclude from NetworkManager 18 + networking.networkmanager.unmanaged = [ "ctr0" ]; 19 + 20 + # IPv6 forwarding 21 + boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1; 22 + 23 + # Jool NAT64 kernel module 24 + boot.extraModulePackages = [ config.boot.kernelPackages.jool ]; 25 + boot.kernelModules = [ "jool" ]; 26 + 27 + systemd.services.jool = { 28 + description = "Jool NAT64"; 29 + after = [ "network.target" ]; 30 + wantedBy = [ "multi-user.target" ]; 31 + serviceConfig = { 32 + Type = "oneshot"; 33 + RemainAfterExit = true; 34 + ExecStart = "${pkgs.jool-cli}/bin/jool instance add --netfilter --pool6 64:ff9b::/96"; 35 + ExecStop = "${pkgs.jool-cli}/bin/jool instance remove"; 36 + }; 37 + }; 38 + 39 + # Firewall rules for container bridge 40 + krebs.iptables.tables.filter.FORWARD.rules = [ 41 + { v6 = true; predicate = "-i ctr0"; target = "ACCEPT"; } 42 + { v6 = true; predicate = "-o ctr0 -m conntrack --ctstate RELATED,ESTABLISHED"; target = "ACCEPT"; } 43 + ]; 44 + }
+42
machines/virtulus/container.nix
··· 1 + { self }: 2 + let 3 + lib = self.inputs.nixpkgs.lib; 4 + hashlib = self.inputs.nix-hashlib.lib; 5 + 6 + # Generate IPv6 suffix from hostname (16 hex chars = 64 bits) 7 + ipv6SuffixFun = hashlib.makeHashFun { 8 + type = "hash"; 9 + dictionary = lib.stringToCharacters "0123456789abcdef"; 10 + length = 16; 11 + }; 12 + 13 + formatIPv6Suffix = hash: 14 + "${builtins.substring 0 4 hash}:${builtins.substring 4 4 hash}:${builtins.substring 8 4 hash}:${builtins.substring 12 4 hash}"; 15 + 16 + machineName = "virtulus"; 17 + ipv6Suffix = formatIPv6Suffix (ipv6SuffixFun machineName); 18 + in 19 + { 20 + privateNetwork = true; 21 + hostBridge = "ctr0"; 22 + 23 + # Static IPv6 from hostname hash: fd00:ctr::7371:bba8:ddd5:45e4 24 + localAddress6 = "fd00:ctr::${ipv6Suffix}/64"; 25 + 26 + specialArgs = { inherit self; }; 27 + 28 + config = { 29 + imports = [ 30 + self.inputs.clan-core.nixosModules.clanCore 31 + ./config.nix 32 + ]; 33 + clan.core.settings.directory = self; 34 + clan.core.settings.machine.name = machineName; 35 + 36 + # DNS64 resolvers (Cloudflare) 37 + networking.nameservers = [ 38 + "2606:4700:4700::64" 39 + "2606:4700:4700::6400" 40 + ]; 41 + }; 42 + }
+4
machines/xerxes/config.nix
··· 10 10 ../../2configs/sunshine.nix 11 11 ../../2configs/rtl-sdr.nix 12 12 ../../2configs/browsers.nix 13 + ../../2configs/container-bridge.nix 13 14 ]; 14 15 system.stateVersion = "25.05"; 15 16 ··· 33 34 services.ollama = { 34 35 enable = true; 35 36 }; 37 + 38 + # extra-container for testing declarative containers without full rebuilds 39 + programs.extra-container.enable = true; 36 40 }