diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6eba117..67fabec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,11 @@ name: CI + on: push: -defaults: - run: - shell: nix develop --command bash -c "{0}" + env: - CACHE_NAME: qois - CACHE_REPOSITORY: qois:qois-infrastructure + ATTIC_AUTH_TOKEN: ${{ secrets.ATTIC_AUTH_TOKEN }} + jobs: build: runs-on: nix @@ -16,46 +15,31 @@ jobs: with: token: ${{ secrets.CI_TOKEN }} lfs: false - - name: Setup Attic Cache - env: - SERVER: https://attic.qo.is/ - ATTIC_AUTH_TOKEN: ${{ secrets.ATTIC_AUTH_TOKEN }} + + - name: Add submodules to nix store to circumvent another nix bug run: | - attic login "$CACHE_NAME" "$SERVER" "$ATTIC_AUTH_TOKEN" - attic use "$CACHE_REPOSITORY" - - name: Run Builds and Checks - run: nix-fast-build --no-nom --max-jobs 6 --skip-cached --attic-cache "$CACHE_REPOSITORY" - deploy: - needs: build - if: success() && github.ref == 'refs/heads/main' - runs-on: nix - env: - SSH_DEPLOY_KEY: "${{ secrets.SSH_DEPLOY_KEY }}" - strategy: - matrix: - profile: - - docs-ops.qo.is - - system-vm - - system-physical - steps: - - name: Initialize CI - uses: https://git.qo.is/qo.is/actions-nix-init@main - with: - token: ${{ secrets.CI_TOKEN }} - lfs: false - - name: "Deploy profile" - run: "auto-deploy ${{ matrix.profile }}" - deploy-ci: - needs: deploy - if: success() && github.ref == 'refs/heads/main' - runs-on: nix - env: - SSH_DEPLOY_KEY: "${{ secrets.SSH_DEPLOY_KEY }}" - steps: - - name: Initialize CI - uses: https://git.qo.is/qo.is/actions-nix-init@main - with: - token: ${{ secrets.CI_TOKEN }} - lfs: false - - name: "Deploy profile" - run: "auto-deploy system-ci" + git clone https://git.qo.is/qo.is/infrastructure-private.git /tmp/private + cd /tmp/private + nix flake prefetch + + - name: Use attic cache + run: nix run .#cache use + + - name: Build + run: | + nix build --max-jobs 12 --cores 12 + nix run .#cache push + + - name: Run Checks + run: nix flake check + + - name: Deploy Docs + if: success() && github.ref == 'refs/heads/main' + run: | + mkdir ~/.ssh/ + echo -e "Host lindberg-webapps.backplane.net.qo.is\n StrictHostKeyChecking no" >> ~/.ssh/config + (umask 0077 && printf "%s\n" "${{ secrets.SSH_DEPLOY_KEY }}" > ~/.ssh/id_ed25519) + # Remote build might be neccessary due to non-wheel nix users signing restrictions. + # However, the build should come from the cache anyway. + nix develop --command deploy --skip-checks --remote-build .#lindberg-webapps.\"docs-ops.qo.is\" + diff --git a/.gitignore b/.gitignore index 6454c83..9e92574 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,3 @@ result* /.direnv /book /.sops.yaml -/.nixos-test-history -/.pre-commit-config.yaml diff --git a/.nixd.json b/.nixd.json index 1e4b0db..b1e6c19 100644 --- a/.nixd.json +++ b/.nixd.json @@ -1,21 +1,18 @@ { - "eval": { - "target": { - "args": [ - "-f", - "default.nix" - ], - "installable": "" + "eval": { + "target": { + "args": ["-f", "default.nix"], + "installable": "" + } + }, + "formatting": { + "command": "nixfmt" + }, + "options": { + "enable": true, + "target": { + "args": [], + "installable": "" + } } - }, - "formatting": { - "command": "nixfmt" - }, - "options": { - "enable": true, - "target": { - "args": [], - "installable": "" - } - } } diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 76d746c..fce5ab4 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,5 @@ { - "recommendations": [ - "jnoortheen.nix-ide" - ] -} + "recommendations": [ + "jnoortheen.nix-ide" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index f6949fe..3eaa3c7 100644 --- a/README.md +++ b/README.md @@ -6,65 +6,63 @@ Check out the current [rendered documentation](https://docs-ops.qo.is). ## Structure -`nixos-configurations`: Main nixos configuration for every host.\ -`defaults`: Configuration defaults\ -`nixos-modules`: Custom modules (e.g. for vpn and routers)\ +`nixos-configurations`: Main nixos configuration for every host. +`defaults`: Configuration defaults +`nixos-modules`: Custom modules (e.g. for vpn and routers) `private`: Private configuration values (like users, sops-encrypted secrets and keys) -## Development +## Building This repository requires [nix flakes](https://nixos.wiki/wiki/Flakes) -- `nix flake check`\ - Execute the project's checks, which includes building all configurations and packages. See [Tests](./checks/README.md). +- `nix build` + Build all host configurations and docs +- `nix build .#nixosConfigurations..config.system.build.toplevel` + Build a single host configuration with +- `nix build .#docs` + Build the documentation website -- `nix build .#nixosConfigurations..config.system.build.toplevel`\ - Build a single host configuration. +## Development -- `nix build .#docs`\ - Build the documentation website. - -- `nix develop`\ +- `nix develop` Development environment - -- `nix fmt`\ +- `nix flake check` + Execute the project's checks +- `nix fmt` Autofix formatting -### Secrets and `private` Submodule +### Working with the private submodule -Secret management is done with [nix-sops](https://github.com/Mic92/sops-nix) and a git submodule in `private`.\ -Make sure you have the submodule correctly available. To clone with submodules (if you have access): +To clone with submodules (if you have access): ```bash git clone --recurse-submodules https://git.qo.is/qo.is/infrastructure.git -# See below for how to commit changes. ``` +On changes: + +```bash +git add private +nix flake lock --update-input private +``` + +## Deployment + +`nix run .#deploy-qois` + +See [Deployment](deploy/README.md) for details. + +## Secrets + +Secret management is done with [nix-sops](https://github.com/Mic92/sops-nix). + Secrets are stored in `private/passwords.sops.yaml` (sysadmin passwords), -`private/nixos-modules/shared-secrets/default.sops.yaml` (shared secrets for all hosts) and +`private/nixos-configurations/secrets.sops.yaml` (shared secrets for all hosts) and `private/nixos-configurations//secrets.sops.yaml` (host specific secrets). -To modify secrets: +Usage: ```bash sops $file # To edit a file sops-rekey # To rekey all secrets, e.g. after a key rollover or new host ``` - -After changing secrets: - -```bash -# Commit changes in subrepo -pushd private - git commit - git push - nix flake prefetch . # Make subrepo available in nix store. Required until nix 2.27. -popd - -git add private -nix flake lock --update-input private -``` - -## Deployment - -See [Deployment](deploy/) for details. diff --git a/SUMMARY.md b/SUMMARY.md index c69dcf2..498cc39 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,10 +1,9 @@ # Summary - [Repository README](README.md) -- [Testing](checks/README.md) - [Deployment](deploy/README.md) -______________________________________________________________________ +--- - [Network Topology](defaults/meta/network.md) - [Hardware (generic)](defaults/hardware/README.md) @@ -12,15 +11,16 @@ ______________________________________________________________________ - [Updates](updates.md) - [New Host Setup](nixos-configurations/setup.md) + # Services - [E-mail](email.md) -- [Git CI Runner](nixos-modules/git-ci-runner/README.md) -- [Git Hosting](nixos-modules/git/README.md) -- [Nextcloud](nixos-modules/cloud/README.md) +- [Git CI Runner](nixos-modules/qois/git-ci-runner/README.md) +- [Git Hosting](nixos-modules/qois/git/README.md) +- [Nextcloud](defaults/nextcloud/README.md) - [Nix Caches](nixos-configurations/lindberg-build/applications/README.md) -- [Static Pages](nixos-modules/static-page/README.md) -- [VPN](nixos-modules/vpn-server/README.md) +- [Static Pages](nixos-modules/qois/static-page/README.md) +- [VPN](defaults/vpn/README.md) - [Vaultwarden](nixos-modules/vault/README.md) # Nixos Configurations @@ -28,3 +28,5 @@ ______________________________________________________________________ - [calanda](nixos-configurations/calanda/README.md) - [cyprianspitz](nixos-configurations/cyprianspitz/README.md) - [lindberg](nixos-configurations/lindberg/README.md) +- [stompert](nixos-configurations/stompert/README.md) + diff --git a/checks/README.md b/checks/README.md deleted file mode 100644 index d8f6db8..0000000 --- a/checks/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Tests - -`nix flake check` currently: - -- builds all nixos-configurations -- builds all packages -- runs all [nixos-module tests](#module-tests) -- checks all deployment configurations -- checks repository formatting. - -## Module Tests - -We test our nixos modules with [NixOS tests](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests). -Running nixos tests requires QEMU virtualisation, so make sure you have KVM virtualisation support enabled. - -Run all: `nix build .#checks.x86_64-linux.nixos-modules`\ -Run single test: `nix build .#checks.x86_64-linux.nixos-modules.entries.vm-test-run-testNameAsInDerivationName` - -### Run Test Interactively - -```bash -nix run .#checks.x86_64-linux.nixos-modules.entries.vm-test-run-testNameAsInDerivationName.driverInteractive -``` - -See [upstream documentation](https://nixos.org/manual/nixos/stable/#sec-running-nixos-tests-interactively) for more details. diff --git a/checks/default.nix b/checks/default.nix index 19ee99a..ae33fc0 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -1,22 +1,22 @@ { self, - flakeSelf, system, pkgs, deployPkgs, - treefmtEval, ... }@inputs: { ${system} = { - formatting = treefmtEval.config.build.check flakeSelf; - nixos-modules = pkgs.callPackage ./nixos-modules { - defaultModule = self.nixosModules.default; - inherit (self.lib) getSubDirs isFolderWithFile; - }; + # Check project formatting + format = pkgs.runCommand "nixfmt-check" { } '' + set -euo pipefail + cd ${self} + ${self.formatter.${system}}/bin/formatter . --check + mkdir $out + ''; - nixos-configurations = import ./nixos-configurations inputs; + #TODO(#29): Integration/System tests # Import deploy-rs tests } // (deployPkgs.deploy-rs.lib.deployChecks self.deploy); diff --git a/checks/nixos-configurations/default.nix b/checks/nixos-configurations/default.nix deleted file mode 100644 index 689078b..0000000 --- a/checks/nixos-configurations/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ self, pkgs, ... }: -pkgs.linkFarmFromDrvs "all" ( - pkgs.lib.mapAttrsToList (_n: v: v.config.system.build.toplevel) self.nixosConfigurations -) diff --git a/checks/nixos-modules/default.nix b/checks/nixos-modules/default.nix deleted file mode 100644 index 4773359..0000000 --- a/checks/nixos-modules/default.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ - linkFarmFromDrvs, - isFolderWithFile, - getSubDirs, - lib, - testers, - defaultModule, -}: -let - inherit (lib) - filter - path - mkDefault - mkForce - readFile - attrNames - concatStringsSep - pipe - ; - modulesBaseDir = ../../nixos-modules; - mkTest = - name: - let - getFilePath = file: path.append modulesBaseDir "./${name}/${file}"; - in - testers.runNixOSTest { - inherit name; - - imports = [ - (import (getFilePath "test.nix") { - inherit name; - inherit lib; - }) - ]; - - defaults = { - imports = [ defaultModule ]; - - qois.outgoing-server-mail.enable = mkForce false; - qois.backup-client.enable = mkForce false; - }; - - # Calls a `test(...)` python function in the test's python file with the list of nodes and helper functions. - # Helper symbols may be added as function args when needed and can be found in: - # https://github.com/NixOS/nixpkgs/blob/master/nixos/lib/test-driver/src/test_driver/driver.py#L121 - testScript = mkDefault ( - { nodes, ... }: - let - script = readFile (getFilePath "test.py"); - nodeArgs = pipe nodes [ - attrNames - (map (val: "${val}=${val}")) - (concatStringsSep ", ") - ]; - in - '' - ${script} - test(${nodeArgs}, subtest=subtest) - '' - ); - }; -in -pipe modulesBaseDir [ - getSubDirs - (filter (isFolderWithFile "test.nix" modulesBaseDir)) - (map mkTest) - (linkFarmFromDrvs "nixos-modules") -] diff --git a/checks/packages/default.nix b/checks/packages/default.nix deleted file mode 100644 index dbd8049..0000000 --- a/checks/packages/default.nix +++ /dev/null @@ -1,5 +0,0 @@ -{ self, pkgs, ... }: -let - inherit (pkgs.lib) attrValues; -in -pkgs.linkFarmFromDrvs "all" (attrValues self.packages) diff --git a/nixos-modules/system/applications.nix b/defaults/base-minimal/applications.nix similarity index 97% rename from nixos-modules/system/applications.nix rename to defaults/base-minimal/applications.nix index b3bf422..ed63b6a 100644 --- a/nixos-modules/system/applications.nix +++ b/defaults/base-minimal/applications.nix @@ -1,4 +1,6 @@ { + config, + lib, pkgs, ... }: diff --git a/nixos-modules/system/default.nix b/defaults/base-minimal/default.nix similarity index 73% rename from nixos-modules/system/default.nix rename to defaults/base-minimal/default.nix index 3a12b67..ce133f9 100644 --- a/nixos-modules/system/default.nix +++ b/defaults/base-minimal/default.nix @@ -2,23 +2,15 @@ config, lib, pkgs, + inputs, ... }: -let - inherit (lib) - concatLists - elem - mapAttrsToList - mkForce - ; -in { imports = [ + ./unfree.nix ./applications.nix ./overlays.nix - ./physical.nix ./security.nix - ./virtual-machine.nix ]; boot.loader.timeout = 2; @@ -43,35 +35,29 @@ in }; users.mutableUsers = false; - users.users = { root.openssh.authorizedKeys.keys = - let - wheelUserKeys = concatLists ( - mapAttrsToList ( - name: user: - if elem "wheel" user.extraGroups && name != "root" then user.openssh.authorizedKeys.keys else [ ] - ) config.users.users - ); - in - wheelUserKeys - ++ [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBS65v7n5ozOUjYGuO/dgLC9C5MUGL5kTnQnvWAYP5B3 ci@git.qo.is" - ]; + with lib; + concatLists ( + mapAttrsToList ( + name: user: + if elem "wheel" user.extraGroups && name != "root" then user.openssh.authorizedKeys.keys else [ ] + ) config.users.users + ); }; # Disable dependency on xorg # TODO: Set environment.noXlibs on hosts that don't need any x libraries. - security.pam.services.su.forwardXAuth = mkForce false; + security.pam.services.su.forwardXAuth = lib.mkForce false; # Package management nix = { settings = let substituters = [ - "https://${config.qois.nixpkgs-cache.hostname}?priority=30" - "https://attic.qo.is/qois-infrastructure?priority=32" + "https://${inputs.self.nixosConfigurations.lindberg-build.config.qois.nixpkgs-cache.hostname}?priority=39" "https://cache.nixos.org?priority=40" + "https://attic.qo.is/qois-infrastructure" ]; in { @@ -83,7 +69,7 @@ in "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "qois-infrastructure:lh35ymN7Aoxm5Hz0S6JusxE+cYzMU+x9OMKjDVIpfuE=" ]; - trusted-substituters = substituters; + trusted-substituters = substituters; # For hosts that limit the subst list inherit substituters; }; gc = { @@ -125,6 +111,12 @@ in defaultEditor = true; }; + sops.defaultSopsFile = + let + defaultSopsPath = "${inputs.private}/nixos-configurations/${config.networking.hostName}/secrets.sops.yaml"; + in + lib.mkIf (builtins.pathExists defaultSopsPath) defaultSopsPath; + services.fstrim.enable = true; qois.outgoing-server-mail.enable = true; diff --git a/nixos-modules/system/etc/gitconfig b/defaults/base-minimal/etc/gitconfig similarity index 100% rename from nixos-modules/system/etc/gitconfig rename to defaults/base-minimal/etc/gitconfig diff --git a/nixos-modules/system/etc/vimrc b/defaults/base-minimal/etc/vimrc similarity index 100% rename from nixos-modules/system/etc/vimrc rename to defaults/base-minimal/etc/vimrc diff --git a/defaults/base-minimal/overlays.nix b/defaults/base-minimal/overlays.nix new file mode 100644 index 0000000..f89be8f --- /dev/null +++ b/defaults/base-minimal/overlays.nix @@ -0,0 +1,12 @@ +{ + config, + lib, + pkgs, + options, + ... +}: + +{ + nixpkgs.overlays = [ (import ../../overlays) ]; + nix.nixPath = options.nix.nixPath.default; +} diff --git a/nixos-modules/system/security.nix b/defaults/base-minimal/security.nix similarity index 98% rename from nixos-modules/system/security.nix rename to defaults/base-minimal/security.nix index a7ceb31..a8a8801 100644 --- a/nixos-modules/system/security.nix +++ b/defaults/base-minimal/security.nix @@ -1,5 +1,7 @@ { + config, lib, + pkgs, ... }: with lib; diff --git a/defaults/base-minimal/unfree.nix b/defaults/base-minimal/unfree.nix new file mode 100644 index 0000000..4e751ae --- /dev/null +++ b/defaults/base-minimal/unfree.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + nixpkgs.config.allowUnfreePredicate = + pkg: + builtins.elem (lib.getName pkg) [ + "corefonts" + "camingo-code" + "helvetica-neue-lt-std" + #"kochi-substitute-naga10" + "ttf-envy-code-r" + "vista-fonts" + "vista-fonts-chs" + "xkcd-font-unstable" + "ricty" + ]; +} diff --git a/defaults/base-vm/default.nix b/defaults/base-vm/default.nix new file mode 100644 index 0000000..c48196f --- /dev/null +++ b/defaults/base-vm/default.nix @@ -0,0 +1,39 @@ +{ + config, + lib, + modulesPath, + pkgs, + ... +}: + +{ + + imports = [ + ../base-minimal + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.loader.grub.enable = true; + + system.autoUpgrade.allowReboot = true; + + services.qemuGuest.enable = true; + + boot.initrd.availableKernelModules = [ + "ahci" + "xhci_pci" + "sr_mod" + ]; + + # Taken from https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/minimal.nix + documentation.enable = lib.mkDefault false; + + documentation.doc.enable = lib.mkDefault false; + + documentation.info.enable = lib.mkDefault false; + + documentation.man.enable = lib.mkDefault false; + + documentation.nixos.enable = lib.mkDefault false; + +} diff --git a/defaults/base/applications.nix b/defaults/base/applications.nix new file mode 100644 index 0000000..2829400 --- /dev/null +++ b/defaults/base/applications.nix @@ -0,0 +1,32 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + environment.systemPackages = + with pkgs; + [ + pciutils + dmidecode + smartmontools + iw + efibootmgr + efitools + efivar + pwgen + powertop + lm_sensors + ] + ++ [ + # Filesystem & Disk Utilities + hdparm + smartmontools + ] + ++ [ + # Networking Utilities + tcpdump + ]; +} diff --git a/defaults/base/default.nix b/defaults/base/default.nix new file mode 100644 index 0000000..99a64fc --- /dev/null +++ b/defaults/base/default.nix @@ -0,0 +1,25 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + imports = [ + ../base-minimal + ./applications.nix + ]; + + # System Services + services.fwupd.enable = true; + + services.smartd = { + enable = true; + notifications.mail = { + enable = true; + mailer = "${pkgs.msmtp}/bin/sendmail"; + sender = "system@qo.is"; + recipient = "sysadmin@qo.is"; + }; + }; +} diff --git a/defaults/hardware/README.md b/defaults/hardware/README.md index fbf1f50..03a63cb 100644 --- a/defaults/hardware/README.md +++ b/defaults/hardware/README.md @@ -1,3 +1,4 @@ + # APU ## Setup @@ -6,5 +7,9 @@ To boot the nixos installer with the console port, add `console=ttyS0,115200n8` # ASROCK Mainboards -`F2`: Boot into BIOS\ +`F2`: Boot into BIOS `F11`: Select boot device + +# NUC + +- [Boot Keybindings](https://www.intel.com/content/www/us/en/support/articles/000005672/boards-and-kits/desktop-boards.html) diff --git a/defaults/hardware/apu.nix b/defaults/hardware/apu.nix index 5cdb6dc..e4256dc 100644 --- a/defaults/hardware/apu.nix +++ b/defaults/hardware/apu.nix @@ -2,7 +2,9 @@ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. { + config, lib, + pkgs, modulesPath, ... }: diff --git a/defaults/hardware/apu1.nix b/defaults/hardware/apu1.nix index b5084d0..9c6e00a 100644 --- a/defaults/hardware/apu1.nix +++ b/defaults/hardware/apu1.nix @@ -2,7 +2,9 @@ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. { + config, lib, + pkgs, modulesPath, ... }: diff --git a/defaults/hardware/asrock-z790m.nix b/defaults/hardware/asrock-z790m.nix index db198d1..c90c220 100644 --- a/defaults/hardware/asrock-z790m.nix +++ b/defaults/hardware/asrock-z790m.nix @@ -2,7 +2,9 @@ # and may be overwritten by future invocations. Please make changes # to /etc/nixos/configuration.nix instead. { + config, lib, + pkgs, modulesPath, ... }: diff --git a/defaults/hardware/asrock.nix b/defaults/hardware/asrock.nix index 0b4baef..44b3f10 100644 --- a/defaults/hardware/asrock.nix +++ b/defaults/hardware/asrock.nix @@ -1,5 +1,7 @@ { + config, lib, + pkgs, modulesPath, ... }: diff --git a/defaults/hardware/nuc.nix b/defaults/hardware/nuc.nix new file mode 100644 index 0000000..c90c220 --- /dev/null +++ b/defaults/hardware/nuc.nix @@ -0,0 +1,33 @@ +# 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" + "ahci" + "usbhid" + "usb_storage" + "sd_mod" + "e1000e" + "virtio-pci" + ]; + boot.initrd.kernelModules = [ ]; + # boot.kernelModules = [ "kvm-intel" "virtio" "tun" ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + # boot.kernelParams = [ "console=ttyS0,115200n8" ]; + + hardware.cpu.intel.updateMicrocode = true; + powerManagement.cpuFreqGovernor = "ondemand"; + nix.settings.max-jobs = lib.mkDefault 8; +} diff --git a/defaults/hardware/wle-regulatory-domain/ath10k-override-eeprom-regulatory-domain.patch b/defaults/hardware/wle-regulatory-domain/ath10k-override-eeprom-regulatory-domain.patch new file mode 100644 index 0000000..1b1f775 --- /dev/null +++ b/defaults/hardware/wle-regulatory-domain/ath10k-override-eeprom-regulatory-domain.patch @@ -0,0 +1,40 @@ +diff --unified --recursive --text archlinux-linux/drivers/net/wireless/ath/regd.c archlinux-linux-patched/drivers/net/wireless/ath/regd.c +--- a/drivers/net/wireless/ath/regd.c 2019-08-29 18:31:52.749909030 +0200 ++++ b/drivers/net/wireless/ath/regd.c 2019-08-29 18:33:33.318773763 +0200 +@@ -345,6 +345,8 @@ + struct ieee80211_channel *ch; + unsigned int i; + ++ return; ++ + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; +@@ -378,6 +380,8 @@ + { + struct ieee80211_supported_band *sband; + ++ return; ++ + sband = wiphy->bands[NL80211_BAND_2GHZ]; + if (!sband) + return; +@@ -407,6 +411,8 @@ + struct ieee80211_channel *ch; + unsigned int i; + ++ return; ++ + if (!wiphy->bands[NL80211_BAND_5GHZ]) + return; + +@@ -639,6 +645,9 @@ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; ++ ++ return 0; ++ + wiphy->regulatory_flags |= REGULATORY_STRICT_REG | + REGULATORY_CUSTOM_REG; + diff --git a/defaults/hardware/wle-regulatory-domain/default.nix b/defaults/hardware/wle-regulatory-domain/default.nix new file mode 100644 index 0000000..fbf2cc7 --- /dev/null +++ b/defaults/hardware/wle-regulatory-domain/default.nix @@ -0,0 +1,23 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + boot.kernelPatches = [ + { + name = "ath10k-override-eeprom-regulatory-domain"; + patch = ./ath10k-override-eeprom-regulatory-domain.patch; + extraConfig = '' + EXPERT y + CFG80211_CERTIFICATION_ONUS y + ATH_REG_DYNAMIC_USER_REG_HINTS y + ATH_REG_DYNAMIC_USER_CERT_TESTING y + ATH_REG_DYNAMIC_USER_CERT_TESTING y + ATH9K_DFS_CERTIFIED y + ATH10K_DFS_CERTIFIED y + ''; + } + ]; +} diff --git a/defaults/hardware/wle200nx.nix b/defaults/hardware/wle200nx.nix new file mode 100644 index 0000000..a8cf0f6 --- /dev/null +++ b/defaults/hardware/wle200nx.nix @@ -0,0 +1,11 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + services.hostapd.extraConfig = '' + ht_capab=[HT40-][HT40+][SHORT-GI-40][TX-STBC][RX-STBC1][DSSS_CCK-40] + ''; +} diff --git a/defaults/meta/default.nix b/defaults/meta/default.nix index bf4f5bd..19bb5b6 100644 --- a/defaults/meta/default.nix +++ b/defaults/meta/default.nix @@ -1,4 +1,7 @@ { + config, + lib, + pkgs, ... }: { diff --git a/defaults/meta/hosts.json b/defaults/meta/hosts.json index 37532af..8ae54a3 100644 --- a/defaults/meta/hosts.json +++ b/defaults/meta/hosts.json @@ -17,11 +17,15 @@ }, "lindberg-webapps": { "hostName": "lindberg-webapps", - "sshKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIByESy+XiBT8/PoE8DUB388B5MA6LVcJBgH1ZgYxr9Mg" + "sshKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJT99lj5OI+V1PlZl/T2ikBORwMiXjDfWpHYfq/GvUM5" }, "batzberg": { "hostName": "batzberg" }, + "stompert": { + "hostName": "stompert", + "sshKey": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEKuqMPLbREFIrYcmReaRoHdz1TatpvlrZN14L6cikia" + }, "router-coredump": { "hostName": "router" }, diff --git a/defaults/meta/network-physical.nix b/defaults/meta/network-physical.nix index e83d37f..f3e7806 100644 --- a/defaults/meta/network-physical.nix +++ b/defaults/meta/network-physical.nix @@ -1,4 +1,7 @@ { + config, + lib, + pkgs, ... }: { @@ -52,6 +55,13 @@ }; }; + eem-lan = { + domain = "eem-lan.net.qo.is"; + hosts = { + stompert.v4.ip = ""; # TODO + }; + }; + riedbach-ext = { # IP: Dynamic domain = "riedbach-ext.net.qo.is"; diff --git a/defaults/meta/network-virtual.nix b/defaults/meta/network-virtual.nix index efbe225..f8ed2e3 100644 --- a/defaults/meta/network-virtual.nix +++ b/defaults/meta/network-virtual.nix @@ -1,5 +1,7 @@ { config, + lib, + pkgs, ... }: { @@ -39,6 +41,11 @@ publicKey = "6XGL4QKB8AMpm/VGcTgWqk9RiSws7DmY5TpIDkXbwlg="; persistentKeepalive = 25; }; + stompert = { + v4.ip = "10.250.0.5"; + publicKey = "CHTjQbmN9WhbRCxKgowxpMx4c5Zu0NDk0rRXEvuB3XA="; + persistentKeepalive = 25; + }; calanda = { v4.ip = "10.250.0.6"; publicKey = "WMuMCzo8e/aNeGP7256mhK0Fe+x06Ws7a9hOZDPCr0M="; diff --git a/defaults/meta/network.md b/defaults/meta/network.md index 07eaae8..72e13ba 100644 --- a/defaults/meta/network.md +++ b/defaults/meta/network.md @@ -37,6 +37,14 @@ package "riedbach.net.qo.is" { riedbachrouter -- "enp5s0" lindberg } +package "eem.net.qo.is" { + node eemrouter + + node stompert + + eemrouter -- "enp2s0" stompert +} + cloud internet[ @ ] @@ -51,6 +59,7 @@ package "coredump.net.qo.is" { internet .. mediaconvchur: INIT7 Fiber (1G/1G) internet .. riedbachrouter: iway Fiber (1G/1G) +internet .. eemrouter: KPN NL Fiber internet .. coredumprouter: Openfactory DSL @enduml ``` @@ -65,6 +74,7 @@ All Services are published under the *qo.is* domain name. Following services are ## Contacts + ### Init7 - [Status Netzwerkdienste](https://www.init7.net/status/) diff --git a/nixos-modules/cloud/README.md b/defaults/nextcloud/README.md similarity index 78% rename from nixos-modules/cloud/README.md rename to defaults/nextcloud/README.md index c9b0898..0e135ad 100644 --- a/nixos-modules/cloud/README.md +++ b/defaults/nextcloud/README.md @@ -11,7 +11,7 @@ For user documentation, refer to the [upstream Nextcloud docs](https://docs.next ## Backup / Restore 1. Stop all related services: nextcloud, php-fpm, redis etc. -1. (mabe dump redis data?) -1. Import Database Backup -1. Restore `/var/lib/nextcloud`, which is currently a bind mount on `lindberg`'s `/mnt/data` volume -1. Resync nextcloud files and database, see [nextcloud docs](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html) +2. (mabe dump redis data?) +3. Import Database Backup +4. Restore `/var/lib/nextcloud`, which is currently a bind mount on `lindberg`'s `/mnt/data` volume +5. Resync nextcloud files and database, see [nextcloud docs](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html) diff --git a/defaults/nextcloud/default.nix b/defaults/nextcloud/default.nix new file mode 100644 index 0000000..3d43d43 --- /dev/null +++ b/defaults/nextcloud/default.nix @@ -0,0 +1,99 @@ +# Default configuration for hosts +{ + config, + lib, + pkgs, + ... +}: + +{ + + sops.secrets."nextcloud/admin" = with config.users.users.nextcloud; { + inherit group; + owner = name; + }; + + services.postgresql.enable = true; + qois.backup-client.includePaths = [ config.services.nextcloud.home ]; + + services.nextcloud = { + enable = true; + https = true; + webfinger = true; + maxUploadSize = "10G"; + + database.createLocally = true; + + config = { + adminpassFile = config.sops.secrets."nextcloud/admin".path; + adminuser = "root"; + dbtype = "pgsql"; + }; + + appstoreEnable = false; + extraApps = { + inherit (config.services.nextcloud.package.passthru.packages.apps) + calendar + contacts + deck + groupfolders + maps + memories + music + news + notes + notify_push + tasks + twofactor_webauthn + ; + }; + + phpOptions = { + "opcache.interned_strings_buffer" = "23"; + }; + + poolSettings = { + "pm" = "dynamic"; + "pm.max_children" = "256"; + "pm.max_requests" = "500"; + "pm.max_spare_servers" = "16"; + "pm.min_spare_servers" = "2"; + "pm.start_servers" = "8"; + }; + + configureRedis = true; + caching.redis = true; + + notify_push = { + enable = true; + bendDomainToLocalhost = true; + }; + + settings = { + log_type = "syslog"; + syslog_tag = "nextcloud"; + "memories.exiftool" = "${lib.getExe pkgs.exiftool}"; + "memories.vod.ffmpeg" = "${lib.getExe pkgs.ffmpeg-headless}"; + "memories.vod.ffprobe" = "${pkgs.ffmpeg-headless}/bin/ffprobe"; + preview_ffmpeg_path = "${lib.getExe pkgs.ffmpeg-headless}"; + mail_smtpmode = "sendmail"; + mail_domain = "qo.is"; + }; + }; + + services.phpfpm.pools.nextcloud.settings = { + "pm.max_children" = lib.mkForce "256"; + "pm.max_spare_servers" = lib.mkForce "16"; + "pm.start_servers" = lib.mkForce "8"; + }; + + users.users.nextcloud.extraGroups = [ "postdrop" ]; + + systemd.services.nextcloud-cron = { + path = [ pkgs.perl ]; + }; + + environment.systemPackages = with pkgs; [ + nodejs # required for Recognize + ]; +} diff --git a/defaults/vpn/README.md b/defaults/vpn/README.md new file mode 100644 index 0000000..962d94d --- /dev/null +++ b/defaults/vpn/README.md @@ -0,0 +1,122 @@ +# VPN + +On [vpn.qo.is](https://vpn.qo.is) we run a [Tailscale](https://tailscale.com) compatible VPN service. To use the service, you can use a normal Tailscale client with following additional configuration: + +| Option | Recommended value | Description | +|--------|-------------------|-------------| +| `accept-routes` | enabled (flag) | Accept direct routes to internal services | +| `exit-node` | `100.64.0.5` (lindberg) or `100.64.0.6` (cypriaspitz) | Use host as [exit node](#exit-nodes) | +| `login-server` | `https://vpn.qo.is` | Use our own VPN service and not tailscale's upstream one | + + +⚠️ Currently, if the client is in an IPv6 network, the transport is broken. See [#51](https://gitlab.com/qo.is/infrastructure/-/issues/51) for progress on this. + +## Exit nodes + +- `100.64.0.5`: lindberg (riedbach-net) +- `100.64.0.6`: cyprianspitz (plessur-net) + +Currently, name resolution for these do not work reliably on first starts, hence the IP must be used. This hould be fixed in the future. + +## User and Client Management + +To register a new client, you can generate a pre-auth key and insert it in the client: + +```bash +headscale preauthkeys create --user marlene.mayer +``` + +Or alternatively use the register command shown when configuring the VPN client. + +## ACL + +At this time, there are a few ACL rules to isolate a users host but do not expect them to be expected to be enforced - expect your client to be accessible by the whole network. + +## Exit Nodes + +To add an exit node, create a preauth secret on the `vpn.qo.is` host: + +```bash +headscale preauthkeys create --user srv --reusable +``` + +and configure the host as follows: + +```nix +# TODO: This should not be a snipped but a module + +{config, ...}: { + # Use this node as vpn exit node + services.tailscale = let meta = config.qois.meta; in { + enable = true; + openFirewall = true; + useRoutingFeatures = "server"; + authKeyFile = "/secrets/wireguard/tailscale-key"; # The preauth secret. TODO: Should be in sops. + extraUpFlags = [ + "--login-server=https://vpn.qo.is" + "--advertise-exit-node" + ( + with meta.network.virtual.backplane.v4; "--advertise-routes=${id}/${builtins.toString prefixLength}" + ) + "--advertise-tags=tag:srv" + ]; + }; +} +``` + +and register it in Headscale with: + +```bash +headscale nodes register -u srv -k nodekey:xyzxyzxyzxyzxyzxyzxyzxyz +``` + +With using the `srv` user, exit nodes and routes get automatically accepted as trusted. + +## Clients + +### NixOS + +Sample config: + +```nix +{ config, pkgs, ... }: { + services.tailscale = { + enable = true; + openFirewall = true; + useRoutingFeatures = "client"; + authKeyFile = "/secrets/wireguard/tailscale-key"; # This is the pre-auth secret. Make sure it's only accessible by root. + extraUpFlags = [ + "--operator" + "yourUserNameChangePlease" + "--accept-routes" + "--exit-node=100.64.0.5" + "--login-server=https://vpn.qo.is" + ]; + }; +} +``` + +### Mobile App + +> Android App: Tip 5 times on the tooltip dots to reveal server config option + +See [this Headscale documentation for more](https://headscale.net/android-client/#configuring-the-headscale-url) on how to configure the mobile app. Note that on restarts, sometimes you have to reopen/save the config dialog. If the Tailscale login site is shown, just close the browser with the ❌. + + +## Backup and Restore + +### Server + +1. `systemctl stop headscale` +2. Replace `/var/lib/headscale` +3. `systemctl start headscale` +4. Monitor logs for errors + +Note: `/var/lib/headscale` contains a sqlite database. + +### Clients + +1. `systemctl stop tailscaled` +2. Replace `/var/lib/tailscale` +3. `systemctl start tailscaled` +4. Monitor logs for errors diff --git a/deploy/README.md b/deploy/README.md index d0abdbc..0a5b7ab 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -4,26 +4,15 @@ Note that you have to be connected to the `vpn.qo.is` (or execute the deployment from a host that is in the `backplane.net.qo.is` overlay network) and that you need to have SSH root access to the target machines. -## Deploy system categories - -We currently split out nixosConfigurations into these categories: - -- `system-ci`: Systems should be updated separately because they might break automated deployment processes. -- `system-vm`: Virtual systems. -- `system-physical`: Physical systems. - -You can roll updates with retries by category with: - -```bash -auto-deploy system-vm -auto-deploy system-physical -``` ## Deploy to selected target hosts ```bash -nix develop - -deploy --skip-checks .#cyprianspitz.system-physical -deploy --skip-checks .#lindberg-build.system-vm +nix run .#deploy-qois .#.system .#.system +``` + +## Deploy with extended timeouts (sometimes required for slow APU devices) + +```bash +nix run .#deploy-qois .#calanda.system -- --confirm-timeout 600 --activation-timeout 600 ``` diff --git a/deploy/default.nix b/deploy/default.nix index 990140e..5fb1a86 100644 --- a/deploy/default.nix +++ b/deploy/default.nix @@ -1,4 +1,5 @@ { + deployPkgs, pkgs, self, ... diff --git a/deploy/docs-ops/default.nix b/deploy/docs-ops/default.nix index 8fd2890..01c25d1 100644 --- a/deploy/docs-ops/default.nix +++ b/deploy/docs-ops/default.nix @@ -1,5 +1,6 @@ { deployPkgs, + pkgs, self, system, ... @@ -12,6 +13,5 @@ in sshUser = "nginx-${domain}"; path = deployPkgs.deploy-rs.lib.activate.noop self.packages.${system}.docs; profilePath = "/var/lib/nginx-${domain}/root"; - remoteBuild = true; }; } diff --git a/deploy/system-ci/default.nix b/deploy/system-ci/default.nix deleted file mode 100644 index a9e49a0..0000000 --- a/deploy/system-ci/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - deployPkgs, - pkgs, - self, - ... -}: -let - inherit (pkgs.lib) pipe filterAttrs mapAttrs; -in -{ - nodes = pipe self.nixosConfigurations [ - (filterAttrs (_n: v: v.config.qois.git-ci-runner.enable)) - (mapAttrs ( - host: config: { - hostname = "${host}.backplane.net.qo.is"; - profiles.system-ci = { - sshUser = "root"; - user = "root"; - activationTimeout = 300; - confirmTimeout = 60; - remoteBuild = true; - path = deployPkgs.deploy-rs.lib.activate.nixos config; - }; - } - )) - ]; -} diff --git a/deploy/system-physical/default.nix b/deploy/system-physical/default.nix deleted file mode 100644 index 4e60068..0000000 --- a/deploy/system-physical/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - deployPkgs, - pkgs, - self, - ... -}: -let - inherit (pkgs.lib) pipe filterAttrs mapAttrs; -in -{ - nodes = pipe self.nixosConfigurations [ - (filterAttrs (_n: v: !v.config.services.qemuGuest.enable && !v.config.qois.git-ci-runner.enable)) - (mapAttrs ( - host: config: { - hostname = "${host}.backplane.net.qo.is"; - profiles.system-physical = { - sshUser = "root"; - user = "root"; - activationTimeout = 600; - confirmTimeout = 120; - remoteBuild = true; - path = deployPkgs.deploy-rs.lib.activate.nixos config; - }; - } - )) - ]; -} diff --git a/deploy/system-vm/default.nix b/deploy/system-vm/default.nix deleted file mode 100644 index 65177b4..0000000 --- a/deploy/system-vm/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ - deployPkgs, - pkgs, - self, - ... -}: -let - inherit (pkgs.lib) pipe filterAttrs mapAttrs; -in -{ - nodes = pipe self.nixosConfigurations [ - (filterAttrs (_n: v: v.config.services.qemuGuest.enable && !v.config.qois.git-ci-runner.enable)) - (mapAttrs ( - host: config: { - hostname = "${host}.backplane.net.qo.is"; - profiles.system-vm = { - sshUser = "root"; - user = "root"; - activationTimeout = 300; - confirmTimeout = 60; - remoteBuild = true; - path = deployPkgs.deploy-rs.lib.activate.nixos config; - }; - } - )) - ]; -} diff --git a/deploy/system/default.nix b/deploy/system/default.nix new file mode 100644 index 0000000..cdaf846 --- /dev/null +++ b/deploy/system/default.nix @@ -0,0 +1,20 @@ +{ + deployPkgs, + pkgs, + self, + system, + ... +}: +{ + nodes = pkgs.lib.mapAttrs (host: config: { + hostname = "${host}.backplane.net.qo.is"; + profiles.system = { + sshUser = "root"; + user = "root"; + activationTimeout = 420; + confirmTimeout = 120; + + path = deployPkgs.deploy-rs.lib.activate.nixos config; + }; + }) self.nixosConfigurations; +} diff --git a/dev-shells/default.nix b/dev-shells/default.nix index 059a81c..1b4f803 100644 --- a/dev-shells/default.nix +++ b/dev-shells/default.nix @@ -1,43 +1,36 @@ { pkgs, - git-hooks-nix, - treefmtEval, system, self, ... }: -let - pre-commit-check = git-hooks-nix.lib.${system}.run { - src = ../.; - hooks.treefmt = { - enable = true; - package = treefmtEval.config.build.wrapper; - always_run = true; - }; - }; -in { - ${system}.default = pkgs.mkShellNoCC { + ${system}.default = pkgs.mkShell { name = "qois-infrastructure-shell"; buildInputs = - pre-commit-check.enabledPackages + let + vscodium-with-extensions = pkgs.vscode-with-extensions.override { + vscodeExtensions = with pkgs.vscode-extensions; [ jnoortheen.nix-ide ]; + vscode = pkgs.vscodium; + }; + in + [ vscodium-with-extensions ] ++ (with self.packages.${system}; [ + cache + deploy-qois sops sops-rekey - auto-deploy ]) ++ (with pkgs; [ attic-client deploy-rs - jq - nix-fast-build - nixVersions.latest nixd nixfmt-rfc-style nixos-anywhere - pssh ssh-to-age + pssh yq + jq ]); LANG = "C.UTF-8"; LC_ALL = "C.UTF-8"; @@ -53,7 +46,11 @@ in done export XDG_DATA_DIRS - ${pre-commit-check.shellHook} + # Make sure we support the pure case as well as non nixos cases + # where dynamic bash completions were not sourced. + #if ! type _completion_loader > /dev/null; then + # . ${pkgs.bash-completion}/etc/profile.d/bash_completion.sh + #fi ''; }; } diff --git a/email.md b/email.md index bba9063..902badc 100644 --- a/email.md +++ b/email.md @@ -9,6 +9,7 @@ E-Mail accounts should be created in a `first.lastname@qo.is` fashion. Alias/forwarding Domains may be added on an best effort basis. Bills for these domains should go directly to the respective owner (i.e. should be registered with own accounts). + ## System E-mails For groups, systems, services that require e-mail access, other accounts may be created. diff --git a/flake.lock b/flake.lock index cb28065..6e79830 100644 --- a/flake.lock +++ b/flake.lock @@ -7,11 +7,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1749105467, - "narHash": "sha256-hXh76y/wDl15almBcqvjryB50B0BaiXJKk20f314RoE=", + "lastModified": 1727447169, + "narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", "owner": "serokell", "repo": "deploy-rs", - "rev": "6bc76b872374845ba9d645a2f012b764fecd765f", + "rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", "type": "github" }, "original": { @@ -23,15 +23,15 @@ "disko": { "inputs": { "nixpkgs": [ - "nixpkgs" + "nixpkgs-nixos-stable" ] }, "locked": { - "lastModified": 1752541678, - "narHash": "sha256-dyhGzkld6jPqnT/UfGV2oqe7tYn7hppAqFvF3GZTyXY=", + "lastModified": 1736165297, + "narHash": "sha256-OT+sF4eNDFN/OdyUfIQwyp28+CFQL7PAdWn0wGU7F0U=", "owner": "nix-community", "repo": "disko", - "rev": "2bf3421f7fed5c84d9392b62dcb9d76ef09796a7", + "rev": "76816af65d5294761636a838917e335992a52e0c", "type": "github" }, "original": { @@ -41,22 +41,6 @@ } }, "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1733328505, - "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_2": { "flake": false, "locked": { "lastModified": 1696426674, @@ -72,56 +56,13 @@ "type": "github" } }, - "git-hooks-nix": { - "inputs": { - "flake-compat": "flake-compat_2", - "gitignore": "gitignore", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1750779888, - "narHash": "sha256-wibppH3g/E2lxU43ZQHC5yA/7kIKLGxVEnsnVK1BtRg=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "16ec914f6fb6f599ce988427d9d94efddf25fe6d", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "git-hooks-nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1743014863, - "narHash": "sha256-jAIUqsiN2r3hCuHji80U7NNEafpIMBXiwKlSrjWMlpg=", + "lastModified": 1702272962, + "narHash": "sha256-D+zHwkwPc6oYQ4G3A1HuadopqRwUY/JkMwHz1YF7j4Q=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd3bac8bfb542dbde7ffffb6987a1a1f9d41699f", + "rev": "e97b3e4186bcadf0ef1b6be22b8558eab1cdeb5d", "type": "github" }, "original": { @@ -131,33 +72,49 @@ "type": "github" } }, - "nixpkgs_2": { + "nixpkgs-nixos-stable": { "locked": { - "lastModified": 1752436162, - "narHash": "sha256-Kt1UIPi7kZqkSc5HVj6UY5YLHHEzPBkgpNUByuyxtlw=", + "lastModified": 1736061677, + "narHash": "sha256-DjkQPnkAfd7eB522PwnkGhOMuT9QVCZspDpJJYyOj60=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "dfcd5b901dbab46c9c6e80b265648481aafb01f8", + "rev": "cbd8ec4de4469333c82ff40d057350c30e9f7d36", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-25.05", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-nixos-unstable": { + "locked": { + "lastModified": 1736012469, + "narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "8f3e1f807051e32d8c95cd12b9b421623850a34d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } }, "private": { "inputs": { - "nixpkgs": [ - "nixpkgs" + "nixpkgs-nixos-unstable": [ + "nixpkgs-nixos-unstable" ] }, "locked": { - "lastModified": 1749920008, - "narHash": "sha256-wn3U2q/+OQYErVyoY9kwZP/fXcDG4ewhJkHX7qHzq8g=", - "rev": "5f8ba2025848dd30539c42ef1f7e6c6f917e70d9", - "revCount": 19, + "lastModified": 1734984619, + "narHash": "sha256-D9awD3ArJ+8jCPr96HruGS4xpkJ7h2+V0Yiaay/9pyE=", + "rev": "18d3b3b703a6139b9ebd5ec64311717cf2a6f9bc", + "revCount": 7, "type": "git", "url": "file:./private" }, @@ -170,25 +127,24 @@ "inputs": { "deploy-rs": "deploy-rs", "disko": "disko", - "git-hooks-nix": "git-hooks-nix", - "nixpkgs": "nixpkgs_2", + "nixpkgs-nixos-stable": "nixpkgs-nixos-stable", + "nixpkgs-nixos-unstable": "nixpkgs-nixos-unstable", "private": "private", - "sops-nix": "sops-nix", - "treefmt-nix": "treefmt-nix" + "sops-nix": "sops-nix" } }, "sops-nix": { "inputs": { "nixpkgs": [ - "nixpkgs" + "nixpkgs-nixos-unstable" ] }, "locked": { - "lastModified": 1752544651, - "narHash": "sha256-GllP7cmQu7zLZTs9z0J2gIL42IZHa9CBEXwBY9szT0U=", + "lastModified": 1736064798, + "narHash": "sha256-xJRN0FmX9QJ6+w8eIIIxzBU1AyQcLKJ1M/Gp6lnSD20=", "owner": "Mic92", "repo": "sops-nix", - "rev": "2c8def626f54708a9c38a5861866660395bb3461", + "rev": "5dc08f9cc77f03b43aacffdfbc8316807773c930", "type": "github" }, "original": { @@ -212,36 +168,16 @@ "type": "github" } }, - "treefmt-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1752055615, - "narHash": "sha256-19m7P4O/Aw/6+CzncWMAJu89JaKeMh3aMle1CNQSIwM=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "c9d477b5d5bd7f26adddd3f96cfd6a904768d4f9", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, "utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", "owner": "numtide", "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index b645da8..d9dae25 100644 --- a/flake.nix +++ b/flake.nix @@ -5,47 +5,34 @@ extra-trusted-public-keys = "qois-infrastructure:lh35ymN7Aoxm5Hz0S6JusxE+cYzMU+x9OMKjDVIpfuE="; }; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; - - treefmt-nix = { - url = "github:numtide/treefmt-nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - git-hooks-nix = { - url = "github:cachix/git-hooks.nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - sops-nix = { - url = "github:Mic92/sops-nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - deploy-rs.url = "github:serokell/deploy-rs"; disko = { url = "github:nix-community/disko"; - inputs.nixpkgs.follows = "nixpkgs"; + inputs.nixpkgs.follows = "nixpkgs-nixos-stable"; + }; + nixpkgs-nixos-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; + nixpkgs-nixos-stable.url = "github:NixOS/nixpkgs/nixos-24.11"; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs = { + nixpkgs.follows = "nixpkgs-nixos-unstable"; + }; }; private.url = "git+file:./private"; - private.inputs.nixpkgs.follows = "nixpkgs"; + private.inputs.nixpkgs-nixos-unstable.follows = "nixpkgs-nixos-unstable"; }; outputs = - { - self, - nixpkgs, - deploy-rs, - treefmt-nix, - ... - }@inputs: + { nixpkgs-nixos-unstable, deploy-rs, ... }@inputs: let system = "x86_64-linux"; # Packages for development and build process - pkgs = import nixpkgs { inherit system; }; - deployPkgs = import nixpkgs { + pkgs = import nixpkgs-nixos-unstable { inherit system; }; + deployPkgs = import nixpkgs-nixos-unstable { inherit system; overlays = [ - deploy-rs.overlays.default - (_self: super: { + deploy-rs.overlay + (self: super: { deploy-rs = { inherit (pkgs) deploy-rs; lib = super.deploy-rs.lib; @@ -53,86 +40,22 @@ }) ]; }; - treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix; - importParams = { - inherit (inputs) - deploy-rs - disko - nixpkgs - sops-nix - private - git-hooks-nix - ; - inherit - deployPkgs - pkgs - system - treefmtEval - ; - flakeSelf = self; + importParams = inputs // { + inherit pkgs; + inherit deployPkgs; + inherit system; }; in { - checks = import ./checks/default.nix ( - importParams - // { - self = { - inherit (self) - lib - packages - nixosModules - nixosConfigurations - deploy - ; - }; - } - ); - deploy = import ./deploy/default.nix ( - importParams - // { - self = { - inherit (self) - lib - packages - nixosModules - nixosConfigurations - ; - }; - } - ); - devShells = import ./dev-shells/default.nix ( - importParams - // { - self = { - inherit (self) lib packages; - }; - } - ); - formatter.${system} = treefmtEval.config.build.wrapper; - nixosConfigurations = import ./nixos-configurations/default.nix ( - importParams - // { - self = { - inherit (self) lib packages nixosModules; - }; - } - ); - nixosModules = import ./nixos-modules/default.nix ( - importParams - // { - self = { - inherit (self) lib packages; - }; - } - ); - packages = import ./packages/default.nix ( - importParams - // { - self = { - inherit (self) lib packages; - }; - } - ); - lib = import ./lib/default.nix { inherit pkgs; }; + checks = import ./checks/default.nix importParams; + deploy = import ./deploy/default.nix importParams; + devShells = import ./dev-shells/default.nix importParams; + formatter.${system} = pkgs.writeShellScriptBin "formatter" '' + ${pkgs.findutils}/bin/find $1 -type f -name '*.nix' -exec ${pkgs.nixfmt-rfc-style}/bin/nixfmt ''${@:2} {} + + ''; + nixosConfigurations = import ./nixos-configurations/default.nix importParams; + nixosModules = import ./nixos-modules/default.nix importParams; + packages = import ./packages/default.nix importParams; + lib = import ./lib/default.nix importParams; }; } diff --git a/lib/default.nix b/lib/default.nix index 3d70a2c..404d93e 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,26 +1,18 @@ { pkgs, ... }: let - inherit (pkgs.lib) - attrNames - filterAttrs - filter - pathExists - path - ; - # Get a list of all subdirectories of a directory. - getSubDirs = base: attrNames (filterAttrs (_n: t: t == "directory") (builtins.readDir base)); - # Check if a folder with a base path and folder name contains a file with a specific name - isFolderWithFile = - fileName: basePath: folderName: - (pathExists (path.append basePath "./${folderName}/${fileName}")); - # Get a list of subfolders that contain a default.nix file. - foldersWithNix = base: filter (isFolderWithFile "default.nix" base) (getSubDirs base); + lib = pkgs.lib; + foldersWithNix = + path: + let + folders = lib.attrNames (lib.filterAttrs (n: t: t == "directory") (builtins.readDir path)); + isFolderWithDefaultNix = folder: lib.pathExists (lib.path.append path "./${folder}/default.nix"); + in + lib.filter isFolderWithDefaultNix folders; in { - inherit getSubDirs isFolderWithFile foldersWithNix; + inherit foldersWithNix; - # Get a list of default.nix files that are nix submodules of the current folder. loadSubmodulesFrom = - basePath: map (folder: path.append basePath "./${folder}/default.nix") (foldersWithNix basePath); + path: map (folder: lib.path.append path "./${folder}/default.nix") (foldersWithNix path); } diff --git a/nixos-configurations/calanda/default.nix b/nixos-configurations/calanda/default.nix index b0109d1..dcc9bff 100644 --- a/nixos-configurations/calanda/default.nix +++ b/nixos-configurations/calanda/default.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { imports = [ @@ -6,9 +6,10 @@ ./filesystems.nix ../../defaults/hardware/apu.nix - ]; - qois.system.physical.enable = true; + ../../defaults/base + ../../defaults/meta + ]; # This value determines the NixOS release from which the default # settings for stateful data, like fi:le locations and database versions @@ -16,5 +17,5 @@ # 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 = "25.05"; # Did you read the comment? + system.stateVersion = "24.11"; # Did you read the comment? } diff --git a/nixos-configurations/calanda/filesystems.nix b/nixos-configurations/calanda/filesystems.nix index f240ed6..ecb21b4 100644 --- a/nixos-configurations/calanda/filesystems.nix +++ b/nixos-configurations/calanda/filesystems.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { fileSystems."/" = { diff --git a/nixos-configurations/calanda/networking.nix b/nixos-configurations/calanda/networking.nix index 9ad8dbe..a96757d 100644 --- a/nixos-configurations/calanda/networking.nix +++ b/nixos-configurations/calanda/networking.nix @@ -1,4 +1,4 @@ -{ config, ... }: +{ config, pkgs, ... }: let meta = config.qois.meta; @@ -32,7 +32,7 @@ in qois.backplane-net.enable = true; # TODO: Metaize ips - qois.router = { + services.qois.router = { enable = true; wanInterface = "enp4s0"; wirelessInterfaces = [ "wlp5s0" ]; diff --git a/nixos-configurations/cyprianspitz/README.md b/nixos-configurations/cyprianspitz/README.md index b01d9bc..84a79c6 100644 --- a/nixos-configurations/cyprianspitz/README.md +++ b/nixos-configurations/cyprianspitz/README.md @@ -1,16 +1,17 @@ -# Host: Cyprianspitz +# Host: Cyprianspitz (+Router: Caral) -## Operations {#\_operations} +## Operations {#_operations} Reboot requires passphrase. -```bash +``` bash # Get HDD Password: sops decrypt --extract '["system"]["hdd"]' private/nixos-configurations/cyprianspitz/secrets.sops.yaml ssh -p 8223 root@calanda.plessur-ext.net.qo.is ``` + Direct remote ssh access: ``` @@ -23,6 +24,40 @@ TODO - [Mainboard Manual](docs/z790m-itx-wifi.pdf) + +### Networking: Caral Internet Router + +A [MikroTik `CCR2004-1G-2XS-PCIe`](https://mikrotik.com/product/ccr2004_1g_2xs_pcie#fndtn-downloads) is used for internet access. +It's a fiber card with build in router, supporting 2x 25Gbit SFP28 cages and 1Gbit RJ45 eth. + +- [RouterOS Docs](https://help.mikrotik.com/docs/spaces/ROS/pages/328059/RouterOS) + +[The manual](docs/CCR2004-1G-2XS-PCIe_241138.pdf) states: + +> This form-factor does come with certain limitations that you should keep in mind. +> The CCR NIC card needs some time to boot up compared to ASIC-based setups. +> If the host system is up before the CCR card, it will not appear among the available devices. +> You should add a PCIe device initialization delay after power-up in the BIOS. +> Or you will need to re-initialize the PCIe devices from the HOST system. + +In our case, since networking is reinitialized after the LUKS password promt, this should not be a issue in practice. However, if networking would not be available, contact someone for a physical reboot and wait longer before entering the HDD password. + +To reload the card's virtual interfaces on a running system: + +```bash +echo "1" > /sys/bus/pci/devices/0000\:01\:00.0/remove +sleep 2 +echo "1" > /sys/bus/pci/rescan +``` + +To restart the card on a running system: + +```bash +echo "1" > /sys/bus/pci/devices/0000\:01\:00.0/reset +sleep 2m # Wait for reboot +echo "1" > /sys/bus/pci/rescan +``` + ### Top Overview ![](docs/top-view.jpg) diff --git a/nixos-configurations/cyprianspitz/applications/backup.nix b/nixos-configurations/cyprianspitz/applications/backup.nix index c364132..241fba8 100644 --- a/nixos-configurations/cyprianspitz/applications/backup.nix +++ b/nixos-configurations/cyprianspitz/applications/backup.nix @@ -1,4 +1,4 @@ -{ config, ... }: +{ pkgs, config, ... }: { qois.backup-server = { diff --git a/nixos-configurations/cyprianspitz/applications/default.nix b/nixos-configurations/cyprianspitz/applications/default.nix index 0a2aceb..18cd6ea 100644 --- a/nixos-configurations/cyprianspitz/applications/default.nix +++ b/nixos-configurations/cyprianspitz/applications/default.nix @@ -1,4 +1,6 @@ { + config, + pkgs, lib, ... }: diff --git a/nixos-configurations/cyprianspitz/applications/vpn.nix b/nixos-configurations/cyprianspitz/applications/vpn.nix index ea7c158..2fafbd0 100644 --- a/nixos-configurations/cyprianspitz/applications/vpn.nix +++ b/nixos-configurations/cyprianspitz/applications/vpn.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { qois.vpn-server.enable = true; } diff --git a/nixos-configurations/cyprianspitz/default.nix b/nixos-configurations/cyprianspitz/default.nix index a6094df..66ff7e7 100644 --- a/nixos-configurations/cyprianspitz/default.nix +++ b/nixos-configurations/cyprianspitz/default.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { imports = [ @@ -10,9 +10,10 @@ ./virtualisation.nix ../../defaults/hardware/asrock-z790m.nix - ]; - qois.system.physical.enable = true; + ../../defaults/base + ../../defaults/meta + ]; # Set your time zone. time.timeZone = "Europe/Amsterdam"; @@ -23,5 +24,5 @@ # 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 = "25.05"; # Did you read the comment? + system.stateVersion = "24.11"; # Did you read the comment? } diff --git a/nixos-configurations/cyprianspitz/docs/CCR2004-1G-2XS-PCIe_241138.pdf b/nixos-configurations/cyprianspitz/docs/CCR2004-1G-2XS-PCIe_241138.pdf new file mode 100644 index 0000000..6e39fbc Binary files /dev/null and b/nixos-configurations/cyprianspitz/docs/CCR2004-1G-2XS-PCIe_241138.pdf differ diff --git a/nixos-configurations/cyprianspitz/networking.nix b/nixos-configurations/cyprianspitz/networking.nix index 3423220..204b392 100644 --- a/nixos-configurations/cyprianspitz/networking.nix +++ b/nixos-configurations/cyprianspitz/networking.nix @@ -1,4 +1,4 @@ -{ config, ... }: +{ config, pkgs, ... }: let meta = config.qois.meta; @@ -14,9 +14,25 @@ in networking.nameservers = [ calandaIp ]; networking.useDHCP = false; - networking.interfaces.enp0s31f6.ipv4.addresses = [ - (getNetV4Ip meta.network.physical.plessur-lan) - ]; + networking.interfaces = { + # enp0s31f6: 1 Gbit mainboard interface + enp0s31f6.ipv4.addresses = [ + (getNetV4Ip meta.network.physical.plessur-lan) + ]; + + # wlp0s20f3: Mainboard Wireless interface + # enp3s0: 2.5 Gbit mainboard interface: Connected to ether1 + #enp3s0.useDHCP = true; + + # enp1s0f0: mikrotik sfp28-1: ether-pcie1 passthrough + enp1s0f0.useDHCP = true; + # enp1s0f1: mikrotik sfp28-2: ether-pcie2 passthrough + enp1s0f1.useDHCP = true; + # enp1s0f2: mikrotik ether1/bridge1: ether-pcie3 bridge \ + enp1s0f2.useDHCP = true; + # enp1s0f3: mikrotik ether1/bridge1: ether-pcie4 bridge > connected to enp3s0 + enp1s0f3.useDHCP = true; + }; networking.defaultGateway = { address = calandaIp; @@ -73,7 +89,7 @@ in }; # Boot - qois.luks-ssh = { + services.qois.luks-ssh = { enable = true; interface = "eth0"; diff --git a/nixos-configurations/cyprianspitz/virtualisation.nix b/nixos-configurations/cyprianspitz/virtualisation.nix index 6e7a883..5905bdf 100644 --- a/nixos-configurations/cyprianspitz/virtualisation.nix +++ b/nixos-configurations/cyprianspitz/virtualisation.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { virtualisation.libvirtd = { enable = true; diff --git a/nixos-configurations/default.nix b/nixos-configurations/default.nix index 96f9aa1..00253e0 100644 --- a/nixos-configurations/default.nix +++ b/nixos-configurations/default.nix @@ -1,17 +1,17 @@ { self, pkgs, - nixpkgs, + nixpkgs-nixos-stable, + disko, + sops-nix, ... }@inputs: let - inherit (pkgs.lib) genAttrs; - inherit (nixpkgs.lib) nixosSystem; configs = self.lib.foldersWithNix ./.; in -genAttrs configs ( +pkgs.lib.genAttrs configs ( config: - nixosSystem { + nixpkgs-nixos-stable.lib.nixosSystem { system = "x86_64-linux"; specialArgs = { inherit inputs; @@ -19,6 +19,15 @@ genAttrs configs ( modules = [ self.nixosModules.default ./${config}/default.nix + disko.nixosModules.disko + sops-nix.nixosModules.sops + ( + { ... }: + { + system.extraSystemBuilderCmds = "ln -s ${self} $out/nixos-configuration"; + imports = [ ./secrets.nix ]; + } + ) ]; } ) diff --git a/nixos-configurations/lindberg-build/applications/default.nix b/nixos-configurations/lindberg-build/applications/default.nix index b965c04..d9360ee 100644 --- a/nixos-configurations/lindberg-build/applications/default.nix +++ b/nixos-configurations/lindberg-build/applications/default.nix @@ -1,4 +1,5 @@ { + config, pkgs, lib, ... @@ -12,7 +13,6 @@ qois.git-ci-runner.enable = true; qois.attic.enable = true; qois.postgresql.package = pkgs.postgresql_15; - qois.renovate.enable = true; # Remove substituters that are hosted on this node, to prevent lockups # since the current nix implementation is not forgiving with unavailable subsituters. diff --git a/nixos-configurations/lindberg-build/applications/nixpkgs-cache.nix b/nixos-configurations/lindberg-build/applications/nixpkgs-cache.nix index 66807ed..f097544 100644 --- a/nixos-configurations/lindberg-build/applications/nixpkgs-cache.nix +++ b/nixos-configurations/lindberg-build/applications/nixpkgs-cache.nix @@ -1,7 +1,8 @@ -{ config, ... }: +{ config, pkgs, ... }: { qois.nixpkgs-cache = { enable = true; + hostname = "nixpkgs-cache.qo.is"; dnsResolvers = [ config.qois.meta.network.virtual.lindberg-vms-nat.hosts.lindberg.v4.ip ]; }; } diff --git a/nixos-configurations/lindberg-build/default.nix b/nixos-configurations/lindberg-build/default.nix index cd093a4..1cbfd2f 100644 --- a/nixos-configurations/lindberg-build/default.nix +++ b/nixos-configurations/lindberg-build/default.nix @@ -1,14 +1,15 @@ -{ ... }: +{ config, pkgs, ... }: { imports = [ + ../../defaults/base-vm + ../../defaults/meta ./applications ./disko-config.nix ./networking.nix ./secrets.nix ]; - qois.system.virtual-machine.enable = true; # Set your time zone. time.timeZone = "Europe/Amsterdam"; @@ -19,5 +20,5 @@ # 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 = "25.05"; # Did you read the comment? + system.stateVersion = "24.11"; # Did you read the comment? } diff --git a/nixos-configurations/lindberg-build/networking.nix b/nixos-configurations/lindberg-build/networking.nix index 0564355..0e8f881 100644 --- a/nixos-configurations/lindberg-build/networking.nix +++ b/nixos-configurations/lindberg-build/networking.nix @@ -1,4 +1,4 @@ -{ config, ... }: +{ config, pkgs, ... }: { diff --git a/nixos-configurations/lindberg-nextcloud/applications/cloud.nix b/nixos-configurations/lindberg-nextcloud/applications/cloud.nix new file mode 100644 index 0000000..8e6b4ff --- /dev/null +++ b/nixos-configurations/lindberg-nextcloud/applications/cloud.nix @@ -0,0 +1,21 @@ +{ config, pkgs, ... }: +let + host = "cloud.qo.is"; +in +{ + + imports = [ ../../../defaults/nextcloud ]; + + services.postgresql.enable = true; + + services.nextcloud = { + hostName = host; + package = pkgs.nextcloud30; + settings.default_phone_region = "CH"; + }; + services.nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + kTLS = true; + }; +} diff --git a/nixos-configurations/lindberg-nextcloud/applications/default.nix b/nixos-configurations/lindberg-nextcloud/applications/default.nix index 2eba300..d872c18 100644 --- a/nixos-configurations/lindberg-nextcloud/applications/default.nix +++ b/nixos-configurations/lindberg-nextcloud/applications/default.nix @@ -1,9 +1,7 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { - qois.postgresql.package = pkgs.postgresql_14; - qois.cloud = { - enable = true; - package = pkgs.nextcloud31; - }; + imports = [ ./cloud.nix ]; + + qois.postgresql.package = pkgs.postgresql_14; } diff --git a/nixos-configurations/lindberg-nextcloud/backup.nix b/nixos-configurations/lindberg-nextcloud/backup.nix index 561f4b1..3b5da39 100644 --- a/nixos-configurations/lindberg-nextcloud/backup.nix +++ b/nixos-configurations/lindberg-nextcloud/backup.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { diff --git a/nixos-configurations/lindberg-nextcloud/default.nix b/nixos-configurations/lindberg-nextcloud/default.nix index eab10d4..78fc78d 100644 --- a/nixos-configurations/lindberg-nextcloud/default.nix +++ b/nixos-configurations/lindberg-nextcloud/default.nix @@ -1,14 +1,14 @@ -{ config, ... }: +{ config, pkgs, ... }: { imports = [ + ../../defaults/base-vm + ../../defaults/meta ./applications ./backup.nix ./secrets.nix ]; - qois.system.virtual-machine.enable = true; - boot.loader.grub.device = "/dev/vda"; fileSystems."/" = { device = "/dev/disk/by-uuid/5b6823ec-921f-400a-a7c0-3fe34d56ae12"; @@ -46,5 +46,5 @@ # 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 = "25.05"; # Did you read the comment? + system.stateVersion = "24.11"; # Did you read the comment? } diff --git a/nixos-configurations/lindberg-webapps/applications/README.md b/nixos-configurations/lindberg-webapps/applications/README.md index 7a0a199..b4445bb 100644 --- a/nixos-configurations/lindberg-webapps/applications/README.md +++ b/nixos-configurations/lindberg-webapps/applications/README.md @@ -1,16 +1,3 @@ # Web Apps -## Setting up new static sites - -Generate ssh key for deployment: - -```bash -export SSH_KEYFILE=$(mktemp --dry-run -- /dev/shm/key-XXXXXXXXX) -mkfifo -m 600 $SSH_KEYFILE -ssh-keygen -q -t ed25519 -C "ci@git.qo.is" -N "" -f $SSH_KEYFILE <<< "y\ny\n" & -wl-copy --trim-newline --foreground --paste-once < $SSH_KEYFILE -# Paste private key in CI secret "SSH_DEPLOY_KEY" now - -# Configure public key: -wl-copy --trim-newline < ${SSH_KEYFILE}.pub -``` +## fabianhauser.ch diff --git a/nixos-configurations/lindberg-webapps/applications/default.nix b/nixos-configurations/lindberg-webapps/applications/default.nix index 672e080..9efef42 100644 --- a/nixos-configurations/lindberg-webapps/applications/default.nix +++ b/nixos-configurations/lindberg-webapps/applications/default.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { imports = [ ]; diff --git a/nixos-configurations/lindberg-webapps/default.nix b/nixos-configurations/lindberg-webapps/default.nix index d3ba75b..1cbfd2f 100644 --- a/nixos-configurations/lindberg-webapps/default.nix +++ b/nixos-configurations/lindberg-webapps/default.nix @@ -1,15 +1,16 @@ -{ ... }: +{ config, pkgs, ... }: { imports = [ + ../../defaults/base-vm + ../../defaults/meta + ./applications ./disko-config.nix ./networking.nix ./secrets.nix ]; - qois.system.virtual-machine.enable = true; - # Set your time zone. time.timeZone = "Europe/Amsterdam"; @@ -19,5 +20,5 @@ # 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 = "25.05"; # Did you read the comment? + system.stateVersion = "24.11"; # Did you read the comment? } diff --git a/nixos-configurations/lindberg-webapps/disko-config.nix b/nixos-configurations/lindberg-webapps/disko-config.nix index 6024053..8a7d268 100644 --- a/nixos-configurations/lindberg-webapps/disko-config.nix +++ b/nixos-configurations/lindberg-webapps/disko-config.nix @@ -3,7 +3,7 @@ disko.devices.disk = { system = { type = "disk"; - device = "/dev/vdb"; + device = "/dev/vda"; content = { type = "gpt"; partitions = { diff --git a/nixos-configurations/lindberg-webapps/networking.nix b/nixos-configurations/lindberg-webapps/networking.nix index 6a5c63d..07f42ff 100644 --- a/nixos-configurations/lindberg-webapps/networking.nix +++ b/nixos-configurations/lindberg-webapps/networking.nix @@ -1,4 +1,4 @@ -{ config, ... }: +{ config, pkgs, ... }: { diff --git a/nixos-configurations/lindberg/README.md b/nixos-configurations/lindberg/README.md index 62f8332..c6957d9 100644 --- a/nixos-configurations/lindberg/README.md +++ b/nixos-configurations/lindberg/README.md @@ -1,14 +1,10 @@ # Host: Lindberg -## Operations {#\_operations} +## Operations {#_operations} -Reboot requires passphrase: +Reboot requires passphrase (see pass `host/lindberg/hdd_luks`) -```bash -# Get passphrase -sops decrypt --extract '["system"]["hdd"]' private/nixos-configurations/lindberg/secrets.sops.yaml - -# Insert passphrase: +``` bash ssh -p 2222 root@lindberg.riedbach-ext.net.qo.is ``` @@ -16,6 +12,7 @@ ssh -p 2222 root@lindberg.riedbach-ext.net.qo.is - [Mainboard Manual](docs/X570Pro4-mainboard-manual.pdf) + ### Front / Back #### Front Overview diff --git a/nixos-configurations/lindberg/applications/default.nix b/nixos-configurations/lindberg/applications/default.nix index bf4ab0c..e0d34f0 100644 --- a/nixos-configurations/lindberg/applications/default.nix +++ b/nixos-configurations/lindberg/applications/default.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { imports = [ ./loadbalancer.nix ]; diff --git a/nixos-configurations/lindberg/applications/loadbalancer.nix b/nixos-configurations/lindberg/applications/loadbalancer.nix index 2594617..97427d2 100644 --- a/nixos-configurations/lindberg/applications/loadbalancer.nix +++ b/nixos-configurations/lindberg/applications/loadbalancer.nix @@ -1,4 +1,7 @@ { + config, + pkgs, + lib, ... }: diff --git a/nixos-configurations/lindberg/backup.nix b/nixos-configurations/lindberg/backup.nix index 7421be3..bb9bb11 100644 --- a/nixos-configurations/lindberg/backup.nix +++ b/nixos-configurations/lindberg/backup.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { qois.backup-client.includePaths = [ "/mnt/data" ]; diff --git a/nixos-configurations/lindberg/default.nix b/nixos-configurations/lindberg/default.nix index cb2e35c..74a84b6 100644 --- a/nixos-configurations/lindberg/default.nix +++ b/nixos-configurations/lindberg/default.nix @@ -1,4 +1,4 @@ -{ ... }: +{ config, pkgs, ... }: { imports = [ @@ -11,9 +11,10 @@ ./virtualisation.nix ../../defaults/hardware/asrock.nix - ]; - qois.system.physical.enable = true; + ../../defaults/base + ../../defaults/meta + ]; # Set your time zone. time.timeZone = "Europe/Amsterdam"; @@ -24,5 +25,5 @@ # 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 = "25.05"; # Did you read the comment? + system.stateVersion = "24.11"; # Did you read the comment? } diff --git a/nixos-configurations/lindberg/filesystems.nix b/nixos-configurations/lindberg/filesystems.nix index d8b39b4..b594021 100644 --- a/nixos-configurations/lindberg/filesystems.nix +++ b/nixos-configurations/lindberg/filesystems.nix @@ -9,8 +9,12 @@ MAILADDR root ARRAY /dev/md/raid_system metadata=1.2 name=any:raid_system UUID=1becc692:aeb83b67:1c65da45:b8bd4b93 ARRAY /dev/md/raid_data metadata=1.2 name=any:raid_data UUID=576eabb1:0722bc27:84d9314f:d0145000 + INACTIVE-ARRAY /dev/md125 metadata=1.2 name=nixos:md_data UUID=b9c36b6d:a2e0fa86:f6dbfe57:857cd0d2 ''; + # TODO: RAID Monitoring + # TODO: Set spin-down time of physical disks + services.fwupd.daemonSettings.EspLocation = pkgs.lib.mkForce config.disko.devices.disk.system-1.content.partitions.boot.content.mountpoint; # Use the systemd-boot EFI boot loader. @@ -24,11 +28,11 @@ path = "/boot-primary"; efiBootloaderId = "NixOS primary"; } - { - devices = [ "nodev" ]; - path = "/boot-secondary"; - efiBootloaderId = "NixOS secondary"; - } + #{ + # devices = [ "nodev" ]; + # path = "/boot-secondary"; + # efiBootloaderId = "NixOS secondary"; + #} ]; }; } diff --git a/nixos-configurations/lindberg/networking.nix b/nixos-configurations/lindberg/networking.nix index aab51c3..67f2b0b 100644 --- a/nixos-configurations/lindberg/networking.nix +++ b/nixos-configurations/lindberg/networking.nix @@ -1,4 +1,4 @@ -{ config, ... }: +{ config, pkgs, ... }: let meta = config.qois.meta; @@ -73,7 +73,7 @@ in # Boot boot.initrd.network.udhcpc.enable = true; - qois.luks-ssh = { + services.qois.luks-ssh = { enable = true; interface = "eth0"; sshPort = 2222; diff --git a/nixos-configurations/lindberg/virtualisation.nix b/nixos-configurations/lindberg/virtualisation.nix index 6e7a883..5905bdf 100644 --- a/nixos-configurations/lindberg/virtualisation.nix +++ b/nixos-configurations/lindberg/virtualisation.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { virtualisation.libvirtd = { enable = true; diff --git a/nixos-configurations/secrets.nix b/nixos-configurations/secrets.nix new file mode 100644 index 0000000..0757d74 --- /dev/null +++ b/nixos-configurations/secrets.nix @@ -0,0 +1,11 @@ +{ inputs, ... }: +{ + sops.secrets = + let + allHostsSecretsFile = "${inputs.private}/nixos-configurations/secrets.sops.yaml"; + in + { + "msmtp/password".sopsFile = allHostsSecretsFile; + "wgautomesh/gossip-secret".sopsFile = allHostsSecretsFile; + }; +} diff --git a/nixos-configurations/setup.md b/nixos-configurations/setup.md index 11fdcf8..542eb18 100644 --- a/nixos-configurations/setup.md +++ b/nixos-configurations/setup.md @@ -3,8 +3,8 @@ ## Prepare Remote Machine 1. Boot nixos installer image -1. Set a root password: `sudo passwd root` -1. Get host ip to connect to ssh with `ip a` +2. Set a root password: `sudo passwd root` +3. Get host ip to connect to ssh with `ip a` ## Verify configuration @@ -12,7 +12,7 @@ ## Installation -````bash +```bash nix develop # Set according to what we want @@ -60,11 +60,11 @@ sops exec-file --no-fifo --filename secret.key private/nixos-configurations/$REM --disk-encryption-keys /run/secrets/system/hdd.key <(yq --raw-output '.system.hdd' {}) \ --disk-encryption-keys /run/secrets/system/initrd-ssh-key <(yq --raw-output '.system.\"initrd-ssh-key\"' {}) " -```` +``` ## Post-Setup -- Add backplane-vpn pubkey to `network-virtual.nix` configuration with +* Add backplane-vpn pubkey to `network-virtual.nix` configuration with ```bash wg pubkey < /secrets/wireguard/private/backplane ``` diff --git a/nixos-configurations/stompert/README.md b/nixos-configurations/stompert/README.md new file mode 100644 index 0000000..8a46e06 --- /dev/null +++ b/nixos-configurations/stompert/README.md @@ -0,0 +1,7 @@ +# Operations {#_operations} + +Reboot requires passphrase (see pass `host/stompert/hdd_luks`) + +``` bash +ssh -p 2222 root@stompert.eem-ext.net.qo.is +``` diff --git a/nixos-configurations/stompert/default.nix b/nixos-configurations/stompert/default.nix new file mode 100644 index 0000000..5eea848 --- /dev/null +++ b/nixos-configurations/stompert/default.nix @@ -0,0 +1,65 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). + +{ config, pkgs, ... }: + +{ + imports = [ + ../../defaults/hardware/apu.nix + ../../defaults/base + ../../defaults/meta + ]; + + boot.initrd.luks.devices."systems".device = + "/dev/disk/by-uuid/5718bd19-cb7a-4728-9ec4-6b2be48215fc"; + + fileSystems."/" = { + device = "/dev/mapper/vg_systems-hv_stompert"; + fsType = "btrfs"; + options = [ "subvol=root" ]; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/bbe12368-1f81-4924-a12c-2edec886f7c8"; + fsType = "ext4"; + }; + + swapDevices = [ { device = "/dev/disk/by-uuid/851e1d05-569f-41ca-8ed9-d7ffba489ffe"; } ]; + + # Use the GRUB 2 boot loader. + boot.loader.grub.enable = true; + # boot.loader.grub.efiSupport = true; + # boot.loader.grub.efiInstallAsRemovable = true; + # boot.loader.efi.efiSysMountPoint = "/boot/efi"; + # Define on which hard drive you want to install Grub. + boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only + + services.qois.luks-ssh = { + enable = true; + interface = "eth1"; + sshPort = 2222; + }; + + networking.hostName = "stompert"; # Define your hostname. + + # The global useDHCP flag is deprecated, therefore explicitly set to false here. + # Per-interface useDHCP will be mandatory in the future, so this generated config + # replicates the default behaviour. + networking.useDHCP = false; + networking.interfaces.enp1s0.useDHCP = true; + networking.interfaces.enp2s0.useDHCP = true; + networking.interfaces.enp3s0.useDHCP = true; + networking.tempAddresses = "disabled"; + + qois.backplane-net.enable = true; + + # Set your time zone. + # time.timeZone = "Europe/Amsterdam"; + + # This value determines the NixOS release with which your system is to be + # compatible, in order to avoid breaking some software such as database + # servers. You should change this only after NixOS release notes say you + # should. + system.stateVersion = "24.11"; # Did you read the comment? +} diff --git a/nixos-modules/backplane-net/default.nix b/nixos-modules/backplane-net/default.nix deleted file mode 100644 index b5c2c4d..0000000 --- a/nixos-modules/backplane-net/default.nix +++ /dev/null @@ -1,80 +0,0 @@ -{ - config, - lib, - ... -}: -with lib; -let - cfg = config.qois.backplane-net; -in -{ - options.qois.backplane-net = { - enable = mkEnableOption "Enable backplane server services"; - netName = mkOption { - description = "Network Name"; - type = types.str; - default = "backplane"; - }; - port = mkOption { - description = "Wireguard Default Port"; - type = types.number; - default = 51825; - }; - }; - - config = lib.mkIf cfg.enable ( - let - hostName = config.networking.hostName; - netConfig = config.qois.meta.network.virtual.${cfg.netName}; - hostNetConfig = netConfig.hosts.${hostName}; - interface = "wg-${cfg.netName}"; - wgService = [ "wireguard-${interface}.service" ]; - in - { - sops.secrets."wgautomesh/gossip-secret".restartUnits = [ "wgautomesh.service" ]; - - networking.wireguard.enable = true; - networking.wireguard.interfaces."wg-${cfg.netName}" = { - ips = [ "${hostNetConfig.v4.ip}/${toString netConfig.v4.prefixLength}" ]; - listenPort = if hostNetConfig.endpoint != null then hostNetConfig.endpoint.port else cfg.port; - privateKeyFile = "/secrets/wireguard/private/${cfg.netName}"; - generatePrivateKeyFile = true; - }; - - systemd.network.wait-online.ignoredInterfaces = [ interface ]; - - networking.firewall.allowedUDPPorts = - if hostNetConfig.endpoint != null then [ hostNetConfig.endpoint.port ] else [ cfg.port ]; - - # Configure wgautomesh to setup peers. Make sure that the name is not used in the VPN module - services.wgautomesh = { - enable = true; - gossipSecretFile = config.sops.secrets."wgautomesh/gossip-secret".path; - openFirewall = true; - settings = { - inherit interface; - - # Map meta network configuration to the format of wgautomesh and filter out peers with endpoints - peers = pipe netConfig.hosts [ - (filterAttrs (peerHostName: _: peerHostName != hostName)) # Not this host - (mapAttrsToList ( - _: peerConfig: { - address = peerConfig.v4.ip; - endpoint = - if (peerConfig.endpoint != null) then - with peerConfig.endpoint; "${fqdn}:${toString port}" - else - null; - pubkey = peerConfig.publicKey; - } - )) - ]; - }; - }; - systemd.services.wgautomesh = { - requires = wgService; - after = wgService; - }; - } - ); -} diff --git a/nixos-modules/cloud/default.nix b/nixos-modules/cloud/default.nix deleted file mode 100644 index e54f2d7..0000000 --- a/nixos-modules/cloud/default.nix +++ /dev/null @@ -1,135 +0,0 @@ -# Default configuration for hosts -{ - config, - lib, - pkgs, - ... -}: - -let - cfg = config.qois.cloud; -in -with lib; -{ - - options.qois.cloud = { - enable = mkEnableOption "Enable qois cloud service"; - - domain = mkOption { - type = types.str; - default = "cloud.qo.is"; - description = "Domain, under which the service is served."; - }; - - package = mkOption { - type = types.package; - description = "Which package to use for the Nextcloud instance."; - relatedPackages = [ - "nextcloud28" - "nextcloud29" - "nextcloud30" - ]; - }; - }; - - config = mkIf cfg.enable { - - services.nginx.virtualHosts."${cfg.domain}" = { - forceSSL = true; - enableACME = true; - kTLS = true; - }; - - sops.secrets."nextcloud/admin" = with config.users.users.nextcloud; { - inherit group; - owner = name; - }; - - services.postgresql.enable = true; - qois.backup-client.includePaths = [ config.services.nextcloud.home ]; - - services.nextcloud = { - inherit (cfg) package; - enable = true; - hostName = cfg.domain; - https = true; - webfinger = true; - maxUploadSize = "10G"; - - database.createLocally = true; - - config = { - adminpassFile = config.sops.secrets."nextcloud/admin".path; - adminuser = "root"; - dbtype = "pgsql"; - }; - - appstoreEnable = false; - extraApps = { - inherit (config.services.nextcloud.package.passthru.packages.apps) - calendar - contacts - deck - groupfolders - # maps # Unsupported with nextcloud31, not widely used currently, so disable for now. - memories - music - news - notes - notify_push - tasks - twofactor_webauthn - ; - }; - - phpOptions = { - "opcache.interned_strings_buffer" = "64"; - "opcache.memory_consumption" = "512"; - "opcache.save_comments" = "1"; - "opcache.max_accelerated_files" = "50000"; - "opcache.fast_shutdown" = "1"; - "opcache.jit" = "1255"; - "opcache.jit_buffer_size" = "8M"; - }; - - poolSettings = { - "pm" = "dynamic"; - "pm.max_children" = "480"; - "pm.max_requests" = "2000"; - "pm.max_spare_servers" = "72"; - "pm.min_spare_servers" = "24"; - "pm.start_servers" = "48"; - }; - - configureRedis = true; - caching.redis = true; - - notify_push = { - enable = true; - bendDomainToLocalhost = true; - }; - - settings = { - log_type = "syslog"; - syslog_tag = "nextcloud"; - "memories.exiftool" = "${lib.getExe pkgs.exiftool}"; - "memories.vod.ffmpeg" = "${lib.getExe pkgs.ffmpeg-headless}"; - "memories.vod.ffprobe" = "${pkgs.ffmpeg-headless}/bin/ffprobe"; - preview_ffmpeg_path = "${lib.getExe pkgs.ffmpeg-headless}"; - mail_smtpmode = "sendmail"; - mail_domain = "qo.is"; - default_phone_region = "CH"; - }; - }; - - users.users.nextcloud.extraGroups = [ "postdrop" ]; - - systemd.services.nextcloud-cron = { - path = [ pkgs.perl ]; - }; - - environment.systemPackages = with pkgs; [ - nodejs # required for Recognize - ]; - }; -} diff --git a/nixos-modules/default.nix b/nixos-modules/default.nix index 4e50c08..0afd3b1 100644 --- a/nixos-modules/default.nix +++ b/nixos-modules/default.nix @@ -1,20 +1,8 @@ -{ - private, - self, - disko, - sops-nix, - ... -}: -{ +inputs: { default = - { ... }: + { config, pkgs, ... }: { - imports = (self.lib.loadSubmodulesFrom ./.) ++ [ - ../defaults/meta - disko.nixosModules.disko - sops-nix.nixosModules.sops - private.nixosModules.default - ]; + imports = (inputs.self.lib.loadSubmodulesFrom ./.) ++ [ inputs.private.nixosModules.default ]; }; } diff --git a/nixos-modules/luks-ssh/default.nix b/nixos-modules/luks-ssh/default.nix index 5f0950a..7f11b88 100644 --- a/nixos-modules/luks-ssh/default.nix +++ b/nixos-modules/luks-ssh/default.nix @@ -1,16 +1,17 @@ { config, lib, + pkgs, ... }: with lib; let - cfg = config.qois.luks-ssh; + cfg = config.services.qois.luks-ssh; in { - options.qois.luks-ssh = { + options.services.qois.luks-ssh = { enable = mkEnableOption "luks-ssh service"; interface = mkOption { @@ -82,7 +83,7 @@ in with lib; concatLists ( mapAttrsToList ( - _name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else [ ] + name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else [ ] ) config.users.users ); hostKeys = [ cfg.sshHostKey ]; diff --git a/nixos-modules/meta/default.nix b/nixos-modules/meta/default.nix index ad18f47..f7d9775 100644 --- a/nixos-modules/meta/default.nix +++ b/nixos-modules/meta/default.nix @@ -1,4 +1,8 @@ { + config, + lib, + pkgs, + options, ... }: { diff --git a/nixos-modules/meta/hosts.nix b/nixos-modules/meta/hosts.nix index af9497c..27526d0 100644 --- a/nixos-modules/meta/hosts.nix +++ b/nixos-modules/meta/hosts.nix @@ -1,6 +1,7 @@ { config, lib, + pkgs, options, ... }: @@ -42,10 +43,10 @@ in }; config = let - hostsWithSshKey = lib.filterAttrs (_name: hostCfg: hostCfg.sshKey != null) cfg; + hostsWithSshKey = lib.filterAttrs (name: hostCfg: hostCfg.sshKey != null) cfg; in { - programs.ssh.knownHosts = lib.mapAttrs (_name: hostCfg: { + programs.ssh.knownHosts = lib.mapAttrs (name: hostCfg: { publicKey = hostCfg.sshKey; }) hostsWithSshKey; }; diff --git a/nixos-modules/meta/network.nix b/nixos-modules/meta/network.nix index e30a26f..3caa3d7 100644 --- a/nixos-modules/meta/network.nix +++ b/nixos-modules/meta/network.nix @@ -1,6 +1,7 @@ { config, lib, + pkgs, options, ... }: @@ -16,6 +17,13 @@ let type = str; inherit description; }); + mkOptStr = + description: + (mkOption { + type = nullOr str; + default = null; + inherit description; + }); mkNetworkIdOpts = v: @@ -217,10 +225,10 @@ in (getHostNamesForNetworks hostname cfg.virtual) ++ (getHostNamesForNetworks hostname cfg.physical); hostsWithPublicKey = lib.filterAttrs ( - _hostName: hostConfig: hostConfig.sshKey != null + hostName: hostConfig: hostConfig.sshKey != null ) config.qois.meta.hosts; in - mapAttrs (name: _hostCfg: { extraHostNames = getHostNames name; }) hostsWithPublicKey; + mapAttrs (name: hostCfg: { extraHostNames = getHostNames name; }) hostsWithPublicKey; }; } diff --git a/nixos-modules/nixpkgs-cache/default.nix b/nixos-modules/nixpkgs-cache/default.nix index 3823bb7..12c55ef 100644 --- a/nixos-modules/nixpkgs-cache/default.nix +++ b/nixos-modules/nixpkgs-cache/default.nix @@ -1,5 +1,6 @@ { config, + pkgs, lib, ... }: @@ -15,7 +16,6 @@ with lib; hostname = mkOption { type = types.str; example = "mycache.myhost.org"; - default = "nixpkgs-cache.qo.is"; description = "Hostname, under which the cache is served"; }; diff --git a/nixos-modules/outgoing-server-mail/default.nix b/nixos-modules/outgoing-server-mail/default.nix index 8718fe4..2f04382 100644 --- a/nixos-modules/outgoing-server-mail/default.nix +++ b/nixos-modules/outgoing-server-mail/default.nix @@ -40,7 +40,7 @@ with lib; host = "mail.cyon.ch"; user = "system@qo.is"; from = "no-reply@qo.is"; - passwordeval = "${pkgs.coreutils}/bin/cat ${config.sops.secrets."msmtp/password".path}"; + passwordeval = "${pkgs.busybox}/bin/cat ${config.sops.secrets."msmtp/password".path}"; }; }; }; diff --git a/nixos-modules/attic/default.nix b/nixos-modules/qois/attic/default.nix similarity index 98% rename from nixos-modules/attic/default.nix rename to nixos-modules/qois/attic/default.nix index 5ab774f..adb9e4b 100644 --- a/nixos-modules/attic/default.nix +++ b/nixos-modules/qois/attic/default.nix @@ -1,5 +1,6 @@ { config, + pkgs, lib, ... }: @@ -84,7 +85,7 @@ in services.nginx = { enable = true; - clientMaxBodySize = "10G"; + clientMaxBodySize = "1g"; virtualHosts.${cfg.domain} = { kTLS = true; forceSSL = true; diff --git a/nixos-modules/backplane-net.hosts/default.nix b/nixos-modules/qois/backplane-net.hosts/default.nix similarity index 95% rename from nixos-modules/backplane-net.hosts/default.nix rename to nixos-modules/qois/backplane-net.hosts/default.nix index ea58c18..b249dac 100644 --- a/nixos-modules/backplane-net.hosts/default.nix +++ b/nixos-modules/qois/backplane-net.hosts/default.nix @@ -1,5 +1,6 @@ { config, + pkgs, lib, ... }: @@ -34,7 +35,7 @@ in networking.hosts = pipe cfg.loadbalancers [ (map (hostname: config.qois.meta.network.virtual.backplane.hosts.${hostname}.v4.ip)) - (flip genAttrs (_lb: cfg.domains)) + (flip genAttrs (lb: cfg.domains)) ]; }; diff --git a/nixos-modules/backplane-net/README.md b/nixos-modules/qois/backplane-net/README.md similarity index 100% rename from nixos-modules/backplane-net/README.md rename to nixos-modules/qois/backplane-net/README.md diff --git a/nixos-modules/qois/backplane-net/default.nix b/nixos-modules/qois/backplane-net/default.nix new file mode 100644 index 0000000..08fb31e --- /dev/null +++ b/nixos-modules/qois/backplane-net/default.nix @@ -0,0 +1,83 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; +let + cfg = config.qois.backplane-net; + hostName = config.networking.hostName; + netConfig = config.qois.meta.network.virtual.${cfg.netName}; + hostNetConfig = netConfig.hosts.${hostName}; + interface = "wg-${cfg.netName}"; + wgService = [ "wireguard-${interface}.service" ]; +in + +{ + options.qois.backplane-net = { + enable = mkEnableOption "Enable backplane server services"; + netName = mkOption { + description = "Network Name"; + type = types.str; + default = "backplane"; + }; + domain = mkOption { + description = "Domain"; + type = types.str; + default = hostNetConfig; + }; + port = mkOption { + description = "Wireguard Default Port"; + type = types.number; + default = 51825; + }; + }; + + config = { + sops.secrets."wgautomesh/gossip-secret".restartUnits = [ "wgautomesh.service" ]; + + networking.wireguard.enable = true; + networking.wireguard.interfaces."wg-${cfg.netName}" = { + ips = [ "${hostNetConfig.v4.ip}/${toString netConfig.v4.prefixLength}" ]; + listenPort = if hostNetConfig.endpoint != null then hostNetConfig.endpoint.port else cfg.port; + privateKeyFile = "/secrets/wireguard/private/${cfg.netName}"; + generatePrivateKeyFile = true; + }; + + systemd.network.wait-online.ignoredInterfaces = [ interface ]; + + networking.firewall.allowedUDPPorts = + if hostNetConfig.endpoint != null then [ hostNetConfig.endpoint.port ] else [ cfg.port ]; + + # Configure wgautomesh to setup peers. Make sure that the name is not used in the VPN module + services.wgautomesh = { + enable = true; + gossipSecretFile = config.sops.secrets."wgautomesh/gossip-secret".path; + openFirewall = true; + settings = { + inherit interface; + + # Map meta network configuration to the format of wgautomesh and filter out peers with endpoints + peers = pipe netConfig.hosts [ + (filterAttrs (peerHostName: _: peerHostName != hostName)) # Not this host + (mapAttrsToList ( + _: peerConfig: { + address = peerConfig.v4.ip; + endpoint = + if (peerConfig.endpoint != null) then + with peerConfig.endpoint; "${fqdn}:${toString port}" + else + null; + pubkey = peerConfig.publicKey; + } + )) + ]; + }; + }; + systemd.services.wgautomesh = { + requires = wgService; + after = wgService; + }; + }; +} diff --git a/nixos-modules/backup-client/README.md b/nixos-modules/qois/backup-client/README.md similarity index 100% rename from nixos-modules/backup-client/README.md rename to nixos-modules/qois/backup-client/README.md diff --git a/nixos-modules/backup-client/default.nix b/nixos-modules/qois/backup-client/default.nix similarity index 99% rename from nixos-modules/backup-client/default.nix rename to nixos-modules/qois/backup-client/default.nix index df872f0..5e45d82 100644 --- a/nixos-modules/backup-client/default.nix +++ b/nixos-modules/qois/backup-client/default.nix @@ -2,6 +2,8 @@ config, lib, options, + pkgs, + self, ... }: diff --git a/nixos-modules/backup-server/README.md b/nixos-modules/qois/backup-server/README.md similarity index 100% rename from nixos-modules/backup-server/README.md rename to nixos-modules/qois/backup-server/README.md diff --git a/nixos-modules/backup-server/default.nix b/nixos-modules/qois/backup-server/default.nix similarity index 98% rename from nixos-modules/backup-server/default.nix rename to nixos-modules/qois/backup-server/default.nix index 15df544..fe3c79f 100644 --- a/nixos-modules/backup-server/default.nix +++ b/nixos-modules/qois/backup-server/default.nix @@ -2,6 +2,8 @@ config, lib, options, + pkgs, + self, ... }: diff --git a/nixos-modules/qois/default.nix b/nixos-modules/qois/default.nix new file mode 100644 index 0000000..6a72f9f --- /dev/null +++ b/nixos-modules/qois/default.nix @@ -0,0 +1,10 @@ +{ + config, + pkgs, + inputs, + ... +}: +{ + + imports = inputs.self.lib.loadSubmodulesFrom ./.; +} diff --git a/nixos-modules/git-ci-runner/README.md b/nixos-modules/qois/git-ci-runner/README.md similarity index 78% rename from nixos-modules/git-ci-runner/README.md rename to nixos-modules/qois/git-ci-runner/README.md index 2d64ab2..694ad88 100644 --- a/nixos-modules/git-ci-runner/README.md +++ b/nixos-modules/qois/git-ci-runner/README.md @@ -2,6 +2,7 @@ Runner for the [Forgejo git instance](../git/README.md). + ## Default docker/ubuntu Runner Registers a default runner with ubuntu OS or executes user's OCI container with podman. @@ -18,14 +19,3 @@ Consequentially, don't use to build nix things that should stay secret (which is ## Create Secret Token To create a new token for registration, follow the steps outlined in the [Forgejo documentation](https://forgejo.org/docs/latest/user/actions/#forgejo-runner). - -## Clear Runner Caches - -Under some circumstances, runner caches need to be cleared. This can be done with: - -```bash -cd /var/lib/private/gitea-runner/ -systemctl stop --all gitea-runner-* -rm -r */.cache/ -systemctl start --all gitea-runner-* -``` diff --git a/nixos-modules/git-ci-runner/default.nix b/nixos-modules/qois/git-ci-runner/default.nix similarity index 86% rename from nixos-modules/git-ci-runner/default.nix rename to nixos-modules/qois/git-ci-runner/default.nix index 7f6e9b6..ac53334 100644 --- a/nixos-modules/git-ci-runner/default.nix +++ b/nixos-modules/qois/git-ci-runner/default.nix @@ -25,35 +25,6 @@ with lib; default = 10; description = "How many nix runner instances to start"; }; - - trustedSubstituters = mkOption { - type = types.listOf types.str; - default = [ - # General substitutors (also elsewhere defined defaults, but without priority params) - "https://cache.nixos.org" - "https://${config.qois.nixpkgs-cache.hostname}" - "https://cache.garnix.io" - - # Project builds - "https://attic.qo.is/qois-infrastructure" # https://git.qo.is/qo.is/infrastructure - "https://attic.qo.is/dotfiles" # https://git.qo.is/fabianhauser/dotfiles - ]; - description = "Substitutors that are trusted by the host."; - }; - - trustedPublicKeys = mkOption { - type = types.listOf types.str; - default = [ - # General subsitutors - "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=" - - # Project builds - "qois-infrastructure:lh35ymN7Aoxm5Hz0S6JusxE+cYzMU+x9OMKjDVIpfuE=" # https://git.qo.is/qo.is/infrastructure - "dotfiles:KpLi0qe5O5rb8E8N8vntZWBDqFwG3Ksx4AFGizYCLoU=" # https://git.qo.is/fabianhauser/dotfiles - ]; - description = "Substitutor public keys that are trusted by the host."; - }; }; config = mkIf cfg.enable (mkMerge [ @@ -63,12 +34,6 @@ with lib; "gitea-runner-${defaultInstanceName}.service" ] ++ (genList (n: "gitea-runner-nix${builtins.toString n}.service") cfg.nixInstances); - nix.settings = { - trusted-substituters = cfg.trustedSubstituters; - trusted-public-keys = cfg.trustedPublicKeys; - - }; - virtualisation.podman = { enable = true; dockerCompat = true; @@ -181,7 +146,7 @@ with lib; { systemd.services = genAttrs (genList (n: "gitea-runner-nix${builtins.toString n}") cfg.nixInstances) - (_name: { + (name: { after = [ "gitea-runner-nix-image.service" ]; @@ -272,9 +237,7 @@ with lib; pkgs.findutils pkgs.gawk pkgs.git - pkgs.git-lfs pkgs.gnugrep - pkgs.gnused pkgs.jq pkgs.nix pkgs.nodejs diff --git a/nixos-modules/git/README.md b/nixos-modules/qois/git/README.md similarity index 91% rename from nixos-modules/git/README.md rename to nixos-modules/qois/git/README.md index c76741a..6b822bc 100644 --- a/nixos-modules/git/README.md +++ b/nixos-modules/qois/git/README.md @@ -38,6 +38,7 @@ sudo -u forgejo 'nix run nixpkgs#forgejo -- admin user create --config ~custom/c ## Backup / Restore 1. `systemctl stop forgejo.service` -1. Import Postgresql Database Backup -1. Restore `/var/lib/forgejo` -1. `systemctl start forgejo.service` +2. Import Postgresql Database Backup +3. Restore `/var/lib/forgejo` +4. `systemctl start forgejo.service` + diff --git a/nixos-modules/git/default.nix b/nixos-modules/qois/git/default.nix similarity index 93% rename from nixos-modules/git/default.nix rename to nixos-modules/qois/git/default.nix index 2983a33..719a3a0 100644 --- a/nixos-modules/git/default.nix +++ b/nixos-modules/qois/git/default.nix @@ -40,11 +40,7 @@ with lib; }; "ssh.minimum_key_sizes".RSA = 2047; session.COOKIE_SECURE = true; - service = { - DISABLE_REGISTRATION = true; - ENABLE_NOTIFY_MAIL = true; - DEFAULT_KEEP_EMAIL_PRIVATE = true; - }; + service.DISABLE_REGISTRATION = true; mailer = { ENABLED = true; PROTOCOL = "sendmail"; diff --git a/nixos-modules/loadbalancer/default.nix b/nixos-modules/qois/loadbalancer/default.nix similarity index 88% rename from nixos-modules/loadbalancer/default.nix rename to nixos-modules/qois/loadbalancer/default.nix index cbefaea..fe5477c 100644 --- a/nixos-modules/loadbalancer/default.nix +++ b/nixos-modules/qois/loadbalancer/default.nix @@ -9,7 +9,7 @@ with lib; let # We assume that all static pages are hosted on lindberg-webapps staticPages = pipe config.qois.static-page.pages [ - (mapAttrsToList (_name: { domain, domainAliases, ... }: [ domain ] ++ domainAliases)) + (mapAttrsToList (name: { domain, domainAliases, ... }: [ domain ] ++ domainAliases)) flatten (map (name: { inherit name; @@ -35,8 +35,6 @@ let "www.raphael.li" = "lindberg-rzimmermann"; "vpn.qo.is" = "cyprianspitz-headscale"; - "api.winder.fh2.ch" = "workstations-8080"; - "www.winder.fh2.ch" = "workstations-3000"; }; getBackplaneIp = hostname: config.qois.meta.network.virtual.backplane.hosts.${hostname}.v4.ip; defaultHostmap = @@ -76,15 +74,6 @@ let backend cyprianspitz-headscale-https mode tcp server s1 ${getBackplaneIp "cyprianspitz"}:${headscalePort} - - # Winder Study Project (tmp) - backend workstations-3000-http - mode http - server s1 10.247.0.156:3000 - - backend workstations-8080-http - mode http - server s1 10.247.0.156:8080 ''; cfg = config.qois.loadbalancer; in @@ -159,7 +148,7 @@ in frontend http mode http bind *:80 - use_backend %[req.hdr(host),lower,map(${domainMappingFile})]-http + use_backend %[req.hdr(host),lower,map_dom(${domainMappingFile})]-http frontend https bind *:443 @@ -167,7 +156,7 @@ in tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } - use_backend %[req.ssl_sni,lower,map(${domainMappingFile})]-https + use_backend %[req.ssl_sni,lower,map_dom(${domainMappingFile})]-https ## Generated Backends: ${httpBackends} diff --git a/nixos-modules/nginx/default.nix b/nixos-modules/qois/nginx/default.nix similarity index 100% rename from nixos-modules/nginx/default.nix rename to nixos-modules/qois/nginx/default.nix diff --git a/nixos-modules/static-page/README.md b/nixos-modules/qois/static-page/README.md similarity index 87% rename from nixos-modules/static-page/README.md rename to nixos-modules/qois/static-page/README.md index 19469d9..3c3252b 100644 --- a/nixos-modules/static-page/README.md +++ b/nixos-modules/qois/static-page/README.md @@ -1,5 +1,6 @@ # Static Pages -This module enables static nginx sites, with data served from "/var/lib/nginx-$domain/root". +This module enables static nginx sites, with data served from "/var/lib/nginx/$domain/root". To deploy the site, a user `nginx-$domain` is added, of which a `root` profile in the home folder can be deployed, e.g. with deploy-rs. + diff --git a/nixos-modules/static-page/default-pages.nix b/nixos-modules/qois/static-page/default-pages.nix similarity index 66% rename from nixos-modules/static-page/default-pages.nix rename to nixos-modules/qois/static-page/default-pages.nix index 5a8b718..a89a947 100644 --- a/nixos-modules/static-page/default-pages.nix +++ b/nixos-modules/qois/static-page/default-pages.nix @@ -1,10 +1,12 @@ { + config, + pkgs, lib, ... }: { - qois.static-page.pages = lib.mkDefault { + qois.static-page.pages = { "fabianhauser.ch" = { domainAliases = [ "www.fabianhauser.ch" @@ -20,13 +22,5 @@ "docs-ops.qo.is".authorizedKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBS65v7n5ozOUjYGuO/dgLC9C5MUGL5kTnQnvWAYP5B3 ci@git.qo.is" ]; - "qo.is" = { - domainAliases = [ - "www.qo.is" - ]; - authorizedKeys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMG6xYcf7+l1RDPB7XcLxTvb6CqkaKqEGGb529Qk3b5T ci@git.qo.is" - ]; - }; }; } diff --git a/nixos-modules/static-page/default.nix b/nixos-modules/qois/static-page/default.nix similarity index 93% rename from nixos-modules/static-page/default.nix rename to nixos-modules/qois/static-page/default.nix index 6fb12ef..8ee20a0 100644 --- a/nixos-modules/static-page/default.nix +++ b/nixos-modules/qois/static-page/default.nix @@ -1,5 +1,6 @@ { config, + pkgs, lib, ... }: @@ -53,7 +54,7 @@ with lib; config = mkIf cfg.enable ( let pageConfigs = concatMapAttrs ( - _name: page: + name: page: let home = "/var/lib/nginx-${page.domain}"; in @@ -76,7 +77,7 @@ with lib; users = { groups = concatMapAttrs ( - _name: + name: { user, ... }: { "${user}" = { }; @@ -84,10 +85,10 @@ with lib; ) pageConfigs; users = { - ${config.services.nginx.user}.extraGroups = mapAttrsToList (_domain: getAttr "user") pageConfigs; + ${config.services.nginx.user}.extraGroups = mapAttrsToList (domain: getAttr "user") pageConfigs; } // (concatMapAttrs ( - _name: + name: { user, home, @@ -134,10 +135,10 @@ with lib; globalRedirect = domain; }; }); - aliasVhosts = concatMapAttrs (_name: mkAliasVhost) pageConfigs; + aliasVhosts = concatMapAttrs (name: mkAliasVhost) pageConfigs; in - aliasVhosts // (mapAttrs (_name: mkVhost) pageConfigs); + aliasVhosts // (mapAttrs (name: mkVhost) pageConfigs); }; } ); diff --git a/nixos-modules/vpn-exit-node/default.nix b/nixos-modules/qois/vpn-exit-node/default.nix similarity index 99% rename from nixos-modules/vpn-exit-node/default.nix rename to nixos-modules/qois/vpn-exit-node/default.nix index 75e6c03..aff1a84 100644 --- a/nixos-modules/vpn-exit-node/default.nix +++ b/nixos-modules/qois/vpn-exit-node/default.nix @@ -1,5 +1,6 @@ { config, + pkgs, lib, ... }: diff --git a/nixos-modules/vpn-server/default.nix b/nixos-modules/qois/vpn-server/default.nix similarity index 97% rename from nixos-modules/vpn-server/default.nix rename to nixos-modules/qois/vpn-server/default.nix index 39361a9..d813532 100644 --- a/nixos-modules/vpn-server/default.nix +++ b/nixos-modules/qois/vpn-server/default.nix @@ -10,7 +10,7 @@ let cfgLoadbalancer = config.qois.loadbalancer; defaultDnsRecords = (mapAttrs ( - _name: value: mkIf (cfgLoadbalancer.hostmap ? ${value}) cfgLoadbalancer.hostmap.${value} + name: value: mkIf (cfgLoadbalancer.hostmap ? ${value}) cfgLoadbalancer.hostmap.${value} ) cfgLoadbalancer.domains) // { "vpn.qo.is" = config.services.headscale.address; diff --git a/nixos-modules/renovate/default.nix b/nixos-modules/renovate/default.nix deleted file mode 100644 index 3eaeffb..0000000 --- a/nixos-modules/renovate/default.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - config, - pkgs, - lib, - inputs, - ... -}: -with lib; -let - cfg = config.qois.renovate; -in -{ - - options.qois.renovate = { - enable = mkEnableOption "Enable renovate service"; - gitServer = mkOption { - description = "Gitea/Forgejo server that should be accessed"; - type = types.str; - default = "git.qo.is"; - }; - gitAuthor = mkOption { - description = "Author of commit messages"; - type = types.str; - default = "Renovate Bot "; - }; - }; - - config = mkIf cfg.enable { - sops.secrets."renovate/token".restartUnits = [ "renovate.service" ]; - sops.secrets."renovate/host_rules".restartUnits = [ "renovate.service" ]; - systemd.services.renovate.environment.LOG_LEVEL = "debug"; - services.renovate = { - enable = true; - credentials = { - RENOVATE_TOKEN = config.sops.secrets."renovate/token".path; - RENOVATE_HOST_RULES = config.sops.secrets."renovate/host_rules".path; - }; - runtimePackages = with pkgs; [ - nix - ]; - settings = { - inherit (cfg) gitAuthor; - endpoint = "https://${cfg.gitServer}/api/v1"; - platform = "gitea"; - autodiscover = true; - optimizeForDisabled = true; - }; - schedule = "*:0/10"; - }; - - systemd.services.renovate = { - path = mkBefore [ inputs.pkgs.nixVersions.latest ]; # Circumvent submodule bug - remove after >=2.26 is the default. - script = mkBefore '' - echo -e "machine ${cfg.gitServer}\n login $(systemd-creds cat 'SECRET-RENOVATE_TOKEN')\n password x-oauth-basic" > ~/.netrc - ''; - }; - }; -} diff --git a/nixos-modules/router-dhcp/default.nix b/nixos-modules/router-dhcp/default.nix index c59db06..34d3b54 100644 --- a/nixos-modules/router-dhcp/default.nix +++ b/nixos-modules/router-dhcp/default.nix @@ -1,17 +1,18 @@ { config, lib, + pkgs, ... }: with lib; let - routerCfg = config.qois.router; - cfg = config.qois.router.dhcp; + routerCfg = config.services.qois.router; + cfg = config.services.qois.router.dhcp; in { - options.qois.router.dhcp = { + options.services.qois.router.dhcp = { enable = mkEnableOption "router dhcp service"; localDomain = mkOption { diff --git a/nixos-modules/router-dns/default.nix b/nixos-modules/router-dns/default.nix index 1d0d462..f1c13fc 100644 --- a/nixos-modules/router-dns/default.nix +++ b/nixos-modules/router-dns/default.nix @@ -1,18 +1,19 @@ { config, lib, + pkgs, ... }: with lib; let - routerCfg = config.qois.router; - dhcpCfg = config.qois.router.dhcp; - cfg = config.qois.router.recursiveDns; + routerCfg = config.services.qois.router; + dhcpCfg = config.services.qois.router.dhcp; + cfg = config.services.qois.router.recursiveDns; in { - options.qois.router.recursiveDns = { + options.services.qois.router.recursiveDns = { enable = mkEnableOption "router recursive dns service"; networkIdIp = mkOption { diff --git a/nixos-modules/router-wireless-ap/default.nix b/nixos-modules/router-wireless-ap/default.nix index da40979..6c31b77 100644 --- a/nixos-modules/router-wireless-ap/default.nix +++ b/nixos-modules/router-wireless-ap/default.nix @@ -1,16 +1,18 @@ { config, lib, + pkgs, ... }: with lib; let - cfg = config.qois.router.wireless; + routerCfg = config.services.qois.router; + cfg = config.services.qois.router.wireless; in { - options.qois.router.wireless = { + options.services.qois.router.wireless = { enable = mkEnableOption "router wireless service"; wleInterface24Ghz = mkOption { diff --git a/nixos-modules/router/README.md b/nixos-modules/router/README.md index 5944b45..b4a000f 100644 --- a/nixos-modules/router/README.md +++ b/nixos-modules/router/README.md @@ -1,4 +1,4 @@ -# Router Role {#\_router_role} +# Router Role {#_router_role} The `router` role set is applied on hosts which serve the rule of a SOHO router. diff --git a/nixos-modules/router/default.nix b/nixos-modules/router/default.nix index f77f8b0..c6bd125 100644 --- a/nixos-modules/router/default.nix +++ b/nixos-modules/router/default.nix @@ -1,16 +1,17 @@ { config, lib, + pkgs, ... }: with lib; let - cfg = config.qois.router; + cfg = config.services.qois.router; in { - options.qois.router = { + options.services.qois.router = { enable = mkEnableOption "router service"; wanInterface = mkOption { @@ -50,7 +51,7 @@ in type = types.str; example = "192.168.0.1"; description = '' - Internal IP of router. + Internal IP of router. ''; }; diff --git a/nixos-modules/static-page/test.nix b/nixos-modules/static-page/test.nix deleted file mode 100644 index 6c2f223..0000000 --- a/nixos-modules/static-page/test.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - ... -}: -{ - # Note: This extends the default configuration from ${self}/checks/nixos-modules - nodes.webserver = - { pkgs, lib, ... }: - let - inherit (pkgs) curl gnugrep; - inherit (lib) mkForce genAttrs const; - in - { - # Setup simple docs.example.com page with an example.com redirect - qois.static-page = { - enable = true; - pages."docs.example.com".domainAliases = [ "example.com" ]; - }; - - # Disable TLS services - services.nginx.virtualHosts = genAttrs [ "docs.example.com" "example.com" ] (const { - forceSSL = mkForce false; - enableACME = mkForce false; - }); - - # Test environment - environment.systemPackages = [ - curl - gnugrep - ]; - }; -} diff --git a/nixos-modules/static-page/test.py b/nixos-modules/static-page/test.py deleted file mode 100644 index 295635f..0000000 --- a/nixos-modules/static-page/test.py +++ /dev/null @@ -1,49 +0,0 @@ -def test(subtest, webserver): - webserver.wait_for_unit("nginx") - webserver.wait_for_open_port(80) - - # Preparations - webserverRoot = "/var/lib/nginx-docs.example.com/root" - indexContent = "It works!" - webserver.succeed(f"mkdir {webserverRoot}") - webserver.succeed(f"echo '{indexContent}' > {webserverRoot}/index.html") - webserver.succeed(f"chown -R nginx-docs.example.com\: {webserverRoot}") - - # Helpers - def curl_variable_test(node, variable, expected, url): - value = node.succeed( - f"curl -s --no-location -o /dev/null -w '%{{{variable}}}' '{url}'" - ) - assert value == expected, ( - f"expected {variable} to be '{expected}' but got '{value}'" - ) - - def expect_http_code(node, code, url): - curl_variable_test(node, "http_code", code, url) - - def expect_http_location(node, location, url): - curl_variable_test(node, "redirect_url", location, url) - - def expect_http_content(node, expectedContent, url): - content = node.succeed(f"curl --no-location --silent '{url}'") - assert content.strip() == expectedContent.strip(), f""" - expected content: - {expectedContent} - at {url} but got following content: - {content} - """ - - # Tests - with subtest("website is successfully served on docs.example.com"): - webserver.succeed("grep docs.example.com /etc/hosts") - expect_http_code(webserver, "200", "http://docs.example.com/index.html") - expect_http_content( - webserver, indexContent, "http://docs.example.com/index.html" - ) - - with subtest("example.com is a redirect to docs.example.com"): - webserver.succeed("grep -e '[^\.]example.com' /etc/hosts") - - url = "http://example.com/index.html" - expect_http_code(webserver, "301", url) - expect_http_location(webserver, "http://docs.example.com/index.html", url) diff --git a/nixos-modules/system/overlays.nix b/nixos-modules/system/overlays.nix deleted file mode 100644 index bb6ec19..0000000 --- a/nixos-modules/system/overlays.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ - options, - ... -}: - -{ - nix.nixPath = options.nix.nixPath.default; -} diff --git a/nixos-modules/system/physical.nix b/nixos-modules/system/physical.nix deleted file mode 100644 index 2597bde..0000000 --- a/nixos-modules/system/physical.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ - config, - lib, - pkgs, - ... -}: -let - cfg = config.qois.system.physical; -in -with lib; -{ - options.qois.system.physical.enable = mkEnableOption "Enable qois physical system configuration"; - - config = lib.mkIf cfg.enable { - environment.systemPackages = - with pkgs; - [ - pciutils - dmidecode - smartmontools - iw - efibootmgr - efitools - efivar - pwgen - powertop - lm_sensors - ] - ++ [ - # Filesystem & Disk Utilities - hdparm - smartmontools - ] - ++ [ - # Networking Utilities - tcpdump - ]; - - # System Services - services.fwupd.enable = true; - - services.smartd = { - enable = true; - notifications.mail = { - enable = true; - mailer = "${pkgs.msmtp}/bin/sendmail"; - sender = "system@qo.is"; - recipient = "sysadmin@qo.is"; - }; - }; - }; -} diff --git a/nixos-modules/system/virtual-machine.nix b/nixos-modules/system/virtual-machine.nix deleted file mode 100644 index 5e5a8ae..0000000 --- a/nixos-modules/system/virtual-machine.nix +++ /dev/null @@ -1,58 +0,0 @@ -{ - config, - lib, - ... -}: -let - cfg = config.qois.system.virtual-machine; -in -with lib; -{ - options.qois.system.virtual-machine.enable = - mkEnableOption "Enable qois system vm default configuration"; - - config = lib.mkIf cfg.enable { - - boot.loader.grub.enable = true; - - system.autoUpgrade.allowReboot = true; - - services.qemuGuest.enable = true; - - boot.initrd.availableKernelModules = - [ - "ahci" - "xhci_pci" - "sr_mod" - ] - ++ - # Taken from https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/qemu-guest.nix - [ - "virtio_net" - "virtio_pci" - "virtio_mmio" - "virtio_blk" - "virtio_scsi" - "9p" - "9pnet_virtio" - ]; - boot.initrd.kernelModules = [ - "virtio_balloon" - "virtio_console" - "virtio_rng" - "virtio_gpu" - ]; - - # Taken from https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/minimal.nix - documentation.enable = lib.mkDefault false; - - documentation.doc.enable = lib.mkDefault false; - - documentation.info.enable = lib.mkDefault false; - - documentation.man.enable = lib.mkDefault false; - - documentation.nixos.enable = lib.mkDefault false; - - }; -} diff --git a/nixos-modules/vault/README.md b/nixos-modules/vault/README.md index 80a04f2..337b152 100644 --- a/nixos-modules/vault/README.md +++ b/nixos-modules/vault/README.md @@ -3,7 +3,7 @@ To use our Vaultwarden instance, you can use the regular [Bitwarden apps](https://bitwarden.com/download/) with our custom server when logging in: -Username: `first.lastname@qo.is`\ +Username: `first.lastname@qo.is` Server Name: `https://vault.qo.is` ## Create Accounts @@ -17,6 +17,7 @@ Please instruct users to: - the password cannot be reset without loosing all the passwords. Use of [Emergency Contacts](https://bitwarden.com/help/emergency-access/) or Organizations may be advisable. + ## Administration An admin panel is available under [vault.qo.is/admin](https://vault.qo.is/admin). @@ -25,10 +26,12 @@ The password is saved in the pass database under `vaultwarden-admin`. In the administration panel, users and organizations may be managed. Instance settings should be changed with the nixos module in the infrastructure repository only. + ## Backup / Restore 1. `systemctl stop vaultwarden.service` -1. Import Postgresql Database Backup -1. Restore `/var/lib/bitwarden_rs` -1. `systemctl start vaultwarden.service` -1. Click `Force clients to resync` in the [Administration interface under _Users_](https://vault.qo.is/admin/users/overview) +2. Import Postgresql Database Backup +3. Restore `/var/lib/bitwarden_rs` +4. `systemctl start vaultwarden.service` +5. Click `Force clients to resync` in the [Administration interface under _Users_](https://vault.qo.is/admin/users/overview) + diff --git a/nixos-modules/vault/default.nix b/nixos-modules/vault/default.nix index 0171b45..36332af 100644 --- a/nixos-modules/vault/default.nix +++ b/nixos-modules/vault/default.nix @@ -34,8 +34,6 @@ with lib; ROCKET_PORT = 8222; USE_SENDMAIL = true; - SENDMAIL_COMMAND = "${pkgs.msmtp}/bin/sendmail"; - SMTP_FROM = "vault@qo.is"; SMTP_FROM_NAME = cfg.domain; @@ -70,6 +68,7 @@ with lib; # See https://search.nixos.org/options?channel=unstable&show=services.vaultwarden.environmentFile sops.secrets."vaultwarden/environment-file".restartUnits = [ "vaultwarden.service" ]; + systemd.services.vaultwarden.path = [ pkgs.msmtp ]; users.users.vaultwarden.extraGroups = [ "postdrop" ]; networking.hosts."127.0.0.1" = [ cfg.domain ]; diff --git a/nixos-modules/vpn-server/README.md b/nixos-modules/vpn-server/README.md deleted file mode 100644 index d45c005..0000000 --- a/nixos-modules/vpn-server/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# VPN - -We run a [Tailscale](https://tailscale.com) compatible VPN service on [vpn.qo.is](https://vpn.qo.is). - -## User and Client Management - -To register a new client on the `vpn.qo.is` host:, generate a pre-auth key and insert it in the client: - -```bash -headscale users create marlene.mayer -headscale preauthkeys create --user marlene.mayer -``` - -> ⚠️ For now, the username must be added to `qois.vpn-server.wheelUsers`. -> In the future, the VPN ACL might get more granular to allow for non-wheel users. - -Alternatively to using a pre-auth key, the register command shown when configuring the VPN client may be used. - -## ACL - -At this time, there are a few ACL rules to isolate a users host but do not expect them to be expected to be enforced - expect your client to be accessible by the whole network. - -## Exit Nodes - -These nodes allow access to the internet for clients connected to the VPN: - -- `100.64.0.5`: lindberg (riedbach-net) -- `100.64.0.6`: cyprianspitz (plessur-net) - -> ⚠️ Currently, name resolution for these do not work reliably on first starts, hence the IP must be used. This hould be fixed in the future. - -### Add exit nodes: - -1. Create a preauth secret on the `vpn.qo.is` host: - ```bash - headscale preauthkeys create --user srv --reusable - ``` -1. Configure the new exit-node host with the `qois.vpn-exit-node` module. - -When using the `srv` user, exit nodes and routes are automatically accepted as trusted. - -## Clients - -To use the service, you can use a normal Tailscale client with following additional configuration: - -| Option | Recommended value | Description | -|--------|-------------------|-------------| -| `accept-routes` | enabled (flag) | Accept direct routes to internal services | -| `exit-node` | `100.64.0.5` (lindberg) or `100.64.0.6` (cypriaspitz) | Use host as [exit node](#exit-nodes) | -| `login-server` | `https://vpn.qo.is` | Use our own VPN service. | - -> ⚠️ Currently, if the client is in an IPv6 network, the transport is broken. -> Disable IPv6 connectivity to use the VPN. -> See [#4](https://git.qo.is/qo.is/infrastructure/issues/4) for details. - -### NixOS - -Sample config with automatic connectivity to VPN on boot: - -```nix -{ config, pkgs, ... }: { - services.tailscale = { - enable = true; - openFirewall = true; - useRoutingFeatures = "client"; - authKeyFile = "/secrets/wireguard/tailscale-key"; # This is the pre-auth secret. Make sure it's only accessible by root. - extraUpFlags = [ - "--operator" - "yourUserNameChangePlease" - "--accept-routes" - "--exit-node=100.64.0.5" - "--login-server=https://vpn.qo.is" - ]; - }; -} -``` - -### Android - -See [this Headscale documentation for more](https://headscale.net/stable/usage/connect/android/) on how to configure the mobile app. - -> ⚠️ Note that on restarts, sometimes you have to reopen/save the config dialog. -> If the Tailscale login site is shown, just close the browser with the ❌. - -## Backup and Restore - -### Server - -1. `systemctl stop headscale` -1. Replace `/var/lib/headscale` -1. `systemctl start headscale` -1. Monitor logs for errors - -Note: `/var/lib/headscale` contains a sqlite database. - -### Clients - -1. `systemctl stop tailscaled` -1. Replace `/var/lib/tailscale` -1. `systemctl start tailscaled` -1. Monitor logs for errors diff --git a/nixos-modules/wwan/README.md b/nixos-modules/wwan/README.md index 8e486bb..655a021 100644 --- a/nixos-modules/wwan/README.md +++ b/nixos-modules/wwan/README.md @@ -1,8 +1,8 @@ -# WWAN Module {#\_wwan_module} +# WWAN Module {#_wwan_module} This module configures WWAN adapters that support MBIM -## Current limitations {#\_current_limitations} +## Current limitations {#_current_limitations} - IPv4 tested only - Currently, it is not simple to get network failures or address diff --git a/nixos-modules/wwan/default.nix b/nixos-modules/wwan/default.nix index 7719eeb..54b9555 100644 --- a/nixos-modules/wwan/default.nix +++ b/nixos-modules/wwan/default.nix @@ -10,7 +10,7 @@ with lib; let - cfg = config.qois.wwan; + cfg = config.services.qois.wwan; mbim-ip-configured = pkgs.writeScriptBin "mbim-ip-configured" ( '' @@ -34,7 +34,7 @@ let ''; in { - options.qois.wwan = { + options.services.qois.wwan = { enable = mkEnableOption "wwan client service"; apn = mkOption { diff --git a/nixos-modules/wwan/mbim-ip.bash b/nixos-modules/wwan/mbim-ip.bash index 1189b46..fafc841 100644 --- a/nixos-modules/wwan/mbim-ip.bash +++ b/nixos-modules/wwan/mbim-ip.bash @@ -6,11 +6,11 @@ MODE=$1 DEV=$2 if [ "$DEBUG" == "" ]; then - DEBUG="false" + DEBUG="false" fi if [ "$MBIM_INTERFACE" == "" ]; then - MBIM_INTERFACE="/dev/cdc-wdm0" + MBIM_INTERFACE="/dev/cdc-wdm0" fi ############################################################################### @@ -29,273 +29,274 @@ ipv6_dns=() ipv6_mtu="" export previous_state state skip_line \ - ipv4_addresses ipv4_gateway ipv4_dns ipv4_mtu \ - ipv6_addresses ipv6_gateway ipv6_dns ipv6_mtu + ipv4_addresses ipv4_gateway ipv4_dns ipv4_mtu \ + ipv6_addresses ipv6_gateway ipv6_dns ipv6_mtu ############################################################################### # Function ############################################################################### function print_debug { - if [ "$DEBUG" != "false" ]; then - echo "[State: $state] $1" >&2 - fi + if [ "$DEBUG" != "false" ]; then + echo "[State: $state] $1" >&2 + fi } function print_full_configuration { - if [[ ${#ipv4_addresses[@]} > 0 ]]; then - printf "IPv4: " - printf '%s, ' "${ipv4_addresses[@]}" - printf "\n" + if [[ "${#ipv4_addresses[@]}" > 0 ]]; then + printf "IPv4: " + printf '%s, ' "${ipv4_addresses[@]}" + printf "\n" - printf "GW: $ipv4_gateway\n" + printf "GW: $ipv4_gateway\n" - printf "DNS: " - printf '%s, ' "${ipv4_dns[@]}" - printf "\n" + printf "DNS: " + printf '%s, ' "${ipv4_dns[@]}" + printf "\n" - printf "MTU: $ipv4_mtu\n" - fi + printf "MTU: $ipv4_mtu\n" + fi - if [[ ${#ipv6_addresses[@]} > 0 ]]; then - echo - printf "IPv6: " - printf '%s, ' "${ipv6_addresses[@]}" - printf "\n" + if [[ "${#ipv6_addresses[@]}" > 0 ]]; then + echo + printf "IPv6: " + printf '%s, ' "${ipv6_addresses[@]}" + printf "\n" - printf "GW: $ipv6_gateway\n" + printf "GW: $ipv6_gateway\n" - printf "DNS: " - printf '%s, ' "${ipv6_dns[@]}" - printf "\n" + printf "DNS: " + printf '%s, ' "${ipv6_dns[@]}" + printf "\n" - printf "MTU: $ipv6_mtu\n" - fi + printf "MTU: $ipv6_mtu\n" + fi } function next_state { - previous_state="$state" - state="$1" + previous_state="$state" + state="$1" } function parse_ip { - # IP [0]: '10.134.203.177/30' - local line_re="IP \[([0-9]+)\]: '(.+)'" - local input=$1 - if [[ $input =~ $line_re ]]; then - local ip_cnt=${BASH_REMATCH[1]} - local ip=${BASH_REMATCH[2]} - fi - echo "$ip" + # IP [0]: '10.134.203.177/30' + local line_re="IP \[([0-9]+)\]: '(.+)'" + local input=$1 + if [[ $input =~ $line_re ]]; then + local ip_cnt=${BASH_REMATCH[1]} + local ip=${BASH_REMATCH[2]} + fi + echo "$ip" } function parse_dns { - # IP [0]: '10.134.203.177/30' - local line_re="DNS \[([0-9]+)\]: '(.+)'" - local input=$1 - if [[ $input =~ $line_re ]]; then - local dns_cnt=${BASH_REMATCH[1]} - local dns=${BASH_REMATCH[2]} - fi - echo "$dns" + # IP [0]: '10.134.203.177/30' + local line_re="DNS \[([0-9]+)\]: '(.+)'" + local input=$1 + if [[ $input =~ $line_re ]]; then + local dns_cnt=${BASH_REMATCH[1]} + local dns=${BASH_REMATCH[2]} + fi + echo "$dns" } function parse_gateway { - # Gateway: '10.134.203.178' - local line_re="Gateway: '(.+)'" - local input=$1 - if [[ $input =~ $line_re ]]; then - local gw=${BASH_REMATCH[1]} - fi - echo "$gw" + # Gateway: '10.134.203.178' + local line_re="Gateway: '(.+)'" + local input=$1 + if [[ $input =~ $line_re ]]; then + local gw=${BASH_REMATCH[1]} + fi + echo "$gw" } function parse_mtu { - # MTU: '1500' - local line_re="MTU: '([0-9]+)'" - local input=$1 - if [[ $input =~ $line_re ]]; then - local mtu=${BASH_REMATCH[1]} - fi - echo "$mtu" + # MTU: '1500' + local line_re="MTU: '([0-9]+)'" + local input=$1 + if [[ $input =~ $line_re ]]; then + local mtu=${BASH_REMATCH[1]} + fi + echo "$mtu" } function parse_input_state_machine { - state="start" - while true; do - if [[ $skip_line == 0 ]]; then - read line || break # TODO: Clean up - else - skip_line=0 - fi - case "$state" in - "start") - read line || break # first line is empty, read a new one #TODO: This is not very clean... - case "$line" in - *"configuration available: 'none'"*) - # Skip none state - # TODO: This is a workaround of the original parser's shortcomming - continue - ;; - *"IPv4 configuration available"*) - next_state "ipv4_ip" - continue - ;; - *"IPv6 configuration available"*) - next_state "ipv6_ip" - continue - ;; - *) - next_state "exit" - continue - ;; - esac - ;; - "error") - echo "Error in pattern matchin of state $previous_state. Exiting." >&2 - exit 2 - ;; - "exit") - break - ;; - "ipv4_ip") - ipv4=$(parse_ip "$line") - if [ -z "$ipv4" ]; then - if [[ ${#ipv4_addresses[@]} < 1 ]]; then - next_state "error" - continue - else - next_state "ipv4_gateway" - skip_line=1 - continue - fi - fi - print_debug "$ipv4" - ipv4_addresses+=("$ipv4") - ;; - "ipv4_gateway") - gw=$(parse_gateway "$line") - if [ -z "$gw" ]; then - next_state "error" - continue - fi - print_debug "$gw" - ipv4_gateway="$gw" - next_state "ipv4_dns" - ;; - "ipv4_dns") - ipv4=$(parse_dns "$line") - if [ -z "$ipv4" ]; then - if [[ ${#ipv4_dns[@]} < 1 ]]; then - next_state "error" - continue - else - next_state "ipv4_mtu" - skip_line=1 - continue - fi - fi - print_debug "$ipv4" - ipv4_dns+=("$ipv4") - ;; - "ipv4_mtu") - mtu=$(parse_mtu "$line") - if [ -z "$mtu" ]; then - next_state "error" - continue - fi - print_debug "$mtu" - ipv4_mtu="$mtu" - next_state "start" - ;; - "ipv6_ip") - ipv6=$(parse_ip "$line") - if [ -z "$ipv6" ]; then - if [[ ${#ipv6_addresses[@]} < 1 ]]; then - next_state "error" - continue - else - next_state "ipv6_gateway" - skip_line=1 - continue - fi - fi - print_debug "$ipv6" - ipv6_addresses+=("$ipv6") - ;; - "ipv6_gateway") - gw=$(parse_gateway "$line") - if [ -z "$gw" ]; then - next_state "error" - continue - fi - print_debug "$gw" - ipv6_gateway="$gw" - next_state "ipv6_dns" - ;; - "ipv6_dns") - ipv6=$(parse_dns "$line") - if [ -z "$ipv6" ]; then - if [[ ${#ipv6_dns[@]} < 1 ]]; then - next_state "error" - continue - else - next_state "ipv6_mtu" - skip_line=1 - continue - fi - fi - print_debug "$ipv6" - ipv6_dns+=("$ipv6") - ;; - "ipv6_mtu") - mtu=$(parse_mtu "$line") - if [ -z "$mtu" ]; then - next_state "error" - continue - fi - print_debug "$mtu" - ipv6_mtu="$mtu" - next_state "start" - ;; - *) - print_debug "Invalid state (came from $previous_state). Exiting." - exit 0 - ;; - esac - done + state="start" + while true; do + if [[ "$skip_line" == 0 ]]; then + read line || break # TODO: Clean up + else + skip_line=0 + fi + case "$state" in + "start") + read line || break # first line is empty, read a new one #TODO: This is not very clean... + case "$line" in + *"configuration available: 'none'"*) + # Skip none state + # TODO: This is a workaround of the original parser's shortcomming + continue + ;; + *"IPv4 configuration available"*) + next_state "ipv4_ip" + continue + ;; + *"IPv6 configuration available"*) + next_state "ipv6_ip" + continue + ;; + *) + next_state "exit" + continue + ;; + esac + ;; + "error") + echo "Error in pattern matchin of state $previous_state. Exiting." >&2 + exit 2 + ;; + "exit") + break + ;; + "ipv4_ip") + ipv4=$(parse_ip "$line") + if [ -z "$ipv4" ]; then + if [[ "${#ipv4_addresses[@]}" < 1 ]]; then + next_state "error" + continue + else + next_state "ipv4_gateway" + skip_line=1 + continue + fi + fi + print_debug "$ipv4" + ipv4_addresses+=("$ipv4") + ;; + "ipv4_gateway") + gw=$(parse_gateway "$line") + if [ -z "$gw" ]; then + next_state "error" + continue + fi + print_debug "$gw" + ipv4_gateway="$gw" + next_state "ipv4_dns" + ;; + "ipv4_dns") + ipv4=$(parse_dns "$line") + if [ -z "$ipv4" ]; then + if [[ "${#ipv4_dns[@]}" < 1 ]]; then + next_state "error" + continue + else + next_state "ipv4_mtu" + skip_line=1 + continue + fi + fi + print_debug "$ipv4" + ipv4_dns+=("$ipv4") + ;; + "ipv4_mtu") + mtu=$(parse_mtu "$line") + if [ -z "$mtu" ]; then + next_state "error" + continue + fi + print_debug "$mtu" + ipv4_mtu="$mtu" + next_state "start" + ;; + "ipv6_ip") + ipv6=$(parse_ip "$line") + if [ -z "$ipv6" ]; then + if [[ "${#ipv6_addresses[@]}" < 1 ]]; then + next_state "error" + continue + else + next_state "ipv6_gateway" + skip_line=1 + continue + fi + fi + print_debug "$ipv6" + ipv6_addresses+=("$ipv6") + ;; + "ipv6_gateway") + gw=$(parse_gateway "$line") + if [ -z "$gw" ]; then + next_state "error" + continue + fi + print_debug "$gw" + ipv6_gateway="$gw" + next_state "ipv6_dns" + ;; + "ipv6_dns") + ipv6=$(parse_dns "$line") + if [ -z "$ipv6" ]; then + if [[ "${#ipv6_dns[@]}" < 1 ]]; then + next_state "error" + continue + else + next_state "ipv6_mtu" + skip_line=1 + continue + fi + fi + print_debug "$ipv6" + ipv6_dns+=("$ipv6") + ;; + "ipv6_mtu") + mtu=$(parse_mtu "$line") + if [ -z "$mtu" ]; then + next_state "error" + continue + fi + print_debug "$mtu" + ipv6_mtu="$mtu" + next_state "start" + ;; + *) + print_debug "Invalid state (came from $previous_state). Exiting." + exit 0 + ;; + esac + done } -interface_stop() { - ip addr flush dev $DEV - ip route flush dev $DEV - ip -6 addr flush dev $DEV - ip -6 route flush dev $DEV +interface_stop(){ + ip addr flush dev $DEV + ip route flush dev $DEV - #TODO: Nameserver? + ip -6 addr flush dev $DEV + ip -6 route flush dev $DEV + + #TODO: Nameserver? } interface_start() { - ip link set $DEV up + ip link set $DEV up - if [[ ${#ipv4_addresses[@]} > 0 ]]; then - ip addr add ${ipv4_addresses[@]} dev $DEV broadcast + #TODO: Works for multiple addresses? - ip link set $DEV mtu $ipv4_mtu - ip route add default via $ipv4_gateway dev $DEV - #TODO: nameserver ${ipv4_dns[@]} - else - echo "No IPv4 address, skipping v4 configuration..." - fi + if [[ "${#ipv4_addresses[@]}" > 0 ]]; then + ip addr add ${ipv4_addresses[@]} dev $DEV broadcast + #TODO: Works for multiple addresses? + ip link set $DEV mtu $ipv4_mtu + ip route add default via $ipv4_gateway dev $DEV + #TODO: nameserver ${ipv4_dns[@]} + else + echo "No IPv4 address, skipping v4 configuration..." + fi - if [[ ${#ipv6_addresses[@]} > 0 ]]; then - ip -6 addr add ${ipv6_addresses[@]} dev $DEV #TODO: Works for multiple addresses? - ip -6 route add default via $ipv6_gateway dev $DEV - ip -6 link set $DEV mtu $ipv6_mtu - #TODO: nameserver ${ipv6_dns[@]}" - else - echo "No IPv6 address, skipping v6 configuration..." - fi + if [[ "${#ipv6_addresses[@]}" > 0 ]]; then + ip -6 addr add ${ipv6_addresses[@]} dev $DEV #TODO: Works for multiple addresses? + ip -6 route add default via $ipv6_gateway dev $DEV + ip -6 link set $DEV mtu $ipv6_mtu + #TODO: nameserver ${ipv6_dns[@]}" + else + echo "No IPv6 address, skipping v6 configuration..." + fi } ############################################################################### @@ -306,23 +307,23 @@ set -e echo "NOTE: This script does not yet support nameserver configuration." case "$MODE" in -"start") - mbim-network $MBIM_INTERFACE start - sleep 1 - mbimcli -d $MBIM_INTERFACE -p --query-ip-configuration=0 | { - parse_input_state_machine - print_full_configuration - interface_stop - interface_start - } - ;; -"stop") - mbim-network $MBIM_INTERFACE stop - interface_stop - ;; -*) - echo "USAGE: $0 start|stop INTERFACE" >&2 - echo "You can set an env variable DEBUG to gather debugging output." >&2 - exit 1 - ;; + "start") + mbim-network $MBIM_INTERFACE start + sleep 1 + mbimcli -d $MBIM_INTERFACE -p --query-ip-configuration=0 | { + parse_input_state_machine + print_full_configuration + interface_stop + interface_start + } + ;; + "stop") + mbim-network $MBIM_INTERFACE stop + interface_stop + ;; + *) + echo "USAGE: $0 start|stop INTERFACE" >&2 + echo "You can set an env variable DEBUG to gather debugging output." >&2 + exit 1 + ;; esac diff --git a/overlays/default.nix b/overlays/default.nix new file mode 100644 index 0000000..430b766 --- /dev/null +++ b/overlays/default.nix @@ -0,0 +1,5 @@ +self: super: { + lib = (super.lib or { }) // { + qois = import ../lib { lib = self.lib; }; + }; +} diff --git a/packages/auto-deploy/default.nix b/packages/auto-deploy/default.nix deleted file mode 100644 index 3c266a7..0000000 --- a/packages/auto-deploy/default.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - deploy-rs, - gitMinimal, - writeShellApplication, - lib, - ... -}: -writeShellApplication { - name = "auto-deploy"; - meta.description = "Deploy machines automatically."; - runtimeInputs = [ - deploy-rs - gitMinimal - ]; - text = lib.readFile ./script.bash; -} diff --git a/packages/auto-deploy/script.bash b/packages/auto-deploy/script.bash deleted file mode 100644 index e7d6324..0000000 --- a/packages/auto-deploy/script.bash +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -#### Environment -FLAKE_ROOT="$(git rev-parse --show-toplevel)" - -export PROFILE="${1:-}" -if [ -z "${PROFILE}" ]; then - echo "🛑 Error: No deployment profile was specified as first parameter (e.g. \"${0} system-vm\")" 1>&2 - exit 1 -fi - -if [ -z "${SSH_DEPLOY_KEY:-}" ]; then - echo "ℹ️ Info: SSH_DEPLOY_KEY env variable was not set, ignoring." - SSH_KEY_FILE_ARG="" -else - TEMP_KEY_FILE=$(mktemp /dev/shm/ssh_deploy_key.XXXXXXXX) - touch "${TEMP_KEY_FILE}" && chmod 600 "${TEMP_KEY_FILE}" - printf "%s\n" "${SSH_DEPLOY_KEY}" >"${TEMP_KEY_FILE}" - SSH_KEY_FILE_ARG="-i ${TEMP_KEY_FILE}" - - # Set up a trap to remove the temporary key file on script exit - trap 'rm -f "${TEMP_KEY_FILE}"' EXIT - trap 'rm -f "${TEMP_KEY_FILE}"' SIGINT - trap 'rm -f "${TEMP_KEY_FILE}"' SIGTERM - trap 'rm -f "${TEMP_KEY_FILE}"' SIGQUIT -fi - -HOSTS=$(nix eval --raw "${FLAKE_ROOT}"#deploy.nodes --apply " - nodes: let - inherit (builtins) attrNames filter concatStringsSep; - names = attrNames nodes; - profile = \"${PROFILE}\"; - filteredNames = filter (name: nodes.\${name}.profiles ? \${profile}) names; - in concatStringsSep \"\\n\" filteredNames -") -if [ -z "$HOSTS" ]; then - echo "🛑 Error: No deployments matching the profile ${PROFILE} were found." 1>&2 - exit 1 -fi - -KNOWN_HOSTS_FILE=$(nix build --no-link --print-out-paths .#nixosConfigurations.lindberg.config.environment.etc."ssh/ssh_known_hosts".source) - -#### Helpers -retry() { - local -r -i max_attempts="$1" - shift - local -i attempt_num=1 - until "$@"; do - if ((attempt_num == max_attempts)); then - echo "🛑 Error: Attempt $attempt_num failed and there are no more attempts left!" 1>&2 - return 1 - else - echo "⚠️ Attempt $attempt_num failed! Trying again in $attempt_num seconds..." - sleep $((attempt_num++)) - fi - done -} - -#### Execution -for HOST in $HOSTS; do - retry 3 deploy \ - --skip-checks \ - --ssh-opts "-o UserKnownHostsFile=${KNOWN_HOSTS_FILE} ${SSH_KEY_FILE_ARG:-}" \ - --targets "${FLAKE_ROOT}#\"${HOST}\".\"${PROFILE}\"" -done diff --git a/packages/cache/default.nix b/packages/cache/default.nix new file mode 100644 index 0000000..5a7c983 --- /dev/null +++ b/packages/cache/default.nix @@ -0,0 +1,42 @@ +{ + attic-client, + findutils, + gnugrep, + writeShellApplication, + ... +}: +writeShellApplication { + name = "cache"; + meta.description = "Access the infrastructure's attic cache. Mostly used in CI."; + runtimeInputs = [ + attic-client + findutils + gnugrep + ]; + text = '' + SERVER="https://attic.qo.is/" + CACHE_NAME="qois" + CACHE_REPO="$CACHE_NAME:qois-infrastructure" + if [ -z "$ATTIC_AUTH_TOKEN" ]; then + echo "Please set the \$ATTIC_AUTH_TOKEN environment variable to access the cache." + exit 3 + fi + attic login "$CACHE_NAME" "$SERVER" "$ATTIC_AUTH_TOKEN" + + case "$1" in + use) + attic use "$CACHE_REPO" + ;; + watch) + attic watch-store "$CACHE_REPO" + ;; + push) + RESULT_PATH="./result" + # Add build dependencies as well + nix-store -qR --include-outputs "$(nix-store -qd $RESULT_PATH)" | grep -v '\.drv$' \ + | xargs attic push "$CACHE_REPO" "$RESULT_PATH" + ;; + + esac + ''; +} diff --git a/packages/default.nix b/packages/default.nix index 1e991b9..c4dc1bf 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -1,28 +1,37 @@ { self, - flakeSelf, system, - private, pkgs, ... }: -let - inherit (self.lib) foldersWithNix; - inherit (pkgs.lib) - path - genAttrs - ; -in +with pkgs.lib; { - ${system} = genAttrs (foldersWithNix ./.) ( - name: - pkgs.callPackage (path.append ./. "./${name}/default.nix") { - inherit - self - flakeSelf - system - private - ; - } - ); + ${system} = + let + packages = pipe (self.lib.foldersWithNix ./.) [ + (map (name: { + inherit name; + path = path.append ./. "./${name}/default.nix"; + })) + (map ( + { name, path }: + { + inherit name; + value = pkgs.callPackage path { + inherit self; + inherit system; + }; + } + )) + listToAttrs + ]; + in + packages + // { + default = + let + nixosConfigs = mapAttrsToList (n: v: v.config.system.build.toplevel) self.nixosConfigurations; + in + pkgs.linkFarmFromDrvs "all" (nixosConfigs ++ (attrValues packages)); + }; } diff --git a/packages/deploy-qois/default.nix b/packages/deploy-qois/default.nix new file mode 100644 index 0000000..ee3f0ac --- /dev/null +++ b/packages/deploy-qois/default.nix @@ -0,0 +1,14 @@ +{ + deploy-rs, + self, + writeShellApplication, + ... +}: +writeShellApplication { + name = "deploy-qois"; + meta.description = "Deploy configuration to specificed targets."; + runtimeInputs = [ deploy-rs ]; + text = '' + deploy --interactive --targets "''${@:-${self}}" + ''; +} diff --git a/packages/docs/default.nix b/packages/docs/default.nix index 66f7dd9..f16736d 100644 --- a/packages/docs/default.nix +++ b/packages/docs/default.nix @@ -3,12 +3,12 @@ mdbook-plantuml, mdbook, plantuml, - flakeSelf, + self, stdenv, ... }: let - version = flakeSelf.rev or flakeSelf.dirtyRev; + version = self.rev or self.dirtyRev; in stdenv.mkDerivation { inherit version; @@ -19,6 +19,6 @@ stdenv.mkDerivation { mdbook-plantuml plantuml ]; - src = flakeSelf; + src = self; buildPhase = "mdbook build --dest-dir $out"; } diff --git a/packages/sops-config/default.nix b/packages/sops-config/default.nix index 74e5c79..1daf54a 100644 --- a/packages/sops-config/default.nix +++ b/packages/sops-config/default.nix @@ -3,7 +3,7 @@ gnupg, lib, runCommand, - private, + self, ssh-to-age, writeText, ... @@ -13,7 +13,7 @@ let metaHostConfigs = import ../../defaults/meta/hosts.nix { }; userPgpKeys = let - keysFolder = "${private}/sops_keys"; + keysFolder = "${self.inputs.private}/sops_keys"; gpgFingerprintsFile = runCommand "userPgpKeys" { @@ -41,9 +41,9 @@ let userAgeKeys = [ ]; serverAgeKeys = let - getHostsWithSshKeys = filterAttrs (_name: cfg: cfg ? sshKey); + getHostsWithSshKeys = filterAttrs (name: cfg: cfg ? sshKey); mapHostToAgeKey = mapAttrs ( - _name: cfg: + name: cfg: readFile ( runCommand "sshToAgeKey" { @@ -75,7 +75,7 @@ writeText ".sops.yaml" ( # Secrets for all hosts { - path_regex = "private/nixos-modules/shared-secrets/default\.sops\.(yaml|json|env|ini)$"; + path_regex = "private/nixos-configurations/secrets\.sops\.(yaml|json|env|ini)$"; pgp = toCommaList userPgpKeys; age = toCommaList (userAgeKeys ++ builtins.attrValues serverAgeKeys); } diff --git a/private b/private index 5f8ba20..90543f5 160000 --- a/private +++ b/private @@ -1 +1 @@ -Subproject commit 5f8ba2025848dd30539c42ef1f7e6c6f917e70d9 +Subproject commit 90543f538fc13c3d291196a9769483c6c51ac84d diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 10302dd..0000000 --- a/renovate.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "lockFileMaintenance": { - "enabled": true, - "automerge": true, - "automergeType": "branch", - "schedule": [ - "* 18-19 * * *" - ] - }, - "cloneSubmodules": true, - "nix": { - "enabled": true - } -} diff --git a/treefmt.nix b/treefmt.nix deleted file mode 100644 index 14412c6..0000000 --- a/treefmt.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ ... }: -{ - projectRootFile = "flake.nix"; - programs = { - nixfmt.enable = true; - deadnix.enable = true; - jsonfmt.enable = true; - yamlfmt.enable = true; - mdformat.enable = true; - ruff-check.enable = true; - ruff-format.enable = true; - shfmt.enable = true; - }; - settings = { - global.excludes = - [ - "*.jpg" - "*.pdf" - "*.toml" - ] - ++ [ - ".vscode/*" - "nixos-modules/system/etc/*" - "private" - "private/*" - - ".envrc" - "robots.txt" - ]; - formatter.jsonfmt.excludes = [ ".vscode/*.json" ]; - }; -} diff --git a/updates.md b/updates.md index f467e57..09373c1 100644 --- a/updates.md +++ b/updates.md @@ -16,20 +16,19 @@ git commit git push ``` -Deploy updates: +Deploy updates: ```bash nix develop # Deploy vms -auto-deploy system-vm +deploy-qois .#lindberg-nextcloud .#lindberg-build -# Deploy CI hosts -auto-deploy system-ci - -# Deploy physical hosts -auto-deploy system-physical +# Deploy fast physical hosts +deploy-qois .#lindberg +# Deploy slow physical hosts (maybe do individually) +deploy-qois --confirm-timeout 600 --activation-timeout 600 --targets .#stompert .#stompert ``` @@ -48,11 +47,11 @@ pssh -l root -H lindberg-nextcloud.backplane.net.qo.is -H lindberg-build.backpla ## Application Updates -Some applications have pinned versions to prevent problems due to accidental upgrades.\ +Some applications have pinned versions to prevent problems due to accidental upgrades. The version switch has to be done manually by switching the package used. This includes the modules for: - `nextcloud` - - Check [admin panel](https://cloud.qo.is/settings/admin/overview) for warnings after upgrading -- `postgresql`, [→ Nixpkgs manual page](https://nixos.org/manual/nixos/stable/#module-services-postgres-upgrading) +- `postgresql`, [→ Nixpkgs manual page](https://nixos.org/manual/nixos/stable/#module-services-postgres-upgrading) +