mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-11 07:10:39 +02:00
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.
|
||||
- `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 :/)
|
||||
- `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
|
||||
- `apps/` Additional runnable actions for this flake
|
||||
- `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"
|
||||
# "192.168.1.0/24"
|
||||
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:
|
||||
#
|
||||
# > net.cidr.coercev4 ["192.168.1.1/24" "192.168.6.1/32"]
|
||||
# "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
|
||||
# any greater cidr length represents a smaller address range which
|
||||
# wouldn't contain all of the original addresses.
|
||||
|
@ -101,15 +108,22 @@
|
|||
if addrs == []
|
||||
then null
|
||||
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:
|
||||
#
|
||||
# > net.cidr.coercev6 ["fd00:dead:cafe::/64" "fd00:fd12:3456:7890::/56"]
|
||||
# "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
|
||||
# any greater cidr length represents a smaller address range which
|
||||
# wouldn't contain all of the original addresses.
|
||||
|
|
|
@ -193,9 +193,8 @@
|
|||
via = nodeName;
|
||||
keepalive = false;
|
||||
};
|
||||
cidrv4 = "${net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv4}/32";
|
||||
cidrv6 = "${net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv6}/128";
|
||||
# TODO check error: addresses = ["10.22.22.2/30"];
|
||||
ipv4 = net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv4;
|
||||
ipv6 = net.cidr.host vmCfg.id cfg.networking.wireguard.cidrv6;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -402,8 +401,8 @@ in {
|
|||
inherit (cfg.networking) host;
|
||||
inherit (cfg.networking.wireguard) openFirewallRules port;
|
||||
};
|
||||
cidrv4 = net.cidr.hostCidr 1 cfg.networking.wireguard.cidrv4;
|
||||
cidrv6 = net.cidr.hostCidr 1 cfg.networking.wireguard.cidrv6;
|
||||
ipv4 = net.cidr.host 1 cfg.networking.wireguard.cidrv4;
|
||||
ipv6 = net.cidr.host 1 cfg.networking.wireguard.cidrv6;
|
||||
};
|
||||
}
|
||||
// extraLib.mergeToplevelConfigs ["disko" "microvm" "systemd"] (mapAttrsToList microvmConfig vms)
|
||||
|
|
|
@ -86,6 +86,23 @@
|
|||
|
||||
# Adds context information to the assertions for this network
|
||||
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 {
|
||||
assertions = [
|
||||
{
|
||||
|
@ -157,16 +174,13 @@
|
|||
if isServer
|
||||
then
|
||||
# Always include all other server nodes.
|
||||
map (serverNode: {
|
||||
wireguardPeerConfig = let
|
||||
snCfg = wgCfgOf serverNode;
|
||||
in {
|
||||
map (serverNode: let
|
||||
snCfg = wgCfgOf serverNode;
|
||||
in {
|
||||
wireguardPeerConfig = {
|
||||
PublicKey = builtins.readFile (peerPublicKeyPath serverNode);
|
||||
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName serverNode}.path;
|
||||
# The allowed ips of a server node are it's own addreses,
|
||||
# plus each external peer's addresses,
|
||||
# plus each client's addresses that is connected via that node.
|
||||
AllowedIPs = snCfg.addresses;
|
||||
AllowedIPs = serverAllowedIPs serverNode;
|
||||
Endpoint = "${snCfg.server.host}:${toString snCfg.server.port}";
|
||||
};
|
||||
})
|
||||
|
@ -192,7 +206,7 @@
|
|||
{
|
||||
PublicKey = builtins.readFile (peerPublicKeyPath clientNode);
|
||||
PresharedKeyFile = config.rekey.secrets.${peerPresharedKeySecret nodeName clientNode}.path;
|
||||
AllowedIPs = clientCfg.addresses;
|
||||
AllowedIPs = map (net.cidr.make 128) clientCfg.addresses;
|
||||
}
|
||||
// optionalAttrs clientCfg.keepalive {
|
||||
PersistentKeepalive = 25;
|
||||
|
@ -207,7 +221,7 @@
|
|||
PublicKey = builtins.readFile (peerPublicKeyPath wgCfg.client.via);
|
||||
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
|
||||
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.";
|
||||
};
|
||||
|
||||
cidrv4 = mkOption {
|
||||
type =
|
||||
if config.client.via != null
|
||||
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.
|
||||
'';
|
||||
ipv4 = mkOption {
|
||||
type = net.types.ipv4;
|
||||
description = mdDoc "The ipv4 address for this machine.";
|
||||
};
|
||||
|
||||
cidrv6 = mkOption {
|
||||
type =
|
||||
if config.client.via != null
|
||||
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.
|
||||
'';
|
||||
ipv6 = mkOption {
|
||||
type = net.types.ipv6;
|
||||
description = mdDoc "The ipv6 address for this machine.";
|
||||
};
|
||||
|
||||
addresses = mkOption {
|
||||
type = types.listOf (
|
||||
if config.client.via != null
|
||||
then net.types.cidr-in nodes.${config.client.via}.config.extra.wireguard.${name}.addresses
|
||||
else net.types.cidr
|
||||
);
|
||||
default = [config.cidrv4 config.cidrv6];
|
||||
type = types.listOf net.types.ip;
|
||||
default = [config.ipv4 config.ipv6];
|
||||
description = mdDoc ''
|
||||
The addresses (with cidr mask) to configure for this interface.
|
||||
The cidr mask determines this peers allowed address range as configured on other peers.
|
||||
The ip addresses (v4 and/or v6) to use for this machine.
|
||||
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