greatly simplify ipv4 and ipv6 configuration

This commit is contained in:
Alex 2023-03-24 14:32:39 +01:00
parent a0db30ca26
commit e2aea648cf
12 changed files with 76 additions and 79 deletions

View file

@ -9,3 +9,4 @@ piranha.polyno.me,2a01:cb05:8984:3c00:223:24ff:feb0:ea82 ssh-ed25519 AAAAC3NzaC1
2a01:e0a:5e4:1d0:223:24ff:feaf:fdec ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAsZas74RT6lCZwuUOPR23nPdbSdpWORyAmRgjoiMVHK 2a01:e0a:5e4:1d0:223:24ff:feaf:fdec ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAsZas74RT6lCZwuUOPR23nPdbSdpWORyAmRgjoiMVHK
df-pw5.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK/dJIxioCkfeehxeGiZR7qquYGoqEH/YrRJ/ukEcaLH df-pw5.machine.deuxfleurs.fr ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK/dJIxioCkfeehxeGiZR7qquYGoqEH/YrRJ/ukEcaLH
10.14.3.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJnpO6zpLWsyyugOoOj+2bUow9TUrcWgURFGGaoyu+co 10.14.3.1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJnpO6zpLWsyyugOoOj+2bUow9TUrcWgURFGGaoyu+co
192.168.1.22 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMf/ioVSSb19Slu+HZLgKt4f1/XsL+K9uMxazSWb/+nQ

View file

@ -8,6 +8,12 @@
./remote-unlock.nix ./remote-unlock.nix
]; ];
deuxfleurs.remoteUnlock = {
networkInterface = "eno1";
staticIP = "192.168.1.22/24";
defaultGateway = "192.168.1.1";
};
# Use the systemd-boot EFI boot loader. # Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.timeout = 20; boot.loader.timeout = 20;
@ -15,8 +21,6 @@
networking.hostName = "carcajou"; networking.hostName = "carcajou";
deuxfleurs.network_interface = "eno1";
deuxfleurs.lan_ip = "192.168.1.22";
deuxfleurs.ipv6 = "2001:910:1204:1::22"; deuxfleurs.ipv6 = "2001:910:1204:1::22";
deuxfleurs.cluster_ip = "10.14.1.2"; deuxfleurs.cluster_ip = "10.14.1.2";

View file

@ -10,8 +10,6 @@
networking.hostName = "caribou"; networking.hostName = "caribou";
deuxfleurs.network_interface = "eno1";
deuxfleurs.lan_ip = "192.168.1.23";
deuxfleurs.ipv6 = "2001:910:1204:1::23"; deuxfleurs.ipv6 = "2001:910:1204:1::23";
deuxfleurs.cluster_ip = "10.14.1.3"; deuxfleurs.cluster_ip = "10.14.1.3";

View file

@ -11,10 +11,11 @@
networking.hostName = "df-pw5"; networking.hostName = "df-pw5";
deuxfleurs.network_interface = "eno1"; deuxfleurs.staticIPv4.address = "192.168.5.130/24";
deuxfleurs.lan_ip = "192.168.5.130";
deuxfleurs.ipv6 = "2a02:a03f:6510:5102:223:24ff:feb0:e8a7"; deuxfleurs.ipv6 = "2a02:a03f:6510:5102:223:24ff:feb0:e8a7";
deuxfleurs.cluster_ip = "10.14.4.1"; deuxfleurs.cluster_ip = "10.14.4.1";
deuxfleurs.is_raft_server = false; deuxfleurs.is_raft_server = false;
system.stateVersion = "22.11";
} }

View file

@ -10,8 +10,7 @@
networking.hostName = "origan"; networking.hostName = "origan";
deuxfleurs.network_interface = "eno1"; deuxfleurs.staticIPv4.address = "192.168.1.33/24";
deuxfleurs.lan_ip = "192.168.1.33";
deuxfleurs.ipv6 = "2a01:e0a:5e4:1d0:223:24ff:feaf:fdec"; deuxfleurs.ipv6 = "2a01:e0a:5e4:1d0:223:24ff:feaf:fdec";
deuxfleurs.cluster_ip = "10.14.2.33"; deuxfleurs.cluster_ip = "10.14.2.33";

View file

@ -10,8 +10,7 @@
networking.hostName = "piranha"; networking.hostName = "piranha";
deuxfleurs.network_interface = "eno1"; deuxfleurs.staticIPv4.address = "192.168.1.25/24";
deuxfleurs.lan_ip = "192.168.1.25";
deuxfleurs.ipv6 = "2a01:cb05:8984:9900:223:24ff:feb0:ea82"; deuxfleurs.ipv6 = "2a01:cb05:8984:9900:223:24ff:feb0:ea82";
deuxfleurs.cluster_ip = "10.14.3.1"; deuxfleurs.cluster_ip = "10.14.3.1";

View file

@ -2,10 +2,7 @@
{ {
deuxfleurs.site_name = "bespin"; deuxfleurs.site_name = "bespin";
deuxfleurs.lan_default_gateway = "192.168.5.254"; deuxfleurs.staticIPv4.defaultGateway = "192.168.5.254";
deuxfleurs.ipv6_default_gateway = "2a02:a03f:6510:5102::1";
deuxfleurs.lan_ip_prefix_length = 24;
deuxfleurs.ipv6_prefix_length = 64;
deuxfleurs.cname_target = "bespin.site.staging.deuxfleurs.org."; deuxfleurs.cname_target = "bespin.site.staging.deuxfleurs.org.";
networking.firewall.allowedTCPPorts = [ 80 443 ]; networking.firewall.allowedTCPPorts = [ 80 443 ];

View file

@ -2,10 +2,7 @@
{ {
deuxfleurs.site_name = "corrin"; deuxfleurs.site_name = "corrin";
deuxfleurs.lan_default_gateway = "192.168.1.1"; deuxfleurs.staticIPv4.defaultGateway = "192.168.1.1";
deuxfleurs.ipv6_default_gateway = "fe80::7ec1:77ff:fe3e:bb90";
deuxfleurs.lan_ip_prefix_length = 24;
deuxfleurs.ipv6_prefix_length = 64;
deuxfleurs.cname_target = "corrin.site.staging.deuxfleurs.org."; deuxfleurs.cname_target = "corrin.site.staging.deuxfleurs.org.";
deuxfleurs.public_ipv4 = "82.120.233.78"; deuxfleurs.public_ipv4 = "82.120.233.78";

View file

@ -2,10 +2,7 @@
{ {
deuxfleurs.site_name = "jupiter"; deuxfleurs.site_name = "jupiter";
deuxfleurs.lan_default_gateway = "192.168.1.1"; deuxfleurs.staticIPv4.defaultGateway = "192.168.1.1";
deuxfleurs.ipv6_default_gateway = "fe80::9038:202a:73a0:e73b";
deuxfleurs.lan_ip_prefix_length = 24;
deuxfleurs.ipv6_prefix_length = 64;
deuxfleurs.cname_target = "jupiter.site.staging.deuxfleurs.org."; deuxfleurs.cname_target = "jupiter.site.staging.deuxfleurs.org.";
# no public ipv4 is used for the staging cluster on Jupiter # no public ipv4 is used for the staging cluster on Jupiter

View file

@ -2,10 +2,6 @@
{ {
deuxfleurs.site_name = "neptune"; deuxfleurs.site_name = "neptune";
deuxfleurs.lan_default_gateway = "192.168.1.1";
deuxfleurs.ipv6_default_gateway = "2001:910:1204:1::1";
deuxfleurs.lan_ip_prefix_length = 24;
deuxfleurs.ipv6_prefix_length = 64;
deuxfleurs.cname_target = "neptune.site.staging.deuxfleurs.org."; deuxfleurs.cname_target = "neptune.site.staging.deuxfleurs.org.";
# no public ipv4 is used for the staging cluster on Neptune, # no public ipv4 is used for the staging cluster on Neptune,

View file

@ -36,36 +36,20 @@ in
in in
{ {
# Parameters for individual nodes # Parameters for individual nodes
network_interface = mkOption {
description = "Network interface name to configure";
type = types.str;
};
lan_ip = mkOption {
description = "IP address of this node on the local network interface";
type = types.str;
};
lan_ip_prefix_length = mkOption {
description = "Prefix length associated with lan_ip";
type = types.int;
};
ipv6 = mkOption { ipv6 = mkOption {
description = "Public IPv6 address of this node"; description = "Static public IPv6 address of this node";
type = types.str; type = types.str;
}; };
ipv6_prefix_length = mkOption { staticIPv4.address = mkOption {
description = "Prefix length associated with ipv6 ip"; description = "IP address (with prefix length) of this node on the local network interface";
type = types.int; type = types.nullOr types.str;
default = null;
}; };
cluster_ip = mkOption { cluster_ip = mkOption {
description = "IP address of this node on the Wesher mesh network"; description = "IP address of this node on the Wesher mesh network";
type = types.str; type = types.str;
}; };
wireguard_port = mkOption {
description = "Port for incoming Wireguard VPN connections";
type = types.port;
default = 33799;
};
is_raft_server = mkOption { is_raft_server = mkOption {
description = "Make this node a RAFT server for the Nomad and Consul deployments"; description = "Make this node a RAFT server for the Nomad and Consul deployments";
@ -74,18 +58,15 @@ in
}; };
# Parameters that generally vary between sites # Parameters that generally vary between sites
lan_default_gateway = mkOption {
description = "IPv4 address of the default route on the local network interface";
type = types.str;
};
ipv6_default_gateway = mkOption {
description = "IPv6 address of the default IPv6 gateway for the targeted net interface";
type = types.str;
};
site_name = mkOption { site_name = mkOption {
description = "Site (availability zone) on which this node is deployed"; description = "Site (availability zone) on which this node is deployed";
type = types.str; type = types.str;
}; };
staticIPv4.defaultGateway = mkOption {
description = "IPv4 address of the default route on the local network interface";
type = types.nullOr types.str;
default = null;
};
public_ipv4 = mkOption { public_ipv4 = mkOption {
description = "Public IPv4 through which this node is accessible (possibly after port opening using DiploNAT), for domain names that are updated by D53"; description = "Public IPv4 through which this node is accessible (possibly after port opening using DiploNAT), for domain names that are updated by D53";
type = types.nullOr types.str; type = types.nullOr types.str;
@ -124,6 +105,13 @@ in
type = types.bool; type = types.bool;
default = false; default = false;
}; };
# Options that generally stay to their default value
wireguardPort = mkOption {
description = "Port for incoming Wireguard VPN connections";
type = types.port;
default = 33799;
};
}; };
imports = [ imports = [
@ -157,33 +145,33 @@ in
systemd.network.networks = { systemd.network.networks = {
"10-uplink" = { "10-uplink" = {
matchConfig = { matchConfig = {
# We could preprend "en* eth*" to match all ethernet interfaces Name = "en* eth*";
Name = "${cfg.network_interface}";
}; };
ipv6AcceptRAConfig = {
Token = "static:${cfg.ipv6}";
UseDNS = false;
};
} // (if cfg.staticIPv4.address == null || cfg.staticIPv4.defaultGateway == null then {
networkConfig = { networkConfig = {
IPv6AcceptRA = false; DHCP = "ipv4";
LinkLocalAddressing = "no";
}; };
dhcpV4Config = {
UseDNS = false;
};
} else {
address = [ address = [
"${cfg.lan_ip}/${toString cfg.lan_ip_prefix_length}" "${cfg.staticIPv4.address}"
"${cfg.ipv6}/${toString cfg.ipv6_prefix_length}"
]; ];
routes = [ routes = [
{ {
routeConfig = { routeConfig = {
Gateway = cfg.lan_default_gateway; Gateway = cfg.staticIPv4.defaultGateway;
# GatewayOnLink - Takes a boolean. If set to true, the kernel does not have to check if the gateway is reachable directly by the current machine (i.e., attached to the local network), so that we can insert the route in the kernel table without it being complained about. Defaults to "no". # GatewayOnLink - Takes a boolean. If set to true, the kernel does not have to check if the gateway is reachable directly by the current machine (i.e., attached to the local network), so that we can insert the route in the kernel table without it being complained about. Defaults to "no".
GatewayOnLink = true; GatewayOnLink = true;
}; };
} }
{
routeConfig = {
Gateway = cfg.ipv6_default_gateway;
GatewayOnLink = true;
};
}
]; ];
}; });
}; };
# Configure Unbound as a central DNS server for everything # Configure Unbound as a central DNS server for everything
@ -221,7 +209,7 @@ in
# Configure Wireguard VPN between all nodes # Configure Wireguard VPN between all nodes
networking.wireguard.interfaces.wg0 = { networking.wireguard.interfaces.wg0 = {
ips = [ "${cfg.cluster_ip}/16" ]; ips = [ "${cfg.cluster_ip}/16" ];
listenPort = cfg.wireguard_port; listenPort = cfg.wireguardPort;
privateKeyFile = "/var/lib/deuxfleurs/wireguard-keys/private"; privateKeyFile = "/var/lib/deuxfleurs/wireguard-keys/private";
mtu = 1420; mtu = 1420;
}; };
@ -248,7 +236,7 @@ in
# systemd.services."wg-quick-wg0".after = [ "unbound.service" ]; # systemd.services."wg-quick-wg0".after = [ "unbound.service" ];
# networking.wg-quick.interfaces.wg0 = { # networking.wg-quick.interfaces.wg0 = {
# address = [ "${cfg.cluster_ip}/16" ]; # address = [ "${cfg.cluster_ip}/16" ];
# listenPort = cfg.wireguard_port; # listenPort = cfg.wireguardPort;
# privateKeyFile = "/var/lib/deuxfleurs/wireguard-keys/private"; # privateKeyFile = "/var/lib/deuxfleurs/wireguard-keys/private";
# mtu = 1420; # mtu = 1420;
# peers = map ({ publicKey, endpoint, IP, ... }: { # peers = map ({ publicKey, endpoint, IP, ... }: {
@ -384,13 +372,14 @@ in
allowedUDPPorts = [ allowedUDPPorts = [
# Allow peers to connect to Wireguard # Allow peers to connect to Wireguard
cfg.wireguard_port cfg.wireguardPort
]; ];
# Allow specific hosts access to specific things in the cluster # Allow specific hosts access to specific things in the cluster
extraCommands = '' extraCommands = ''
# Allow everything from router (usefull for UPnP/IGD) # Allow UDP packets comming from port 1900 from a local address,
iptables -A INPUT -s ${cfg.lan_default_gateway} -j ACCEPT # these are necessary for UPnP/IGD
iptables -A INPUT -s 192.168.0.0/16 -p udp --sport 1900 -j ACCEPT
# Allow docker containers to access all ports # Allow docker containers to access all ports
iptables -A INPUT -s 172.17.0.0/16 -j ACCEPT iptables -A INPUT -s 172.17.0.0/16 -j ACCEPT
@ -401,7 +390,7 @@ in
# When stopping firewall, delete all rules that were configured manually above # When stopping firewall, delete all rules that were configured manually above
extraStopCommands = '' extraStopCommands = ''
iptables -D INPUT -s ${cfg.lan_default_gateway} -j ACCEPT iptables -D INPUT -s 192.168.0.0/16 -p udp --sport 1900 -j ACCEPT
iptables -D INPUT -s 172.17.0.0/16 -j ACCEPT iptables -D INPUT -s 172.17.0.0/16 -j ACCEPT
iptables -D INPUT -s ${cfg.cluster_prefix}/${toString cfg.cluster_prefix_length} -j ACCEPT iptables -D INPUT -s ${cfg.cluster_prefix}/${toString cfg.cluster_prefix_length} -j ACCEPT
''; '';

View file

@ -1,8 +1,27 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
let
cfg = config.deuxfleurs.remoteUnlock;
in
with builtins; with builtins;
with pkgs.lib; with pkgs.lib;
{ {
options.deuxfleurs.remoteUnlock = {
networkInterface = mkOption {
description = "Network interface to configure with static IP";
type = types.str;
};
staticIP = mkOption {
description = "IP address (with prefix length) of this node on the local network interface";
type = types.str;
};
defaultGateway = mkOption {
description = "IP address of default gateway";
type = types.str;
};
};
config = { config = {
boot.initrd.availableKernelModules = [ "pps_core" "ptp" "e1000e" ]; boot.initrd.availableKernelModules = [ "pps_core" "ptp" "e1000e" ];
boot.initrd.network.enable = true; boot.initrd.network.enable = true;
@ -13,12 +32,12 @@
hostKeys = [ "/var/lib/deuxfleurs/remote-unlock/ssh_host_ed25519_key" ]; hostKeys = [ "/var/lib/deuxfleurs/remote-unlock/ssh_host_ed25519_key" ];
}; };
boot.initrd.network.postCommands = '' boot.initrd.network.postCommands = ''
ip addr add ${config.deuxfleurs.lan_ip}/${toString config.deuxfleurs.lan_ip_prefix_length} dev ${config.deuxfleurs.network_interface} ip addr add ${cfg.staticIP} dev ${cfg.networkInterface}
ip link set dev ${config.deuxfleurs.network_interface} up ip link set dev ${cfg.networkInterface} up
ip route add default via ${config.deuxfleurs.lan_default_gateway} dev ${config.deuxfleurs.network_interface} ip route add default via ${cfg.defaultGateway} dev ${cfg.networkInterface}
ip a ip a
ip route ip route
ping -c 4 ${config.deuxfleurs.lan_default_gateway} ping -c 4 ${cfg.defaultGateway}
echo 'echo run cryptsetup-askpass to unlock drives' >> /root/.profile echo 'echo run cryptsetup-askpass to unlock drives' >> /root/.profile
''; '';
}; };