diff options
Diffstat (limited to 'hostnix/weebnix')
| -rw-r--r-- | hostnix/weebnix/Makefile | 7 | ||||
| -rw-r--r-- | hostnix/weebnix/boot/config.txt | 36 | ||||
| -rw-r--r-- | hostnix/weebnix/configuration.nix | 93 | ||||
| -rw-r--r-- | hostnix/weebnix/dyndns.nix | 78 | ||||
| -rw-r--r-- | hostnix/weebnix/hardware-configuration.nix | 51 | ||||
| -rw-r--r-- | hostnix/weebnix/home-assistant.nix | 116 | ||||
| -rw-r--r-- | hostnix/weebnix/oidc.nix | 51 | ||||
| -rw-r--r-- | hostnix/weebnix/privacy-frontends.nix | 15 | ||||
| -rw-r--r-- | hostnix/weebnix/syncthing.nix | 136 | ||||
| -rw-r--r-- | hostnix/weebnix/system.nix | 49 |
10 files changed, 632 insertions, 0 deletions
diff --git a/hostnix/weebnix/Makefile b/hostnix/weebnix/Makefile new file mode 100644 index 0000000..90591a9 --- /dev/null +++ b/hostnix/weebnix/Makefile @@ -0,0 +1,7 @@ +push: + rsync --rsync-path='sudo rsync' *.nix weebnix.lan:/etc/nixos/ + +switch: push + ssh weebnix.lan sudo nixos-rebuild switch + +.PHONY: push switch diff --git a/hostnix/weebnix/boot/config.txt b/hostnix/weebnix/boot/config.txt new file mode 100644 index 0000000..b407ad7 --- /dev/null +++ b/hostnix/weebnix/boot/config.txt @@ -0,0 +1,36 @@ +[pi3] +kernel=u-boot-rpi3.bin + +[pi02] +kernel=u-boot-rpi3.bin + +[pi4] +kernel=u-boot-rpi4.bin +enable_gic=1 +armstub=armstub8-gic.bin + +# Otherwise the resolution will be weird in most cases, compared to +# what the pi3 firmware does by default. +disable_overscan=1 + +# Supported in newer board revisions +arm_boost=1 + +[cm4] +# Enable host mode on the 2711 built-in XHCI USB controller. +# This line should be removed if the legacy DWC2 controller is required +# (e.g. for USB device mode) or if USB support is not required. +otg_mode=1 + +[all] +# Boot in 64-bit mode. +arm_64bit=1 + +# U-Boot needs this to work, regardless of whether UART is actually used or not. +# Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still +# a requirement in the future. +enable_uart=1 + +# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel +# when attempting to show low-voltage or overtemperature warnings. +avoid_warnings=1 diff --git a/hostnix/weebnix/configuration.nix b/hostnix/weebnix/configuration.nix new file mode 100644 index 0000000..a0166f5 --- /dev/null +++ b/hostnix/weebnix/configuration.nix @@ -0,0 +1,93 @@ +{ config, pkgs, ... }: + +{ + imports = [ + ./dyndns.nix + ./hardware-configuration.nix + ./home-assistant.nix + ./oidc.nix + ./privacy-frontends.nix + ./syncthing.nix + ./system.nix + ]; + + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + nix.settings.trusted-users = [ "joe" ]; + + security.sudo.wheelNeedsPassword = false; + + security.acme.acceptTerms = true; + security.acme.defaults.email = "hostmaster@mou.fo"; + # TODO switch to production certs + security.acme.defaults.server = "https://acme-staging-v02.api.letsencrypt.org/directory"; + + users.users.joe = { + isNormalUser = true; + extraGroups = [ "wheel" "syncthing" ]; + openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHcqQDnH0LcUWFV+cd9aABfM55+72UAn1ZY5x5bHwPL4IEgT1nagbi1X3FwCJkh2rEcDsHl4FflcNfh+IyU2VyuQfRIXl7CKP040ovXmPVzgU8JiEDrrRebpZ7aHCKk+4Q6cJ8dzAI1sRogVyYrV0hLB4yeMnVexkIcsQMt5pXQ1zodlzHfW1W7OWQDbKjIyh4pv1KJ/IIjiBIt7l+OCqi7wZK4ubmxyMhmZx1xpRC5mz2/29Mpt+1VgCmxC7Hv1SG7yu+U0s4eJ3kbzFKNcZ/bCYqFxK48dT66qhS3qZFg09omumG8IbEUcx+WqM1V7WhiJYig9x5ovmMToQXTJ5uxLtcovnxO/53IgwV7INvmr8+NhD+LlkQfSjjUAW09bhVj9sKIW2bbrIxlOT8z6CQY9zGXNXi8u1oxPt3Q7d3rMxoWhWnr2l3Ok7OIkWooOK3e0NdhgIAxZKlYJAmIYaX391sGTyiuwUy96mg5JcYsLYMfkEg/Sv+2vQp8kkvB0E= joe@sparky" + ]; + }; + + environment.systemPackages = with pkgs; [ + dig + file + gitFull + jq + libraspberrypi + sqlite-interactive + tmux + tree + ]; + + programs.vim.defaultEditor = true; + programs.nano.enable = false; + + services.openssh.enable = true; + + services.nginx = { + enable = true; + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + # Slightly crazy setup to SNI reverse proxy HTTPS to multiple upstreams. + # We displace ourselves onto port 8443, and send requests that are not + # intended for us to weeber. This is done because Apache running on weeber + # cannot SNI reverse proxy, so we put weebnix in front of weeber on IPv4. + # TODO get rid of all this when replacing weeber or maybe consider HAProxy + defaultSSLListenPort = 8443; + streamConfig = '' + map $ssl_preread_server_name $selected_upstream { + hostnames; + weebnix.mou.fo self; + *.weebnix.mou.fo self; + default weeber; + } + upstream self { server 127.0.0.1:8443; } + upstream weeber { server 192.168.0.168:443; } + server { + listen 0.0.0.0:443; + listen [::0]:443; + proxy_pass $selected_upstream; + ssl_preread on; + } + ''; + }; + + # TODO remove upon switching to production certs + services.oauth2_proxy.extraConfig = { + "ssl-insecure-skip-verify" = true; + "ssl-upstream-insecure-skip-verify" = true; + }; + + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? +} diff --git a/hostnix/weebnix/dyndns.nix b/hostnix/weebnix/dyndns.nix new file mode 100644 index 0000000..a59c665 --- /dev/null +++ b/hostnix/weebnix/dyndns.nix @@ -0,0 +1,78 @@ +{ config, pkgs, ... }: + +{ + # Needs to be started manually, and the key added to nameservers. + # Based on https://nixos.org/manual/nixos/stable/index.html#module-security-acme-config-dns + systemd.services.sig0-keygen = { + unitConfig = { + ConditionPathExists = "!/var/lib/secrets/${config.networking.fqdn}.id"; + }; + serviceConfig = { + Type = "oneshot"; + }; + path = [ pkgs.bind ]; + scriptArgs = config.networking.fqdn; + script = '' + mkdir -p /var/lib/secrets + chmod 755 /var/lib/secrets + cd /var/lib/secrets + dnssec-keygen -a RSASHA512 -b 2048 -n HOST -T KEY $1. > $1.id + ''; + }; + + systemd.services.dyndns = { + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + unitConfig = { + AssertPathExists = "/var/lib/secrets/${config.networking.fqdn}.id"; + # Defer errors for ~45min, throttle e-mails to ~hourly. + StartLimitIntervalSec = "1hr"; + StartLimitBurst = "45"; + }; + serviceConfig = { + Type = "oneshot"; + Restart = "on-failure"; + RestartSec = "1min"; + }; + path = [ pkgs.dnsutils pkgs.gawk pkgs.iproute2 ]; + scriptArgs = config.networking.fqdn; + script = '' + RR=''${1%%.*}.dynamic.''${1#*.} + + IP4=`dig +short @1.1.1.1 ch txt whoami.cloudflare | tr -d \"` + if [ -z "$IP4" ]; then + echo "Missing IP: $IP4" >&2 + exit 100 + fi + + # Follow some RFC 6724 default address guidance, excluding ULA. + # It might be more robust to bind a public source socket (RFC 5014). + IP6=`ip -6 address show scope global -deprecated | awk -F'[ /]+' '$2 == "inet6" && $3 !~ /^f[cd]/ { print $3; exit }'` + + OLDIP4=`dig +short @popfresh.mou.fo $RR A 2> /dev/null` + OLDIP6=`dig +short @popfresh.mou.fo $RR AAAA 2> /dev/null` + # [ "x$IP" = "x$OLDIP4" ] && exit 0 # no update + if [ "x$IP4" = "x$OLDIP4" -a "x$IP6" = "x$OLDIP6" ]; then + exit 0 + fi + + nsupdate -v -k /var/lib/secrets/`< /var/lib/secrets/$1.id`.private <<. + update delete $RR. A + update add $RR. 300 A $IP4 + update delete $RR. AAAA + ''${IP6:+update add $RR. 300 AAAA $IP6} + update delete $RR. TXT + update add $RR. 300 TXT "v=spf1 include:_spf.mou.fo ~all" + send + . + ''; + }; + + systemd.timers.dyndns = { + wantedBy = [ "multi-user.target" ]; + timerConfig = { + OnStartupSec = "10"; + OnUnitActiveSec = "1min"; + }; + }; +} diff --git a/hostnix/weebnix/hardware-configuration.nix b/hostnix/weebnix/hardware-configuration.nix new file mode 100644 index 0000000..d7ce9dc --- /dev/null +++ b/hostnix/weebnix/hardware-configuration.nix @@ -0,0 +1,51 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "usbhid" "usb_storage" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/574841f9-3d47-419b-a431-e0c0c0c4ee9d"; + fsType = "btrfs"; + options = [ "subvol=nixos-root" ]; + }; + + fileSystems."/nix" = + { device = "/dev/disk/by-uuid/574841f9-3d47-419b-a431-e0c0c0c4ee9d"; + fsType = "btrfs"; + options = [ "subvol=nix,noatime" ]; + }; + + fileSystems."/home" = + { device = "/dev/disk/by-uuid/574841f9-3d47-419b-a431-e0c0c0c4ee9d"; + fsType = "btrfs"; + options = [ "subvol=home" ]; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/8D56-48CD"; + fsType = "vfat"; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.end0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlan0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; + powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; +} diff --git a/hostnix/weebnix/home-assistant.nix b/hostnix/weebnix/home-assistant.nix new file mode 100644 index 0000000..77c7fa8 --- /dev/null +++ b/hostnix/weebnix/home-assistant.nix @@ -0,0 +1,116 @@ +{ pkgs, ... }: + +{ + services.postgresql = { + enable = true; + ensureDatabases = [ "hass" ]; + ensureUsers = [{ + name = "hass"; + ensureDBOwnership = true; + }]; + }; + + services.home-assistant = { + enable = true; + extraPackages = ps: with ps; [ psycopg2 ]; + extraComponents = [ + "androidtv_remote" + "apple_tv" + "cast" + "homekit_controller" + "hue" + "spotify" + "esphome" + "met" + "radio_browser" + ]; + customComponents = [ + ( + pkgs.buildHomeAssistantComponent rec { + owner = "BeryJu"; + domain = "auth_header"; + version = "1.10"; + src = pkgs.fetchFromGitHub { + inherit owner; + repo = "hass-auth-header"; + rev = "refs/tags/v${version}"; + hash = "sha256-dSmY3d8Kx0pXl+20dTGAYgjSH6OhNh53jPX7VLCZs7Y="; + }; + dontBuild = true; + } + ) + ( + pkgs.buildHomeAssistantComponent rec { + owner = "make-all"; + domain = "tuya_local"; + version = "2023.12.1"; + src = pkgs.fetchFromGitHub { + inherit owner; + repo = "tuya-local"; + rev = "refs/tags/${version}"; + hash = "sha256-vi5EmtXAyXaUbJl+yAT5EL0yYb3XFRaAj6fybQRCM4A="; + }; + propagatedBuildInputs = with pkgs.home-assistant.python.pkgs; [ + ( + buildPythonPackage rec { + pname = "tinytuya"; + version = "1.13.1"; + format = "wheel"; + src = pkgs.fetchPypi { + inherit pname version format; + hash = "sha256-j7t4P4U9iuVHyb6HASkf7LmBheHN32IjdKE60HUbjIE="; + }; + } + ) + colorama + ]; + dontBuild = true; + } + ) + ]; + config = { + default_config = { }; + http = { + server_host = "::1"; + trusted_proxies = [ "::1" ]; + use_x_forwarded_for = true; + }; + recorder.db_url = "postgresql://@/hass"; + auth_header = { }; + }; + }; + + services.nginx.virtualHosts."ha.weebnix.mou.fo" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://[::1]:8123"; + proxyWebsockets = true; + extraConfig = '' + # This is frequently used in examples but without clear explanation. It + # might help with WebSockets. + proxy_buffering off; + # oauth2_proxy NixOS module sets some non-standard headers, but we need + # the preferred_username claim. + auth_request_set $preferred_username $upstream_http_x_auth_request_preferred_username; + proxy_set_header X-Forwarded-Preferred-Username $preferred_username; + ''; + }; + # Duplicate relevant parts of root route to skip oauth2-proxy module magic. + locations."/api/" = { + proxyPass = "http://[::1]:8123"; + proxyWebsockets = true; + extraConfig = '' + proxy_buffering off; + ''; + }; + # Disable service worker caching that works improperly with reverse proxy. + # https://github.com/home-assistant/frontend/issues/14836 + # https://community.home-assistant.io/t/disabling-service-worker-reverse-proxy-auth-causes-issues/167082 + locations."/service_worker.js" = { + return = ''410 "Service worker disabled: https://github.com/home-assistant/frontend/issues/14836"''; + }; + }; + + services.oauth2_proxy.nginx.virtualHosts = [ "ha.weebnix.mou.fo" ]; +} diff --git a/hostnix/weebnix/oidc.nix b/hostnix/weebnix/oidc.nix new file mode 100644 index 0000000..bf70882 --- /dev/null +++ b/hostnix/weebnix/oidc.nix @@ -0,0 +1,51 @@ +{ ... }: + +{ + services.keycloak = { + enable = true; + database.passwordFile = "/var/lib/secrets/keycloak.dbpass"; + settings = { + hostname = "kc.weebnix.mou.fo"; + http-host = "127.0.0.1"; + http-port = 7567; + proxy = "edge"; + }; + }; + + services.nginx.virtualHosts."kc.weebnix.mou.fo" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:7567"; + # We can handle oauth2-proxy callbacks on any subdomain, but the Keycloak + # subdomain is the least arbitrary. + locations."/oauth2/".proxyPass = "http://127.0.0.1:4180"; + }; + + # Work around "upstream sent too big header" because of large tokens. + services.nginx.appendHttpConfig = '' + proxy_buffers 8 16k; + proxy_buffer_size 16k; + ''; + + # The oauth2_proxy module has a magic nginx.virtualHosts option that rewrites + # nginx configs. It's mostly unhelpful, but we use it for brevity. In + # particular, it configures Traefik-like ForwardAuth authentication with + # auth_request. Note if this resource is missing for whatever reason, the + # module magic will fail open (auth_request unset). + services.oauth2_proxy = { + enable = true; + cookie.domain = "weebnix.mou.fo"; + setXauthrequest = true; # include claims + email.domains = [ "*" ]; # allow any authenticated user + # https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/#keycloak-oidc-auth-provider + provider = "keycloak-oidc"; + clientID = "weebnix.mou.fo"; + # Sets OAUTH2_PROXY_COOKIE_SECRET and OAUTH2_PROXY_CLIENT_SECRET. + keyFile = "/var/lib/secrets/oauth2-proxy.env"; + redirectURL = "https://kc.weebnix.mou.fo/oauth2/callback"; + extraConfig = { + "oidc-issuer-url" = "https://kc.weebnix.mou.fo/realms/staging"; + "whitelist-domain" = ".weebnix.mou.fo"; + }; + }; +} diff --git a/hostnix/weebnix/privacy-frontends.nix b/hostnix/weebnix/privacy-frontends.nix new file mode 100644 index 0000000..b312155 --- /dev/null +++ b/hostnix/weebnix/privacy-frontends.nix @@ -0,0 +1,15 @@ +{ ... }: + +{ + services.libreddit = { + enable = true; + address = "[::1]"; + port = 7682; + }; + + services.nginx.virtualHosts."lr.weebnix.mou.fo" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://[::1]:7682"; + }; +} diff --git a/hostnix/weebnix/syncthing.nix b/hostnix/weebnix/syncthing.nix new file mode 100644 index 0000000..a0a09be --- /dev/null +++ b/hostnix/weebnix/syncthing.nix @@ -0,0 +1,136 @@ +{ ... }: + +let + staggeredVersioning = { + type = "staggered"; + params = { + cleanInterval = "3600"; + maxAge = "31536000"; + }; + }; +in +{ + systemd.tmpfiles.rules = [ + "d /var/lib/syncthing 0775 syncthing syncthing" + ]; + + systemd.services.syncthing = { + serviceConfig.UMask = "0002"; + }; + + services.syncthing = { + enable = true; + openDefaultPorts = true; + # Syncthing supports named sockets but the NixOS module assumes network. + guiAddress = "[::1]:8384"; + settings = { + devices = { + "Asus Nexus 7" = { + id = "BVZARYC-2D56A6I-V6L2VQF-MU7IVCT-ITJTCGQ-IGMZG2W-RZRCTOT-K4GDHAY"; + }; + "DESKTOP-SFVBFBU" = { + id = "FQEK2MG-2AVMHEM-H6KASQ3-RTA3Z3F-A4R4MUY-YELZVRQ-6QUDSHA-DZZN7AJ"; + autoAcceptFolders = true; + }; + "Joes-iPhone-6" = { + id = "F5APH5K-XXO454B-6YU4BTT-YPHF4KT-OD7YF5Y-JTWJRSU-UNJ2KZK-IVJZNQT"; + autoAcceptFolders = true; + }; + "iPad" = { + id = "U7D7667-RFEFHXX-TUJGGII-CE62S6P-YC6MWNV-4LBJ4YJ-5ZUZVPT-GBC5PQH"; + autoAcceptFolders = true; + }; + "maxsettings-C6554E6AF22F" = { + id = "HO3QQZO-RDWYDB6-U74ZQRC-FP7YPB2-IPB2EBC-KIQ5JII-FD4KBXR-J3GCOQ5"; + autoAcceptFolders = true; + }; + "penguin" = { + id = "5BEB6SZ-YAPV3CC-54RZF3V-HQXXP3Y-TTVDWDU-SHHNVCH-IXKZ3O2-6RXG6QL"; + autoAcceptFolders = true; + }; + "sparky" = { + id = "FE43LDI-33WS467-LIGFWCC-5PPSKN6-GYODEWJ-KLQZLN7-H3GYGLG-IJ2JGQW"; + autoAcceptFolders = true; + }; + "steamdeck" = { + id = "SCUAABL-XU6AS5H-IZZE4PN-LY5J4LH-OYZMXTU-2UMTVUL-I7B7QKE-ZBPSAQ5"; + autoAcceptFolders = true; + }; + "weeber.mou.fo" = { + id = "PRE6XCX-7JDMJGJ-6TPMHOS-TP2AT3S-T6CAR3Z-URL5EEU-HVXUDJ4-C5UJ2AV"; + autoAcceptFolders = true; + }; + }; + folders = { + "Documents" = { + id = "bhemx-9nh3v"; + path = "~/Documents"; + versioning = staggeredVersioning; + devices = [ "sparky" "weeber.mou.fo" ]; + }; + "Downloads" = { + id = "kvq6q-axjhu"; + path = "~/Downloads"; + versioning = staggeredVersioning; + devices = [ "sparky" "weeber.mou.fo" ]; + }; + "Game/Documents/Bioshock" = { + id = "7zhqz-x6uvw"; + path = "~/Game/Documents/Bioshock"; + versioning = staggeredVersioning; + devices = [ "weeber.mou.fo" ]; + }; + "Game/Epic Games/TheTalosPrinciple/UserData" = { + id = "vek7u-iausx"; + path = "~/Game/Epic Games/TheTalosPrinciple/UserData"; + versioning = staggeredVersioning; + devices = [ "DESKTOP-SFVBFBU" "maxsettings-C6554E6AF22F" "weeber.mou.fo" ]; + }; + "Game/PCSX2" = { + id = "chxsg-hpqgm"; + path = "~/Game/PCSX2"; + versioning = staggeredVersioning; + devices = [ "maxsettings-C6554E6AF22F" "weeber.mou.fo" ]; + }; + "Pictures" = { + id = "vfjsd-4fczh"; + path = "~/Pictures"; + versioning = staggeredVersioning; + devices = [ "sparky" "weeber.mou.fo" ]; + }; + "Sync" = { + id = "7thks-5badk"; + path = "~/Sync"; + versioning = staggeredVersioning; + devices = [ + "Asus Nexus 7" + "DESKTOP-SFVBFBU" + "Joes-iPhone-6" + "iPad" + "penguin" + "sparky" + "weeber.mou.fo" + ]; + }; + "iPad" = { + id = "qtzmu-fqdrs"; + path = "~/iPad"; + versioning = staggeredVersioning; + devices = [ "iPad" "weeber.mou.fo" ]; + }; + }; + }; + }; + + services.nginx.virtualHosts."st.weebnix.mou.fo" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://[::1]:8384"; + # https://docs.syncthing.net/users/faq.html#why-do-i-get-host-check-error-in-the-gui-api + recommendedProxySettings = false; + }; + }; + + services.oauth2_proxy.nginx.virtualHosts = [ "st.weebnix.mou.fo" ]; +} diff --git a/hostnix/weebnix/system.nix b/hostnix/weebnix/system.nix new file mode 100644 index 0000000..8c80708 --- /dev/null +++ b/hostnix/weebnix/system.nix @@ -0,0 +1,49 @@ +{ pkgs, lib, ... }: + +{ + boot.loader.systemd-boot.enable = true; + # Raspberry Pi has no NVRAM. + boot.loader.efi.canTouchEfiVariables = false; + + boot.kernelPackages = pkgs.linuxPackages_rpi4; + # https://github.com/NixOS/nixpkgs/issues/122130#issuecomment-1568815007 + # It's unclear if these are strictly necessary with the downstream kernel, + # but let's leave them in to keep working with mainline. + boot.initrd.availableKernelModules = [ "uas" "pcie-brcmstb" "reset-raspberrypi" ]; + + networking.hostName = "weebnix"; + networking.domain = "mou.fo"; + # TODO secrets management or switch to wired + networking.wireless = { + enable = true; + networks."oldschool".psk = builtins.readFile /var/lib/secrets/oldschool.wpa-psk; + }; + + systemd.network.enable = true; + networking.useNetworkd = true; + networking.dhcpcd.enable = false; + networking.tempAddresses = "disabled"; + + systemd.network.networks = let + default = { + networkConfig = { + DHCP = "yes"; + MulticastDNS = "yes"; + }; + ipv6AcceptRAConfig.Token = "prefixstable"; # RFC 7217 + }; + in { + "10-wlan" = lib.recursiveUpdate default { + matchConfig.Name = "wlan0"; + }; + "10-eth" = lib.recursiveUpdate default { + matchConfig.Name = "end0"; + linkConfig.RequiredForOnline = "no"; + }; + }; + + # Problematic when the clock is unreliable (Pi has no RTC). + services.resolved.dnssec = "false"; + + time.timeZone = "America/New_York"; +} |
