This repository has no description
0

Configure Feed

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

superconfig / 2configs / container-bridge.nix
4.3 kB 121 lines
1{ config, lib, pkgs, ... }: 2{ 3 # Local DNS64 resolver for containers 4 # Synthesizes AAAA records with 64:ff9b::/96 prefix for IPv4-only hosts 5 services.unbound = { 6 enable = true; 7 settings = { 8 server = { 9 interface = [ "fd00:c700::1" "127.0.0.1" ]; 10 access-control = [ 11 "fd00:c700::/64 allow" 12 "127.0.0.0/8 allow" 13 ]; 14 # DNS64: synthesize AAAA with NAT64 prefix 15 module-config = ''"dns64 validator iterator"''; 16 dns64-prefix = "64:ff9b::/96"; 17 # Always synthesize, even if real AAAA exists (needed when host has no IPv6) 18 dns64-synthall = "yes"; 19 }; 20 forward-zone = [ 21 { 22 name = "."; 23 forward-addr = [ 24 "1.1.1.1" # Cloudflare (IPv4 - always works) 25 "8.8.8.8" # Google (IPv4) 26 "2606:4700:4700::1111" # Cloudflare (IPv6 - when available) 27 ]; 28 } 29 ]; 30 }; 31 }; 32 33 # Bridge interface for containers 34 systemd.network.netdevs."10-ctr0" = { 35 netdevConfig = { 36 Kind = "bridge"; 37 Name = "ctr0"; 38 }; 39 }; 40 41 systemd.network.networks."10-ctr0" = { 42 matchConfig.Name = "ctr0"; 43 address = [ "fd00:c700::1/64" ]; 44 networkConfig.ConfigureWithoutCarrier = true; 45 }; 46 47 # Exclude from NetworkManager 48 networking.networkmanager.unmanaged = [ "ctr0" ]; 49 50 # IP forwarding 51 boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1; 52 boot.kernel.sysctl."net.ipv4.ip_forward" = 1; 53 54 # Jool NAT64 kernel module 55 boot.extraModulePackages = [ config.boot.kernelPackages.jool ]; 56 boot.kernelModules = [ "jool" ]; 57 58 systemd.services.jool = { 59 description = "Jool NAT64"; 60 after = [ "network.target" ]; 61 wantedBy = [ "multi-user.target" ]; 62 serviceConfig = { 63 Type = "oneshot"; 64 RemainAfterExit = true; 65 ExecStart = "${pkgs.jool-cli}/bin/jool instance add --netfilter --pool6 64:ff9b::/96"; 66 ExecStop = "${pkgs.jool-cli}/bin/jool instance remove"; 67 }; 68 }; 69 70 # Update Jool pool4 with current IPv4 address (needed for NAT64 on dynamic IPs) 71 systemd.services.jool-pool4-update = { 72 description = "Update Jool NAT64 pool4 with current IPv4"; 73 after = [ "jool.service" "network-online.target" ]; 74 wants = [ "network-online.target" ]; 75 wantedBy = [ "multi-user.target" ]; 76 path = [ pkgs.iproute2 pkgs.gawk pkgs.jool-cli ]; 77 serviceConfig = { 78 Type = "oneshot"; 79 RemainAfterExit = true; 80 }; 81 script = '' 82 # Get default route's source IP 83 IP=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '/src/ {print $7}') 84 if [ -n "$IP" ]; then 85 # Flush old pool and add new 86 jool pool4 flush --tcp 2>/dev/null || true 87 jool pool4 flush --udp 2>/dev/null || true 88 jool pool4 flush --icmp 2>/dev/null || true 89 jool pool4 add "$IP" 1-65535 --tcp 90 jool pool4 add "$IP" 1-65535 --udp 91 jool pool4 add "$IP" 1-65535 --icmp 92 echo "Jool pool4 updated to $IP" 93 else 94 echo "No IPv4 address found, skipping pool4 update" 95 fi 96 ''; 97 }; 98 99 # Firewall rules for container bridge 100 krebs.iptables.tables.filter.FORWARD.rules = [ 101 # IPv6 forwarding for containers 102 { v4 = false; v6 = true; predicate = "-i ctr0"; target = "ACCEPT"; } 103 { v4 = false; v6 = true; predicate = "-o ctr0 -m conntrack --ctstate RELATED,ESTABLISHED"; target = "ACCEPT"; } 104 # IPv4 forwarding for NAT64 translated packets 105 { v4 = true; v6 = false; predicate = "-m conntrack --ctstate RELATED,ESTABLISHED"; target = "ACCEPT"; } 106 { v4 = true; v6 = false; predicate = ""; target = "ACCEPT"; } 107 ]; 108 109 # NAT66 - masquerade container IPv6 to reach public IPv6 (when host has IPv6) 110 # NAT44 - masquerade NAT64 translated IPv4 packets 111 krebs.iptables.tables.nat.POSTROUTING.rules = [ 112 { v4 = false; v6 = true; predicate = "-s fd00:c700::/64 ! -d fd00:c700::/64"; target = "MASQUERADE"; } 113 { v4 = true; v6 = false; predicate = ""; target = "MASQUERADE"; } # Masquerade all outbound IPv4 114 ]; 115 116 # Allow containers to reach host's DNS64 resolver (IPv6 only) 117 krebs.iptables.tables.filter.INPUT.rules = [ 118 { v4 = false; v6 = true; predicate = "-s fd00:c700::/64 -p udp --dport 53"; target = "ACCEPT"; } 119 { v4 = false; v6 = true; predicate = "-s fd00:c700::/64 -p tcp --dport 53"; target = "ACCEPT"; } 120 ]; 121}