diff --git a/README.md b/README.md index 86f0285..ec305f0 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,9 @@ and using the regular imperative NixOS deployment options instead. * ephemeral execution so no state is being kept across restarts * if state is needed, bind mounts can be defined in the nspawn configuration -## TODO +## Open Issues +* proper IPv6 support * the whole host nix store is being bind mounted into the container * explore if only needed store paths could be bind mounted instead * maybe create an option to make a separate nix daemon instance available in the container diff --git a/checks.nix b/checks.nix index 060b8d7..c102c44 100644 --- a/checks.nix +++ b/checks.nix @@ -86,13 +86,17 @@ in config = { }; network.veth.config = { host = { - networkConfig.Address = [ - "fc42::1/64" - "192.168.42.1/24" - ]; + networkConfig = { + DHCPServer = false; + Address = [ + "fc42::1/64" + "192.168.42.1/24" + ]; + }; }; container = { networkConfig = { + DHCP = false; Address = [ "fc42::2/64" "192.168.42.2/24" diff --git a/host.nix b/host.nix index db96c90..10bece8 100644 --- a/host.nix +++ b/host.nix @@ -7,6 +7,45 @@ let cfg = config.virtualisation.nixos-nspawn-ephemeral; + containerVdevNetwork = { + matchConfig = { + Kind = "veth"; + Name = "host0"; + Virtualization = "container"; + }; + networkConfig = { + DHCP = lib.mkDefault true; + LinkLocalAddressing = lib.mkDefault true; + LLDP = true; + EmitLLDP = "customer-bridge"; + IPv6DuplicateAddressDetection = lib.mkDefault 0; + IPv6AcceptRA = lib.mkDefault true; + MulticastDNS = true; + }; + }; + + hostVdevNetwork = name: { + matchConfig = { + Kind = "veth"; + Name = "ve-${name}"; + }; + networkConfig = { + Address = lib.mkDefault [ + "0.0.0.0/30" + "::/64" + ]; + DHCPServer = lib.mkDefault true; + IPMasquerade = lib.mkDefault "both"; + LinkLocalAddressing = lib.mkDefault true; + LLDP = true; + EmitLLDP = "customer-bridge"; + IPv6DuplicateAddressDetection = lib.mkDefault 0; + IPv6AcceptRA = lib.mkDefault false; + IPv6SendRA = lib.mkDefault true; + MulticastDNS = true; + }; + }; + containerModule = lib.types.submodule ( { config, @@ -42,37 +81,33 @@ let _loc: defs: (import "${toString pkgs.path}/nixos/lib/eval-config.nix" { modules = - let - containerDefaults = { + [ + ./container.nix + { networking.hostName = lib.mkDefault name; nixpkgs.hostPlatform = lib.mkDefault pkgs.system; + networking.firewall.interfaces."host0" = { + allowedTCPPorts = [ + 5353 # MDNS + ]; + allowedUDPPorts = [ + 5353 # MDNS + ]; + }; + systemd.network.networks."10-container-host0" = - lib.mkIf (config.network.veth.enable -> config.network.veth.config.container != null) - ( - lib.mkMerge [ - { - matchConfig = { - Kind = "veth"; - Name = "host0"; - Virtualization = "container"; - }; - networkConfig = { - LinkLocalAddressing = lib.mkDefault false; - LLDP = true; - EmitLLDP = "customer-bridge"; - IPv6DuplicateAddressDetection = lib.mkDefault 0; - IPv6AcceptRA = lib.mkDefault false; - }; - } - config.network.veth.config.container - ] - ); - }; - in - [ - containerDefaults - ./container.nix + let + veth = config.network.veth; + customConfig = if veth.config.container != null then veth.config.container else { }; + in + lib.mkIf veth.enable ( + lib.mkMerge [ + containerVdevNetwork + customConfig + ] + ); + } ] ++ cfg.imports ++ (map (x: x.value) defs); @@ -186,30 +221,27 @@ in networking = { useNetworkd = true; firewall.interfaces."ve-+" = { - # allow DHCP - allowedUDPPorts = [ 67 ]; + allowedTCPPorts = [ + 5353 # MDNS + ]; + allowedUDPPorts = [ + 67 # DHCP + 5353 # MDNS + ]; }; }; systemd.network.networks = lib.flip lib.mapAttrs' cfg.containers ( name: containerCfg: lib.nameValuePair "10-ve-${name}" ( - lib.mkIf (containerCfg.network.veth.enable -> containerCfg.network.veth.config.host != null) ( + let + veth = containerCfg.network.veth; + customConfig = if veth.config.host != null then veth.config.host else { }; + in + lib.mkIf veth.enable ( lib.mkMerge [ - { - matchConfig = { - Kind = "veth"; - Name = "ve-${name}"; - }; - networkConfig = { - LinkLocalAddressing = lib.mkDefault false; - LLDP = true; - EmitLLDP = "customer-bridge"; - IPv6DuplicateAddressDetection = lib.mkDefault 0; - IPv6AcceptRA = lib.mkDefault false; - }; - } - containerCfg.network.veth.config.host + (hostVdevNetwork name) + customConfig ] ) )