forked from mirrors_public/oddlama_nix-config
feat: remove the need to specify cidrs in wireguard addresses and
properly derive allowed ips
This commit is contained in:
parent
4057ee9051
commit
3862bd6b14
4 changed files with 59 additions and 53 deletions
|
@ -23,7 +23,7 @@ This is my personal nix config.
|
||||||
- `envoy/` - Hetzner Cloud server. Primarily used as my mailserver and VPN provider.
|
- `envoy/` - Hetzner Cloud server. Primarily used as my mailserver and VPN provider.
|
||||||
- `zackbiene/` - ODROID N2+. Hosts IoT and Home Automation stuff and fully isolates that stuff from my internal network.
|
- `zackbiene/` - ODROID N2+. Hosts IoT and Home Automation stuff and fully isolates that stuff from my internal network.
|
||||||
- not yet ready to be publicized: my main development machine, the powerful home server, some services ... (still in transition from gentoo :/)
|
- not yet ready to be publicized: my main development machine, the powerful home server, some services ... (still in transition from gentoo :/)
|
||||||
- `modules/` additional NixOS modules that are not yet upstreamed.
|
- `modules/` additional NixOS modules that are not yet upstreamed, or specific to this setup.
|
||||||
- `nix/` library functions and plumbing
|
- `nix/` library functions and plumbing
|
||||||
- `apps/` Additional runnable actions for this flake
|
- `apps/` Additional runnable actions for this flake
|
||||||
- `default.nix` Collects all apps and generates a definition for a specified system
|
- `default.nix` Collects all apps and generates a definition for a specified system
|
||||||
|
|
|
@ -67,15 +67,22 @@
|
||||||
# > net.cidr.canonicalize "192.168.1.100/24"
|
# > net.cidr.canonicalize "192.168.1.100/24"
|
||||||
# "192.168.1.0/24"
|
# "192.168.1.0/24"
|
||||||
canonicalize = x: libWithNet.net.cidr.make (libWithNet.net.cidr.length x) (ip x);
|
canonicalize = x: libWithNet.net.cidr.make (libWithNet.net.cidr.length x) (ip x);
|
||||||
# coercev4 :: [cidr4] -> (cidr4 | null)
|
# coercev4 :: [cidr4 | ipv4] -> (cidr4 | null)
|
||||||
#
|
#
|
||||||
# Returns the smallest cidr network that includes all given addresses
|
# Returns the smallest cidr network that includes all given addresses.
|
||||||
|
# If no cidr mask is given, /32 is assumed.
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
#
|
#
|
||||||
# > net.cidr.coercev4 ["192.168.1.1/24" "192.168.6.1/32"]
|
# > net.cidr.coercev4 ["192.168.1.1/24" "192.168.6.1/32"]
|
||||||
# "192.168.0.0/21"
|
# "192.168.0.0/21"
|
||||||
coercev4 = addrs: let
|
coercev4 = addrs_: let
|
||||||
|
# Append /32 if necessary
|
||||||
|
addrs = map (x:
|
||||||
|
if lib.hasInfix "/" x
|
||||||
|
then x
|
||||||
|
else "${x}/32")
|
||||||
|
addrs_;
|
||||||
# The smallest occurring length is the first we need to start checking, since
|
# The smallest occurring length is the first we need to start checking, since
|
||||||
# any greater cidr length represents a smaller address range which
|
# any greater cidr length represents a smaller address range which
|
||||||
# wouldn't contain all of the original addresses.
|
# wouldn't contain all of the original addresses.
|
||||||
|
@ -101,15 +108,22 @@
|
||||||
if addrs == []
|
if addrs == []
|
||||||
then null
|
then null
|
||||||
else libWithNet.net.cidr.make bestLength firstIp;
|
else libWithNet.net.cidr.make bestLength firstIp;
|
||||||
# coercev6 :: [cidr6] -> (cidr6 | null)
|
# coercev6 :: [cidr6 | ipv6] -> (cidr6 | null)
|
||||||
#
|
#
|
||||||
# Returns the smallest cidr network that includes all given addresses
|
# Returns the smallest cidr network that includes all given addresses.
|
||||||
|
# If no cidr mask is given, /128 is assumed.
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
#
|
#
|
||||||
# > net.cidr.coercev6 ["fd00:dead:cafe::/64" "fd00:fd12:3456:7890::/56"]
|
# > net.cidr.coercev6 ["fd00:dead:cafe::/64" "fd00:fd12:3456:7890::/56"]
|
||||||
# "fd00:c000::/18"
|
# "fd00:c000::/18"
|
||||||
coercev6 = addrs: let
|
coercev6 = addrs_: let
|
||||||
|
# Append /128 if necessary
|
||||||
|
addrs = map (x:
|
||||||
|
if lib.hasInfix "/" x
|
||||||
|
then x
|
||||||
|
else "${x}/128")
|
||||||
|
addrs_;
|
||||||
# The smallest occurring length is the first we need to start checking, since
|
# The smallest occurring length is the first we need to start checking, since
|
||||||
# any greater cidr length represents a smaller address range which
|
# any greater cidr length represents a smaller address range which
|
||||||
# wouldn't contain all of the original addresses.
|
# wouldn't contain all of the original addresses.
|
||||||
|
|
|
@ -193,9 +193,8 @@
|
||||||
via = nodeName;
|
via = nodeName;
|
||||||
keepalive = false;
|
keepalive = false;
|
||||||
};
|
};
|
||||||
cidrv4 = "${net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv4}/32";
|
ipv4 = net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv4;
|
||||||
cidrv6 = "${net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv6}/128";
|
ipv6 = net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv6;
|
||||||
# TODO check error: addresses = ["10.22.22.2/30"];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -402,8 +401,8 @@ in {
|
||||||
inherit (cfg.networking) host;
|
inherit (cfg.networking) host;
|
||||||
inherit (cfg.networking.wireguard) openFirewallRules port;
|
inherit (cfg.networking.wireguard) openFirewallRules port;
|
||||||
};
|
};
|
||||||
cidrv4 = net.cidr.hostCidr 1 cfg.networking.wireguard.cidrv4;
|
ipv4 = net.cidr.host 1 cfg.networking.wireguard.cidrv4;
|
||||||
cidrv6 = net.cidr.hostCidr 1 cfg.networking.wireguard.cidrv6;
|
ipv6 = net.cidr.host 1 cfg.networking.wireguard.cidrv6;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// extraLib.mergeToplevelConfigs ["disko" "microvm" "systemd"] (mapAttrsToList microvmConfig vms)
|
// extraLib.mergeToplevelConfigs ["disko" "microvm" "systemd"] (mapAttrsToList microvmConfig vms)
|
||||||
|
|
|
@ -86,6 +86,23 @@
|
||||||
|
|
||||||
# Adds context information to the assertions for this network
|
# Adds context information to the assertions for this network
|
||||||
assertionPrefix = "Wireguard network '${wgName}' on '${nodeName}'";
|
assertionPrefix = "Wireguard network '${wgName}' on '${nodeName}'";
|
||||||
|
|
||||||
|
# Calculates which traffic should be routed to a given server node
|
||||||
|
# Usually we just want to allow other peers to route traffic
|
||||||
|
# for our "children" through us, additional to traffic to us of course.
|
||||||
|
# If a server exposes additional network access (global, lan, ...),
|
||||||
|
# these can be added aswell. TODO (do that)
|
||||||
|
serverAllowedIPs = serverNode: let
|
||||||
|
snCfg = wgCfgOf serverNode;
|
||||||
|
in
|
||||||
|
map (net.cidr.make 128) (
|
||||||
|
# The server accepts traffic to it's own address
|
||||||
|
snCfg.addresses
|
||||||
|
# plus traffic for any of its external peers
|
||||||
|
++ attrValues snCfg.server.externalPeers
|
||||||
|
# plus traffic for any client that is connected via that server
|
||||||
|
++ map (n: (wgCfgOf n).addresses) (filter (n: (wgCfgOf n).client.via == serverNode) associatedClientNodes)
|
||||||
|
);
|
||||||
in {
|
in {
|
||||||
assertions = [
|
assertions = [
|
||||||
{
|
{
|
||||||
|
@ -157,16 +174,13 @@
|
||||||
if isServer
|
if isServer
|
||||||
then
|
then
|
||||||
# Always include all other server nodes.
|
# Always include all other server nodes.
|
||||||
map (serverNode: {
|
map (serverNode: let
|
||||||
wireguardPeerConfig = let
|
snCfg = wgCfgOf serverNode;
|
||||||
snCfg = wgCfgOf serverNode;
|
in {
|
||||||
in {
|
wireguardPeerConfig = {
|
||||||
PublicKey = builtins.readFile (peerPublicKeyPath serverNode);
|
PublicKey = builtins.readFile (peerPublicKeyPath serverNode);
|
||||||
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName serverNode}.path;
|
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName serverNode}.path;
|
||||||
# The allowed ips of a server node are it's own addreses,
|
AllowedIPs = serverAllowedIPs serverNode;
|
||||||
# plus each external peer's addresses,
|
|
||||||
# plus each client's addresses that is connected via that node.
|
|
||||||
AllowedIPs = snCfg.addresses;
|
|
||||||
Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}";
|
Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}";
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
@ -192,7 +206,7 @@
|
||||||
{
|
{
|
||||||
PublicKey = builtins.readFile (peerPublicKeyPath clientNode);
|
PublicKey = builtins.readFile (peerPublicKeyPath clientNode);
|
||||||
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName clientNode}.path;
|
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName clientNode}.path;
|
||||||
AllowedIPs = clientCfg.addresses;
|
AllowedIPs = map (net.cidr.make 128) clientCfg.addresses;
|
||||||
}
|
}
|
||||||
// optionalAttrs clientCfg.keepalive {
|
// optionalAttrs clientCfg.keepalive {
|
||||||
PersistentKeepalive = 25;
|
PersistentKeepalive = 25;
|
||||||
|
@ -207,7 +221,7 @@
|
||||||
PublicKey = builtins.readFile (peerPublicKeyPath wgCfg.client.via);
|
PublicKey = builtins.readFile (peerPublicKeyPath wgCfg.client.via);
|
||||||
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName wgCfg.client.via}.path;
|
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName wgCfg.client.via}.path;
|
||||||
# TODO this should be 0.0.0.0 if the client wants to route all traffic
|
# TODO this should be 0.0.0.0 if the client wants to route all traffic
|
||||||
AllowedIPs = (wgCfgOf wgCfg.client.via).addresses;
|
AllowedIPs = serverAllowedIPs wgCfg.client.via;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -301,44 +315,23 @@ in {
|
||||||
description = mdDoc "The order priority used when creating systemd netdev and network files.";
|
description = mdDoc "The order priority used when creating systemd netdev and network files.";
|
||||||
};
|
};
|
||||||
|
|
||||||
cidrv4 = mkOption {
|
ipv4 = mkOption {
|
||||||
type =
|
type = net.types.ipv4;
|
||||||
if config.client.via != null
|
description = mdDoc "The ipv4 address for this machine.";
|
||||||
then net.types.cidrv4-in nodes.${config.client.via}.config.extra.wireguard.${name}.cidrv4
|
|
||||||
else net.types.cidrv4;
|
|
||||||
description = mdDoc ''
|
|
||||||
The ipv4 host address (with cidr mask) to configure for this interface.
|
|
||||||
The cidr mask determines this peers allowed address range as configured on other peers.
|
|
||||||
The mask should usually be fully restricted (/32) when no external clients are configured
|
|
||||||
and no other node uses this as a via.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cidrv6 = mkOption {
|
ipv6 = mkOption {
|
||||||
type =
|
type = net.types.ipv6;
|
||||||
if config.client.via != null
|
description = mdDoc "The ipv6 address for this machine.";
|
||||||
then net.types.cidrv6-in nodes.${config.client.via}.config.extra.wireguard.${name}.cidrv6
|
|
||||||
else net.types.cidrv6;
|
|
||||||
description = mdDoc ''
|
|
||||||
The ipv6 host address (with cidr mask) to configure for this interface.
|
|
||||||
The cidr mask determines this peers allowed address range as configured on other peers.
|
|
||||||
The mask should usually be fully restricted (/128) when no external clients are configured
|
|
||||||
and no other node uses this as a via.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
addresses = mkOption {
|
addresses = mkOption {
|
||||||
type = types.listOf (
|
type = types.listOf net.types.ip;
|
||||||
if config.client.via != null
|
default = [config.ipv4 config.ipv6];
|
||||||
then net.types.cidr-in nodes.${config.client.via}.config.extra.wireguard.${name}.addresses
|
|
||||||
else net.types.cidr
|
|
||||||
);
|
|
||||||
default = [config.cidrv4 config.cidrv6];
|
|
||||||
description = mdDoc ''
|
description = mdDoc ''
|
||||||
The addresses (with cidr mask) to configure for this interface.
|
The ip addresses (v4 and/or v6) to use for this machine.
|
||||||
The cidr mask determines this peers allowed address range as configured on other peers.
|
|
||||||
The actual network cidr will automatically be derived from all network participants.
|
The actual network cidr will automatically be derived from all network participants.
|
||||||
By default this will just include {option}`cidrv4` and {option}`cidrv6` as configured.
|
By default this will just include {option}`ipv4` and {option}`ipv6` as configured.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue