Skip to content

Commit

Permalink
networking: use custom network units for veth
Browse files Browse the repository at this point in the history
Also enables MDNS to resolve IPv6 addresses for hostnames.
  • Loading branch information
fpletz committed Dec 19, 2024
1 parent be308da commit 90750a6
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 49 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 8 additions & 4 deletions checks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
120 changes: 76 additions & 44 deletions host.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
]
)
)
Expand Down

0 comments on commit 90750a6

Please sign in to comment.