Initial oxbow setup
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				CI / Check, build and cache Nix flake (push) Successful in 14m56s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	CI / Check, build and cache Nix flake (push) Successful in 14m56s
				
			This commit is contained in:
		
							
								
								
									
										56
									
								
								nixos/boxes/home/oxbow.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								nixos/boxes/home/oxbow.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
{
 | 
			
		||||
  imports = [
 | 
			
		||||
    (import ./routing-common {
 | 
			
		||||
      index = 1;
 | 
			
		||||
      name = "oxbow";
 | 
			
		||||
    })
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  config.nixos.systems.oxbow = {
 | 
			
		||||
    system = "x86_64-linux";
 | 
			
		||||
    nixpkgs = "mine";
 | 
			
		||||
    home-manager = "mine";
 | 
			
		||||
 | 
			
		||||
    configuration = { lib, pkgs, config, ... }:
 | 
			
		||||
    let
 | 
			
		||||
      inherit (lib);
 | 
			
		||||
    in
 | 
			
		||||
    {
 | 
			
		||||
      config = {
 | 
			
		||||
        boot = {
 | 
			
		||||
          kernelParams = [ "intel_iommu=on" ];
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        hardware = {
 | 
			
		||||
          enableRedistributableFirmware = true;
 | 
			
		||||
          cpu = {
 | 
			
		||||
            intel.updateMicrocode = true;
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        fileSystems = {
 | 
			
		||||
          "/boot" = {
 | 
			
		||||
            device = "/dev/disk/by-label/ESP";
 | 
			
		||||
            fsType = "vfat";
 | 
			
		||||
          };
 | 
			
		||||
          "/nix" = {
 | 
			
		||||
            device = "/dev/disk/by-label/nix";
 | 
			
		||||
            fsType = "ext4";
 | 
			
		||||
          };
 | 
			
		||||
          "/persist" = {
 | 
			
		||||
            device = "/dev/disk/by-label/persist";
 | 
			
		||||
            fsType = "ext4";
 | 
			
		||||
            neededForBoot = true;
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        my = {
 | 
			
		||||
          secrets = {
 | 
			
		||||
            # key = "ssh-ed25519 ";
 | 
			
		||||
          };
 | 
			
		||||
          server.enable = true;
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										286
									
								
								nixos/boxes/home/routing-common/default.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								nixos/boxes/home/routing-common/default.nix
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,286 @@
 | 
			
		||||
{ index, name }: { lib, ... }:
 | 
			
		||||
let
 | 
			
		||||
  inherit (lib.my) net;
 | 
			
		||||
  inherit (lib.my.c.home) domain vlans prefixes;
 | 
			
		||||
in
 | 
			
		||||
{
 | 
			
		||||
  nixos.systems."${name}" = {
 | 
			
		||||
    assignments = {
 | 
			
		||||
      modem = {
 | 
			
		||||
        ipv4.address = net.cidr.host (254 - index) prefixes.modem.v4;
 | 
			
		||||
      };
 | 
			
		||||
      core = {
 | 
			
		||||
        name = "${name}-core";
 | 
			
		||||
        inherit domain;
 | 
			
		||||
        ipv4 = {
 | 
			
		||||
          address = net.cidr.host (index + 1) prefixes.core.v4;
 | 
			
		||||
          mask = 24;
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
      hi = {
 | 
			
		||||
        inherit domain;
 | 
			
		||||
        ipv4 = {
 | 
			
		||||
          address = net.cidr.host (index + 1) prefixes.hi.v4;
 | 
			
		||||
          mask = 22;
 | 
			
		||||
          gateway = null;
 | 
			
		||||
        };
 | 
			
		||||
        ipv6.address = net.cidr.host (index + 1) prefixes.hi.v6;
 | 
			
		||||
      };
 | 
			
		||||
      lo = {
 | 
			
		||||
        name = "${name}-lo";
 | 
			
		||||
        inherit domain;
 | 
			
		||||
        ipv4 = {
 | 
			
		||||
          address = net.cidr.host (index + 1) prefixes.lo.v4;
 | 
			
		||||
          mask = 21;
 | 
			
		||||
          gateway = null;
 | 
			
		||||
        };
 | 
			
		||||
        ipv6.address = net.cidr.host (index + 1) prefixes.lo.v6;
 | 
			
		||||
      };
 | 
			
		||||
      untrusted  = {
 | 
			
		||||
        name = "${name}-ut";
 | 
			
		||||
        inherit domain;
 | 
			
		||||
        ipv4 = {
 | 
			
		||||
          address = net.cidr.host (index + 1) prefixes.untrusted.v4;
 | 
			
		||||
          mask = 24;
 | 
			
		||||
          gateway = null;
 | 
			
		||||
        };
 | 
			
		||||
        ipv6.address = net.cidr.host (index + 1) prefixes.untrusted.v6;
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    configuration = { lib, pkgs, config, assignments, allAssignments, ... }:
 | 
			
		||||
      let
 | 
			
		||||
        inherit (lib) mkIf mkMerge mkForce;
 | 
			
		||||
        inherit (lib.my) networkdAssignment;
 | 
			
		||||
      in
 | 
			
		||||
      {
 | 
			
		||||
        config = {
 | 
			
		||||
          environment = {
 | 
			
		||||
            systemPackages = with pkgs; [
 | 
			
		||||
              ethtool
 | 
			
		||||
            ];
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          services = {
 | 
			
		||||
            resolved = {
 | 
			
		||||
              llmnr = "false";
 | 
			
		||||
              extraConfig = ''
 | 
			
		||||
                MulticastDNS=false
 | 
			
		||||
              '';
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            iperf3 = {
 | 
			
		||||
              enable = true;
 | 
			
		||||
              openFirewall = true;
 | 
			
		||||
            };
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          systemd.network = {
 | 
			
		||||
            wait-online.enable = false;
 | 
			
		||||
            config = {
 | 
			
		||||
              networkConfig = {
 | 
			
		||||
                ManageForeignRoutes = false;
 | 
			
		||||
              };
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            netdevs =
 | 
			
		||||
            let
 | 
			
		||||
              mkVLAN = name: vid: {
 | 
			
		||||
                "25-${name}" = {
 | 
			
		||||
                  netdevConfig = {
 | 
			
		||||
                    Name = name;
 | 
			
		||||
                    Kind = "vlan";
 | 
			
		||||
                  };
 | 
			
		||||
                  vlanConfig.Id = vid;
 | 
			
		||||
                };
 | 
			
		||||
              };
 | 
			
		||||
            in
 | 
			
		||||
            mkMerge [
 | 
			
		||||
              {
 | 
			
		||||
                "25-wan".netdevConfig = {
 | 
			
		||||
                  Name = "wan";
 | 
			
		||||
                  Kind = "bridge";
 | 
			
		||||
                };
 | 
			
		||||
                "25-lan".netdevConfig = {
 | 
			
		||||
                  Name = "lan";
 | 
			
		||||
                  Kind = "bridge";
 | 
			
		||||
                };
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              (mkVLAN "hi" vlans.hi)
 | 
			
		||||
              (mkVLAN "lo" vlans.lo)
 | 
			
		||||
              (mkVLAN "untrusted" vlans.untrusted)
 | 
			
		||||
              (mkVLAN "wan-tunnel" vlans.wan)
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            links = {
 | 
			
		||||
              "10-lan-jim" = {
 | 
			
		||||
                matchConfig = {
 | 
			
		||||
                  # Matching against MAC address seems to break VLAN interfaces
 | 
			
		||||
                  # (since they share the same MAC address)
 | 
			
		||||
                  Driver = "igb";
 | 
			
		||||
                  Path = "pci-0000:01:00.0";
 | 
			
		||||
                };
 | 
			
		||||
                linkConfig = {
 | 
			
		||||
                  Name = "lan-jim";
 | 
			
		||||
                  RxBufferSize = 4096;
 | 
			
		||||
                  TxBufferSize = 4096;
 | 
			
		||||
                  MTUBytes = toString lib.my.c.home.hiMTU;
 | 
			
		||||
                };
 | 
			
		||||
              };
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            networks =
 | 
			
		||||
            let
 | 
			
		||||
              mkVLANConfig = name: {
 | 
			
		||||
                "60-${name}" = mkMerge [
 | 
			
		||||
                  (networkdAssignment name assignments.hi)
 | 
			
		||||
                  {
 | 
			
		||||
                    dns = [ "127.0.0.1" "::1" ];
 | 
			
		||||
                    domains = [ config.networking.domain ];
 | 
			
		||||
                    networkConfig = {
 | 
			
		||||
                      IPv6AcceptRA = mkForce false;
 | 
			
		||||
                      IPv6SendRA = true;
 | 
			
		||||
                    };
 | 
			
		||||
                    ipv6SendRAConfig = {
 | 
			
		||||
                      DNS = [
 | 
			
		||||
                        (net.cidr.host 1 prefixes."${name}".v4)
 | 
			
		||||
                        (net.cidr.host 2 prefixes."${name}".v4)
 | 
			
		||||
                        (net.cidr.host 1 prefixes."${name}".v6)
 | 
			
		||||
                        (net.cidr.host 2 prefixes."${name}".v6)
 | 
			
		||||
                      ];
 | 
			
		||||
                      Domains = [ config.networking.domain ];
 | 
			
		||||
                    };
 | 
			
		||||
                    ipv6Prefixes = [
 | 
			
		||||
                      {
 | 
			
		||||
                        ipv6PrefixConfig.Prefix = prefixes."${name}".v6;
 | 
			
		||||
                      }
 | 
			
		||||
                    ];
 | 
			
		||||
                  }
 | 
			
		||||
                ];
 | 
			
		||||
              };
 | 
			
		||||
            in
 | 
			
		||||
            mkMerge [
 | 
			
		||||
              {
 | 
			
		||||
                "50-wan-phy" = {
 | 
			
		||||
                  matchConfig.Name = "wan-phy";
 | 
			
		||||
                  networkConfig.Bridge = "wan";
 | 
			
		||||
                };
 | 
			
		||||
                "50-wan-tunnel" = {
 | 
			
		||||
                  matchConfig.Name = "wan-tunnel";
 | 
			
		||||
                  networkConfig.Bridge = "wan";
 | 
			
		||||
                };
 | 
			
		||||
                "50-wan" = mkMerge [
 | 
			
		||||
                  (networkdAssignment "wan" assignments.modem)
 | 
			
		||||
                  {
 | 
			
		||||
                    matchConfig.Name = "wan";
 | 
			
		||||
                    DHCP = "ipv4";
 | 
			
		||||
                    dhcpV4Config.UseDNS = false;
 | 
			
		||||
                    routes = map (r: { routeConfig = r; }) [
 | 
			
		||||
                      # {
 | 
			
		||||
                      #   Destination = prefixes.ctrs.v4;
 | 
			
		||||
                      #   Gateway = allAssignments.shill.routing.ipv4.address;
 | 
			
		||||
                      # }
 | 
			
		||||
                    ];
 | 
			
		||||
                  }
 | 
			
		||||
                ];
 | 
			
		||||
 | 
			
		||||
                "50-lan-jim" = {
 | 
			
		||||
                  matchConfig.Name = "lan-jim";
 | 
			
		||||
                  networkConfig.Bridge = "lan";
 | 
			
		||||
                };
 | 
			
		||||
                "50-lan-dave" = {
 | 
			
		||||
                  matchConfig.Name = "lan-dave";
 | 
			
		||||
                  networkConfig.Bridge = "lan";
 | 
			
		||||
                };
 | 
			
		||||
                "55-lan" = {
 | 
			
		||||
                  matchConfig.Name = "lan";
 | 
			
		||||
                  vlan = [ "hi" "lo" "untrusted" ];
 | 
			
		||||
                };
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              (mkVLANConfig "hi")
 | 
			
		||||
              (mkVLANConfig "lo")
 | 
			
		||||
              (mkVLANConfig "untrusted")
 | 
			
		||||
            ];
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          my = {
 | 
			
		||||
            secrets = {
 | 
			
		||||
              files = {
 | 
			
		||||
                # "estuary/kelder-wg.key" = {
 | 
			
		||||
                #   owner = "systemd-network";
 | 
			
		||||
                # };
 | 
			
		||||
              };
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            firewall = {
 | 
			
		||||
              trustedInterfaces = [ "hi" "lo" ];
 | 
			
		||||
              udp.allowed = [ 5353 ];
 | 
			
		||||
              tcp.allowed = [ 5353 ];
 | 
			
		||||
              nat = {
 | 
			
		||||
                enable = true;
 | 
			
		||||
                externalInterface = "wan";
 | 
			
		||||
                # externalIP = assignments.internal.ipv4.address;
 | 
			
		||||
                forwardPorts = [
 | 
			
		||||
                  # {
 | 
			
		||||
                  #   port = "http";
 | 
			
		||||
                  #   dst = allAssignments.middleman.internal.ipv4.address;
 | 
			
		||||
                  # }
 | 
			
		||||
                ];
 | 
			
		||||
              };
 | 
			
		||||
              extraRules =
 | 
			
		||||
              let
 | 
			
		||||
                aa = allAssignments;
 | 
			
		||||
                matchInet = rule: sys: ''
 | 
			
		||||
                  ip daddr ${aa."${sys}".hi.ipv4.address} ${rule}
 | 
			
		||||
                  ip6 daddr ${aa."${sys}".hi.ipv6.address} ${rule}
 | 
			
		||||
                '';
 | 
			
		||||
              in
 | 
			
		||||
              ''
 | 
			
		||||
                table inet filter {
 | 
			
		||||
                  chain input {
 | 
			
		||||
                    iifname base meta l4proto { udp, tcp } th dport domain accept
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  chain routing-tcp {
 | 
			
		||||
                    # Safe enough to allow all SSH
 | 
			
		||||
                    tcp dport ssh accept
 | 
			
		||||
 | 
			
		||||
                    return
 | 
			
		||||
                  }
 | 
			
		||||
                  chain routing-udp {
 | 
			
		||||
                    return
 | 
			
		||||
                  }
 | 
			
		||||
                  chain filter-routing {
 | 
			
		||||
                    tcp flags & (fin|syn|rst|ack) == syn ct state new jump routing-tcp
 | 
			
		||||
                    meta l4proto udp ct state new jump routing-udp
 | 
			
		||||
                    return
 | 
			
		||||
                  }
 | 
			
		||||
                  chain filter-untrusted {
 | 
			
		||||
                    ip daddr ${prefixes.modem.v4} reject
 | 
			
		||||
                    oifname wan accept
 | 
			
		||||
                    return
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  chain forward {
 | 
			
		||||
                    iifname untrusted jump filter-untrusted
 | 
			
		||||
                    iifname { wan, untrusted } oifname { hi, lo } jump filter-routing
 | 
			
		||||
                  }
 | 
			
		||||
                  chain output { }
 | 
			
		||||
                }
 | 
			
		||||
                table inet nat {
 | 
			
		||||
                  chain prerouting {
 | 
			
		||||
                    ${matchInet "meta l4proto { udp, tcp } th dport domain redirect to :5353" name}
 | 
			
		||||
                  }
 | 
			
		||||
                  chain postrouting {
 | 
			
		||||
                    oifname wan masquerade
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              '';
 | 
			
		||||
            };
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user