nibylandia/nixos/scylla/configuration.nix

596 lines
15 KiB
Nix

{ config, pkgs, ... }:
{
imports = [ ./hardware-configuration.nix ];
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot = {
kernelPackages = pkgs.linuxPackages_latest;
kernelParams =
[ "arm-smmu.disable_bypass=0" "pci=pcie_bus_perf" "iommu.passthrough=1" ];
# Setup SFP+ network interfaces early so systemd can pick everything up.
initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.restool}/bin/restool
copy_bin_and_libs ${pkgs.restool}/bin/ls-main
copy_bin_and_libs ${pkgs.restool}/bin/ls-addni
# Patch paths
sed -i "1i #!$out/bin/sh" $out/bin/ls-main
'';
initrd.postDeviceCommands = ''
ls-addni dpmac.7
ls-addni dpmac.8
ls-addni dpmac.9
ls-addni dpmac.10
'';
kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true;
"net.ipv6.conf.all.accept_ra" = 0;
"net.ipv6.conf.all.autoconf" = 0;
"net.ipv6.conf.all.use_tempaddr" = 0;
};
};
age.secrets = {
wgNibylandiaScylla.file = ../../secrets/wg/nibylandia_scylla.age;
wgDN42Scylla.file = ../../secrets/wg/dn42_w1kl4s_scylla.age;
ddnsKeyKea = {
file = ../../secrets/lan/nibylandia-ddns-kea.age;
mode = "444";
};
ddnsKeyBind = {
file = ../../secrets/lan/nibylandia-ddns-bind.age;
mode = "400";
owner = "named";
group = "named";
};
};
networking.hostName = "scylla";
networking.wireless.enable = false;
time.timeZone = "Europe/Warsaw";
systemd.network.enable = true;
networking.useNetworkd = true;
networking.useDHCP = false;
networking.interfaces = {
eth0 = {
useDHCP = true;
macAddress = "50:7b:9d:b5:fa:e8";
};
lan = {
ipv4.addresses = [{
address = "192.168.24.1";
prefixLength = 24;
}];
};
eth1 = {
ipv4.addresses = [{
address = "192.168.20.1";
prefixLength = 24;
}];
};
};
networking.nameservers = [ "192.168.20.1" ];
networking.vlans = {
lan = {
id = 10;
interface = "eth1";
};
};
networking.wireguard.interfaces = {
wg-nibylandia = {
ips = [ "10.255.255.2/24" ];
privateKeyFile = config.age.secrets.wgNibylandiaScylla.path;
listenPort = 51315;
allowedIPsAsRoutes = true;
peers = [{
publicKey = "xwTYtejNZCtOyPMNcZVlsBIGYae6aUQczh7UwujLxXg=";
allowedIPs = [ "10.255.255.0/24" ];
endpoint = "zorigami.is-a.cat:51315";
persistentKeepalive = 15;
}];
};
dn42_w1kl4s_1 = {
ips = [ "fd25:af2d:1f51:255::1/64" "fe80::255:acab/64" ];
privateKeyFile = config.age.secrets.wgDN42Scylla.path;
listenPort = 51516;
allowedIPsAsRoutes = false;
peers = [{
publicKey = "zNP632K1qrezFIl8NQK1tR3XEdYHat/YgzdCXnFIWDE=";
allowedIPs = [ "0.0.0.0/0" "::/0" ];
endpoint = "193.31.26.15:53137";
}];
postSetup = ''
${pkgs.iproute}/bin/ip addr add dev dn42_w1kl4s_1 172.20.148.161/32 peer 172.23.193.2/32
'';
};
};
networking.firewall.enable = true;
networking.firewall.logRefusedConnections = false;
networking.nat = {
enable = true;
externalInterface = "eth0";
internalInterfaces = [ "lan" "eth1" "virbr1" "virbr2" ];
forwardPorts = [
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.101.2:22";
sourcePort = 11520;
proto = "tcp";
} # sdomi's vm
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:22";
sourcePort = 23;
proto = "tcp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.32:22";
sourcePort = 32;
proto = "tcp";
}
{
destination = "192.168.20.31";
sourcePort = 2582;
proto = "tcp";
}
{
destination = "192.168.20.31";
sourcePort = "51411:51423";
proto = "tcp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:80";
sourcePort = 80;
proto = "tcp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:443";
sourcePort = 443;
proto = "tcp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:2005";
sourcePort = 2005;
proto = "tcp";
}
{
destination = "192.168.20.31";
sourcePort = "51411:51423";
proto = "udp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:80";
sourcePort = 80;
proto = "udp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:443";
sourcePort = 443;
proto = "udp";
}
{
loopbackIPs = [ "185.102.189.133" ];
destination = "192.168.20.31:2005";
sourcePort = 2005;
proto = "udp";
}
];
};
networking.firewall.allowedTCPPorts = [
179 # bgp
53
5201
6443 # k3s
];
networking.firewall.allowedUDPPorts = [
179 # bgp
53
51315
51516 # dn42-w1kl4s
];
networking.firewall.interfaces."eth1".allowedTCPPorts = [ 8123 ];
networking.firewall.interfaces."lan".allowedTCPPorts = [ 8123 ];
systemd.network.wait-online.extraArgs = [ "--any" ];
services.k3s = {
enable = false;
role = "server";
};
services.kea = {
dhcp4 = {
enable = true;
settings = {
interfaces-config = {
interfaces = [ "lan/192.168.24.1" "eth1/192.168.20.1" ];
};
lease-database = {
name = "/var/lib/kea/dhcp4.leases";
persist = true;
type = "memfile";
};
rebind-timer = 2000;
renew-timer = 1000;
valid-lifetime = 4000;
dhcp-ddns = {
enable-updates = true;
ncr-protocol = "UDP";
ncr-format = "JSON";
server-ip = "127.0.0.1";
server-port = 53001;
};
ddns-send-updates = true;
ddns-replace-client-name = "when-not-present";
ddns-update-on-renew = true;
ddns-override-client-update = true;
ddns-override-no-update = true;
subnet4 = [
{
subnet = "192.168.24.0/24";
pools = [{ pool = "192.168.24.40 - 192.168.24.240"; }];
reservations-out-of-pool = true;
reservations-in-subnet = true;
ddns-qualifying-suffix = "nibylandia.lan.";
option-data = [
{
name = "routers";
data = "192.168.24.1";
}
{
name = "domain-name-servers";
data = "192.168.24.1";
}
];
reservations = [{
hw-address = "34:15:13:b6:2a:e7";
hostname = "yamaha";
ip-address = "192.168.24.11";
}];
}
{
subnet = "192.168.20.0/24";
pools = [{ pool = "192.168.20.40 - 192.168.20.240"; }];
reservations-out-of-pool = true;
reservations-in-subnet = true;
ddns-qualifying-suffix = "nibylandia.lan.";
option-data = [
{
name = "routers";
data = "192.168.20.1";
}
{
name = "domain-name-servers";
data = "192.168.20.1";
}
];
reservations = [
{
hw-address = "00:02:c9:53:9a:c2";
hostname = "stereolith";
ip-address = "192.168.20.31";
}
{
hw-address = "00:30:93:12:0f:bf";
hostname = "microlith";
ip-address = "192.168.20.32";
}
];
}
];
};
};
dhcp-ddns = {
enable = true;
settings = {
dns-server-timeout = 100;
ip-address = "127.0.0.1";
ncr-format = "JSON";
ncr-protocol = "UDP";
forward-ddns = {
ddns-domains = [{
key-name = "bind-key-2021-12-27";
dns-servers = [{ ip-address = "192.168.20.1"; }];
name = "nibylandia.lan.";
}];
};
reverse-ddns = {
ddns-domains = [
{
key-name = "bind-key-2021-12-27";
dns-servers = [{ ip-address = "192.168.20.1"; }];
name = "20.168.192.in-addr.arpa.";
}
{
key-name = "bind-key-2021-12-27";
dns-servers = [{ ip-address = "192.168.20.1"; }];
name = "24.168.192.in-addr.arpa.";
}
];
};
tsig-keys = [{
name = "bind-key-2021-12-27";
algorithm = "HMAC-SHA512";
secret = "__keaInclude ${config.age.secrets.ddnsKeyKea.path}";
}];
};
};
};
services.bind = {
enable = true;
listenOn = [ "192.168.20.1" "192.168.24.1" ];
forwarders = [ "8.8.8.8" "1.1.1.1" "8.8.4.4" "1.0.0.1" ];
cacheNetworks = [ "192.168.20.0/24" "192.168.24.0/24" ];
zones = {
"nibylandia.lan" = {
master = true;
file = "/var/lib/bind/nibylandia.lan.zone";
extraConfig = ''
allow-update { key "bind-key-2021-12-27"; };
'';
};
"20.168.192.in-addr.arpa" = {
master = true;
file = "/var/lib/bind/20.168.192.in-addr.arpa.zone";
extraConfig = ''
allow-update { key "bind-key-2021-12-27"; };
'';
};
"24.168.192.in-addr.arpa" = {
master = true;
file = "/var/lib/bind/24.168.192.in-addr.arpa.zone";
extraConfig = ''
allow-update { key "bind-key-2021-12-27"; };
'';
};
};
extraConfig = ''
key "bind-key-2021-12-27" {
algorithm hmac-sha512;
include "${config.age.secrets.ddnsKeyBind.path}";
};
'';
extraOptions = ''
dnssec-validation no;
'';
};
services.bird2 = {
enable = true;
checkConfig = false;
config = ''
define OWNAS = 4242423137;
define OWNIP = 172.20.148.161;
define OWNIPv6 = fd25:af2d:1f51:255::1;
define OWNNET = 172.20.148.160/27;
define OWNNETv6 = fdc0:b038:c31e::/48;
define OWNNETSET = [ 172.20.148.160/27+ ];
define OWNNETSETv6 = [ fdc0:b038:c31e::/48+ ];
router id OWNIP;
protocol device {
scan time 10;
}
/*
* Utility functions
*/
function is_self_net() {
return net ~ OWNNETSET;
}
function is_self_net_v6() {
return net ~ OWNNETSETv6;
}
function is_valid_network() {
return net ~ [
172.20.0.0/14{21,29}, # dn42
172.20.0.0/24{28,32}, # dn42 Anycast
172.21.0.0/24{28,32}, # dn42 Anycast
172.22.0.0/24{28,32}, # dn42 Anycast
172.23.0.0/24{28,32}, # dn42 Anycast
172.31.0.0/16+, # ChaosVPN
10.100.0.0/14+, # ChaosVPN
10.127.0.0/16{16,32}, # neonetwork
10.0.0.0/8{15,24} # Freifunk.net
];
}
roa4 table dn42_roa;
roa6 table dn42_roa_v6;
protocol static {
roa4 { table dn42_roa; };
include "/etc/bird/roa_dn42.conf";
};
protocol static {
roa6 { table dn42_roa_v6; };
include "/etc/bird/roa_dn42_v6.conf";
};
function is_valid_network_v6() {
return net ~ [
fd00::/8{44,64} # ULA address space as per RFC 4193
];
}
protocol kernel {
scan time 20;
ipv6 {
import none;
export filter {
if source = RTS_STATIC then reject;
krt_prefsrc = OWNIPv6;
accept;
};
};
};
protocol kernel {
scan time 20;
ipv4 {
import none;
export filter {
if source = RTS_STATIC then reject;
krt_prefsrc = OWNIP;
accept;
};
};
}
protocol static {
route OWNNET reject;
ipv4 {
import all;
export none;
};
}
protocol static {
route OWNNETv6 reject;
ipv6 {
import all;
export none;
};
}
template bgp dnpeers {
local as OWNAS;
path metric 1;
ipv4 {
import filter {
if is_valid_network() && !is_self_net() then {
if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
reject;
} else accept;
} else reject;
};
export filter { if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };
import limit 1000 action block;
};
ipv6 {
import filter {
if is_valid_network_v6() && !is_self_net_v6() then {
if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
reject;
} else accept;
} else reject;
};
export filter { if is_valid_network_v6() && source ~ [RTS_STATIC, RTS_BGP] then accept; else reject; };
import limit 1000 action block;
};
}
include "/etc/bird/peers/*";
'';
};
security.polkit.enable = true;
virtualisation.libvirtd.enable = true;
services.avahi = {
enable = true;
reflector = true;
allowInterfaces = [ "lan" "eth1" ];
};
nixpkgs.config.allowUnfree = true;
nixpkgs.overlays =
[ (self: super: { restool = self.callPackage ./pkgs/restool { }; }) ];
environment.systemPackages = with pkgs; [
pv
libarchive
lshw
zip
file
tcpdump
lsof
restool
ethtool
pciutils
usbutils
dig
dstat
wget
bind
nmap
iperf
config.boot.kernelPackages.perf
];
programs = {
mtr.enable = true;
mosh.enable = true;
neovim = {
enable = true;
defaultEditor = true;
viAlias = true;
vimAlias = true;
};
zsh = {
enable = true;
enableBashCompletion = true;
autosuggestions.enable = true;
syntaxHighlighting.enable = true;
};
command-not-found.enable = false;
};
nix = {
package = pkgs.nixUnstable;
extraOptions = ''
experimental-features = nix-command flakes
'';
};
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGfIRe1nH6vwjQTjqHNnkKAdr1VYqGEeQnqInmf3A6UN ar@khas"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO6rEwERSm/Fj4KO4SxFIo0BUvi9YNyf8PSL1FteMcMt arachnist@monolith"
];
services.openssh.enable = true;
system.stateVersion = "22.05";
}