From b910dc465e305e5b4600d685b18c2600c3669aa6 Mon Sep 17 00:00:00 2001 From: Sebastian Wendel Date: Thu, 4 Jul 2024 13:47:18 +0200 Subject: [PATCH] first commit --- .envrc | 5 + .gitignore | 53 + .vscode/extensions.json | 11 + .vscode/settings.json | 33 + LICENSE.md | 24 + README.md | 202 ++ default.nix | 14 + flake.lock | 2550 +++++++++++++++++ flake.nix | 285 ++ hosts/dev-vm/clevis.age | Bin 0 -> 2422 bytes hosts/dev-vm/default.nix | 27 + hosts/dev-vm/hardware.nix | 37 + hosts/dev-vm/storage.nix | 143 + hosts/srxfdm00/default.nix | 16 + hosts/srxfdm00/hardware.nix | 11 + hosts/srxfdm00/services/fluidd.nix | 19 + hosts/srxfdm00/services/klipper/default.nix | 33 + hosts/srxfdm00/services/klipper/firmware.ini | 109 + hosts/srxfdm00/services/klipper/settings.cfg | 583 ++++ hosts/srxfdm00/services/moonraker.nix | 44 + hosts/srxfdm00/services/octoprint.nix | 11 + hosts/srxfdm00/services/wireguard.nix | 39 + hosts/srxfdm00/vpn_srx.age | Bin 0 -> 1189 bytes hosts/srxgp00/default.nix | 56 + hosts/srxgp00/hardware.nix | 22 + hosts/srxgp00/services/coturn/auth-secret.age | 22 + hosts/srxgp00/services/coturn/default.nix | 81 + hosts/srxgp00/services/dendrite/default.nix | 185 ++ .../srxgp00/services/dendrite/environment.age | 21 + .../srxgp00/services/dendrite/private-key.age | 21 + hosts/srxgp00/services/forgejo/default.nix | 108 + .../services/forgejo/mailerPassword.age | 22 + hosts/srxgp00/services/forgejo/runner.nix | 59 + .../srxgp00/services/forgejo/runnerToken.age | 21 + hosts/srxgp00/services/grafana/default.nix | 99 + .../srxgp00/services/grafana/oidc-secret.age | 21 + hosts/srxgp00/services/hedgedoc/default.nix | 97 + .../srxgp00/services/hedgedoc/environment.age | Bin 0 -> 1204 bytes hosts/srxgp00/services/hydra/default.nix | 209 ++ hosts/srxgp00/services/hydra/private-key.age | 24 + hosts/srxgp00/services/hydra/secrets.age | Bin 0 -> 3514 bytes hosts/srxgp00/services/influxdb/default.nix | 43 + hosts/srxgp00/services/jellyfin/default.nix | 25 + .../services/keycloak/databasePassword.age | 21 + hosts/srxgp00/services/keycloak/default.nix | 48 + .../srxgp00/services/mailserver/accounts.nix | 10 + .../services/mailserver/autoconfig.nix | 31 + hosts/srxgp00/services/mailserver/default.nix | 171 ++ hosts/srxgp00/services/mailserver/dmarc.nix | 34 + .../services/mailserver/ldap-bind-secret.age | 30 + .../mailserver/ldap-config-secret.age | 29 + .../services/mailserver/mailbox-Ies6sh.age | 22 + .../services/mailserver/mailbox-Oom7oh.age | 22 + .../services/mailserver/mailbox-Osoo5u.age | 21 + .../mailserver/mailbox-dmarc-client.age | 21 + .../services/mailserver/mailbox-dmarc.age | Bin 0 -> 1205 bytes .../services/mailserver/mailbox-ugai0U.age | Bin 0 -> 1205 bytes .../services/mailserver/mailbox-xaev9B.age | 21 + .../srxgp00/services/mailserver/webclient.nix | 31 + hosts/srxgp00/services/minio/default.nix | 103 + hosts/srxgp00/services/minio/user_admin.age | Bin 0 -> 1225 bytes .../services/minio/user_prometheus.age | Bin 0 -> 1258 bytes hosts/srxgp00/services/mysql/default.nix | 14 + .../srxgp00/services/nextcloud/adminpass.age | 21 + hosts/srxgp00/services/nextcloud/default.nix | 153 + hosts/srxgp00/services/nextcloud/secrets.age | 22 + hosts/srxgp00/services/nginx/checkip.nix | 33 + hosts/srxgp00/services/nginx/default.nix | 10 + hosts/srxgp00/services/nginx/nix-hamburg.nix | 27 + hosts/srxgp00/services/nginx/srx.digital.nix | 26 + hosts/srxgp00/services/nginx/srx81.de.nix | 26 + .../srxgp00/services/oauth2-proxy/default.nix | 80 + .../srxgp00/services/oauth2-proxy/secrets.age | 21 + hosts/srxgp00/services/openldap/default.nix | 133 + .../services/openldap/ldap-bind-secret.age | Bin 0 -> 1185 bytes .../services/openldap/ldap-config-secret.age | 22 + hosts/srxgp00/services/paperless/default.nix | 53 + hosts/srxgp00/services/paperless/password.age | 21 + hosts/srxgp00/services/plausible/default.nix | 48 + hosts/srxgp00/services/plausible/mail.age | Bin 0 -> 1175 bytes hosts/srxgp00/services/plausible/password.age | 21 + hosts/srxgp00/services/plausible/secret.age | 21 + hosts/srxgp00/services/postgresql/default.nix | 14 + .../services/prometheus/alertmanager-env.age | Bin 0 -> 1364 bytes .../services/prometheus/alertmanager.nix | 107 + .../services/prometheus/check/apcupsd.nix | 7 + hosts/srxgp00/services/prometheus/default.nix | 8 + .../services/prometheus/prometheus.nix | 93 + hosts/srxgp00/services/prometheus/rules.nix | 37 + .../services/prometheus/rules/apcupsd.nix | 41 + .../services/prometheus/rules/dendrite.nix | 6 + .../srxgp00/services/prometheus/rules/dns.nix | 16 + .../services/prometheus/rules/encryption.nix | 8 + .../services/prometheus/rules/forgejo.nix | 6 + .../services/prometheus/rules/harddisk.nix | 26 + .../services/prometheus/rules/http.nix | 16 + .../services/prometheus/rules/instance.nix | 17 + .../services/prometheus/rules/mail.nix | 11 + .../services/prometheus/rules/memory.nix | 18 + .../services/prometheus/rules/network.nix | 17 + .../srxgp00/services/prometheus/rules/nix.nix | 7 + .../services/prometheus/rules/prometheus.nix | 38 + .../services/prometheus/rules/services.nix | 22 + .../services/prometheus/rules/storage.nix | 60 + .../services/prometheus/rules/tasks.nix | 11 + .../services/prometheus/rules/workload.nix | 7 + hosts/srxgp00/services/restic/default.nix | 31 + hosts/srxgp00/services/restic/repo_key.age | 21 + hosts/srxgp00/services/restic/repo_ssh.age | Bin 0 -> 1563 bytes .../srxgp00/services/vaultwarden/default.nix | 120 + .../srxgp00/services/vaultwarden/secrets.age | 22 + hosts/srxgp00/services/wireguard/default.nix | 164 ++ hosts/srxgp00/storage.nix | 140 + hosts/srxgp00/vpn_srx.age | Bin 0 -> 1189 bytes hosts/srxgp01/default.nix | 39 + hosts/srxgp01/hardware.nix | 21 + hosts/srxgp01/services/wireguard.nix | 35 + hosts/srxgp01/storage.nix | 121 + hosts/srxgp01/vpn_srx.age | 22 + hosts/srxgp02/default.nix | 37 + hosts/srxgp02/hardware.nix | 16 + hosts/srxgp02/services/wireguard.nix | 35 + hosts/srxgp02/storage.nix | 93 + hosts/srxgp02/vpn_srx.age | 21 + hosts/srxk8s00/default.nix | 29 + hosts/srxk8s00/hardware.nix | 19 + hosts/srxk8s00/services/k3s.nix | 39 + hosts/srxk8s00/services/wireguard.nix | 35 + hosts/srxk8s00/storage.nix | 122 + hosts/srxk8s00/vpn_srx.age | 21 + hosts/srxmc00/cifs_nas.age | 21 + hosts/srxmc00/default.nix | 32 + hosts/srxmc00/hardware.nix | 38 + hosts/srxmc00/networking/wireguard.nix | 35 + hosts/srxmc00/networking/wireless.nix | 12 + hosts/srxmc00/services/mounts/default.nix | 48 + hosts/srxmc00/storage.nix | 98 + hosts/srxmc00/vpn_srx.age | Bin 0 -> 1189 bytes hosts/srxmc00/wifi_client.age | 21 + hosts/srxnas00/default.nix | 42 + hosts/srxnas00/dns_update.age | 21 + hosts/srxnas00/hardware.nix | 39 + hosts/srxnas00/network/knsupdate/default.nix | 16 + hosts/srxnas00/network/wireguard/default.nix | 36 + hosts/srxnas00/networking/default.nix | 68 + hosts/srxnas00/networking/dns/blocky.nix | 123 + hosts/srxnas00/networking/dns/knsupdate.nix | 16 + hosts/srxnas00/networking/dns/unbound.nix | 68 + hosts/srxnas00/networking/kea/default.nix | 223 ++ hosts/srxnas00/networking/networks/dmz.nix | 40 + hosts/srxnas00/networking/networks/gst.nix | 40 + hosts/srxnas00/networking/networks/op.nix | 40 + hosts/srxnas00/networking/networks/usr.nix | 44 + hosts/srxnas00/networking/networks/wan.nix | 23 + .../srxnas00/networking/wireguard/mullvad.nix | 180 ++ hosts/srxnas00/networking/wireguard/srx.nix | 40 + hosts/srxnas00/networking/wireless.nix | 19 + hosts/srxnas00/services/apcupsd/default.nix | 16 + .../srxnas00/services/home-assistant/auth.nix | 10 + .../services/home-assistant/default.nix | 88 + .../srxnas00/services/home-assistant/http.nix | 10 + .../home-assistant/lovelace/default.nix | 18 + .../services/home-assistant/zones.nix | 23 + hosts/srxnas00/services/jellyfin/default.nix | 7 + hosts/srxnas00/services/minidlna/default.nix | 23 + hosts/srxnas00/services/mosquitto/default.nix | 10 + hosts/srxnas00/services/netboot/default.nix | 47 + hosts/srxnas00/services/rtl-sdr/default.nix | 26 + hosts/srxnas00/services/vault/default.nix | 46 + hosts/srxnas00/services/vdr/default.nix | 26 + .../srxnas00/services/zigbee2mqtt/default.nix | 34 + hosts/srxnas00/storage.nix | 187 ++ hosts/srxnas00/storage/nfs/default.nix | 49 + hosts/srxnas00/vpn_mvd.age | 21 + hosts/srxnas00/vpn_srx.age | 23 + hosts/srxnas01/clevis.age | Bin 0 -> 2465 bytes hosts/srxnas01/default.nix | 46 + hosts/srxnas01/dns_update.age | 22 + hosts/srxnas01/hardware.nix | 54 + hosts/srxnas01/network/knsupdate/default.nix | 16 + hosts/srxnas01/network/wireguard/default.nix | 36 + hosts/srxnas01/services/minidlna/default.nix | 23 + hosts/srxnas01/services/samba/default.nix | 97 + hosts/srxnas01/storage.nix | 177 ++ hosts/srxnas01/vpn_srx.age | Bin 0 -> 1189 bytes hosts/srxnb00/clevis.age | Bin 0 -> 6166 bytes hosts/srxnb00/default.nix | 24 + hosts/srxnb00/hardware.nix | 49 + hosts/srxnb00/services/restic/default.nix | 69 + hosts/srxnb00/services/restic/repo_key.age | Bin 0 -> 1177 bytes hosts/srxnb00/services/restic/repo_ssh.age | Bin 0 -> 1564 bytes hosts/srxnb00/services/wireguard.nix | 67 + hosts/srxnb00/storage.nix | 144 + hosts/srxnb00/vpn_ccl.age | Bin 0 -> 1189 bytes hosts/srxnb00/vpn_srx.age | Bin 0 -> 1189 bytes hosts/srxtab00/default.nix | 17 + hosts/srxtab00/hardware.nix | 95 + hosts/srxtab00/services/wireguard.nix | 35 + hosts/srxtab00/vpn_srx.age | 21 + hosts/srxws00/default.nix | 25 + hosts/srxws00/hardware.nix | 33 + hosts/srxws00/services/nfs.nix | 69 + hosts/srxws00/services/wireguard.nix | 35 + hosts/srxws00/storage.nix | 98 + hosts/srxws00/vpn_srx.age | Bin 0 -> 1189 bytes hosts/srxws01/clevis.age | Bin 0 -> 2423 bytes hosts/srxws01/default.nix | 36 + hosts/srxws01/hardware.nix | 52 + hosts/srxws01/services/wireguard.nix | 35 + hosts/srxws01/storage.nix | 135 + hosts/srxws01/vpn_srx.age | 21 + lib/terraform.nix | 93 + modules/custom/dns/knot/acls.nix | 53 + modules/custom/dns/knot/default.nix | 15 + modules/custom/dns/knot/policies.nix | 23 + modules/custom/dns/knot/remotes.nix | 73 + modules/custom/dns/knot/secrets/default.nix | 49 + modules/custom/dns/knot/secrets/notify.age | Bin 0 -> 1482 bytes modules/custom/dns/knot/secrets/transfer.age | Bin 0 -> 1484 bytes modules/custom/dns/knot/secrets/tsig_xfr.age | Bin 0 -> 1637 bytes modules/custom/dns/knot/secrets/update.age | Bin 0 -> 1483 bytes .../custom/dns/knot/secrets/update_k8s.age | 26 + .../knot/secrets/update_terraform_cicd.age | 26 + .../knot/secrets/update_terraform_swendel.age | Bin 0 -> 1506 bytes modules/custom/dns/knot/submission.nix | 27 + modules/custom/dns/knot/templates.nix | 34 + modules/custom/dns/knot/zones.nix | 10 + modules/custom/dns/zones/curious.bio.nix | 121 + modules/custom/dns/zones/default.nix | 41 + modules/custom/dns/zones/nix-hamburg.de.nix | 13 + modules/custom/dns/zones/sourceindex.de.nix | 13 + modules/custom/dns/zones/srx.dev.nix | 30 + modules/custom/dns/zones/srx.digital.nix | 103 + modules/custom/dns/zones/vpn.srx.dev.nix | 56 + modules/filesystems/zfs.nix | 24 + modules/hardware/bluetooth.nix | 6 + modules/hardware/cpu/amd.nix | 12 + modules/hardware/cpu/intel.nix | 12 + modules/hardware/default.nix | 38 + modules/hardware/disk.nix | 42 + modules/hardware/gpu/amd.nix | 12 + modules/hardware/gpu/intel.nix | 11 + modules/hardware/gpu/nvidia.nix | 40 + modules/hardware/laptop.nix | 6 + modules/hardware/power.nix | 10 + modules/hardware/rpi4.nix | 37 + modules/hardware/security/nitrokey.nix | 15 + modules/hardware/security/secureboot.nix | 21 + modules/hardware/security/yubikey.nix | 23 + modules/hardware/sound/pipewire.nix | 21 + modules/hardware/sound/pulseaudio.nix | 15 + modules/roles/core/boot.nix | 29 + modules/roles/core/commands.nix | 9 + modules/roles/core/cve.nix | 6 + modules/roles/core/default.nix | 37 + modules/roles/core/dns.nix | 10 + modules/roles/core/editor.nix | 6 + modules/roles/core/fail2ban.nix | 29 + modules/roles/core/home-manager.nix | 11 + modules/roles/core/locale.nix | 21 + modules/roles/core/motd.nix | 38 + modules/roles/core/nix.nix | 60 + modules/roles/core/openssh.nix | 7 + modules/roles/core/pkgs.nix | 40 + modules/roles/core/security.nix | 41 + modules/roles/core/swap.nix | 4 + modules/roles/core/time.nix | 14 + modules/roles/core/tmux.nix | 13 + modules/roles/core/users.nix | 8 + modules/roles/core/vault.nix | 12 + modules/roles/core/zsh.nix | 9 + modules/roles/desktop/default.nix | 16 + .../roles/desktop/desktop-manager/default.nix | 51 + .../roles/desktop/desktop-manager/gnome.nix | 5 + .../roles/desktop/display-manager/default.nix | 5 + modules/roles/desktop/display-manager/gdm.nix | 7 + modules/roles/desktop/office/default.nix | 7 + modules/roles/desktop/office/evolution.nix | 11 + modules/roles/desktop/office/printer.nix | 15 + modules/roles/desktop/office/scanner.nix | 13 + modules/roles/desktop/system/default.nix | 71 + .../roles/desktop/system/documentation.nix | 10 + modules/roles/desktop/system/fonts.nix | 36 + modules/roles/desktop/system/stylix.nix | 47 + .../roles/desktop/window-manager/default.nix | 5 + .../desktop/window-manager/sway/default.nix | 34 + modules/roles/media-center/default.nix | 52 + modules/roles/nas/default.nix | 9 + modules/roles/server/acme.age | 47 + modules/roles/server/default.nix | 45 + modules/roles/workstation/default.nix | 19 + modules/services/container/default.nix | 16 + modules/services/container/docker.nix | 20 + modules/services/container/k3s/default.nix | 123 + .../container/k3s/k8s_cluster_token.age | 21 + .../container/k3s/k8s_dns_update_rfc2136.age | Bin 0 -> 1233 bytes .../container/k3s/k8s_environment.age | Bin 0 -> 1182 bytes .../container/k3s/k8s_traefik_dashboard.age | Bin 0 -> 1209 bytes modules/services/container/podman.nix | 20 + modules/services/database/mysql.nix | 28 + modules/services/database/postgresql.nix | 37 + modules/services/dns/avahi.nix | 14 + modules/services/dns/default.nix | 47 + modules/services/dns/knot/default.nix | 30 + modules/services/dns/knot/modules.nix | 29 + modules/services/dns/knot/monitoring.nix | 38 + modules/services/dns/knot/secrets/notify.age | 26 + .../services/dns/knot/secrets/transfer.age | 25 + .../services/dns/knot/secrets/tsig_xfr.age | Bin 0 -> 1637 bytes modules/services/dns/knot/secrets/update.age | Bin 0 -> 1483 bytes .../services/dns/knot/secrets/update_k8s.age | Bin 0 -> 1516 bytes .../knot/secrets/update_terraform_cicd.age | Bin 0 -> 1503 bytes .../knot/secrets/update_terraform_swendel.age | Bin 0 -> 1506 bytes modules/services/dns/knot/system.nix | 26 + .../services/dns/knot/zones/srx.digital.nix | 139 + modules/services/dns/knsupdate.nix | 170 ++ modules/services/monitoring/default.nix | 7 + modules/services/monitoring/loki.nix | 94 + modules/services/monitoring/prometheus.nix | 33 + modules/services/monitoring/promtail.nix | 48 + modules/services/monitoring/telegraf.nix | 36 + modules/services/netboot/config.nix | 36 + modules/services/netboot/default.nix | 88 + modules/services/security/clamav/default.nix | 12 + modules/services/security/tang/default.nix | 33 + modules/services/storage/samba/default.nix | 97 + .../services/storage/syncthing/default.nix | 165 ++ modules/services/virtualisation/libvirt.nix | 41 + modules/services/virtualisation/microvm.nix | 43 + modules/services/web/nginx.nix | 40 + modules/users/default.nix | 8 + .../users/personal/crstl/browser/chromium.nix | 17 + .../users/personal/crstl/browser/firefox.nix | 242 ++ modules/users/personal/crstl/cad/cadquery.nix | 4 + modules/users/personal/crstl/cad/default.nix | 8 + modules/users/personal/crstl/cad/kicad.nix | 9 + modules/users/personal/crstl/cad/openscad.nix | 12 + modules/users/personal/crstl/cad/slicer.nix | 7 + modules/users/personal/crstl/chat/default.nix | 11 + modules/users/personal/crstl/default.nix | 111 + .../crstl/desktop-manager/blueman-applet.nix | 1 + .../personal/crstl/desktop-manager/dconf.nix | 103 + .../crstl/desktop-manager/gnome-keyring.nix | 10 + .../crstl/desktop-manager/kdeconnect.nix | 6 + .../desktop-manager/nextcloud-client.nix | 9 + modules/users/personal/crstl/editor/emacs.nix | 389 +++ modules/users/personal/crstl/editor/helix.nix | 289 ++ .../users/personal/crstl/editor/neovim.nix | 548 ++++ .../users/personal/crstl/editor/vscodium.nix | 196 ++ modules/users/personal/crstl/gpg/default.nix | 21 + .../users/personal/crstl/gpg/keyserver.age | 44 + modules/users/personal/crstl/media/mpd.nix | 14 + modules/users/personal/crstl/media/mpv.nix | 70 + modules/users/personal/crstl/office/pass.nix | 15 + modules/users/personal/crstl/packages.nix | 16 + modules/users/personal/crstl/password.age | 45 + .../users/personal/crstl/system/gammastep.nix | 7 + modules/users/personal/crstl/system/gtk.nix | 14 + .../personal/crstl/system/home-manager.nix | 3 + .../users/personal/crstl/system/kanshi.nix | 67 + modules/users/personal/crstl/system/qt.nix | 6 + .../users/personal/crstl/system/stylix.nix | 29 + modules/users/personal/crstl/system/xdg.nix | 6 + .../personal/crstl/terminal/alacritty.nix | 14 + .../users/personal/crstl/terminal/awscli.nix | 9 + modules/users/personal/crstl/terminal/bat.nix | 27 + .../personal/crstl/terminal/dircolors.nix | 5 + modules/users/personal/crstl/terminal/git.nix | 101 + .../users/personal/crstl/terminal/htop.nix | 32 + modules/users/personal/crstl/terminal/imv.nix | 78 + modules/users/personal/crstl/terminal/jq.nix | 1 + .../users/personal/crstl/terminal/kitty.nix | 26 + modules/users/personal/crstl/terminal/lf.nix | 25 + modules/users/personal/crstl/terminal/lsd.nix | 11 + modules/users/personal/crstl/terminal/mpd.nix | 14 + .../personal/crstl/terminal/nix-index.nix | 5 + modules/users/personal/crstl/terminal/rbw.nix | 13 + .../users/personal/crstl/terminal/ripgrep.nix | 9 + modules/users/personal/crstl/terminal/ssh.nix | 6 + .../personal/crstl/terminal/starship.nix | 63 + .../users/personal/crstl/terminal/thefuck.nix | 9 + .../users/personal/crstl/terminal/tmux.nix | 12 + .../users/personal/crstl/terminal/yazi.nix | 12 + .../users/personal/crstl/terminal/zoxide.nix | 7 + modules/users/personal/crstl/terminal/zsh.nix | 68 + .../personal/crstl/window-manager/dunst.nix | 50 + .../personal/crstl/window-manager/rofi.nix | 51 + .../personal/crstl/window-manager/sway.nix | 355 +++ .../crstl/window-manager/swayidle.nix | 35 + .../personal/crstl/window-manager/waybar.nix | 209 ++ modules/users/system/automat/default.nix | 45 + modules/users/system/automat/ssh-private.age | Bin 0 -> 2864 bytes modules/users/system/root/default.nix | 14 + modules/users/system/root/password.age | Bin 0 -> 2570 bytes modules/users/system/service.nix | 30 + nix/deploy.nix | 27 + nix/devshell.nix | 291 ++ nix/home-manager.nix | 49 + nix/hosts.nix | 133 + nix/modules.nix | 94 + nix/nixos.nix | 40 + nix/overlay.nix | 36 + nix/packages.nix | 40 + nix/terranix.nix | 63 + overlays/cadquery.nix | 21 + overlays/nix-latest.nix | 18 + secrets.nix | 95 + terranix/backend.nix | 14 + terranix/default.nix | 16 + terranix/gitea/curious.bio.nix | 109 + terranix/gitea/default.nix | 14 + terranix/gitea/nix-hamburg.de.nix | 9 + terranix/gitea/octopot.de.nix | 9 + terranix/gitea/srx.digital.nix | 75 + terranix/gitea/swendel.nix | 64 + terranix/github/default.nix | 10 + terranix/github/srx.digital.nix | 28 + terranix/grafana/default.nix | 20 + terranix/hcloud/default.nix | 20 + terranix/hydra/default.nix | 12 + terranix/hydra/srx.digital.nix | 63 + terranix/keycloak/default.nix | 12 + terranix/keycloak/srx.digital.nix | 114 + terranix/minio/admins.nix | 33 + terranix/minio/default.nix | 14 + terranix/minio/hydra.nix | 65 + terranix/minio/terraform.nix | 15 + terranix/tfsec.nix | 6 + terranix/variables.nix | 57 + 429 files changed, 21127 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100755 .vscode/extensions.json create mode 100755 .vscode/settings.json create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 hosts/dev-vm/clevis.age create mode 100644 hosts/dev-vm/default.nix create mode 100644 hosts/dev-vm/hardware.nix create mode 100644 hosts/dev-vm/storage.nix create mode 100644 hosts/srxfdm00/default.nix create mode 100644 hosts/srxfdm00/hardware.nix create mode 100644 hosts/srxfdm00/services/fluidd.nix create mode 100644 hosts/srxfdm00/services/klipper/default.nix create mode 100644 hosts/srxfdm00/services/klipper/firmware.ini create mode 100644 hosts/srxfdm00/services/klipper/settings.cfg create mode 100644 hosts/srxfdm00/services/moonraker.nix create mode 100644 hosts/srxfdm00/services/octoprint.nix create mode 100644 hosts/srxfdm00/services/wireguard.nix create mode 100644 hosts/srxfdm00/vpn_srx.age create mode 100644 hosts/srxgp00/default.nix create mode 100644 hosts/srxgp00/hardware.nix create mode 100644 hosts/srxgp00/services/coturn/auth-secret.age create mode 100644 hosts/srxgp00/services/coturn/default.nix create mode 100644 hosts/srxgp00/services/dendrite/default.nix create mode 100644 hosts/srxgp00/services/dendrite/environment.age create mode 100644 hosts/srxgp00/services/dendrite/private-key.age create mode 100644 hosts/srxgp00/services/forgejo/default.nix create mode 100644 hosts/srxgp00/services/forgejo/mailerPassword.age create mode 100644 hosts/srxgp00/services/forgejo/runner.nix create mode 100644 hosts/srxgp00/services/forgejo/runnerToken.age create mode 100644 hosts/srxgp00/services/grafana/default.nix create mode 100644 hosts/srxgp00/services/grafana/oidc-secret.age create mode 100644 hosts/srxgp00/services/hedgedoc/default.nix create mode 100644 hosts/srxgp00/services/hedgedoc/environment.age create mode 100644 hosts/srxgp00/services/hydra/default.nix create mode 100644 hosts/srxgp00/services/hydra/private-key.age create mode 100644 hosts/srxgp00/services/hydra/secrets.age create mode 100644 hosts/srxgp00/services/influxdb/default.nix create mode 100644 hosts/srxgp00/services/jellyfin/default.nix create mode 100644 hosts/srxgp00/services/keycloak/databasePassword.age create mode 100644 hosts/srxgp00/services/keycloak/default.nix create mode 100644 hosts/srxgp00/services/mailserver/accounts.nix create mode 100644 hosts/srxgp00/services/mailserver/autoconfig.nix create mode 100644 hosts/srxgp00/services/mailserver/default.nix create mode 100644 hosts/srxgp00/services/mailserver/dmarc.nix create mode 100644 hosts/srxgp00/services/mailserver/ldap-bind-secret.age create mode 100644 hosts/srxgp00/services/mailserver/ldap-config-secret.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-Ies6sh.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-Oom7oh.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-Osoo5u.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-dmarc-client.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-dmarc.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-ugai0U.age create mode 100644 hosts/srxgp00/services/mailserver/mailbox-xaev9B.age create mode 100644 hosts/srxgp00/services/mailserver/webclient.nix create mode 100644 hosts/srxgp00/services/minio/default.nix create mode 100644 hosts/srxgp00/services/minio/user_admin.age create mode 100644 hosts/srxgp00/services/minio/user_prometheus.age create mode 100644 hosts/srxgp00/services/mysql/default.nix create mode 100644 hosts/srxgp00/services/nextcloud/adminpass.age create mode 100644 hosts/srxgp00/services/nextcloud/default.nix create mode 100644 hosts/srxgp00/services/nextcloud/secrets.age create mode 100644 hosts/srxgp00/services/nginx/checkip.nix create mode 100644 hosts/srxgp00/services/nginx/default.nix create mode 100644 hosts/srxgp00/services/nginx/nix-hamburg.nix create mode 100644 hosts/srxgp00/services/nginx/srx.digital.nix create mode 100644 hosts/srxgp00/services/nginx/srx81.de.nix create mode 100644 hosts/srxgp00/services/oauth2-proxy/default.nix create mode 100644 hosts/srxgp00/services/oauth2-proxy/secrets.age create mode 100644 hosts/srxgp00/services/openldap/default.nix create mode 100644 hosts/srxgp00/services/openldap/ldap-bind-secret.age create mode 100644 hosts/srxgp00/services/openldap/ldap-config-secret.age create mode 100644 hosts/srxgp00/services/paperless/default.nix create mode 100644 hosts/srxgp00/services/paperless/password.age create mode 100644 hosts/srxgp00/services/plausible/default.nix create mode 100644 hosts/srxgp00/services/plausible/mail.age create mode 100644 hosts/srxgp00/services/plausible/password.age create mode 100644 hosts/srxgp00/services/plausible/secret.age create mode 100644 hosts/srxgp00/services/postgresql/default.nix create mode 100644 hosts/srxgp00/services/prometheus/alertmanager-env.age create mode 100644 hosts/srxgp00/services/prometheus/alertmanager.nix create mode 100644 hosts/srxgp00/services/prometheus/check/apcupsd.nix create mode 100644 hosts/srxgp00/services/prometheus/default.nix create mode 100644 hosts/srxgp00/services/prometheus/prometheus.nix create mode 100644 hosts/srxgp00/services/prometheus/rules.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/apcupsd.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/dendrite.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/dns.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/encryption.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/forgejo.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/harddisk.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/http.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/instance.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/mail.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/memory.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/network.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/nix.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/prometheus.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/services.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/storage.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/tasks.nix create mode 100644 hosts/srxgp00/services/prometheus/rules/workload.nix create mode 100644 hosts/srxgp00/services/restic/default.nix create mode 100644 hosts/srxgp00/services/restic/repo_key.age create mode 100644 hosts/srxgp00/services/restic/repo_ssh.age create mode 100644 hosts/srxgp00/services/vaultwarden/default.nix create mode 100644 hosts/srxgp00/services/vaultwarden/secrets.age create mode 100644 hosts/srxgp00/services/wireguard/default.nix create mode 100644 hosts/srxgp00/storage.nix create mode 100644 hosts/srxgp00/vpn_srx.age create mode 100644 hosts/srxgp01/default.nix create mode 100644 hosts/srxgp01/hardware.nix create mode 100644 hosts/srxgp01/services/wireguard.nix create mode 100644 hosts/srxgp01/storage.nix create mode 100644 hosts/srxgp01/vpn_srx.age create mode 100644 hosts/srxgp02/default.nix create mode 100644 hosts/srxgp02/hardware.nix create mode 100644 hosts/srxgp02/services/wireguard.nix create mode 100644 hosts/srxgp02/storage.nix create mode 100644 hosts/srxgp02/vpn_srx.age create mode 100644 hosts/srxk8s00/default.nix create mode 100644 hosts/srxk8s00/hardware.nix create mode 100644 hosts/srxk8s00/services/k3s.nix create mode 100644 hosts/srxk8s00/services/wireguard.nix create mode 100644 hosts/srxk8s00/storage.nix create mode 100644 hosts/srxk8s00/vpn_srx.age create mode 100644 hosts/srxmc00/cifs_nas.age create mode 100644 hosts/srxmc00/default.nix create mode 100644 hosts/srxmc00/hardware.nix create mode 100644 hosts/srxmc00/networking/wireguard.nix create mode 100644 hosts/srxmc00/networking/wireless.nix create mode 100644 hosts/srxmc00/services/mounts/default.nix create mode 100644 hosts/srxmc00/storage.nix create mode 100644 hosts/srxmc00/vpn_srx.age create mode 100644 hosts/srxmc00/wifi_client.age create mode 100644 hosts/srxnas00/default.nix create mode 100644 hosts/srxnas00/dns_update.age create mode 100644 hosts/srxnas00/hardware.nix create mode 100644 hosts/srxnas00/network/knsupdate/default.nix create mode 100644 hosts/srxnas00/network/wireguard/default.nix create mode 100644 hosts/srxnas00/networking/default.nix create mode 100644 hosts/srxnas00/networking/dns/blocky.nix create mode 100644 hosts/srxnas00/networking/dns/knsupdate.nix create mode 100644 hosts/srxnas00/networking/dns/unbound.nix create mode 100644 hosts/srxnas00/networking/kea/default.nix create mode 100644 hosts/srxnas00/networking/networks/dmz.nix create mode 100644 hosts/srxnas00/networking/networks/gst.nix create mode 100644 hosts/srxnas00/networking/networks/op.nix create mode 100644 hosts/srxnas00/networking/networks/usr.nix create mode 100644 hosts/srxnas00/networking/networks/wan.nix create mode 100644 hosts/srxnas00/networking/wireguard/mullvad.nix create mode 100644 hosts/srxnas00/networking/wireguard/srx.nix create mode 100644 hosts/srxnas00/networking/wireless.nix create mode 100644 hosts/srxnas00/services/apcupsd/default.nix create mode 100644 hosts/srxnas00/services/home-assistant/auth.nix create mode 100644 hosts/srxnas00/services/home-assistant/default.nix create mode 100644 hosts/srxnas00/services/home-assistant/http.nix create mode 100644 hosts/srxnas00/services/home-assistant/lovelace/default.nix create mode 100644 hosts/srxnas00/services/home-assistant/zones.nix create mode 100644 hosts/srxnas00/services/jellyfin/default.nix create mode 100644 hosts/srxnas00/services/minidlna/default.nix create mode 100644 hosts/srxnas00/services/mosquitto/default.nix create mode 100644 hosts/srxnas00/services/netboot/default.nix create mode 100644 hosts/srxnas00/services/rtl-sdr/default.nix create mode 100644 hosts/srxnas00/services/vault/default.nix create mode 100644 hosts/srxnas00/services/vdr/default.nix create mode 100644 hosts/srxnas00/services/zigbee2mqtt/default.nix create mode 100644 hosts/srxnas00/storage.nix create mode 100644 hosts/srxnas00/storage/nfs/default.nix create mode 100644 hosts/srxnas00/vpn_mvd.age create mode 100644 hosts/srxnas00/vpn_srx.age create mode 100644 hosts/srxnas01/clevis.age create mode 100644 hosts/srxnas01/default.nix create mode 100644 hosts/srxnas01/dns_update.age create mode 100644 hosts/srxnas01/hardware.nix create mode 100644 hosts/srxnas01/network/knsupdate/default.nix create mode 100644 hosts/srxnas01/network/wireguard/default.nix create mode 100644 hosts/srxnas01/services/minidlna/default.nix create mode 100644 hosts/srxnas01/services/samba/default.nix create mode 100644 hosts/srxnas01/storage.nix create mode 100644 hosts/srxnas01/vpn_srx.age create mode 100644 hosts/srxnb00/clevis.age create mode 100644 hosts/srxnb00/default.nix create mode 100644 hosts/srxnb00/hardware.nix create mode 100644 hosts/srxnb00/services/restic/default.nix create mode 100644 hosts/srxnb00/services/restic/repo_key.age create mode 100644 hosts/srxnb00/services/restic/repo_ssh.age create mode 100644 hosts/srxnb00/services/wireguard.nix create mode 100644 hosts/srxnb00/storage.nix create mode 100644 hosts/srxnb00/vpn_ccl.age create mode 100644 hosts/srxnb00/vpn_srx.age create mode 100644 hosts/srxtab00/default.nix create mode 100644 hosts/srxtab00/hardware.nix create mode 100644 hosts/srxtab00/services/wireguard.nix create mode 100644 hosts/srxtab00/vpn_srx.age create mode 100644 hosts/srxws00/default.nix create mode 100644 hosts/srxws00/hardware.nix create mode 100644 hosts/srxws00/services/nfs.nix create mode 100644 hosts/srxws00/services/wireguard.nix create mode 100644 hosts/srxws00/storage.nix create mode 100644 hosts/srxws00/vpn_srx.age create mode 100644 hosts/srxws01/clevis.age create mode 100644 hosts/srxws01/default.nix create mode 100644 hosts/srxws01/hardware.nix create mode 100644 hosts/srxws01/services/wireguard.nix create mode 100644 hosts/srxws01/storage.nix create mode 100644 hosts/srxws01/vpn_srx.age create mode 100644 lib/terraform.nix create mode 100644 modules/custom/dns/knot/acls.nix create mode 100644 modules/custom/dns/knot/default.nix create mode 100644 modules/custom/dns/knot/policies.nix create mode 100644 modules/custom/dns/knot/remotes.nix create mode 100644 modules/custom/dns/knot/secrets/default.nix create mode 100644 modules/custom/dns/knot/secrets/notify.age create mode 100644 modules/custom/dns/knot/secrets/transfer.age create mode 100644 modules/custom/dns/knot/secrets/tsig_xfr.age create mode 100644 modules/custom/dns/knot/secrets/update.age create mode 100644 modules/custom/dns/knot/secrets/update_k8s.age create mode 100644 modules/custom/dns/knot/secrets/update_terraform_cicd.age create mode 100644 modules/custom/dns/knot/secrets/update_terraform_swendel.age create mode 100644 modules/custom/dns/knot/submission.nix create mode 100644 modules/custom/dns/knot/templates.nix create mode 100644 modules/custom/dns/knot/zones.nix create mode 100644 modules/custom/dns/zones/curious.bio.nix create mode 100644 modules/custom/dns/zones/default.nix create mode 100644 modules/custom/dns/zones/nix-hamburg.de.nix create mode 100644 modules/custom/dns/zones/sourceindex.de.nix create mode 100644 modules/custom/dns/zones/srx.dev.nix create mode 100644 modules/custom/dns/zones/srx.digital.nix create mode 100644 modules/custom/dns/zones/vpn.srx.dev.nix create mode 100644 modules/filesystems/zfs.nix create mode 100644 modules/hardware/bluetooth.nix create mode 100644 modules/hardware/cpu/amd.nix create mode 100644 modules/hardware/cpu/intel.nix create mode 100644 modules/hardware/default.nix create mode 100644 modules/hardware/disk.nix create mode 100644 modules/hardware/gpu/amd.nix create mode 100644 modules/hardware/gpu/intel.nix create mode 100644 modules/hardware/gpu/nvidia.nix create mode 100644 modules/hardware/laptop.nix create mode 100644 modules/hardware/power.nix create mode 100644 modules/hardware/rpi4.nix create mode 100644 modules/hardware/security/nitrokey.nix create mode 100644 modules/hardware/security/secureboot.nix create mode 100644 modules/hardware/security/yubikey.nix create mode 100644 modules/hardware/sound/pipewire.nix create mode 100644 modules/hardware/sound/pulseaudio.nix create mode 100644 modules/roles/core/boot.nix create mode 100644 modules/roles/core/commands.nix create mode 100644 modules/roles/core/cve.nix create mode 100644 modules/roles/core/default.nix create mode 100644 modules/roles/core/dns.nix create mode 100644 modules/roles/core/editor.nix create mode 100644 modules/roles/core/fail2ban.nix create mode 100644 modules/roles/core/home-manager.nix create mode 100644 modules/roles/core/locale.nix create mode 100644 modules/roles/core/motd.nix create mode 100644 modules/roles/core/nix.nix create mode 100644 modules/roles/core/openssh.nix create mode 100644 modules/roles/core/pkgs.nix create mode 100644 modules/roles/core/security.nix create mode 100644 modules/roles/core/swap.nix create mode 100644 modules/roles/core/time.nix create mode 100644 modules/roles/core/tmux.nix create mode 100644 modules/roles/core/users.nix create mode 100644 modules/roles/core/vault.nix create mode 100644 modules/roles/core/zsh.nix create mode 100644 modules/roles/desktop/default.nix create mode 100644 modules/roles/desktop/desktop-manager/default.nix create mode 100644 modules/roles/desktop/desktop-manager/gnome.nix create mode 100644 modules/roles/desktop/display-manager/default.nix create mode 100644 modules/roles/desktop/display-manager/gdm.nix create mode 100644 modules/roles/desktop/office/default.nix create mode 100644 modules/roles/desktop/office/evolution.nix create mode 100644 modules/roles/desktop/office/printer.nix create mode 100644 modules/roles/desktop/office/scanner.nix create mode 100644 modules/roles/desktop/system/default.nix create mode 100644 modules/roles/desktop/system/documentation.nix create mode 100644 modules/roles/desktop/system/fonts.nix create mode 100644 modules/roles/desktop/system/stylix.nix create mode 100644 modules/roles/desktop/window-manager/default.nix create mode 100644 modules/roles/desktop/window-manager/sway/default.nix create mode 100644 modules/roles/media-center/default.nix create mode 100644 modules/roles/nas/default.nix create mode 100644 modules/roles/server/acme.age create mode 100644 modules/roles/server/default.nix create mode 100644 modules/roles/workstation/default.nix create mode 100644 modules/services/container/default.nix create mode 100644 modules/services/container/docker.nix create mode 100644 modules/services/container/k3s/default.nix create mode 100644 modules/services/container/k3s/k8s_cluster_token.age create mode 100644 modules/services/container/k3s/k8s_dns_update_rfc2136.age create mode 100644 modules/services/container/k3s/k8s_environment.age create mode 100644 modules/services/container/k3s/k8s_traefik_dashboard.age create mode 100644 modules/services/container/podman.nix create mode 100644 modules/services/database/mysql.nix create mode 100644 modules/services/database/postgresql.nix create mode 100644 modules/services/dns/avahi.nix create mode 100644 modules/services/dns/default.nix create mode 100644 modules/services/dns/knot/default.nix create mode 100644 modules/services/dns/knot/modules.nix create mode 100644 modules/services/dns/knot/monitoring.nix create mode 100644 modules/services/dns/knot/secrets/notify.age create mode 100644 modules/services/dns/knot/secrets/transfer.age create mode 100644 modules/services/dns/knot/secrets/tsig_xfr.age create mode 100644 modules/services/dns/knot/secrets/update.age create mode 100644 modules/services/dns/knot/secrets/update_k8s.age create mode 100644 modules/services/dns/knot/secrets/update_terraform_cicd.age create mode 100644 modules/services/dns/knot/secrets/update_terraform_swendel.age create mode 100644 modules/services/dns/knot/system.nix create mode 100644 modules/services/dns/knot/zones/srx.digital.nix create mode 100644 modules/services/dns/knsupdate.nix create mode 100644 modules/services/monitoring/default.nix create mode 100644 modules/services/monitoring/loki.nix create mode 100644 modules/services/monitoring/prometheus.nix create mode 100644 modules/services/monitoring/promtail.nix create mode 100644 modules/services/monitoring/telegraf.nix create mode 100644 modules/services/netboot/config.nix create mode 100644 modules/services/netboot/default.nix create mode 100644 modules/services/security/clamav/default.nix create mode 100644 modules/services/security/tang/default.nix create mode 100644 modules/services/storage/samba/default.nix create mode 100644 modules/services/storage/syncthing/default.nix create mode 100644 modules/services/virtualisation/libvirt.nix create mode 100644 modules/services/virtualisation/microvm.nix create mode 100644 modules/services/web/nginx.nix create mode 100644 modules/users/default.nix create mode 100644 modules/users/personal/crstl/browser/chromium.nix create mode 100644 modules/users/personal/crstl/browser/firefox.nix create mode 100644 modules/users/personal/crstl/cad/cadquery.nix create mode 100644 modules/users/personal/crstl/cad/default.nix create mode 100644 modules/users/personal/crstl/cad/kicad.nix create mode 100644 modules/users/personal/crstl/cad/openscad.nix create mode 100644 modules/users/personal/crstl/cad/slicer.nix create mode 100644 modules/users/personal/crstl/chat/default.nix create mode 100644 modules/users/personal/crstl/default.nix create mode 100644 modules/users/personal/crstl/desktop-manager/blueman-applet.nix create mode 100644 modules/users/personal/crstl/desktop-manager/dconf.nix create mode 100644 modules/users/personal/crstl/desktop-manager/gnome-keyring.nix create mode 100644 modules/users/personal/crstl/desktop-manager/kdeconnect.nix create mode 100644 modules/users/personal/crstl/desktop-manager/nextcloud-client.nix create mode 100644 modules/users/personal/crstl/editor/emacs.nix create mode 100644 modules/users/personal/crstl/editor/helix.nix create mode 100644 modules/users/personal/crstl/editor/neovim.nix create mode 100644 modules/users/personal/crstl/editor/vscodium.nix create mode 100644 modules/users/personal/crstl/gpg/default.nix create mode 100644 modules/users/personal/crstl/gpg/keyserver.age create mode 100644 modules/users/personal/crstl/media/mpd.nix create mode 100644 modules/users/personal/crstl/media/mpv.nix create mode 100644 modules/users/personal/crstl/office/pass.nix create mode 100644 modules/users/personal/crstl/packages.nix create mode 100644 modules/users/personal/crstl/password.age create mode 100644 modules/users/personal/crstl/system/gammastep.nix create mode 100644 modules/users/personal/crstl/system/gtk.nix create mode 100644 modules/users/personal/crstl/system/home-manager.nix create mode 100644 modules/users/personal/crstl/system/kanshi.nix create mode 100644 modules/users/personal/crstl/system/qt.nix create mode 100644 modules/users/personal/crstl/system/stylix.nix create mode 100644 modules/users/personal/crstl/system/xdg.nix create mode 100644 modules/users/personal/crstl/terminal/alacritty.nix create mode 100644 modules/users/personal/crstl/terminal/awscli.nix create mode 100644 modules/users/personal/crstl/terminal/bat.nix create mode 100644 modules/users/personal/crstl/terminal/dircolors.nix create mode 100644 modules/users/personal/crstl/terminal/git.nix create mode 100644 modules/users/personal/crstl/terminal/htop.nix create mode 100644 modules/users/personal/crstl/terminal/imv.nix create mode 100644 modules/users/personal/crstl/terminal/jq.nix create mode 100644 modules/users/personal/crstl/terminal/kitty.nix create mode 100644 modules/users/personal/crstl/terminal/lf.nix create mode 100644 modules/users/personal/crstl/terminal/lsd.nix create mode 100644 modules/users/personal/crstl/terminal/mpd.nix create mode 100644 modules/users/personal/crstl/terminal/nix-index.nix create mode 100644 modules/users/personal/crstl/terminal/rbw.nix create mode 100644 modules/users/personal/crstl/terminal/ripgrep.nix create mode 100644 modules/users/personal/crstl/terminal/ssh.nix create mode 100644 modules/users/personal/crstl/terminal/starship.nix create mode 100644 modules/users/personal/crstl/terminal/thefuck.nix create mode 100644 modules/users/personal/crstl/terminal/tmux.nix create mode 100644 modules/users/personal/crstl/terminal/yazi.nix create mode 100644 modules/users/personal/crstl/terminal/zoxide.nix create mode 100644 modules/users/personal/crstl/terminal/zsh.nix create mode 100644 modules/users/personal/crstl/window-manager/dunst.nix create mode 100644 modules/users/personal/crstl/window-manager/rofi.nix create mode 100644 modules/users/personal/crstl/window-manager/sway.nix create mode 100644 modules/users/personal/crstl/window-manager/swayidle.nix create mode 100644 modules/users/personal/crstl/window-manager/waybar.nix create mode 100644 modules/users/system/automat/default.nix create mode 100644 modules/users/system/automat/ssh-private.age create mode 100644 modules/users/system/root/default.nix create mode 100644 modules/users/system/root/password.age create mode 100644 modules/users/system/service.nix create mode 100644 nix/deploy.nix create mode 100644 nix/devshell.nix create mode 100644 nix/home-manager.nix create mode 100644 nix/hosts.nix create mode 100644 nix/modules.nix create mode 100644 nix/nixos.nix create mode 100644 nix/overlay.nix create mode 100644 nix/packages.nix create mode 100644 nix/terranix.nix create mode 100644 overlays/cadquery.nix create mode 100644 overlays/nix-latest.nix create mode 100644 secrets.nix create mode 100644 terranix/backend.nix create mode 100644 terranix/default.nix create mode 100644 terranix/gitea/curious.bio.nix create mode 100644 terranix/gitea/default.nix create mode 100644 terranix/gitea/nix-hamburg.de.nix create mode 100644 terranix/gitea/octopot.de.nix create mode 100644 terranix/gitea/srx.digital.nix create mode 100644 terranix/gitea/swendel.nix create mode 100644 terranix/github/default.nix create mode 100644 terranix/github/srx.digital.nix create mode 100644 terranix/grafana/default.nix create mode 100644 terranix/hcloud/default.nix create mode 100644 terranix/hydra/default.nix create mode 100644 terranix/hydra/srx.digital.nix create mode 100644 terranix/keycloak/default.nix create mode 100644 terranix/keycloak/srx.digital.nix create mode 100644 terranix/minio/admins.nix create mode 100644 terranix/minio/default.nix create mode 100644 terranix/minio/hydra.nix create mode 100644 terranix/minio/terraform.nix create mode 100644 terranix/tfsec.nix create mode 100644 terranix/variables.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..61cf455 --- /dev/null +++ b/.envrc @@ -0,0 +1,5 @@ +use flake + +dotenv_if_exists .envrc.local + +eval "$shellHook" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..447d929 --- /dev/null +++ b/.gitignore @@ -0,0 +1,53 @@ +.envrc.local +.*.swo +.*.swp +.direnv +.DS_Store +.pre-commit-config.yaml +result* +*.qcow2 +*.log +temp +*.pyc +TODOS.md +.devenv + +# terraform +.terraform +*.tf.json +*.tfstate + +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100755 index 0000000..33d3bea --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + "recommendations": [ + "arrterian.nix-env-selector", + "bbenoist.nix", + "brettm12345.nixfmt-vscode", + "hashicorp.hcl", + "jnoortheen.nix-ide", + "mikestead.dotenv", + ], + "unwantedRecommendations": [] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100755 index 0000000..d3eea4f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,33 @@ +{ + "files.associations": { + "flake.lock": "json", + "*.hcl": "hcl", + }, + "[terraform]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + }, + "[terraform-vars]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + }, + "[hcl]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + }, + "[nix]": { + "editor.defaultFormatter": "jnoortheen.nix-ide", + "editor.formatOnSave": true, + "editor.insertSpaces": true, + "editor.tabSize": 2, + "editor.codeLens": true, + "emmet.triggerExpansionOnTab": true, + "editor.quickSuggestions": { + "comments": "on", + "strings": "on" + } + } +} diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..0e9c25d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,24 @@ +# The MIT License (MIT) + +Copyright © 2023 Sebastian Wendel + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c46a9d7 --- /dev/null +++ b/README.md @@ -0,0 +1,202 @@ + +# srx digital - nix platform repository + +Nix Flake Logo + +This is the platform repository of [srx.digital](https://srx.digital), a Nix development and operations company based in Hamburg, Germany. + +[NixOS](https://nixos.org/) is a Linux distribution built on the [Nix package manager](https://nixos.wiki/wiki/Nix_package_manager), utilizing declarative configuration to ensure reproducible and reliable system setups. + +This repository contains opinionated configurations for deploying NixOS systems and cloud infrastructures with [Terraform](https://www.terraform.io/), written in pure [Nix](https://nixos.org/learn) expressions. It offers developers and DevOps engineers an insight into the potential of Nix. + +## 📜 Principles of Operation + +This repository uses 100% Infrastructure as Code and does not need to be configured manually. All services are monitored and backed up. Common services are modularized for reuse, but the separation of custom configurations is in progress. Reusable components will be moved to a separate Flake module in the near future. + +📌 **Note** + +> Some customer-specific configurations are stored in a private Git repository and imported as the `srx-nixos-shadow` flake to protect customer infrastructure. Due to its private nature, some tasks may fail and should be commented out. Generally, all expressions should evaluate without issues. + +## 🛠️ Components + +- [flake-parts](https://github.com/hercules-ci/flake-parts): Simplify Nix Flakes with the module system. +- [git-hooks](https://github.com/cachix/git-hooks.nix): Seamless integration of git hooks with Nix. +- [agenix](https://github.com/ryantm/agenix): Encrypted secrets for NixOS and Home Manager. +- [deploy-rs](https://github.com/serokell/deploy-rs): A multi-profile Nix-flake deployment tool. +- [nixos-anywhere](https://github.com/nix-community/nixos-anywhere): Install NixOS anywhere via SSH. +- [disko](https://github.com/nix-community/disko): Declarative disk partitioning. +- [srvos](https://github.com/nix-community/srvos): NixOS profiles for servers. +- [Tang & Clevis](https://fosdem.org/2024/schedule/event/fosdem-2024-3044-clevis-tang-unattended-boot-of-an-encrypted-nixos-system/): An automated encryption framework for full disk encryption. +- [Lanzaboote](https://github.com/nix-community/lanzaboote): Secure Boot for NixOS. +- [home-manager](https://github.com/nix-community/home-manager): Manage user environments using Nix. +- [terranix](https://terranix.org/): Create [OpenTofu](https://opentofu.org/) JSON files the NixOS way. +- [kubenix](https://kubenix.org/): Kubernetes management with Nix. +- [stylix](https://stylix.danth.me/): Apply consistent color schemes, fonts, and wallpapers. +- [hydra](https://github.com/NixOS/hydra): The Nix-based continuous build system. + +## 📁 Repository layout + +```txt +├── hosts - NixOS server configurations +├── lib - Reusable Nix libraries +├── modules - Reusable NixOS modules +├── nix - Flake-parts modules +├── overlays - Nix package overlays +├── secrets.nix - Age-encrypted secrets +├── terranix - Terraform Nix expressions +├── default.nix - Legacy support with flake-compat +├── flake.lock - Lock file for version pinning +└── flake.nix - Flakes configuration +``` + +## 🚀 Getting started + +### 📋 Prerequisites + +Before proceeding, ensure the following tools are installed: + +- [Git](https://git-scm.com/): For cloning and managing the repository. +- [direnv](https://direnv.net/): To automatically enter Nix environments. +- [Nix package manager](https://nixos.org/download#download-nix): Essential for Nix or NixOS operations. + +### 🛠️ Commands + +Run `menu` or `nix flake show` to view all commands and aliases provided by the devshell, as defined in [nix/devshell.nix](nix/devshell.nix). + +### 🖥️ NixOS + +#### 🔐 Secrets + +Secrets are encrypted using [agenix](https://github.com/ryantm/agenix). To add secret files and new hosts with their SSH public key, edit [nix/hosts.nix](nix/hosts.nix). + +- `agenix --edit` edits FILE using $EDITOR +- `agenix --decrypt` decrypts FILE to STDOUT +- `agenix --rekey` re-encrypts all secrets with specified recipients + +#### 🏭 Development + +To begin, run `nix develop` in the source tree to enter the development shell, or use [direnv](https://direnv.net/) for automatic entry. Check [flake.nix](flake.nix) or run `nix flake show` to view the flake definition. Server definitions are described in the [hosts](hosts) folder. Module definitions are located in the [nix/modules.nix](nix/modules.nix) and [modules](modules) folders. + +#### 🧪 local Testing + +To build and run a local [QEMU](https://www.qemu.org/) VM, use the following steps: + +1. Build the system with: + + ```sh + nixos-rebuild build-vm --flake .#dev-vm + ``` + +2. Configure the network settings: + + ```sh + export QEMU_NET_OPTS="hostfwd=tcp::2221-:22" + ``` + +3. Start the VM: + + ```sh + result/bin/run-dev-vm-vm + ``` + +4. Access the VM via SSH: + + ```sh + ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@localhost -p 2221 + ``` + +#### 🎯 Deployment + +[deploy-rs](https://github.com/serokell/deploy-rs) is a straightforward deployment tool for NixOS systems. It is configured in [nix/deploy.nix](nix/deploy.nix), where you can adjust `autoRollback` or `magicRollback` options. + +To deploy, run: + +```sh +deploy .#dev-vm +``` + +For more information on usage, refer to the [`deploy --help`](https://github.com/serokell/deploy-rs) documentation. + +### 🪐 Terraform + +This project uses [OpenTofu](https://opentofu.org/) and [terranix](https://terranix.org/) for creating Terraform JSON files the Nix way. + +#### 🔗 Environment Variables + +Create a local and private [.envrc.local](.envrc.local) file to authenticate with remote services during local development and operations. + +- **AWS_ACCESS_KEY_ID** and **AWS_SECRET_ACCESS_KEY**: Required for accessing S3 services, crucial for state management. Refer to [Terraform S3 State](https://developer.hashicorp.com/terraform/language/settings/backends/s3) for more details. +- **GITHUB_TOKEN**: Authenticates against GitHub for repository access and API interactions. [Details](https://docs.github.com/en/actions/security-guides/automatic-token-authentication). +- **HYDRA_HOST**, **HYDRA_USERNAME**, **HYDRA_PASSWORD**: Configures and authenticates with a Hydra server for CI/CD operations. [Hydra provider documentation](https://github.com/DeterminateSystems/terraform-provider-hydra). +- **GRAFANA_AUTH**: Enables Grafana server authentication for dashboard access and API use. [Grafana provider usage](https://registry.terraform.io/providers/grafana/grafana/). +- **MINIO_ENABLE_HTTPS**, **MINIO_ENDPOINT**, **MINIO_ROOT_USER**, **MINIO_ROOT_PASSWORD**: Sets up MinIO services, ensuring secure and authenticated connections. [MinIO provider usage](https://registry.terraform.io/providers/aminueza/minio). + +#### 📦 State Management + +The [Terraform state](https://developer.hashicorp.com/terraform/language/state) is stored outside the repository in an S3 Bucket, configured in [terraform.nix](terranix/minio/terraform.nix) and hosted by [minio.nix](hosts/srxgp00/services/minio/default.nix). + +#### 🔧 Configuration + +Terraform version and providers are pinned and configured in [nix/terranix.nix](nix/terranix.nix). Terraform resources are declared in the [terranix](terranix) folder. + +#### 🕹️ Terraform Commands + +- `nix run .#tf-init` - Initializes the working directory. +- `nix run .#tf-state` - Performs basic state modifications. +- `nix run .#tf-import` - Import existing infrastructure resources. +- `nix run .#tf-validate` - Validates using [tfsec](https://github.com/aquasecurity/tfsec), configured in [tfsec.nix](terranix/tfsec.nix). +- `nix run .#tf-plan` - Creates the execution plan. +- `nix run .#tf-apply` - Executes the actions proposed in the plan. +- `nix run .#tf-destroy` - Destroys all remote objects. + +#### 🧰 Helpers + +- `nix run .#tf2nix resource.tf` - Converts HCL files to Nix. +- `nix run .#json2nix resource.yaml` - Converts JSON or YAML files to Nix. + +#### 🧩 Common Functions + +Generalized functions for reuse are in [lib/terraform.nix](lib/terraform.nix) and [nix/terranix.nix](nix/terranix.nix). + +### 🔄 Updates + +This project uses [nix flakes](https://nixos.wiki/wiki/Flakes) to manage [nixpkgs](https://github.com/NixOS/nixpkgs) versions. To upgrade, use `nix flake update` for all inputs or `nix flake update nixpkgs` to update a single flake input. + +To check if a remote system is behind your flake state, run `nix run .#nix-upgrades`: + +```sh +🔍 Scanning for upgradable hosts... + +dev-vm: ⚠️ Modified: 24.05.20240618.938aa15 +``` + +### 🤖 CI/CD + +I utilize the [Nix Hydra project](https://github.com/NixOS/hydra) to test and build all packages and hosts, strictly following the `Zero Hydra Failures` paradigm to ensure every build is successful and stable. + +You can view all our jobs and their statuses at [build.nix.srx.digital](https://build.nix.srx.digital/). + +## 🚧 Reporting issues + +If you experience any issues with the infrastructure, please [post a new issue to this repository](https://code.srx.digital/srx/srx-platform-nix/issues). + +## 💬 Contact + +Need help with Nix? Write me an e-mail to book an appointment for Nix/NixOS/DevOps related topics. You can find me at: + +- [SRX Digital - Development & Operations](https://srx.digital/) +- [Nix Hamburg Matrix channel](https://matrix.to/#/#nix-hh:curious.bio) for live discussions. + +## 📚 Links + +- [Nix packages search](https://search.nixos.org/packages) +- [NixOS options search](https://search.nixos.org/options) +- [Nix Manual](https://nix.dev/manual/nix/stable/) +- [NixOS Manual](https://nixos.org/manual/nixos/stable/) +- [NixOS & Flakes Book](https://nixos-and-flakes.thiscute.world/) +- [NixOS Wiki](https://nixos.wiki/wiki/Main_Page) +- [Awesome Nix](https://github.com/nix-communi/awesome-nix) + +## 📜 License + +All files in this repository are licensed under the terms of the MIT License (MIT). Please refer to the full license text in [LICENSE](LICENSE.md). diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..01fb7ce --- /dev/null +++ b/default.nix @@ -0,0 +1,14 @@ +{ system ? builtins.currentSystem, src ? ./. }: +let + inherit (lock.nodes.flake-compat.locked) owner repo rev narHash; + + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + + flake-compat = fetchTarball { + url = "https://github.com/${owner}/${repo}/archive/${rev}.tar.gz"; + sha256 = narHash; + }; + + flake = import flake-compat { inherit src system; }; +in +flake.defaultNix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..e62a21c --- /dev/null +++ b/flake.lock @@ -0,0 +1,2550 @@ +{ + "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": [ + "home-manager" + ], + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1718371084, + "narHash": "sha256-abpBi61mg0g+lFFU0zY4C6oP6fBwPzbHPKBGw676xsA=", + "owner": "ryantm", + "repo": "agenix", + "rev": "3a56735779db467538fb2e577eda28a9daacaca6", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "base16": { + "inputs": { + "fromYaml": "fromYaml" + }, + "locked": { + "lastModified": 1708890466, + "narHash": "sha256-LlrC09LoPi8OPYOGPXegD72v+//VapgAqhbOFS3i8sc=", + "owner": "SenchoPens", + "repo": "base16.nix", + "rev": "665b3c6748534eb766c777298721cece9453fdae", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "base16.nix", + "type": "github" + } + }, + "base16-fish": { + "flake": false, + "locked": { + "lastModified": 1622559957, + "narHash": "sha256-PebymhVYbL8trDVVXxCvZgc0S5VxI7I1Hv4RMSquTpA=", + "owner": "tomyun", + "repo": "base16-fish", + "rev": "2f6dd973a9075dabccd26f1cded09508180bf5fe", + "type": "github" + }, + "original": { + "owner": "tomyun", + "repo": "base16-fish", + "type": "github" + } + }, + "base16-foot": { + "flake": false, + "locked": { + "lastModified": 1696725948, + "narHash": "sha256-65bz2bUL/yzZ1c8/GQASnoiGwaF8DczlxJtzik1c0AU=", + "owner": "tinted-theming", + "repo": "base16-foot", + "rev": "eedbcfa30de0a4baa03e99f5e3ceb5535c2755ce", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-foot", + "type": "github" + } + }, + "base16-helix": { + "flake": false, + "locked": { + "lastModified": 1696727917, + "narHash": "sha256-FVrbPk+NtMra0jtlC5oxyNchbm8FosmvXIatkRbYy1g=", + "owner": "tinted-theming", + "repo": "base16-helix", + "rev": "dbe1480d99fe80f08df7970e471fac24c05f2ddb", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-helix", + "type": "github" + } + }, + "base16-kitty": { + "flake": false, + "locked": { + "lastModified": 1665001328, + "narHash": "sha256-aRaizTYPpuWEcvoYE9U+YRX+Wsc8+iG0guQJbvxEdJY=", + "owner": "kdrag0n", + "repo": "base16-kitty", + "rev": "06bb401fa9a0ffb84365905ffbb959ae5bf40805", + "type": "github" + }, + "original": { + "owner": "kdrag0n", + "repo": "base16-kitty", + "type": "github" + } + }, + "base16-schemes": { + "flake": false, + "locked": { + "lastModified": 1702718998, + "narHash": "sha256-VTczZi1C4WSzejpTFbneMonAdarRLtDnFehVxWs6ad0=", + "owner": "tinted-theming", + "repo": "base16-schemes", + "rev": "2b6f2d0677216ddda50c9cabd6ee70fae4665f81", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-schemes", + "type": "github" + } + }, + "base16-tmux": { + "flake": false, + "locked": { + "lastModified": 1696725902, + "narHash": "sha256-wDPg5elZPcQpu7Df0lI5O8Jv4A3T6jUQIVg63KDU+3Q=", + "owner": "tinted-theming", + "repo": "base16-tmux", + "rev": "c02050bebb60dbb20cb433cd4d8ce668ecc11ba7", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-tmux", + "type": "github" + } + }, + "base16-vim": { + "flake": false, + "locked": { + "lastModified": 1716150083, + "narHash": "sha256-ZMhnNmw34ogE5rJZrjRv5MtG3WaqKd60ds2VXvT6hEc=", + "owner": "tinted-theming", + "repo": "base16-vim", + "rev": "6e955d704d046b0dc3e5c2d68a2a6eeffd2b5d3d", + "type": "github" + }, + "original": { + "owner": "tinted-theming", + "repo": "base16-vim", + "type": "github" + } + }, + "bats-assert": { + "flake": false, + "locked": { + "lastModified": 1636059754, + "narHash": "sha256-ewME0l27ZqfmAwJO4h5biTALc9bDLv7Bl3ftBzBuZwk=", + "owner": "bats-core", + "repo": "bats-assert", + "rev": "34551b1d7f8c7b677c1a66fc0ac140d6223409e5", + "type": "github" + }, + "original": { + "owner": "bats-core", + "repo": "bats-assert", + "type": "github" + } + }, + "bats-support": { + "flake": false, + "locked": { + "lastModified": 1548869839, + "narHash": "sha256-Gr4ntadr42F2Ks8Pte2D4wNDbijhujuoJi4OPZnTAZU=", + "owner": "bats-core", + "repo": "bats-support", + "rev": "d140a65044b2d6810381935ae7f0c94c7023c8c3", + "type": "github" + }, + "original": { + "owner": "bats-core", + "repo": "bats-support", + "type": "github" + } + }, + "blobs": { + "flake": false, + "locked": { + "lastModified": 1604995301, + "narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=", + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "blobs", + "type": "gitlab" + } + }, + "cachix": { + "inputs": { + "devenv": "devenv_2", + "flake-compat": [ + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "pre-commit-hooks": [ + "devenv", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1712055811, + "narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=", + "owner": "cachix", + "repo": "cachix", + "rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "cachix", + "type": "github" + } + }, + "cadquery-src": { + "flake": false, + "locked": { + "lastModified": 1702838737, + "narHash": "sha256-Ng3Ehf9E5q3VQ6qf7P9lVnpsS1mWmTTV4nEnDKU6OVA=", + "owner": "CadQuery", + "repo": "cadquery", + "rev": "245b6f39e597d324cbe8652b385a2130cdce545b", + "type": "github" + }, + "original": { + "owner": "CadQuery", + "repo": "cadquery", + "rev": "245b6f39e597d324cbe8652b385a2130cdce545b", + "type": "github" + } + }, + "commonmark-simple": { + "flake": false, + "locked": { + "lastModified": 1707333942, + "narHash": "sha256-o1am93UXviPVdwwPPL5DcD8M4gwFple8SKw/lVmixa8=", + "owner": "srid", + "repo": "commonmark-simple", + "rev": "0308362957d77eea462c2c99d110820fbf30b4b8", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "commonmark-simple", + "type": "github" + } + }, + "commonmark-simple_2": { + "flake": false, + "locked": { + "lastModified": 1705078713, + "narHash": "sha256-YgDHJG8M47ZXGLWu8o7MhXbIrgQ0Ai32Gr8nKvZGGw8=", + "owner": "srid", + "repo": "commonmark-simple", + "rev": "fc106c94f781f6a35ef66900880edc08cbe3b034", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "commonmark-simple", + "type": "github" + } + }, + "commonmark-wikilink": { + "flake": false, + "locked": { + "lastModified": 1711394028, + "narHash": "sha256-eu5gMmgRz6Y51TBCaB26uJKNN3z1LRfUcTV4+PMy5Gw=", + "owner": "srid", + "repo": "commonmark-wikilink", + "rev": "57dcf665082ffc1b6f35a427e203ed115821b15c", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "commonmark-wikilink", + "type": "github" + } + }, + "commonmark-wikilink_2": { + "flake": false, + "locked": { + "lastModified": 1705502834, + "narHash": "sha256-79fzI4fPhCkfusDXctQwwmjIcWMrLfTvUtKBY32asuM=", + "owner": "srid", + "repo": "commonmark-wikilink", + "rev": "f6d7bdf7f1fce09ba2a4259b0306b0eef24c0cf7", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "commonmark-wikilink", + "type": "github" + } + }, + "cq-editor-src": { + "flake": false, + "locked": { + "lastModified": 1701895648, + "narHash": "sha256-mHXEaA6vphps6F0WemdB6fGRY4lzpcxLU7WuYEp8c20=", + "owner": "CadQuery", + "repo": "CQ-editor", + "rev": "4ef178af06d24a53fee87d576f8cada14c0111a3", + "type": "github" + }, + "original": { + "owner": "CadQuery", + "repo": "CQ-editor", + "rev": "4ef178af06d24a53fee87d576f8cada14c0111a3", + "type": "github" + } + }, + "cq-flake": { + "inputs": { + "cadquery-src": "cadquery-src", + "cq-editor-src": "cq-editor-src", + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": "nixpkgs", + "ocp-src": "ocp-src", + "ocp-stubs-src": "ocp-stubs-src", + "pybind11-stubgen-src": "pybind11-stubgen-src", + "pywrap-src": "pywrap-src" + }, + "locked": { + "lastModified": 1703111559, + "narHash": "sha256-nlpTdCXw+/EVWAOtnMuFz0pudsiY4mpofYPESAi8+oY=", + "owner": "vinszent", + "repo": "cq-flake", + "rev": "cdccdf10d5cb3cf286e65db294fe72f548d2832b", + "type": "github" + }, + "original": { + "owner": "vinszent", + "repo": "cq-flake", + "type": "github" + } + }, + "crane": { + "inputs": { + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1718474113, + "narHash": "sha256-UKrfy/46YF2TRnxTtKCYzqf2f5ZPRRWwKCCJb7O5X8U=", + "owner": "ipetkov", + "repo": "crane", + "rev": "0095fd8ea00ae0a9e6014f39c375e40c2fbd3386", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "deploy-rs": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "nixpkgs": [ + "nixpkgs" + ], + "utils": [ + "flake-utils" + ] + }, + "locked": { + "lastModified": 1718194053, + "narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=", + "owner": "serokell", + "repo": "deploy-rs", + "rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "deploy-rs", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": [ + "flake-compat" + ], + "nix": "nix_2", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": [ + "git-hooks" + ] + }, + "locked": { + "lastModified": 1719953558, + "narHash": "sha256-7S0E9elPniVfV0pq2FCNgTXirl9MqYMDVIafmSzmGcU=", + "owner": "cachix", + "repo": "devenv", + "rev": "a7fa60374d7830ee978a06652a9f6e26b4aba30c", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv_2": { + "inputs": { + "flake-compat": [ + "devenv", + "cachix", + "flake-compat" + ], + "nix": "nix", + "nixpkgs": "nixpkgs_2", + "poetry2nix": "poetry2nix", + "pre-commit-hooks": [ + "devenv", + "cachix", + "pre-commit-hooks" + ] + }, + "locked": { + "lastModified": 1708704632, + "narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=", + "owner": "cachix", + "repo": "devenv", + "rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "python-rewrite", + "repo": "devenv", + "type": "github" + } + }, + "devshell": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717408969, + "narHash": "sha256-Q0OEFqe35fZbbRPPRdrjTUUChKVhhWXz3T9ZSKmaoVY=", + "owner": "numtide", + "repo": "devshell", + "rev": "1ebbe68d57457c8cae98145410b164b5477761f4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719864345, + "narHash": "sha256-e4Pw+30vFAxuvkSTaTypd9zYemB/QlWcH186dsGT+Ms=", + "owner": "nix-community", + "repo": "disko", + "rev": "544a80a69d6e2da04e4df7ec8210a858de8c7533", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "dns": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719459426, + "narHash": "sha256-4Kn9Pb3lvsik/VYsEAYgXpkcmLhrr0tTE6oIT2PMSPA=", + "owner": "nix-community", + "repo": "dns.nix", + "rev": "e6693931023206f1f3c2bfc57d2c98b5f27f52e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dns.nix", + "type": "github" + } + }, + "dns_2": { + "inputs": { + "flake-utils": [ + "srx-nixos-shadow", + "flake-utils" + ], + "nixpkgs": [ + "srx-nixos-shadow", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719459426, + "narHash": "sha256-4Kn9Pb3lvsik/VYsEAYgXpkcmLhrr0tTE6oIT2PMSPA=", + "owner": "nix-community", + "repo": "dns.nix", + "rev": "e6693931023206f1f3c2bfc57d2c98b5f27f52e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "dns.nix", + "type": "github" + } + }, + "ema": { + "inputs": { + "emanote": "emanote_2", + "flake-parts": [ + "srx-nixos-shadow", + "emanote", + "flake-parts" + ], + "flake-root": [ + "srx-nixos-shadow", + "emanote", + "flake-root" + ], + "haskell-flake": [ + "srx-nixos-shadow", + "emanote", + "haskell-flake" + ], + "nixpkgs": [ + "srx-nixos-shadow", + "emanote", + "nixpkgs" + ], + "treefmt-nix": [ + "srx-nixos-shadow", + "emanote", + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1710101403, + "narHash": "sha256-7n+2ekoXM5ltDoirVyCX3Ob94dm7L8SllI1JMmFmeGA=", + "owner": "srid", + "repo": "ema", + "rev": "51566e4155602b0a243a369b37dc503ebdebabce", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "ema", + "type": "github" + } + }, + "ema_2": { + "inputs": { + "flake-parts": [ + "srx-nixos-shadow", + "emanote", + "ema", + "emanote", + "flake-parts" + ], + "flake-root": [ + "srx-nixos-shadow", + "emanote", + "ema", + "emanote", + "flake-root" + ], + "haskell-flake": [ + "srx-nixos-shadow", + "emanote", + "ema", + "emanote", + "haskell-flake" + ], + "nixpkgs": [ + "srx-nixos-shadow", + "emanote", + "ema", + "emanote", + "nixpkgs" + ], + "treefmt-nix": [ + "srx-nixos-shadow", + "emanote", + "ema", + "emanote", + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1707484760, + "narHash": "sha256-2wHRjoFJUpVnH7H/80bnaw8h3WELZqP9dM6DfjXWtAo=", + "owner": "srid", + "repo": "ema", + "rev": "e3539ddd27b72a6bb90c8614ae63c70ff3351936", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "ema", + "type": "github" + } + }, + "emanote": { + "inputs": { + "commonmark-simple": "commonmark-simple", + "commonmark-wikilink": "commonmark-wikilink", + "ema": "ema", + "emanote-template": "emanote-template_2", + "flake-parts": [ + "srx-nixos-shadow", + "flake-parts" + ], + "flake-root": "flake-root_3", + "haskell-flake": "haskell-flake_2", + "heist-extra": "heist-extra_2", + "nix-health": "nix-health", + "nixpkgs": [ + "srx-nixos-shadow", + "nixpkgs" + ], + "systems": "systems_6", + "treefmt-nix": "treefmt-nix_2", + "unionmount": "unionmount_2" + }, + "locked": { + "lastModified": 1716931809, + "narHash": "sha256-VO93zEGfBaJc1tLRQeDgnqxqXjhXZhjfED+NvyZgZu8=", + "owner": "srid", + "repo": "emanote", + "rev": "fcf67dca2e7a95e4c5ac187586dc1e92dea530cf", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "emanote", + "type": "github" + } + }, + "emanote-template": { + "flake": false, + "locked": { + "lastModified": 1703877265, + "narHash": "sha256-2xdikzzHrIHr1s2pAJrBJU8mZP258Na3V4P4RWteDZM=", + "owner": "srid", + "repo": "emanote-template", + "rev": "9d458b63c80162519ae55814e60f17cc9d3f95a3", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "emanote-template", + "type": "github" + } + }, + "emanote-template_2": { + "flake": false, + "locked": { + "lastModified": 1711847690, + "narHash": "sha256-A/5b7vB1+FI2qsuPJL/pZ9CkWozSCbOoaqqN4y+Pmxc=", + "owner": "srid", + "repo": "emanote-template", + "rev": "32330b5e3bdca89ca67f5c212be6db43dbb13cd8", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "emanote-template", + "type": "github" + } + }, + "emanote_2": { + "inputs": { + "commonmark-simple": "commonmark-simple_2", + "commonmark-wikilink": "commonmark-wikilink_2", + "ema": "ema_2", + "emanote-template": "emanote-template", + "flake-parts": "flake-parts_2", + "flake-root": "flake-root_2", + "haskell-flake": "haskell-flake", + "heist-extra": "heist-extra", + "nixpkgs": "nixpkgs_4", + "systems": "systems_5", + "treefmt-nix": "treefmt-nix", + "unionmount": "unionmount" + }, + "locked": { + "lastModified": 1709754457, + "narHash": "sha256-JBpIQsCSaQzLY5LnCO9xj3O7nnv0ekgO1ZTSkevRfi4=", + "owner": "srid", + "repo": "emanote", + "rev": "922f79430416b09e91d735a27b01ddbb48ef7b83", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "emanote", + "type": "github" + } + }, + "firefox-addons": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "dir": "pkgs/firefox-addons", + "lastModified": 1719875691, + "narHash": "sha256-DtfpH7yivPHcfXV0EL70NwCKlg6nVTZGNngWkPshQjM=", + "owner": "rycee", + "repo": "nur-expressions", + "rev": "f2c6c0e41d6c2c82524b9d104bcfd1750a426d1b", + "type": "gitlab" + }, + "original": { + "dir": "pkgs/firefox-addons", + "owner": "rycee", + "repo": "nur-expressions", + "type": "gitlab" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "locked": { + "lastModified": 1717312683, + "narHash": "sha256-FrlieJH50AuvagamEvWMIE6D2OAnERuDboFDYAED/dE=", + "owner": "nix-community", + "repo": "flake-compat", + "rev": "38fd3954cf65ce6faf3d0d45cd26059e059f07ea", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_3": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_4": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719877454, + "narHash": "sha256-g5N1yyOSsPNiOlFfkuI/wcUjmtah+nxdImJqrSATjOU=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "4e3583423212f9303aa1a6337f8dffb415920e4f", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1704982712, + "narHash": "sha256-2Ptt+9h8dczgle2Oo6z5ni5rt/uLMG47UFTR1ry/wgg=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "07f6395285469419cf9d078f59b5b49993198c00", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { + "inputs": { + "nixpkgs-lib": [ + "srx-nixos-shadow", + "hercules-ci-effects", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-root": { + "locked": { + "lastModified": 1713493429, + "narHash": "sha256-ztz8JQkI08tjKnsTpfLqzWoKFQF4JGu2LRz8bkdnYUk=", + "owner": "srid", + "repo": "flake-root", + "rev": "bc748b93b86ee76e2032eecda33440ceb2532fcd", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, + "flake-root_2": { + "locked": { + "lastModified": 1692742795, + "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", + "owner": "srid", + "repo": "flake-root", + "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, + "flake-root_3": { + "locked": { + "lastModified": 1692742795, + "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", + "owner": "srid", + "repo": "flake-root", + "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_7" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "fromYaml": { + "flake": false, + "locked": { + "lastModified": 1689549921, + "narHash": "sha256-iX0pk/uB019TdBGlaJEWvBCfydT6sRq+eDcGPifVsCM=", + "owner": "SenchoPens", + "repo": "fromYaml", + "rev": "11fbbbfb32e3289d3c631e0134a23854e7865c84", + "type": "github" + }, + "original": { + "owner": "SenchoPens", + "repo": "fromYaml", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1719259945, + "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "git-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_4", + "gitignore": "gitignore_2", + "nixpkgs": [ + "nixvim", + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719259945, + "narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "git-hooks", + "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" + } + }, + "gitignore_2": { + "inputs": { + "nixpkgs": [ + "nixvim", + "git-hooks", + "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" + } + }, + "gnome-shell": { + "flake": false, + "locked": { + "lastModified": 1713702291, + "narHash": "sha256-zYP1ehjtcV8fo+c+JFfkAqktZ384Y+y779fzmR9lQAU=", + "owner": "GNOME", + "repo": "gnome-shell", + "rev": "0d0aadf013f78a7f7f1dc984d0d812971864b934", + "type": "github" + }, + "original": { + "owner": "GNOME", + "ref": "46.1", + "repo": "gnome-shell", + "type": "github" + } + }, + "haskell-flake": { + "locked": { + "lastModified": 1709233214, + "narHash": "sha256-kraFY5MmY7yxsEtSF8qPrFVmA6MXkF+sJfo7EV1dcY8=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "3a8c1b58cff60886260156a20a3b3ad725bbf885", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "haskell-flake", + "type": "github" + } + }, + "haskell-flake_2": { + "locked": { + "lastModified": 1712823089, + "narHash": "sha256-AGkk2WK/E9mLcoEdfegZ1aYNh6HtOdPuEx4O+r44u3I=", + "owner": "srid", + "repo": "haskell-flake", + "rev": "92e393141a123c9695bc15dbe1ca0a1b7fef142b", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "haskell-flake", + "type": "github" + } + }, + "heist-extra": { + "flake": false, + "locked": { + "lastModified": 1706086475, + "narHash": "sha256-scXMVFKSaS4Wi4y6I84oPKHaTmLECsvq8eLxGL0XH5o=", + "owner": "srid", + "repo": "heist-extra", + "rev": "c6d8ef79b415fab276fb461d5860bbf2628e6e43", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "heist-extra", + "type": "github" + } + }, + "heist-extra_2": { + "flake": false, + "locked": { + "lastModified": 1710541479, + "narHash": "sha256-9e4U78eutom6D3EJqsCdV8iQxNgYA/pi001r5CZdm0A=", + "owner": "srid", + "repo": "heist-extra", + "rev": "589b7636f620dcdfc0dc07dea720feed1ab3e0fa", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "heist-extra", + "type": "github" + } + }, + "hercules-ci-effects": { + "inputs": { + "flake-parts": "flake-parts_3", + "nixpkgs": "nixpkgs_5" + }, + "locked": { + "lastModified": 1719226092, + "narHash": "sha256-YNkUMcCUCpnULp40g+svYsaH1RbSEj6s4WdZY/SHe38=", + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "rev": "11e4b8dc112e2f485d7c97e1cee77f9958f498f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "hercules-ci-effects", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719827385, + "narHash": "sha256-qs+nU20Sm8czHg3bhGCqiH+8e13BJyRrKONW34g3i50=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "391ca6e950c2525b4f853cbe29922452c14eda82", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-24.05", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1719091691, + "narHash": "sha256-AxaLX5cBEcGtE02PeGsfscSb/fWMnyS7zMWBXQWDKbE=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "23c1f06316b67cb5dabdfe2973da3785cfe9c34a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "kubenix": { + "inputs": { + "flake-compat": "flake-compat_3", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_4", + "treefmt": "treefmt" + }, + "locked": { + "lastModified": 1719313214, + "narHash": "sha256-3CY/B/60A5rikhU5OlgDdNZMsOSIA1MteA2UPm4EHU0=", + "owner": "hall", + "repo": "kubenix", + "rev": "d6ddf1b4e8804e3c9564696a493ac14c0bcb19e2", + "type": "github" + }, + "original": { + "owner": "hall", + "repo": "kubenix", + "type": "github" + } + }, + "lanzaboote": { + "inputs": { + "crane": "crane", + "flake-compat": [ + "flake-compat" + ], + "flake-parts": [ + "flake-parts" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks-nix": [ + "git-hooks" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1719818887, + "narHash": "sha256-Bogl1pJlgby7OpR16jp8zwOWV7FHRxCsnNxHcisyIq0=", + "owner": "nix-community", + "repo": "lanzaboote", + "rev": "0e6457c98547ec8866714d4222545e7e8c1ae429", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "lanzaboote", + "type": "github" + } + }, + "microvm": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "spectrum": "spectrum" + }, + "locked": { + "lastModified": 1719525795, + "narHash": "sha256-nWGOQgqyhj7YynykVlM/DKxaYshhraV27R5tqQgWAEg=", + "owner": "astro", + "repo": "microvm.nix", + "rev": "3692c11ceed00632345b106b24a8cd2c9ffe5569", + "type": "github" + }, + "original": { + "owner": "astro", + "repo": "microvm.nix", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1712911606, + "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", + "owner": "domenkozar", + "repo": "nix", + "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719845423, + "narHash": "sha256-ZLHDmWAsHQQKnmfyhYSHJDlt8Wfjv6SQhl2qek42O7A=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "ec12b88104d6c117871fad55e931addac4626756", + "type": "github" + }, + "original": { + "owner": "lnl7", + "repo": "nix-darwin", + "type": "github" + } + }, + "nix-fast-build": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1719475157, + "narHash": "sha256-8zW6eWvE9T03cMpo/hY8RRZIsSCfs1zmsJOkEZzuYwM=", + "owner": "Mic92", + "repo": "nix-fast-build", + "rev": "030e586195c97424844965d2ce680140f6565c02", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "nix-fast-build", + "type": "github" + } + }, + "nix-filter": { + "locked": { + "lastModified": 1678109515, + "narHash": "sha256-C2X+qC80K2C1TOYZT8nabgo05Dw2HST/pSn6s+n6BO8=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "aa9ff6ce4a7f19af6415fb3721eaa513ea6c763c", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nix-filter_2": { + "locked": { + "lastModified": 1710156097, + "narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "3342559a24e85fc164b295c3444e8a139924675b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "poetry2nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688870561, + "narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "165b1650b753316aa7f1787f3005a8d2da0f5301", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nix-hamburg-website": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nix-filter": "nix-filter", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit": [ + "git-hooks" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1715951121, + "narHash": "sha256-9b2Ifbur3NJ3pidZxoffSLiXLpgpWJqAYtQFr/TWERE=", + "ref": "refs/heads/main", + "rev": "a101b3de595b168b95c18503be041557d3d3eb3f", + "revCount": 20, + "type": "git", + "url": "ssh://forgejo@code.srx.digital/nix-hamburg/nix-hamburg.astro.nix" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@code.srx.digital/nix-hamburg/nix-hamburg.astro.nix" + } + }, + "nix-health": { + "locked": { + "dir": "module", + "lastModified": 1716931776, + "narHash": "sha256-M4YqLtNAkj8pqG6dp7wHKz9EOecB3bWHp7WHyXIlMMc=", + "owner": "juspay", + "repo": "nix-health", + "rev": "2f8d8dc30121923192c78a8f5152c5c89fdf1809", + "type": "github" + }, + "original": { + "dir": "module", + "owner": "juspay", + "repo": "nix-health", + "type": "github" + } + }, + "nix-index-database": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719832725, + "narHash": "sha256-dr8DkeS74KVNTgi8BE0BiUKALb+EKlMIV86G2xPYO64=", + "owner": "nix-community", + "repo": "nix-index-database", + "rev": "2917972ed34ce292309b3a4976286f8b5c08db27", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-index-database", + "type": "github" + } + }, + "nix-vscode-extensions": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719883589, + "narHash": "sha256-Xiir5+DZfsVLzI/DmVdCL9rt6RbfNPS0uW0pdymm4wM=", + "owner": "nix-community", + "repo": "nix-vscode-extensions", + "rev": "3be7b0b799d739c3e15f3fd0a909d682c173962f", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-vscode-extensions", + "type": "github" + } + }, + "nix_2": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression_2" + }, + "locked": { + "lastModified": 1712911606, + "narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=", + "owner": "domenkozar", + "repo": "nix", + "rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.21", + "repo": "nix", + "type": "github" + } + }, + "nixlib": { + "locked": { + "lastModified": 1719708727, + "narHash": "sha256-XFNKtyirrGNdehpg7lMNm1skEcBApjqGhaHc/OI95HY=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "1bba8a624b3b9d4f68db94fb63aaeb46039ce9e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixos-anywhere": { + "inputs": { + "disko": [ + "disko" + ], + "flake-parts": [ + "flake-parts" + ], + "nixos-images": "nixos-images", + "nixos-stable": "nixos-stable", + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1719852663, + "narHash": "sha256-83rF68wdvOc9iyHSIxlgk/PMoFXilIYabOxC+meamyo=", + "owner": "nix-community", + "repo": "nixos-anywhere", + "rev": "f99d120b3788a286989db4e592a698f5d310d2f6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-anywhere", + "type": "github" + } + }, + "nixos-generators": { + "inputs": { + "nixlib": "nixlib", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719841141, + "narHash": "sha256-WOyohxFJJdfDvEB7N3eTcX44lNU2rZes1inHsyHL7mM=", + "owner": "nix-community", + "repo": "nixos-generators", + "rev": "140dcc2b9a0eb87ba5e9011076a1a7af19179ab1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-generators", + "type": "github" + } + }, + "nixos-hardware": { + "locked": { + "lastModified": 1719895800, + "narHash": "sha256-xNbjISJTFailxass4LmdWeV4jNhAlmJPwj46a/GxE6M=", + "owner": "NixOS", + "repo": "nixos-hardware", + "rev": "6e253f12b1009053eff5344be5e835f604bb64cd", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixos-hardware", + "type": "github" + } + }, + "nixos-images": { + "inputs": { + "nixos-stable": [ + "nixos-anywhere", + "nixos-stable" + ], + "nixos-unstable": [ + "nixos-anywhere", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1717994219, + "narHash": "sha256-ueTu01bYU5QXdL77psMkApYHpk339xNHg/M7ZzP3uPI=", + "owner": "nix-community", + "repo": "nixos-images", + "rev": "e2fd329c3a39a90bb43e1e2cf47c180ed57831bf", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixos-images", + "type": "github" + } + }, + "nixos-stable": { + "locked": { + "lastModified": 1717696253, + "narHash": "sha256-1+ua0ggXlYYPLTmMl3YeYYsBXDSCqT+Gw3u6l4gvMhA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9b5328b7f761a7bbdc0e332ac4cf076a3eedb89b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1703013332, + "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-24_05": { + "locked": { + "lastModified": 1717144377, + "narHash": "sha256-F/TKWETwB5RaR8owkPPi+SPJh83AQsm6KrQAlJ8v/uA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "805a384895c696f802a9bf5bf4720f37385df547", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-24.05", + "type": "indirect" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1703961334, + "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-regression_2": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1718811006, + "narHash": "sha256-0Y8IrGhRmBmT7HHXlxxepg2t8j1X90++qRN3lukGaIk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "03d771e513ce90147b65fe922d87d3a0356fc125", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1692808169, + "narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9201b5ff357e781bf014d0330d18555695df7ba8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1719838683, + "narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1704842529, + "narHash": "sha256-OTeQA+F8d/Evad33JMfuXC89VMetQbsU4qcaePchGr4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "eabe8d3eface69f5bb16c18f8662a702f50c20d5", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1713714899, + "narHash": "sha256-+z/XjO3QJs5rLE5UOf015gdVauVRQd2vZtsFkaXBq2Y=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6143fc5eeb9c4f00163267708e26191d1e918932", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixvim": { + "inputs": { + "devshell": [ + "devshell" + ], + "flake-compat": [ + "flake-compat" + ], + "flake-parts": [ + "flake-parts" + ], + "git-hooks": "git-hooks_2", + "home-manager": [ + "home-manager" + ], + "nix-darwin": "nix-darwin", + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1719929751, + "narHash": "sha256-CaXyTEyn5le7ad13CzigKAf8TI1iSy+PQFRkZZIatpM=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "3d969603481c745f8faa411f1e8b7c97517c67a3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, + "nur": { + "locked": { + "lastModified": 1719956777, + "narHash": "sha256-Vl8Tsb/XE1dcHvDiA50vJbVYEZBmdWnqaGWD3ONGTzE=", + "owner": "nix-community", + "repo": "NUR", + "rev": "4ecd7170303a6e7eb0e34d44dfaf157b7b146adb", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NUR", + "type": "github" + } + }, + "ocp-src": { + "flake": false, + "locked": { + "lastModified": 1701196143, + "narHash": "sha256-PMkMYEVBHt0i7ahgqF8jLhHHp7IRS7hd+JyydovNJ4A=", + "owner": "cadquery", + "repo": "ocp", + "rev": "4b98a5dc79fa900f7429975708f6a8c2e41cecd1", + "type": "github" + }, + "original": { + "owner": "cadquery", + "repo": "ocp", + "rev": "4b98a5dc79fa900f7429975708f6a8c2e41cecd1", + "type": "github" + } + }, + "ocp-stubs-src": { + "flake": false, + "locked": { + "lastModified": 1672527176, + "narHash": "sha256-m9Rg36GYlYfwEfF0PQJWEXf8TyM5HmjeuhJCODiurvY=", + "owner": "cadquery", + "repo": "ocp-stubs", + "rev": "e838ff400d5ee2f4a0579d2a713b19311855288f", + "type": "github" + }, + "original": { + "owner": "cadquery", + "repo": "ocp-stubs", + "type": "github" + } + }, + "poetry2nix": { + "inputs": { + "flake-utils": "flake-utils", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "devenv", + "cachix", + "devenv", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1692876271, + "narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=", + "owner": "nix-community", + "repo": "poetry2nix", + "rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "poetry2nix", + "type": "github" + } + }, + "pybind11-stubgen-src": { + "flake": false, + "locked": { + "lastModified": 1700678104, + "narHash": "sha256-76u1GcHPPh8oYQeQZDJ4K/so0U7F6rznZ1xa6syqI9s=", + "owner": "CadQuery", + "repo": "pybind11-stubgen", + "rev": "6dc681d838d3ec9a8a9aa4260c8392d3fb700ff0", + "type": "github" + }, + "original": { + "owner": "CadQuery", + "repo": "pybind11-stubgen", + "type": "github" + } + }, + "pywrap-src": { + "flake": false, + "locked": { + "lastModified": 1676015766, + "narHash": "sha256-QhAvJHV5tFq9bjKOzEpcudZNnmUmNVrJ+BLCZJhO31g=", + "owner": "CadQuery", + "repo": "pywrap", + "rev": "f3bcde70fd66a2d884fa60a7a9d9f6aa7c3b6e16", + "type": "github" + }, + "original": { + "owner": "CadQuery", + "repo": "pywrap", + "type": "github" + } + }, + "root": { + "inputs": { + "agenix": "agenix", + "base16-schemes": "base16-schemes", + "cq-flake": "cq-flake", + "deploy-rs": "deploy-rs", + "devenv": "devenv", + "devshell": "devshell", + "disko": "disko", + "dns": "dns", + "firefox-addons": "firefox-addons", + "flake-compat": "flake-compat_2", + "flake-parts": "flake-parts", + "flake-root": "flake-root", + "flake-utils": "flake-utils_2", + "git-hooks": "git-hooks", + "home-manager": "home-manager", + "impermanence": "impermanence", + "kubenix": "kubenix", + "lanzaboote": "lanzaboote", + "microvm": "microvm", + "nix-fast-build": "nix-fast-build", + "nix-hamburg-website": "nix-hamburg-website", + "nix-index-database": "nix-index-database", + "nix-vscode-extensions": "nix-vscode-extensions", + "nixos-anywhere": "nixos-anywhere", + "nixos-generators": "nixos-generators", + "nixos-hardware": "nixos-hardware", + "nixpkgs": "nixpkgs_3", + "nixvim": "nixvim", + "nur": "nur", + "simple-nixos-mailserver": "simple-nixos-mailserver", + "srvos": "srvos", + "srx-digital-website": "srx-digital-website", + "srx-nixos-shadow": "srx-nixos-shadow", + "stylix": "stylix", + "systems": "systems_8", + "terranix": "terranix", + "treefmt-nix": "treefmt-nix_3", + "vault-secrets": "vault-secrets" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "lanzaboote", + "flake-utils" + ], + "nixpkgs": [ + "lanzaboote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1718504420, + "narHash": "sha256-F2HT/abCfr0CDpkvXwYCscJyD66XDTLMVfdrIMRp2ck=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "0043c3f92304823cc2c0a4354b0feaa61dfb4cd9", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "simple-nixos-mailserver": { + "inputs": { + "blobs": "blobs", + "flake-compat": [ + "flake-compat" + ], + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-24_05": "nixpkgs-24_05" + }, + "locked": { + "lastModified": 1718697807, + "narHash": "sha256-Enla61WFisytTYbWygPynEbu8vozjeGc6Obkj2GRj7o=", + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "rev": "290a995de5c3d3f08468fa548f0d55ab2efc7b6b", + "type": "gitlab" + }, + "original": { + "owner": "simple-nixos-mailserver", + "repo": "nixos-mailserver", + "type": "gitlab" + } + }, + "spectrum": { + "flake": false, + "locked": { + "lastModified": 1708358594, + "narHash": "sha256-e71YOotu2FYA67HoC/voJDTFsiPpZNRwmiQb4f94OxQ=", + "ref": "refs/heads/main", + "rev": "6d0e73864d28794cdbd26ab7b37259ab0e1e044c", + "revCount": 614, + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + }, + "original": { + "type": "git", + "url": "https://spectrum-os.org/git/spectrum" + } + }, + "srvos": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719835186, + "narHash": "sha256-o0FB8SQVLOnbsYTk2Bt6gXwsfqEv4ZHsGP50/kM/gR0=", + "owner": "nix-community", + "repo": "srvos", + "rev": "14b3b0aa48fa291f1be26ab8948d5b9eadaed0b8", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "srvos", + "type": "github" + } + }, + "srx-digital-website": { + "inputs": { + "flake-parts": [ + "flake-parts" + ], + "nix-filter": "nix-filter_2", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit": [ + "git-hooks" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1715951577, + "narHash": "sha256-jeD4kUPQ/D6JejNcCOEVp3vR74E9ViRqyyoN0ADz7Xo=", + "ref": "refs/heads/main", + "rev": "bc1debcba00827af290174b4228b38e6eac19782", + "revCount": 58, + "type": "git", + "url": "ssh://forgejo@code.srx.digital/srx/srx.astro.nix" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@code.srx.digital/srx/srx.astro.nix" + } + }, + "srx-nixos-shadow": { + "inputs": { + "dns": "dns_2", + "emanote": "emanote", + "flake-compat": [ + "flake-compat" + ], + "flake-parts": [ + "flake-parts" + ], + "flake-utils": "flake-utils_3", + "hercules-ci-effects": "hercules-ci-effects", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": [ + "git-hooks" + ], + "treefmt-nix": [ + "treefmt-nix" + ] + }, + "locked": { + "lastModified": 1720092823, + "narHash": "sha256-OYIdNAbRFgLdkzhAxhjpaw5hLQPJQ5oKIht+zckAX8Y=", + "ref": "refs/heads/main", + "rev": "ee18bff34a774eaaa7def58f97a9321021d16287", + "revCount": 13, + "type": "git", + "url": "ssh://forgejo@code.srx.digital/srx/srx-nixos-shadow" + }, + "original": { + "type": "git", + "url": "ssh://forgejo@code.srx.digital/srx/srx-nixos-shadow" + } + }, + "stylix": { + "inputs": { + "base16": "base16", + "base16-fish": "base16-fish", + "base16-foot": "base16-foot", + "base16-helix": "base16-helix", + "base16-kitty": "base16-kitty", + "base16-tmux": "base16-tmux", + "base16-vim": "base16-vim", + "flake-compat": [ + "flake-compat" + ], + "gnome-shell": "gnome-shell", + "home-manager": [ + "home-manager" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719525570, + "narHash": "sha256-xSO/H67GAHEW0siD2PHoO/e97MbROL3r3s5SpF6A6Dc=", + "owner": "danth", + "repo": "stylix", + "rev": "1ff9d37d27377bfe8994c24a8d6c6c1734ffa116", + "type": "github" + }, + "original": { + "owner": "danth", + "repo": "stylix", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "id": "systems", + "type": "indirect" + } + }, + "systems_5": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_8": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "terranix": { + "inputs": { + "bats-assert": "bats-assert", + "bats-support": "bats-support", + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ], + "terranix-examples": "terranix-examples" + }, + "locked": { + "lastModified": 1695406838, + "narHash": "sha256-xiUfVD6rtsVWFotVtUW3Q1nQh4obKzgvpN1wqZuGXvM=", + "owner": "terranix", + "repo": "terranix", + "rev": "fc9077ca02ab5681935dbf0ecd725c4d889b9275", + "type": "github" + }, + "original": { + "owner": "terranix", + "repo": "terranix", + "type": "github" + } + }, + "terranix-examples": { + "locked": { + "lastModified": 1636300201, + "narHash": "sha256-0n1je1WpiR6XfCsvi8ZK7GrpEnMl+DpwhWaO1949Vbc=", + "owner": "terranix", + "repo": "terranix-examples", + "rev": "a934aa1cf88f6bd6c6ddb4c77b77ec6e1660bd5e", + "type": "github" + }, + "original": { + "owner": "terranix", + "repo": "terranix-examples", + "type": "github" + } + }, + "treefmt": { + "inputs": { + "nixpkgs": [ + "kubenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688026376, + "narHash": "sha256-qJmkr9BWDpqblk4E9/rCsAEl39y2n4Ycw6KRopvpUcY=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "df3f32b0cc253dfc7009b7317e8f0e7ccd70b1cf", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "srx-nixos-shadow", + "emanote", + "ema", + "emanote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1693468138, + "narHash": "sha256-DddblCahuTW8K0ncPOheTlG3igE8b15LJjafF1PWhOo=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "6930a5ba0a722385baf273885a03f561dcb1af67", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_2": { + "inputs": { + "nixpkgs": [ + "srx-nixos-shadow", + "emanote", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1711963903, + "narHash": "sha256-N3QDhoaX+paWXHbEXZapqd1r95mdshxToGowtjtYkGI=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "49dc4a92b02b8e68798abd99184f228243b6e3ac", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "treefmt-nix_3": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1719887753, + "narHash": "sha256-p0B2r98UtZzRDM5miGRafL4h7TwGRC4DII+XXHDHqek=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "bdb6355009562d8f9313d9460c0d3860f525bc6c", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "unionmount": { + "flake": false, + "locked": { + "lastModified": 1691619410, + "narHash": "sha256-V9/OcGu9cy4kV9jta12A6w5BEj8awSEVYrXPpg8YckQ=", + "owner": "srid", + "repo": "unionmount", + "rev": "ed73b627f88c8f021f41ba4b518ba41beff9df42", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "unionmount", + "type": "github" + } + }, + "unionmount_2": { + "flake": false, + "locked": { + "lastModified": 1710078535, + "narHash": "sha256-gKBgBtuiRTD3/3EeY8aMgFzuaSEffJacBxsCB3ct1eg=", + "owner": "srid", + "repo": "unionmount", + "rev": "41ae982fa118770bf4d3a3f2d48ac1ffb61c9f09", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "unionmount", + "type": "github" + } + }, + "vault-secrets": { + "inputs": { + "flake-compat": [ + "flake-compat" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1714988039, + "narHash": "sha256-ZYPX1Skhy9ZEfeRkAzdqO+MvjBdF4a7blrXcTJ3q/Yw=", + "owner": "serokell", + "repo": "vault-secrets", + "rev": "44ef2078d9149aa3b23fe132e8c8d8bbd624c06c", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "vault-secrets", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..14952dd --- /dev/null +++ b/flake.nix @@ -0,0 +1,285 @@ +{ + description = "SRX NixOS Platform"; + + nixConfig = { + extra-trusted-substituters = [ + "https://nix-config.cachix.org" + "https://nix-community.cachix.org" + "https://tweag-jupyter.cachix.org" + "https://serokell.cachix.org" + "https://cache.nix.srx.digital" + ]; + extra-trusted-public-keys = [ + "nix-config.cachix.org-1:Vd6raEuldeIZpttVQfrUbLvXJHzzzkS0pezXCVVjDG4=" + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "tweag-jupyter.cachix.org-1:UtNH4Zs6hVUFpFBTLaA4ejYavPo5EFFqgd7G7FxGW9g=" + "serokell.cachix.org-1:5DscEJD6c1dD1Mc/phTIbs13+iW22AVbx0HqiSb+Lq8=" + "cache.nix.srx.digital-1:+sJ/hAmjuhTpRakfhkCj7i2LoqNyBgm+YItJUSAWWlg=" + ]; + }; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05"; + + nixos-hardware.url = "github:NixOS/nixos-hardware"; + + nur.url = "github:nix-community/NUR"; + + nixos-anywhere = { + url = "github:nix-community/nixos-anywhere"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + disko.follows = "disko"; + treefmt-nix.follows = "treefmt-nix"; + }; + }; + + nixos-generators = { + url = "github:nix-community/nixos-generators"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nix-index-database = { + url = "github:nix-community/nix-index-database"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; + + flake-utils.url = "github:numtide/flake-utils"; + + flake-compat.url = "github:nix-community/flake-compat"; + + devenv = { + url = "github:cachix/devenv"; + inputs = { + nixpkgs.follows = "nixpkgs"; + pre-commit-hooks.follows = "git-hooks"; + flake-compat.follows = "flake-compat"; + }; + }; + + devshell = { + url = "github:numtide/devshell"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + flake-root.url = "github:srid/flake-root"; + + srvos = { + url = "github:nix-community/srvos"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + home-manager = { + url = "github:nix-community/home-manager/release-24.05"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + lanzaboote = { + url = "github:nix-community/lanzaboote"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + flake-parts.follows = "flake-parts"; + flake-utils.follows = "flake-utils"; + pre-commit-hooks-nix.follows = "git-hooks"; + }; + }; + + nix-fast-build = { + url = "github:Mic92/nix-fast-build"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + treefmt-nix.follows = "treefmt-nix"; + }; + }; + + systems.url = "github:nix-systems/default"; + + agenix = { + url = "github:ryantm/agenix"; + inputs = { + home-manager.follows = "home-manager"; + nixpkgs.follows = "nixpkgs"; + }; + }; + + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + nixvim = { + url = "github:nix-community/nixvim"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + flake-compat.follows = "flake-compat"; + devshell.follows = "devshell"; + home-manager.follows = "home-manager"; + treefmt-nix.follows = "treefmt-nix"; + }; + }; + + deploy-rs = { + url = "github:serokell/deploy-rs"; + inputs = { + flake-compat.follows = "flake-compat"; + nixpkgs.follows = "nixpkgs"; + utils.follows = "flake-utils"; + }; + }; + + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + git-hooks = { + url = "github:cachix/git-hooks.nix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + }; + }; + + base16-schemes = { + url = "github:tinted-theming/base16-schemes"; + flake = false; + }; + + stylix = { + url = "github:danth/stylix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + home-manager.follows = "home-manager"; + }; + }; + + kubenix = { + url = "github:hall/kubenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + + microvm = { + url = "github:astro/microvm.nix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + vault-secrets = { + url = "github:serokell/vault-secrets"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + }; + }; + + dns = { + url = "github:nix-community/dns.nix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + impermanence.url = "github:nix-community/impermanence"; + + simple-nixos-mailserver = { + url = "gitlab:simple-nixos-mailserver/nixos-mailserver"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + }; + }; + + terranix = { + url = "github:terranix/terranix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + nix-vscode-extensions = { + url = "github:nix-community/nix-vscode-extensions"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + flake-compat.follows = "flake-compat"; + }; + }; + + firefox-addons = { + url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-utils.follows = "flake-utils"; + }; + }; + + cq-flake = { + url = "github:vinszent/cq-flake"; + inputs.flake-utils.follows = "flake-utils"; + }; + + srx-nixos-shadow = { + url = "git+ssh://forgejo@code.srx.digital/srx/srx-nixos-shadow"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-compat.follows = "flake-compat"; + flake-parts.follows = "flake-parts"; + pre-commit-hooks.follows = "git-hooks"; + treefmt-nix.follows = "treefmt-nix"; + }; + }; + + srx-digital-website = { + url = "git+ssh://forgejo@code.srx.digital/srx/srx.astro.nix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + treefmt-nix.follows = "treefmt-nix"; + pre-commit.follows = "git-hooks"; + }; + }; + + nix-hamburg-website = { + url = "git+ssh://forgejo@code.srx.digital/nix-hamburg/nix-hamburg.astro.nix"; + inputs = { + nixpkgs.follows = "nixpkgs"; + flake-parts.follows = "flake-parts"; + treefmt-nix.follows = "treefmt-nix"; + pre-commit.follows = "git-hooks"; + }; + }; + }; + + outputs = inputs@ { flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "x86_64-linux" "aarch64-linux" ]; + imports = [ + ./nix/hosts.nix + ./nix/packages.nix + ./nix/modules.nix + ./nix/overlay.nix + ./nix/nixos.nix + ./nix/home-manager.nix + ./nix/deploy.nix + ./nix/devshell.nix + ./nix/terranix.nix + ]; + }; +} diff --git a/hosts/dev-vm/clevis.age b/hosts/dev-vm/clevis.age new file mode 100644 index 0000000000000000000000000000000000000000..036d92be750dd76f6e86157524f5b87c5489a1bb GIT binary patch literal 2422 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 * / 100 +rotation_distance: 22.6789511 +gear_ratio: 50:10 +microsteps: 32 +full_steps_per_rotation: 200 +nozzle_diameter: 0.400 +filament_diameter: 1.75 +heater_pin: PA2 +sensor_type: ATC Semitec 104GT-2 +sensor_pin: PF4 +min_temp: 10 +max_temp: 270 +max_power: 1.0 +min_extrude_temp: 170 +control: pid +pid_Kp: 21.464 +pid_Ki: 0.878 +pid_Kd: 131.198 +pressure_advance: 0.05 +pressure_advance_smooth_time: 0.040 + +## E0 on MOTOR6 +[tmc2209 extruder] +uart_pin: PE1 +interpolate: false +run_current: 0.5 +sense_resistor: 0.110 +stealthchop_threshold: 0 + +##################################################################### +# Bed Heater +##################################################################### + +## SSR Pin - HE1 +## Thermistor - TB +[heater_bed] +heater_pin: PA3 +sensor_type: Generic 3950 +sensor_pin: PF3 +## Adjust max_power so it doesn't exceed the SSR rating. The Omron G3NA-210B-DC5 SSR is rated at 4 amps without a heatsink. +## The formula is "4 / (Wattage_of_bed_heater / Mains_voltage) = max_power" +## If max_power is greater than 1.0, use 1.0 +max_power: 0.6 +min_temp: 0 +max_temp: 120 +control: pid +pid_Kp: 38.507 +pid_Ki: 0.820 +pid_Kd: 451.976 + +##################################################################### +# Probe +##################################################################### + +## Inductive Probe +## This probe is not used for Z height, only Quad Gantry Leveling +[probe] +# Omron TL-Q5MC2 NPN Inductive Probe (NC) +# https://www.mouser.de/datasheet/2/307/omrns03968_1-2279740.pdf +pin: PG15 +x_offset: 0 +y_offset: 25.0 +z_offset: 0 +speed: 10.0 +samples: 3 +samples_result: median +sample_retract_dist: 3.0 +samples_tolerance: 0.006 +samples_tolerance_retries: 3 + +##################################################################### +# Fan Control +##################################################################### + +## Print Cooling Fan - FAN0 +[fan] +pin: PA8 +kick_start_time: 0.5 +## Depending on your fan, you may need to increase this value +## if your fan will not start. Can change cycle_time (increase) +## if your fan is not able to slow down effectively +off_below: 0.10 + +## Hotend Fan - FAN1 +[heater_fan hotend_fan] +pin: PE5 +max_power: 1.0 +kick_start_time: 0.5 +heater: extruder +heater_temp: 50.0 +## If you are experiencing back flow, you can reduce fan_speed +#fan_speed: 1.0 + +## Controller fan - FAN2 +[controller_fan controller_fan] +pin: PD12 +kick_start_time: 0.5 +heater: heater_bed + +## Exhaust fan - FAN3 +#[heater_fan exhaust_fan] +#pin: PD13 +#max_power: 1.0 +#shutdown_speed: 0.0 +#kick_start_time: 5.0 +#heater: heater_bed +#heater_temp: 60 +#fan_speed: 1.0 + +##################################################################### +# LED Control +##################################################################### + +## Chamber Lighting - HE2 Connector +#[output_pin caselight] +##Octopus 1.0 & 1.1, Octopus PRO 1.0 +#pin: PB10 +##Octopus PRO 1.1 +#pin: PB0 +#pwm:true +#shutdown_value: 0 +#value:1 +#cycle_time: 0.01 + +[neopixel headlight] +## Stealthburner lighting - RGB_LED +pin: PB0 +chain_count: 3 +color_order: GRBW +initial_RED: 1.0 +initial_GREEN: 0.0 +initial_BLUE: 0.0 +initial_WHITE: 0.0 + +##################################################################### +# Additional Sensors +##################################################################### + +# [temperature_sensor chamber_temp] +# ## Chamber Temperature - T1 +# sensor_type: ATC Semitec 104NT-4-R025H42G +# sensor_pin: PF5 +# min_temp: 0 +# max_temp: 100 +# gcode_id: chamber_th + +##################################################################### +# Homing and Gantry Adjustment Routines +##################################################################### + +[idle_timeout] +timeout: 1800 + +[safe_z_home] +home_xy_position: 233,346 +speed:100 +z_hop:10 +z_hop_speed:10 + +[quad_gantry_level] +gantry_corners: + -60,-10 + 410,420 +points: + 50,25 + 50,275 + 300,275 + 300,25 +speed: 100 +horizontal_move_z: 10 +retries: 5 +retry_tolerance: 0.0075 +max_adjust: 10 + +[bed_mesh] +speed: 300 +horizontal_move_z: 15 +mesh_min: 40, 40 +mesh_max: 310,310 +fade_start: 0.6 +fade_end: 10.0 +probe_count: 5,5 +algorithm: bicubic + +[bed_mesh default] +version: 1 +points: + -0.095299, -0.102799, -0.102799, -0.097799, -0.102799 + -0.144049, -0.146549, -0.135299, -0.137799, -0.141549 + -0.159049, -0.156549, -0.141549, -0.141549, -0.159049 + -0.141549, -0.154049, -0.157799, -0.159049, -0.172799 + -0.097799, -0.120299, -0.120299, -0.110299, -0.109049 +x_count: 5 +y_count: 5 +mesh_x_pps: 2 +mesh_y_pps: 2 +algo: bicubic +tension: 0.2 +min_x: 40.0 +max_x: 310.0 +min_y: 40.0 +max_y: 310.0 + +######################################## +# EXP1 / EXP2 (display) pins +######################################## + +[board_pins] +aliases: + EXP1_1=PE8, + EXP1_2=PE7, + EXP1_3=PE9, + EXP1_4=PE10, + EXP1_5=PE12, + EXP1_6=PE13, + EXP1_7=PE14, + EXP1_8=PE15, + EXP1_9=, + EXP1_10=<5V>, + EXP2_1=PA6, + EXP2_2=PA5, + EXP2_3=PB1, + EXP2_4=PA4, + EXP2_5=PB2, + EXP2_6=PA7, + EXP2_7=PC15, + EXP2_8=, + EXP2_9=, + EXP2_10=<5V> + +##################################################################### +# Displays +##################################################################### + +[display] # mini12864 LCD Display +lcd_type: uc1701 +cs_pin: EXP1_3 +a0_pin: EXP1_4 +rst_pin: EXP1_5 +encoder_pins: ^EXP2_5, ^EXP2_3 +click_pin: ^!EXP1_2 +contrast: 63 +spi_software_miso_pin: EXP2_1 +spi_software_mosi_pin: EXP2_6 +spi_software_sclk_pin: EXP2_2 + +[neopixel btt_mini12864] # Neopixel RGB in mini12864 +pin: EXP1_6 +chain_count: 3 +initial_RED: 0.1 +initial_GREEN: 0.5 +initial_BLUE: 0.0 +color_order: RGB + +[delayed_gcode setdisplayneopixel] # Index 1 = display, Index 2 and 3 = Knob +initial_duration: 1 +gcode: + SET_LED LED=btt_mini12864 RED=1 GREEN=1 BLUE=1 INDEX=1 TRANSMIT=0 + SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=2 TRANSMIT=0 + SET_LED LED=btt_mini12864 RED=1 GREEN=0 BLUE=0 INDEX=3 + +[virtual_sdcard] +path: /var/lib/moonraker/gcodes + +[pause_resume] + +##################################################################### +# Macros +##################################################################### + +[gcode_macro PARK] +gcode: + {% set th = printer.toolhead %} + G0 X{th.axis_maximum.x // 2} Y{th.axis_maximum.y // 2} Z30 + +[gcode_macro G32] +gcode: + SAVE_GCODE_STATE NAME=STATE_G32 + G90 + G28 + QUAD_GANTRY_LEVEL + BED_MESH_CALIBRATE + G28 + PARK + RESTORE_GCODE_STATE NAME=STATE_G32 + +[gcode_macro PRINT_START] +gcode: + G32 ; home all axes + G90 ; absolute positioning + G1 Z20 F3000 ; move nozzle away from bed + +[gcode_macro PRINT_END] +gcode: + # safe anti-stringing move coords + {% set th = printer.toolhead %} + {% set x_safe = th.position.x + 20 * (1 if th.axis_maximum.x - th.position.x > 20 else -1) %} + {% set y_safe = th.position.y + 20 * (1 if th.axis_maximum.y - th.position.y > 20 else -1) %} + {% set z_safe = [th.position.z + 2, th.axis_maximum.z]|min %} + + SAVE_GCODE_STATE NAME=STATE_PRINT_END + + M400 ; wait for buffer to clear + G92 E0 ; zero the extruder + G1 E-5.0 F1800 ; retract filament + + TURN_OFF_HEATERS + + G90 ; absolute positioning + G0 X{x_safe} Y{y_safe} Z{z_safe} F20000 ; move nozzle to remove stringing + G0 X{th.axis_maximum.x//2} Y{th.axis_maximum.y - 2} F3600 ; park nozzle at rear + M107 ; turn off fan + + BED_MESH_CLEAR + + # The purpose of the SAVE_GCODE_STATE/RESTORE_GCODE_STATE + # command pair is to restore the printer's coordinate system + # and speed settings since the commands above change them. + # However, to prevent any accidental, unintentional toolhead + # moves when restoring the state, explicitly set MOVE=0. + RESTORE_GCODE_STATE NAME=STATE_PRINT_END MOVE=0 + +[gcode_macro CANCEL_PRINT] +rename_existing: BASE_CANCEL_PRINT +gcode: + M220 S100 ; Reset Speed factor override percentage to default (100%) + M221 S100 ; Reset Extrude factor override percentage to default (100%) + G91 ; Set coordinates to relative + {% if printer.extruder.temperature >= 170 %} + G1 F1800 E-1 ; Retract filament 3 mm to prevent oozing + {% endif %} + ;if all axis are homed, lift the hotend to leave room for hot filament to ooze and to keep it clear of the bed. + {% if printer.toolhead.homed_axes == "xyz" %} + G1 F6000 Z10 ; Move Z Axis up 10 mm to allow filament ooze freely + G90 ; Set coordinates to absolute + G1 X10 Y221 F1000 ; Move Printer Head Out of Way + {% endif %} + ;set part fan speed to zero. + M106 S0 + ;bed and hotend are left at the print temps in case I want to restart. + CLEAR_PAUSE + BASE_CANCEL_PRINT + +[gcode_macro INJECT_FILAMENT] +gcode: + {% set E = params.E|default(62) %} + M117 Injecting filament + G91 + G1 E{E} F2100 + G90 + +[gcode_macro CLEAN_NOZZLE] +gcode: + {% if "xyz" in printer.toolhead.homed_axes %} + {% if printer.extruder.temperature >= 200 %} + M117 Cleaning nozzle + G91 + G0 Z10 F10000 + SAVE_GCODE_STATE NAME=clean_nozzle + G90 + G0 X200 Y305 F10000 + SAVE_GCODE_STATE NAME=clean_nozzle_above + G0 Z1.4 F10000 + G0 X250 F10000 + G0 Y304 X200 + G0 Y305 X250 + G0 Y304 X200 + G0 Y305 X250 + G0 Y304 X200 + G0 Y304 X250 + G0 Y305 X200 + G0 Y304 X250 + G0 Y303 X200 + G0 Y303 X250 + G0 Y304 X200 + G0 Y303 X250 + G0 Y304 X200 + G0 Y305 X250 + G0 Y303 X200 + G0 Y305 X250 + RESTORE_GCODE_STATE NAME=clean_nozzle_above MOVE=1 + M117 Cleaned! + RESTORE_GCODE_STATE NAME=clean_nozzle MOVE=1 + G91 + G0 Z-10 F10000 + G90 + {% endif %} + {% else %} + { action_raise_error("Please home your axes!") } + M117 Please home first! + {% endif %} + +[gcode_macro PRIME_NOZZLE] +gcode: + {% set E = params.E|default(0.5) %} # retract size + {% if not "xyz" in printer.toolhead.homed_axes %} + { action_raise_error("Please home your axes!") } + M117 Please home first! + {% else %} + {% if not printer.extruder.temperature >= 200 %} + { action_raise_error("Heat up nozzle first!") } + M117 Heat up nozzle first! + {% else %} + {% if not printer["filament_switch_sensor toolhead_sensor"].filament_detected %} + G90 + G0 X200 Y305 F10000 + INJECT_FILAMENT + CLEAN_NOZZLE + {% endif %} + {% endif %} + {% endif %} + + +[gcode_macro EXTRUDER_MAINTENANCE] +gcode: + {% set th = printer.toolhead %} + G0 X{th.axis_maximum.x // 2} Y0 Z{th.axis_maximum.z // 2} diff --git a/hosts/srxfdm00/services/moonraker.nix b/hosts/srxfdm00/services/moonraker.nix new file mode 100644 index 0000000..08a80bd --- /dev/null +++ b/hosts/srxfdm00/services/moonraker.nix @@ -0,0 +1,44 @@ +{ lib, config, ... }: +{ + services.moonraker = { + enable = true; + group = "${config.services.klipper.group}"; + + allowSystemControl = true; + + settings = { + server = { + max_upload_size = 16384; + }; + octoprint_compat = { + enable_ufp = true; + webcam_enabled = true; + }; + zeroconf = { }; + history = { }; + authorization = { + force_logins = true; + cors_domains = [ + "*.local" + "*.lan" + "*://localhost:*" + "http://*.lan" + "http://*.local" + ]; + trusted_clients = [ + "10.0.0.0/8" + "127.0.0.0/8" + "169.254.0.0/16" + "172.16.0.0/12" + "192.168.1.0/24" + "FE80::/10" + "::1/128" + ]; + }; + }; + }; + + security.polkit.enable = lib.mkIf config.services.moonraker.allowSystemControl true; + + networking.firewall.allowedTCPPorts = [ config.services.moonraker.port ]; +} diff --git a/hosts/srxfdm00/services/octoprint.nix b/hosts/srxfdm00/services/octoprint.nix new file mode 100644 index 0000000..54240c6 --- /dev/null +++ b/hosts/srxfdm00/services/octoprint.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + services.octoprint = { + enable = true; + openFirewall = true; + plugins = with pkgs.octoprint.plugins; [ + themeify + stlviewer + ]; + }; +} diff --git a/hosts/srxfdm00/services/wireguard.nix b/hosts/srxfdm00/services/wireguard.nix new file mode 100644 index 0000000..75edb39 --- /dev/null +++ b/hosts/srxfdm00/services/wireguard.nix @@ -0,0 +1,39 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.12/24" ]; + networkConfig = { + IPMasquerade = "ipv4"; + IPForward = true; + }; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxfdm00/vpn_srx.age b/hosts/srxfdm00/vpn_srx.age new file mode 100644 index 0000000000000000000000000000000000000000..6cb04164b60fc7e014724423c35ba902cbae9752 GIT binary patch literal 1189 zcmZ9LDbM5t06-B4QUeCHW(2F6Z+l-PY|?XjO{d57m`PUjnrS0MgI?c8*ET|KDV6Eq;e-NV)GmffWZ zN)QOMDuhP3j;jT4(+fYV;E6<+Ez@9e;cf;Qm4mdJtpn1Cli<@zgrPN{85_E4&<@)m zVwf036>!DSox}Nz=xTkiZ-`a|_c9B>u0ykv8P!xQr39V6Wg&6RIml#|l&A0z)?JZo9 znK@A`a1unf;prM)VOG!N$?;my23m=@aWPRycg4~0G!VUI z-2fmrRMmuOp^r71g|vR#?Tzj1(GaUq(zU*FTanccebX}Gv87CP((pKH<37gcqS-hp zAZG>xj&gx*+X)60*A11MxE0PcVbjA{R70nE9#MAlI+K0wKrJ3FoU^{q-88RT+X8rU zaj`^?gGm^6ww-h76-Gk-0(%$#z~lUdsu~C^%?0F(2<~CYaSVUbwNi#r**(C3d0OkE z=7C`o7^9d#XaG7{meuoqXVU!=cSOj%FgpdavYfpL4EB3l$SHz>#tD_910YUn2#aNp zivfJFc93;T4IY95Ov#`LG^^#ZrqRfDhm9+>Q<@LTIKZB)TcnRPN|*pqB}kL2^xM?! z974FnB+747zQ_Gi(8Pmer`#>rZiAkwTFf4=9T~{%D3bBsfXIlJ01>hf3mH*9#pTxK zP?&-OCM@Pg&IX6gC1vu3#8hNU7dhn|xJS>y<)by4mzi}pbpf>gU?;YrE0MLE!@Ogc z@Myv3wZ?dCcNN7&Eg9R21YcPrdQ{q{J(3++G`XR3ZFjN>a6``A_Umx)Q>I|zb`d&H z=((<8TKA%hlH4x#$f|gI9tQzcODK$5D#83lQ89V_B0-1-|7tV!CEcQ=%!Y~96W4Sf zQG{vt8_wFXtv!%gvto9^)6Y@Aeiy5WEX~NdF=K{Lho;4`AcbU*X^D`>((9<&!%v8JPXE6D=ri;OV%|Nj Kp4|KN_x}Kw1dXx) literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/default.nix b/hosts/srxgp00/default.nix new file mode 100644 index 0000000..b17e06c --- /dev/null +++ b/hosts/srxgp00/default.nix @@ -0,0 +1,56 @@ +{ self, lib, ... }: +{ + imports = [ + self.nixosModules.roles-server + self.nixosModules.filesystems-zfs + self.nixosModules.services-security-tang + self.nixosModules.services-netboot + self.nixosModules.services-monitoring-loki + self.nixosModules.custom-dns-knot + + ./hardware.nix + ./storage.nix + ./services/wireguard + ./services/nginx + ./services/oauth2-proxy + # ./services/openldap + ./services/mysql + ./services/influxdb + ./services/postgresql + ./services/minio + ./services/restic + ./services/grafana + ./services/prometheus + ./services/keycloak + ./services/mailserver + ./services/coturn + ./services/dendrite + ./services/hydra + ./services/plausible + ./services/forgejo + ./services/vaultwarden + ./services/hedgedoc + ./services/nextcloud + ./services/paperless + ./services/jellyfin + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxgp00"; + domain = "srx.digital"; + hostId = "8556b001"; + }; + + systemd.network.networks."10-uplink".networkConfig.Address = "2a01:4f9:6b:2573::1/64"; + + services.knot.settings.server = { + identity = "ns1.srx.dev"; + listen = lib.mkForce [ + "10.80.0.1@53" + "65.108.77.254@53" + "2a01:4f9:6b:2573::1@53" + ]; + }; +} diff --git a/hosts/srxgp00/hardware.nix b/hosts/srxgp00/hardware.nix new file mode 100644 index 0000000..99ced29 --- /dev/null +++ b/hosts/srxgp00/hardware.nix @@ -0,0 +1,22 @@ +{ self, inputs, modulesPath, ... }: +{ + imports = with inputs; [ + (modulesPath + "/installer/scan/not-detected.nix") + self.nixosModules.hardware + self.nixosModules.hardware-cpu-amd + srvos.nixosModules.hardware-hetzner-online-amd + ]; + + boot = { + initrd = { + availableKernelModules = [ + "xhci_pci" + "ahci" + "nvme" + ]; + kernelModules = [ ]; + }; + swraid.enable = true; + zfs.devNodes = "/dev/disk/by-uuid"; + }; +} diff --git a/hosts/srxgp00/services/coturn/auth-secret.age b/hosts/srxgp00/services/coturn/auth-secret.age new file mode 100644 index 0000000..db2942e --- /dev/null +++ b/hosts/srxgp00/services/coturn/auth-secret.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw RrFIECbXxeuPEyGxWOHSWr23wh7cJ2ojtxeOuiQG1Tw +HL4pQADIbm67noLw+WHr7VWbkCeGLW0Gg9iW2FinQP4 +-> ssh-ed25519 JzjriQ mhhYpWUGZoDWLO9KHbikn+P/sm//F+Rr7+KXWx9elW4 +qe/oMpinF6trDHeb5gu1dJ+f4AIbydlQ5Kko+7hcDBE +-> ssh-rsa 6hPx7A +JadRDjvcFPCFeXxmyk3Xlns1jpnlACM6AYX7XCiPwlqxjsdM3z3Ffo3rXg3CD2C+ +v7nJ4WJ0vxiGwKy5R2RIpKpV+ufCEpifjlwxmyJMiyW2XT4zKGdFKvDmz487yhIV +l1xQYEfxL9rLrGRu14nFT7ogmpQL1XxDjBu+wRaBamLL/XoMtDQnOh0WxOy606jW +o2BXUpibE637bTQ9I5W8CjRg0vmx9DxfRpe1K/v91dB39TTekxPiK4hqZKN4CfvU +vKua/lT102auTHT9CVnUS9hbfgAlMYL/iOpV7RgjpMLbMn1km9seTzLwmq0ZaKIO +ZFmhPtSAFPziUtgsejlJHF2ubGoOyeZ29Ufch8QemEF4JTg53bavJrSBeo3GH0Ed +khu874/lgzD7qEj+ZobZrY+asHb5vN4bjdiMsSC2P3/h/P1I+a3/UzU1Q+l4zIdi +IUNvEuZassxef1IN7WFMX+58Mnhe5xFIACGDyGmFANX1CwW/SHGJVR50kuBYlivD +tzhCs09LSvA3XCLTmv3xAlPNuVo4yWMtBSIA5wjyI9Aii3LiwrNu7WJZVHm/P7HR +8vtLiUJHqE4/cntL3hdu1y9JT6Q5p+iIOorkVOxP/YYkzber1E4tlB53gX3nn9Zc +UlwcjYu98Rlr7ZQpBHfNlG2kPVk4eB+wQ0FANEpN/DM +-> ssh-ed25519 Dfencg Hhxyaq+w1z3iliBW3YkShIb2/UozH4iDMnkPKINJkn0 +tjpcXjYEam9qj6MNlLXbc4i/pTK1UXek2zK7K9E7rfc +--- 8hw3Ug1U7dk7EF0kMJXJVFKGralF+GDOzh6D1gTihHY + +FUJqiuXfLW,s4zQ-L*YPӿZt˽ \ No newline at end of file diff --git a/hosts/srxgp00/services/coturn/default.nix b/hosts/srxgp00/services/coturn/default.nix new file mode 100644 index 0000000..9abd7e1 --- /dev/null +++ b/hosts/srxgp00/services/coturn/default.nix @@ -0,0 +1,81 @@ +{ config, ... }: +{ + age.secrets.coturnAuthSecret = { + file = ./auth-secret.age; + owner = "turnserver"; + }; + + services = { + coturn = rec { + enable = true; + no-cli = true; + + min-port = 49000; + max-port = 50000; + + realm = "turn.srx.digital"; + + use-auth-secret = true; + static-auth-secret-file = config.age.secrets.coturnAuthSecret.path; + + cert = "${config.security.acme.certs.${realm}.directory}/fullchain.pem"; + pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; + + extraConfig = '' + prometheus + listening-ip=65.108.77.254 + listening-ip=2a01:4f9:6b:2573::1 + no-multicast-peers + denied-peer-ip=127.0.0.0-127.255.255.255 + denied-peer-ip=0.0.0.0-0.255.255.255 + denied-peer-ip=10.0.0.0-10.255.255.255 + denied-peer-ip=100::-100::ffff:ffff:ffff:ffff + denied-peer-ip=100.64.0.0-100.127.255.255 + denied-peer-ip=169.254.0.0-169.254.255.255 + denied-peer-ip=172.16.0.0-172.31.255.255 + denied-peer-ip=192.0.0.0-192.0.0.255 + denied-peer-ip=192.0.2.0-192.0.2.255 + denied-peer-ip=192.168.0.0-192.168.255.255 + denied-peer-ip=192.88.99.0-192.88.99.255 + denied-peer-ip=198.18.0.0-198.19.255.255 + denied-peer-ip=198.51.100.0-198.51.100.255 + denied-peer-ip=203.0.113.0-203.0.113.255 + denied-peer-ip=240.0.0.0-255.255.255.255 + denied-peer-ip=::1 + denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff + denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff + denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255 + ''; + }; + + nginx.virtualHosts.${config.services.coturn.realm} = { + forceSSL = true; + enableACME = true; + }; + + prometheus.scrapeConfigs = [{ + job_name = "coturn"; + scrape_interval = "60s"; + metrics_path = "/metrics"; + scheme = "http"; + static_configs = [{ targets = [ "${config.services.coturn.realm}:9641" ]; }]; + }]; + }; + + networking.firewall = + let + range = with config.services.coturn; [{ + from = min-port; + to = max-port; + }]; + in + { + allowedTCPPorts = [ 3478 ]; + allowedTCPPortRanges = range; + allowedUDPPorts = [ 3478 ]; + allowedUDPPortRanges = range; + }; +} diff --git a/hosts/srxgp00/services/dendrite/default.nix b/hosts/srxgp00/services/dendrite/default.nix new file mode 100644 index 0000000..ece0622 --- /dev/null +++ b/hosts/srxgp00/services/dendrite/default.nix @@ -0,0 +1,185 @@ +{ pkgs, config, ... }: +let + name = "dendrite"; + domain_name = "srx.digital"; + server_name = "matrix.${domain_name}"; + admin_domain = "admin.${server_name}"; + chat_domain = "chat.${server_name}"; + bindHost = "localhost"; +in +{ + age.secrets = { + dendriteEnvironment.file = ./environment.age; + dendritePrivateKey.file = ./private-key.age; + }; + + services = { + dendrite = { + enable = true; + openRegistration = false; + environmentFile = config.age.secrets.dendriteEnvironment.path; + settings = { + global = { + server_name = domain_name; + private_key = "$CREDENTIALS_DIRECTORY/private_key"; + + database = { + connection_string = "postgres:///${name}?host=/run/postgresql"; + max_open_conns = 90; + max_idle_conns = 5; + conn_max_lifetime = -1; + }; + + logging = [{ + type = "std"; + level = "info"; + }]; + + metrics.enabled = true; + + trusted_third_party_id_servers = [ + "matrix.org" + "vector.im" + "nixos.org" + ]; + + dns_cache = { + enabled = true; + cache_size = 4096; + cache_lifetime = "600s"; + }; + }; + + media_api.dynamic_thumbnails = true; + mscs.mscs = [ "msc2836" ]; + + client_api = { + registration_disabled = true; + rate_limiting.enabled = false; + registration_shared_secret = "$REGISTRATION_SHARED_SECRET"; + }; + + sync_api = { + search.enable = true; + real_ip_header = "X-Real-IP"; + }; + + federation_api = { + key_perspectives = [{ + server_name = "matrix.org"; + keys = [ + { + key_id = "ed25519:auto"; + public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw"; + } + { + key_id = "ed25519:a_RXGa"; + public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ"; + } + ]; + }]; + }; + + turn = { + turn_uris = [ + "turn:${config.services.coturn.realm}:3478?transport=udp" + "turn:${config.services.coturn.realm}:3478?transport=tcp" + ]; + turn_shared_secret = config.services.coturn.static-auth-secret-file; + }; + }; + + }; + + postgresql = { + ensureDatabases = [ name ]; + ensureUsers = [{ + inherit name; + ensureDBOwnership = true; + }]; + }; + + postgresqlBackup.databases = [ name ]; + + nginx.virtualHosts = { + ${domain_name} = { + forceSSL = true; + enableACME = true; + locations."= /.well-known/matrix/client".alias = pkgs.writeText "matrix-client" ( + builtins.toJSON { "m.homeserver".base_url = "https://${server_name}"; } + ); + locations."= /.well-known/matrix/server".extraConfig = + let + server."m.server" = "${server_name}:443"; + in + '' + add_header Content-Type application/json; + return 200 '${builtins.toJSON server}'; + ''; + }; + + ${server_name} = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${bindHost}:${toString config.services.dendrite.httpPort}"; + }; + + ${admin_domain} = { + enableACME = true; + forceSSL = true; + locations."/".root = pkgs.synapse-admin; + }; + + ${chat_domain} = { + enableACME = true; + forceSSL = true; + locations."/".root = pkgs.element-web.override { + conf = { + brand = "srx digital"; + branding = { + welcome_background_url = "https://images.unsplash.com/photo-1480843669328-3f7e37d196ae?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"; + auth_header_logo_url = "https://${domain_name}/favicon.svg"; + }; + default_server_config = { + "m.homeserver" = { + base_url = "https://${server_name}"; + server_name = "${server_name}"; + }; + "m.identity_server".base_url = "https://${server_name}"; + }; + help_url = "https://${domain_name}"; + }; + }; + }; + }; + + prometheus.scrapeConfigs = [{ + job_name = "dendrite"; + scrape_interval = "60s"; + metrics_path = "/metrics"; + scheme = "http"; + static_configs = [{ targets = [ "${bindHost}:${toString config.services.dendrite.httpPort}" ]; }]; + }]; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${server_name}:443" ]; + tags.host = server_name; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${server_name}" ]; + tags.host = server_name; + interval = "10m"; + }]; + }; + }; + + systemd.services.dendrite = { + serviceConfig.LoadCredential = [ "private_key:${config.age.secrets.dendritePrivateKey.path}" ]; + requires = [ "postgresql.service" "keycloak.service" ]; + after = [ "postgresql.service" "keycloak.service" ]; + }; +} + diff --git a/hosts/srxgp00/services/dendrite/environment.age b/hosts/srxgp00/services/dendrite/environment.age new file mode 100644 index 0000000..6ca9e38 --- /dev/null +++ b/hosts/srxgp00/services/dendrite/environment.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw /AFAsp3kPh6uhjFn9GjZN84mywODGn3dO4JDRu/Ltk8 +9SWydf6/WZl1V9KpxVhslYZ2afTfFIoSxa1qeKi34KA +-> ssh-ed25519 JzjriQ YsdZUPErOFyRsPnDh/A7t7JnrGWVvs8lkcQh/vRVDh8 +20qNy3Ll2CXS6xcmcNOAUNFCvD7jvFrzmWnNPSdNAjo +-> ssh-rsa 6hPx7A +uQJDNP/W09WfODdzLW/oHrby2IbHsPwYqIqrnhnJQpMBaE27GcQyQ3/oX0fpFVOY +yY3LSMSa16O5pP+T9f/SC8Kklt/AKJ9bn/9E35olnhv9X9Qh/5aCk7FmAXvACguu +0OYyB/c6r8e8t2C9uitvYNwa2W5v7I6QdpiTVZBCncp/VN0aPsS+kAVxtKQndbjF +7rUmN0MtqeMP37/cIJHnK9ZoGuotkW0h+heI1Wjd808Kx4kdCJnon/NPJ873CEFQ +XEK29u0wRRRBJPKdNnWu6KDViUIoHynl4Rl0Qzi4LA20X+6+nlx2Gel99tSBSu7p +Bc5m0xiYYy69QamuSmEesvyUB//zIBPQToxiQdZD4n++9d/+HDQ/QYOOEHlpi5DA +KpHqCte6eKStSlKAvAt7A4ccSMuVXebT9NhsAUcuTp8i6z8oLH0N/H/L/MDgzgvi +FtiKdThJYlyiLDziKX6LcRVaeJxg+sLBwnNfrWVuWoka2q37LbcUlFrSDF0Us0dl +0/Y/rAC6KJztcc/zBkbnuWCZlaaBtVcLE6vpbicCTss8R+UhJCC7cin1Cnhvqgl3 +lKmln3MpsAniHCje/SWgqRyXx6fVpCDKwe+qIW1SaCekQWUo/hpJuTLfoPvBdozx +kXCiAhp9ZvHB3+mA9cUzET/DQ6WVjIGpHNncv/oKEW0 +-> ssh-ed25519 Dfencg qd8p5uFbUwDuSQn2Ql6uDYvB49V1auQCsVge0jUJzGo +amF9Mfa/Wgym1Wf0s8KoutpZvIFaYIELGd54ZG+0VSM +--- cBsNcjTDQXyuYeSA60Buo9IhJ45tzsBjplwrtbVgLEI +C|-}ѼP r[)+6Ďq@$1㻥7tPwZK-(gcN0kZⷻ](>;vqrjv5\U{Za^Ǣ3dhq,[B|VFlu|%S~/gwh \ No newline at end of file diff --git a/hosts/srxgp00/services/dendrite/private-key.age b/hosts/srxgp00/services/dendrite/private-key.age new file mode 100644 index 0000000..10f9670 --- /dev/null +++ b/hosts/srxgp00/services/dendrite/private-key.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw JXCOHhmEwyJskFn5WwcNHZmg7QlabhxVgxgikGertgE +5LlKRT0UivqcDoaXPFxtMmCsbmpRmexqK1iOcthJW7k +-> ssh-ed25519 JzjriQ fcLWfzAqfTVyWTf0ac8PqX0WtxbhSmxVoy95CPHjEFQ +IAASir2G1vnmkwBWTI/YLo0l39/cllqxGnuleMiEZmI +-> ssh-rsa 6hPx7A +Y+TtSaCA6ViMsNbsCOSUeTv0jhtR6oKEn7A+H+lwJ778lmqxjSAAiChiU8aIGQ5H ++n27+w696fISNkvRYYr1qzkqCA5qCL/gBAzTVMt5zungOem6pyF2jsdiwUiW4jFv +caVcfa0LhnHkQtgcc4qxSomxmQ8jnSzmsXBpR0EQddTZl++fxmhlpO47JI1zHUV1 +rTU7kYR4/6+Y8+qeImySexDAfxfSbig+O9v3Ph5yBM/dQKTKGCWilUSXGvy9sG/0 +hru1lWZ9KU/Hqu+19Ng28dbg1+nVjq13Q7vkwg4dgf5s9CJBzEp+A3kjZn6e5m+G +G3pv5LwfrihKfrEJVT10ARBw8ZVJIX/MD54xvIdOIndTg7LHJq0CIdL6yBjnpm5U +J+jf13HMoXLgf/HzxBA2o2dsz6zIiLfz5kLGXwNAO1nKrmQZs1jOpRcR1kksM4Ih +XYGT4w3unkpEhRHwnNZg6W3d6+5impU7OLGGRAZYdu7LwpcgXY1IA0XfqLc7n+VW +AKfaDlHHqwZAQy/ccNyaeuFf28R3uxkNvFcGeWOFw3A5iEyzBqyAHsbJJ5vD/LmB +3LktOTfrqz6JUKQSy4OI+zlt3yKLC4x/ot9rAWMjHKrtU4Ugf/ZSgzkXao+RfpiZ +FURQfpoHxT3in6bxjo+p5gsbtdElhqDL9bQdOLXNnx8 +-> ssh-ed25519 Dfencg rGosZgGJT6tEZiJcZte/yBr8ymn7R/VCoa9KimfNNQk +S0JvXPtI/qwfA5J+M19ecFk0QsUM8KJfeivzzzvKyFA +--- PQcVC0cWPhooEvu7xzoT0mUVGX9H0gqbewEtLogLMEU +p\ lm$խXa.m0 K8ψqMSEqRϫW(}एl ssh-ed25519 jDpDqw jT12Vok7oCoHwjYXiJbXak9fKwfcAoZvniEBmaDcPBs +Qn0Pt+4ItG3W/4FmGwS4bmoKLOolJIDvBMe7/yjJDpA +-> ssh-ed25519 JzjriQ L9XwYsGzK7D5bse4rtJI3NlgTsb6kShilXXKLK4wjD0 +LrZ7K+tOp38fh0i0v6y0ngWSHIuDiu1TA7OX5AWrNWs +-> ssh-rsa 6hPx7A +CVypkGjpStOfHiWyi0/edlGJVO2CsLj2DGnbpCh+EiTPp5MIimXJsv547uPNCdqV +XxFwbGU833q8QLju3ESfx6bfPAwd7waaEXmovcPgIz3YXO+9cZNITFYwwfBWUWx0 +w7e5mp6XtYxxLIvIjz9wb/S9W+/h9LAqxoOVdevj6WQt5estpNgkBVg9eilZInsL +h66xccTpuEdzhPgTcxmFTPYJf0fScm6DQoao1MzZV7Pe9XD/ryqngw0JHBlokd68 +HNvLy49tR9MmPbML5tVhK5SHkUYD7DqCkKKxafXiVtX/kAn2MqTMPVw8nqbivgvZ +6zy5/nrQfbCS8GyFRkjcIydAFzaVh4u1bczuBS7X1YEkqJRyw3OcdaAfo/7IxHK6 +TLBR1IXELRIsVhwysDaZSsr2cLnuTC8HRC9p2qdnb0/ijKBt/Ud6vIlozUB6nD5l +ybG/AQaUS3qniieFVHKCZ1ky8Fc52qIuRrRQ77cFg6a947ag79YyJV26hbyEum8Y +/rV47QEI1o8NxSXDs8ivQN32b5OKEHVEqi5G82gmA+JR1txsnYwxgvwRcpqfxhp0 +yYQIltOoauObii0FpeL7CgcInTZR6M5Pirci/ockBOvRh69VvSx9galc7ae4izCR +mkT8p14JkDcbkkCvA3StBdcHJn3cYk8nS21A5np2R9U +-> ssh-ed25519 Dfencg sRiDIIupHKr2ntrv85rAARp4d/v4Nu+eh7WbVZHBFRU +X5mxkEQkN1zaDBOKVP6bjwCkO+BbFllT+IviAhjXutg +--- s9jOcB3p945ujdml4LdOf7UGJeXWl+HPwCOItXCDMtY +z:(+kICPX a +F0*-{'4]: ssh-ed25519 jDpDqw 1QcQUWrDCoAbMO+vVjHW8/7TVERv/u/yYg5FEWDNIjs +9grSDCY6vp1JCEVFMlSPVl52/3hAXid955IlwwEQ8N4 +-> ssh-ed25519 JzjriQ EixF6itE/FEMMmVg5tvuvolhRzljxHOtHrNUBDSX/2E +6EGocnqczp6fV/hNtD4r9cQuNP3AXrHBzwkI4umsnNE +-> ssh-rsa 6hPx7A +Zvw2oBZweTCbDjm/246mYtzuES9+qb0NHIp1c2ins+yDqD3WWEz0clfb1zw+/QNL +5g9lKuADFhBYksMA7M+ZmixMfWFeYt/Df88qpNrXCTLzkKdM31tc2xBmcDRsaC3m +qhrUu+V45rZJAy2hmvEcizWhuOEbvIFkpWuX72FEjXPNUHECyawBC5fl9xstGGZV +jPXKt0rq7cMnmFEw/q510ApsY8ZYa1B7Oz6ySx0YBD0cLnTheqPnWAQ0apXtca4a +k6w/jd1B0nJ9rF8HotQ+HUC579GoeGhWqMPaXIAEUlM1rwxik3lW3C5eA/JqRqNq +ZFvmG7ivQ0eySBxSHmaDp/IM6joLY1k4ECi6duRepmKt+B8rPfP79XLRqtyf+oiL +9ELrXCg4je6qSZZcrWI56Ag6Hz7/Ox4hlKnGjFfSqpZnix1EF6H5MXfidztJIftb +mQEFt1sst1Z3x5x3ILjAb+8xGHoMaAQd/QKdlfqzPrF8Q7uV5xoMBEOYggjmG33L +TKxJobVpE5vXEVO68whdPTcZ+mCZc06W7+ouJOWCmSJ1sfY8sK5qKiEU/2URvzQR +vslFUJ2DgwHNY5qoHs+FmUCoBT8t4eS+3rKJWDPAF+enBD+L5z2AeRX5vFNmrlFV +5+De4ZreFd41lTSS+hTrnxCHHqbVrTVctTp3z/9cR0A +-> ssh-ed25519 Dfencg AhPbUI130CBwlCyxzxGLpQS2K7KfKfqEV/QxcSDMzBE +FBM5u2+4EhYvPlCjr/txAZ+hf1RkM7D8GuBEBm4NXyc +--- My/nXxUyWQWXzxxUF/buVxAJa1fQsChLTVq7Ccq8HP8 +rzj}&/iG7%.Az@EIlmcO9qr=ny>A/3} \ No newline at end of file diff --git a/hosts/srxgp00/services/grafana/default.nix b/hosts/srxgp00/services/grafana/default.nix new file mode 100644 index 0000000..f114c5b --- /dev/null +++ b/hosts/srxgp00/services/grafana/default.nix @@ -0,0 +1,99 @@ +{ config, ... }: +let + name = "grafana"; + domain = "metrics.srx.digital"; +in +{ + age.secrets = { + grafanaOidcSecret.file = ./oidc-secret.age; + grafanaOidcSecret.owner = name; + }; + + services = { + grafana = { + enable = true; + settings = { + analytics.reporting_enabled = false; + + server = { + inherit domain; + root_url = "https://${config.services.grafana.settings.server.domain}"; + http_port = 3003; + enforce_domain = true; + enable_gzip = true; + }; + + database = { + type = "postgres"; + url = "postgres:///${name}?host=/run/postgresql&user=${name}"; + }; + + smtp = { + enabled = true; + host = "mail.srx.digital"; + from_name = "SRX Metrics"; + from_address = "no-reply@srx.digital"; + user = "no-reply@srx.digital"; + key_file = config.age.secrets.forgejoMailerPassword.path; + startTLS_policy = "MandatoryStartTLS"; + }; + + security = { + cookie_secure = true; + disable_gravatar = true; + strict_transport_security = true; + admin_user = "service"; + }; + + "auth.generic_oauth" = { + enabled = true; + auto_login = false; + name = "OpenID"; + icon = "signin"; + allow_sign_up = true; + client_id = "metrics"; + client_secret = "$__file{${toString config.age.secrets.grafanaOidcSecret.path}}"; + scopes = "openid profile email"; + auth_url = "https://id.srx.digital/realms/srx/protocol/openid-connect/auth"; + token_url = "https://id.srx.digital/realms/srx/protocol/openid-connect/token"; + api_url = "https://id.srx.digital/realms/srx/protocol/openid-connect/userinfo"; + }; + }; + + provision.enable = true; + }; + + postgresql = { + ensureDatabases = [ name ]; + ensureUsers = [{ + inherit name; + ensureDBOwnership = true; + }]; + }; + + postgresqlBackup.databases = [ name ]; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${config.services.grafana.settings.server.domain}:443" ]; + tags.host = config.services.grafana.settings.server.domain; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${config.services.grafana.settings.server.domain}" ]; + tags.host = config.services.grafana.settings.server.domain; + interval = "10m"; + }]; + }; + }; + + services.nginx.virtualHosts."${domain}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://${config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}"; + proxyWebsockets = true; + }; + }; +} diff --git a/hosts/srxgp00/services/grafana/oidc-secret.age b/hosts/srxgp00/services/grafana/oidc-secret.age new file mode 100644 index 0000000..6d3ee34 --- /dev/null +++ b/hosts/srxgp00/services/grafana/oidc-secret.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw C7WQ0F+OHuWXvlbxVoaAyZh1+CVIISqijYrINi6qywU +V3Kupx4Ht1qZKNwxBDBQ1i6JZBY0DYuLv6rn7EYc01Y +-> ssh-ed25519 JzjriQ LxStntQkytwa0u8nL3B7RyicbKDdCRWxeDmi8Ao0NQ4 +c52RbPkcOILVtf2SOhomRElFYEO4YKHJAWAqF0uupvc +-> ssh-rsa 6hPx7A +OKfMxzebbZAlQSgfxsryiMb9KIS7q2nlMHy4ZAyH+2+zGLK4l+FsnyAMosY5vDcF +Iw5qa1CbRijtRDg5g9jh2tDej+Q35Z+xF7r+AauCEFfEz0LDxF74wrWOp4GtxWU6 +NdQaDmlGRcibx07W1joQAruJJLuxijw0MRz4zczZ6sc72HLbBz3xE6cCub4CDv7I +QSGvMQ0cCKj/tlFRA35Ju3GlWIZaMBtRli5DSBbsjkkb+0lr2g/KxLF7nNlKb8DV +9wSRZ34DBB/cEAbKqHxnr4Dbg8qOWPuYN47KjZQf2Fp4B1TXw0EAQb0a+JTWDI+g +uM0kq26k4TjiLObo/dGXQw/70XLPSCXlquwI81a3XXWUjE2vkoq2wgTPIbcO+Zka +WesYDIbMiVMkH9CORtn/00goJjU2KWfbHp3rxQ8PVu6juXPnxJuDNAPNWmE1/mxN +TIe2QKuvomf+8oWpM428CFObPTgSvV1A1pWTRmX8CSgAzBfzgjUfuco1UrzOqM5R +qpS7YfgpoHmOGWFILwjxwgEa6/VLYajvNmxpZtF1XTkReWJsvfmcan7g9P6+kW+a +C4CRAyZ4UotJWdurcMIYhpG0AbxnOQ43uqWuXSx26rQdPZSt+DxdrnigoyqMCmFR +byiIg97v/7aRNApPjoo9LiCE3kWNhD71Z0oAxY7U7uM +-> ssh-ed25519 Dfencg dTb8RftZcE9uEQfKul4jVnO2lHlLPigN4U8PAYHEcBk +bTFhBh7Rw7grDwXnZSuol/pppLMolAxafYVdNVELxHg +--- HTwqUOKnllUy3ADExAh6DdIHGj9dCMRBHEIIxRE7f0g +-ؗo$JUw|x";yJ !B;SzDv+J%ufEq%u( \ No newline at end of file diff --git a/hosts/srxgp00/services/hedgedoc/default.nix b/hosts/srxgp00/services/hedgedoc/default.nix new file mode 100644 index 0000000..f625f48 --- /dev/null +++ b/hosts/srxgp00/services/hedgedoc/default.nix @@ -0,0 +1,97 @@ +{ config, ... }: +{ + age.secrets.hedgedocEnvironment = { + file = ./environment.age; + owner = "hedgedoc"; + }; + + services = { + hedgedoc = { + enable = true; + environmentFile = config.age.secrets.hedgedocEnvironment.path; + + settings = { + domain = "pad.srx.digital"; + host = "127.0.0.1"; + port = 3005; + + allowAnonymous = true; + allowAnonymousEdits = true; + allowEmailRegister = true; + allowFreeURL = true; + allowGravatar = false; + + enableStatsAp = true; + hsts.enable = true; + protocolUseSSL = true; + useCDN = false; + + csp = { + enable = true; + upgradeInsecureRequest = "auto"; + addDefaults = true; + allowFraming = false; + allowPDFEmbed = false; + }; + + db = { + database = "hedgedoc"; + dialect = "postgres"; + host = "/run/postgresql"; + }; + + oauth2 = { + baseURL = "https://pad.srx.dev"; + userProfileURL = "https://id.srx.digital/realms/srx/protocol/openid-connect/userinfo"; + userProfileUsernameAttr = "preferred_username"; + userProfileDisplayNameAttr = "name"; + userProfileEmailAttr = "email"; + tokenURL = "https://id.srx.digital/realms/srx/protocol/openid-connect/token"; + authorizationURL = "https://id.srx.digital/realms/srx/protocol/openid-connect/auth"; + scope = "openid email profile roles"; + clientID = "pad"; + clientSecret = "$CMD_OAUTH2_CLIENT_SECRET"; + }; + }; + }; + + postgresql = { + ensureDatabases = [ config.services.hedgedoc.settings.db.database ]; + ensureUsers = [{ + name = config.services.hedgedoc.settings.db.database; + ensureDBOwnership = true; + }]; + }; + + postgresqlBackup.databases = [ config.services.hedgedoc.settings.db.database ]; + + nginx.virtualHosts."${toString config.services.hedgedoc.settings.domain}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = + "http://${config.services.hedgedoc.settings.host}:${toString config.services.hedgedoc.settings.port}"; + }; + + prometheus.scrapeConfigs = [{ + job_name = "hedgedoc"; + scrape_interval = "60s"; + metrics_path = "/metrics"; + scheme = "http"; + static_configs = [{ targets = [ "${config.services.hedgedoc.settings.host}:${toString config.services.hedgedoc.settings.port}" ]; }]; + }]; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${config.services.hedgedoc.settings.domain}:443" ]; + tags.host = config.services.hedgedoc.settings.domain; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${config.services.hedgedoc.settings.domain}" ]; + tags.host = config.services.hedgedoc.settings.domain; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/hedgedoc/environment.age b/hosts/srxgp00/services/hedgedoc/environment.age new file mode 100644 index 0000000000000000000000000000000000000000..3be50b3d3c97f699ddd28a76c7a292c19c7cd9e8 GIT binary patch literal 1204 zcmZ9LJ}MX*>P61gSEQc$o01B)On%ph|Pv|Dt*i#Ct;3IOVmCoMN=RY z*elp1P)BZZV9hJG^6Tjez{v>k8?kVs*o@T0@{|PfF=ZSr`aezWcV%J@V5wTt-0)4w zWf0Z0#3)NEmug0&cbdixO41$CjE~@)rWjjpl|YZZdM#)i*XugTcund9XAE5m4{U>N)ovfs%E}*1W8=(l7@B7gFQclJSv7$kKuNN*3~?jNy3^sVDV$B~tZ#GmoNjGB zA?K;lq3%Mv!(*oLt1cGDegjWzzM#&M zsJWq%?q}R}-TMi`+SR-$xi#Ikkq}tj-0oE##91G0mk~qKmM8@jvx1qnMN&!AJ%RO_adJL$wgyh2%6TL7O6H*Q;=z^eWyX85J!XZd{rX2(XW3g2gJ$kb}#f>&-^cU8(MmD#QY^4RXX2 zxmU6@RRrOjqYk@*7_Ff!@%$#L#D%ud#nb70W*3ydVbsVg0~{E;Na}PNi??e7!Fs*H zSGg9u21&Y##9ob07d;5UCh1jZ^5Z_{_Tz^hKWuasUNVjb3B}>d2+*X%(aEONT!?Q4 zv&?6xj*C{&YveT&b7;+3ge^7(!WU7L?j*<>~P@V#`9C042BAonJ4jkvFZJ@Sv_Z?8!f + timeout = ${toString (60 * 60)} + + + + cache_size = 32m + + + + + listen_address = ${config.services.hydra.listenHost} + port = ${toString metrics.notify} + + + + queue_runner_metrics_address = ${config.services.hydra.listenHost}:${toString metrics.runner} + + store_uri = s3://${s3.bucket}?endpoint=${s3.host}®ion=${s3.region}&secret-key=${config.age.secrets.hydra-private-key.path}&write-nar-listing=1&ls-compression=br&log-compression=br + binary_cache_public_uri = https://${host.cache} + + upload_logs_to_binary_cache = true + compress_build_logs = false + + max_output_size = ${toString (10 * 1024 * 1024 * 1024)} + ''; + }; + + nginx.virtualHosts = { + "${host.hydra}" = { + forceSSL = true; + enableACME = true; + locations = { + "/".proxyPass = "http://${config.services.hydra.listenHost}:${toString config.services.hydra.port}"; + "/static/".alias = "${config.services.hydra.package}/libexec/hydra/root/static/"; + }; + }; + + "${host.cache}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost${config.services.minio.listenAddress}/${s3.bucket}/"; + extraConfig = '' + proxy_set_header Connection ""; + chunked_transfer_encoding off; + ''; + }; + extraConfig = '' + ignore_invalid_headers off; + client_max_body_size 0; + proxy_buffering off; + ''; + }; + }; + + postgresqlBackup.databases = lib.optionals config.services.hydra.enable [ job_name ]; + + prometheus.scrapeConfigs = [ + { + job_name = "hydra"; + metrics_path = "/prometheus"; + scheme = "https"; + static_configs = [{ targets = [ "${host.hydra}:443" ]; }]; + } + { + job_name = "hydra_notify"; + metrics_path = "/metrics"; + scheme = "http"; + static_configs = [ + { targets = [ "${config.services.hydra.listenHost}:${toString metrics.notify}" ]; } + ]; + } + { + job_name = "hydra_queue_runner"; + metrics_path = "/metrics"; + scheme = "http"; + static_configs = [ + { targets = [ "${config.services.hydra.listenHost}:${toString metrics.runner}" ]; } + ]; + } + { + job_name = "hydra-webserver"; + metrics_path = "/metrics"; + scheme = "http"; + static_configs = [{ + targets = [ "${config.services.hydra.listenHost}:${toString config.services.hydra.port}" ]; + }]; + } + ]; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host.hydra}:443" ]; + tags.host = host.hydra; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host.hydra}" ]; + tags.host = host.hydra; + interval = "10m"; + }]; + }; + }; + + users.users.hydra-queue-runner.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPtiFwECxheHv30ELg61uS6Ixc0QAIdG26BGl5f2+RsJ hydra-queue-runner@srxgp00" + ]; +} diff --git a/hosts/srxgp00/services/hydra/private-key.age b/hosts/srxgp00/services/hydra/private-key.age new file mode 100644 index 0000000..747fbd7 --- /dev/null +++ b/hosts/srxgp00/services/hydra/private-key.age @@ -0,0 +1,24 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw n3Z3q336cK7bhfkYbK4QN2FW15bHXSzEBZ2yMPE16Qs +3xhoh7ajmNN4JVp8FFUeFvFysSRsxW7uwvlecvAeLA0 +-> ssh-ed25519 JzjriQ I+ZfvxfUK3bxFHDjqPr1aRNNVRK4wT9EGZSrPNZzWT4 +sLyL1zzVQBfvt9+WjqBXtiDKOsEpzzh9t0I0AfOx7dk +-> ssh-rsa 6hPx7A +WW4cpr4fyH58Z1PoM0S/O9sHATvN0r043jj7WLd6nhff0LBurAh3x1QVBeWOpAz5 +dGekgdxXql3R76fNyUVZeC1pKRKrZD4QI3Ovbcb3VFYLvwuAIf93gTARxJrMpozc +KZ5+jBX7tw0cwyvAcZBY5pMQmJOFsMX2qmh06rufX4SpvPeh7I3FtFS8MOGY4hVW +mhMxuyryT9DhKXT0ck06AAjcr5x4pZP8CjbVZipjQ0HXsg44Lsqn4XQTI2W2VN7K +8bSml5nJ9oyeKBKKJccdlq7ydMqCKyRS1SEvET4S6tbNnuAW4KYKXfc6FvoQSJ/X +Yc+HnnbivSCTfsbA2AW0i1n3NuXpA2Oxo+z3BDXemX6mmbqKFgjxVyl3rUtAakAW +BsjpVKFnsJ1cbIrt0uyup7WQ+DnHKf0b/zqOCKvmBj04kQfEvcSPhI/N3e8bqtDr +X9D5ej7f5LbH/0NMNMAIVQuVqYRZ9AkA0ewautyc8KnE+lmW/5rDR0FwtC0ZupK0 +RFevUeHg1p6bWqtiF9aFn3TAR9M2lCKK8IIo5k5oc07uKdQpUdxTtqdw7ABRM0m7 +TvbxYHwYMfSNucKWpW9grJDMcczfdtivdlnI61m5B1VDG7FmavmqqCS5GCCZE+bO +iOGFDBO+zk3xuU0KBy9/xfr2SK1eDTKYD4VREa8tAl0 +-> ssh-ed25519 Dfencg nTEW+fbvaSeUOA3OekA416m8e+FNTY+BD1qImGj7JRw +Hz5/IOgsOjy4l1V2ajavDlx1cNlO6HQ19y1WurUcYR0 +--- 49LYxbN12cDPp4KAg6tlytMyYHjulnZY1NFp9QdWq5E +6EQ҈*[ED +^?KàxaxPkڬE4/ R)5ޯ].n=Dk@M +m +؍@"|V\[98e1x|bj~5N"º35D}qץ \ No newline at end of file diff --git a/hosts/srxgp00/services/hydra/secrets.age b/hosts/srxgp00/services/hydra/secrets.age new file mode 100644 index 0000000000000000000000000000000000000000..2ab6f43df850975715989d5a402cf35e89445253 GIT binary patch literal 3514 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 ACIA2c literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/influxdb/default.nix b/hosts/srxgp00/services/influxdb/default.nix new file mode 100644 index 0000000..1b4e9e8 --- /dev/null +++ b/hosts/srxgp00/services/influxdb/default.nix @@ -0,0 +1,43 @@ +{ pkgs, config, ... }: +let + host = "tsdb.srx.digital"; +in +{ + environment.systemPackages = with pkgs; [ influxdb2-cli ]; + + services = { + influxdb2 = { + enable = true; + settings = { + reporting-disabled = true; + http-bind-address = "127.0.0.1:8086"; + }; + }; + + grafana.provision.datasources.settings.datasources = [{ + type = "influxdb"; + name = "influxdb"; + url = "http://${config.services.influxdb2.settings.http-bind-address}"; + }]; + + nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.influxdb2.settings.http-bind-address}"; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/jellyfin/default.nix b/hosts/srxgp00/services/jellyfin/default.nix new file mode 100644 index 0000000..bd083a0 --- /dev/null +++ b/hosts/srxgp00/services/jellyfin/default.nix @@ -0,0 +1,25 @@ +let + host = "media.srx.digital"; + port = 8096; +in +{ + services.nginx.virtualHosts."${toString host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://srxnas00.vpn.srx.dev:${toString port}"; + }; + + services.telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; +} diff --git a/hosts/srxgp00/services/keycloak/databasePassword.age b/hosts/srxgp00/services/keycloak/databasePassword.age new file mode 100644 index 0000000..9d35e36 --- /dev/null +++ b/hosts/srxgp00/services/keycloak/databasePassword.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw OBYvz2ORZFwdIvca0uIXDXWdpfRiaFp/5G7syyGrcyU +vxYdkAiCVBfqzeqKfLFI9PsuDo7DhCCE5b/igNePfPk +-> ssh-ed25519 JzjriQ Dsy0LuOggSmN77ZPMWFzY6xOGi88uiN2prxrUeF/lW0 +BoLCPpQSKQM/GE+oAipiKp1n9Q3ChOXQIdGlnhGof80 +-> ssh-rsa 6hPx7A +npus090BSB1GRvneHlBqi1QZtPCIOTN+QMKCXSitoDYpyh7sJu5qGNmFrRE/g9+I +Iwoj+LNiV95YZVLl2Ta3/AiLXNOzcHp/JixDmOfn8cT3NrT3TF6kXLWBodqHIT3b +4tWsUn08rwzG3lrNKabudB/63Qpn8Hm1AzNPhQaBLs2gfHTGsKJluuqDggM/i/B0 +t2DkTvYNLvyKkYl4SFV2IYN+QlL0USuNiLsMUObbFpSl1Djh1oI75sibFMywkhbM +iy1/R04JvEXSmsZSVr9OU/q0dKR1w2b1W3rq8018EB9UVvbpD7NkmNqO1UhmECtM +HM/e+gslGHdkZTZuAYx/cUayA4QlWUOiM9KseoXRYjhiEEJ1q/yTst4AkmZIb2bF +ZG5D2WlPF/wP7Y/hwZv4kV76390DRSP8qyetWEKyM5G//DS1S44T6g4FXa1HtOLV +SkuixhTtszX3NYi1/0GiUhKujKicADeL14q0TroKI49ScqZEfYYo2yBunRVqxltQ +dV50wegZRHCAALGYVuC7r33Ke1Y6zLmThZYpaOc5OwpiLHGFNsYFe8VOLw8Z6yz/ +YkAZncDH/ej20YzKIWF7A6L32shw2mp8anCxu3i+uguLwLBvrC+BAGgEPfgyRKB5 +BXxmupzmXyygijXpHdVlDQzGIFXVVKQMyeSLABSaz58 +-> ssh-ed25519 Dfencg D/NzwQbbP1VMl11ezv7RLCZobWPd2jocy/Xx/GG7fQM +gOAksl62iBAesCjnKYCEjaYUCNEnhnpvbwjTthb/YsU +--- uWbkqQse85XYIZmig8Sj9Qthf4bHtSmWorvKnFFonO0 +s{ KRup*.A:8"}J va1Wx/,'Hc_~^ 8 \ No newline at end of file diff --git a/hosts/srxgp00/services/keycloak/default.nix b/hosts/srxgp00/services/keycloak/default.nix new file mode 100644 index 0000000..ae69055 --- /dev/null +++ b/hosts/srxgp00/services/keycloak/default.nix @@ -0,0 +1,48 @@ +{ config, ... }: +{ + age.secrets.keycloakDatabasePassword.file = ./databasePassword.age; + + services = { + keycloak = { + enable = true; + database.passwordFile = config.age.secrets.keycloakDatabasePassword.path; + settings = { + hostname = "id.srx.digital"; + proxy = "edge"; + http-host = "127.0.0.1"; + http-port = 8787; + hostname-strict-backchannel = true; + metrics-enabled = true; + }; + }; + + postgresqlBackup.databases = [ config.services.keycloak.database.name ]; + + nginx.virtualHosts."${config.services.keycloak.settings.hostname}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.keycloak.settings.http-host}:${toString config.services.keycloak.settings.http-port}"; + }; + + prometheus.scrapeConfigs = [{ + job_name = "keycloak"; + static_configs = [{ + targets = [ "${config.services.keycloak.settings.http-host}:${toString config.services.keycloak.settings.http-port}" ]; + }]; + }]; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${config.services.keycloak.settings.hostname}:443" ]; + tags.host = config.services.keycloak.settings.hostname; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${config.services.keycloak.settings.hostname}" ]; + tags.host = config.services.keycloak.settings.hostname; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/mailserver/accounts.nix b/hosts/srxgp00/services/mailserver/accounts.nix new file mode 100644 index 0000000..bc5c215 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/accounts.nix @@ -0,0 +1,10 @@ +{ + age.secrets = { + # nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt' + mailbox-Oom7oh.file = ./mailbox-Oom7oh.age; + mailbox-ugai0U.file = ./mailbox-ugai0U.age; + mailbox-Osoo5u.file = ./mailbox-Osoo5u.age; + mailbox-Ies6sh.file = ./mailbox-Ies6sh.age; + mailbox-xaev9B.file = ./mailbox-xaev9B.age; + }; +} diff --git a/hosts/srxgp00/services/mailserver/autoconfig.nix b/hosts/srxgp00/services/mailserver/autoconfig.nix new file mode 100644 index 0000000..b526746 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/autoconfig.nix @@ -0,0 +1,31 @@ +{ config, ... }: +let + domains = { + tld = "srx.digital"; + mail = "mail.${domains.tld}"; + web = "autoconfig.${domains.tld}"; + }; +in +{ + services.go-autoconfig = { + enable = true; + settings = { + service_addr = "127.0.0.1:1327"; + domain = "${domains.tld}"; + imap = { + server = "${domains.mail}"; + port = 993; + }; + smtp = { + server = "${domains.mail}"; + port = 465; + }; + }; + }; + + services.nginx.virtualHosts."${domains.web}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.go-autoconfig.settings.service_addr}"; + }; +} diff --git a/hosts/srxgp00/services/mailserver/default.nix b/hosts/srxgp00/services/mailserver/default.nix new file mode 100644 index 0000000..38042da --- /dev/null +++ b/hosts/srxgp00/services/mailserver/default.nix @@ -0,0 +1,171 @@ +{ lib, config, inputs, ... }: +let + host = "mail.srx.digital"; +in +{ + imports = with inputs; [ + srx-nixos-shadow.nixosModules.mail + simple-nixos-mailserver.nixosModule + + ./accounts.nix + ./autoconfig.nix + ./webclient.nix + # ./dmarc.nix + ]; + + mailserver = { + # https://nixos-mailserver.readthedocs.io/en/latest/options.html + enable = true; + fqdn = "${host}"; + + domains = [ + "srx.dev" + "srx.digital" + "sourceindex.de" + "nix-hamburg.de" + ]; + + enableImap = false; + enablePop3 = false; + enablePop3Ssl = true; + + enableManageSieve = lib.mkForce true; + localDnsResolver = false; + + messageSizeLimit = 52428800; + + sieveDirectory = "/var/lib/sieve"; + mailDirectory = "/var/lib/vmail"; + dkimKeyDirectory = "/var/lib/dkim"; + certificateScheme = "acme-nginx"; + + monitoring.enable = lib.mkForce false; + + backup = { + enable = true; + snapshotRoot = "/var/backup/mail"; + }; + + fullTextSearch = { + enable = true; + autoIndex = true; + indexAttachments = true; + enforced = "yes"; + autoIndexExclude = [ + "\\Trash" + "\\Spam" + "\\Junk" + ]; + memoryLimit = 20480; + }; + + policydSPFExtraConfig = '' + skip_addresses = 10.0.0.0/16,127.0.0.0/8,::ffff:,::1 + ''; + }; + + services = { + dovecot2 = { + mailPlugins.globally.enable = [ "old_stats" ]; + extraConfig = '' + plugin { + old_stats_refresh = 30 secs + old_stats_track_cmds = yes + } + + service old-stats { + unix_listener old-stats { + user = ${config.services.prometheus.exporters.dovecot.user} + group = ${config.services.prometheus.exporters.dovecot.group} + mode = 0660 + } + + fifo_listener old-stats-mail { + mode = 0660 + user = ${config.services.dovecot2.user} + group = ${config.services.dovecot2.group} + } + + fifo_listener old-stats-user { + mode = 0660 + user = ${config.services.dovecot2.user} + group = ${config.services.dovecot2.group} + } + } + + metric imap_select_no { + filter = event=imap_command_finished AND cmd_name=SELECT AND tagged_reply_state=NO + } + + metric imap_select_no_notfound { + filter = event=imap_command_finished AND cmd_name=SELECT AND tagged_reply="NO*Mailbox doesn't exist:*" + } + + metric storage_http_gets { + filter = event=http_request_finished AND category=storage AND method=get + } + + metric imap_command { + filter = event=imap_command_finished + group_by = cmd_name tagged_reply_state + } + + metric push_notifications { + filter = event=push_notification_finished + } + ''; + }; + + fail2ban = { + enable = true; + jails = { + dovecot = '' + enabled = true + filter = dovecot[mode=aggressive] + maxretry = 5 + ''; + + postfix = '' + enabled = true + filter = postfix + maxretry = 5 + ''; + + postfix-sasl = '' + enabled = true + filter = postfix[mode=auth] + maxretry = 5 + ''; + }; + }; + + prometheus = { + exporters = { + postfix.enable = true; + dovecot = { + enable = true; + socketPath = "/var/run/dovecot2/old-stats"; + }; + }; + + scrapeConfigs = [ + { + job_name = "postfix"; + scrape_interval = "60s"; + metrics_path = "/metrics"; + static_configs = [ + { targets = [ "localhost:${toString config.services.prometheus.exporters.postfix.port}" ]; } + ]; + } + { + job_name = "dovecot"; + scrape_interval = "60s"; + metrics_path = "/metrics"; + static_configs = [ + { targets = [ "localhost:${toString config.services.prometheus.exporters.dovecot.port}" ]; } + ]; + } + ]; + }; + }; +} diff --git a/hosts/srxgp00/services/mailserver/dmarc.nix b/hosts/srxgp00/services/mailserver/dmarc.nix new file mode 100644 index 0000000..b4e7a50 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/dmarc.nix @@ -0,0 +1,34 @@ +{ config, ... }: +{ + age.secrets = { + mailBoxDmarc.file = ./mailbox-dmarc.age; + mailBoxDmarcClient = { + file = ./mailbox-dmarc-client.age; + owner = config.services.prometheus.exporters.dmarc.user; + }; + }; + + mailserver.loginAccounts."dmarc@srx.digital".hashedPasswordFile = + config.age.secrets.mailBoxDmarc.path; + + services.prometheus = { + exporters.dmarc = { + enable = true; + imap = { + host = "mail.srx.digital"; + username = "dmarc@srx.digital"; + passwordFile = config.age.secrets.mailBoxDmarcClient.path; + }; + }; + scrapeConfigs = [{ + job_name = "dmarc"; + scrape_interval = "60s"; + metrics_path = "/metrics"; + static_configs = [{ + targets = [ + "${config.services.prometheus.exporters.dmarc.listenAddress}:${toString config.services.prometheus.exporters.dmarc.port}" + ]; + }]; + }]; + }; +} diff --git a/hosts/srxgp00/services/mailserver/ldap-bind-secret.age b/hosts/srxgp00/services/mailserver/ldap-bind-secret.age new file mode 100644 index 0000000..b8ace9a --- /dev/null +++ b/hosts/srxgp00/services/mailserver/ldap-bind-secret.age @@ -0,0 +1,30 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpEcERxdyBEYzFJ +UnhtcnNmREx5ZkVab05PY25qcUZZYW9oaXNPTmhqWW1PcXJIQVNvClVYQWIwYUgz +TGxWYUNBcXBkMmxBTExRZmhaalJjbjJReUdDZ1FWMThxZEkKLT4gc3NoLWVkMjU1 +MTkgSnpqcmlRIEFwU3NtQzRnODVENCtHblhLTW15WnFHSHFPNVI4em9MbG42cFlT +MnlveVkKd0tOWlpIK2lWQkJqa1BVOW44bWQvRy9mRjNUdzUyK3FZZkhNVVg5ZEZY +UQotPiBzc2gtcnNhIDZoUHg3QQp3VUNpNG0zQ0ozZFdFME05Yml2WWxDbTJTSmVS +VFJoa0ZOd2FDcFRxbE1UaTRVcWFWRG5MYktrVk5pNHMzZ3hNCmpOb2dNcnYrUUNO +WUZnYUVhbzcxa1FvVnU4aU5DYTVWaDF4Z00yY1JRTWlabDlvankrdFpnVlVNZGwz +a2R6SFgKcHZsMXphdGQyMjBWOXlSekJBNWpqWExSSy8wbW1wMUJBaTBJZExUOWhr +aUpHVTlBdVIxaTE1TXBzVW9KdjFWegpBTmQ2WklTOEVPNCtWNmVuNVhPV2UzOCs0 +c0RGbDBrYUFFVXZrUVNxQnFsVDV0Nnpib1pPTE1KeFZhMm1TQStxCjRsc21qZURp +MS9hbCtxODFQVE9IaUsvVjFzbEdmYjNYMUtuQXZYemRnWDFRYlhPdldpVFFpMHU5 +bXdhMENiYUcKV2wrQXltaTJZZm1vVlUzQmJmWjljZi9uQXZwU1VydU1paWdVQkVK +SWNNU2VnMkhUUi9xbWljajk3eFFPcUhBegpGaE1qb2poQU4rNEtZQnNGR0F4TC9Q +V29ORzNXNm9QNTdQemFQUXVCYXd6QTl4T0J4UlVuNU5Ga2drUE9KZllxClYrOXVF +NGJEUGlLaktMQStGcTQ1ZzhQU21pazhrMTdhOTltWlp0aWp5VllDMjc3UTR5ZUcy +ZncyQS9xZ004ekEKcG5oNGdZbTdjMjdWUFdBYnRsRWtiNCtoV2p5OWNNU2xHekJC +ODRkYmNKdTQxNDQ4NURmd2pXSkFGaW9hdXNBbQoxMHFta28vaTZDVDkwMWRHQmVK +WWVqbHVuOEJSRkVhTk5kbmdQeW5TTWRQQys5RVlOV0F2WjdzNHhUcU9xSklUCjdJ +NGhEVzdEWjZYdTNjbEZSdUJYTGFBRlNzc2VVOFNPMWhxN3MzOC9BM2cKLT4gc3No +LWVkMjU1MTkgUUF0anFRIEFWRVFkZ2ViRmRMTUFZWFJsZVlIcEJPZE1reFhjOUdV +d1BwTDRkdnpMbmcKNU5Bem55Q1AzODRWNVplQ2xmTnZybVIyK2ZtTHRzcHRDdURO +VmdhQmxJQQotPiBPbEJjKXBMLWdyZWFzZSBIOyFOPiAiMkRuIDJwcSB6b0E2c3E4 +CjROcnlyQVc2enhzUHlBOUtyNk5OL3FIbkx6VE5JUW0weEpjbjlrT1lxMG91ZmRl +OHNQTThHcnFxVnZOSENXUXIKc2s2cWc0NAotLS0gODhIUjFxMHV6K2tMNGlYU1cy +K214VmpGVytBNzFxVU1xTWlKQkxMV253VQoywXcrQeeo8fLE17veSy7lDzOahKD0 +oY0GUlps1e6YVBXiFyZpo9NM/DnnNRgFsC3uMBHRIe3c19kwaVPFQTaE2nG99jrp +iLnw +-----END AGE ENCRYPTED FILE----- diff --git a/hosts/srxgp00/services/mailserver/ldap-config-secret.age b/hosts/srxgp00/services/mailserver/ldap-config-secret.age new file mode 100644 index 0000000..55628cf --- /dev/null +++ b/hosts/srxgp00/services/mailserver/ldap-config-secret.age @@ -0,0 +1,29 @@ +-----BEGIN AGE ENCRYPTED FILE----- +YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IGpEcERxdyAxUVA0 +MVYySnhnUzI0YnI1eForZko0L2VKSWNHd1lQQzNPYkE3Y2p1alVBCkRMSTNxd3RF +NFZob2loa2dIUkFQclV0VU1YUU5qNUx5OWczYVJzbmx4OE0KLT4gc3NoLWVkMjU1 +MTkgSnpqcmlRIEZid2hWMi9yengyZUZtN0U5VnNVbE51UExpN2pQSlMyMHc2WElV +Qm9JU00KYXJaMy8vY0pKR0kraXY0QVhZdFZCWjJjR0p5b04raGNuLzVXVExrV2ZB +cwotPiBzc2gtcnNhIDZoUHg3QQoxUmZqbjRBd2IxQkRJZUZTcXZqNDZScTh6NGlW +ZE42R3A0NEc0UjdhWXd2UEpFekY2aXZ6K29jWDNpNlp5dExXCjJ0ejZlelRjRGcx +WjlvOUVxU1JBN2lUMFRGWkFZUUtHc1JOaXlpTDZSZ3B3NHg1MThESG5aQUVIN29H +Z1lUaVIKVzZYV1A4YjI5bTEzd0E3SWtmcnZkRnQzWTJ2d2pmLzVVZW1wNWlZY3Ur +eWhPMVB1MzJUNEVvY1JEUXAzMlA3RQp3RVJiQnZnZ1lPSFcrSTllM1ZDUnB0RS84 +Wm8zTFVzYU92S1JJZHdUN3ArSGNzc0lldUJydVdmMTNqNGd1Y2lXCmFpWEk5d1VS +enA2d3J6TUg5M2FDQU1nRWhVd21kNWRRZVpuTGo4YUk3Q0xXbVhYK2dnT240dnov +K0RUcG1JRXcKbnVBdzFrQWVlQWpyMFhQNmRvekhvRXpzWE9PellNaTEwdDNSVFZF +cWJjNVdWUTIxSWdKckpGdEpBbjZFNm5IZApOcCtZZk9UbUg5ZUNiQy9SN0JHeXQ4 +WHlVemlsbERYcDY2VjQyYzJ6UW0wMHZMM2dpaFAvbHBjanN4SXh4NGNxCmhpRWU3 +d3YzaktZL2E4UGE0bnVkbUNpYUYzYnZMR1dVZzJwcGFkUm9MRnNoS055QjZYNEFs +aC9aWUtRVCtpN2UKSEZ1VkpCL0dyMXJQNTlpdW9qaEc4SjlnOGY3MnNIcFEvdGJL +RlNvU0xndk8vSVVDeVNyUlY0amw3Ukpzc1JBNQpOeWY2Z0grTWtiTE5VNG5EdWlS +Vk03OFRiSnlsSHB3Qkg0Q1NMMzR3R1JXSElvakVqblNlR3JtWjJubnQxd0haCndw +bDJpZVJUTW9aWURzTW1TeVFnaXZsOHN1cXpGLzNXTmJ1VjFWNXFGTWsKLT4gc3No +LWVkMjU1MTkgUUF0anFRIFhjdmZTb3NUZVY0MWZMbGU1U0hweEFHMWFxKzRwdWgx +bG1sc3JoLzZZbVEKVWhnR1RlL1lVWGNOZnYwRXdSN28yMVY2cG0vcFd0UlRsVW81 +UFJrL29YOAotPiBxLWdyZWFzZSBVQGVyICdDNVloNjRsIHNqXzI7JQpaaGowT2NP +YzNoZUFPZTF2clQ3VnExVnRUTkpmVXhKTm5nSGdmRUVCCi0tLSBYY0RsalNZRlMx +RFQ3RzdjOVpGRTJ6MDByU1ZtMDNJWXI4Q1JLSGQxMVhjCma15P6/4SfGzxHhqxMm +mseZxfDqWy6KgTPOIcxGbU3itwueFJgFwYVWHynlx7TAfSJZFVNMYQycE/KeoVE9 +TgP8/rHeWD66IaQ= +-----END AGE ENCRYPTED FILE----- diff --git a/hosts/srxgp00/services/mailserver/mailbox-Ies6sh.age b/hosts/srxgp00/services/mailserver/mailbox-Ies6sh.age new file mode 100644 index 0000000..12a2026 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/mailbox-Ies6sh.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw IqUKNln5TWRzlKY6CHjia6VuDYlMpjL+D3NKHI+fHjQ +EODXEkWjzP68TC9/JOQ3piORAEECNnYlH71mLUmbHZc +-> ssh-ed25519 JzjriQ 2InSkL416EOGoG70EBVjFSwNWwS6Vx3uatbERPipmng +6f5XnAluFpTpqxPWu/O6DQzvkcfI/ipXJgk3gc8oB38 +-> ssh-rsa 6hPx7A +I5U3iYOzM33IXleaRta1ONJKwbh50DLr+65ad8G8XiZ3AMn5e5zhlxKVzXJ9G84V +iNHd1mOn+fdOGXJNs5ze60TyJaVlG/E1uNE7yj+yu9D99KZB7LIh6a+OcO6PYdYQ +339QHQ90hs1nlt9oKc7Z6tHZh4o4ROOPSP0FleB4c1N5l8OXD8NzLbUtiTKfMdTd +4vRQUcgzhe8giqPRl0Qy8arCijS43dCUBNeQPK1MqJXsl76QLaJJDRQ7ouOV918K ++JNLMhEwM9O6berEp++y0VcED3vBNkfbijJhKH0ogE4/kKJhxS4YQQKThLzxjUsd +2OSFlan+9lahEGo0vqFAn5rDpsTEL16RLKYGg1Z234ZZ3ukLqyi4eimfT8Os/PE9 +QgCDJ+PkR+z8ZMh38SICNiHoFZXW9ziVXlxtojtHzenHkdi/3NKpsjwFlmFs1eRs +fM5T2Vgyucf5WgBeoPa3wr5MJvnc3KtcTZdB4z/kn26QLQCCMJNC6+6gdg4CZHJj +bSgtzmNwjdsiUg3MNFcmY3u5R4eEnMZFK11XP9/IxCJOYtVymKca6iihDZi9OGa1 +WZuSfuHDcxAbcWnaO5b6pSjr3QbrFPOdIdDFzODjjet2843XN7/ToNpsJX3rd50m +ngWwO+amNj182WBy+PWK4FLBYom0hONyq0PJjVqK8ko +-> ssh-ed25519 Dfencg 7Gqsm3fValaJV9P60O+tC7dRHnubFWt3S+M806QGqRQ +VRRS9cdXvEYk1T7eIB9/KDfjO/7YrnPsmiHiYEhV7RU +--- uooLSbExMNA6pRi4MxSHNOS8ziNYp/19fkd1jdIsZjA +V +݉x.ΕɎ$,ܠgT:`_Gޏh?, Q"D0 1oriMƆ bgۻRoΑ \ No newline at end of file diff --git a/hosts/srxgp00/services/mailserver/mailbox-Oom7oh.age b/hosts/srxgp00/services/mailserver/mailbox-Oom7oh.age new file mode 100644 index 0000000..4e98767 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/mailbox-Oom7oh.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw AsYcnmBOaBvP0KN6Fn5eHCY+LH+OtOAS/h9n/QzVFCM +Ev5qsh+Eqd8nSax1BU0vOpk/gw1XUDz306hzoFDpick +-> ssh-ed25519 JzjriQ BeuJoHDNgji4cWsv7iSJFiRVnI0jyPiO96O6Nt2ijEo +eilK7JsfMKkEO1RrjeSPWeGjn1a5GN3OxTN/Vypx+Ng +-> ssh-rsa 6hPx7A +SKD7bmzmJeqjJthm9Q++I+UHfcYWiBNSksF7N0agLso6w5t2EZ41TxY6WyJyeLA7 +3oAWHoHlwrFa2GCnazP3Mf4d7l04zJwLNHeok2D7P4q6r0a0saN1z01GHP4UbBnX +fiMKHFWn1bzT3UjtEcbo2RKVbWNsiwFXff5wZBzM2V/buTG9ipV9lf1qsdaCeA2W +MAEtIBqh5LdmacHR2bJkqzFwo4cCOHdYDs5HWxS8iJKXQ0K+He+pFv2fI1wuaLnM +cWC79MvSwAHy0KEbDfbBlUZPVPC7Bl4KInVxAKsqAOILjAAxH9fIVpIV7yGCxBew +lZZjbNYY9lL+b8YnFHKpUd/1Uh8qIJPBmkjVlAIaOT+mlwQMixJ0+nowABtyyKgm +7AoRBUlGlXpJg5xlkHLNJWx9c7Jp3q03VOHDAhR7qP93bXZbKZWVOxcOOijnF+/g +uwGTCGAAxnyTQl/mL5KYAXQCCSa+wDLalVemaToFkenwJryLTghAjvlvwvSYdgMx +t6EbgMEe+VW9XnFhrOlnuUsdC9Lpv59/eylNPu28lfSmg2bEi22b29C+bNweOwWm +9coXVF9GOk+40iC9bBKsLPPQbs+o4x9n/kYF6zCPIOtlNmFHWog63gWc1NR9Y+JH +32JK9OBkJynabaUs8LmgBosDbmfPmSZbnN9QSOKfho0 +-> ssh-ed25519 Dfencg jX/fnsqLBNa+wUpuuG9m0jCGlTg6BeylyMEGFQkFEiM +t9/eZWkxCGggy10XfvTperveQbPTthPt6mrwlO4dHn8 +--- 64kfsS5RRpZyihA0J+QFREM9cQNjULs/HA3B0BKx8zM +V*L3V7|6DX&e ~3|sO寧gϧ2c+ +WpZMN\ٷl!%ǻ&4l $5d;NA8q \ No newline at end of file diff --git a/hosts/srxgp00/services/mailserver/mailbox-Osoo5u.age b/hosts/srxgp00/services/mailserver/mailbox-Osoo5u.age new file mode 100644 index 0000000..44e26bb --- /dev/null +++ b/hosts/srxgp00/services/mailserver/mailbox-Osoo5u.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw 0ek8rx0G8dE/y32fvD2NWPNf3BeRpUDyKN6YSag9qnk +zU2szwIaM0luqkXTqjr4qb/WEi8qwIfRfWAv2RZ3Hi8 +-> ssh-ed25519 JzjriQ NAMwKbrCpOm9wIl0zcd1JP8byAU64O2/yTmsf0yG3A0 +HebNORNtGrhBE3Ujcx56li8FgJUiyw9OimyCDw9kriM +-> ssh-rsa 6hPx7A +R1OIFZEF7GSLllqP+QMVm40hCAx8uChBTN4/lKXl8QdOYQSLZH6L817yWt+UF3Vs +0Q/skWWODUDj6apdh63iypkqSbhxWVHy7XlWki3oJNBp8fmioPtmZ7UHKWxzEtil +7ZtgJ/vkbJywFa8Is0rTs+Q8thTpthn2Ezdz/SbFy9X8f3fQRn7xgYTh08p3dJrF +tecmByC9Q6Jci0Xgw4+ZtjJbjgaYAQaMuyLVT+nx2v7fn/jnIckk6JifulvSxihC +mYf5qy9zG2R0J2ikdE4V/j8dFQS5+o3OU0qPqvXhNSKNWz71qLa3zJytHD6cZEcS +CUPJLQzI3oP8hbOk+NJ0m6ZGa3p219qSiNKq/P/EoiUKzJs4EJHlHWa3VOvjg+KM +uZeFYuHSAZcAjbtK3dCa9pESrsVzb/mDIwlT1K5PcHcyT2SQbTqXNFapqFJ9DzVR +hQTbuy/uL7nTTsMuMq71K+d1T+HGquVaLjqqXCiippppYhaenLvotrT+Zgl0mpin +ds/n9G5BBuXSM6pzOs97xTxUup2j0Xq7ykr3x8Cd6kyGc25b3AVbSHVLbfQ/4U7B +X/RmfIISYwPZvEiygc3mzyzLQEeLxi2q35yfmSJOk6DdUbGsGoF4ufXT0GjKj+gN +iYiHteEqoZ+MGkyviowtCuVSD5soF2pLrdEfm3txnfw +-> ssh-ed25519 Dfencg QVprlje+Zb4bsWPvtqsmd66mMvgAavFzDZYI0MoWA2k +1OqfCxvJ8oESIN0R3yD8f3HX0b7TqmjMqEFn+Hx8q04 +--- 9ilMGkwGdMFexB4xqRnlw+Z70McoFNsAJ9bD+4FddDU +`}M)vUoڝdSnL2V[_6FpdfDps0-ˇ)NaFfLަL?!A 9 \ No newline at end of file diff --git a/hosts/srxgp00/services/mailserver/mailbox-dmarc-client.age b/hosts/srxgp00/services/mailserver/mailbox-dmarc-client.age new file mode 100644 index 0000000..fe0dcbb --- /dev/null +++ b/hosts/srxgp00/services/mailserver/mailbox-dmarc-client.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw VRdFs1jw4vLlb9+U8wQI1O4dR/d5eO01YJXsX51LsxU +h+7Ke2y2TA5MdGp4UpouKUkz3+tSY4M0fB/leuShITo +-> ssh-ed25519 JzjriQ 5ayIpvnxJVz2xjczZfawxKa6v6dY+QjB7m2YFFX/FCg +IwRDDARLTk+ecqvcaAD+s4XGDEIMb9YHV3VsVWCoxVQ +-> ssh-rsa 6hPx7A +wEQcgNdS1VWnw0uQrxBifBRuS3rYEqlPRlLYSnvWOuSv91ySpiKnG53WnRCbMWZ4 +Zjrgd5Rqzd5M3ZLebguO5OOW63kuc6ZPtJPigYBjjUIVtMlZDYLeVsx4t1RAzULO +EWTDuuK3npQ3+zkAJ172iUsFzH8CQ3HXNy3BI+SS80SddI5cx8BuPpXhL/1uv8sf +vEQ/dz7oMLX8o4Cy8vLXKM1H6mm01qcqlF2E4eXIvk9OeqnkAbr6y8NU1pY6Q8F4 +CCVdVk7CSndnGk5R0x8bEaGnLMtMrNGKwjJoO9pMFKH9Dicnw1rNNxHfz4aGHUNV +XejAzYDtKxRge/wxfpd0sL2ybOhGse1IfjlWcSYeOycJVwGoRVYyFmUGgYUsdV3o +YzVWIyP7rcG7e7rwBd5ch3JqIgMFk3tZzBTaDHqk/NlxlSQd99Foz9FAV2/rT8eG +8fqH7+i3bpukHoV3VjF7boknj8pUqynGsivy7Awb6xF/dZTeOOnjztgScpF02RWW +S23HlI9QSkeir7cSHmtSBNmjGChJ0ruWDxt+qMnttak+eyzSpn/PPJMJZy/VquJL +BlLyE/IUkvuOJ+WBf7ZcyM1MIRTS7zJFrGOX3RV+7bgrHSHc+cZvmPJWK5GmXuJw +ZQtzmwQkbdZaAEADwtbHZScPSqVizxcx0M4yZHW4XCg +-> ssh-ed25519 Dfencg q01T3MDcsYOgbf0M70ohPJVmMxm7uU5zkEcjqpS2MTg +0kqqufEzwCLEBPk7w/nxZxWX5AcAJKQnOhdciUQmJeg +--- d0At3NFxZg2VONRpp4H7HucYjo8u/jmMMoGlono5Y8k +QZ|kc_t;rOJd3|$vzk`bi;?hA1 zKkCw@?&7~8u1;>+LES6`!O1RN{0Bat<@0euf8l3dH5N^rXP@R(2zLmycrvT&XyISc z^%@~(fGyavpWQ0jx0Z>l$^NaJ(qdYTgopC5yV=G;jpVn1gDH_VQayxd01_GL4SB%* z$&lO-0gbOE39S|&U61KlDTjlsH=85%e;Yr6DpqDuhEy?nOcVuYR$a^TS%Eqcg@{N# z^4L02YTY5Vi+7kp-fvRgNrLBhD~Z)`;8q8ZvM_z)y@o$ zPQ!+RPVS|P;JrNw7?UQA7h z5x{hrpZGyia?(lo#N8n~yK9Jq`{ei(2)*>o3|=S`{9D6ug@1#NYUJ!)s0^ew2A!(_VQ zK1$xyW3?R#ICirGE`hUP6Pje_Ua^jdBgqX|h98)-D6eXbYEM>sDeFBvHkf=7ibmbst+8 zEs?u8ZR2V`7=SVW?`(Q_M+nN+twLTV=js*{45@SGt7|SFZ##(4nsFY@>t?B1qrsb- zFj^|H1#FAQi{-_E3EQFrnJ+Uy2C+SX5DeOXAp?J1+J1Moo zl~>l=tJ&MA2yykgPcP8-=91_fB*T<_kMcs?w{wc z9=!ght(q5q{r>F-$;*e2s`tMNp8fIWq4(Sed(i72pMLj(0OI}pm;V50ADv(T literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/mailserver/mailbox-ugai0U.age b/hosts/srxgp00/services/mailserver/mailbox-ugai0U.age new file mode 100644 index 0000000000000000000000000000000000000000..6c3eba586b130abc31f01fc85d9412bef1eeec92 GIT binary patch literal 1205 zcmZ9Lz02ct0Du)8G`Kh^$YF63!fU>pWKo(X{iR9s-6l;$jx?W5^U)-2(gbd};TF-s zS%l+oa8tzL28ZKZ#Zd)0oJ7GzE`ANrA0EzBfT5v@fU?}4!e@g`?3nV(hvr%7Yh?2U<#m<2KtNbUksur~cj zR4_v?{Pu8!d*s~9TD9wU%SOaeNQpFy20=luL9Y36w&>j)I7xPo?ou@;7;lf1ZLWO;5X^Q>HCl>G7G(Cx66X2k$HjIw$H z3AI|f)XrE8DWpr)bg)l;!DKyb9FD3E?>!S3BAswf6Oik)TFTZr3NKVDop5^}dU;6h zR1YH@S#A62sMVCHoG^-#T+`MYqNGK2vzs-!&v|XU zH=#Domafdl6sVm2nWRxnpGGi#Q5w`&MwYVhvm7eil5F{+@Kczi60T^v8YaUX>y!)x zFB&7QaW4pcHNy+qG?XZd;&WmG&L*uI?i%?5*GpU}qM|#^TZBQle(i9w-bPLrK>VT; zyns!6Ua<{#SXX@-&(1FGq^!By8lAq;Boztdrr%~W3TcR>I>wSE%tY^qFVYI~M!7Z| ztWdiXN})J1MOe8jY%ZkS@|wgnRz6zidWz|1W(@#aG+BEnxh2pBMZqqnH%U`_l^uhg?sCVCc^yX*Z+^=Kz8T3CCH<;W2 literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/mailserver/mailbox-xaev9B.age b/hosts/srxgp00/services/mailserver/mailbox-xaev9B.age new file mode 100644 index 0000000..23397c1 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/mailbox-xaev9B.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw LL0r/vdSlTSYHqUh7eBfPr+WGPZU0iaC2+wjLrV77Ek +msGNfMkfyMsUJu3aSG7C7stpgZ0gwqI8IVZlFT1MKbE +-> ssh-ed25519 JzjriQ MYqtyTLYdp4JyA1a/ci6C44/9ye90RebTpfpM099xj0 +mCDfmBUgPmo4EjENSKvRkRokuQHqFXoivVBR2Tku5/g +-> ssh-rsa 6hPx7A +NUNRebYgygx3knvHH6jySx9ML0XSbCUy3FxNHWhXB1HSv1MxtPG57XTSsgISvmA0 ++Q/4p/1fB99FDvuZZyY1xDoCguJsUGMDzwfeb9J9bYwyuJR0h7ZB3UJWz417PcBV +KEGHYC6H7sdse/wC60deta4ZoftiwPHSxim7nta6uuUuVWkXlZxy/21ypknDo1NY +v/Ek6LhvzzhvYDwotjuQPVXOo4DulFE7AoNo5Xqd4VuzkifBZ7U6zxHRz17sNcOY +sLJW/6uEASbH9jarEv0PN9qcou5WtWEOiSoNdRs5SPWuq+SrFNRMmQOlz9m/9RNd +2zaNpeectLO7mMBq5VC+SIPUGNy+wq2oDg/NKt9WNHMfActciv/q0gJDDUHLYaMz +XponS47ngYP6SRS47g0IiufcT0KJsD8b8aMqyBL2zBslLoSXPThzYrzmfKMe2NKl +GVNDYn7LQkspZkL9Y4PcHcc6fiVHjqZxL1Rsx+H+yaXYz5PlTsL+g1jFeySsHPrT +NtQ7U0dbgSgG6yXMyYEl2QqHE1RFWjhDz7PWORJD0xCDTGBT5tp2crNeZ8sHYWqA +ipz52GgWszBTTYmMBYbke3MCj3/lJP1imcrNhIBILSLVHc0mkZl2srmLbCsvNq6U +Yxrdr4Q1l0julNiil7IFdZHo41LJpfCYSaCRvLXSyps +-> ssh-ed25519 Dfencg FnGT29dYaYptFPwz8wyMmTFIzgDDRQUYrzVPO/Y2dQ8 +k38BfgRhf5J5ZT1JsRcI/VS5iPCnQtXucZDEnVjYoA4 +--- 4fsRMPbGZKgCJyas/nepabKgC+8HGEZgjvBbVvGAfrA +AGgY^cCz^PJ_مg3v8`g.z^.B%; UߘЂP>"3!m=c+s \ No newline at end of file diff --git a/hosts/srxgp00/services/mailserver/webclient.nix b/hosts/srxgp00/services/mailserver/webclient.nix new file mode 100644 index 0000000..cec8604 --- /dev/null +++ b/hosts/srxgp00/services/mailserver/webclient.nix @@ -0,0 +1,31 @@ +{ pkgs, ... }: +let + host = "mail.srx.digital"; +in +{ + services.roundcube = { + enable = true; + hostName = "${host}"; + dicts = with pkgs.aspellDicts; [ en fr es de ]; + extraConfig = '' + $config['imap_host'] = "ssl://${host}"; + $config['smtp_host'] = "ssl://${host}"; + $config['smtp_user'] = "%u"; + $config['smtp_pass'] = "%p"; + ''; + }; + + services.telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; +} diff --git a/hosts/srxgp00/services/minio/default.nix b/hosts/srxgp00/services/minio/default.nix new file mode 100644 index 0000000..4a8460a --- /dev/null +++ b/hosts/srxgp00/services/minio/default.nix @@ -0,0 +1,103 @@ +{ lib, pkgs, config, ... }: +let + host = "s3.srx.digital"; + admin = "admin.s3.srx.digital"; +in +{ + age.secrets = { + minioRootCredentials.file = ./user_admin.age; + minioPrometheusCredentials.file = ./user_prometheus.age; + }; + + environment.shellAliases.minio-client = "${pkgs.minio-client}/bin/mc"; + + services = { + minio = { + enable = true; + region = "eu-central-1"; + listenAddress = ":9900"; + consoleAddress = ":9901"; + rootCredentialsFile = config.age.secrets.minioRootCredentials.path; + }; + + nginx.virtualHosts = { + "${host}" = { + forceSSL = true; + enableACME = true; + extraConfig = '' + ignore_invalid_headers off; + client_max_body_size 0; + proxy_buffering off; + ''; + locations."/" = { + proxyPass = "http://localhost${config.services.minio.listenAddress}"; + extraConfig = '' + proxy_set_header Connection ""; + chunked_transfer_encoding off; + ''; + }; + }; + "${admin}" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost${config.services.minio.consoleAddress}"; + proxyWebsockets = true; + }; + }; + }; + + prometheus.exporters.minio = { + enable = true; + minioBucketStats = true; + minioAddress = "https://${host}/"; + }; + }; + + systemd.services = { + minio.serviceConfig.Environment = [ + "MINIO_SERVER_URL=https://${host}/" + "MINIO_BROWSER_REDIRECT=false" + ]; + + prometheus-minio-exporter.serviceConfig = { + EnvironmentFile = config.age.secrets.minioPrometheusCredentials.path; + ExecStart = lib.mkForce '' + ${pkgs.prometheus-minio-exporter}/bin/minio-exporter \ + -web.listen-address ${config.services.prometheus.exporters.minio.listenAddress}:${toString config.services.prometheus.exporters.minio.port} \ + -minio.server ${config.services.prometheus.exporters.minio.minioAddress} \ + -minio.access-key $MINIO_PROMETHEUS_USER \ + -minio.access-secret $MINIO_PROMETHEUS_PASSWORD \ + ${lib.optionalString config.services.prometheus.exporters.minio.minioBucketStats "-minio.bucket-stats"} + ''; + }; + }; + + services.telegraf.extraConfig.inputs = { + x509_cert = [ + { + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + } + { + sources = [ "https://${admin}:443" ]; + tags.host = admin; + interval = "10m"; + } + ]; + + http_response = [ + { + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + } + { + urls = [ "https://${admin}" ]; + tags.host = admin; + interval = "10m"; + } + ]; + }; +} diff --git a/hosts/srxgp00/services/minio/user_admin.age b/hosts/srxgp00/services/minio/user_admin.age new file mode 100644 index 0000000000000000000000000000000000000000..ec628e1c51733ac42fb8b8c8f5baa86ebed65762 GIT binary patch literal 1225 zcmZA0IjiIZ0KjoqQ6wH9vf9oA!D4u3CU+WTl1$D?CYfY%Z8eiSnVFoEOR@43?A8wp zw|I>!Xlt`9E7({pEFv~5Hd?Y=l*NT>-dr9^q)EALL2{L6nb`k=ybDf41MrGPnB11KxpsWEY zYoaH{N>|DCDfJF5-g0NBfHYWABaxiDE0~L$?*E!Nrd6U%k^TS^-9>`L_i@4Bs-lZ_No>cxnV*B5(wS7_19AcX{FL@ zofWfPEC5&}q>Veb&z28$NSte9Y$il0X9$TU>$%=YOI49tPIL}pt01%9u^jQZ$Q$EG zRfPfpRPUeb%*0a(hBxTwcQQI3<6>=^hB!##NWll=K-E%=?e`!K#+wVZ)TWZZIOzXf>5 zO{F?&(u$X+-YBom@GdyZB1o2KbeO@Sh7VY6Lo?%C)=SJekjg*Mw;Dq^eZKx^|%0A!y|f}wCW zjzjHJxvhLXYUqX>rSrLHSSe`1O+ofVdvFKTj@?BYmPG~gVYN7+q`(1zBSqDlLeO+Pc zChcGxYzhN47tIMXHIYn zIvI#NIK<&WhTy^NpeNCjFE!ZcJqGsFz2ky9xRSeEFQdtF7C0_fFa*`7Yic z#pxC)F{t}eC(FF9yT(Zp>vw!U;SW_uZaf#`*Sb5w+L=Mdg2rspSe}e0Zs=vyxJHcf z0O%3~0u(x8hO;E<;BDB;S|^yK$`;o5A|S^7F})#yPguhma0&WfO>X^kH|>Dg6dN+V zkfAiVL|bzT3U#uO*xn!_0_Bi$`Oq*oS)Ug)$X}MuysyNg>Dq}45hI+vjn@NlIBrtW z6^ji)SMzjDGXH96w(3xxUehe3$aD$@WnW#7%8D-iWAiwh=RJv;HjOWDxMVS7i)w19 z2_4PSyr?K978j%CPMU1EcppMLJz9-ikJO0JP)4jN4j9|WS|&G!vE;Qa9ozF>t#N#4 zxk*msF3y|LVIMBROku_T4nmlWmq9*o>Mgr+3}G#|B7r)vCsNubht<4{^y6j;?{b;a zEeUV>RSCE0jCavVLW=-Qn0kXrWmxc?GdPno3MnGz1q3Z5j1z`Vfdp z13St_r<8o+D-&q0)Yhoy8WnQ97_-e3MwfWSN!dO+5F>aJcw5^V?d_cFO9USSwGR-_ zc^HjQY8mRo6{L83Ff&t`$#CQ_lyX$VdINswhiYx01B7pJ-}f9mX$m$I76+qV085q} zWRPHyrmZ}Pns4cm!y0wpnIKBFAF3#CX3ddA!H#^w!cmxrcP~LfY zYV}K729PD#8;#JU(whxde(kfKfa@w4!!yfX8A6bSDMFJr=a$=CHaRWVNv6lEz#%s~ za-SAZG>CU1(4sM}j^krFgXfe_Y@&&tgtQKZTbdE`pl%&?^1o~N&BKki9UTJ;Eu9te zq1+$1J;=1SFeppW({V}cEU-+ZNQo2^1QoPm8Z4dDsBP^sM( zCsc#M$h^q}sN3y!=-Q>y7{|I_|Mf9{vNS9JZS`+o;_Zwj|BdS9Hq{+Do1`0UQDe*nrL Bwk-ev literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/mysql/default.nix b/hosts/srxgp00/services/mysql/default.nix new file mode 100644 index 0000000..25da40b --- /dev/null +++ b/hosts/srxgp00/services/mysql/default.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: +{ + services = { + mysql = { + enable = true; + package = pkgs.mariadb; + }; + + mysqlBackup = { + enable = true; + calendar = "05:00:00"; + }; + }; +} diff --git a/hosts/srxgp00/services/nextcloud/adminpass.age b/hosts/srxgp00/services/nextcloud/adminpass.age new file mode 100644 index 0000000..f8f4f4a --- /dev/null +++ b/hosts/srxgp00/services/nextcloud/adminpass.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw gXLNgjhGBM10SZ1U2F269Hi0snqwdMBR9cxDA5vABDs +BVTnuH5HbgS2SQoZEFl7GsXvcYO7Eq1lH2zGhflfUR0 +-> ssh-ed25519 JzjriQ 3c/vRp79jgta5Ow2TfO3VOKABVTSSpshM43eU7o/uRo +LQt1o3Fm5T2ot6Dly9pNbl1YOt+0SQxqnSxMiapzWJs +-> ssh-rsa 6hPx7A +VzCl3ya8O0fD+nzqrTfZvH/W+JSQ1k6K30hKprc0FqhIMWWpmG7k9MDt28zlKqbI +V2Im+QWT3UNohQ7uKo+RsBTkGTRtL/kyGCUqqjfQEyDMgXSdjb05kaE0/jjFR+Tp +MrhuXn390S7Bb/vWW3pv+BqcyHMwHIp9raQeOULu0qBhCVkDaqZbKHqMXOyYyrrn +ooAbofosADSIQkKDkFoBdhIraPejKp7US1ytEG5SaG5uSZXUlgE4iwm8BFos6xKt +CJ8OX/RaNwylA2mkf704wZmY8DPt+0AGuzhyXvfQwB+InQLvNHLEnUl7ErCbxENH +lNWG5+EI7oYQycYg7UN1ofnBSbuvchERPVmDPRx7GSwqrIXj0uWtyys/NERYl1gV +GRdnzC90U+HBhN5l46hnHpyYuO6h434cAPeVa7pE6BQ2ZXvE07vPdyG0uMobq05x +7jLQoX6IAMzBLfzu8g7JpBRyRULhXm9ejPgnH3qCEvXWrRnwc16+1moMADXLyq62 +WtKxFlYALyZ3DnAUW2alZYMdSFTvGQ30GhX/7lSj2ndQ/3XppsX8BtGGVMkSX3g6 +Zc6Re4xqiXKDcqmtn1MJUNSm2kFC+Y/FXYmf92rkmnE0DfoEROwKs45PFX+Thz7P +NjRNPb0rjVJu+YipuOl4Bz1AC96U2BUTBcmwFP8ux8Y +-> ssh-ed25519 Dfencg H6B2Vjd4e6PJwMfsPBaYCYNCDehCryWXD/yvQgKPixk +1GbC05c7ruTO+Ca9KO6fpfMugigGKNhWR0Xw6qB5D0Y +--- ylP9OpryQ/nl1nCS46mGrOsS+8wR4YclZRQRK7hl3To +*e^+uK_ȋz?E Iŀl]޾FAŹYńu$׭r3c| \ No newline at end of file diff --git a/hosts/srxgp00/services/nextcloud/default.nix b/hosts/srxgp00/services/nextcloud/default.nix new file mode 100644 index 0000000..fa8657a --- /dev/null +++ b/hosts/srxgp00/services/nextcloud/default.nix @@ -0,0 +1,153 @@ +{ config, pkgs, ... }: +{ + age.secrets = { + nextcloudAdminPass = { + file = ./adminpass.age; + owner = "nextcloud"; + }; + + nextcloudSecrets = { + file = ./secrets.age; + owner = "nextcloud"; + }; + }; + + environment.systemPackages = with pkgs; [ + ffmpeg + ocrmypdf + tesseract + ]; + + services = { + nextcloud = { + enable = true; + hostName = "cloud.srx.digital"; + + package = pkgs.nextcloud29; + extraAppsEnable = true; + + configureRedis = true; + webfinger = true; + https = true; + maxUploadSize = "1024M"; + + extraApps = { + inherit (pkgs.nextcloud29Packages.apps) mail; + inherit (pkgs.nextcloud29Packages.apps) contacts; + inherit (pkgs.nextcloud29Packages.apps) calendar; + inherit (pkgs.nextcloud29Packages.apps) deck; + inherit (pkgs.nextcloud29Packages.apps) forms; + inherit (pkgs.nextcloud29Packages.apps) polls; + oidc_login = pkgs.fetchNextcloudApp { + url = "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v3.1.1/oidc_login.tar.gz"; + sha256 = "sha256-EVHDDFtz92lZviuTqr+St7agfBWok83HpfuL6DFCoTE="; + license = "gpl3"; + }; + }; + + phpOptions = { + post_max_size = "1024M"; + upload_max_filesize = "1024M"; + expose_php = "Off"; + short_open_tag = "Off"; + catch_workers_output = "yes"; + display_errors = "stderr"; + error_reporting = "E_ALL & ~E_DEPRECATED & ~E_STRICT"; + "opcache.enable_cli" = "1"; + "opcache.fast_shutdown" = "1"; + "opcache.interned_strings_buffer" = "16"; + "opcache.max_accelerated_files" = "10000"; + "opcache.memory_consumption" = "1024"; + "opcache.revalidate_freq" = "1"; + "openssl.cafile" = "/etc/ssl/certs/ca-certificates.crt"; + }; + + poolSettings = { + "pm" = "dynamic"; + "pm.max_children" = "512"; + "pm.max_requests" = "4096"; + "pm.max_spare_servers" = "512"; + "pm.min_spare_servers" = "32"; + "pm.start_servers" = "64"; + }; + + config = { + dbtype = "pgsql"; + dbhost = "/run/postgresql"; + adminuser = "service"; + adminpassFile = config.age.secrets.nextcloudAdminPass.path; + }; + + secretFile = config.age.secrets.nextcloudSecrets.path; + + settings = { + overwriteProtocol = "https"; + default_phone_region = "+49"; + oidc_login_client_id = "cloud"; + oidc_login_provider_url = "https://id.srx.digital/realms/srx"; + oidc_login_logout_url = "https://${config.services.nextcloud.hostName}/apps/oidc.login/oidc"; + oidc_login_scope = "openid email profile roles"; + oidc_login_attributes = { + id = "preferred_username"; + mail = "email"; + }; + oidc_create_groups = true; + oidc_login_auto_redirect = true; + oidc_login_button_text = "Log in with OpenID"; + oidc_login_disable_registration = false; + oidc_login_end_session_redirect = true; + oidc_login_hide_password_form = true; + oidc_login_redir_fallback = true; + oidc_login_update_avatar = false; + allow_user_to_change_display_name = false; + lost_password_link = "disabled"; + overwritehost = config.services.nextcloud.hostName; + "htaccess.IgnoreFrontController" = true; + }; + }; + + postgresql = { + ensureDatabases = [ config.services.nextcloud.config.dbname ]; + ensureUsers = [{ + name = config.services.nextcloud.config.dbuser; + ensureDBOwnership = true; + }]; + }; + + postgresqlBackup.databases = [ "nextcloud" ]; + + + nginx.virtualHosts = { + "${config.services.nextcloud.hostName}" = { + forceSSL = true; + enableACME = true; + }; + + "srx.digital".locations = { + "= /.well-known/carddav".return = "301 https://${config.services.nextcloud.hostName}/remote.php/dav"; + "= /.well-known/caldav".return = "301 https://${config.services.nextcloud.hostName}/remote.php/dav"; + "= /.well-known/webdav".return = "301 https://${config.services.nextcloud.hostName}/remote.php/dav"; + }; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${config.services.nextcloud.hostName}:443" ]; + tags.host = config.services.nextcloud.hostName; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${config.services.nextcloud.hostName}" ]; + tags.host = config.services.nextcloud.hostName; + interval = "10m"; + }]; + }; + }; + + systemd.services.nextcloud-setup = { + wantedBy = [ "multi-user.target" ]; + requires = [ "postgresql.service" ]; + after = [ "network.target" "postgresql.service" ]; + }; +} diff --git a/hosts/srxgp00/services/nextcloud/secrets.age b/hosts/srxgp00/services/nextcloud/secrets.age new file mode 100644 index 0000000..6676653 --- /dev/null +++ b/hosts/srxgp00/services/nextcloud/secrets.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw gt4LnY8JEyRm05USTTnnmoGb+yhY2ivHF7AYyDRS2zs +rLxQQOl158KA7sFDoSA1Dq9eo4hvKqyFQKuMiJYIKPw +-> ssh-ed25519 JzjriQ jLuV616OJ/W3mUU47Srd5zMrCK8R7mYM6s5ol/0Pl2s +MjUPz0mq7v+Ye4ZRR7yTXL8To+o7KZFrXjiHf3WQA7E +-> ssh-rsa 6hPx7A +3iihKSQ2x0fzSzXM+PRWTSrW4xqE0Gx73uZHWRnX/FlmipfC6tl5Dha9jPOKY8q1 +spUKmpvjs/N/MELP1z5NJMhnLXKO5S4FA81R2VJ/iR9XqTK+wx0reuytBsE291du +5PyKcMzFT+Nr6frPaHji9UC8J1GDb5zUXApRE2aAZjSeA0wA5bYXM0/bI8nt72hj +rK0Jn31I3oHHxU6jMFRMRv2yDHinSM88fF9c5qIDr7CHGyVZVi6aKUYi5WRXl0gV +JFQJ64Te9jPdpYk0SmvBtcTDQfBzYjEQDut4j2ssPkM+QqT96yCaRBdQ38J0oxEc +z/aeBJ3CQ2Sgq7D7wp+1Tj0gL2dgRtf6BriWSc+gJlwHk74xiruCj1V7PS0cGYqj +0f4p1zpdwnst0z/guzbpZfwXaMvHCYe44cpdY0WvuV6oRIifHC0ValbNUlnAdoyw +A6+/wuyBzcTDda5muhh6C4d6OzibcX0s5yuZ9NtqiLzPFgeCUNKcdAGlcQvq39Mh +89tKLWrSFVfbL3E/xQqiLX9x3W2iXPp4wETGnF8tcTeJpqYRL63g+/VpqYg0ZTki +jadSj01JWsr3uis/yAhV07rAIf+r6laPzpt50UuFmyadL5ODEVFyeh3SkndC/Cq0 +f4kq3FBrTjB+i+qw/a3Db2at6xT0ZATMzcvK2CK+Nig +-> ssh-ed25519 Dfencg 21+CtN2dIcGrA2/9M9gwiHfvundfX2IDWm3joukktQM +245qkkTOClX/swsR5gI4pYmmtCkGwKQC55E7RilEcGw +--- LsD1y9ZZvjrUAkeIg6lHAwh0CwbtBdT6f5HWNXLOX5k +|2>zUuLU'OHAс Jԡug +1+ 6k:waQa$6D?-H \ No newline at end of file diff --git a/hosts/srxgp00/services/nginx/checkip.nix b/hosts/srxgp00/services/nginx/checkip.nix new file mode 100644 index 0000000..7814f57 --- /dev/null +++ b/hosts/srxgp00/services/nginx/checkip.nix @@ -0,0 +1,33 @@ +{ pkgs, ... }: +let + host = "checkip.srx.digital"; +in +{ + services = { + nginx = { + additionalModules = [ pkgs.nginxModules.echo ]; + virtualHosts."${host}" = { + enableACME = true; + forceSSL = true; + locations."/".extraConfig = '' + default_type text/plain; + echo $remote_addr; + ''; + }; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/nginx/default.nix b/hosts/srxgp00/services/nginx/default.nix new file mode 100644 index 0000000..af5d8bf --- /dev/null +++ b/hosts/srxgp00/services/nginx/default.nix @@ -0,0 +1,10 @@ +{ self, ... }: +{ + imports = [ + self.nixosModules.services-web-nginx + ./checkip.nix + ./nix-hamburg.nix + ./srx.digital.nix + ./srx81.de.nix + ]; +} diff --git a/hosts/srxgp00/services/nginx/nix-hamburg.nix b/hosts/srxgp00/services/nginx/nix-hamburg.nix new file mode 100644 index 0000000..c8119b1 --- /dev/null +++ b/hosts/srxgp00/services/nginx/nix-hamburg.nix @@ -0,0 +1,27 @@ +{ pkgs, ... }: +let + host = "nix-hamburg.de"; +in +{ + services = { + nginx.virtualHosts."${host}" = { + enableACME = true; + forceSSL = true; + locations."/".root = pkgs.nix-hamburg; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/nginx/srx.digital.nix b/hosts/srxgp00/services/nginx/srx.digital.nix new file mode 100644 index 0000000..837e119 --- /dev/null +++ b/hosts/srxgp00/services/nginx/srx.digital.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: +let + host = "srx.digital"; +in +{ + services = { + nginx.virtualHosts."${host}" = { + enableACME = true; + forceSSL = true; + locations."/".root = pkgs.srx-digital; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/nginx/srx81.de.nix b/hosts/srxgp00/services/nginx/srx81.de.nix new file mode 100644 index 0000000..527d6ca --- /dev/null +++ b/hosts/srxgp00/services/nginx/srx81.de.nix @@ -0,0 +1,26 @@ +let + host = "srx81.de"; +in +{ + services = { + nginx.virtualHosts."${host}" = { + enableACME = true; + forceSSL = true; + locations."/" = { }; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/oauth2-proxy/default.nix b/hosts/srxgp00/services/oauth2-proxy/default.nix new file mode 100644 index 0000000..f0ebd88 --- /dev/null +++ b/hosts/srxgp00/services/oauth2-proxy/default.nix @@ -0,0 +1,80 @@ +{ config, ... }: +let + domain = "srx.digital"; + host = "auth.${domain}"; + oidc = "https://id.${domain}/realms/srx"; +in +{ + age.secrets.oauth2-proxy.file = ./secrets.age; + + services = { + oauth2-proxy = { + enable = true; + keyFile = config.age.secrets.oauth2-proxy.path; + + nginx.domain = host; + cookie.domain = ".${domain}"; + email.domains = [ domain ]; + + reverseProxy = true; + passBasicAuth = true; + setXauthrequest = true; + + provider = "keycloak-oidc"; + clientID = "nginx"; + loginURL = oidc; + scope = "openid profile email"; + + extraConfig = { + metrics-address = "127.0.0.1:5673"; + oidc-issuer-url = oidc; + code-challenge-method = "S256"; + session-store-type = "redis"; + redis-connection-url = "redis://${config.services.redis.servers.oauth2-proxy.bind}:${toString config.services.redis.servers.oauth2-proxy.port}/0"; + }; + }; + + redis.servers.oauth2-proxy = { + enable = true; + port = 6386; + }; + + nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = config.services.oauth2-proxy.httpAddress; + }; + + prometheus.scrapeConfigs = [{ + job_name = "oauth2-proxy"; + static_configs = [{ targets = [ config.services.oauth2-proxy.extraConfig.metrics-address ]; }]; + }]; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; + + systemd.services.oauth2-proxy = { + requires = [ + "nginx.service" + "keycloak.service" + "redis-oauth2-proxy.service" + ]; + after = [ + "nginx.service" + "keycloak.service" + "redis-oauth2-proxy.service" + ]; + }; +} diff --git a/hosts/srxgp00/services/oauth2-proxy/secrets.age b/hosts/srxgp00/services/oauth2-proxy/secrets.age new file mode 100644 index 0000000..d77af79 --- /dev/null +++ b/hosts/srxgp00/services/oauth2-proxy/secrets.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw W2dbMcjU4bR5zQ0k2Z/6hR7hwzZ9PkAEv61suzJs/E4 +NiLEBUVQVEbTN6heg+JDCvt7b5hFDc3zOItKwJLttbU +-> ssh-ed25519 JzjriQ gBWt7o4AKcR9ByJCnLe6S6mh8v1Fq2mqk/BPK4Y2z24 +Ginz/IkisV4BRmjcj4ZmwCUawibIo4KYO5NeASxS5ns +-> ssh-rsa 6hPx7A +UWmmiSoCzvY0Jk+Uf76MgiHS5ha/Qze8arOTWctfge+DM6ur8eGxJUq5U7FoPj2s +Grv4hS/NxcXg006S+ID8/c1jWBtU8mCZG8lck5iNMpfnQZ+cRGPdv/Wef19ORtTp +LDCPjzWNJg6G985HPQu6G6+RbYJGJnN1Kf6c9mrmXNIJmiJoRIBjxbLicfHzjYKl +dyIQ20RpOwrhrl6QWhZl1A+KCqh2oMExm4qaocBD2+IKp8GZRWPFX4YBkqWzphnx +R8u+1bxcN7ZCkB09FaLoVCgQabh01hGpDSUcvQbHfvn1YJtXVegqUUrf6atU7NbT +z51z2EEIZ1lHYE1qGDTBHAl81y5gSSmW2ccHKDQ9CsuIByXgjOGLo0/FLB+fr3oA +bHaCvKQvRfz3wXS19X78xLz1MZHBFDWpVmRqEkNijQJGu1Ihii8ATNeu/IVS3erF +WIxYjs65xYr0+zY6+90n07E1+Gt+qW4ZBstslz/eP0f9iVa2uOCsvnQU8MKrurBM +43WqRlIz7HjeHXUlBBtzelGfjL1WRTM786haIeNlzkl2XDZ2Av1qUdhPBGA7rSl7 +jNVF4Rj9YurRtB78IF3XFGDmyNt5/TNw0qOF32jKpetO26GiYV/Ia+QKwLklnUuz +hT+7JzO5uQx9u4EqElQvBwSnk3NQ3+EBuBt8lZP56Ns +-> ssh-ed25519 Dfencg G/63XTx+5UrL9Kd6frbq/q7EG5b8RJ4y57+mfVSEMlY +MNTaYp9jlvoBMI2PxdiccpqEYBY8mARp3tqPZuSo4bs +--- fzhYndI2/14JjCXprVjEvTDo2pSvalSTpxAVXqFA8g0 +j~ugy0O<d_4r9j[횄- <1.~ -[}LdaPÃFh "tҽF%)xd0gD!Q|!"5r\[OtP,1"T@k{ \ No newline at end of file diff --git a/hosts/srxgp00/services/openldap/default.nix b/hosts/srxgp00/services/openldap/default.nix new file mode 100644 index 0000000..fb15a74 --- /dev/null +++ b/hosts/srxgp00/services/openldap/default.nix @@ -0,0 +1,133 @@ +{ pkgs, config, ... }: +let + domain = "srx.digital"; + host = "ldap.${domain}"; + adminUser = "service"; + testUser = "hans"; + # domainSet = lib.splitString "." domain; + # domainTLD = lib.lists.last domainSet; + # domainSLD = lib.lists.last (lib.lists.reverseList domainSet); + # distinguishedName = "dc=${domainSLD},dc=${domainTLD}"; + distinguishedName = "dc=srx,dc=digital"; + bindDnAdmin = "cn=${adminUser},${distinguishedName}"; +in +{ + age.secrets = { + ldapConfigSecret = { + file = ./ldap-config-secret.age; + owner = "openldap"; + }; + + ldapBindSecret = { + file = ./ldap-bind-secret.age; + owner = "openldap"; + }; + }; + + services.openldap = { + enable = true; + urlList = [ + "ldaps://" + "ldapi://" + ]; + configDir = "/var/lib/openldap/slapd.d"; + settings = { + attrs = { + olcReferral = "ldap://${host}"; + olcLogLevel = [ "stats" ]; + olcSecurity = "ssf=128"; + olcTLSProtocolMin = "3.3"; + olcTLSCipherSuite = "ECDHE-RSA-AES256-SHA384:AES256-SHA256:!RC4:HIGH:!MD5:!EDH:!EXP:!SSLV2:!eNULL"; + olcTLSCACertificateFile = "${config.security.acme.certs.${host}.directory}/fullchain.pem"; + olcTLSCertificateKeyFile = "${config.security.acme.certs.${host}.directory}/key.pem"; + olcTLSCertificateFile = "${config.security.acme.certs.${host}.directory}/chain.pem"; + }; + children = { + "cn=schema".includes = [ + "${pkgs.openldap}/etc/schema/core.ldif" + "${pkgs.openldap}/etc/schema/cosine.ldif" + "${pkgs.openldap}/etc/schema/inetorgperson.ldif" + "${pkgs.openldap}/etc/schema/dyngroup.ldif" + "${pkgs.openldap}/etc/schema/namedobject.ldif" + "${pkgs.openldap}/etc/schema/nis.ldif" + ]; + "olcDatabase={0}config" = { + attrs = { + objectClass = "olcDatabaseConfig"; + olcDatabase = "{0}config"; + olcAccess = [ "{0}to * by * none break" ]; + }; + }; + "olcDatabase={-1}frontend" = { + attrs = { + objectClass = "olcDatabaseConfig"; + olcDatabase = "{-1}frontend"; + olcAccess = [ + "{0}to * by dn.exact=uidNumber=0+gidNumber=0,cn=peercred,cn=external,cn=auth manage stop by * none stop" + ]; + }; + }; + "olcDatabase={2}monitor" = { + attrs = { + objectClass = "olcMonitorConfig"; + olcDatabase = "{2}Monitor"; + }; + }; + "olcDatabase={1}mdb" = { + attrs = { + objectClass = [ + "olcDatabaseConfig" + "olcMdbConfig" + ]; + olcDatabase = "{1}mdb"; + olcDbDirectory = "${config.services.openldap.configDir}"; + olcDbIndex = [ + "objectClass eq" + "cn pres,eq" + "uid pres,eq" + "sn pres,eq,subany" + ]; + olcSuffix = distinguishedName; + olcRootDN = bindDnAdmin; + olcRootPW.path = "${config.age.secrets.ldapBindSecret.path}"; + }; + }; + }; + }; + declarativeContents = { + ${distinguishedName} = '' + dn: ${distinguishedName} + objectClass: top + objectClass: dcObject + objectClass: organization + o: ${domain} + + dn: ou=posix,${distinguishedName} + objectClass: top + objectClass: organizationalUnit + + dn: ou=accounts,ou=posix,${distinguishedName} + objectClass: top + objectClass: organizationalUnit + + dn: uid=${testUser},ou=accounts,ou=posix,${distinguishedName} + objectClass: person + objectClass: posixAccount + userPassword: somePasswordHash + homeDirectory: /home/${testUser} + uidNumber: 1234 + gidNumber: 1234 + cn: "" + sn: "" + ''; + }; + }; + + security.acme.certs."${host}" = { + domain = "${host}"; + inherit (config.services.openldap) group; + reloadServices = [ config.services.openldap.group ]; + }; + + security.dhparams.enable = true; +} diff --git a/hosts/srxgp00/services/openldap/ldap-bind-secret.age b/hosts/srxgp00/services/openldap/ldap-bind-secret.age new file mode 100644 index 0000000000000000000000000000000000000000..75c19f71e0c3757275cf99094124b09370289a19 GIT binary patch literal 1185 zcmZ9LIm_e(0ER78B=%c~#k3MWCz;9QSVYJqncSIVlF8LbuE~8&GC6;MpoJocU?JG7 z<+`1OZPFhiM5His|v8i{XkaN-%3cOnxKiZhV#xqujO zIc>^xZ4xs@-SWl~RN8er?uMyGG21X1i=LtVpC&9>n`*1Z(hEf7HPAVjwaf1poKPW= z574aO;^kyOO*O_+lvZpFXlr7VKzkzaoueUcsBD7A>|C7fwBaxUma$X3jLfySrT96m z?YtG5s1rs4vrg}ui`Rg-UyeGv6n=E&aJ$il(tRsAnWKMU2SKl3hEw_B#jdFeJ8TU)heJkLyc}x4(zPl z*PWkAYSQI8oVVnhl-s5kMeoR4Y>sAg3l>RZr~YgL%G1ITWdURy$1AyaCmYHz1X8BkgvO|+IK zq^U%*$#MwFY#P_OZ57A4I!=2D5zO<|Nj3K1V+>?>L%#8LRdI2#Vjf)Jb}EEXfNb_a z>Ll59aJ2Un3{gDBmDEn8W}8FCxMD0ZL~UwaE$Y@d;X`J!B?z5F4%lF^uEaFWq&beC zb!e=cVw}rc+3pAz++l)lU2#EdEni>)XW?8^1u5AIdXmNHjg$Zxu2XB7&yeQIu0VUAMwpA7BN2II%n5v$ksu2ChNjp-7828R#B0Wj7KX zaXt51@B5+6nPdiX<55kL(siEy__?F>MR7ScxpUfPN@`}J0G6$-hb1fwO4eOj zJdZ$X@pa)`@IXD=}zV+v~Uns9VSpItDRrKc{ zUw``18-M)s>3hfbfBEL`?~xZa&t86_{04n32EkXK{G@;Q<-0F^{Ob?Dzw?a!_wz>& M<)`WgkJHEh0ndMu?EnA( literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/openldap/ldap-config-secret.age b/hosts/srxgp00/services/openldap/ldap-config-secret.age new file mode 100644 index 0000000..63025a8 --- /dev/null +++ b/hosts/srxgp00/services/openldap/ldap-config-secret.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw tQJi3a3tKiJl5ZfNkro+cOEGDAbUh+vbGf+L4MTCu0k +UioTuNzRsHau5sCRfw7L1y2z52EKlQKscNAv6aCEKl8 +-> ssh-ed25519 JzjriQ UxmUpbg8QKiYsKjkHk00uDc2LcKRye+uwPGiwMD0wmA +/pBpwVPDdiH8TMNksH2V8FtysncRGvtO3sdoSeU2GG4 +-> ssh-rsa 6hPx7A +iJBX2tRnuY0ZMquFrij61pUpuJsgKIy7cgaISaW0vSFtiplmorYVKY2DUmHJ1qbO +4cCb7P72XDs+5utQyTvO80WTKEFMUxAYpVb8VJ3MuP9mRNvlptcI1lCB47IhcKzK +YZFXpbRAMp4u9kTxZiaYakiQsPoaDK6FjQ9XEG1JxjOn1u4XB/WHxG9blW+AIpn9 +1h+Fs7DJF1tU20MlwaLLF5XooxLbDKr/MKeiR1k0y3H6eDtEiQH+Ay42/e1yPwAG +BOO08YxEzAl8sLg8rzlyCu7O1uTvP2wlvqBMV324iu1ug6Le7Gh4ilQyGSLsYOxK +m6rggC5kUEhfBT+60ACReFJx/T/8A/KTYLiQ03F/lmimaCPqnNwkydjSCmIOOiYc +u+hFS6/9TyNM97svMhmq0ttwOhf+zIXVB0zHJ2w9Pj4U77KPrd/C6Ctvn2Q6XK1a +y3EAhTErk4R5fXUiQIcN/5V4lkGPAnwrlqRu4fZAhX/os16M8YZkRoKPNp+aI9Ji +RXBIenbhBNv/9N6/ID1aTZ8Epq420mcT/VEXN/9KkiReWt9ju+lf1NQcCzW4ETZT +WGWay1k0/MFkXBXBW/r1D1p595U8jNB1kfyz/AKTbY/MP2G5FTdM+GsBQ+E6lE9+ +B5xY/iwbrOj6HIuWqGXtk2/c9mOuBTFwCtx06KScayU +-> ssh-ed25519 Dfencg 1sbJD67nv/ArocTaWkLnM9YclfGlRCa696NkshUhaAk +eFbUDRH4GGJVNHv89qwxMdlpjpl+4o3jxPYT9bm+Du8 +--- KVW/9rQkJ+rdNKHcKAlIXpI4yNcdXzmx0NaePNSuyns +5B5g Ód[W{Y&zMP:9:.2 +z$m#z { l7Ć* \ No newline at end of file diff --git a/hosts/srxgp00/services/paperless/default.nix b/hosts/srxgp00/services/paperless/default.nix new file mode 100644 index 0000000..629bfaa --- /dev/null +++ b/hosts/srxgp00/services/paperless/default.nix @@ -0,0 +1,53 @@ +{ config, ... }: +let + name = "paperless"; + host = "paper.srx.digital"; +in +{ + age.secrets.paperlessPassword = { + file = ./password.age; + owner = "paperless"; + }; + + services = { + paperless = { + enable = true; + passwordFile = config.age.secrets.paperlessPassword.path; + settings = { + PAPERLESS_OCR_LANGUAGE = "deu+eng"; + PAPERLESS_ADMIN_USER = "service"; + PAPERLESS_DBHOST = "/run/postgresql"; + }; + }; + + postgresql = { + ensureDatabases = [ name ]; + ensureUsers = [{ + inherit name; + ensureDBOwnership = true; + }]; + }; + + postgresqlBackup.databases = [ name ]; + + nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/paperless/password.age b/hosts/srxgp00/services/paperless/password.age new file mode 100644 index 0000000..90a3632 --- /dev/null +++ b/hosts/srxgp00/services/paperless/password.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw ImlVc99pq750TSzRKTcl+MiuH48A0a8i/CzWr3hMTCA +6HmkKtwIhBoLBYUSsr73gSZwZ2nOJPGhtVF/oZxjzAM +-> ssh-ed25519 JzjriQ d8yMMWhdt6idbv8bxxHRvSRDXsfuOUm90YTfrXoD1EE +yQtX8LadpLxetD1zMxPge0wjIjV/9TDcjCmseGdrYuQ +-> ssh-rsa 6hPx7A +qKpB3nXTGN3gGW8K9XE3bfRTJpukEuIpb3Km/4hppWaA72gWXZOeSICTMZEf7u6/ +oRYJpOX9DR1dbX4dXYTuyidyUWUQ6jr5xwzpVNO2EGfZj8bqfRjB4CBzf1ixYZx6 +je6rsFPc10BU8rwYxb3F6ZdIJGpwmVnqNDHBcgl0uprUyGhEAAytKuS+QJO6h1/T +SvB49ToPr2gOLbYicuIL85Zo2PsHlQLQzt+2+jLWPShFUb9PPyyqbnp70TSu2vkD +UZMyxoe861E7ocx28zrm968TzR/UsRo8vLixvcAKlee02OpNe3eWnRlduDuoeR28 +aUSXKnqPs3BPpce4/pcpnYXpqCUtrWILV6OQQ0qq3dZSif82CyHx9e8ftXyYMUZ2 +1HBVLO7qMgx5oN1U70Oxy3ZOwv3UIqHhOe42BiF0cNpIEEtdWVl2RjVyN6pL/3ci +SZO2r2aS29oEOtxGGwQXlJJn1T7z94isotFFOst0/s4Qwp+bUv6G85CdVI3OJaJ2 +5ACu4j/mtP7v6MkY/yTVU62Ne57BxI3Y4TvV8cJqIneeVQlsZwyE0YM1C6Lvp0J6 +UUQjQRItfrX3bXuZZ6N6joPLN6wFARmxgIXAJtevaDC9IkSgpPWDSrs/Vfhj5IBD +zkuwSije7KzjKLQxQs2Qv5FabKN13xqu/VOPnAWBvCw +-> ssh-ed25519 Dfencg tglNj/t+eye5AZIEtxRjAg/TQtYWUxJO8wCKPM7ITHQ +3lZEIz8qPuoiyiNM8i8gFzX4spMmbNut51DQ9AOMjHc +--- rD33wYC+pDGERf8tYF96oGcUHZapBLHnVxPfi3PDu54 + i>tD$ U_I}Z@{ h1s0`9[S.ooH QQ \ No newline at end of file diff --git a/hosts/srxgp00/services/plausible/default.nix b/hosts/srxgp00/services/plausible/default.nix new file mode 100644 index 0000000..eb3c0dc --- /dev/null +++ b/hosts/srxgp00/services/plausible/default.nix @@ -0,0 +1,48 @@ +{ config, ... }: +let + host = "analytics.srx.digital"; +in +{ + age.secrets = { + plausibleAminPassword.file = ./password.age; + plausibleSecretKey.file = ./secret.age; + plausibleMailPassword.file = ./mail.age; + }; + + services = { + plausible = { + enable = true; + adminUser = { + activate = true; + email = "hostmaster@srx.digital"; + passwordFile = config.age.secrets.plausibleAminPassword.path; + }; + server = { + baseUrl = "https://${host}"; + disableRegistration = true; + secretKeybaseFile = config.age.secrets.plausibleSecretKey.path; + }; + mail.email = "no-reply@srx.digital"; + }; + + nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://localhost:${toString config.services.plausible.server.port}"; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/plausible/mail.age b/hosts/srxgp00/services/plausible/mail.age new file mode 100644 index 0000000000000000000000000000000000000000..487aa5aa2b5598c747cbe117974c165e4aa96b4c GIT binary patch literal 1175 zcmZ9LJIm_?06?7tvx$p$kq&oIL(RKMK!v>DNs}hc1MZMC&9iwmZ62MS1^>zm;A4QFqOu2?4gBZpN|Lo>P<{5PDPb zJwMEwfTR>Oa!Z%NFcK?OKd1alZx>8{zK@vh1(Gk65Wd$I9AH_FCMX<_Eu*9C6`#?0 z<%$uz*Bn@%79GVMK8-{+0hRyL)JJtK?af>ey~VO5BYSs+N3H8+-th@d9oLriE5!&I zx8-*Uy5=@u?XW#crHN)x*02)3H>4xkil8*(6-*Flr4?L<2KKbn&$R0pZ+69gAsIj` zGw;UG%FKlw$mKKIst=shc&a@Zha-{28H*FLn;J{K&Iw6e)ML>^$TdGe{7AwAfX_}q zXT?GW=yI3AYv3GFJZnHJ-0x@7kc_dUYjZaXZVfqmJD4FdZP3V2#6@$jVFh>$#l%Dd zA_@ghvq5${)F*{O5uyy0BO9^IGa}xQ%Q{RAn3`0RhcLztWuI2$K^kVD0i}MX$|i1A z(Nu4VGIE7M*qSkb(WMWPV!|uWac`1p+)toaL$G&_(_ta-U3AXw2@raS4|fj{eprwj z4c#=IYnx9X4sl$ErX3d=1t%1zK8hU5={tWq1tV)@90pC&_CDa#Idh(>tIPV>15fqPIuzk70+~UA4$56w{W{7E9z@pJaOgukMW)Axeca8s;P*hh_aWRvkcF4fjG)_skG1Ej# zq7gagki$p&x#QvfX*TJfx>< z9EKx>MmqH)kvkc6*_FzWS6VdXbxD(=VbljG*y%?^0JhuhCO7vU57&Dza|dn^$e0uvoB1M2x literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/plausible/password.age b/hosts/srxgp00/services/plausible/password.age new file mode 100644 index 0000000..e1ad754 --- /dev/null +++ b/hosts/srxgp00/services/plausible/password.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw BHpRYwBogzVgKIZ4UGrIhHs7KPGi5X1LHj3ePqbP4hY +9q1B89pSlI5ZD/42TAHGHL+yHa0a6hQR5Glezc6F/yg +-> ssh-ed25519 JzjriQ a8pElvBQ5eblGFHamtwGR4DnsvbBeiks1apLIdPs2AA +lhufHExUpSpVfAbUsLVOc3cR2oOMek2aiBEWTmxM468 +-> ssh-rsa 6hPx7A +FFtNqcWwHH4Jr51oLzZnyGRuAwLQ+RFEHhXnjrt2xtSOV8b6LmDprr7swahjz7Cl +fjda2A0rBElySjfzc4QIAzNtqjTGIzcmeGxuQrEWhbQyGoARWgp/EQxSln7ydD1x +ancyiPWTgnd2Wld0mAxoMRhp/0EbNdRlA3JIxlIeb5qxQyxSy72Yg9S3qxjwi9SM +q0WbjW4Tg4IRh2J/okP0H7KLfABi0qXB9pfWCtBtuUxNMZ2ekEzouS8SBumd6oUR +AYpCGt/eAn/AwOXCdAD73onsB8odB0MVpH1RYZRU9wOuHPIuTZjH+h3AI4779AnM +jLDvMEZVe0KMXuYrb/94djkyfnIeECEzOtc7W5i8vS283zoAJdjqwIRY5P1JOB3K +XbutCM1QnWTmx3GZ99UwyAYEfRHWMHdsBOxygJXYgXFSWQJa0monKayX2s0GPHEz +s1/CwqJ95TPsucPfC59q7UVkIinDTk1osR42hjqoKbOPWvPR0O9yajhijvMiNJJp +fkEieUAzIT/YzoAkbRbC4Myzitq97VPsHIfFy2jPG1tf5gVN2yxZj3EFIKxM5tEN +kvx+WLhY/1HPP4c31hXs0+U6Gw5sML/j9ntJnD0cmPsyoeWbjUNhuX8ulM4zUv/X +k2d3k61F9nLMU6yEPw+V8mzPqf0UQaL7VW2UapTPkRQ +-> ssh-ed25519 Dfencg TLzld5xDEsoRFtEsMsahiRYg9A51L4ub8j0+vSRP/T0 +9x8xqil/0DQUgWFPAp7yc9iWnJ9uX9MosTmwP+fjEKY +--- 0H2hrCIaBG759rpwwPW6x456cJTgayK838A178Vy12A +lg M*?2rqv~d 5+(4o[*YJ \ No newline at end of file diff --git a/hosts/srxgp00/services/plausible/secret.age b/hosts/srxgp00/services/plausible/secret.age new file mode 100644 index 0000000..da72f8d --- /dev/null +++ b/hosts/srxgp00/services/plausible/secret.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw oIY2chGlJnQwRKGYUPMAmueSm/hRcj4qyEGRP4v99DA +iNW2k9EEprnMGRA2BHitSztk49lbbaQt/QJR40BC2K4 +-> ssh-ed25519 JzjriQ mq5SPS7+UlBdCS6ZTtHy7MGZyIGudllK0QKTCzAbfR4 +mGaMwonri+MgWovKK6iNrM6N4eTBZrHX5FrPij+lLz0 +-> ssh-rsa 6hPx7A +KQmnB9QgfxBMTAUnO3l7YjDqQAskGQV3Hve7IRg4b4sG7HFW3aI9SIKXpECzVvT4 +5kHqrSJNeQvo8fUdxdqvfXDPaxaVz+sWUmfbTzcZagAg6jkxEqlxeUzDw6mMgUu+ +QjJsSFIwOIyNTlAjdcbH9ZdEKZKGsmbaPvMJlqrDs+PPKpXdkemHDcO2QrWdKqlX +N227ljuOf05Qgbn+JJw3m91tMscxDERFCfCt28jLX2IaPdriexLiJv6LDSLIyf3y +uhwtbVX24PmKhCPeL/PKYjFKyCXrWyhNSlOE7bQSgWSdfxinvSsjc8DWwfC7vhvo +aouEhAzXGd1AnQTBuUz8N68fQckSw5RVgYt4fbemN0Y22GFK51ZstjYmP+33xMTb +CKrs9/wB+nEmIzQ3N7yj+xbCoYmpJ7Ce2Q/qdp4MYUn3wVgoU4SiwWAZUe4aXgAd +LmGo1UF9MgPETDEhf4TDNQoQWL4mxNxHDTEUSfjsDd/yL1DVt0hfzoVsGgSXDHD2 +GeTv0/nCu/NhWW8Lxo/HEcSg3JzFk0kd53LzvXTqqx8vnXW1lyzZcsZZp05gJxqo +iiKIzzUBbDhXR+pkhab9J6DOxKxIZabjjejsb8cKS8clOTwsyqExsbi/dYoQaFmd +Sr9B6FlpANDdhSTcnmOXJ9GHtNzjMNiiYil7TyMfl5M +-> ssh-ed25519 Dfencg /fWY2Ahqeu99jIPhbcbzlPZDz1Pev45LNSis0aCx0n0 +IblFmuMc9XhDTrpG/iy0jeGpn8vmYytSdCeXpKeeJX0 +--- Xezwhc5YCpsxxJWuvyNwYozTh1OXst7iT6xCuepciLI +pzsߩĽfTdD%wx /^*v܀'ME ZpozzΌH.[6ԁIJ1@ 88jĤz \ No newline at end of file diff --git a/hosts/srxgp00/services/postgresql/default.nix b/hosts/srxgp00/services/postgresql/default.nix new file mode 100644 index 0000000..8099c3e --- /dev/null +++ b/hosts/srxgp00/services/postgresql/default.nix @@ -0,0 +1,14 @@ +{ lib, pkgs, ... }: +{ + services = { + postgresql.package = lib.mkForce pkgs.postgresql_14; + + postgresqlBackup = { + enable = true; + startAt = "*-*-* 05:00:00"; + compression = "none"; + }; + + prometheus.exporters.postgres.enable = true; + }; +} diff --git a/hosts/srxgp00/services/prometheus/alertmanager-env.age b/hosts/srxgp00/services/prometheus/alertmanager-env.age new file mode 100644 index 0000000000000000000000000000000000000000..c14049ec3a6996a7b1668fc74f65a6b8814a749b GIT binary patch literal 1364 zcmZA0+3OSq0Kjp{A{#>Ncrnv{Vd=y4YmVKWgGAfencdmn?p(V&GrLO&b6>kV*Y3>D zff-ZzmEVV!^5`v17BorhID=c4p=`Z-ce7>4vEn5>KDWa(t zP96;t2g(p&dFN7^y33Y{Rw@X&*==I;|g{{@a2?|;|3oG zl{poOu4~fGT9Rr@m@CflDiAtig(BQGgH)@{24=L-+;LNGA>wM*jg=r` zaH@tC31uh{(zifmVLDntN&z(zTZqK~6|V@ohT7yH4@1dGI7xKN5%B?<2(~RulF()d znG&EHBDx{fuj!3w+%@D`Nz?OjrQZdl&{zyf;Yh{3H742x$r+S*Ekqn|*WrOMH^RXDDdP~QPdXt7} z-J6!FzAI7s2orL3AWR5JF>!n$PJwc#t?D_#E|5Be7DcG$UfPrTa8PN^L)h--RywG9 zc{mT{24}L(nIF46*W&s!QWjva1<;Z#$R-C95bd^vA``e^PLue`1OtTu+N4M;p34b} zXN#G^@GK?Jo*s`hA1p#1PKF^Mw@p(try2$=h*m4_s|X9t43Oh+LZ#dcCUJHoD@NPz zF>#6Rlz5skZ4HIyijvvnum!Mj4kciuATogk2J5p?JrmpQwh;B$l~kJ|ep@Y+Tprjr zTxL#HkmfU0XbU5s1WPg829h$zPKpv*o}&~|uco*L)ub-T>v7YAgjTnf(n%2ditHf` zt0NBwD`8^NqFuy7ziY4|z^9?yq|6f8=`M(}CctT?MSPl(C}Eapb_^Ms+0QbN2;`fN zZ$3)fH#T;b3`NG8Rl%yr0l`4wN(3TJ3~5zy+aKjMOU}%BxzBgTe4Yb6jLT4>(wt(h=Af`qXFvAp#7+`sMd5NVf;84K$cE@$+*r^@tKpoL45J`ZR+s}N?`|`K#wI?Y;Hvz3hf#-E&kJo_h89)s5@d{<$U>ckKOb)0^4-yT92} z-f{iN?X_C*x9JNHet0F=^4Il;`1|NjPVBn;-M6b>{qgRm=it@!scX~se=K#^9XjED Yy?XJE9r3dt!^p;c$G%*9x$_qNAF5H~G5`Po literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/prometheus/alertmanager.nix b/hosts/srxgp00/services/prometheus/alertmanager.nix new file mode 100644 index 0000000..9f0840e --- /dev/null +++ b/hosts/srxgp00/services/prometheus/alertmanager.nix @@ -0,0 +1,107 @@ +{ config, ... }: +let + host = "alerts.srx.digital"; +in +{ + age.secrets.prometheusAlertmanagerEnv.file = ./alertmanager-env.age; + + services = { + prometheus = { + scrapeConfigs = [{ + job_name = "alertmanager"; + static_configs = [{ + targets = [ "${config.services.prometheus.alertmanager.listenAddress}:${toString config.services.prometheus.alertmanager.port}" ]; + }]; + }]; + + alertmanager = { + enable = true; + webExternalUrl = "https://${host}"; + listenAddress = "localhost"; + + environmentFile = config.age.secrets.prometheusAlertmanagerEnv.path; + configuration = { + global = { + smtp_smarthost = "mail.srx.digital:587"; + smtp_auth_username = "$SMTP_USERNAME"; + smtp_auth_password = "$SMTP_PASSWORD"; + smtp_from = "$SMTP_USERNAME"; + }; + + route = { + receiver = "default"; + routes = [ + { + receiver = "mail"; + group_by = [ "host" ]; + group_wait = "30s"; + group_interval = "2m"; + repeat_interval = "2h"; + } + { + receiver = "telegram"; + group_by = [ "host" ]; + group_wait = "30s"; + group_interval = "2m"; + repeat_interval = "2h"; + } + ]; + }; + + receivers = [ + { name = "default"; } + { + name = "mail"; + email_configs = [{ + to = "$SMTP_RECEIVER"; + send_resolved = true; + }]; + } + { + name = "telegram"; + telegram_configs = [{ + bot_token = "$TELEGRAM_BOT_TOKEN"; + chat_id = -419206986; + parse_mode = "HTML"; + }]; + } + ]; + }; + }; + + alertmanagers = [{ + scheme = "http"; + path_prefix = "/"; + static_configs = [{ + targets = [ + "${config.services.prometheus.alertmanager.listenAddress}:${toString config.services.prometheus.alertmanager.port}" + ]; + }]; + }]; + }; + + nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.prometheus.alertmanager.listenAddress}:${toString config.services.prometheus.alertmanager.port}"; + }; + + oauth2-proxy.nginx.virtualHosts."${host}" = { + allowed_email_domains = [ "srx.digital" ]; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/prometheus/check/apcupsd.nix b/hosts/srxgp00/services/prometheus/check/apcupsd.nix new file mode 100644 index 0000000..a241c6f --- /dev/null +++ b/hosts/srxgp00/services/prometheus/check/apcupsd.nix @@ -0,0 +1,7 @@ +{ config, ... }: +{ + services.prometheus.scrapeConfigs = [{ + job_name = "apcupsd"; + static_configs = [{ targets = [ "srxnas00.vpn.srx.dev:${toString config.services.prometheus.exporters.apcupsd.port}" ]; }]; + }]; +} diff --git a/hosts/srxgp00/services/prometheus/default.nix b/hosts/srxgp00/services/prometheus/default.nix new file mode 100644 index 0000000..4591258 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./prometheus.nix + ./alertmanager.nix + ./rules.nix + ./check/apcupsd.nix + ]; +} diff --git a/hosts/srxgp00/services/prometheus/prometheus.nix b/hosts/srxgp00/services/prometheus/prometheus.nix new file mode 100644 index 0000000..138235b --- /dev/null +++ b/hosts/srxgp00/services/prometheus/prometheus.nix @@ -0,0 +1,93 @@ +{ config, ... }: +let + host = "status.srx.digital"; + hosts = [ + "srxgp00.vpn.srx.dev" + "srxgp01.vpn.srx.dev" + "srxgp02.vpn.srx.dev" + "srxk8s00.vpn.srx.dev" + "srxnas00.vpn.srx.dev" + "srxnas01.vpn.srx.dev" + "copepod.vpn.srx.dev" + "diatome.vpn.srx.dev" + "opd00.vpn.srx.dev" + ]; + openwrt = [ + "srxap01.op.hq.hh.srx.digital" + "srxfw01.op.hq.hh.srx.digital" + ]; +in +{ + services = { + prometheus = { + enable = true; + extraFlags = [ "--storage.tsdb.retention.time=30d" ]; + scrapeConfigs = [ + { + job_name = "prometheus"; + static_configs = [{ + targets = [ + "srxgp00.vpn.srx.dev:${toString config.services.prometheus.port}" + ]; + }]; + } + { + job_name = "node"; + static_configs = [ + { + targets = builtins.concatMap + (name: [ + "${name}:${toString config.services.prometheus.exporters.node.port}" + ]) + hosts; + } + ]; + } + { + job_name = "telegraf"; + static_configs = [{ + targets = builtins.concatMap (name: [ "${name}:9273" ]) hosts; + }]; + } + { + job_name = "openwrt"; + static_configs = [{ + targets = builtins.concatMap (name: [ "${name}:9273" ]) openwrt; + }]; + } + ]; + }; + + nginx.virtualHosts."${host}" = { + forceSSL = true; + enableACME = true; + locations."/".proxyPass = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}"; + }; + + oauth2-proxy.nginx.virtualHosts."${host}" = { + allowed_email_domains = [ "srx.digital" ]; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + + grafana.provision.datasources.settings.datasources = [{ + name = "Prometheus"; + type = "prometheus"; + access = "proxy"; + url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}"; + isDefault = true; + }]; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules.nix b/hosts/srxgp00/services/prometheus/rules.nix new file mode 100644 index 0000000..1e60e53 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules.nix @@ -0,0 +1,37 @@ +{ lib, pkgs, ... }: +let + getRuleFiles = lib.mapAttrs' + ( + f: _: lib.nameValuePair (lib.removeSuffix ".nix" f) (import (./rules + "/${f}")) + ) + (builtins.readDir ./rules); + + formatRules = + rules: + (lib.mapAttrsToList ( + name: opts: { + alert = name; + expr = opts.condition; + for = opts.time or "1m"; + labels = opts.labels or { }; + annotations.description = opts.description; + } + )) + rules; + + writeRuleFile = + name: value: + (pkgs.writeText "prometheus-rules-${name}.yaml" ( + builtins.toJSON { + groups = [ + { + inherit name; + rules = formatRules value; + } + ]; + } + )); +in +{ + services.prometheus.ruleFiles = lib.attrsets.mapAttrsToList writeRuleFile getRuleFiles; +} diff --git a/hosts/srxgp00/services/prometheus/rules/apcupsd.nix b/hosts/srxgp00/services/prometheus/rules/apcupsd.nix new file mode 100644 index 0000000..6e0289b --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/apcupsd.nix @@ -0,0 +1,41 @@ +{ + apcupsd_line_volts = { + condition = "apcupsd_line_volts < 200"; + description = "The UPS line voltage on {{$labels.instance}} dropped below 200V, indicating a potential blackout: {{$value}} V!"; + }; + + apcupsd_battery_volts = { + condition = "apcupsd_battery_volts < 20"; + description = "The UPS battery voltage on {{$labels.instance}} dropped below 20V: {{$value}} V!"; + }; + + apcupsd_battery_volts_nominal = { + condition = "apcupsd_battery_nominal_volts < 20"; + description = "The nominal UPS battery voltage on {{$labels.instance}} dropped below 20V: {{$value}} V!"; + }; + + apcupsd_temperature = { + condition = "apcupsd_internal_temperature_celsius > 40"; + description = "The internal UPS temperature on {{$labels.instance}} exceeds 40°C: {{$value}}°C!"; + }; + + apcupsd_ups_load = { + condition = "apcupsd_ups_load_percent > 80"; + description = "The UPS load on {{$labels.instance}} is higher than 80%: {{$value}}%!"; + }; + + apcupsd_battery_time_left = { + condition = "apcupsd_battery_time_left_seconds < 600"; + description = "Less than 10 minutes of UPS battery charge remaining on {{$labels.instance}}: {{$value}} seconds!"; + }; + + apcupsd_battery_charge = { + condition = "apcupsd_battery_charge_percent < 80"; + description = "Less than 80% battery charge remaining on {{$labels.instance}}: {{$value}}%!"; + }; + + apcupsd_status_not_online = { + condition = ''apcupsd_info{status != "ONLINE"}''; + description = "The UPS status on {{$labels.instance}} is not online: {{$labels.status}}!"; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/dendrite.nix b/hosts/srxgp00/services/prometheus/rules/dendrite.nix new file mode 100644 index 0000000..39436a5 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/dendrite.nix @@ -0,0 +1,6 @@ +{ + dendrite_up = { + condition = "dendrite_up != 1"; + description = "Dendrite on {{$labels.instance}} seems to be down!"; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/dns.nix b/hosts/srxgp00/services/prometheus/rules/dns.nix new file mode 100644 index 0000000..b7f0b79 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/dns.nix @@ -0,0 +1,16 @@ +{ + dns_query = { + condition = "dns_query_result_code != 0"; + description = "{{$labels.domain}} : could retrieve A record {{$labels.instance}} from server {{$labels.server}}: {{$labels.result}}!"; + }; + + dns_secure_query = { + condition = "secure_dns_state != 0"; + description = "{{$labels.domain}} : could retrieve A record {{$labels.instance}} from server {{$labels.server}}: {{$labels.result}} for protocol {{$labels.protocol}}!"; + }; + + dnssec_zone_days_left = { + condition = "dnssec_zone_record_resolves == 1 and dnssec_zone_record_days_left <= 10"; + description = "{{$labels.domain}} : could retrieve A record {{$labels.instance}} from server {{$labels.server}}: {{$labels.result}} for protocol {{$labels.protocol}}!"; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/encryption.nix b/hosts/srxgp00/services/prometheus/rules/encryption.nix new file mode 100644 index 0000000..4ecb677 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/encryption.nix @@ -0,0 +1,8 @@ +{ + # cert_expiry = { + # # condition = "x509_cert_expiry < 7*24*3600"; + # # description = "{{$labels.instance}}: The TLS certificate from {{$labels.source}} will expire in less than 7 days: {{$value}}s"; + # condition = ''x509_cert_expiry{issuer_common_name="R3"} < ${toString (60 * 60 * 24 * 5)}''; + # description = "{{ $labels.san }} does expire in less than 5 days"; + # }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/forgejo.nix b/hosts/srxgp00/services/prometheus/rules/forgejo.nix new file mode 100644 index 0000000..2ef725a --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/forgejo.nix @@ -0,0 +1,6 @@ +{ + # forgejo_http_500 = { + # condition = ''rate(promhttp_metric_handler_requests_total{job="forgejo", code="500"}[5m]) > 3''; + # description = "{{$labels.instance}}: forgejo instances error rate went up: {{$value}} errors in 5 minutes"; + # }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/harddisk.nix b/hosts/srxgp00/services/prometheus/rules/harddisk.nix new file mode 100644 index 0000000..ae23393 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/harddisk.nix @@ -0,0 +1,26 @@ +{ + # smart_errors = { + # condition = ''smart_device_health_ok{enabled!="Disabled"} != 1''; + # description = "{{$labels.instance}}: S.M.A.R.T reports: {{$labels.device}} ({{$labels.model}}) has errors."; + # }; + + mdraid_not_active = { + condition = ''node_md_state{state="active"} != 1''; + description = "{{$labels.instance}} with device {{$labels.device}} is in {{$labels.state}}."; + }; + + mdraid_is_recovering = { + condition = ''node_md_state{state="recovering"} == 1''; + description = "{{$labels.instance}} with device {{$labels.device}} is in {{$labels.state}}."; + }; + + mdraid_disks_down = { + condition = "mdstat_DisksDown != 0"; + description = "{{$labels.instance}} with device {{$labels.device}} is in {{$labels.state}}."; + }; + + mdraid_disks_faild = { + condition = "mdstat_DisksFailed != 0"; + description = "{{$labels.instance}} with device {{$labels.device}} is in {{$labels.state}}."; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/http.nix b/hosts/srxgp00/services/prometheus/rules/http.nix new file mode 100644 index 0000000..a2f57d2 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/http.nix @@ -0,0 +1,16 @@ +{ + http = { + condition = "http_response_result_code != 0"; + description = "{{$labels.server}} : http request failed from {{$labels.instance}}: {{$labels.result}}!"; + }; + + # http_not_ok = { + # condition = "0 * (http_response_http_response_code != 200) + 1"; + # description = "{{ $labels.exported_server }} does not return Ok for more than 5 minutes"; + # }; + + # http_match_failed = { + # condition = "http_response_response_string_match == 0"; + # description = "{{$labels.server}} : http body not as expected; status code: {{$labels.status_code}}!"; + # }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/instance.nix b/hosts/srxgp00/services/prometheus/rules/instance.nix new file mode 100644 index 0000000..894637a --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/instance.nix @@ -0,0 +1,17 @@ +{ + instance_down = { + condition = "up == 0"; + time = "5m"; + description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."; + }; + + instance_reboot = { + condition = "system_uptime < 300"; + description = "{{$labels.host}} just rebooted."; + }; + + instance_uptime = { + condition = "system_uptime > 2592000"; + description = "{{$labels.host}} has been up for more than 30 days."; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/mail.nix b/hosts/srxgp00/services/prometheus/rules/mail.nix new file mode 100644 index 0000000..e09efb7 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/mail.nix @@ -0,0 +1,11 @@ +{ + postfix_queue_length = { + condition = "avg_over_time(postfix_queue_length[1h]) > 10"; + description = "{{$labels.instance}}: postfix mail queue has undelivered {{$value}} items"; + }; + + # https://doc.dovecot.org/configuration_manual/stats/old_statistics/ + # dovecot_up + # dovecot_user_auth_failures + # dovecot_user_auth_db_tempfails +} diff --git a/hosts/srxgp00/services/prometheus/rules/memory.nix b/hosts/srxgp00/services/prometheus/rules/memory.nix new file mode 100644 index 0000000..c16ef7c --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/memory.nix @@ -0,0 +1,18 @@ +{ + memory_under_pressure = { + condition = "rate(node_vmstat_pgmajfault[1m]) > 1000"; + description = "{{$labels.instance}}: The node is under heavy memory pressure. High rate of major page faults: {{$value}}"; + }; + + ram_using_90percent = { + condition = "mem_buffered + mem_free + mem_cached < mem_total * 0.1"; + time = "1h"; + description = "{{$labels.host}} is using at least 90% of its RAM for at least 1 hour."; + }; + + swap_using_30percent = { + condition = "mem_swap_total - (mem_swap_cached + mem_swap_free) > mem_swap_total * 0.3"; + time = "30m"; + description = "{{$labels.host}} is using 30% of its swap space for at least 30 minutes."; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/network.nix b/hosts/srxgp00/services/prometheus/rules/network.nix new file mode 100644 index 0000000..f76e87b --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/network.nix @@ -0,0 +1,17 @@ +{ + ## ssh: connect to host srxgp00.srx.digital port 22: Connection refused + # connection_failed = { + # condition = "net_response_result_code != 0"; + # description = "{{$labels.server}}: connection to {{$labels.port}}({{$labels.protocol}}) failed from {{$labels.instance}}"; + # }; + + # ping = { + # condition = "ping_result_code != 0"; + # description = "{{$labels.url}}: ping from {{$labels.instance}} has failed!"; + # }; + + # ping_high_latency = { + # condition = "ping_average_response_ms > 5000"; + # description = "{{$labels.instance}}: ping probe from {{$labels.source}} is encountering high latency!"; + # }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/nix.nix b/hosts/srxgp00/services/prometheus/rules/nix.nix new file mode 100644 index 0000000..bb070b3 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/nix.nix @@ -0,0 +1,7 @@ +{ + # nixpkgs_out_of_date = { + # condition = ''(time() - flake_input_last_modified{input="nixpkgs"}) / (60 * 60 * 24) > 7''; + # time = "1h"; + # description = "{{$labels.host}} cannot reach nfs export [{{$labels.server}}]:{{$labels.path}}"; + # }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/prometheus.nix b/hosts/srxgp00/services/prometheus/rules/prometheus.nix new file mode 100644 index 0000000..db3f7ff --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/prometheus.nix @@ -0,0 +1,38 @@ +{ + prometheus_wal_corruption = { + condition = ''prometheus_tsdb_wal_corruptions_total > 1''; + description = "Prometheus TSDB database has a corrupt Write-Ahead Log (WAL) of {{ $value }}."; + }; + + prometheus_too_many_restarts = { + condition = ''changes(process_start_time_seconds{job=~"prometheus|pushgateway|alertmanager|telegraf"}[15m]) > 2''; + description = "Prometheus has restarted more than twice in the last 15 minutes. It might be crashlooping."; + }; + + prometheus_not_connected_to_alertmanager = { + condition = "prometheus_notifications_alertmanagers_discovered < 1"; + description = "Prometheus cannot connect the alertmanager VALUE = {{ $value }} LABELS = {{ $labels }}"; + }; + + prometheus_rule_evaluation_failures = { + condition = "increase(prometheus_rule_evaluation_failures_total[3m]) > 0"; + description = + "Prometheus encountered {{ $value }} rule evaluation failures, leading to potentially ignored alerts. VALUE = {{ $value }} LABELS = {{ $labels }}"; + }; + + prometheus_template_expansion_failures = { + condition = "increase(prometheus_template_text_expansion_failures_total[3m]) > 0"; + time = "0m"; + description = "Prometheus encountered {{ $value }} template text expansion failures VALUE = {{ $value }} LABELS = {{ $labels }}"; + }; + + prometheus_alertmanager_config_not_synced = { + condition = ''count(count_values("config_hash", alertmanager_config_hash)) > 1''; + description = "Configurations of AlertManager cluster instances are out of sync."; + }; + + # prometheus_alerts_silences_changed = { + # condition = ''abs(delta(alertmanager_silences{state="active"}[1h])) >= 1''; + # description = "alertmanager: number of active silences has changed: {{$value}}"; + # }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/services.nix b/hosts/srxgp00/services/prometheus/rules/services.nix new file mode 100644 index 0000000..9754cc4 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/services.nix @@ -0,0 +1,22 @@ +{ + systemd_service_failed = { + condition = ''systemd_units_active_code{name!~"nixpkgs-update-.*.service"} == 3''; + description = "{{$labels.host}} failed to (re)start service {{$labels.name}}."; + }; + + service_not_running = { + condition = ''systemd_units_active_code{name=~"teamspeak3-server.service|tt-rss.service", sub!="running"}''; + description = "{{$labels.host}} should have a running {{$labels.name}}."; + }; + + telegraf_down = { + condition = ''min(up{job=~"telegraf"}) by (source, job, instance, org) == 0''; + time = "3m"; + description = "{{$labels.instance}}: {{$labels.job}} telegraf exporter from {{$labels.source}} is down."; + }; + + oom_kills = { + condition = "increase(kernel_vmstat_oom_kill[5m]) > 0"; + description = "{{$labels.instance}}: OOM kill detected"; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/storage.nix b/hosts/srxgp00/services/prometheus/rules/storage.nix new file mode 100644 index 0000000..48d5c5a --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/storage.nix @@ -0,0 +1,60 @@ +{ + filesystem_device_error = { + condition = ''node_filesystem_device_error{fstype!="tmpfs",fstype!="ramfs",device_error!="permission denied"} != 0''; + time = "5m"; + description = "{{ $labels.instance }} with device {{ $labels.device }} of filesystem type {{ $labels.fstype }} has an error for more than 5 minutes."; + }; + + filesystem_full_80percent = { + condition = ''disk_used_percent{mode!="ro", path!="/boot"} >= 80''; + time = "10m"; + description = "{{$labels.instance}} device {{$labels.device}} on {{$labels.path}} got less than 20% space left on its filesystem."; + }; + + filesystem_inodes_full = { + condition = "disk_inodes_free / disk_inodes_total < 0.10"; + time = "10m"; + description = "{{$labels.instance}} device {{$labels.device}} on {{$labels.path}} got less than 10% inodes left on its filesystem."; + }; + + filesystem_tmpfs_root_full = { + condition = ''node_filesystem_free_bytes{fstype="tmpfs",mountpoint="/"} <= 128000000''; + time = "10m"; + description = "{{$labels.host}}: {{$labels.name}} only 128MB left on / tmpfs filesystem."; + }; + + unusual_disk_read_latency = { + condition = "rate(diskio_read_time[1m]) / rate(diskio_reads[1m]) > 0.1 and rate(diskio_reads[1m]) > 0"; + description = '' + {{$labels.instance}}: Disk latency is growing (read operations > 100ms) + ''; + }; + + unusual_disk_write_latency = { + condition = "rate(diskio_write_time[1m]) / rate(diskio_write[1m]) > 0.1 and rate(diskio_write[1m]) > 0"; + description = '' + {{$labels.instance}}: Disk latency is growing (write operations > 100ms) + ''; + }; + + ext4_errors = { + condition = "ext4_errors_value > 0"; + description = "{{$labels.instance}}: ext4 has reported {{$value}} I/O errors: check /sys/fs/ext4/*/errors_count"; + }; + + zfs_zpool_errors = { + condition = "zpool_status_errors > 0"; + description = "{{$labels.instance}} reports: zpool {{$labels.name}} has {{$value}} errors"; + }; + + zfs_errors = { + condition = "zfs_arcstats_l2_io_error + zfs_dmu_tx_error + zfs_arcstats_l2_writes_error > 0"; + description = "{{$labels.instance}} reports: {{$value}} ZFS IO errors."; + }; + + nfs_export_not_present = { + condition = "nfs_export_present == 0"; + time = "1h"; + description = "{{$labels.host}} cannot reach nfs export [{{$labels.server}}]:{{$labels.path}}"; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/tasks.nix b/hosts/srxgp00/services/prometheus/rules/tasks.nix new file mode 100644 index 0000000..1e2678a --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/tasks.nix @@ -0,0 +1,11 @@ +{ + daily_task_not_run = { + condition = ''time() - task_last_run{state="ok",frequency="daily"} > (24 + 6) * 60 * 60''; + description = "{{$labels.host}}: {{$labels.name}} was not run in the last 24h"; + }; + + daily_task_failed = { + condition = ''task_last_run{state="fail"}''; + description = "{{$labels.host}}: {{$labels.name}} failed to run"; + }; +} diff --git a/hosts/srxgp00/services/prometheus/rules/workload.nix b/hosts/srxgp00/services/prometheus/rules/workload.nix new file mode 100644 index 0000000..7f119e1 --- /dev/null +++ b/hosts/srxgp00/services/prometheus/rules/workload.nix @@ -0,0 +1,7 @@ +{ + load15 = { + condition = "system_load15 / system_n_cpus >= 2.0"; + time = "10m"; + description = "{{$labels.host}} is running with load15 > 1 for at least 5 minutes: {{$value}}"; + }; +} diff --git a/hosts/srxgp00/services/restic/default.nix b/hosts/srxgp00/services/restic/default.nix new file mode 100644 index 0000000..ea58877 --- /dev/null +++ b/hosts/srxgp00/services/restic/default.nix @@ -0,0 +1,31 @@ +{ config, pkgs, ... }: +{ + age.secrets = { + resticRepoKey.file = ./repo_key.age; + resticRepoSsh.file = ./repo_ssh.age; + }; + + environment.systemPackages = with pkgs; [ restic ]; + + services.restic.backups.base = { + paths = [ "/var/lib" "/var/backup" ]; + exclude = [ "/var/lib/prometheus2" ]; + repository = "sftp:u388681@u388681.your-storagebox.de:/home"; + passwordFile = config.age.secrets.resticRepoKey.path; + extraOptions = [ "sftp.command='ssh -p 23 -i /run/agenix/resticRepoSsh u388681@u388681.your-storagebox.de -s sftp'" ]; + initialize = true; + checkOpts = [ "--with-cache" ]; + timerConfig.OnCalendar = "04:00"; + pruneOpts = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + "--keep-yearly 1" + ]; + }; + + home-manager.users.root.home.sessionVariables = { + RESTIC_PASSWORD_FILE = config.age.secrets.resticRepoKey.path; + RESTIC_REPOSITORY = config.services.restic.backups.base.repository; + }; +} diff --git a/hosts/srxgp00/services/restic/repo_key.age b/hosts/srxgp00/services/restic/repo_key.age new file mode 100644 index 0000000..c175b7f --- /dev/null +++ b/hosts/srxgp00/services/restic/repo_key.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw 7D0to1lD5NYopXp6MRwGP6GZWEjWaeAmV/nBba7OQQA +5IV3RHhr9e/rxSEedOqcC1WfQkdbfrKT1wgZ/ymac5A +-> ssh-ed25519 JzjriQ 2bnS1m0OzNYgOucjqFZtW8ocC+UTkJSGZCpTAWyANCY +tGZ0KxDH8k7urTXxlb9LFMgtm7gvUrEqIdvw7AQWigo +-> ssh-rsa 6hPx7A +RPYNdYz6UOvv8HbT3VXOqGpp7z2kJ3VSEBQIA/oJjZgO/PyI7fkzu95lua0pVit+ +aidXMhA+q3vcFCmoWB/aFmn2T7dlqOO+AkdUFZPP7Z06LxgDbCJIPmX8g9b4NYHE +fWfwdolq05Rrm7qrAFc8+anAvk30+2F2I3f7usXvDCYm0O/tAzgBcui12rm3nO+J +SXZ9t6TL+0svgN2gFDxjzmeZvro3LeUL7n1y9dXbj0rIi8g/7ppXy9kUVJEfDuZh +8muyRTKXNHb53AD/Z+NIN9kCj/aWEyy9IcxEvGGYWNQ+R62dRBSYo1hNYZ/7Rv02 +0A5SFywjwh61kTEETmvYfzEJdByT3FgdJnGIG30YRlwO95DSiY0iRMtGPBMYaTms +mM3QlWqLKOFfYwPibm36kf1JvrvdV2nh2Fr+mV5lw1R0sVj2Ak9RzdGXWEkmhSzM +Mjw1RRmZBhC9a3MKM661xe+bWEvrvbL9ycRp0o5lcS1CWDSLjzo3syme8fkLBjU/ +L+Pb6GOKA2kNsIlDDC4w32g5oSFCfyfcbCfSJ4+BYg6zFm0ZFjbZLZTZ+I3jOmrr +2uMWzvgxjWJtr2eYC9eE0PTC5z9AzHUkf+aRcHT2y7QlJMY6/1aiC5qbR1sto7+Z +9tndCYJiiZuUP2GxDqz0qLvd0AwLzh+ywn+Atm1hvp0 +-> ssh-ed25519 Dfencg Uvz/a9lKs8vo6gYow1hXZaJ6GqekZgoWWJ6dDyrmEC0 +fJN3p/QyQp6UjmNYaiAsW4GasMwGo3JLb2zTxCgqVbs +--- 6Pmav0/SMX4SmlTO/yLcScfVSHwfLLnxki0vjI8N8jo +5Jԇ8yÌSܟz Q4GLkر0'x $ \ No newline at end of file diff --git a/hosts/srxgp00/services/restic/repo_ssh.age b/hosts/srxgp00/services/restic/repo_ssh.age new file mode 100644 index 0000000000000000000000000000000000000000..48f90aa9384f9a1d14be880b31ff7da9b9f396cd GIT binary patch literal 1563 zcmZ9L`Lo;v0f3P~s_E1jVECm)eS#u3K9cNiHXE^MvPm|3WwY7M=|h`)lRc76cC*=d zKs&>;RAe0Gk`^sUppqFOEDI5TTjhPh$B zT4F1bqYHIn&J-b!spaE#42Y?oI!0QfgR;V5BdJE8<~qXVm8)^NCvSCvDG?po)*RWLb1oE7yLAEhTNrIQC@xmjNxtqzEusgIO**4c2FbA6sLN3K&fII+@~A5Y ztT`FTP}C)(KAw()Tv*a7+AwER<9fA_bTQI~I!p`<1SPXctDU%MXs3SIN@>*BV5y~t zol3@du2NF^xDV45(o3cVbEG?cCmiHxwwiA=n<)?zxU31?KoRCROOsaJYBbIX6HUYJ zOa8#0A{|pH8v0cATuUv+h|ObNWzGkpNzvUz0yMQ0Z6?Q#i*M7O3&% z+*Ffgic(EmDneP4^q@)yhS{W-w2TS?&UtwZOi8K;N=DlZ;4$4U!FXFNd6Ohcry2@d zs#Bkik}44wf*J;Kh9a|~Hmh?a#vz2%o<$;{$Yr;R;x)aU5FS3p!cIK_C9Ftu)&5ZB z=XyP9YJnS3VIJjuyaO>KZs?k$5pEU8dm>5@)Au; ziAElgg8@mfb!BhDGQ${>5${~Uw@)ZeYhbbf0$Zin{n=(7qMn*v& zssJUZ;<@N7T&w#f(7bPl(ud;_-{H{X0Lp^ewW##Jiif{Aou2 z_}g2LUgN)XbMBJkqWnm(z`cL*>gSjD-Sfh_pQbk-tsUQ{ZTR{x@AtiDJ4R*q@YIj4 zK6vmWE5^Db^8I&R_2Q6iZD8wVrm-_M*atH=0TR~vu4V(SNg2dq8*^1I#)58Qd0 zR4z2h+x`OVKlJ=gggTSE4tV4Au9trHoA>gU+&){SJgU6)#7%2&h?~Dy55Did!?VsQ z=k9y{{=j%e0na{l<(liV_{Ftr9zn1Cfq2muz%2)UzwCa|y?3d<;f=ju<2moSzpcEm zZs*(ftJm+_v1XG_JUi7d+keYS_wtSIiS3o|44@CZ{p-b7oYtN*7k~1}%O1St`>%sv z+7YPUtDlG7eX9Hq_uiYb8;iS6s?!4-Z+vIf=^O5{AKv}i&f49_Hfd{~_|NB#ooPRc z{G8Zc_~x(Ho-{Ts@8f^?>8CFk9Qp2@OWBbPuf6r=@_7G;_CB`q6!r{x)cx>J;#UqI zTEG1(7p^+oyI{-r*1yNN<1@SQr}wZQuYKx)2hXlP$$a_Hzc!yOUX?7bKC$=p{{dFI BN=^U( literal 0 HcmV?d00001 diff --git a/hosts/srxgp00/services/vaultwarden/default.nix b/hosts/srxgp00/services/vaultwarden/default.nix new file mode 100644 index 0000000..070fb66 --- /dev/null +++ b/hosts/srxgp00/services/vaultwarden/default.nix @@ -0,0 +1,120 @@ +{ config, ... }: +let + host = "vault.srx.digital"; + owner = "vaultwarden"; +in +{ + age.secrets.vaultwarden = { + file = ./secrets.age; + inherit owner; + group = owner; + }; + + environment.etc = { + "fail2ban/filter.d/vaultwarden.conf".text = '' + [INCLUDES] + before = common.conf + + [Definition] + failregex = ^.*Username or password is incorrect\. Try again\. IP: \. Username:.*$ + ignoreregex = + journalmatch = _SYSTEMD_UNIT=vaultwarden.service + ''; + + "fail2ban/filter.d/vaultwarden-admin.conf".text = '' + [INCLUDES] + before = common.conf + + [Definition] + failregex = ^.*Invalid admin token\. IP: .*$ + ignoreregex = + journalmatch = _SYSTEMD_UNIT=vaultwarden.service + ''; + }; + + services = { + vaultwarden = { + enable = true; + + environmentFile = config.age.secrets.vaultwarden.path; + dbBackend = "postgresql"; + + config = { + DOMAIN = "https://${host}"; + SIGNUPS_ALLOWED = false; + + DATABASE_URL = "postgresql://@/${owner}"; + + SMTP_HOST = "mail.srx.digital"; + SMTP_FROM = "no-reply@srx.digital"; + SMTP_USERNAME = "no-reply@srx.digital"; + SMTP_PORT = 465; + SMTP_SSL = true; + SMTP_SECURITY = "force_tls"; + + ROCKET_ADDRESS = "::1"; + ROCKET_PORT = 8812; + + ENABLE_WEBSOCKET = true; + }; + }; + + postgresql = { + enable = true; + ensureDatabases = [ owner ]; + + ensureUsers = [ + { + name = owner; + ensureDBOwnership = true; + } + ]; + }; + + postgresqlBackup.databases = [ owner ]; + + nginx.virtualHosts."${host}" = { + enableACME = true; + forceSSL = true; + + locations."/".proxyPass = "http://[::1]:${toString config.services.vaultwarden.config.ROCKET_PORT}/"; + + locations."/notifications/hub" = { + proxyPass = "http://[::1]:${toString config.services.vaultwarden.config.ROCKET_PORT}/"; + proxyWebsockets = true; + }; + }; + + fail2ban.jails = { + vaultwarden = '' + enabled = true + filter = vaultwarden + port = 80,443,8000 + maxretry = 5 + ''; + + vaultwarden-admin = '' + enabled = true + port = 80,443 + filter = vaultwarden-admin + maxretry = 3 + bantime = 14400 + findtime = 14400 + ''; + }; + + telegraf.extraConfig.inputs = { + x509_cert = [{ + sources = [ "https://${host}:443" ]; + tags.host = host; + interval = "10m"; + }]; + + http_response = [{ + urls = [ "https://${host}" ]; + tags.host = host; + interval = "10m"; + }]; + }; + }; +} diff --git a/hosts/srxgp00/services/vaultwarden/secrets.age b/hosts/srxgp00/services/vaultwarden/secrets.age new file mode 100644 index 0000000..92e3023 --- /dev/null +++ b/hosts/srxgp00/services/vaultwarden/secrets.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw qZBccj3l3NXQaKEGeRnn58SvCVdSCoF67tr7TGFvM0Y +H41HjuG8QmApI3qCPzOZB+zqv4PrgAFrX9qu3NuiB/o +-> ssh-ed25519 JzjriQ Gzpr05qnZskY5Vi0p/6RNCKo7EimD+18j2+JNDfBujw +kSsEfpmcCn18N20nJnHDid65DOMojxbJO9RDJNenT/4 +-> ssh-rsa 6hPx7A +ZY88w1W0jRbEMHqUv9Pot7mIXD60z8dL0RfFB588ahbnniBe+0dBUpphMAhGgkY8 +Rpk3ZgM679AOiNSmW7Umv0tgN1YmvuF1fS2OmPb/yQTobLPoVRDQYtn620SclUx8 +7VCNUN7IgiwwzUggTzHedUryEw9yROLFBmPIqB5I5OZWhv3Qw9urVEXgI6WkkFm6 +PkpRwjjiPtgOV2P0GMOK+s1qqne7/IYwhpIGAit1oqTSfP6+BFx1Gmv9a9QvB7tW +AB0cZBRVVmMDZ9e4QDeCvOJgNG3p9G2NIMNOSbMHwaqYbEd52Nu+//YednvuPGU+ +UF/ryHivOQO1moLlsPBD1vEIy/oVYDQPfzKRCHToig/iqXnQnwn3aEE0qK7DJpun +bPVcYUfBzzKKBE00gV27f11Z0njj8Ut94JyaARQkp0LSYz7Wx2YlcUIIWUEMrBHr +RLVEO0mavy983EpxGqZvhm/9f3lsHiJgA9osGOvRMq/kwaKn+XwrFpDLTGJYjQRZ +N3Z0ujxvb2NxhwWGhWOthCi7zRtpMcI5fvivMsvaN3++9jffj021qODoVcGU4z1y +mmM/SyR+KLL7sUzyGpwq/ESQdfjyIpCDgoqi32N2FecvrXC6+1Hxm5DBlsxNMlw9 +9KQu7/V6HbosBY7BkzaqFIiSDJGwi2wsfxL0B4IT8Ac +-> ssh-ed25519 Dfencg mbnAJcIZWV9jB7rsKj/jmWcvXcs+mbpfyVTIXv4VD0k +gg1qVUpCg2lRX3TTty3lsP4TLp81i4MzQNOU1BR3VCA +--- VPEeIrf8pMfnTs65lDhxkd/3b5yKX5DMeoxN2T7PrEY + EҸk,/M&@}]@Z%5duSm3^ų~.PQRQ5\ڶ'Fl:M? QƜ*'WmBnxd~ ))A&!7^ST3J +[{ZPiv_*@SRFu~RO;bW(zE@VnmJ^}*dq#9&ZYV׫G,8cX+9E2Yt:\1b:8TϤBKrwFڇ& E9kUͼƽ%bu,(>lp)] \ No newline at end of file diff --git a/hosts/srxgp00/services/wireguard/default.nix b/hosts/srxgp00/services/wireguard/default.nix new file mode 100644 index 0000000..a80dfa3 --- /dev/null +++ b/hosts/srxgp00/services/wireguard/default.nix @@ -0,0 +1,164 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [ + { + wireguardPeerConfig = { + # srxnas01.vpn.srx.dev + PublicKey = "vXNyMPTm2Gwmu5xwR4NA6neuH849YdTtIzQ03L1IZVY="; + AllowedIPs = [ "10.80.0.2/32" "10.50.0.0/23" ]; + }; + } + { + wireguardPeerConfig = { + # srxws00.vpn.srx.dev + PublicKey = "vi/DohCorqMv8lR8TwI27YM6F9uRggD9T2E5PdbiCBs="; + AllowedIPs = [ "10.80.0.3/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxmc00.vpn.srx.dev + PublicKey = "bxA6bVjEn6UmOizdmujDPe2DxU2iSVJus+FQPdlKJGI="; + AllowedIPs = [ "10.80.0.14/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxnas00.vpn.srx.dev + PublicKey = "kiEzfTU5pWSy7r/RuRXE8/4rnvctebVq1mZ+8BfLzQk="; + AllowedIPs = [ "10.80.0.4/32" "192.168.178.0/24" ]; + }; + } + { + wireguardPeerConfig = { + # srxgp01.vpn.srx.dev + PublicKey = "FFErzX2/KEv/k5FNrp9w7j8+JKz5P+D8WqunoksHxg8="; + AllowedIPs = [ "10.80.0.5/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxgp02.vpn.srx.dev + PublicKey = "WYJaYVzyJTbrOKz3dW8PKl3c6vRcJQx0/AE6LGWRfl4="; + AllowedIPs = [ "10.80.0.6/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxk8s00.vpn.srx.dev + PublicKey = "ukZbSy6XDELBg2jGjnwINr73G7OyT0tmAkVuTKs7zjc="; + AllowedIPs = [ "10.80.0.7/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxws01.vpn.srx.dev + PublicKey = "UszZ79FXBcXllXmRC9/LKw+Qc+fNHvZnCA9+DYdXKx0="; + AllowedIPs = [ "10.80.0.8/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxtab00.vpn.srx.dev + PublicKey = "pYYc6p3KNHMtTPXojK8urO3MURnaG9/wyEg7hOUDUGM="; + AllowedIPs = [ "10.80.0.9/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxfdm00.vpn.srx.dev + PublicKey = "eJ6OhRhTwSyxdT466SQbrjAIMFSZ8C1yVFMEeDxHxSw="; + AllowedIPs = [ "10.80.0.12/32" ]; + }; + } + { + wireguardPeerConfig = { + # srxnb00.srx.digital + PublicKey = "3nWyVTUqkH/6b45FmRV7DKy13wp9g6vgxqL28GFZpFA="; + AllowedIPs = [ "10.80.0.100/32" ]; + }; + } + { + wireguardPeerConfig = { + # copepod.curious.bio + PublicKey = "WTAG/4iEQO1S5H6uwQB2z+r9q8nMkVILILrSnqu23zc="; + AllowedIPs = [ "10.80.0.10/32" ]; + }; + } + { + wireguardPeerConfig = { + # diatome.curious.bio + PublicKey = "lyz3nEnjCMi2fX0HAstSUbfOkXYn6HNgkYz0I6w3r3w="; + AllowedIPs = [ "10.80.0.50/32" "10.10.0.0/24" ]; + }; + } + { + wireguardPeerConfig = { + # opd00.octopod.de + PublicKey = "D3/wnVy1BUgNvSwkhPMoaZIbxycUpjVHByEmlznZj2U="; + AllowedIPs = [ "10.80.0.66/32" ]; + }; + } + ]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.1/24" ]; + routes = [ + { + routeConfig = { + Gateway = "10.80.0.2"; + Destination = "10.50.0.0/23"; + }; + } + { + routeConfig = { + Gateway = "10.80.0.4"; + Destination = "192.168.178.0/24"; + }; + } + { + routeConfig = { + Gateway = "10.80.0.50"; + Destination = "10.10.0.0/24"; + }; + } + ]; + + networkConfig = { + IPMasquerade = "ipv4"; + IPForward = true; + }; + }; + }; + + networking = { + nat = { + enable = true; + externalInterface = "enp9s0"; + internalInterfaces = [ "vpn_srx" ]; + }; + + firewall = { + allowedUDPPorts = [ 51820 ]; + trustedInterfaces = [ "vpn_srx" ]; + }; + }; +} diff --git a/hosts/srxgp00/storage.nix b/hosts/srxgp00/storage.nix new file mode 100644 index 0000000..3ad0d46 --- /dev/null +++ b/hosts/srxgp00/storage.nix @@ -0,0 +1,140 @@ +{ lib, ... }: +let + pool = "rpool"; + disks = [ "/dev/nvme0n1" "/dev/nvme1n1" ]; +in +{ + disko.devices = { + disk = lib.genAttrs disks (device: { + type = "disk"; + inherit device; + content = { + type = "gpt"; + partitions = { + BOOT = { + size = "1M"; + type = "EF02"; + }; + ESP = { + size = "512M"; + type = "EF00"; + content = { + name = "boot"; + type = "mdraid"; + }; + }; + SYSTEM = { + size = "100%"; + content = { + inherit pool; + type = "zfs"; + }; + }; + }; + }; + }); + zpool = { + ${pool} = { + type = "zpool"; + mode = "mirror"; + options = { + ashift = "12"; + autotrim = "on"; + }; + rootFsOptions = { + acltype = "posixacl"; + compression = "zstd"; + normalization = "formD"; + dnodesize = "auto"; + relatime = "on"; + xattr = "sa"; + canmount = "off"; + mountpoint = "none"; + "com.sun:auto-snapshot" = "false"; + }; + mountpoint = null; + datasets = + let + default = mountpoint: { + type = "zfs_fs"; + inherit mountpoint; + mountOptions = [ "X-mount.mkdir" ]; + }; + can_not_mount = { + type = "zfs_fs"; + options = { + canmount = lib.mkForce "off"; + mountpoint = lib.mkForce "none"; + }; + mountpoint = lib.mkForce null; + mountOptions = lib.mkForce [ ]; + }; + in + { + "reserved" = { + type = "zfs_fs"; + options = { + refreservation = "10GiB"; + canmount = lib.mkForce "off"; + mountpoint = lib.mkForce "none"; + }; + mountpoint = lib.mkForce null; + }; + "nixos" = can_not_mount; + "nixos/etc" = default "/etc"; + "nixos/nix" = default "/nix"; + "user" = can_not_mount; + "user/root" = default "/root"; + "user/home" = { + type = "zfs_fs"; + options."com.sun:auto-snapshot" = "true"; + mountpoint = "/home"; + mountOptions = [ "X-mount.mkdir" ]; + }; + "data" = can_not_mount; + "data/log" = default "/var/log"; + "data/lib" = { + type = "zfs_fs"; + options."com.sun:auto-snapshot" = "true"; + mountpoint = "/var/lib"; + mountOptions = [ "X-mount.mkdir" ]; + }; + "data/cache" = default "/var/cache"; + "data/backup" = default "/var/backup"; + }; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=1G" + "mode=755" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=1G" ]; + }; + }; + mdadm = { + boot = { + type = "mdadm"; + level = 1; + metadata = "1.0"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + }; + }; + + virtualisation.containers.storage.settings.storage = { + driver = lib.mkForce "zfs"; + graphroot = "/var/lib/containers/storage"; + runroot = "/run/containers/storage"; + }; +} diff --git a/hosts/srxgp00/vpn_srx.age b/hosts/srxgp00/vpn_srx.age new file mode 100644 index 0000000000000000000000000000000000000000..b0d8e9a1363f60c848441366a5845bcee865dc0f GIT binary patch literal 1189 zcmZA0x$5Ku0D$qe+!QwJ156_pyn2sKyVzU zHW^oQ&9u>NDBM=n)`tCJ(c*c^XILTGPz`$%J9THiHnIvW^Jl%2E4!5pewVh>A+gI3fp!Zl$0k91EH24 zU*J+6&ukx|JTU6wtupN{Jf5dYG`5lgLRD+VPIik^$QfXmQ~I@_&6<9xwVk^m5_KkN zU^TNIhLcJZxJVLRQV+oNDEPw?cjZ+LYP-UOZO#^QE8V*oWziQmR{%3(cV1JR z*d>;bW1?#qx5AJYc_1ZOBdrjYB@X_|Wa6Z8qF!6vDzXQD==HdqELsCP$va~>U!Cx7 zI_SzdK@U?*nXp40CHQ#IdV^<+X;PArtvf07lACD2!FAF=^-PO}4IpD17+Vm8Tyei( ztcT~KOo$K*?-3uSqFmozwlra{n8?9sB*=v3g*kXg0ugb*qQZb9M$|evUb;s0)SJ7M+t(l;w_-;pn=?Ok@1>A_iX*K%QsiaFO+=Q+!gS14oWl_bf z)=W(SJiS2Yr4!Cv#$S*rNh>xM@7JO)>@shIV;+I>p{T+s_JN0ohmFgbGE**9f0wsC z8@f{2%s6Ko(QJkMdDN`{>l?#bkOKrP{ ssh-ed25519 jDpDqw WnhWeNKot4zApDkMal8vjIxpmMul39tcmJZF9YJtVj0 +0gwUYEKdSrYO+fq4U70V9W5LugfiLwEzW7bSCPweHsI +-> ssh-ed25519 JzjriQ R1FaxvVeyyqLEPGVdsmaTpWit+QSC5BnS5jqYvPUUkg +6Cwb4mi+EPpk/LzJ7VpApkTD/6MegBjS2rRLtGkzpDU +-> ssh-rsa 6hPx7A +RAXOjZ8LeeFgSdBOS0qD02s68zRcTYWTpulwm10W4eqZB2AbplvZublnG0PNPrYu +lUu2ptHFQq5jfl9YeOZczGcdsuDR82ahrKgtSiAcbvIyswOLxmnE+SVj5TuMIGsE +N8RTGZpT1+ZhdT+QzfiA1BraoaHvND+bRuVpQ6mt6QzZNSsfOSRec2/p88KAGUdR +6nzgqvxvbBZJ9jAz2pmnMSAHJAELgtTMeSdTrpwTJdemUaORXTbOnAFsjMdPoMdV +5x9gRXCk/o+Jl4OBHnVArpRTmEvt719SLMYDqQuYzVbaOGBZ6dcZ1Hzf1K65o4HZ +LMNorjzSkrCTMmtL3jG8fKcyc3rQK6RWA7OJayVcf5fVkoPA/JLuHqjKND/0lMem +bXNEtaeMjfizVFf90f/wzzIdfOkSQW+gzMcSbIlliZZ4mGrgYByfVuUwfR84mAP4 +jThEtSJPc+VujTL9PCHyw8li5TvhdBmPPFfzWUpWCE2lqjtCXBZNtNzFBoy5z/k4 +2i6U19uN1Fi2waKAkYoy07/etMez90Q8k/e3M4AzIHwnP1X1NDWM5AofI8Srr1pX +8+kZbf2c+/zTa5HlfOzew1/c3rSbqeqUwtKNPrPn0ge0TUnRhjauq+3rIgqVPQfU +/Jv9u2hyiJynIbV2kwFHLwpb/rddRYeXR5jH1tz7etA +-> ssh-ed25519 OWgoVA JEXll+XDPdskWuqvYB2i4mtgaj6aI+Ers3I4Q+5Ysmc +qsTvL91fYwCg7WBfe1LIDDc5jZtUkwj2l/PUk6PlXPw +--- 4O0bS87UH3sI7wO4FnsKPnEIvG114VccYplGIRrCSMY +OSMf!YLY6Z!C3̢ +朗Y!o#(*Jc=}{r&V: \ No newline at end of file diff --git a/hosts/srxgp02/default.nix b/hosts/srxgp02/default.nix new file mode 100644 index 0000000..6ec9fea --- /dev/null +++ b/hosts/srxgp02/default.nix @@ -0,0 +1,37 @@ +{ inputs, lib, ... }: +{ + imports = with inputs; [ + self.nixosModules.roles-server + self.nixosModules.services-security-tang + self.nixosModules.custom-dns-knot + ./hardware.nix + ./storage.nix + ./services/wireguard.nix + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxgp02"; + domain = "srx.digital"; + }; + + systemd.network.networks."10-uplink" = { + matchConfig.Name = "ens6"; + networkConfig = { + Address = "2a02:247a:275:9300::1/128"; + DHCP = "ipv4"; + Gateway = "fe80::1"; + IPv6AcceptRA = "no"; + }; + }; + + services.knot.settings.server = { + identity = "ns3.srx.dev"; + listen = lib.mkForce [ + "10.80.0.6@53" + "212.132.77.48@53" + "2a02:247a:275:9300::1@53" + ]; + }; +} diff --git a/hosts/srxgp02/hardware.nix b/hosts/srxgp02/hardware.nix new file mode 100644 index 0000000..c92a05c --- /dev/null +++ b/hosts/srxgp02/hardware.nix @@ -0,0 +1,16 @@ +{ inputs, ... }: +{ + imports = with inputs; [ + self.nixosModules.hardware-cpu-amd + ]; + + boot.initrd = { + availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "virtio_pci" + "virtio_blk" + ]; + kernelModules = [ ]; + }; +} diff --git a/hosts/srxgp02/services/wireguard.nix b/hosts/srxgp02/services/wireguard.nix new file mode 100644 index 0000000..3a8f924 --- /dev/null +++ b/hosts/srxgp02/services/wireguard.nix @@ -0,0 +1,35 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.6/24" ]; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxgp02/storage.nix b/hosts/srxgp02/storage.nix new file mode 100644 index 0000000..7d6465c --- /dev/null +++ b/hosts/srxgp02/storage.nix @@ -0,0 +1,93 @@ +{ lib, ... }: +let + disks = [ "/dev/vda" ]; +in +{ + disko.devices = { + disk = lib.genAttrs disks (device: { + name = lib.last (lib.splitString "/" device); + inherit device; + content = { + type = "gpt"; + partitions = { + BOOT = { + size = "1M"; + type = "EF02"; + }; + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + SYSTEM = { + size = "100%"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/var" = { + mountpoint = "/var"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/etc" = { + mountpoint = "/etc"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/root" = { + mountpoint = "/root"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + }; + }; + }; + }; + }; + }); + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "size=512M" + "mode=755" + "noatime" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=512M" ]; + }; + }; + }; +} diff --git a/hosts/srxgp02/vpn_srx.age b/hosts/srxgp02/vpn_srx.age new file mode 100644 index 0000000..f7b8989 --- /dev/null +++ b/hosts/srxgp02/vpn_srx.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw 7ynUC8MwwumjA2zybiAhqeGcvxOMJ61okSqJaMOe5ms +tzk+xLLRYFeQ3Mjti8UpHPil3DdSqhwzarClsoxfvF0 +-> ssh-ed25519 JzjriQ oLtd6Vmsf1m9odSHk5uq0vW9bmv7BjPnjw/v/NQoGhg ++wmkgZvLkvW6W5GaCHvFuBo4EfxfrEEHO5Prc/9YeQw +-> ssh-rsa 6hPx7A +rI3QyXZF476fOotDKZrpyA/unO6V44THBYnUBhlMMsudwk+FGYkPNMrzg4Yb+PPI +W9BJpT6qv+xEfRdLstwQQlopSX1TB1uEQEh3wsG3cyGKY46wzgPkivWIXTvPJSRh +fi/b5UgAqMjDJ7kyr9/iY1WlkW2t5MpEi52lSG75JehR1H77EJ3nFvW4wh0bVhfv +9zkRuLp0qEpn/lUUu7ZXDeKyA4926ktSEv+osraxdeFf5bgJcjhpxb9Xhawm6tko +q2afnfBGwFhDLgcoJT/nKdRyJPzfVCW5Ly6w6d8wWJ6DO7oYj9uA2DDaht6WSdt7 +5j+J2T3IPuaqiL60ZSjhsLs7xmFqDUIffe3ISjXVHwm/hqw7SwnjIO2AE0ZuPheL +sno093olsaxcB1KqjE69UZjYZTwe6rBzv3Ex+7r5Eon4nyj7zNLM3/+FTHGeJ7wy +5LQeCHvGjL21XV0OIibQpCBzp1+UvWMx1iIonV3ZDeo63fF5wgFruqVTzYlzPZ0Y +X9CRT986o5Slkkbn8R3qLv1NQ43nj2kOAuKmyHQD7KjzFILnaHfEj9SfBJO7gj09 +vln8/i8JJWmtEtGSQsM5w0nUyg1XO+deBogtYwGZuR3cMbTQ3Sx/l7B6/04zG9Eq +p7TbZQroYTiCpN+1sFM+CU5+IH6suTm/V5ceSaA3lms +-> ssh-ed25519 aP/BWw 3iooFYwuEefd1N+jLMQ3sYiQq0XBmX2azY0eXrOFl0Q +ELLsGeEcX5ogjfFWY1701v4Ivtvq/hziRUPHSv6rChE +--- OT8IzDy21tnteI84bMhLrPMmX/hzYZIf/dv8wqYtiBE +O2+0w }Kz@"7 Ve?:?˹WO <!1<B \ No newline at end of file diff --git a/hosts/srxk8s00/default.nix b/hosts/srxk8s00/default.nix new file mode 100644 index 0000000..56724c3 --- /dev/null +++ b/hosts/srxk8s00/default.nix @@ -0,0 +1,29 @@ +{ inputs, ... }: +{ + imports = with inputs; [ + self.nixosModules.roles-server + self.nixosModules.filesystems-zfs + ./hardware.nix + ./storage.nix + ./services/wireguard.nix + ./services/k3s.nix + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxk8s00"; + domain = "srx.digital"; + hostId = "8585b085"; + }; + + systemd.network.networks."10-uplink" = { + matchConfig.Name = "enp1s0"; + networkConfig = { + Address = "2a01:4f8:1c0c:5214::1/64"; + DHCP = "ipv4"; + Gateway = "fe80::1"; + IPv6AcceptRA = "no"; + }; + }; +} diff --git a/hosts/srxk8s00/hardware.nix b/hosts/srxk8s00/hardware.nix new file mode 100644 index 0000000..d03af2c --- /dev/null +++ b/hosts/srxk8s00/hardware.nix @@ -0,0 +1,19 @@ +{ modulesPath, ... }: +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot = { + initrd = { + availableKernelModules = [ + "sr_mod" + "virtio_scsi" + "xhci_pci" + ]; + kernelModules = [ ]; + }; + loader.systemd-boot.enable = true; + }; +} diff --git a/hosts/srxk8s00/services/k3s.nix b/hosts/srxk8s00/services/k3s.nix new file mode 100644 index 0000000..fb28ea2 --- /dev/null +++ b/hosts/srxk8s00/services/k3s.nix @@ -0,0 +1,39 @@ +{ self, lib, config, ... }: +{ + imports = [ self.nixosModules.services-container-k3s ]; + + services.k3s = { + enable = true; + role = "server"; + extraFlags = toString [ + "--tls-san=k8s.vpn.srx.dev" + "--cluster-domain=k8s.vpn.srx.dev" + + "--bind-address=10.80.0.7" + "--advertise-address=10.80.0.7" + "--cluster-cidr=10.42.0.0/16,2001:cafe:42::/56" + "--service-cidr=10.43.0.0/16,2001:cafe:43::/112" + "--node-external-ip=78.46.220.70,2a01:4f8:1c0c:5214::1" + # "--node-external-ip=10.80.0.7,78.46.220.70,2a01:4f8:1c0c:5214::1" + + "--container-runtime-endpoint unix:///run/containerd/containerd.sock" + "--write-kubeconfig-mode 644" + + "--disable traefik" + + "--snapshotter=zfs" + "--node-label storage.os.srx.digital/fs=zfs" + + "--node-label os.srx.digital/release=${config.system.nixos.release}" + "--node-label os.srx.digital/codename=${config.system.nixos.codeName}" + "--node-label os.srx.digital/version=${config.system.nixos.version}" + "--node-label os.srx.digital/kernel=${config.boot.kernelPackages.kernel.version}" + ]; + }; + + virtualisation.containers.storage.settings.storage = { + driver = lib.mkForce "zfs"; + graphroot = "/var/lib/containers/storage"; + runroot = "/run/containers/storage"; + }; +} diff --git a/hosts/srxk8s00/services/wireguard.nix b/hosts/srxk8s00/services/wireguard.nix new file mode 100644 index 0000000..61212b8 --- /dev/null +++ b/hosts/srxk8s00/services/wireguard.nix @@ -0,0 +1,35 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.7/24" ]; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxk8s00/storage.nix b/hosts/srxk8s00/storage.nix new file mode 100644 index 0000000..80ba3d8 --- /dev/null +++ b/hosts/srxk8s00/storage.nix @@ -0,0 +1,122 @@ +{ lib, ... }: +let + disks = [ "/dev/sda" ]; + pool = "rpool"; +in +{ + disko.devices = { + disk = lib.genAttrs disks (device: { + type = "disk"; + inherit device; + content = { + type = "gpt"; + partitions = { + BOOT = { + size = "1M"; + type = "EF02"; + }; + ESP = { + size = "512M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + SYSTEM = { + size = "100%"; + content = { + inherit pool; + type = "zfs"; + }; + }; + }; + }; + }); + zpool = { + ${pool} = { + type = "zpool"; + options = { + ashift = "12"; + autotrim = "on"; + }; + rootFsOptions = { + acltype = "posixacl"; + compression = "zstd"; + normalization = "formD"; + dnodesize = "auto"; + relatime = "on"; + xattr = "sa"; + canmount = "off"; + mountpoint = "none"; + "com.sun:auto-snapshot" = "false"; + }; + mountpoint = null; + datasets = + let + default = mountpoint: { + type = "zfs_fs"; + inherit mountpoint; + mountOptions = [ "X-mount.mkdir" ]; + }; + can_not_mount = { + type = "zfs_fs"; + options = { + canmount = lib.mkForce "off"; + mountpoint = lib.mkForce "none"; + }; + mountpoint = lib.mkForce null; + mountOptions = lib.mkForce [ ]; + }; + in + { + "reserved" = { + type = "zfs_fs"; + options = { + refreservation = "10GiB"; + canmount = lib.mkForce "off"; + mountpoint = lib.mkForce "none"; + }; + mountpoint = lib.mkForce null; + }; + "nixos" = can_not_mount; + "nixos/etc" = default "/etc"; + "nixos/nix" = default "/nix"; + "user" = can_not_mount; + "user/root" = default "/root"; + "user/home" = { + type = "zfs_fs"; + options."com.sun:auto-snapshot" = "true"; + mountpoint = "/home"; + mountOptions = [ "X-mount.mkdir" ]; + }; + "data" = can_not_mount; + "data/log" = default "/var/log"; + "data/lib" = { + type = "zfs_fs"; + options."com.sun:auto-snapshot" = "true"; + mountpoint = "/var/lib"; + mountOptions = [ "X-mount.mkdir" ]; + }; + "data/backup" = default "/var/backup"; + "data/containerd" = default "/var/lib/containerd/io.containerd.snapshotter.v1.zfs"; + }; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=1G" + "mode=755" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=1G" ]; + }; + }; + }; +} diff --git a/hosts/srxk8s00/vpn_srx.age b/hosts/srxk8s00/vpn_srx.age new file mode 100644 index 0000000..f51c104 --- /dev/null +++ b/hosts/srxk8s00/vpn_srx.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw 9YryRmhy0lZrVhxChemltvwGdT4lsuK/RDWMtrNMU3E +S7VLEgSKYjdOuhUbdPQz4ZrqV6z8m5bSBHD0Zmw9PFQ +-> ssh-ed25519 JzjriQ fonWi7/x79+GFQcEks0aL9lN3pO4DE5tUsAPX5SlbT0 +EHdq9DobUfdnPKllFJCsoIDrVowDehX8iOpboLZO39I +-> ssh-rsa 6hPx7A +AcBhB3wNfGw2NnFAUd8Q3YhhJdv3PXGvqtqJiG+YnPz6c4Grh4aEQTDwG1KX746Q +qdMY8Ex5vhPfuuo9Tss3Cx7iaSf+ZpeiP7Y1jVVBdU3p+MQbBkTTrMHA/soE/D1c +7v2k7c4e23sSGOhQhS5dtTlbaGOaOHHxUoTKPUM5BoViPNA2Hg2dKst13jd+OxEN +reWNs9RMIkU9qq2Q3zcil3SYQW1JxWSG49TCd/k54w7cokUy9zbCxBR625RE9Jo6 +1aPdNRPfJG516uyKUFgrpu++4eagnr07UhlbeFzHwxjdldU5dE+9sTFzdCaHQ+Gt +2QXbzV6LXuRaXrkA533B7eJW+Zdh/GIdp56YYHFQiVydeZ2frqBnyz8wBiQhB2Xx +ayoZjUJtLbyzNrJH7Sf1QxA9Wm58DUccZG/cqTbOSTUNOLNWDxgjxvL+lv1eIsKQ +xD+FMKIJp76PWFD/hUaBJTlLyQsHH4QZAH5/lR2LToJ3FpRvsRq/SueW46D7K6fe +sulRIU7+aRv7EnS+q+MBTT9UUwn4YH90bJiLACqXnneqpz7A5vrzSRS6Qz21SijN +LblSstibPzRHD9XsQeKJds7RHX0FJBwxIL8kkF+lz4aaWyKrjo9yIEBM30zgKnop +tfXAfv8gUXarOMRfS0ejEFkZKGqjWmd1ihNVC3V4On4 +-> ssh-ed25519 v+/Ozg q+s4IJMnprnuqLVVJMyqy52e570rSsmA2DL7CJkuMHw +2p4781Rf32IcOVW/Jpw7RwULbo5uOPVI40dkXLvIzoU +--- OaFcaS6xsFWh6frrV9qit8HD/O8WD95KOMPJYAgXydY +gsk~);A~W\Q"ln?:^/C/n\կĖ-.e&T߮6C{&~[it \ No newline at end of file diff --git a/hosts/srxmc00/cifs_nas.age b/hosts/srxmc00/cifs_nas.age new file mode 100644 index 0000000..6d4301c --- /dev/null +++ b/hosts/srxmc00/cifs_nas.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw yIGqiRUQgfQjhMntccdHKN2JVQrXU/PX7h7H+Ir2CH8 +tHODqdTUtQd9NqR1HnmcLVhDEp3GfZyyOL/6+DYpUOE +-> ssh-ed25519 JzjriQ C7anMW0cKyRi9K6rAhVg6j0of2yTk/VHYKJg7dHbzmk +bk0qIXglNi8DeH7v3ulgwJLoDHBlst6ph+tiyOGv8k4 +-> ssh-rsa 6hPx7A +PzF2gOmBtoPNPTgyyKFMGjMOGbKs3VgpJJNKx9lY/nFyqTV5u3PPKwG9ngAkc2Ne +u2jLdir3SQkmOSTXXLmQTKRdMoZuyneDlhFvfgdfI/4v9FN71vPXuq7qIY+SfuL3 +qTUp0YlILc66TrWJnOqXv3R3wvEsbRxeGj1rMAK3axOAN+gMjdoUUX6xJG49DT2J +oslfBAxdcoNxrtlsBCI4p+FtPULOqMJelQCYAT8a8TJLdZjXqlCbCCu6ULy20fsd +8xSuSVcs81c2lk0wsav9uqBWRJcphmvS2IrFMY9EiHlcaTYJIwS50pl36ZY6ylLa +d8FtmrjQT2SWkifWPgCx4MaHPPu5MfvqvGNyAIn+5K3fari45HAqekVY7QEQcytU +/cxnt40EPt2Xxe6xZBhSrd7Aw2dIKAf06pdfU0WsmV0UZFM6cwzqMbQ+sh0sNsR8 +p4IyNaU21RAod4xGPORImqGwzMVFLG7HLI9PMECoyVVYsEkZWIE5tSazjrzcc8ik +FA6ORpaHObs0vF+GGzH80W3O2HBDHIxClkb1KdNtNK6+Joh0vrBex0BV+KMYCBPD +PSCPD8ybikK75dDsB80Yfqh3Ek62n5rlN3a2LAYrm68CT8jGrn3yUY/ROxE0Eril +yq+dn7qy43Fc7WXeP89qS9VF2kSc7tyG8YYYuXSryK8 +-> ssh-ed25519 5VC2zg tadTAjVvntLemams1E9SRD9BFWiL7UxkNYp/7pAqyzU +qxPmYHFc3h+YLprMxBZEZFYoNrSEJbTIZtWSyCftHB4 +--- YU8k/iMQJjFmYA+LQa8I9EJs/h1R8m3mkJskVKUal9Y +Ej_2lEpH[|Xj]R/IS^DASMjGe"DBmv \ No newline at end of file diff --git a/hosts/srxmc00/default.nix b/hosts/srxmc00/default.nix new file mode 100644 index 0000000..8d29223 --- /dev/null +++ b/hosts/srxmc00/default.nix @@ -0,0 +1,32 @@ +{ lib, self, ... }: +{ + imports = [ + self.nixosModules.hardware + self.nixosModules.roles-media-center + ./hardware.nix + ./storage.nix + ./networking/wireguard.nix + ./networking/wireless.nix + ./services/mounts + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxmc00"; + domain = "srx.digital"; + networkmanager.enable = lib.mkForce false; + }; + + systemd.network = { + enable = true; + networks."10-wan" = { + matchConfig.Name = "enp1s0"; + networkConfig.DHCP = "ipv4"; + }; + networks."11-wifi" = { + matchConfig.Name = "wlp0s12f0"; + networkConfig.DHCP = "ipv4"; + }; + }; +} diff --git a/hosts/srxmc00/hardware.nix b/hosts/srxmc00/hardware.nix new file mode 100644 index 0000000..8480f00 --- /dev/null +++ b/hosts/srxmc00/hardware.nix @@ -0,0 +1,38 @@ +{ lib, config, self, inputs, ... }: +{ + imports = with inputs; [ + self.nixosModules.hardware + self.nixosModules.hardware-cpu-intel + # self.nixosModules.hardware-gpu-intel + self.nixosModules.hardware-bluetooth + self.nixosModules.hardware-security-secureboot + srvos.nixosModules.mixins-systemd-boot + ]; + + boot = { + initrd = { + availableKernelModules = [ + "ahci" + "nvme" + "sd_mod" + "usb_storage" + "usbhid" + "xhci_pci" + "r8169" + ]; + kernelModules = [ ]; + systemd = { + enable = true; + inherit (config.systemd) network; + }; + clevis.enable = true; + }; + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + powerManagement.cpuFreqGovernor = "performance"; +} diff --git a/hosts/srxmc00/networking/wireguard.nix b/hosts/srxmc00/networking/wireguard.nix new file mode 100644 index 0000000..e628bd3 --- /dev/null +++ b/hosts/srxmc00/networking/wireguard.nix @@ -0,0 +1,35 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.14/24" ]; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxmc00/networking/wireless.nix b/hosts/srxmc00/networking/wireless.nix new file mode 100644 index 0000000..af1f5c9 --- /dev/null +++ b/hosts/srxmc00/networking/wireless.nix @@ -0,0 +1,12 @@ +{ config, ... }: +{ + age.secrets.wifiClient.file = ../wifi_client.age; + + networking.wireless = { + enable = true; + networks."@SSID@".psk = "@PASSWD@"; + environmentFile = config.age.secrets.wifiClient.path; + }; + + services.telegraf.extraConfig.inputs.wireless = { }; +} diff --git a/hosts/srxmc00/services/mounts/default.nix b/hosts/srxmc00/services/mounts/default.nix new file mode 100644 index 0000000..6c3e1b4 --- /dev/null +++ b/hosts/srxmc00/services/mounts/default.nix @@ -0,0 +1,48 @@ +{ + + age.secrets.cifsNas.file = ../../cifs_nas.age; + + fileSystems = { + "/mnt/movies" = { + device = "//192.168.178.71/movies"; + fsType = "cifs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.device-timeout=5s" + "x-systemd.idle-timeout=60" + "x-systemd.mount-timeout=5s" + "credentials=/run/agenix/cifsNas" + ]; + }; + + "/mnt/videos" = { + device = "//192.168.178.71/videos"; + fsType = "cifs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.device-timeout=5s" + "x-systemd.idle-timeout=60" + "x-systemd.mount-timeout=5s" + "credentials=/run/agenix/cifsNas" + ]; + }; + + "/mnt/music" = { + device = "//192.168.178.71/music"; + fsType = "cifs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.device-timeout=5s" + "x-systemd.idle-timeout=60" + "x-systemd.mount-timeout=5s" + "credentials=/run/agenix/cifsNas" + ]; + }; + }; +} diff --git a/hosts/srxmc00/storage.nix b/hosts/srxmc00/storage.nix new file mode 100644 index 0000000..8aed04e --- /dev/null +++ b/hosts/srxmc00/storage.nix @@ -0,0 +1,98 @@ +{ lib, ... }: +let + disks = [ "/dev/disk/by-id/wwn-0x5000000000002b6f" ]; +in +{ + disko.devices = { + disk = lib.genAttrs disks (device: { + name = lib.last (lib.splitString "/" device); + inherit device; + content = { + type = "gpt"; + partitions = { + ESP = { + label = "EFI"; + name = "ESP"; + type = "EF00"; + start = "1MiB"; + end = "512MiB"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + SYSTEM = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + passwordFile = "/etc/hostname"; + settings.allowDiscards = true; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/var" = { + mountpoint = "/var"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/etc" = { + mountpoint = "/etc"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/root" = { + mountpoint = "/root"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + }; + }; + }; + }; + }; + }; + }); + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "size=1G" + "mode=755" + "noatime" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=1G" ]; + }; + }; + }; +} diff --git a/hosts/srxmc00/vpn_srx.age b/hosts/srxmc00/vpn_srx.age new file mode 100644 index 0000000000000000000000000000000000000000..67ad1f483ddcec560d776c8cd7ea398d6d09654f GIT binary patch literal 1189 zcmZ9LIqUNT0Ea~!BrbxWxM*DseVgWLf}$j8?xwk~I;BaPqs`r%qYk3rJBc{x$nWtxxQyr`KW4>&9DX5@2t8mUB?lOVOw&Q z@9TXtu2h!T!iZ?-e4*Y6dPlU*F-9~KFYZI28E1NKb(qCt+O7b+=D<64nISgJ5bdrb zkVtGg{#s-gs?w*>7R=Xc6 z1Wy)=ZztEEZ+w#BELd`Ds$zq zRNCmnmgtvE##-=6Qhb!S4enM7^491!#sQgWA#x^-4sRyhUc(mO0BnYwL`;cj-#gu8 z4fD?yRH-;TQm{30x{^M@X*7 zifpE_wzojIoD%6-%We#9w`#e|*#|>Rxf^bfep3v+qf-F0vXi>qFE<0VTC}M2EHpgG2^PPLLLTjC>q4?_q^PUGINrm9&W_GGSpXU2gDs=)>j3k@ekUCyf4t3H!<*Ko zvoJ9zXi+e?rf{vEcKr0Cn8UzJvT9iRAxS3=7nGbh4uumiX7jrhz!JGB;CQ?ijLZj& zASeKW_-?~sgNs$Adeka#uOp;j*61uYNn>Gi* ssh-ed25519 jDpDqw EDyZ7jbudtHWerEUwUIU0yR7j/84bgbO1BVmWnpKmBc +F4k9tOk3YW/VSv73wAU6soKNOTyMfzanzDzIVtkFABc +-> ssh-ed25519 JzjriQ GqJXNeK19JpRtrvhfvoBUa03YMGbLyf472pbch6Kl0Y +iW9UlEX3033xeU9QQWJsEUAf8u+cay9ON/CdZbEo8bo +-> ssh-rsa 6hPx7A +2L6MeBaDoNQx1xH7oDrjZ4j8WNtmqS99lR7ow7SEuf3mGBv0cka9qnv865LRE49K +NPRhZPXO+p6laL8l3dRNnT3lKKLPMe0EMzJBO+ZlclHBet0Gq4d1Op1UqDrS11rq +sBnfs8GxQuY/6KEarY/0wz53HFSv3zv3mD3Cq8TTYzJMe8jPBJAXpkwjG5uWltw8 +e0YOfUBbilYpE7B11Fg8r1516nno30qnr+cDAJWZLY4QxymX41sUiToiYrAM0THn +xFWtU8kWhkfNAgREU3zLQ4vZTay0Qbw7oKzUhBHByjxKEsanythS5x+JyV+KHsZw +ZJtSAAmeZ4E0Wh69hvFXqZewe9vFf2gqFbcGxSevPrHzhdHXucnbC1nO4OQloPZU +Pst9Iu428bcT8QAK5M4G4UN7rrPMVzntMmUI8XsyFECRA9i/nRGVSEGXb9FxlLeF +UqFHnI5NowTCR5HMfZt2ZiEhVICN1r86nZdgWauWp4kpAWWk5yyc/bOEp56ZJCwy +56jD4x/hViJygevfEbqBPINzI9w3AK4TTdGqOaXK3w93NQN2TlfY5EN70cw7HqvU +vmkhKcuSbozgCRs9YsxwCt+CMD89Xlltn4U/6o/QLTqGjCS2khTHBxkV8R8T4XUc +rCOsmeRsVqddlcVf3CSs6xNcAwJKwtugOdeRKWFm/zA +-> ssh-ed25519 5VC2zg di3NQcPdTUlFG7Kb6TaNAHvVPf32TE8tLV88QEkqa1g +4MYQ3nB2NUfzgciXO1cQuh3U5aJwhlv1brXZYtJ657c +--- lp5sWjUswhDxr4XUvMf/eTDrDdXUmrf6PNWZd1aPi4E +h%K7..,̿<1/5I‰x/7(N}qWbPhDѻ "M,t/,@Z0٤}m\ \ No newline at end of file diff --git a/hosts/srxnas00/default.nix b/hosts/srxnas00/default.nix new file mode 100644 index 0000000..8d51dd2 --- /dev/null +++ b/hosts/srxnas00/default.nix @@ -0,0 +1,42 @@ +{ self, ... }: +{ + imports = [ + self.nixosModules.hardware + self.nixosModules.roles-nas + self.nixosModules.roles-desktop + self.nixosModules.services-security-tang + ./hardware.nix + ./storage.nix + ./network/wireguard + ./network/knsupdate + ./storage/nfs + ./services/apcupsd + ./services/mosquitto + ./services/home-assistant + ./services/zigbee2mqtt + ./services/rtl-sdr + ./services/minidlna + ./services/jellyfin + ./services/vdr + ./services/netboot + ./services/vault + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxnas00"; + domain = "srx.digital"; + hostId = "4e34e4ef"; + }; + + systemd.network = { + enable = true; + networks."10-uplink" = { + matchConfig.Name = "enp1s0"; + networkConfig.DHCP = "ipv4"; + }; + }; + + systemd.oomd.enable = false; +} diff --git a/hosts/srxnas00/dns_update.age b/hosts/srxnas00/dns_update.age new file mode 100644 index 0000000..9978a80 --- /dev/null +++ b/hosts/srxnas00/dns_update.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw E4NgDWizGATiF5OHbAb5hgyj5Pam8tF+KvGKZV4Wngc +Jkc7H++MW6C4VAT17Ja5VrK/+S1id3Yxqchw9fW8/1w +-> ssh-ed25519 JzjriQ onB8XvHpoFBqq70He+Q5RGT+6125pNuuyX2oFJs692c +1E1naGOAQmxnrW3MgTeLze8JgU0wOi+cISVhpQx16BE +-> ssh-rsa 6hPx7A +ETBzZkMgH60pQxGyXdQfrFwOIU02nDdaC31ton0vBvEdY7EQ9x1EwfwG5GAKnS4M +WtUnOdOqPC2W0i8MSOnbODk9nNbZAyxVP0wn4N3RimFjgWNOY2QO0gzTI+tA7MIl +prFIwSn9QRYzcBkQSQ1aNVjOZ/xc920YCNHDfXyUkPad6I5qAKXbHjd+kg01pTTE +OkGuBuxlX6jNbsjtPHDRCynWwFlOSjIzaEeYSN1qLDwocAMnVej3aVZtLFUkQCOn +LXXBUHJv9IYWW0TAmYeltL23a/IgNN7cBnecclXz4bGDNS6MX/gF8OPFgwvufn9A +3v8Bd6RlKmSt1gg6q/k3Kb68GIGrgV+dh03Gwv7Scam3/RclCaVx8ll2bvXRtdbf +nfreO7A19g5PK8U2I2FgItLuK0F6D7cc8NB3soZ2gGQnB5uqU4UIV+zzapC4ZvSX +S/xJN9mSwDgVfoKYfoux+u8dB+BoRICm3VZMoVZ3RsfeHXOMja0Mb03Q0ikuO7A2 +TvHxvQqiUzAtP0+I9rznHlzWgNybQTqob5pOkd7ZM3K36OfXg9sDA8vyuNaEOu5b +cqIUi3ZF8ibN6toclyYa/Cv02WKxhLAK3k5mgdMMOEvAXn1SOaJA2nyhAyS/zekp +UWOSUBjGR61FK5YsW9JAM2rXHNyhTtj6Cn++lvUJeKw +-> ssh-ed25519 ZeuIrQ X6hyEa0SQYh1S7fT1D60jXjtAYkzFM5hcoQGGAn1zSE +seXKUxh6t60VfFc+Uf6JUemeotHhK9LGjbkbXNXQcJo +--- MymLkRE7ZVLzdgiwVcBhQCCTroE+Lx02mpY70TEc6H8 +BC4@4px6qLOWFlSQ9Vkr_p{CxRn׻AU.SYnhΩH&lX' \ No newline at end of file diff --git a/hosts/srxnas00/hardware.nix b/hosts/srxnas00/hardware.nix new file mode 100644 index 0000000..f7ef28f --- /dev/null +++ b/hosts/srxnas00/hardware.nix @@ -0,0 +1,39 @@ +{ self, inputs, config, modulesPath, ... }: +{ + imports = with inputs; [ + (modulesPath + "/installer/scan/not-detected.nix") + self.nixosModules.hardware + self.nixosModules.hardware-cpu-intel + # self.nixosModules.hardware-gpu-intel + self.nixosModules.hardware-security-secureboot + self.nixosModules.filesystems-zfs + srvos.nixosModules.mixins-systemd-boot + ]; + + boot = { + initrd = { + availableKernelModules = [ + "ahci" + "nvme" + "sd_mod" + "usb_storage" + "usbhid" + "xhci_pci" + "r8169" + ]; + kernelModules = [ ]; + systemd = { + enable = true; + inherit (config.systemd) network; + }; + network.enable = true; + clevis.enable = true; + }; + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + }; + + powerManagement.cpuFreqGovernor = "powersave"; +} diff --git a/hosts/srxnas00/network/knsupdate/default.nix b/hosts/srxnas00/network/knsupdate/default.nix new file mode 100644 index 0000000..758c9fa --- /dev/null +++ b/hosts/srxnas00/network/knsupdate/default.nix @@ -0,0 +1,16 @@ +{ config, ... }: +{ + age.secrets.knsupdate = { + file = ../../dns_update.age; + owner = config.users.users.knsupdate.group; + }; + + srx.service.knsupdate = { + enable = true; + server = "dns.vpn.srx.dev"; + ttl = 120; + ipVersions = [ 4 ]; + interval = "*:0/1"; + keyFile = config.age.secrets.knsupdate.path; + }; +} diff --git a/hosts/srxnas00/network/wireguard/default.nix b/hosts/srxnas00/network/wireguard/default.nix new file mode 100644 index 0000000..5bfa835 --- /dev/null +++ b/hosts/srxnas00/network/wireguard/default.nix @@ -0,0 +1,36 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" "192.168.178.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.4/24" ]; + networkConfig.IPForward = true; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxnas00/networking/default.nix b/hosts/srxnas00/networking/default.nix new file mode 100644 index 0000000..a6e51b1 --- /dev/null +++ b/hosts/srxnas00/networking/default.nix @@ -0,0 +1,68 @@ +{ + imports = [ + ./wireguard/srx.nix + ./wireless.nix + # ./networks/op.nix + # ./networks/wan.nix + # ./networks/usr.nix + # ./networks/dmz.nix + # ./networks/gst.nix + # ./wireguard/mullvad.nix + # ./dns/knsupdate.nix + # ./dns/blocky.nix + # ./kea + ]; + + networking.useNetworkd = true; + + systemd.network = { + enable = true; + # netdevs = { + # bond0 = { + # netdevConfig = { + # Kind = "bond"; + # Name = "bond0"; + # }; + # bondConfig = { + # Mode = "802.3ad"; + # LACPTransmitRate = "fast"; + # TransmitHashPolicy = "layer3+4"; + # DownDelaySec = 0.2; + # UpDelaySec = 0.2; + # MIIMonitorSec = 0.1; + # }; + # }; + # }; + + networks = { + enp2s0 = { + matchConfig.Name = "enp2s0"; + matchConfig.MACAddress = "00:1e:06:45:12:27"; + address = [ "192.168.178.10/24" ]; + routes = [ + { routeConfig.Gateway = "192.168.178.1"; } + { routeConfig.Gateway = "fe80::1"; } + ]; + bridgeConfig = { }; + linkConfig.RequiredForOnline = "routable"; + }; + + # enp2s0 = { + # # matchConfig.MACAddress = "00:1e:06:45:12:27"; + # # networkConfig.Bond = "bond0"; + # networkConfig.LinkLocalAddressing = "no"; + # }; + + # enp3s0 = { + # matchConfig.MACAddress = "00:1e:06:45:12:28"; + # networkConfig.Bond = "bond0"; + # }; + + # bond0 = { + # matchConfig.Name = "bond0"; + # linkConfig.RequiredForOnline = "carrier"; + # networkConfig.LinkLocalAddressing = "no"; + # }; + }; + }; +} diff --git a/hosts/srxnas00/networking/dns/blocky.nix b/hosts/srxnas00/networking/dns/blocky.nix new file mode 100644 index 0000000..2d3a0c5 --- /dev/null +++ b/hosts/srxnas00/networking/dns/blocky.nix @@ -0,0 +1,123 @@ +{ config, ... }: +{ + networking.firewall.interfaces = { + br_usr = { + allowedUDPPorts = [ config.services.blocky.settings.ports.dns ]; + allowedTCPPorts = [ config.services.blocky.settings.ports.dns ]; + }; + }; + + # networking.firewall.extraCommands = '' + # ip6tables --table nat --flush OUTPUT + # ${lib.flip (lib.concatMapStringsSep "\n") ["udp" "tcp"] (proto: '' + # ip6tables --table nat --append OUTPUT \ + # --protocol ${proto} --destination ::1 --destination-port 53 \ + # --jump REDIRECT --to-ports ${toString config.services.blocky.settings.ports.dns} + # '')} + # ''; + + services.blocky = { + enable = true; + settings = { + # https://0xerr0r.github.io/blocky/configuration/ + + upstreams = { + groups = { + default = [ + "https://dns.digitale-gesellschaft.ch/dns-query" + "tcp-tls:dns2.digitalcourage.de:853" + "tcp-tls:dns3.digitalcourage.de:853" + "tcp-tls:fdns1.dismail.de:853" + "tcp-tls:one.one.one.one:853" + ]; + unencrypted = [ + "1.0.0.1" + "1.1.1.1" + "2606:4700:4700::1001" + "2606:4700:4700::1111" + "dns2.digitalcourage.de" + ]; + }; + timeout = "2s"; + }; + + startVerifyUpstream = true; + connectIPVersion = "dual"; + + blocking = { + blackLists = { + # https://disconnect.me/trackerprotection + ads = [ + "http://sysctl.org/cameleon/hosts" + "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts" + "https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt" + "https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt" + ]; + fakenews = [ + "https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts" + ]; + }; + + whiteLists = { }; + + clientGroupsBlock = { + default = [ "ads" ]; + sensitive = [ + "ads" + "fakenews" + ]; + }; + + blockType = "zeroIp"; + blockTTL = "1m"; + + loading = { + downloads = { + timeout = "4m"; + attempts = 5; + cooldown = "10s"; + }; + refreshPeriod = "4h"; + strategy = "failOnError"; + }; + }; + + filtering.queryTypes = [ ]; + + caching = { + minTime = "5m"; + maxTime = "30m"; + maxItemsCount = 0; + prefetching = true; + prefetchExpires = "2h"; + prefetchThreshold = 5; + prefetchMaxItemsCount = 0; + cacheTimeNegative = "30m"; + }; + + ports = { + dns = 53; + http = 4040; + }; + + log = { + level = "info"; + format = "text"; + timestamp = true; + privacy = true; + }; + + hostsFile = { + sources = [ "/etc/hosts" ]; + hostsTTL = "60m"; + filterLoopback = true; + loading.refreshPeriod = "30m"; + }; + + prometheus = { + enable = true; + path = "/metrics"; + }; + }; + }; +} diff --git a/hosts/srxnas00/networking/dns/knsupdate.nix b/hosts/srxnas00/networking/dns/knsupdate.nix new file mode 100644 index 0000000..a752fec --- /dev/null +++ b/hosts/srxnas00/networking/dns/knsupdate.nix @@ -0,0 +1,16 @@ +{ config, ... }: +{ + age.secrets.knsupdate = { + file = ../../dns_update.age; + owner = config.users.users.knsupdate.group; + }; + + srx.service.knsupdate = { + enable = true; + server = "dns.vpn.srx.dev"; + ttl = 120; + interval = "*:0/1"; + ipVersions = [ 4 ]; + keyFile = config.age.secrets.knsupdate.path; + }; +} diff --git a/hosts/srxnas00/networking/dns/unbound.nix b/hosts/srxnas00/networking/dns/unbound.nix new file mode 100644 index 0000000..52d3037 --- /dev/null +++ b/hosts/srxnas00/networking/dns/unbound.nix @@ -0,0 +1,68 @@ +{ pkgs, ... }: +{ + services.unbound = { + enable = true; + settings = { + remote-control = { + control-enable = true; + control-use-cert = false; + }; + server = { + num-threads = 4; + verbosity = 1; + prefetch = true; + prefetch-key = true; + serve-expired = true; + cache-min-ttl = 60; + cache-max-ttl = 3600; + infra-cache-slabs = "8"; + key-cache-slabs = "8"; + msg-cache-slabs = "8"; + rrset-cache-slabs = "8"; + msg-cache-size = "256m"; + rrset-cache-size = "512m"; + interface = [ + "0.0.0.0" + "'::0'" + ]; + access-control = builtins.concatLists [ + [ + # localhost + "::1/128 allow" + "127.0.0.0/8 allow" + ] + [ + # default + "0.0.0.0/0 deny" + "::/0 deny" + ] + ]; + tls-cert-bundle = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"; + unblock-lan-zones = true; + insecure-lan-zones = true; + domain-insecure = [ + "d.f.ip6.arpa" + "ffdd" + ]; + }; + forward-zone = [ + { + name = "."; + forward-tls-upstream = true; + forward-addr = [ + # Quad9 + "2620:fe::fe@853#dns.quad9.net" + "9.9.9.9@853#dns.quad9.net" + "2620:fe::9@853#dns.quad9.net" + "149.112.112.112@853#dns.quad9.net" + # Cloudflare DNS + "2606:4700:4700::1111@853#cloudflare-dns.com" + "1.1.1.1@853#cloudflare-dns.com" + "2606:4700:4700::1001@853#cloudflare-dns.com" + "1.0.0.1@853#cloudflare-dns.com" + ]; + } + ]; + }; + }; +} diff --git a/hosts/srxnas00/networking/kea/default.nix b/hosts/srxnas00/networking/kea/default.nix new file mode 100644 index 0000000..d6758a3 --- /dev/null +++ b/hosts/srxnas00/networking/kea/default.nix @@ -0,0 +1,223 @@ +{ lib, config, ... }: +let + dns = { + host = "srx.dev"; + servers = "dns.vpn.${dns.host}"; + zone = "op.hq.hh.${dns.host}"; + }; +in +{ + networking.firewall.interfaces = { + br_usr = { + allowedUDPPorts = [ 67 ]; + allowedTCPPorts = [ 67 ]; + }; + }; + + services.kea = { + ctrl-agent = { + enable = true; + settings = { + control-sockets = { + dhcp4 = { + socket-name = "/run/kea/kea-dhcp4.socket"; + socket-type = "unix"; + }; + dhcp6 = { + socket-name = "/run/kea/kea-dhcp6.socket"; + socket-type = "unix"; + }; + }; + }; + }; + + # dhcp-ddns = { + # # https://kea.readthedocs.io/en/kea-2.2.0/arm/ddns.html#adding-forward-dns-servers + # enable = true; + # settings = { + # forward-ddns = { + # ddns-hosts = [ + # { + # name = "${dns.host}."; + # key-name = "update"; + # dns-servers = [ + # { + # ip-address = inputs.dns.servers; + # port = 53; + # } + # ]; + # } + # ]; + # }; + # }; + # }; + + dhcp4 = { + enable = true; + settings = { + interfaces-config.interfaces = [ "br_usr" ]; + + control-socket = { + socket-name = "/run/kea/kea-dhcp4.socket"; + socket-type = "unix"; + }; + + lease-database = { + name = "/var/lib/kea/dhcp4.leases"; + persist = true; + type = "memfile"; + }; + + rebind-timer = 2000; + renew-timer = 1000; + valid-lifetime = 4000; + + match-client-id = false; + + client-classes = [ + { + name = "iPXE"; + test = "substring(option[77].hex, 0, 4) == 'iPXE'"; + boot-file-name = "http://netboot.srx.digital/boot.php"; + } + { + name = "UEFI-32-7"; + test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00007'"; + boot-file-name = "ipxe.efi"; + } + { + name = "UEFI-32-8"; + test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00008'"; + boot-file-name = "ipxe.efi"; + } + { + name = "UEFI-32-9"; + test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00009'"; + boot-file-name = "ipxe.efi"; + } + { + name = "Legacy"; + test = "substring(option[60].hex,0,20) == 'PXEClient:Arch:00000'"; + boot-file-name = "undionly.kpxe"; + } + ]; + + subnet4 = [ + { + interface = "br_usr"; + subnet = "10.50.0.0/23"; + pools = [{ pool = "10.50.0.100 - 10.50.0.250"; }]; + option-data = [ + { + name = "routers"; + data = "10.50.0.1"; + } + { + name = "domain-name"; + data = dns.host; + } + { + name = "domain-name-servers"; + # data = "10.50.0.10"; + data = "10.50.0.1"; + } + { + name = "domain-search"; + data = dns.zone; + } + ]; + reservations = [ + { + hostname = "srxws00.${dns.zone}"; + ip-address = "10.50.0.200"; + hw-address = "f4:a8:0d:07:f4:5c"; + next-server = "10.50.0.10"; + } + { + hostname = "srxws00.${dns.zone}"; + ip-address = "10.50.0.201"; + hw-address = "c8:94:02:b9:a8:83"; + next-server = "10.50.0.10"; + } + { + hostname = "vm-pxe-test1.${dns.zone}"; + ip-address = "10.50.0.250"; + hw-address = "52:54:00:21:33:86"; + next-server = "10.50.0.10"; + } + { + hostname = "vm-pxe-test2.${dns.zone}"; + ip-address = "10.50.0.251"; + hw-address = "52:54:00:db:34:7f"; + next-server = "10.50.0.10"; + } + { + hostname = "nixos-karos.${dns.zone}"; + ip-address = "10.50.0.123"; + hw-address = "b4:a9:fc:7d:d8:dc"; + next-server = "10.50.0.10"; + } + ]; + } + ]; + + # dhcp-ddns.enable-updates = true; + # ddns-send-updates = true; + # ddns-qualifying-suffix = "${dns.zone}."; + }; + }; + + dhcp6 = { + enable = true; + settings = { + interfaces-config.interfaces = [ "br_usr" ]; + + control-socket = { + socket-name = "/run/kea/kea-dhcp6.socket"; + socket-type = "unix"; + }; + + lease-database = { + name = "/var/lib/kea/dhcp6.leases"; + persist = true; + type = "memfile"; + }; + + preferred-lifetime = 3000; + rebind-timer = 2000; + renew-timer = 1000; + valid-lifetime = 4000; + + subnet6 = [ + { + interface = "br_usr"; + subnet = "fd42:fab:2381:500::/119"; + pools = [{ pool = "fd42:fab:2381:500::50-fd42:fab:2381:500::1ff"; }]; + option-data = [ + { + name = "dns-servers"; + # data = "fd42:fab:2381:500::10"; + data = "fd42:fab:2381:500::1"; + } + ]; + } + ]; + # dhcp-ddns.enable-updates = true; + # ddns-send-updates = true; + # ddns-qualifying-suffix = "${dns.zone}."; + }; + }; + }; + + services.prometheus.exporters.kea = { + enable = lib.mkIf config.services.kea.dhcp4.enable or config.services.kea.dhcp6.enable true; + controlSocketPaths = + lib.optionals config.services.kea.dhcp4.enable [ "/run/kea/kea-dhcp4.socket" ] + ++ lib.optionals config.services.kea.dhcp6.enable [ "/run/kea/kea-dhcp6.socket" ]; + }; + + systemd.services.kea-ctrl-agent = { + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + }; +} diff --git a/hosts/srxnas00/networking/networks/dmz.nix b/hosts/srxnas00/networking/networks/dmz.nix new file mode 100644 index 0000000..2e52f65 --- /dev/null +++ b/hosts/srxnas00/networking/networks/dmz.nix @@ -0,0 +1,40 @@ +{ + systemd.network = { + netdevs = { + vlan_dmz = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan_dmz"; + }; + vlanConfig.Id = 600; + }; + + br_dmz = { + netdevConfig = { + Kind = "bridge"; + Name = "br_dmz"; + }; + }; + }; + + networks = { + bond0.vlan = [ "vlan_dmz" ]; + + vlan_dmz = { + matchConfig.Name = "vlan_dmz"; + networkConfig.Bridge = "br_dmz"; + linkConfig.RequiredForOnline = "enslaved"; + }; + + br_dmz = { + matchConfig.Name = "br_dmz"; + address = [ + "10.60.0.10/23" + "fd42:fab:2381:600::10/120" + ]; + bridgeConfig = { }; + linkConfig.RequiredForOnline = "routable"; + }; + }; + }; +} diff --git a/hosts/srxnas00/networking/networks/gst.nix b/hosts/srxnas00/networking/networks/gst.nix new file mode 100644 index 0000000..b076e9c --- /dev/null +++ b/hosts/srxnas00/networking/networks/gst.nix @@ -0,0 +1,40 @@ +{ + systemd.network = { + netdevs = { + vlan_gst = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan_gst"; + }; + vlanConfig.Id = 400; + }; + + br_gst = { + netdevConfig = { + Kind = "bridge"; + Name = "br_gst"; + }; + }; + }; + + networks = { + bond0.vlan = [ "vlan_gst" ]; + + vlan_gst = { + matchConfig.Name = "vlan_gst"; + networkConfig.Bridge = "br_gst"; + linkConfig.RequiredForOnline = "enslaved"; + }; + + br_gst = { + matchConfig.Name = "br_gst"; + address = [ + "192.168.52.10/24" + "fd42:fab:2381:400::10/120" + ]; + bridgeConfig = { }; + linkConfig.RequiredForOnline = "routable"; + }; + }; + }; +} diff --git a/hosts/srxnas00/networking/networks/op.nix b/hosts/srxnas00/networking/networks/op.nix new file mode 100644 index 0000000..1ca5ef7 --- /dev/null +++ b/hosts/srxnas00/networking/networks/op.nix @@ -0,0 +1,40 @@ +{ + systemd.network = { + netdevs = { + vlan_op = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan_op"; + }; + vlanConfig.Id = 500; + }; + + br_op = { + netdevConfig = { + Kind = "bridge"; + Name = "br_op"; + }; + }; + }; + + networks = { + bond0.vlan = [ "vlan_op" ]; + + vlan_op = { + matchConfig.Name = "vlan_op"; + networkConfig.Bridge = "br_op"; + linkConfig.RequiredForOnline = "enslaved"; + }; + + br_op = { + matchConfig.Name = "br_op"; + address = [ + "10.40.0.10/23" + "fd42:fab:2381:400::10/120" + ]; + bridgeConfig = { }; + linkConfig.RequiredForOnline = "routable"; + }; + }; + }; +} diff --git a/hosts/srxnas00/networking/networks/usr.nix b/hosts/srxnas00/networking/networks/usr.nix new file mode 100644 index 0000000..8f94cf0 --- /dev/null +++ b/hosts/srxnas00/networking/networks/usr.nix @@ -0,0 +1,44 @@ +{ + systemd.network = { + netdevs = { + vlan_usr = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan_usr"; + }; + vlanConfig.Id = 300; + }; + + br_usr = { + netdevConfig = { + Kind = "bridge"; + Name = "br_usr"; + }; + }; + }; + + networks = { + bond0.vlan = [ "vlan_usr" ]; + + vlan_usr = { + matchConfig.Name = "vlan_usr"; + networkConfig.Bridge = "br_usr"; + linkConfig.RequiredForOnline = "enslaved"; + }; + + br_usr = { + matchConfig.Name = "br_usr"; + address = [ + "10.50.0.10/23" + "fd42:fab:2381:500::10/119" + ]; + routes = [ + { routeConfig.Gateway = "10.50.0.1"; } + { routeConfig.Gateway = "fe80::1"; } + ]; + bridgeConfig = { }; + linkConfig.RequiredForOnline = "routable"; + }; + }; + }; +} diff --git a/hosts/srxnas00/networking/networks/wan.nix b/hosts/srxnas00/networking/networks/wan.nix new file mode 100644 index 0000000..cf10376 --- /dev/null +++ b/hosts/srxnas00/networking/networks/wan.nix @@ -0,0 +1,23 @@ +{ + systemd.network = { + netdevs = { + vlan_wan = { + netdevConfig = { + Kind = "vlan"; + Name = "vlan_wan"; + }; + vlanConfig.Id = 200; + }; + }; + + networks = { + bond0.vlan = [ "vlan_wan" ]; + + vlan_wan = { + matchConfig.Name = "vlan_wan"; + networkConfig.DHCP = "yes"; + linkConfig.RequiredForOnline = "routable"; + }; + }; + }; +} diff --git a/hosts/srxnas00/networking/wireguard/mullvad.nix b/hosts/srxnas00/networking/wireguard/mullvad.nix new file mode 100644 index 0000000..4962faf --- /dev/null +++ b/hosts/srxnas00/networking/wireguard/mullvad.nix @@ -0,0 +1,180 @@ +{ config, ... }: +let + Name = "vpn_mvd"; + Description = "EAobLeO0BWJWUQ0JIWFTIld3PjCSC2Je0iY2hzaW/BU="; + MTUBytes = "1300"; + ListenPort = 51821; + FirewallMark = 42; + Table = 51820; +in +{ + age.secrets.vpnMvd = { + file = ../../vpn_mvd.age; + owner = "systemd-network"; + }; + + # networking.wg-quick.interfaces.vpn_mvd = { + # address = ["10.65.243.251/32" "fc00:bbbb:bbbb:bb01::2:f3fa/128"]; + # privateKeyFile = config.age.secrets.vpnMvd.path; + # peers = [ + # { + # allowedIPs = ["0.0.0.0/0" "::0/0"]; + # publicKey = "UrQiI9ISdPPzd4ARw1NHOPKKvKvxUhjwRjaI0JpJFgM="; + # endpoint = "193.32.249.66:51820"; + # } + # ]; + # }; + + # networking.wireguard.interfaces.wg0 = { + # preSetup = '' + # ip netns add ${socketNamespace} + # ''; + # inherit socketNamespace; + # }; + + boot.kernel.sysctl."net.ipv4.conf.all.src_valid_mark" = 1; + + systemd.network = { + netdevs."${Name}" = { + netdevConfig = { + Kind = "wireguard"; + inherit Name Description MTUBytes; + }; + + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnMvd.path; + inherit ListenPort FirewallMark; + }; + + wireguardPeers = [ + { + wireguardPeerConfig = { + Endpoint = "193.32.249.66:51820"; + PublicKey = "UrQiI9ISdPPzd4ARw1NHOPKKvKvxUhjwRjaI0JpJFgM="; + AllowedIPs = [ + "0.0.0.0/0" + "::0/0" + ]; + PersistentKeepalive = 15; + }; + } + ]; + }; + + networks."${Name}" = { + matchConfig = { + inherit Name; + }; + address = [ + "10.65.243.251/32" + "fc00:bbbb:bbbb:bb01::2:f3fa/128" + ]; + networkConfig = { + DNS = "10.64.0.1"; + DNSDefaultRoute = true; + inherit Description; + }; + linkConfig = { + # ActivationPolicy = "up"; + ActivationPolicy = "manual"; + inherit MTUBytes; + }; + routes = [ + { + routeConfig = { + Destination = "0.0.0.0/0"; + inherit Table; + # GatewayOnLink = true; + }; + } + { + routeConfig = { + Destination = "::/0"; + inherit Table; + # GatewayOnLink = true; + }; + } + ]; + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + InvertRule = true; + inherit FirewallMark; + inherit Table; + }; + } + { + routingPolicyRuleConfig = { + SuppressPrefixLength = 0; + Table = "main"; + }; + } + ]; + }; + }; +} +# +## RESTORE +# +# systemctl stop wireguard-vpn_mvd +# ip route replace default via 10.50.0.1 +# unlink /etc/resolv.conf ; echo 'nameserver 1.1.1.1' > /etc/resolv.conf +# ping -c 1 8.8.8.8 +# dig google.de +# +## CHECKS +# ip address show vpn_mvd +# ip route show table 51820 +# ip route get 65.108.77.254 +# ip route get 10.50.0.4 +# ip rule show table main | grep suppress_prefixlength +# ip rule show table 51820 | grep fwmark +# sysctl net.ipv4.conf.all.src_valid_mark +# curl -s -4 https://checkip.srx.digital/ +# curl -s -6 https://checkip.srx.digital/ +# https://www.wireguard.com/netns/ +# +# ip route show table 51820 +# ip route get 65.108.77.254 +# ip route get 10.50.0.4 +# ip rule show table main | grep suppress_prefixlength +# ip rule show table 51820 | grep fwmark +# sysctl net.ipv4.conf.all.src_valid_mark +# curl -s -4 https://checkip.srx.digital/ +# curl -s -6 https://checkip.srx.digital/ +# 17: vpn_mvd: mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 +# link/none +# inet 10.65.243.251/32 scope global vpn_mvd +# valid_lft forever preferred_lft forever +# inet6 fc00:bbbb:bbbb:bb01::2:f3fa/128 scope global +# valid_lft forever preferred_lft forever +# default dev vpn_mvd scope link +# 65.108.77.254 dev vpn_mvd table 51820 src 10.65.243.251 uid 0 +# cache +# 10.50.0.4 dev br_usr src 10.50.0.10 uid 0 +# cache +# 32764: from all lookup main suppress_prefixlength 0 +# 32765: not from all fwmark 0xca6c lookup 51820 +# 32765: not from all fwmark 0x2a lookup 51820 proto static +# net.ipv4.conf.all.src_valid_mark = 1 +# 193.32.249.133 +# 2a03:1b20:3:f011::e003 +# +# +# ip link add vpn_mvd type wireguard +# ip link set mtu 1420 up dev vpn_mvd +# +# ip -4 address add 10.65.243.251/32 dev vpn_mvd +# ip -4 route add 0.0.0.0/0 dev vpn_mvd table 51820 +# ip -4 rule add not fwmark 51820 table 51820 +# ip -4 rule add table main suppress_prefixlength 0 +# +# ip -6 address add fc00:bbbb:bbbb:bb01::2:f3fa/128 dev vpn_mvd +# ip -6 route add ::/0 dev vpn_mvd table 51820 +# ip -6 rule add not fwmark 51820 table 51820 +# ip -6 rule add table main suppress_prefixlength 0 +# +# sysctl -q net.ipv4.conf.all.src_valid_mark=1 +# +# wg set vpn_mvd fwmark 51820 +# wg setconf vpn_mvd /dev/fd/63 diff --git a/hosts/srxnas00/networking/wireguard/srx.nix b/hosts/srxnas00/networking/wireguard/srx.nix new file mode 100644 index 0000000..2feecb7 --- /dev/null +++ b/hosts/srxnas00/networking/wireguard/srx.nix @@ -0,0 +1,40 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.2/24" ]; + networkConfig = { + IPMasquerade = "ipv4"; + IPForward = true; + }; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; + +} diff --git a/hosts/srxnas00/networking/wireless.nix b/hosts/srxnas00/networking/wireless.nix new file mode 100644 index 0000000..5460077 --- /dev/null +++ b/hosts/srxnas00/networking/wireless.nix @@ -0,0 +1,19 @@ +{ config, ... }: { + age.secrets.wifi_client.file = ../wifi_client.age; + + networking = { + interfaces.wlp0s21f0u2.useDHCP = true; + + wireless = { + enable = true; + environmentFile = config.age.secrets.wifi_client.path; + + networks = { + "skynet".psk = "@PASS_SKYNET@"; + "FRITZ!Box Fon WLAN 7360".psk = "@PASS_WERK2@"; + }; + }; + }; + + services.telegraf.extraConfig.inputs.wireless = { }; +} diff --git a/hosts/srxnas00/services/apcupsd/default.nix b/hosts/srxnas00/services/apcupsd/default.nix new file mode 100644 index 0000000..e3a7dcc --- /dev/null +++ b/hosts/srxnas00/services/apcupsd/default.nix @@ -0,0 +1,16 @@ +{ + services = { + apcupsd = { + enable = true; + + configText = '' + UPSTYPE usb + NISIP 127.0.0.1 + BATTERYLEVEL 50 + MINUTES 5 + ''; + }; + + prometheus.exporters.apcupsd.enable = true; + }; +} diff --git a/hosts/srxnas00/services/home-assistant/auth.nix b/hosts/srxnas00/services/home-assistant/auth.nix new file mode 100644 index 0000000..ff19c09 --- /dev/null +++ b/hosts/srxnas00/services/home-assistant/auth.nix @@ -0,0 +1,10 @@ +{ + services.home-assistant.config.homeassistant.auth_providers = [ + { type = "homeassistant"; } + { + type = "trusted_networks"; + trusted_networks = [ "10.50.0.0/23" "192.168.178.0/24" ]; + allow_bypass_login = true; + } + ]; +} diff --git a/hosts/srxnas00/services/home-assistant/default.nix b/hosts/srxnas00/services/home-assistant/default.nix new file mode 100644 index 0000000..c654f6d --- /dev/null +++ b/hosts/srxnas00/services/home-assistant/default.nix @@ -0,0 +1,88 @@ +{ pkgs, config, lib, ... }: +{ + imports = [ + ./auth.nix + ./http.nix + ./zones.nix + ./lovelace + ]; + + users.users.hass = { + extraGroups = + [ "dialout" ] + ++ lib.optionals config.hardware.i2c.enable [ "i2c" ] + ++ lib.optionals config.hardware.bluetooth.enable [ "lp" ] + ++ lib.optionals config.sound.enable [ "audio" ]; + }; + + # age.secrets.homeAssistantSecrets.file = ./home-assistant-s2ecrets.age; + + services = { + home-assistant = { + enable = true; + package = + (pkgs.home-assistant.override { + # https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/home-assistant/component-packages.nix + extraComponents = [ + "auth" + "backup" + "esphome" + "lovelace" + "matrix" + "mqtt" + "network" + "zeroconf" + ]; + extraPackages = py: with py; [ psycopg2 pip ]; + }).overrideAttrs { doInstallCheck = false; }; + config = { + homeassistant = { + external_url = "https://home.srx.digital"; + internal_url = "https://home.vpn.srx.dev"; + }; + default_config = { }; + logger = { + default = "info"; + }; + mqtt = { + broker = "localhost"; + port = 1883; + discovery = true; + }; + backup = { }; + bluetooth = { }; + dhcp = { }; + discovery = { }; + esphome = { }; + frontend = { }; + history = { }; + prometheus = { }; + system_health = { }; + system_log = { }; + wake_on_lan = { }; + webhook = { }; + zeroconf = { }; + recorder = { + db_url = "postgresql://@/hass"; + purge_keep_days = 90; + }; + }; + }; + + postgresql = { + enable = true; + ensureDatabases = [ "hass" ]; + ensureUsers = [ + { + name = "hass"; + ensureDBOwnership = true; + } + ]; + }; + + postgresqlBackup = { + enable = true; + databases = [ "hass" ]; + }; + }; +} diff --git a/hosts/srxnas00/services/home-assistant/http.nix b/hosts/srxnas00/services/home-assistant/http.nix new file mode 100644 index 0000000..39912e1 --- /dev/null +++ b/hosts/srxnas00/services/home-assistant/http.nix @@ -0,0 +1,10 @@ +{ + # https://www.home-assistant.io/integrations/http + services.home-assistant.config.http = { + server_host = "0.0.0.0"; + # trusted_proxies = ["10.80.0.10"]; + use_x_forwarded_for = true; + ip_ban_enabled = true; + login_attempts_threshold = 5; + }; +} diff --git a/hosts/srxnas00/services/home-assistant/lovelace/default.nix b/hosts/srxnas00/services/home-assistant/lovelace/default.nix new file mode 100644 index 0000000..6de9d9b --- /dev/null +++ b/hosts/srxnas00/services/home-assistant/lovelace/default.nix @@ -0,0 +1,18 @@ +{ + services.home-assistant.lovelaceConfig = { + title = "SRX"; + views = [ + { + title = "Overview"; + cards = [ + { + type = "markdown"; + content = '' + https://srx.digital + ''; + } + ]; + } + ]; + }; +} diff --git a/hosts/srxnas00/services/home-assistant/zones.nix b/hosts/srxnas00/services/home-assistant/zones.nix new file mode 100644 index 0000000..b2bd9fa --- /dev/null +++ b/hosts/srxnas00/services/home-assistant/zones.nix @@ -0,0 +1,23 @@ +{ + services.home-assistant.config = { + homeassistant = { + name = "SRX"; + unit_system = "metric"; + time_zone = "Europe/Berlin"; + temperature_unit = "C"; + latitude = "53.5527778"; + longitude = "9.9611111"; + elevation = 13; + }; + + zone = [ + { + name = "Wohlwill"; + icon = "mdi:flower"; + latitude = "53.5527778"; + longitude = "9.9611111"; + radius = "200"; + } + ]; + }; +} diff --git a/hosts/srxnas00/services/jellyfin/default.nix b/hosts/srxnas00/services/jellyfin/default.nix new file mode 100644 index 0000000..a07a8fb --- /dev/null +++ b/hosts/srxnas00/services/jellyfin/default.nix @@ -0,0 +1,7 @@ +{ + services.jellyfin = { + enable = true; + openFirewall = true; + group = "users"; + }; +} diff --git a/hosts/srxnas00/services/minidlna/default.nix b/hosts/srxnas00/services/minidlna/default.nix new file mode 100644 index 0000000..a925b1a --- /dev/null +++ b/hosts/srxnas00/services/minidlna/default.nix @@ -0,0 +1,23 @@ +{ + users.users.minidlna.extraGroups = [ "users" ]; + + services.minidlna = { + enable = true; + openFirewall = true; + + settings = { + inotify = "yes"; + friendly_name = "srx"; + + media_dir = [ + "V,/srv/movies" + "A,/srv/music" + ]; + + extraConfig = '' + enable_tivo=no + max_connections=50 + ''; + }; + }; +} diff --git a/hosts/srxnas00/services/mosquitto/default.nix b/hosts/srxnas00/services/mosquitto/default.nix new file mode 100644 index 0000000..bb56532 --- /dev/null +++ b/hosts/srxnas00/services/mosquitto/default.nix @@ -0,0 +1,10 @@ +{ + services.mosquitto = { + enable = true; + listeners = [{ + port = 1883; + acl = [ "pattern readwrite #" ]; + settings = { allow_anonymous = true; }; + }]; + }; +} diff --git a/hosts/srxnas00/services/netboot/default.nix b/hosts/srxnas00/services/netboot/default.nix new file mode 100644 index 0000000..8a5031a --- /dev/null +++ b/hosts/srxnas00/services/netboot/default.nix @@ -0,0 +1,47 @@ +{ pkgs, ... }: +let + ipxeDerivation = pkgs.ipxe.overrideDerivation (_drv: { + additionalOptions = [ + "KEYBOARD_MAP" + "NET_PROTO_IPV6" + "DOWNLOAD_PROTO_NFS" + "DOWNLOAD_PROTO_FTP" + "DOWNLOAD_PROTO_FILE" + "DOWNLOAD_PROTO_HTTPS" + "CONSOLE_FRAMEBUFFER" + "CONSOLE_SERIAL" + "CONSOLE_SYSLOG" + "IMAGE_TRUST_CMD" + "IMAGE_ARCHIVE_CMD" + "IMAGE_ZLIB" + "IMAGE_GZIP" + "IMAGE_SCRIPT" + "IMAGE_PNG" + "CERT_CMD" + "CONSOLE_CMD" + "DIGEST_CMD" + "IMAGE_MEM_CMD" + "IPSTAT_CMD" + "NEIGHBOUR_CMD" + "NSLOOKUP_CMD" + "NTP_CMD" + "PARAM_CMD" + "PCI_CMD" + "POWEROFF_CMD" + "PXE_CMD" + "TIME_CMD" + "VLAN_CMD" + ]; + }); +in +{ + networking.firewall = { + allowedUDPPorts = [ 69 ]; + allowedTCPPorts = [ 69 ]; + }; + + services.atftpd = { + enable = true; + root = ipxeDerivation; + }; +} diff --git a/hosts/srxnas00/services/rtl-sdr/default.nix b/hosts/srxnas00/services/rtl-sdr/default.nix new file mode 100644 index 0000000..39b216a --- /dev/null +++ b/hosts/srxnas00/services/rtl-sdr/default.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: +{ + hardware = { + rtl-sdr.enable = true; + hackrf.enable = true; + }; + + environment.systemPackages = with pkgs; [ + rtl-sdr + rtl_433 + ]; + + services.prometheus.exporters.rtl_433 = { + enable = true; + channels = [{ + channel = 6543; + location = "Kitchen"; + name = "Acurite"; + }]; + ids = [{ + id = 1; + location = "universe"; + name = "Werk2"; + }]; + }; +} diff --git a/hosts/srxnas00/services/vault/default.nix b/hosts/srxnas00/services/vault/default.nix new file mode 100644 index 0000000..0d4b8a5 --- /dev/null +++ b/hosts/srxnas00/services/vault/default.nix @@ -0,0 +1,46 @@ +{ pkgs, config, ... }: +let + host = "vault.vpn.srx.dev"; + ip = "10.80.0.4"; + ports = { + api = 8200; + cluster = 8201; + stats = 8125; + }; + schema = "https"; +in +{ + environment = { + systemPackages = [ pkgs.vault ]; + variables.VAULT_ADDR = "${schema}://${host}:${toString ports.api}"; + }; + + services.vault = { + enable = true; + package = pkgs.vault-bin; + storageBackend = "raft"; + address = "${ip}:${toString ports.api}"; + tlsCertFile = "${config.security.acme.certs.${host}.directory}/fullchain.pem"; + tlsKeyFile = "${config.security.acme.certs.${host}.directory}/key.pem"; + listenerExtraConfig = '' + tls_min_version = "tls12" + ''; + extraConfig = '' + ui = true + api_addr = "${schema}://${host}:${toString ports.api}" + cluster_addr = "${schema}://${host}:${toString ports.cluster}" + ''; + # extraSettingsPaths = [ + # (pkgs.writeTextDir "nomad.hcl" (builtins.readFile ./policies/nomad.hcl)) + # ]; + # telemetryConfig = '' + # statsite_address = "${host}:${toString ports.stats}" + # ''; + }; + + security.acme.certs."${host}" = { + domain = "${host}"; + group = "vault"; + reloadServices = [ "vault.service" ]; + }; +} diff --git a/hosts/srxnas00/services/vdr/default.nix b/hosts/srxnas00/services/vdr/default.nix new file mode 100644 index 0000000..dbd4afd --- /dev/null +++ b/hosts/srxnas00/services/vdr/default.nix @@ -0,0 +1,26 @@ +{ pkgs, ... }: +{ + # services.vdr = { + # enable = true; + + # package = pkgs.wrapVdr.override { + # plugins = with pkgs.vdrPlugins; [ + # epgsearch + # femon + # markad + # streamdev + # vnsiserver + # ]; + # }; + # videoDir = "/srv/videos/vdr"; + # }; + + services.tvheadend.enable = true; + # services.antennas.enable = true; + + environment.systemPackages = with pkgs; [ + dtv-scan-tables + dvb-apps + w_scan2 + ]; +} diff --git a/hosts/srxnas00/services/zigbee2mqtt/default.nix b/hosts/srxnas00/services/zigbee2mqtt/default.nix new file mode 100644 index 0000000..1e117f5 --- /dev/null +++ b/hosts/srxnas00/services/zigbee2mqtt/default.nix @@ -0,0 +1,34 @@ +{ + users.users.zigbee2mqtt.extraGroups = [ "dialout" ]; + + services.zigbee2mqtt = { + enable = true; + + settings = { + serial.port = "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0"; + + permit_join = true; + + homeassistant = { + discovery_topic = "homeassistant"; + status_topic = "homeassistant/status"; + }; + + availability = { + active.timeout = 10; + passive.timeout = 1500; + }; + + mqtt = { + server = "mqtt://localhost:1883"; + include_device_information = true; + keepalive = 60; + }; + + advanced = { + output = "json"; + log_level = "info"; + }; + }; + }; +} diff --git a/hosts/srxnas00/storage.nix b/hosts/srxnas00/storage.nix new file mode 100644 index 0000000..6f9a0ac --- /dev/null +++ b/hosts/srxnas00/storage.nix @@ -0,0 +1,187 @@ +{ lib, ... }: +let + disks = { + system = [ "/dev/disk/by-id/nvme-eui.00253855015004a5" ]; + data = [ + "/dev/disk/by-id/wwn-0x5000c50065b38b37" + "/dev/disk/by-id/wwn-0x5000c5007296fdf7" + "/dev/disk/by-id/wwn-0x5000c5007b7125de" + "/dev/disk/by-id/wwn-0x5000c5007b712c7e" + ]; + }; + compression = "zstd"; + rootFsOptions = { + acltype = "posixacl"; + dnodesize = "auto"; + normalization = "formD"; + xattr = "sa"; + relatime = "on"; + canmount = "off"; + mountpoint = "none"; + inherit compression; + "com.sun:auto-snapshot" = "false"; + }; + passwordFile = "/etc/hostname"; + system = lib.genAttrs disks.system + (device: + let + name = builtins.replaceStrings [ "_" ] [ "-" ] (lib.lists.last (builtins.split "/" device)); + in + { + type = "disk"; + inherit name device; + content = { + type = "gpt"; + partitions = { + esp = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + system = { + size = "100%"; + content = { + type = "luks"; + inherit name; + content = { + type = "zfs"; + pool = "system"; + }; + inherit passwordFile; + settings.allowDiscards = true; + }; + }; + }; + }; + }); + raid = lib.genAttrs disks.data + (device: + let + name = builtins.replaceStrings [ "_" ] [ "-" ] (lib.lists.last (builtins.split "/" device)); + in + { + type = "disk"; + inherit name device; + content = { + type = "gpt"; + partitions = { + raid = { + size = "100%"; + content = { + type = "luks"; + inherit name; + content = { + type = "zfs"; + pool = "raid"; + }; + inherit passwordFile; + settings.allowDiscards = true; + }; + }; + }; + }; + }); + default = mountpoint: { + type = "zfs_fs"; + options = { + inherit mountpoint; + }; + inherit mountpoint; + }; + auto_snapshot = mountpoint: { + type = "zfs_fs"; + options = { + inherit mountpoint; + "com.sun:auto-snapshot" = "true"; + }; + inherit mountpoint; + }; + can_not_mount = { + type = "zfs_fs"; + options = { + canmount = "off"; + mountpoint = "none"; + }; + mountpoint = null; + mountOptions = [ ]; + }; +in +{ + disko.devices = { + disk = system // raid; + zpool = { + system = { + type = "zpool"; + options = { + ashift = "12"; + autotrim = "on"; + }; + inherit rootFsOptions; + mountpoint = null; + datasets = { + "reserved" = { + type = "zfs_fs"; + options = { + canmount = "off"; + mountpoint = "none"; + refreservation = "10GiB"; + }; + mountpoint = null; + mountOptions = [ ]; + }; + "nixos" = can_not_mount; + "nixos/etc" = default "/etc"; + "nixos/nix" = default "/nix"; + "user" = can_not_mount; + "user/root" = default "/root"; + "user/home" = auto_snapshot "/home"; + "data" = can_not_mount; + "data/lib" = auto_snapshot "/var/lib"; + "data/log" = default "/var/log"; + "data/cache" = default "/var/cache"; + "data/backup" = default "/var/backup"; + }; + }; + raid = { + type = "zpool"; + mode = "raidz"; + options = { + ashift = "12"; + autotrim = "on"; + }; + inherit rootFsOptions; + mountpoint = null; + datasets = { + "data" = can_not_mount; + "data/backups" = default "/srv/backups"; + "data/home" = auto_snapshot "/srv/home"; + "data/documents" = auto_snapshot "/srv/documents"; + "data/movies" = default "/srv/movies"; + "data/music" = default "/srv/music"; + "data/pictures" = default "/srv/pictures"; + "data/videos" = default "/srv/videos"; + "data/public" = default "/srv/public"; + }; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=1G" + "mode=755" + "noatime" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=1G" ]; + }; + }; + }; +} diff --git a/hosts/srxnas00/storage/nfs/default.nix b/hosts/srxnas00/storage/nfs/default.nix new file mode 100644 index 0000000..6d5cfc7 --- /dev/null +++ b/hosts/srxnas00/storage/nfs/default.nix @@ -0,0 +1,49 @@ +{ config, ... }: +{ + services.nfs.server = { + enable = true; + + statdPort = 4000; + lockdPort = 4001; + mountdPort = 4002; + + exports = '' + /export \ + 10.80.0.0/24(ro,fsid=0,no_subtree_check) \ + 10.50.0.0/23(ro,fsid=0,no_subtree_check) \ + 192.168.178.0/24(ro,fsid=0,no_subtree_check) + + /export/public \ + 10.80.0.0/24(ro,fsid=0,no_subtree_check) \ + 10.50.0.0/23(ro,nohide,insecure,no_subtree_check) \ + 192.168.178.0/24(ro,nohide,insecure,no_subtree_check) + ''; + }; + + networking.firewall = { + allowedTCPPorts = [ + 111 + 2049 + config.services.nfs.server.statdPort + config.services.nfs.server.lockdPort + config.services.nfs.server.mountdPort + ]; + allowedUDPPorts = [ + 111 + 2049 + config.services.nfs.server.statdPort + config.services.nfs.server.lockdPort + config.services.nfs.server.mountdPort + ]; + }; + + fileSystems = { + "/export/public" = { + device = "/srv/public"; + options = [ + "bind" + "X-mount.mkdir" + ]; + }; + }; +} diff --git a/hosts/srxnas00/vpn_mvd.age b/hosts/srxnas00/vpn_mvd.age new file mode 100644 index 0000000..e8c6445 --- /dev/null +++ b/hosts/srxnas00/vpn_mvd.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw EdgPWroD+DMAj0ToTcqIubkUWjLR2D+aFOO5zKmGdDo +0SHG1/7tBzIOaWw4F09jSRNJlLyJd/HEtZQqt3vAgkw +-> ssh-ed25519 JzjriQ V1P5BkpFEDGmIYljW1eZ9TtTCY/SPyFUDXU3a6nyaTU +SBkjuaMnEwxfhw/k9NKsQnzhkHvl2cEFOwnkxHm1U4k +-> ssh-rsa 6hPx7A +NhfmPvHC/IH4m2VPofNfRwDo9MZFgg2CG6Ms90z1pIQADFkdWaKRGsjrNXxijqQ6 +FJVdZFOIm9UDAvSwup1sgHDNzGESgZF6giou/wAUHwasLMGeq6w81ECAC+S2vrhM +oysVqqHau43mynqa/c3AVLsqf+BUJ/36gA7vs4azV8EX91v19KWj9Tw3B7EMsx9i +1xzUc6oA/KCosxSTAv8qbnMF7k5F07O18r5T7ybfJGRQNcJIyhTrcYWiDRfvmTI3 +c6JugKj+SYFbJ69v6Xhbc/XymLjG2DsvH2xlwoJoOfiTNyNnflFqWjtws13AJEyP +Kr1MRbfIoV6inGqFG57AB78TmkdOoHf/sGqr3xOuAOoG6z+DXbvDacfuoLR4/7Fl +NoOQSe9mvytBNEXpU34EUTKoYMGTpa26RD+TWRufjAg24uEBxctAnT4cX0Pz/ocs +4+w+jLP40Z2h7unEbak42v+LQaoFRwOH1bMGQxWsz579Mgt+SlQQoIENYASxEGgF +XaAMpPyRDISFrBeWG85ybYe4Uzp5vvIGoCLDzOguGxSPLtgAwnYzDCU6i3WBrdDp +pHkXyZeGXO53JBKSRPGxxTw8vIWDeQdo9GHngyu/Ni9CNB+yX7AANN/JDv1UfGeV +Io/9nDCYyGLtZazlZ5oMJvr4tT2EsAZi+M9TKYvlC+o +-> ssh-ed25519 ZeuIrQ FnZKjmd7OnN2m4Wp454VEmlMknUrnbDt3H3XiY2c3TI +fGBRRtiQJx14Fhjl5PG4p7dmbuWT0blx5UjjaYqgEt0 +--- r/IdYY+5f/9CBsS14j/COE9eMlqIjajRB3FdJx245sA +ÔQaKeش4J 1b3rfrーcȋˢrV>r \{!EF \ No newline at end of file diff --git a/hosts/srxnas00/vpn_srx.age b/hosts/srxnas00/vpn_srx.age new file mode 100644 index 0000000..fba0e07 --- /dev/null +++ b/hosts/srxnas00/vpn_srx.age @@ -0,0 +1,23 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw Tc1M7fljgqubhq6L4bVVNyzGTFsGUsbEX7iJInRRMCI +73ErEXZOZ5Mdk3TM50B/3bzChNS/Bw7kJCGBiS2qtB4 +-> ssh-ed25519 JzjriQ YxeQ0Irz6PcafUUcyBWNhUhkMrTKnerIp3xy1Ao3ZQs +ZHQn3i0z3MQ5TFGZICTV+ZIv90NMVKkorv+yiAqGGt8 +-> ssh-rsa 6hPx7A +yBuoRBC2/QunJQpwEXQcbPdRSXemOXx+wxOeObxqPn2+Q4W2NEhYV4FSUWe9tt5X +pIzErpqrBfeermbwZahURtmGsMeBayliR15wqn25Wt49stbFWRNvF4eWzec5/RwP +kPB5EZdE3IULOc95E4zrQkaeK59Q1GMP4fmiK9g/KQNiSGl5SkH1vKwEHyNE/1Ki +Ow9TjfXL8oeyCiXz7/IlGI8qSVzPEh+Ejz2n9BTpEOCnISuUT8XfyT01AG84RfgA +VvoQJVYWI1CovZea4wbGoIWDsbUBeRDn0my9MdLWIjq1Mv62Uax9YvmjzZSMWRIK +Z9AACWEs6F+TX69WBWiw1y/V8l6QHQ2IFfc2zWrGMivWAXP5ia4rGLaxS1Z0s+S8 +4JGxjwseQi8doUoOMIU+yxT0XnLAaOUqKjThFSVoFSiyV0udHZy8qZ9Oh3Kh6NSa +TVC2XTQSfcVchNRs+FeedR2t7BQiNmkABmA7lF6dK9gCOlzmpnzKgFLGpNCc9OqI +nE7Lz/FrZoFRZq+XfH0AX0yivDFeqfis4vroA4c8Ls4sWTUtThKhr9VQznkgFl+Q +lRKyDjRlm8pBj0N+kyejNG1hyQZcbEDF1YGAr+gFUK3DTCZ5qmNWVqOHgYLve4Qs +Yz6QPC0BdbV0KjVQBhtFWi3MiDbXmvZc83RKQCv7Zyk +-> ssh-ed25519 ZeuIrQ c8ZUf78mhgLNjzD3kPnyEy1j64gqCUQFJKK2ku8FEw0 +gmE6MS3XPzZc9/jWVjGNKMaPjQm/g5nN8xo+4wzIEKE +--- uD16fyRo5yikgO5E78EPD/h6nSUaMVCZ9JCtuJ+5tjk +2 4 +dV Vr+:j0À`FU Jf _\l5\2=lPJ2_ +n \ No newline at end of file diff --git a/hosts/srxnas01/clevis.age b/hosts/srxnas01/clevis.age new file mode 100644 index 0000000000000000000000000000000000000000..b108f848324e44f045100a2d73490b0f38dbe27f GIT binary patch literal 2465 zcmZA0=U-EY0>*K?RJ8G06s?L>p~a0cdwB&t*&*{}Cl)n1Iaw#k$sPx+TCE@;P_*Kf zI*QhcptV*zgsK#j;b{GUtBL|us8R(*QSbHDebGPQ`F&qKCL4^0J&-@<4LVTI0@QCK zgh@DjR$3rn$HNvfjYeXnIk{f0FOufwW>_)5N5t0&b#FL%e=O8lY$BQL5RPZAP?FKoRpR34WJKPZXNfs5XNXkqel(3>qbxO~f<=uf)y9 zWD1WsYL-i^BnD)5(o|5`8>NeN2Cr8u`M>55n9}HWMU(;HC;^IG6Y{zpu^042EP z;V3|rKfTTejs6uUwAYIL~m<)2i zRzYMnONq%`Q6rlU20WNo8k0Jh?htImd?qSlr}=mU(4_{<6c&Rfl({q^5rPxB1#|&9 zB;ym$j71tme=Z(b0{$j%S^^xK@5~RX+*>jjA${3hmLb= zK`Mk2bwQ_0ABB}(3+%yMLdb$iIeLLy!V`D`78)N`aS>wJE2atMC|wv*M?F*@M6v)1 z9Zq3Z$Am&UMgT2hp#^e)9J!sr6KgR6ruK2UPFSFFtE3?x9dwytjoYdrkkm2E#B<2) zB9D>H!@)A9N1*W;8EixmamaK|9UW9@i8LK(=9mMBp6b#8NLYoLxPVFSp~|Hphz$BA zZYj~Ak;*h`9F?vL35?$EHO!N6L=G*Fh>3+bs}JM_g>JG@&Ly*zVMa72gg}v+C6fta4vQt^a|`%UqtzZ% zGbIe7n`eXVYL850LdB3JY|zMXBC1wNHxN+7t>FgVf_|S%VUuP^^%lKSgK|SWlLCr~ zR8$s>{PQ(Zzg6Oir0H})ot{X-95ET62E*)Fz-bPtXL_Z?=!iT_0{hu z4xSBkojL~x{Lb~&KkDAn%B1JxGq&y`|En~vXQL2SK_m)RPVkCezGZ{cY8B1dxS3;2X8%9 zqx4;y8UMq`Hh(49*|d~XfAdzCX8Nl2V&3Pn_vp*G&+nx@ZttcRe&iTp zk&X}#t~Kvb+`5d!Y_620>fFmOE1i}{(dOZ1<7_>o6j5hyEnh_JWpRf zt*)Tq=j&@$jsCOZV{H9h@<7j`qG=bBXH<=LJUyKk%J)yXHYMpKHfZ||PHst1PojN) zWJ2c8zdpG&Cz<)UV5+64ey}sYB1tsZir>kf-kT?~?nr5TvAS`fY~m>F^P9k!D?_=L z#-4~8mwa@$7T-A1T+mzyLx(!I-qt>hD;-Sui1=b|p*EMlcxH{RWbFy@s+H2|<*mBA zj}FB#DtGE%3n!b-2yf)|`Gn!A`C|^uJ$~T$!>6BYNVxv5+CqEE?x7Zmv}31Y*j3%% z_{`!Pv%g{c5H#3xpWqhdq&H_>8|aSvZTZrcoJ%`KoScpu+B@z_=+c69+kuv%?XQ0R zdRmKCckYj>hs143l$?3KgXx5(ievk|M?S-qPmE`Vp59E|a3OBEzH1nQFPy&B zivJI3A$a~Ue#+*t`rX6KV2?2VJ=_hiu`SdwVqg@%WLJB)yu#Mgl=ov|=7t5z6Emna zNxgpqy<4vCyls#6dr!X?-v6K>Oe(%Z=h`A8+PdeUlu@rgOgdYd+Xp4cpAO_b$T#UW z)gar{k=hu{qS2N$~uAv->NhcWe{(oNs;b*q+ur zKfZf|li0F|e%Fh#+PTLo$VGi)zy9*_I^L}3wjO1D&zl2t zD-K9sb^J!A>exH>ZS4B|-1S}b;;UtE=-+l!RLdm~JO7Am%l+mnez~MPQN29y*#Z6 zRFbYHwHC3HN=)?5k69%<-3lr=Iw_<@s{fddsFNXV$VNq2ncnjAPFs7yof= zb=_aH{;NM)GyBE3L|WgBza~x|-G8QGfs{A?;=%kz&ZD8aJ8OHh_n-M{YJnuVD0M8U zc2eVHetTtI+p~fnY8ZK`x6%`PvlhpTGmtLy^{o8|c}cVTyC#et$L{KA%v*6!zlM18 zUh&qAiZ%F&{Q8pEgi`U@nYQt#m*=jyB+6UWQ=J2~HkAE(PoYoxsd@ZQwY%u?*IIr` OT-jAnQ}W5hAO8nIB^1;E literal 0 HcmV?d00001 diff --git a/hosts/srxnas01/default.nix b/hosts/srxnas01/default.nix new file mode 100644 index 0000000..900740d --- /dev/null +++ b/hosts/srxnas01/default.nix @@ -0,0 +1,46 @@ +{ self, ... }: +{ + imports = [ + self.nixosModules.roles-nas + self.nixosModules.services-security-tang + self.nixosModules.services-virtualisation-microvm + ./hardware.nix + ./storage.nix + ./network/wireguard + ./network/knsupdate + ./services/minidlna + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxnas01"; + domain = "srx.digital"; + hostId = "8656cb50"; + }; + + systemd.network = { + enable = true; + networks."10-uplink" = { + matchConfig.Name = "enp2s0"; + address = [ "10.50.0.10/23" ]; + routes = [ + { routeConfig.Gateway = "10.50.0.1"; } + { routeConfig.Gateway = "fe80::1"; } + ]; + }; + }; + + fileSystems."/mnt/cryptix" = { + device = "aufdie12.lan:/mnt/main/sort"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.device-timeout=5s" + "x-systemd.idle-timeout=60" + "x-systemd.mount-timeout=5s" + ]; + }; +} diff --git a/hosts/srxnas01/dns_update.age b/hosts/srxnas01/dns_update.age new file mode 100644 index 0000000..1d4631a --- /dev/null +++ b/hosts/srxnas01/dns_update.age @@ -0,0 +1,22 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw Yzqy7yM+713dnrLXcfjUhLFMjnQpl95wHJlzIjnQfSE +xIVphrMwhRQkwUXDv+pAkfqc8LIsQ1Ns22QTtKADG+Q +-> ssh-ed25519 JzjriQ k3JUDjOI5Qzelhc4fegecq9OWRdIJpZknIrwtXtQBWM +RsROE/3lcZlEbeBfzAMOyCMu4vChgNr5O1QJcdU9Tko +-> ssh-rsa 6hPx7A +udLGjSbutZOksoH/SwNDRn2tWkNHtnVvDK6V/EAJN4iyg4JkWA59lDt7cmeMHGw6 +hBIs0uqV7MsVCIqVxYpBM8fTnNb3I21JhsHQ0mHjynkc1ncD64UlIKfKslzp5yZL +2+/5I3bK6QO2lujwlnX45MqggU6K0l7C2Z/PmdCJ/nP90CjkIept9XPmdZBHWn+M +sTAsR9C4E0lopbbj2RVu1+Rep+8nATXgaWObh20hnO2By6PRywGBLFVLsscn94HG +TRWRmFAmxeEoqQaksxz12k+YZa82K+1isWAvj3869WmA9aHV74PZtlFhG4ZBEdvv +u9HX9y5ZxTI157m4q/EZGkcXbvPWTueuF9U0e/6zM2K7gJe6nHgArVcoemliDHzT +9w6n/5OKMinT+0XyQElvcqkZMyQtV3Fl8lBEIITuzxfZkBPRmgzAqGCdEJM4pQyI +XWDOGF8F9Ufg0ecDVR7fmBcSjUKYn+DSrlRxkX3TK5XUkVKm0H6yy7P7L9Cgzfr/ +6gPCW6bXa78QQYwfF20MUYlQ3EkpceDjj91NbPexu2YPr00J3bgmscus2r6QZJoc +CvTGQLpDP2bRfTDPFEyCEJQnUmjScmjwu/Nyg14uI8oVFyFG1+VwbQo0sLqAv/AD +NDYBiCybp2NdttMddPRqajN/aba2quWlZJNFDlOWM5g +-> ssh-ed25519 MrfLnw 47sMO7L4n9gmlB9IE4N3L6gcPb6/j/9VHmHDLw6W0iQ ++K+0xVmpm7SAQfkhW3VhbO6dNjSZ+gigbXCaJUKVsSU +--- mIAhV7mEGrObCXLHe+rfdIHOj7f1vM/mFf5KSBwPpuk +d$l +SIP2~g: D2FC9mݰM-c^z}oE.A +Ixw-mRBP<_:A2JۃYx81 \ No newline at end of file diff --git a/hosts/srxnas01/hardware.nix b/hosts/srxnas01/hardware.nix new file mode 100644 index 0000000..4274517 --- /dev/null +++ b/hosts/srxnas01/hardware.nix @@ -0,0 +1,54 @@ +{ inputs, config, modulesPath, ... }: +{ + imports = with inputs; [ + (modulesPath + "/installer/scan/not-detected.nix") + self.nixosModules.hardware + self.nixosModules.hardware-cpu-intel + self.nixosModules.hardware-security-secureboot + self.nixosModules.filesystems-zfs + ]; + + age.secrets.clevis.file = ./clevis.age; + + boot = { + initrd = { + systemd = { + enable = true; + inherit (config.systemd) network; + }; + network = { + enable = true; + ssh = { + enable = true; + authorizedKeys = config.users.users.root.openssh.authorizedKeys.keys; + port = 2222; + hostKeys = [ /etc/ssh/ssh_host_ed25519_key_initrd ]; + }; + }; + availableKernelModules = [ + "ahci" + "nvme" + "sd_mod" + "usb_storage" + "usbhid" + "xhci_pci" + "r8169" + ]; + kernelModules = [ ]; + clevis = { + enable = true; + useTang = true; + devices = { + "nvme-eui.0025385a81b4239b".secretFile = config.age.secrets.clevis.path; + "wwn-0x5000c500d6b1b870".secretFile = config.age.secrets.clevis.path; + }; + }; + }; + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + }; + + powerManagement.cpuFreqGovernor = "powersave"; +} diff --git a/hosts/srxnas01/network/knsupdate/default.nix b/hosts/srxnas01/network/knsupdate/default.nix new file mode 100644 index 0000000..0630e51 --- /dev/null +++ b/hosts/srxnas01/network/knsupdate/default.nix @@ -0,0 +1,16 @@ +{ config, ... }: +{ + age.secrets.knsupdate = { + file = ../../dns_update.age; + owner = config.srx.service.knsupdate.user; + }; + + srx.service.knsupdate = { + enable = true; + zone = "srx.digital"; + server = "dns.vpn.srx.dev"; + ttl = 120; + interval = "*:0/1"; + keyFile = config.age.secrets.knsupdate.path; + }; +} diff --git a/hosts/srxnas01/network/wireguard/default.nix b/hosts/srxnas01/network/wireguard/default.nix new file mode 100644 index 0000000..6a9512d --- /dev/null +++ b/hosts/srxnas01/network/wireguard/default.nix @@ -0,0 +1,36 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" "10.50.0.0/23" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.2/24" ]; + networkConfig.IPForward = true; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxnas01/services/minidlna/default.nix b/hosts/srxnas01/services/minidlna/default.nix new file mode 100644 index 0000000..a925b1a --- /dev/null +++ b/hosts/srxnas01/services/minidlna/default.nix @@ -0,0 +1,23 @@ +{ + users.users.minidlna.extraGroups = [ "users" ]; + + services.minidlna = { + enable = true; + openFirewall = true; + + settings = { + inotify = "yes"; + friendly_name = "srx"; + + media_dir = [ + "V,/srv/movies" + "A,/srv/music" + ]; + + extraConfig = '' + enable_tivo=no + max_connections=50 + ''; + }; + }; +} diff --git a/hosts/srxnas01/services/samba/default.nix b/hosts/srxnas01/services/samba/default.nix new file mode 100644 index 0000000..7129105 --- /dev/null +++ b/hosts/srxnas01/services/samba/default.nix @@ -0,0 +1,97 @@ +{ + services.samba = { + enable = true; + openFirewall = true; + securityType = "user"; + extraConfig = '' + server string = %h + workgroup = srx + netbios name = %h + + logging = systemd + log level = 1 + + load printers = no + + server min protocol = SMB3 + client min protocol = SMB3 + + aio read size = 16384 + aio write size = 16384 + + security = user + map to guest = bad user + guest account = nobody + invalid users = root + force group = users + create mask = 0660 + directory mask = 0770 + ''; + + shares = { + public = { + comment = "public exchange share"; + path = "/srv/public"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "yes"; + }; + + movies = { + comment = "privat movie share"; + path = "/srv/movies"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "yes"; + }; + + music = { + comment = "privat music share"; + path = "/srv/music"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "yes"; + }; + + home = { + comment = "privat home share"; + path = "/srv/home"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + documents = { + comment = "privat document share"; + path = "/srv/documents"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + pictures = { + comment = "privat picture share"; + path = "/srv/pictures"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + videos = { + comment = "privat video share"; + path = "/srv/videos"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + backups = { + comment = "privat samba share."; + path = "/srv/backups"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + }; + }; +} diff --git a/hosts/srxnas01/storage.nix b/hosts/srxnas01/storage.nix new file mode 100644 index 0000000..2ad4491 --- /dev/null +++ b/hosts/srxnas01/storage.nix @@ -0,0 +1,177 @@ +{ lib, ... }: +let + disks = { + system = [ "/dev/disk/by-id/nvme-eui.0025385a81b4239b" ]; + data = [ "/dev/disk/by-id/wwn-0x5000c500d6b1b870" ]; + }; + compression = "zstd"; + rootFsOptions = { + acltype = "posixacl"; + dnodesize = "auto"; + normalization = "formD"; + xattr = "sa"; + relatime = "on"; + canmount = "off"; + mountpoint = "none"; + inherit compression; + "com.sun:auto-snapshot" = "false"; + }; + options = { + ashift = "12"; + autotrim = "on"; + }; + passwordFile = "/etc/hostname"; + system = lib.genAttrs disks.system + (device: + let + name = builtins.replaceStrings [ "_" ] [ "-" ] (lib.lists.last (builtins.split "/" device)); + in + { + type = "disk"; + inherit name device; + content = { + type = "gpt"; + partitions = { + esp = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + system = { + size = "100%"; + content = { + type = "luks"; + inherit name; + content = { + type = "zfs"; + pool = "system"; + }; + inherit passwordFile; + settings.allowDiscards = true; + }; + }; + }; + }; + }); + data = lib.genAttrs disks.data + (device: + let + name = builtins.replaceStrings [ "_" ] [ "-" ] (lib.lists.last (builtins.split "/" device)); + in + { + type = "disk"; + inherit name device; + content = { + type = "gpt"; + partitions = { + data = { + size = "100%"; + content = { + type = "luks"; + inherit name; + content = { + type = "zfs"; + pool = "data"; + }; + inherit passwordFile; + settings.allowDiscards = true; + }; + }; + }; + }; + }); + default = mountpoint: { + type = "zfs_fs"; + options = { + inherit mountpoint; + }; + inherit mountpoint; + }; + auto_snapshot = mountpoint: { + type = "zfs_fs"; + options = { + inherit mountpoint; + "com.sun:auto-snapshot" = "true"; + }; + inherit mountpoint; + }; + can_not_mount = { + type = "zfs_fs"; + options = { + canmount = "off"; + mountpoint = "none"; + }; + mountpoint = null; + mountOptions = [ ]; + }; +in +{ + disko.devices = { + disk = system // data; + zpool = { + system = { + type = "zpool"; + inherit options rootFsOptions; + mountpoint = null; + datasets = { + "reserved" = { + type = "zfs_fs"; + options = { + canmount = "off"; + mountpoint = "none"; + refreservation = "10GiB"; + }; + mountpoint = null; + mountOptions = [ ]; + }; + "nixos" = can_not_mount; + "nixos/etc" = default "/etc"; + "nixos/nix" = default "/nix"; + "user" = can_not_mount; + "user/root" = default "/root"; + "user/home" = auto_snapshot "/home"; + "var" = can_not_mount; + "var/lib" = auto_snapshot "/var/lib"; + "var/log" = default "/var/log"; + "var/cache" = default "/var/cache"; + "var/backup" = default "/var/backup"; + }; + }; + data = { + type = "zpool"; + inherit options rootFsOptions; + mountpoint = null; + datasets = { + "data" = can_not_mount; + "data/backups" = default "/srv/backups"; + "data/home" = auto_snapshot "/srv/home"; + "data/documents" = auto_snapshot "/srv/documents"; + "data/movies" = default "/srv/movies"; + "data/music" = default "/srv/music"; + "data/pictures" = default "/srv/pictures"; + "data/videos" = default "/srv/videos"; + "data/public" = default "/srv/public"; + }; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "size=1G" + "mode=755" + "noatime" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=1G" ]; + }; + }; + }; +} diff --git a/hosts/srxnas01/vpn_srx.age b/hosts/srxnas01/vpn_srx.age new file mode 100644 index 0000000000000000000000000000000000000000..6603d4dc29fb15bd77f12384f1c3da0e99af4922 GIT binary patch literal 1189 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ϙWDzNF zH&{Kc4EK&e0+rw?DPx@BugxQJy0XMA1ZJxfU{BMfapIM%VfT8@FdZWTbygT_iFuOy zD0w~?uGJadQ%t#jUuSH^qNp`CYyW_y}i3bbnxHdfZob$b`4g@r84YbXUIJ<*w1jQ}mRt?DAJQOb_6R}zwtt8l?3zhsFntFbWB7lXhKhOYz!jGx0@{!OdvY;a=4wG&jZ@q9n1F=Un1on_Q^8isuE24_lh6^WYhx(YNDy7 zx;lNkZY!v$fsYdGsh*iBr7#u-IB2{3I)1s6$azE@U$;aIw30=1%oynmI5CWn|ynsOeco=Y`Htk^oXnBAZ>kH2;d2$X?qHkJ@bW7+tp@D zSXlTne=}njtONxy2SQ0^nf}t_Zi>OQat?a0ub9KW^8htghuo&CB*-l1VQOIe5 zF*V*O)I^j@hBcR6V7tH?bV>uq^Y^i%YkNPGB@k+ON-b)&4X&VH_rD3mh@3kvypeKW zF>IJothvDwy(@_)_ctq|gOc&^=$4j-Z+{qiHQH?9S#V#5I|Z0@x&mK~XK~wdYyXe1 z>+4U`LxyHN@(;AdI^B$u=^Jj=MnL1aj|7#eHKXY_>#SZj`tkI(-0q|8rgN6*!JUL| zAb>mglZcd&If>MO6rNV}ur0x#7?UV+s(kQmB!0f%?4o8#G7ygbBH9Erh!9C;pf okXkjxzk>#Y^_co&TXelGPFh5l|1$8JD&w7R7yC#@(RYNpG zQ{{rS3Bb~!m#Dl67sau#i|+rl^P07(v5~B*&&j>9#5sCksf@5GehD&nPx%jL@SgNg z0ici?l-WU9Is5c{6Yi`jqw5JZ&QswZE&9Sw_{k4ft7ZHmGYZ2G-q704+mMMq?+?(8 z5XgevvAc)VYI-ij=W=%CQV11mu%9$VTNj4c)KqiwIU7bMEJYWVF>4}8%N0PO?G6N2`yenE z8guteYH?JpBlJ_FME5MqZJU&=er~Oxk47<9CMI{2d^jFX3EaCnG&%OZQWuI21g6v@ zn=T2nf*%$WoARYqvHr$*H6Q7);`s~U5HRe*f(#fgH9)DAD&(g$a(QqpCFcr3tfw=@ zOk#YM9l~{wD?#9=7{Pl#<4*!1I(j!-5{??Vp`}ywY}tYaudh^jzE5I$TS}j}cght} zlKqM`tibrlFr;8dw3KrJMsBJnoW+I7qImsoZmU zpPp_*!ZvG3`kLf|0Cs>rjp$S(wK`cEFLQF+3mRnX?}w2~gIPSP*IE$ zO6G!<2JM=%Zna+0s8c!kSohI^yxyi;lR-#Bjjl63+%t8S=vAmNDR-Q3!D*6rtodF? z;loEWycutAI)3x0b-C`VX%o1yA>s5oKC5u3Ip1MN5968E9_bzpBatR%%4g4IWKIy^ zpJ%4JMo>pGHuDN`1U5RfiU)`;t-YL`+7o5?hDRCDcDvmuW_=_sCsVryRdlHWl1O literal 0 HcmV?d00001 diff --git a/hosts/srxnb00/services/restic/repo_ssh.age b/hosts/srxnb00/services/restic/repo_ssh.age new file mode 100644 index 0000000000000000000000000000000000000000..3ed6583843eccce2fef679f080feac546ebd3295 GIT binary patch literal 1564 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 Q)vHI(AOHN%Cs_URUwFumSO5S3 literal 0 HcmV?d00001 diff --git a/hosts/srxtab00/default.nix b/hosts/srxtab00/default.nix new file mode 100644 index 0000000..35b792a --- /dev/null +++ b/hosts/srxtab00/default.nix @@ -0,0 +1,17 @@ +{ inputs, ... }: +{ + imports = with inputs; [ + self.nixosModules.roles-workstation + self.nixosModules.services-storage-syncthing + ./hardware.nix + ./services/wireguard.nix + ]; + + system.stateVersion = "23.11"; + + networking = { + hostName = "srxtab00"; + domain = "srx.digital"; + hostId = "81774791"; + }; +} diff --git a/hosts/srxtab00/hardware.nix b/hosts/srxtab00/hardware.nix new file mode 100644 index 0000000..a72a5b7 --- /dev/null +++ b/hosts/srxtab00/hardware.nix @@ -0,0 +1,95 @@ +{ inputs, lib, modulesPath, pkgs, ... }: +{ + imports = with inputs; [ + (modulesPath + "/installer/scan/not-detected.nix") + self.nixosModules.hardware + self.nixosModules.hardware-cpu-intel + self.nixosModules.hardware-gpu-intel + self.nixosModules.hardware-security-secureboot + nixos-hardware.nixosModules.microsoft-surface-go + ]; + + boot = { + initrd = { + availableKernelModules = [ + "nvme" + "rtsx_pci_sdmmc" + "usbhid" + "xhci_pci" + ]; + kernelModules = [ ]; + luks.devices.system = { + device = "/dev/disk/by-uuid/1f66cad5-a9ed-4ca1-b0c2-49436a762ee5"; + allowDiscards = true; + bypassWorkqueues = true; + }; + }; + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + + # use the mainline kernel, since wireplumber segfaults with the nixos-hardware version + kernelPackages = lib.mkForce pkgs.linuxPackages_latest; + }; + + fileSystems = { + "/" = { + device = "none"; + fsType = "tmpfs"; + options = [ + "noatime" + "size=20%" + "mode=755" + ]; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/9A9A-B16F"; + fsType = "vfat"; + }; + + "/nix" = { + device = "/dev/disk/by-uuid/ac0096c0-3e16-4f29-8730-581cff1b0d91"; + fsType = "btrfs"; + options = [ + "noatime" + "discard=async" + "subvol=nix" + ]; + neededForBoot = true; + }; + + "/persist" = { + device = "/dev/disk/by-uuid/ac0096c0-3e16-4f29-8730-581cff1b0d91"; + fsType = "btrfs"; + options = [ + "noatime" + "discard=async" + "subvol=persist" + ]; + neededForBoot = true; + }; + }; + + age.identityPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ]; + + environment.persistence."/persist" = { + files = [ + "/etc/machine-id" + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + directories = [ + "/etc/secureboot" + "/home" + "/etc/NetworkManager" + "/var/log" + "/var/lib" + ]; + }; + + services.thermald.enable = lib.mkForce false; +} diff --git a/hosts/srxtab00/services/wireguard.nix b/hosts/srxtab00/services/wireguard.nix new file mode 100644 index 0000000..f42852c --- /dev/null +++ b/hosts/srxtab00/services/wireguard.nix @@ -0,0 +1,35 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.9/24" ]; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxtab00/vpn_srx.age b/hosts/srxtab00/vpn_srx.age new file mode 100644 index 0000000..57e1721 --- /dev/null +++ b/hosts/srxtab00/vpn_srx.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw lMiJgOtZjQmEA6uHZaj0hOm1c+nEzcluTDY+t0aGwlY +g33NxHReXUJnttwuvwgAssuwR96Qk0IYq0tWYUWbLnY +-> ssh-ed25519 JzjriQ PfLdV9B5wuV6H+vqmAWE73ZQC687izR+3Qx6uytCwTs +mpOYSzUpRlj7TJyKwldjl30xNfWMqDYdPuAyWPXkk5k +-> ssh-rsa 6hPx7A +E0WTEOxtajBGtbHWtfXJtASHvJ/jzP9SDzK6/wQuY18D8dhSwPBBYZW2umcIxHRf +tiZtUR6Xfea85pwvRbrVtG4OgD6VrX5RHDezCpooIUq124emGUuAXLnXsiaK2gU8 +VeENmZMruutCPA1AdjMrlv3Hu/WoCX32ddZdRUdnkbezb8j+wV00CJFcljEogXmq +O8vkHWxLPz+aPepg/VUhPrZ1bgxdxutPh/B5BodC1NAo2IpkTGyvVAPIbxgYPAWO +/JQZmJf1bqCcKyoCig/CggUwBXrK2nFk+ozbUYrJaBivnWIRJXMZDC9RAy+/dlsk +z/941Re6jW7sZdd93T16L1Wy8OnSo9yaaNB2FvxZC3lx0lU76S/Rf4Z4lRpLsPdX +pyvGQLBHAC5z39paTp7IdRBWePi7TU+ZD8EaBDZDK6WVsJf2CayXA0zm9Hbws7ha +1im2a9tLY5y/hm60ElKqT8J6Vd2Ord4XdFl/EBzaGXKVm4wpjq2nZFOXJpfiLs9L +hvwo9h4ixovAORNcos4HexlWYvUmMJt2jIfKQf3+5cOiK5+2dxGh2uDGDvBY6/G1 +tpx2VoZrkOarinUYx+aroAsNKZWQ74wNPzk5TFMKQQJ5n7BrfXpB4d84E19D+Ytg +WrJ3I/aGtkjd7N0OWaUnBDGKtIjwtQELvCBIVesxhZo +-> ssh-ed25519 xkaJLw pAC7AHHNlB6fESC3kXRvb/D+ZBXQrTLBpXsnX01xqzg +7Oe0RTbzF2WA5yQmbb8DfjPN4UVi8E2ZKmuzrXevZNM +--- tQ29HZq8ATniDoqMqoEznzo//PJdGeM5ra3JaW1nHRg +'S+\hqِ^<DnOz5@C Ҡ/6 Mq繊Զֿ\RLX \ No newline at end of file diff --git a/hosts/srxws00/default.nix b/hosts/srxws00/default.nix new file mode 100644 index 0000000..bd70866 --- /dev/null +++ b/hosts/srxws00/default.nix @@ -0,0 +1,25 @@ +{ inputs, ... }: +{ + imports = with inputs; [ + self.nixosModules.roles-workstation + self.nixosModules.filesystems-zfs + self.nixosModules.services-storage-syncthing + ./hardware.nix + ./storage.nix + ./services/wireguard.nix + ./services/nfs.nix + ]; + + system.stateVersion = "24.05"; + + networking = { + hostName = "srxws00"; + domain = "srx.digital"; + hostId = "9222a8ae"; + + interfaces = { + eno1.wakeOnLan.enable = true; + eno2.wakeOnLan.enable = true; + }; + }; +} diff --git a/hosts/srxws00/hardware.nix b/hosts/srxws00/hardware.nix new file mode 100644 index 0000000..0dcb856 --- /dev/null +++ b/hosts/srxws00/hardware.nix @@ -0,0 +1,33 @@ +{ inputs, config, modulesPath, ... }: +{ + imports = with inputs; [ + (modulesPath + "/installer/scan/not-detected.nix") + self.nixosModules.hardware + self.nixosModules.hardware-cpu-intel + self.nixosModules.hardware-gpu-amd + self.nixosModules.hardware-security-secureboot + nixos-hardware.nixosModules.supermicro-x10sll-f + ]; + + boot = { + initrd = { + availableKernelModules = [ + "ahci" + "ehci_pci" + "nvme" + "usb_storage" + "usbhid" + "xhci_pci" + ]; + kernelModules = [ ]; + systemd = { + enable = true; + inherit (config.systemd) network; + }; + }; + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; + }; + }; +} diff --git a/hosts/srxws00/services/nfs.nix b/hosts/srxws00/services/nfs.nix new file mode 100644 index 0000000..6b34594 --- /dev/null +++ b/hosts/srxws00/services/nfs.nix @@ -0,0 +1,69 @@ +{ + fileSystems = { + "/mnt/home" = { + device = "srxnas01.op.hq.hh.srx.dev:/export/mnt"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.idle-timeout=600" + ]; + }; + + "/mnt/backup" = { + device = "srxnas01.op.hq.hh.srx.dev:/export/backup"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.idle-timeout=600" + ]; + }; + + "/mnt/pictures" = { + device = "srxnas01.op.hq.hh.srx.dev:/export/pictures"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.idle-timeout=600" + ]; + }; + + "/mnt/music" = { + device = "srxnas01.op.hq.hh.srx.dev:/export/music"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.idle-timeout=600" + ]; + }; + + "/mnt/videos" = { + device = "srxnas01.op.hq.hh.srx.dev:/export/videos"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.idle-timeout=600" + ]; + }; + + "/mnt/movies" = { + device = "srxnas01.op.hq.hh.srx.dev:/export/movies"; + fsType = "nfs"; + options = [ + "noauto" + "X-mount.mkdir" + "x-systemd.automount" + "x-systemd.idle-timeout=600" + ]; + }; + }; +} diff --git a/hosts/srxws00/services/wireguard.nix b/hosts/srxws00/services/wireguard.nix new file mode 100644 index 0000000..0c8142a --- /dev/null +++ b/hosts/srxws00/services/wireguard.nix @@ -0,0 +1,35 @@ +{ config, ... }: +{ + age.secrets.vpnSrx = { + file = ../vpn_srx.age; + owner = "systemd-network"; + }; + + systemd.network = { + netdevs."50-vpn_srx" = { + netdevConfig = { + Kind = "wireguard"; + Name = "vpn_srx"; + MTUBytes = "1300"; + }; + wireguardConfig = { + PrivateKeyFile = config.age.secrets.vpnSrx.path; + ListenPort = 51820; + }; + wireguardPeers = [{ + wireguardPeerConfig = { + PublicKey = "MPvns6jFwZPJvzZtxEDIMSIBBBtBQKBWQ8us3Wgj0mc="; + AllowedIPs = [ "10.80.0.0/24" ]; + Endpoint = "65.108.77.254:51820"; + }; + }]; + }; + + networks."vpn_srx" = { + matchConfig.Name = "vpn_srx"; + address = [ "10.80.0.3/24" ]; + }; + }; + + networking.firewall.trustedInterfaces = [ "vpn_srx" ]; +} diff --git a/hosts/srxws00/storage.nix b/hosts/srxws00/storage.nix new file mode 100644 index 0000000..d5b2b08 --- /dev/null +++ b/hosts/srxws00/storage.nix @@ -0,0 +1,98 @@ +{ lib, ... }: +let + disks = [ "/dev/disk/by-id/nvme-SKHynix_HFS001TDE9X081N_ADA6N43261050645J" ]; +in +{ + disko.devices = { + disk = lib.genAttrs disks (device: { + name = lib.last (lib.splitString "/" device); + inherit device; + content = { + type = "gpt"; + partitions = { + ESP = { + label = "EFI"; + name = "ESP"; + type = "EF00"; + start = "1MiB"; + end = "512MiB"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + SYSTEM = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + passwordFile = "/etc/hostname"; + settings.allowDiscards = true; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/nix" = { + mountpoint = "/nix"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/var" = { + mountpoint = "/var"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/etc" = { + mountpoint = "/etc"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/root" = { + mountpoint = "/root"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + "/home" = { + mountpoint = "/home"; + mountOptions = [ + "compress=zstd" + "discard=async" + "noatime" + ]; + }; + }; + }; + }; + }; + }; + }; + }); + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "size=1G" + "mode=755" + "noatime" + ]; + }; + "/tmp" = { + fsType = "tmpfs"; + mountOptions = [ "size=1G" ]; + }; + }; + }; +} diff --git a/hosts/srxws00/vpn_srx.age b/hosts/srxws00/vpn_srx.age new file mode 100644 index 0000000000000000000000000000000000000000..9959a0a8c3df6b325b30422e738e4d9dd1530b3c GIT binary patch literal 1189 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 ssh-ed25519 jDpDqw vj8zX+whDpCdCSVJgnSJZskUur3XRdyZezBXVfbnNW4 +zqAcqrop8ztrdvv9k41zcZpSfGwiKSOZZ/h55csKLLU +-> ssh-ed25519 JzjriQ 0fXTMwdHnjNEDN1QzBjqc2avm30r9nkcB5BkW+yiqk0 +tsEEmW0dtYlFUszS1/SYVg6Z2AUCxR7lglQQgkqCLUc +-> ssh-rsa 6hPx7A +M7mRYs2IU3IQpw5D5d59Vymjtx7BbUxG3ia5MS9Naxy0XvsvJuF+aWHaG6eofkwT +fMhYA11v3tAjmnMLg5Yeflp407iiYUE4IFS9tjJF6Vf9t48JDomlSSbmBaLdxFID +IznYr5TYnLX7cqg2k938pYQiwUkgXPlqXWfo0mZQl6eWgwicNJoV9RSAK+xeB0v5 +gh63v/lC45eJRax46ECZCUS1fiGjzrojzcgpFVfHwoXNxtp84Yo5LH9PjB2F5zUA +JrJo2l8oU5UfXr/ff4IRb9PFhJiuyrP2034kHYEFhC1y0QDMFVyYF8oLm9MCgaFK +IFSAHj5EeuQQ+gamUSmkdg5DIc2JtpMXAXQjHUsDmphKer4J1TmAl7QU0tVgswzQ +Fc/2a2j+xXGPIJv4Q8U/h4WDWi8O5RMxFsdbiVgTsYTlOWkGPbJY1+9mJCAE1IWB +wXiWQIjs+HRgjKkFvzlc+f9kr7ea/AkMj3Es1gpmNzYD2E65HkRIvWUOE2RAcLzD +xR+fNNB4rTnkByD51xqT+36uhDxB6dLmmvvHKh/4Cs32l3SvmnMvClI4JpteXdHY +mT90KDOPfgXK+yhXrnogOXIr0pkohBoP/zznfW5wOCbFvLEZgSPi+xnwN0uz+6gr +OVtsKoUh0JWuAcFI4wxRyW8nMTcW8N4T1fusEh/arSg +-> ssh-ed25519 Sk9VBA SzsxaOsMJnWoEYIL35fOjblvOdhQl6qvoZqfpnJyQTg +RX5DQpeJTviFFkZM6MT1OYCNRJqPZ+Hx44PBAMFUzQs +--- BVCT5FBu5kipw4jhqwiHsSMea+bO3tumrXBOnC2UWQM +XZD뇓ջ= XYG7)J7yo}p,P2) rϤR#%/dev/null 2>&1 || ${lib.getExe pkgs.vault} login -method=oidc + '' + else + ""; + in + { tofuCommand + , tufoConfig ? defaultTFConfig + , subdir ? defaultSubDir + , backend ? defaultBackend + , + }: + { + type = "app"; + program = toString (pkgs.writers.writeBash tofuCommand '' + pushd ${toString subdir} >/dev/null + ${vaultLogin} + if [[ -e config.tf.json ]]; then rm -f config.tf.json; fi + cp ${tufoConfig} config.tf.json \ + && ${lib.getExe opentofu} init ${if backend then "-upgrade" else "-backend=false"} \ + && ${lib.getExe opentofu} ${toString tofuCommand} $@ + popd >/dev/null + ''); + }; + + tf-validate = { + type = "app"; + program = toString (pkgs.writers.writeBash "tf-validate" '' + pushd ${toString subdir} >/dev/null + cp ${tufoConfig} config.tf.json \ + && ${lib.getExe opentofu} version \ + && ${lib.getExe opentofu} init -backend=false \ + && ${lib.getExe opentofu} validate \ + && ${lib.getExe opentofu} test \ + && ${pkgs.tfsec}/bin/tfsec --config-file ${tfsecConfig} \ + && ${pkgs.tflint}/bin/tflint + popd >/dev/null + ''); + }; + + tf2nix = { + type = "app"; + program = toString (pkgs.writers.writeBash "tf2nix" '' + HCL=$(realpath $@) + pushd ${toString subdir} >/dev/null + ${lib.getExe pkgs.hcl2json} $HCL > output.json + ${self.packages.${system}.json2nix}/bin/json2nix output.json + popd >/dev/null + ''); + }; + + tf-state = pkgs.runCommand "tf-state" { } '' + mkdir -p $out \ + && cp ${tufoConfig} config.tf.json \ + && cp ${tfsecConfig} tfsec.json \ + && ${lib.getExe opentofu} init -backend=false \ + && ${lib.getExe opentofu} version -json > terraform.json \ + && ${lib.getExe opentofu} validate \ + && ${pkgs.tfsec}/bin/tfsec --config-file ${tfsecConfig} \ + && ${pkgs.tflint}/bin/tflint \ + && cp tfsec.json terraform.json .terraform.lock.hcl $out + ''; + + mkApps = + commands: prefixMapper (genAttrs commands (tofuCommand: mkTofuApp { inherit tofuCommand; })); +} diff --git a/modules/custom/dns/knot/acls.nix b/modules/custom/dns/knot/acls.nix new file mode 100644 index 0000000..8420256 --- /dev/null +++ b/modules/custom/dns/knot/acls.nix @@ -0,0 +1,53 @@ +{ + services.knot.settings.acl = { + notify.action = "notify"; + + transfer = { + action = "transfer"; + address = [ + "10.80.0.5" # srxgp01 + "10.80.0.6" # srxgp02 + ]; + }; + + update = { + action = "update"; + address = [ + "10.80.0.0/24" + "127.0.0.1" + "::1/128" + ]; + key = "update"; + }; + + update_k8s = { + action = "update"; + address = [ + "10.80.0.0/24" + "127.0.0.1" + "::1/128" + ]; + key = "update_k8s"; + }; + + update_terraform_swendel = { + action = "update"; + address = [ + "10.80.0.0/24" + "127.0.0.1" + "::1/128" + ]; + key = "update_terraform_swendel"; + }; + + update_terraform_cicd = { + action = "update"; + address = [ + "10.80.0.0/24" + "127.0.0.1" + "::1/128" + ]; + key = "update_terraform_cicd"; + }; + }; +} diff --git a/modules/custom/dns/knot/default.nix b/modules/custom/dns/knot/default.nix new file mode 100644 index 0000000..3c2ce36 --- /dev/null +++ b/modules/custom/dns/knot/default.nix @@ -0,0 +1,15 @@ +{ self, ... }: +{ + imports = [ + self.nixosModules.services-dns-knot + self.nixosModules.custom-dns-zones + + ./secrets + ./acls.nix + ./policies.nix + ./remotes.nix + ./submission.nix + ./templates.nix + ./zones.nix + ]; +} diff --git a/modules/custom/dns/knot/policies.nix b/modules/custom/dns/knot/policies.nix new file mode 100644 index 0000000..3f9d567 --- /dev/null +++ b/modules/custom/dns/knot/policies.nix @@ -0,0 +1,23 @@ +{ + services.knot.settings.policy = { + denic_13 = { + keystore = "default"; + signing-threads = 4; + algorithm = "ecdsap256sha256"; + ksk-submission = "denic"; + ksk-lifetime = "365d"; + zsk-lifetime = "30d"; + propagation-delay = "1d"; + }; + + denic_13_test = { + keystore = "default"; + signing-threads = 4; + algorithm = "ecdsap256sha256"; + ksk-submission = "denic"; + ksk-lifetime = "14d"; + zsk-lifetime = "3d"; + propagation-delay = "1d"; + }; + }; +} diff --git a/modules/custom/dns/knot/remotes.nix b/modules/custom/dns/knot/remotes.nix new file mode 100644 index 0000000..9cd95e6 --- /dev/null +++ b/modules/custom/dns/knot/remotes.nix @@ -0,0 +1,73 @@ +{ + services.knot.settings.remote = { + srxgp00 = { + address = [ "10.80.0.1@853" ]; + cert-key = "EPap376f5O3gAIt36SaTceDgyE90GaANE9YCcjSRUbA="; + quic = true; + }; + + srxgp01 = { + address = [ "10.80.0.5@853" ]; + cert-key = "DFloXBI1hyI/aTGSEc+3ZjoeVz7a7Vi5AeP5ouKaByI="; + quic = true; + }; + + srxgp02 = { + address = [ "10.80.0.6@853" ]; + cert-key = "oq6Ig/gcTr7VCn7gQQjuMN2txkVZIJ58iSvrisxKE20="; + quic = true; + }; + + # denic + a_nic_de.address = [ + "194.0.0.53" + "2001:678:2::53" + ]; + f_nic_de.address = [ + "81.91.164.5" + "2a02:568:0:2::53" + ]; + l_de_net.address = [ + "77.67.63.105" + "2001:668:1f:11::105" + ]; + n_de_net.address = [ + "194.146.107.6" + "2001:67c:1011:1::53" + ]; + s_de_net.address = [ + "195.243.137.26" + "2003:8:14::53" + ]; + z_nic_de.address = [ + "194.246.96.1" + "2a02:568:fe02::de" + ]; + + # digital + v0n0_nic_digital.address = [ + "65.22.20.36" + "2a01:8840:16::36" + ]; + v0n1_nic_digital.address = [ + "65.22.21.36" + "2a01:8840:17::36" + ]; + v0n2_nic_digital.address = [ + "65.22.22.36" + "2a01:8840:18::36" + ]; + v0n3_nic_digital.address = [ + "161.232.10.36" + "2a01:8840:f4::36" + ]; + v2n0_nic_digital.address = [ + "65.22.23.36" + "2a01:8840:19::36" + ]; + v2n1_nic_digital.address = [ + "161.232.11.36" + "2a01:8840:f5::36" + ]; + }; +} diff --git a/modules/custom/dns/knot/secrets/default.nix b/modules/custom/dns/knot/secrets/default.nix new file mode 100644 index 0000000..89d238b --- /dev/null +++ b/modules/custom/dns/knot/secrets/default.nix @@ -0,0 +1,49 @@ +{ config, ... }: +{ + age.secrets = { + knot_key_xfr = { + file = ./tsig_xfr.age; + owner = "knot"; + }; + + knot_key_transfer = { + file = ./transfer.age; + owner = "knot"; + }; + + knot_key_notify = { + file = ./notify.age; + owner = "knot"; + }; + + knot_key_update = { + file = ./update.age; + owner = "knot"; + }; + + knot_key_update_k8s = { + file = ./update_k8s.age; + owner = "knot"; + }; + + knot_key_update_terraform_swendel = { + file = ./update_terraform_swendel.age; + owner = "knot"; + }; + + knot_key_update_terraform_cicd = { + file = ./update_terraform_cicd.age; + owner = "knot"; + }; + }; + + services.knot.keyFiles = [ + config.age.secrets.knot_key_xfr.path + config.age.secrets.knot_key_transfer.path + config.age.secrets.knot_key_notify.path + config.age.secrets.knot_key_update.path + config.age.secrets.knot_key_update_k8s.path + config.age.secrets.knot_key_update_terraform_swendel.path + config.age.secrets.knot_key_update_terraform_cicd.path + ]; +} diff --git a/modules/custom/dns/knot/secrets/notify.age b/modules/custom/dns/knot/secrets/notify.age new file mode 100644 index 0000000000000000000000000000000000000000..9d05ac4bf8b5773cce731e5f810142a469e1e5a3 GIT binary patch literal 1482 zcmZA1Iq35Q7{~EfM18~-RFLq0b2Ud1gtWPu=5Et85r;Hab2dlQq;U~MTtwtW zL0%CAbr8i-K}B9c5PU@kanVIY2T@Qw76tKLUI+IFKFjm{xlwQy6kdHQ5AnV@zpo?c zhyZ7gjGAV57WgQRBa>0WluXr)(rI173tmCn7#9_3x2z8I#1P2kzUG^#+-GSksWslB zDFxJZpYmg`n(3_>S(AMu9^H;2L9;f?zMulR_lbDyaML#Wza|bz9qXeC!%n+pjB7`h zT3$GPU-q=1QObTxb&6X|LF=me$dnhzZjA2(ca@^qk zg7b%pryV)5a&lh-g3weDl5^eJ)=VVF$5#V(LeMWHgwva+H;eWmVkvc12HGJ zCb6Ih#|*^QYY0$geAC3d5+Z8Y`*|Si`WOZE3>}2+l;1%cIs`d=F{b9|Zi!~|AyAf1 zDbP+^TPt}`fz%Bn#trh4sL5G|&klNC6LNowjMR0+1%ijm0(WHll>4i2yXMW6ubz05 zwP$HJWl{@3j`405Tk}>5m<*h|xiDvwno~jnblXO5+KH)25JAcn;moD53t~|RF~|Zf zv#2nq1W=_zQkQNmmxWfUi4*8*h)uZbauHO!y^5b0HHY0~SHNB|DD)~5r;^4?$6`(N zO&|fQsF@@L78ASqDvN8=HC(P-pI|lKsCjII49;{$zwnjADUw((lJZmTwg;pJx5~*{ zCIDR^0SQt>*yS|~G2%i_R&rLjyr6bl${T2@YT$(pwh2b&nRehQu!StSq0?2T$-D@d zMcmV^8LR{zRr+=%D7sDLt?!B3mPy-1Z5h&)8(HrE`{S#PGU1hsqfv?N7weT%h;bg} z41r>*=9DfPLdc<%V88Mcv1N66yX#p%q9xYfiQ_%EnHI+8AO*QH-Ega9X)`{hA&HTrKsuY;zbZ;2Rs}$c_T5dF$Gw(GW1{G@C4*Zk8qD0oxNR z3kOR*E-_^2yPb6?K*mp5BbHrn-c}lCkjH>E(_sI9&DEf()s3*R5jGBuK+HHnlmluO z&LUqTDcyt%+nl0R?022GrqC&lP@}%3r_dIH8=cr$B);XslR-A zOA6opgVWr|Uw_-{uYLRRJ&^s>m)3J5=hlnAUH{$t+jq`A^v%s*{B55bwF1&Z~1$pvL z{Kk{wrQ(T4U-|1L;nmOoeEHnzcIn!$jbGo|UM6o#e*cMh`rUgU|K$EB9=vew*^j>e E7as2QasU7T literal 0 HcmV?d00001 diff --git a/modules/custom/dns/knot/secrets/transfer.age b/modules/custom/dns/knot/secrets/transfer.age new file mode 100644 index 0000000000000000000000000000000000000000..00824737a54b66b41883975f431b6c01129e22e0 GIT binary patch literal 1484 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 ssh-ed25519 jDpDqw Q1229okMaQ7BBD8jW+trkE/531nZpPDm4gdEsi4HnnQ +f2V+08IAE4JCtdH7DZwuL0Qz3x6VyV/+NMYQbQrS4UA +-> ssh-ed25519 JzjriQ F44IX1AnOijWQvSIvNF+x31iKPRydUcGpN2+3WE4j1M +yZOfRden8DElpHIp/KQRlBe/M3SKti5E1k0chTpph9s +-> ssh-rsa 6hPx7A +rdClA1QsmF4XbN1c9riIOyXlQ+037DPk/NHUUsTKPmUUf79fsd7xy0ysAOgyMmFF +876OPD78ADNE0b0LHCs40WW+gzjMafRWZ4UOZJuPxf00VD4+Gpa7rzJ7DoEgub9C +lvbVbwgqU453q1qSheFdZudO06W1HccobEbHA5IbScDNQZUhGEcHpKs2+8J6VlO3 +gb6FyTU2cEU/oT+/fQxNjxqk1u7sVQp2jJ7f216zlcDWJ48yqdZwHi7w16mZyowy +dlWw5mdTqmZGgPEBDf8Bleewgh2MuDeodsLfzWPibwYKMJGd1AeidTzcUmIvQnW4 +dabhLXn3Hhy+GXV/ENrtly7oNgj50EdWWh3esRXJG8kZPBAZYvf9Aya+Uy/UyyfU +q5OSNBSJ6ML2Dor7vCWw1ZE0vLbXY/ikGuScGUVb26G2LhwjtT3d7Voc3Zda6iTs +2uraU5r9q0YFwvqIRDq3UYLM8uvxf1xBodf83JOpr2VNyLmIJuubKXGDm3mk4Vn4 +0Nu8X6/A01wTlsXUJeKPHL3Q9WM0NOOsPC1Ks5l57OIymLfob4Dq1uOCvCUdJFRm +iYj2a8mf9TnR32fAkV9LDPM9TIsFXIS/tpA0AIRe5FgQ07JhGhuRhAzi4Kf2Lswa +RBHQuZcrSMZ89zqMPSfE3FCQvBbysq0OikgmufJv3Bs +-> ssh-ed25519 Dfencg KDa5YlsXrSBJPs/hpGpsYfMr6sKhK4aZigUwDd/Wp3Y +IyWUtpbC1WUrfSgYUt+EMmScAsz9Z0jCl4oE9N/UCEc +-> ssh-ed25519 OWgoVA rUeWC6dgBvHQaMlk45u/0TyGi0JlQ+qZSDFfHZYSijE +Jc+YAfBn1xm2kAIzlb+u0Fta1G2T+F8VBlUjararGWU +-> ssh-ed25519 aP/BWw 4NIQEGBA05hGP8liXq3DP1XU50T0GUVvFlGQu4l7aD4 +7pgd/qKlWRw489to8Y9VdFp4pGpWQexrvadyEqhD7ms +--- IkR9E4EZw5kUePnJK2+xALsjdvfknKW4NTUoUqulewg +)mS5Z#[i rcct.C˒: cAAÃ.ʨ鳨&-v*R5Խ "kځq QB +,#&']qx276A}m@, QkW9 Sf҂` \ No newline at end of file diff --git a/modules/custom/dns/knot/secrets/update_terraform_cicd.age b/modules/custom/dns/knot/secrets/update_terraform_cicd.age new file mode 100644 index 0000000..4531674 --- /dev/null +++ b/modules/custom/dns/knot/secrets/update_terraform_cicd.age @@ -0,0 +1,26 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw MeB3IYguHb/KbEx1Tzli1uq2gOJVkrwCvrid6TUeWGA +x9PIk2zvGNwFm+DybuhFUo7ZRhF6geyASAd9Nxo/Miw +-> ssh-ed25519 JzjriQ MLV2mPDbStlt4YrNmv9UtSDtmK7L4wR7M2IuEakVLGU +fxh7dgU0Cu0ZTER8b24M0iv7wKeVdVE7CGqNF7Igobg +-> ssh-rsa 6hPx7A +Btd0qiGDyGyYX+UxXUfEd5voTplxZ/tqi/yfF2+Ss23DVeWWLk3TnNfiMR15eTUG +elAqDU5/MghPdqXEnTwzAoksb8w2yonzOHunSQu3hYUyvWaDvCMfGgJ9WP/zSsmv +Loe7jSwv8qcXEB4QvhvIBSjqU7s2Orms4Py0Xe9NihLsmwF+or65gOt6TBsn9t9W +Dzmc7ASFZj5Vb7ryNIgw9CCWyd7trRzCIRoE8znQqxdTJwY4kFbTFlKWyAXZ3KsP +dxmlClWS7eYM5Zd2a4b9V2CsDzY8pIM6QL827eHRVyqCg7xf3AoCJZvpo09iZyHR +pjlYE0sXM/i2suRk/aWliGih5/XJQhK1C0RNQpK305RicGj4vP5fkfXGMlpWV8UU +B/ozQMQFsgfsxPzgR2j3BfYWrvZC45WbB2pgUqNRDsqiSJEvSaI+7ezqZLYw9IGu +/G8AVbZLaAdm22OFlxOKwFcs6FtGure3gPGb39KW3IAqhesd0SpgV1GvnarSzXko +x4Qh7A1uKfIPY+IfZ0EgA1EpdWwrmUBtuTsJPrQymfAKUNcHgkFGfQPgpkHiacsY +9XG9FqaCWr+3qCWOy65nbVqB9h2ORCq2IXcfnfnRZFej9kAPDXpeuYFuipO4Gaay +iQS57uPezLRuoajhVplpshr95Zr5ZVcd/gFa2isTtXI +-> ssh-ed25519 Dfencg fRy4KqmTrjv7JifXnkKS5SHpXGHMhs27qd1iFnBmj2I +NeAZnwqOZKK571SNGXPSrdVAfTyoWn4BgZ/qUfXm1aQ +-> ssh-ed25519 OWgoVA XK0qU4kOq8kYcBXWJuLBH+K/X3B0Y2xklaYEBY1waFA +GgSmjDNW6OIE3kk4D6ooleQRywtqNED0Rm4Brnx5UZ0 +-> ssh-ed25519 aP/BWw AdbhT0YxEvb2yZ0tQxDbIHSfYFEGG83GOLtokjukV0c +BC/qk2xiXMcLb1oB3OqBcnhD6DP0yCtrqIfUvDzVWTI +--- ck1Jx0o4PwGn0bWgEy+9SfkHcHAlsz+6nPZsnKwwGNM +ՍV0{MZmҜ@U8`-_MPPW$/29L jp.w`kyi?`.zI +E%?"ڧ 2C@H4ssDC @~O9 SU/ee[JЮ  \ No newline at end of file diff --git a/modules/custom/dns/knot/secrets/update_terraform_swendel.age b/modules/custom/dns/knot/secrets/update_terraform_swendel.age new file mode 100644 index 0000000000000000000000000000000000000000..a35ad19f4a00a2af2e6c2e12a3f4f912016c7cb2 GIT binary patch literal 1506 zcmZXU%j??&0LKLnO2C77@GuV*MTGu-CQX}1Rg@%6+BD6pdDl~#SDPkjUQL=HqBjL6 zdQyBIWDFbwPb#Q*n96*Ou}#o}`csB(7eN_bcFJx!xv^ zZ1VuDdcffmouXJBdM=D0yen!7A1R*S%<1jkZKhtL8fOe-19B^ai)P*rf-VvM%9l{Rg|d@Xm{)PZ;b znu5w^m=BhVrbecmGwy;)v1||uFk(-AP2*Eg$z#K;+5{6e(+Uo1Rl<$wDv7cs9l4 z3=vv~q#X={SA47GN?1+$Vxs{5Y@?}xm*Eyy)F8d>SKf+G1+sxXec{jOp-b+f+H}WD z2xj*!#y5`d&&p+`_qRs3*98Ph0`p=;w>y-CBU1B}h8lz3&S5AyYdB8J;|y13Q8A}P zw~f+fYq6SMn+8&ZMU=omMuoQt$H;Iy91(>Ydj1*cKlD$=TS&=zu> z1+cFcsse7D9fZ>Q9#|pn7B>uQ1~KxO*wSsuKvIQIVv0)3NNDYyC)8Aet~Yh4m$F|P ziaoJdb2o~OQRq$q9W>R(MfW?{We9MB_d}stg-|z|+Q@>yyYrd6k4j=b$CfZY$NMe; ztL{FfJ^zNxz?}f>!ZUWsdO|@}kxkgXQ-_Mc?g&!PRXt?3XI%YZ-@*TsB|H^x-29$h*le>TCodkYdGkZkYPn~=VL_| zHbs(2DAJG(5D$ozkK^2KO!6g$Qie#(vwh33Cd|qa*Y*-~&M26}iy-LYyxRICzAjKE zE&HiAKmq{Tp$1xDaWro%VuY6KqJ`BcX{y#+MGZ5pg~@ujlxF0Ty}9F?jgI^q83&!j zmz}P=qa#Q$n|d&y`=+L?TD|XKp1PUHtT!!owWYWb4}{?yl_gE}_S%kDIV1KVmxbjV zg&AWLTHS&zXF@g1YnHf`CK|z3Cpv)*3wsNvVsj%;LuQm_JvS7y6!Gbq?$;Qe3scc! z8xqohRc0^Q(3%DY$pr`$STSbM$F)c-w#ErFy_cj#@HMMCJ| zL%B@oxgKXBS&w38MCfgy#!T*sdEVorA%p{Pi8qD9$>134E}eBk+cD;so-uHc#;_Sy zz$aF)%=&zV1BZu)op1u9Nod1WAvj$a>av!+hL_@E8Z~|NE&| z?>qP5qc1)nUAp7qZ%5BwxpMVq=JR{5U;gE^e_cBDy7|V(N56k6zH&5-Q+_QI|&<1Y>i$~x2@+5Hft0y0PcR}&PtJhARK6v?~FYdhS+$o9t z;b8dF+kZZP;? ssh-ed25519 jDpDqw X/76giRMWT5Bei/ene17F9o5ySZmnsJzp8VIEK3yymM +zEGfvQ5E1j39VFKbUzGSVaWdvM2ePTjAix+ZCoCWF3g +-> ssh-ed25519 JzjriQ fRVhe4wHUkDLQ/Fv9TEZEQoeuAUwalMgt7Xr5mCCg3Q +6DjFk13o/fjra2uFerEQJGqMDWp089V51015D9N08Po +-> ssh-rsa 6hPx7A +hbahzcyBc+7y7epHqhWHK+JEGaY52DBwMD0FBtb5F0PGSst1ulrTFpdra0UnKmEi +WJ7gWJQIchVDTByTb/VRRKe+Rk02AunpcUg2WJmpJ+xMns4fWVEd/2fYWoiWONgB +VNv00tvJsaAMBGmbmtGWv5jcI6OvlGFyNN47VnrJH6ya1cnEtsKiljCMm0W6+dfE +8O/aT5PVobVJCc4XEzweyrGH1znxvMWtyY1+EDZLwBaGQysO/hh+0ePP42qvYloD +6kRC/YYsMrbJyMqAnMC3hg8t7qKZM0nxIAtNGqMF7rxaNvMx1DgP9u9hoANKNZB3 +dGrgUVoYK2rsQmuGzwD/11M+ihJI/kK1apZW3UC3K5eDdmB7n98RlrhbVjhUZIDz +lYCPBqxOAtbA/zswnnIXvOmOwI+XE0LXY/jHBafpV8lXDAfzgHLbroBv8vokoidY +CtyNVphDH4v6eIEip20gtR9r2MDvNloL7V4PLxjyzt/+KV7hCpvPh/1GkciVYSms +STythFlFAQy5JI2RJUWuRQbDcrMYtVzodBA63f8Boj2kjkdZkMN0PTbYzSy/3LKw +b8ILMVC8L+W7d8tDAH5PPu0CBviSPY1RID9Jy9CsCNIXf+AKeJW3oxoWhv45wqy3 +fK1SgnMFUZKsIB9vbt8tMWqkBeSz2gvqLBPB/LVBFvA +-> ssh-ed25519 IK8+2Q pPqhFm0vVBIONpCZjuTNtWtZpFEwyA2SZh0MqzKPiFA +nDDGOFxW8jZ2Sd01kEN4SmFO7ie41aZR1uF70u8xPKQ +-> ssh-ed25519 SiDnLw CzYEihGdqLSzyE1a2XmnBrRwsvOxr1/DeJllPe7AXz4 +LIioBqrzVBw+viLjqdJx2JhG7wyFHoSw9sO1QR1lhHg +-> ssh-ed25519 Dfencg XsIvCMuZZ0kIds5nFrfFU/oN3C3Qj2+if2ETg+kkZFM +QZUECi7Ecn4GF4qTEw4SfAXTLdHUcMugIPZUFXl2zDQ +-> ssh-ed25519 OWgoVA SPC5dN82Skmlz/WGzHK7pG4jd9eJWHjEz+vuj9wZQHU +0Zv6QJov+R2EG1EOmN0m3c2QdaHqaFDE2YXOraPnZ5o +-> ssh-ed25519 aP/BWw t4xZomtfnEHuWNIkcTo7werR2TTuvfrbCSHXG0u5zmk +eZ5Tvvi6TKsg0UddHRhcoux9RlIjx9BVNdcz/6BLUhg +-> ssh-ed25519 v+/Ozg XyO362OVP+cIzJpcVNBExNZiV8V5rmkEj0Y4W2R6bXE +lYqrxXFF0mlXdTMReRYOoyef3Dr51vGTx8qBNWFDTIk +-> ssh-ed25519 5VC2zg mRUyKzgANYYz6gVQ8v/awn5PjkwJQP1qTRHlU8gmXDE +wmujtn+WijbXl8iu0uKHqqvRrkBRj5FnU1sZM+nd414 +-> ssh-ed25519 ZeuIrQ sApBrVKZ0yuILVwixKUNld4clCyLqUjVTNrg8Byb6G8 +CBgAMocNTvVqSRgBZ09yobavIsES9k8iLQ6NZeHuaNw +-> ssh-ed25519 MrfLnw bu2Lt/vS7vpNvAhSxDNErihHyFOSiV+zab/rDYtxjTs +DIhxoqCjIAo4eCcfhFwkCvWCophVs8fxZ0DSghStK5E +-> ssh-ed25519 TVW7ow nYGRe/cqWDQWwT1gGvu8PSXseT77WMcLI/VloHEAGzA +5SW+hiir3uWSbuBXbxdf5+SAFWGdhl/bYxcLcFpMjc8 +-> ssh-ed25519 xkaJLw Wz0a5l4oFX5tcxJiimdUcJfnZy7mj0znr5Jb9GOD8iE +OVEyjj8Ve9JrHWjQzJQ9d2IwWRR9qRF7ollbCmHQ5+Y +-> ssh-ed25519 al5mZw JOKOXNvEyxE/jG3LmjHIN4xYsJXr3xDoRhOb3A4bSk0 +43enBdIg0v4BJS75uZWTb7yH8WseW19CZDUa8wE/uNY +-> ssh-ed25519 Sk9VBA HvU0s8e/lNulRYMjW3nEiCuUk+whT4sFkQdKWXMrS3I +GYUAkwq7yL7zqcu3ekY/lw8WxB7ZiX2Y5vKkGZHZKsY +--- 0krOWry1XDLPkGSeWrS31d+kd8Z5u86bcQ2bs1vg8Zg +>8jCK&ۑZnt/aԚ;$xh.${>Q@#O*/,[&Ç)w*1V(HN,ZK +}M27VsBX7ڤ;k+aȀM*ˋ +ǠMA5(@ꗿ:CDhFv^Gs ](,E"zΉr( |h'~i \ No newline at end of file diff --git a/modules/roles/server/default.nix b/modules/roles/server/default.nix new file mode 100644 index 0000000..dc1fa81 --- /dev/null +++ b/modules/roles/server/default.nix @@ -0,0 +1,45 @@ +{ inputs, self, lib, hostType, config, ... }: +{ + imports = with inputs; [ + srvos.nixosModules.server + self.nixosModules.roles-core + self.nixosModules.services-monitoring + ]; + + age.secrets.acmeUpdate.file = ./acme.age; + + nix = lib.optionalAttrs (hostType == "nixos") { + optimise.dates = [ "05:30" ]; + }; + + programs.msmtp = { + enable = true; + setSendmail = lib.mkIf config.services.postfix.enable false; + defaults.aliases = "/etc/aliases"; + accounts = { + default = { + auth = false; + host = "mail.vpn.srx.dev"; + from = "no-reply@srx.digital"; + }; + }; + }; + + environment.etc.aliases = { + text = '' + root: hostmaster@srx.digital + ''; + mode = "0644"; + }; + + security.acme = { + acceptTerms = true; + defaults = { + keyType = "ec384"; + email = "echo8@srx.dev"; + dnsProvider = "rfc2136"; + credentialsFile = config.age.secrets.acmeUpdate.path; + webroot = null; + }; + }; +} diff --git a/modules/roles/workstation/default.nix b/modules/roles/workstation/default.nix new file mode 100644 index 0000000..2f13b01 --- /dev/null +++ b/modules/roles/workstation/default.nix @@ -0,0 +1,19 @@ +{ self, pkgs, ... }: +{ + imports = [ + self.nixosModules.roles-desktop + self.nixosModules.hardware-security-yubikey + # self.nixosModules.hardware-security-nitrokey + self.nixosModules.services-container-podman + self.nixosModules.services-virtualisation-libvirt + self.nixosModules.services-virtualisation-microvm + ]; + + programs = { + wireshark = { + enable = true; + package = pkgs.wireshark; + }; + kdeconnect.enable = true; + }; +} diff --git a/modules/services/container/default.nix b/modules/services/container/default.nix new file mode 100644 index 0000000..4ab6cf8 --- /dev/null +++ b/modules/services/container/default.nix @@ -0,0 +1,16 @@ +{ pkgs, ... }: +{ + virtualisation = { + containers = { + enable = true; + registries.search = [ + "docker.io" + "quay.io" + "code.srx.digital" + ]; + + ociSeccompBpfHook.enable = true; + containersConf.settings.engine.helper_binaries_dir = [ "${pkgs.netavark}/bin" ]; + }; + }; +} diff --git a/modules/services/container/docker.nix b/modules/services/container/docker.nix new file mode 100644 index 0000000..ef16da1 --- /dev/null +++ b/modules/services/container/docker.nix @@ -0,0 +1,20 @@ +{ lib, config, ... }: +{ + imports = [ ./default.nix ]; + + virtualisation = { + oci-containers.backend = "docker"; + + docker = { + enable = true; + storageDriver = config.virtualisation.containers.storage.settings.storage.driver; + autoPrune.enable = true; + }; + }; + + services.telegraf.extraConfig.inputs.docker = lib.mkIf config.services.telegraf.enable { }; + + users.users.telegraf = lib.mkIf config.services.telegraf.enable { + extraGroups = lib.optionals config.virtualisation.docker.enable [ "docker" ]; + }; +} diff --git a/modules/services/container/k3s/default.nix b/modules/services/container/k3s/default.nix new file mode 100644 index 0000000..2e26d5c --- /dev/null +++ b/modules/services/container/k3s/default.nix @@ -0,0 +1,123 @@ +{ lib, pkgs, config, inputs, ... }: +let + inherit (inputs) kubenix; + k3s-reset-node = pkgs.writeShellScriptBin "k3s-reset-node" '' + read -p "Are you sure? This will purge all k3s data: " -n 1 -r; echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + set +e + systemctl stop containerd.service k3s.service 2>/dev/null + systemctl kill containerd.service k3s.service 2>/dev/null + find /sys/fs/cgroup/systemd/system.slice/containerd.service* /sys/fs/cgroup/kubepods* -name cgroup.procs -print0 | xargs -0 -r cat | xargs -r kill -9 2>/dev/null + mount | awk '/\/var\/lib\/kubelet|\/run\/netns|\/run\/containerd/ {print $3}' | xargs -r umount 2>/dev/null + for ID in $(zfs list -r rpool/data/containerd | grep rpool/data/containerd/ | awk '{print $1}'); do zfs destroy -R $ID; done 2>/dev/null + rm -rf /run/containerd /etc/rancher /var/lib/cni /var/lib/containerd /var/lib/kubelet /var/lib/rancher 2>/dev/null + set -e + systemctl start containerd.service k3s.service + fi + ''; +in +{ + age.secrets = { + k8s_cluster_token.file = ./k8s_cluster_token.age; + k8s_environment.file = ./k8s_environment.age; + k8s_dns_update_rfc2136.file = ./k8s_dns_update_rfc2136.age; + k8s_traefik_dashboard.file = ./k8s_traefik_dashboard.age; + }; + + environment = { + systemPackages = with pkgs; [ + k3s + k3s-reset-node + ]; + + shellAliases = { + k = "${pkgs.k3s}/bin/k3s kubectl"; + kubectl = "${pkgs.k3s}/bin/k3s kubectl"; + }; + + etc."kubenix.yaml".source = + (kubenix.evalModules.${pkgs.hostPlatform.system} { + module = + { kubenix, ... }: + { + imports = [ kubenix.modules.k8s ]; + kubernetes = { + version = "1.26"; + resources = { + namespaces = { + "traefik" = { }; + "cert-manager" = { }; + "external-dns" = { }; + }; + secrets = { + traefik-dashboard-auth-secret = { + metadata.namespace = "traefik"; + data.users = "ref+file://${config.age.secrets.k8s_traefik_dashboard.path}"; + }; + dns-rfc2136-key-cert-manager = { + metadata.namespace = "cert-manager"; + stringData.password = "ref+file://${config.age.secrets.k8s_dns_update_rfc2136.path}"; + }; + dns-rfc2136-key-external-dns = { + metadata.namespace = "external-dns"; + stringData.password = "ref+file://${config.age.secrets.k8s_dns_update_rfc2136.path}"; + }; + }; + }; + }; + }; + }).config.kubernetes.resultYAML; + }; + + virtualisation.containerd = { + enable = lib.mkIf config.services.k3s.enable true; + settings = + let + fullCNIPlugins = pkgs.buildEnv { + name = "full-cni"; + paths = with pkgs; [ + cni-plugins + cni-plugin-flannel + ]; + }; + in + { + plugins."io.containerd.grpc.v1.cri".cni = { + bin_dir = "${fullCNIPlugins}/bin"; + conf_dir = "/var/lib/rancher/k3s/agent/etc/cni/net.d/"; + }; + }; + }; + + services.k3s = { + package = pkgs.k3s_1_29; + clusterInit = lib.mkIf (config.services.k3s.role == "server") true; + tokenFile = config.age.secrets.k8s_cluster_token.path; + environmentFile = config.age.secrets.k8s_environment.path; + }; + + systemd.services.k3s.path = with pkgs; [ + openiscsi + nfs-utils + ipset + ]; + + system.activationScripts.kubenix.text = '' + cat /etc/kubenix.yaml | ${pkgs.vals}/bin/vals eval > /var/lib/rancher/k3s/server/manifests/kubenix.yaml + ''; + + boot.kernel.sysctl = { + "net.core.rmem_max" = 2500000; + }; + + networking.firewall = { + allowedTCPPorts = [ + 80 + 443 + ]; + allowedUDPPorts = [ + 80 + 443 + ]; + }; +} diff --git a/modules/services/container/k3s/k8s_cluster_token.age b/modules/services/container/k3s/k8s_cluster_token.age new file mode 100644 index 0000000..bd2b84f --- /dev/null +++ b/modules/services/container/k3s/k8s_cluster_token.age @@ -0,0 +1,21 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw i0MtK0mAm0I6gig+7PsGsfe359YXhuKRoOnAn31W5Bs +9IcUM1N48YXgbYaPX6W48QfvmarUdjaOWynkUOmpIe4 +-> ssh-ed25519 JzjriQ +aZGSlPBlZJcMqc3lQZcEEmjOdcymOtkbDonEieGvnQ +hirQkN9Sj4YUpUahKOVkJ+cvb7mu85Hei4VBYQu3lMM +-> ssh-rsa 6hPx7A +Ryd3f+kT9TovF/EsM5PKfFJoSJAgSmt2zdYHkn+wMV7P6rlc26hsIcF5N2QnzuZl +YnMOZQBqX+r2Wr73l/Co08/2GxpKQVMo/1sJps1tBYMMEdViXXWIYpPpjJiSQkEK +4pa6+iahqtv0eOG4BAzw1iVRPLH030oLOBLHXFTuMa6Z4nbbokXMfH0WPVmyMNfx +B2NNd9BVr5IumWUdFo4/H7vbqVI3+9l5X5PEA4RQY3HStXzVzKN3byyCMymG4IJJ +u99DTSQLttWwMzQeaZpQTz5AaFdrOv7/ZxF3c5x9glhHIeuFHwDvEAT55Wj13uoy +F4lhEMwnHOh0nNClafOZvxUDn+T7/BQj8eHsZrDEVNOaBJ7+SxYS4BaGxLuDIwuR +DKoDYGq5cGYqo3kwKKX/JrYvVF/dS8J7fWAwYE4QeT9BNbPzhf4ikmMGnIOKEu4y +ZaQNu1MgfF4TkquS2cUDHr5GFJ1cUG9kh+fnluS0XA7UB2hJp1GJlDaGtNXtUeza +y2FRO28IS6HsNyXgU0/jUBck0iLK4SVlnHqbAkVFVe3ieMSfCs8ItvR4gHtACMlp +tfY/lM6ndoGuP3h5TeyHIzeLh2GAGEheagHKkWrq5Y9H5ey7DhUvM8hQLnSPoxfi +M2W82r+qr/MzBCVPZwESdBm/N+X5iRK7ARGkb7Tvx80 +-> ssh-ed25519 v+/Ozg Owz68lZizxg/Pwm8hJkP64A/w0PIcMV4GK73HTiVTRE +aK+CqTK4k6a9RPixSVRhvjxvlJX0lrJ8zySr8Bzbz8k +--- v9J7DptW6p5Je46ZYX7K44JsxcMB7BsEmhUi8E6gU4Y +f-T鼩!4iPZBeBܡ@D'J=w \ No newline at end of file diff --git a/modules/services/container/k3s/k8s_dns_update_rfc2136.age b/modules/services/container/k3s/k8s_dns_update_rfc2136.age new file mode 100644 index 0000000000000000000000000000000000000000..fe099d65344005a95b843d46d474c60dc473645f GIT binary patch literal 1233 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 literal 0 HcmV?d00001 diff --git a/modules/services/container/podman.nix b/modules/services/container/podman.nix new file mode 100644 index 0000000..25af1b5 --- /dev/null +++ b/modules/services/container/podman.nix @@ -0,0 +1,20 @@ +{ pkgs, config, lib, ... }: +{ + imports = [ ./default.nix ]; + + virtualisation = { + oci-containers.backend = "podman"; + + podman = { + enable = true; + autoPrune.enable = true; + + dockerCompat = true; + dockerSocket.enable = true; + + extraPackages = with pkgs; [ zfs passt ]; + }; + }; + + users.users.telegraf = lib.mkIf config.services.telegraf.enable { extraGroups = [ "podman" ]; }; +} diff --git a/modules/services/database/mysql.nix b/modules/services/database/mysql.nix new file mode 100644 index 0000000..c1871c4 --- /dev/null +++ b/modules/services/database/mysql.nix @@ -0,0 +1,28 @@ +{ lib, config, ... }: +{ + services = { + mysql = { + enable = true; + settings = { + mysqld = { + plugin-load-add = [ + "server_audit" + "ed25519=auth_ed25519" + ]; + }; + + mysqldump = { + quick = true; + max_allowed_packet = "16M"; + }; + }; + }; + + mysqlBackup.enable = lib.mkIf config.services.mysql.enable true; + + telegraf.extraConfig.inputs.mysql = lib.mkIf config.services.telegraf.enable { + servers = [ "tcp(127.0.0.1:3306)/" ]; + metric_version = 2; + }; + }; +} diff --git a/modules/services/database/postgresql.nix b/modules/services/database/postgresql.nix new file mode 100644 index 0000000..23032d3 --- /dev/null +++ b/modules/services/database/postgresql.nix @@ -0,0 +1,37 @@ +{ lib, pkgs, config, ... }: +{ + services = { + postgresql = { + enable = true; + enableTCPIP = true; + package = pkgs.postgresql_14; + settings = { + logging_collector = true; + log_connections = true; + log_disconnections = true; + }; + }; + + postgresqlBackup = { + enable = true; + backupAll = true; + compression = "zstd"; + }; + + prometheus = { + exporters.postgres.enable = true; + scrapeConfigs = [ + { + job_name = "postgresql"; + static_configs = [ + { targets = [ "localhost:${toString config.services.prometheus.exporters.postgres.port}" ]; } + ]; + } + ]; + }; + + telegraf.extraConfig.inputs.postgresql = lib.mkIf config.services.telegraf.enable { }; + }; + + users.users.telegraf = lib.mkIf config.services.telegraf.enable { extraGroups = [ "postgres" ]; }; +} diff --git a/modules/services/dns/avahi.nix b/modules/services/dns/avahi.nix new file mode 100644 index 0000000..23bc370 --- /dev/null +++ b/modules/services/dns/avahi.nix @@ -0,0 +1,14 @@ +{ + services.avahi = { + enable = true; + ipv4 = true; + ipv6 = true; + nssmdns4 = true; + nssmdns6 = true; + publish = { + enable = true; + userServices = true; + workstation = true; + }; + }; +} diff --git a/modules/services/dns/default.nix b/modules/services/dns/default.nix new file mode 100644 index 0000000..7487948 --- /dev/null +++ b/modules/services/dns/default.nix @@ -0,0 +1,47 @@ +{ pkgs, lib, inputs, config, ... }: + +with lib; +with inputs; + +let + cfg = config.srx.service.dns; + + identity = "${config.services.knot.settings.server.identity}."; + primary = config.srx.service.dns.defaults.SOA.nameServer; + + writeZoneFile = zone: records: pkgs.writeText "${zone}.zone" ( + dns.lib.toString zone records + ); + + knotZones = lib.attrsets.mapAttrs + (zone: records: { + file = lib.mkIf (identity == primary) (writeZoneFile zone records); + template = lib.mkIf (identity != primary) "slave"; + }) + cfg.zones; +in +{ + options.srx.service.dns = { + zones = mkOption { + type = types.attrs; + default = { }; + description = ""; + }; + + defaults = mkOption { + type = types.attrs; + default = { }; + description = ""; + }; + + mergeHosts = mkOption { + type = types.bool; + default = true; + description = ""; + }; + }; + + config = { + services.knot.settings.zone = lib.mkIf config.services.knot.enable knotZones; + }; +} diff --git a/modules/services/dns/knot/default.nix b/modules/services/dns/knot/default.nix new file mode 100644 index 0000000..0f85469 --- /dev/null +++ b/modules/services/dns/knot/default.nix @@ -0,0 +1,30 @@ +{ + imports = [ + ./modules.nix + ./monitoring.nix + ./system.nix + ]; + + services.knot = { + enable = true; + + settings = { + server = { + listen = [ "0.0.0.0@53" "::@53" ]; + listen-quic = [ "0.0.0.0@853" ]; + tcp-reuseport = true; + tcp-fastopen = true; + }; + + log.syslog.any = "info"; + + database = { + journal-db = "/var/lib/knot/journal"; + kasp-db = "/var/lib/knot/kasp"; + timer-db = "/var/lib/knot/timer"; + }; + + keystore.default.backend = "pem"; + }; + }; +} diff --git a/modules/services/dns/knot/modules.nix b/modules/services/dns/knot/modules.nix new file mode 100644 index 0000000..df2a067 --- /dev/null +++ b/modules/services/dns/knot/modules.nix @@ -0,0 +1,29 @@ +{ + services.knot.settings = { + mod-rrl.default = { + rate-limit = 512; + slip = 2; + }; + + mod-cookies.default = { + secret-lifetime = "30h"; + badcookie-slip = 3; + }; + + mod-stats.all = { + server-operation = true; + edns-presence = true; + flag-presence = true; + query-size = true; + query-type = true; + request-protocol = true; + request-bytes = true; + request-edns-option = true; + reply-size = true; + reply-nodata = true; + response-code = true; + response-bytes = true; + response-edns-option = true; + }; + }; +} diff --git a/modules/services/dns/knot/monitoring.nix b/modules/services/dns/knot/monitoring.nix new file mode 100644 index 0000000..152ecd3 --- /dev/null +++ b/modules/services/dns/knot/monitoring.nix @@ -0,0 +1,38 @@ +{ lib, config, ... }: +{ + services.prometheus = { + exporters = { + knot.enable = true; + + dnssec = { + enable = true; + configuration.records = lib.attrsets.mapAttrsToList + (zone: _: { + inherit zone; + record = "@"; + type = "SOA"; + }) + config.srx.service.dns.zones; + }; + }; + + scrapeConfigs = [ + { + job_name = "knot"; + static_configs = [{ + targets = lib.lists.forEach config.srx.service.dns.defaults.NS ( + host: toString host + ":${toString config.services.prometheus.exporters.knot.port}" + ); + }]; + } + { + job_name = "dnssec"; + static_configs = [{ + targets = lib.lists.forEach config.srx.service.dns.defaults.NS ( + host: toString host + ":${toString config.services.prometheus.exporters.dnssec.port}" + ); + }]; + } + ]; + }; +} diff --git a/modules/services/dns/knot/secrets/notify.age b/modules/services/dns/knot/secrets/notify.age new file mode 100644 index 0000000..15a6f9b --- /dev/null +++ b/modules/services/dns/knot/secrets/notify.age @@ -0,0 +1,26 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw LalGl43X63KHU3u5YttzpM50W+OYCYUzKmlA0DcUYyw +2IEm+ynbpZUjtZn++6Pec1AujVvXZLmz3qv93buUV5M +-> ssh-ed25519 JzjriQ hmEu3Z8VFX7FMyRououBFcXb3hfIJTcI1bp0IcZKKUI +Sm6bx5GqMtL8FE4IyTUPEZJ/hD1yZtCzSSqVWN1RRSw +-> ssh-rsa 6hPx7A +rN5fraYhNXxCAw1k9LjrfS+GwCZxJLMVpGKb8WvXY2GcH8iqkifAcr9OLOHjA8SX +tJTuiiP++jpm4gnOLIKr7JF3Zf7KEaTMAzMPmlqmCMlhsetR2xsI4lX0CEmskqNd +Y/HyFLxA8/033QfSTMrMtwb2HnTDTui1hxyk78mMZK1WfmH7mBTW981dO0Eu3Xzw +Rp/Mr/Q6j6ALvv/RIAmAaS4XPFudzgRF3+LdQ7sIbolL4Qs4TmLs2pJZUgtbi9uj +hNyO+CMEsjGTimsk3P0XArNgTBwSsLoWe3kqrOEI6Qq1nTCaZrAZSdLHlyPIiKsJ +OFOw+PmdKPhJwZ7hdC8q7NLxQt9323nDG5s1HlzSNLYSLPJO8RBNW2tC0UJHLR0A +HaDmjJbrpGWnr2FZEHRTppzzAFHQRLNYufpauGLizfquyJ3JnvuBm0XMN0D7Dv4y +ozYf0r/ul8y7ce054j+B+9U2R9u1TGF2kYi3VtA+tKiamIrJZoyTYhKtp95JyDHq +RZcCeLAHxCWpkPoGFRZc2M3lc0rml4WgZQWvPm2sZt4aPZ2oxWselcBBvafwFJbV +bG6cfrqtrkAvfz05F6fJkNqYrlwzD4Sbs7smmq1PHAdVa3/sCqx1NWKQjsrxbL4U +DauI7+dBDCTU5Ti6jDxdKLU3ZeFy+0rS8qAbUt8v9i0 +-> ssh-ed25519 Dfencg lRmg947fjO2+6jQk7dfUnFCEmLQL8fpZk+NKyCK0vlw +H3+IQlxiC1qtvUdCZN7G3SMPKSeEveKOR6EEaAkgzYY +-> ssh-ed25519 OWgoVA 6EkpFgTdjTp8r4xkdRiDyL1IT3Xi71EFaQ+B/5eYumU +AiEzhEXzMRKG78stZxhvzw43JdHvVH0iez7RVWL5fi8 +-> ssh-ed25519 aP/BWw Jfgvos/ToJnlRXxrw1HJqVK96yFdul08m/urWIybzxY +IUFcGvwu+Haa3czjtA5bmn9JR4J7UH2zWCWJIeEuhV8 +--- IuNh2It+4aP21cuhFNy0u/Cr78ZkWzeSeGo5W2hLvi8 +0k5 QW vdRQG* ;.;3]:L\i.|ΤI/! +L$=X#J +;3m)44˕^#)Ƌ'X3HnTcvZ \ No newline at end of file diff --git a/modules/services/dns/knot/secrets/transfer.age b/modules/services/dns/knot/secrets/transfer.age new file mode 100644 index 0000000..7e84d9c --- /dev/null +++ b/modules/services/dns/knot/secrets/transfer.age @@ -0,0 +1,25 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw ZvaQoA2+Kx/Cmhh2v5X8HuZdDR8J+kl3RoxIUW5Ob3Y +5li2vxm7Bo9kAz8X+GGvkzfnG3LezaOQSIWkeP35mmM +-> ssh-ed25519 JzjriQ TXpjguPNNLkMNvoYLjmuBn2ebNi95y2p+ajXvE68BWY +TGRPfwMamNsdX8g0LMn8jDVQmH0faz5iaJwSBquV8So +-> ssh-rsa 6hPx7A +AEQfpzGm/5ehJgGLfG6W5d1ejyGG/+lPt3msIxPP8+nalIqxSXYDRroEt1yvVy9H +BqhHggbHSluOaFBwco+oSGwz5+WWOqkt8X7QpOgKr/e8Su4Uw977YsKbrpozY6Sv +OI3ae8Y1tIvRu4t7zGYGKPAximuMoJQZZU7BODox5JwXPrn8i9qxL7/04ZmChVdv +gXDwidVjCKBn8GhTLMeMDfeOxZmnT2ISVgwxQwCagZObZjJvoAaK5YKReJ9MXMYz +lKMc3x//mvh/zNOxMsAOgcgejGfXrZ5V4nQ0AYo93Auk+8wCl+o55w08bypD0g0n +8XbbGRBhMbqUliV6K+dECeEgedpwelI/sGuVRztihr48gUTaepHYskHjR5zmtFU+ +vDIqL+sagpXYHAA5jKQFOO06UoOI/564MAGg2RDqBy3oO2PhrIf5Wx7Bc55gRa/V +iuBTM0Z1CFk/xAQcyuCvT4l3PPwQw0nRhjdUVy5iPWk4acPZ8eypMXfpYApSTEo+ +FYnV97Oy6NCokg4ab4zOzGywP763fveoBDzim5d7mSypRMQCNvHghkt0B4DFj1++ ++WTIQCH81nm1uRaq3kLrGC3uweyFLLzAi/s4uzJ64OQIWz6l2CwZGLRpvSbOZOTR +fHU+3sLE5m8bdzpGmUU03sIVMT8I6DEWqO+hKY6WZ0g +-> ssh-ed25519 Dfencg h38X7a6k0ekakfrLqFnwPfsFR8OqhJiLZVyvmuLXGTw +3mWIWVV2Qn4sSlWoJY5P9K6KKS9DmdwTv5GJLQxIm9Q +-> ssh-ed25519 OWgoVA lbL/exL/ISUxxcyhRn+UYBecgCmYd0kacaYaqWaniUk +LEWaRQUrxaheMZ84+DaIT8+SSbRvvInG+uFgy6MHUMc +-> ssh-ed25519 aP/BWw T152dvP4OVYfpmBmL1fVp3qWSa6H+9H696CIFEh/zQI +EMek0YWld7Tt0Q7VJhCfGMZV4rj09hRQL1Ub1mnFpcI +--- 2A2PrD2AOi/L8xjLJ1aCSDn0IqP2XOuXe9h9n5jWC+I +.x?ˀC!Pcu$M o"zFb߆4@t;$L`8B@cgԡWbYz0Xcc^i^~$1%HJs4a-bX'G7v 0/)4o[?xȋ \ No newline at end of file diff --git a/modules/services/dns/knot/secrets/tsig_xfr.age b/modules/services/dns/knot/secrets/tsig_xfr.age new file mode 100644 index 0000000000000000000000000000000000000000..907a923c9f37ed3254feb628cdf44a518daacf21 GIT binary patch literal 1637 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 literal 0 HcmV?d00001 diff --git a/modules/services/dns/knot/secrets/update_terraform_swendel.age b/modules/services/dns/knot/secrets/update_terraform_swendel.age new file mode 100644 index 0000000000000000000000000000000000000000..a322afee42b9e36cce049d25bbc8b721b7cb904c GIT binary patch literal 1506 zcmZY9$?Nol0mgB8#pO*=q+-Q`bPlDo3_r7HW)OwRB$;HA%w(I%BBI%o$-Ye{Ln*W` zUFe~$hf=7A)>mk~C}=NlRow7UmxCgT2Y2xxh=@W31<}iUv46qm@_ZjV^w0dp=0rbJ%3*pyCOi#XCdhfyb_+G-H$Z|u#!;HUdJzzfQz;o@a!6*j|*T4EFIAi}2Z z+bVlRTz0*po%GNVx_Mcv8+$}V(s42e-~pFJo#1j`TuxdBp%xvvDH3}*+splGIE2_Z zM;5#Fv8%#fY{X1)>J4UxVRPET(Dnoz2n(M{jUa2wgymAWL?A^4b;Bpu__|>HzA$!} z8yF>`&Ij4d$PC-7r=l~dt%D8@4^VR#9n3*B={@JM5bs)($h55JG}f2&A*d{=#XLON zY2zb@nQIiA9`_i!_Z{A3PLq%aNKgh#Az-x)vPmL5)~SMDO1-s6T&IwHsallKw&VMk!RO)J5HR;$O@Ex2t zg>l-I(R8&Cqs(xC)1dbPzY3^Blv7}XQ`3Y%qHTgh*jPb0G}Y-6MGJn&O2(1MTC2?f zR*?k-%07am8-QcTO)O)RE?9!#gzTtDQJrYjZ(Y-9_He=Sc&3xOj~&zsiqzOx z)4N>l(y(`c#U$tu16dIB7 zVM02aiwY1qkgAoWP$SEBXJ|oU>ocIs-c4KG7d+>#xzZt zXwu27kkYJ+Eq)t8Su*zo5-F^(H#9ic2%QNFVA6uqnOO8qEDtO)UB)1$PWTXZ(Y=li%&``1~htU475r?u&#QUU}rgUvIhl z{LLTz{`D(~+wQ*b-k(0c@T*TAV9vd8-NWD9f7cb4{?WX5?nn1NR$p_!|FfGud}n&& zQ-8ev(x3nRzu$cG)VY^$zc|F#)(^f!uD|}^=~piP<<;{D_G|yD$N$iqz*pz5|L3jm uJ|?^|`^9G$Uqb2s-0<;DPk#8E{``yW&tLxH@XY%^{q&93zr5q2|9%T{5eWPM literal 0 HcmV?d00001 diff --git a/modules/services/dns/knot/system.nix b/modules/services/dns/knot/system.nix new file mode 100644 index 0000000..e2843bf --- /dev/null +++ b/modules/services/dns/knot/system.nix @@ -0,0 +1,26 @@ +{ + networking.firewall = { + allowedTCPPorts = [ 53 853 ]; + allowedUDPPorts = [ 53 853 ]; + }; + + boot.kernel.sysctl = + let + socket_bufsize = 1048576; + busy_latency = 0; + backlog = 40000; + optmem_max = 20480; + in + { + "net.ipv4.tcp_fastopen" = 3; + "net.ipv4.tcp_tw_reuse" = 1; + "net.core.wmem_max" = socket_bufsize; + "net.core.wmem_default" = socket_bufsize; + "net.core.rmem_max" = socket_bufsize; + "net.core.rmem_default" = socket_bufsize; + "net.core.busy_read" = busy_latency; + "net.core.busy_poll" = busy_latency; + "net.core.netdev_max_backlog" = backlog; + "net.core.optmem_max" = optmem_max; + }; +} diff --git a/modules/services/dns/knot/zones/srx.digital.nix b/modules/services/dns/knot/zones/srx.digital.nix new file mode 100644 index 0000000..5ac3713 --- /dev/null +++ b/modules/services/dns/knot/zones/srx.digital.nix @@ -0,0 +1,139 @@ +{ dns, ... }: +with dns.lib.combinators; +{ + SOA = { + nameServer = "ns1.srx.dev."; + adminEmail = "hostmaster_ao5aeF@srx.digital"; + serial = 1981080812; + refresh = 6 * 60 * 60; + retry = 60 * 60; + }; + + NS = [ + "ns1.srx.dev." + "ns2.srx.dev." + "ns3.srx.dev." + ]; + + MX = [ (mx.mx 10 "mail") ]; + + TXT = [ (with spf; strict [ "mx" ]) ]; + + DMARC = [ + { + p = "quarantine"; + sp = "reject"; + rua = [ "mailto:dmarc@srx.digital" ]; + ruf = [ "mailto:dmarc@srx.digital" ]; + } + ]; + + DKIM = [ + { + selector = "mail"; + s = [ "email" ]; + p = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDbg881GUU/m6SGOkSbg4/USEP0TnN7xPqrv1tcALo1wnNRmUjBBIrQueidF0vwlEQr41iuuDH28ggKuSSUmlfxFVWvaYrgN2hdd54xCshfW47kUwsH+J8VzrLTAUU4p8PP2EMRVvF2cKPce4tdBWHjbw4YzfYlyTTo3vBS/aLE1QIDAQAB"; + } + ]; + + SRV = [ + { service = "https"; proto = "tcp"; port = 443; target = "autoconfig"; } + { service = "caldavs"; proto = "tcp"; port = 443; target = "cloud"; } + { service = "carddavs"; proto = "tcp"; port = 443; target = "cloud"; } + { service = "submissions"; proto = "tcp"; port = 465; target = "mail"; } + { service = "imaps"; proto = "tcp"; port = 993; target = "mail"; } + ]; + + A = [ "65.108.77.254" ]; + AAAA = [ "2a01:4f9:6b:2573::1" ]; + + subdomains = rec { + srxgp00 = host "65.108.77.254" "2a01:4f9:6b:2573::1"; + srxgp01 = host "152.53.17.250" "2a0a:4cc0:1:131a::1"; + srxgp02 = host "212.132.77.48" "2a02:247a:275:9300::1"; + srxk8s00 = host "78.46.220.70" "2a01:4f8:1c0c:5214::1"; + vpn = delegateTo [ "ns1" "ns2" "ns3" ]; + whoami = delegateTo [ "ns1" "ns2" "ns3" ]; + whoami6 = delegateTo [ "ns1" "ns2" "ns3" ]; + dns = srxgp00; + ns1 = srxgp00; + ns2 = srxgp01; + ns3 = srxgp02; + mail = srxgp00; + autoconfig = srxgp00; + ldap = srxgp00; + support = srxgp00; + checkip = srxgp00; + netboot = srxgp00; + tsdb = srxgp00; + id = srxgp00; + vault = srxgp00; + cloud = srxgp00; + code = srxgp00; + "live.code" = srxgp00; + pad = srxgp00; + analytics = srxgp00; + home = srxgp00; + media = srxgp00; + office = srxgp00; + paperless = srxgp00; + paper = srxgp00; + meet = srxgp00; + survey = srxgp00; + metrics = srxgp00; + logs = srxgp00; + turn = srxgp00; + status = srxgp00; + auth = srxgp00; + "push.status" = srxgp00; + alerts = srxgp00; + push = srxgp00; + s3 = srxgp00; + "admin.s3" = srxgp00; + geo.subdomains = { + de = srxgp00; + us = srxgp00; + uk = srxgp00; + nl = srxgp00; + }; + + ai.subdomains = { + image = srxgp00; + }; + + nix.subdomains = { + cache = srxgp00; + build = srxgp00; + hydra = srxgp00; + }; + + matrix = { + CNAME = [ "srx.digital." ]; + subdomains = { + chat = srxgp00; + admin = srxgp00; + }; + }; + + hh.subdomains = { + hq.subdomains = { + op.subdomains = rec { + srxfw01 = host "10.50.0.1" null; + srxsw01 = host "10.50.0.3" null; + srxap01 = host "10.50.0.4" null; + srxnas01 = host "10.50.0.10" null; + netboot = srxnas01; + nfs = srxnas01; + }; + }; + }; + + l.subdomains = { + hq.subdomains = { + op.subdomains = { + srxnas00 = host "192.168.178.71" null; + }; + }; + }; + }; +} diff --git a/modules/services/dns/knsupdate.nix b/modules/services/dns/knsupdate.nix new file mode 100644 index 0000000..284269a --- /dev/null +++ b/modules/services/dns/knsupdate.nix @@ -0,0 +1,170 @@ +{ lib, pkgs, config, ... }: +with lib; +let + cfg = config.srx.service.${name}; + name = "knsupdate"; + recordType = ipVersion: if ipVersion == 4 then "A" else "AAAA"; +in +{ + options.srx.service.${name} = { + enable = mkEnableOption '' + If enabled, ${name} will periodically update + the dns record. + ''; + + package = mkPackageOption pkgs "knot-dns" { }; + + zone = mkOption { + type = types.str; + default = config.networking.domain; + example = "example.com"; + description = '' + Specifies the zone of the dynamic update + message. + ''; + }; + + record = mkOption { + type = types.str; + default = config.networking.hostName; + example = "www"; + description = '' + Specifies the record of the dynamic update + message. + ''; + }; + + server = mkOption { + type = types.str; + default = null; + example = "ns1.example.com"; + description = '' + Specifies a receiving server of the dynamic + update message. + + The name parameter can be either a host name + or an IP address. + ''; + }; + + port = mkOption { + type = types.int; + default = 53; + description = '' + Specifies a receiving server port of the + dynamic update message. + ''; + }; + + ttl = mkOption { + type = types.int; + default = 60 * 60; + description = '' + Specifies the records TTL in seconds. + ''; + }; + + interval = mkOption { + type = types.str; + default = "02:15"; + example = "hourly"; + description = '' + Update the dns record at this interval. + Updates by default at 2:15 AM every day. + + The format is described in + {manpage}`systemd.time(7)`. + ''; + }; + + ipVersions = mkOption { + type = types.listOf (types.enum [ 4 6 ]); + default = [ 4 6 ]; + description = '' + Specifies the Internet Protocol Version + to use. + ''; + }; + + lockupService = mkOption { + type = types.str; + default = "https://checkip.srx.digital/"; + description = '' + The URL of the IP lookup service. This service returns + the current public IP address of the machine making + the request. It supports both IPv4 and IPv6 addresses. + ''; + }; + + keyFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/${name}/keyFile"; + description = '' + Specifies the TSIG key file to authenticate the request. + + The format is described in + {manpage}`knot-dns.knsupdate(1)`. + ''; + }; + + user = mkOption { + type = types.str; + default = name; + description = "User under which ${name} runs."; + }; + + group = mkOption { + type = types.str; + default = name; + description = "Group under which ${name} runs."; + }; + }; + + config = lib.mkIf cfg.enable { + systemd = lib.foldl' + (acc: ipVersion: lib.recursiveUpdate acc { + services."${name}-IPv${toString ipVersion}" = { + description = "${name} updates DNS zones for dynamic IPv${toString ipVersion} records"; + path = [ pkgs.curl cfg.package ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + User = cfg.user; + Group = cfg.group; + LoadCredential = "tsig:${cfg.keyFile}"; + }; + script = '' + IP=$(${getExe pkgs.curl} -s -${toString ipVersion} ${cfg.lockupService}) + if [[ ! -z "$IP" ]]; then + ${cfg.package}/bin/knsupdate -k ''${CREDENTIALS_DIRECTORY}/tsig << EOT + server ${cfg.server} ${toString cfg.port} + zone ${cfg.zone} + del ${cfg.record}.${cfg.zone}. + add ${cfg.record}.${cfg.zone}. ${toString cfg.ttl} ${recordType ipVersion} $IP + send + EOT + fi + ''; + }; + + timers."${name}-IPv${toString ipVersion}" = { + enable = true; + timerConfig.OnCalendar = cfg.interval; + wantedBy = [ "timers.target" ]; + }; + }) + { } + cfg.ipVersions; + + users = optionalAttrs (cfg.user == name) { + users.${cfg.user} = { + group = cfg.user; + isSystemUser = true; + }; + + groups.${cfg.group}.gid = config.users.users.${cfg.user}.uid; + }; + }; +} diff --git a/modules/services/monitoring/default.nix b/modules/services/monitoring/default.nix new file mode 100644 index 0000000..47d3b1a --- /dev/null +++ b/modules/services/monitoring/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./prometheus.nix + ./telegraf.nix + ./promtail.nix + ]; +} diff --git a/modules/services/monitoring/loki.nix b/modules/services/monitoring/loki.nix new file mode 100644 index 0000000..be58be3 --- /dev/null +++ b/modules/services/monitoring/loki.nix @@ -0,0 +1,94 @@ +{ config, ... }: +{ + services = { + loki = { + enable = true; + configuration = rec { + server = { + http_listen_address = "0.0.0.0"; + http_listen_port = 3100; + }; + + auth_enabled = false; + + common = { + ring = { + instance_addr = server.http_listen_address; + kvstore.store = "inmemory"; + }; + replication_factor = 1; + }; + + ingester = { + lifecycler = { + address = server.http_listen_address; + final_sleep = "0s"; + }; + + chunk_idle_period = "1h"; + max_chunk_age = "1h"; + chunk_target_size = 1048576; + chunk_retain_period = "30s"; + }; + + schema_config.configs = [ + { + from = "2020-10-24"; + store = "boltdb-shipper"; + object_store = "filesystem"; + schema = "v13"; + index = { + prefix = "index_"; + period = "24h"; + }; + } + ]; + + storage_config = { + filesystem.directory = "${config.services.loki.dataDir}/chunks"; + boltdb_shipper = { + active_index_directory = "${config.services.loki.dataDir}/active_index"; + cache_location = "${config.services.loki.dataDir}/cache"; + cache_ttl = "24h"; + }; + }; + + limits_config = { + reject_old_samples = true; + reject_old_samples_max_age = "168h"; + allow_structured_metadata = false; + split_queries_by_interval = "24h"; + }; + + table_manager = { + retention_deletes_enabled = false; + retention_period = "0s"; + }; + + compactor.working_directory = "${config.services.loki.dataDir}/compactor"; + + query_range.cache_results = true; + + memberlist.join_members = [ "logs.vpn.srx.dev:${server.http_listen_address}" ]; + }; + }; + + prometheus.scrapeConfigs = [{ + job_name = "loki"; + static_configs = [{ + targets = [ + "${config.services.loki.configuration.server.http_listen_address}:${toString config.services.loki.configuration.server.http_listen_port}" + ]; + }]; + }]; + + grafana.provision.datasources.settings.datasources = [{ + name = "Loki"; + type = "loki"; + access = "proxy"; + url = "http://${config.services.loki.configuration.server.http_listen_address}:${toString config.services.loki.configuration.server.http_listen_port}"; + jsonData = { timeout = 60; maxLines = 1000; }; + }]; + }; +} + diff --git a/modules/services/monitoring/prometheus.nix b/modules/services/monitoring/prometheus.nix new file mode 100644 index 0000000..cc86f5e --- /dev/null +++ b/modules/services/monitoring/prometheus.nix @@ -0,0 +1,33 @@ +{ pkgs, lib, config, ... }: +{ + services.prometheus.exporters = { + systemd.enable = true; + smartctl.enable = lib.mkIf config.services.smartd.enable true; + node = { + enable = true; + enabledCollectors = [ + "systemd" + "processes" + "cgroups" + ]; + }; + blackbox = { + enable = true; + configFile = pkgs.writeText "blackbox-exporter.yaml" ( + builtins.toJSON { + modules.ssh_banner = { + prober = "tcp"; + timeout = "10s"; + tcp = { + preferred_ip_protocol = "ip4"; + query_response = [{ + expect = "^SSH-2.0-"; + send = "SSH-2.0-blackbox-ssh-check"; + }]; + }; + }; + } + ); + }; + }; +} diff --git a/modules/services/monitoring/promtail.nix b/modules/services/monitoring/promtail.nix new file mode 100644 index 0000000..c77a53a --- /dev/null +++ b/modules/services/monitoring/promtail.nix @@ -0,0 +1,48 @@ +{ config, ... }: +{ + services = { + promtail = { + enable = true; + configuration = { + server = { + http_listen_address = "0.0.0.0"; + http_listen_port = 9080; + grpc_listen_port = 0; + }; + clients = [{ url = "http://logs.vpn.srx.dev:3100/loki/api/v1/push"; }]; + scrape_configs = [{ + job_name = "journal"; + journal = { + json = true; + max_age = "12h"; + labels.job = "systemd-journal"; + }; + pipeline_stages = [ + { json.expressions = { transport = "_TRANSPORT"; unit = "_SYSTEMD_UNIT"; msg = "MESSAGE"; coredump_cgroup = "COREDUMP_CGROUP"; coredump_exe = "COREDUMP_EXE"; coredump_cmdline = "COREDUMP_CMDLINE"; coredump_uid = "COREDUMP_UID"; coredump_gid = "COREDUMP_GID"; }; } + { labels.coredump_unit = "coredump_unit"; } + { template = { source = "msg"; template = "{{if .coredump_exe}}{{.coredump_exe}} core dumped (user: {{.coredump_uid}}/{{.coredump_gid}}, command: {{.coredump_cmdline}}){{else}}{{.msg}}{{end}}"; }; } + { template = { source = "unit"; template = "{{if .unit}}{{.unit}}{{else}}{{.transport}}{{end}}"; }; } + { replace = { source = "unit"; expression = "^(session-\\d+.scope)$"; replace = "session.scope"; }; } + { regex = { expression = "(?P[^/]+)$"; source = "coredump_cgroup"; }; } + { labels.unit = "unit"; } + { output.source = "msg"; } + ]; + relabel_configs = [ + { source_labels = [ "__journal__systemd_unit" ]; target_label = "unit"; } + { source_labels = [ "__journal__transport" ]; target_label = "transport"; } + { source_labels = [ "__journal__hostname" ]; target_label = "host"; } + ]; + }]; + }; + }; + + prometheus.scrapeConfigs = [{ + job_name = "promtail"; + static_configs = [{ + targets = [ + "${config.services.promtail.configuration.server.http_listen_address}:${toString config.services.promtail.configuration.server.http_listen_port}" + ]; + }]; + }]; + }; +} diff --git a/modules/services/monitoring/telegraf.nix b/modules/services/monitoring/telegraf.nix new file mode 100644 index 0000000..394dc0f --- /dev/null +++ b/modules/services/monitoring/telegraf.nix @@ -0,0 +1,36 @@ +{ inputs, ... }: +{ + imports = with inputs; [ + srvos.nixosModules.mixins-telegraf + ]; + + services.telegraf = { + enable = true; + extraConfig = { + inputs = { + cpu = { }; + mem = { }; + swap = { }; + bond = { }; + disk = { }; + diskio = { }; + cgroup = { }; + system = { }; + conntrack = { }; + dns_query = { }; + filecount = { }; + hugepages = { }; + interrupts = { }; + iptables = { }; + kernel = { }; + netstat = { }; + nstat = { }; + processes = { }; + kernel_vmstat = { }; + systemd_units = { }; + internet_speed.interval = "60m"; + }; + outputs.prometheus_client.listen = ":9273"; + }; + }; +} diff --git a/modules/services/netboot/config.nix b/modules/services/netboot/config.nix new file mode 100644 index 0000000..f6ef327 --- /dev/null +++ b/modules/services/netboot/config.nix @@ -0,0 +1,36 @@ +{ lib, pkgs, config, ... }: +{ + imports = [ + ../../roles/core/fail2ban.nix + ../../roles/core/zsh.nix + ../../roles/core/editor.nix + ]; + + boot.supportedFilesystems = [ "zfs" "btrfs" ]; + + services = { + openssh.enable = true; + rpcbind.enable = true; + getty.autologinUser = lib.mkForce null; + }; + + users.users.root.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6vk3k1p6YMsGLFQ/xABLYK/VJicywkf1MJawnN7oXU" + ]; + + environment.systemPackages = with pkgs; [ + ethtool + iotop + iperf + lsof + nvme-cli + pciutils + socat + sysstat + tcpdump + usbutils + vnstat + ]; + + system.stateVersion = config.system.nixos.release; +} diff --git a/modules/services/netboot/default.nix b/modules/services/netboot/default.nix new file mode 100644 index 0000000..33b700a --- /dev/null +++ b/modules/services/netboot/default.nix @@ -0,0 +1,88 @@ +{ pkgs, modulesPath, ... }: +let + nixosNetboot = + let + inherit ((import (pkgs.path + "/nixos/lib/eval-config.nix") { + system = "x86_64-linux"; + modules = [{ + imports = [ + (modulesPath + "/installer/netboot/netboot-base.nix") + ./config.nix + ]; + }]; + }).config.system) build; + in + pkgs.symlinkJoin { + name = "nixos-netboot"; + paths = with build; [ + kernel + netbootRamdisk + netbootIpxeScript + ]; + }; + + ipxeMenu = pkgs.writeTextDir "boot.php" '' + #!ipxe + + echo ip-address: ''${net0/ip} + echo ip-subnet-mask: ''${net0/netmask} + echo boot-file: ''${filename} + + :menu + menu iPXE boot menu + + item disk Boot Disk + item nixos-netboot Boot NixOS Netboot + item netboot-xyz Boot Netboot.xyz + item shell Start iPXE shell + item off Shutdown + item reset Reboot + + choose --default nixos-netboot --timeout 5000 res || goto menu + goto ''${res} + + :disk + exit + + :nixos-netboot + chain --autofree images/nixos-netboot/netboot.ipxe || goto menu + + :netboot-xyz + chain --autofree ipxe/netboot-xyz.ipxe || goto menu + + :shell + shell || goto menu + + :off + echo power off system + sleep 10 || goto menu + poweroff + + :reset + reboot + ''; + + ipxeNetbootXyz = pkgs.writeTextDir "netboot-xyz.ipxe" '' + #!ipxe + chain --autofree https://boot.netboot.xyz/ + ''; + + ipxeCollection = pkgs.symlinkJoin { + name = "ipxe"; + paths = [ ipxeNetbootXyz ]; + }; + + netbootWebRoot = pkgs.runCommand "webroot" { } '' + mkdir -pv $out/images + ln -s ${ipxeMenu}/boot.php $out/boot.php + ln -s ${nixosNetboot} $out/images/nixos-netboot + ln -s ${ipxeCollection} $out/ipxe + ''; +in +{ + services.nginx.virtualHosts."netboot.srx.digital" = { + forceSSL = true; + enableACME = true; + locations."/".root = netbootWebRoot; + }; +} diff --git a/modules/services/security/clamav/default.nix b/modules/services/security/clamav/default.nix new file mode 100644 index 0000000..6a51210 --- /dev/null +++ b/modules/services/security/clamav/default.nix @@ -0,0 +1,12 @@ +{ lib, ... }: +{ + services.clamav = { + scanner = { + enable = lib.mkDefault true; + interval = "daily"; + }; + updater.enable = lib.mkDefault true; + fangfrisch.enable = lib.mkDefault true; + daemon.enable = lib.mkDefault true; + }; +} diff --git a/modules/services/security/tang/default.nix b/modules/services/security/tang/default.nix new file mode 100644 index 0000000..3ceb0b0 --- /dev/null +++ b/modules/services/security/tang/default.nix @@ -0,0 +1,33 @@ +{ pkgs, ... }: +let + port = 7654; +in +{ + services.tang = { + enable = true; + listenStream = [ + "7654" + # "${host}" + ]; + ipAddressAllow = [ + "0.0.0.0/0" + # "10.80.0.0/24" + ]; + }; + + + environment.systemPackages = with pkgs; [ + cryptsetup + clevis + tang + jose + ]; + + networking.firewall.allowedTCPPorts = [ port ]; + + # services.nginx.virtualHosts.${host} = { + # forceSSL = true; + # enableACME = true; + # locations."/".proxyPass = "http://${bind}"; + # }; +} diff --git a/modules/services/storage/samba/default.nix b/modules/services/storage/samba/default.nix new file mode 100644 index 0000000..7129105 --- /dev/null +++ b/modules/services/storage/samba/default.nix @@ -0,0 +1,97 @@ +{ + services.samba = { + enable = true; + openFirewall = true; + securityType = "user"; + extraConfig = '' + server string = %h + workgroup = srx + netbios name = %h + + logging = systemd + log level = 1 + + load printers = no + + server min protocol = SMB3 + client min protocol = SMB3 + + aio read size = 16384 + aio write size = 16384 + + security = user + map to guest = bad user + guest account = nobody + invalid users = root + force group = users + create mask = 0660 + directory mask = 0770 + ''; + + shares = { + public = { + comment = "public exchange share"; + path = "/srv/public"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "yes"; + }; + + movies = { + comment = "privat movie share"; + path = "/srv/movies"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "yes"; + }; + + music = { + comment = "privat music share"; + path = "/srv/music"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "yes"; + }; + + home = { + comment = "privat home share"; + path = "/srv/home"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + documents = { + comment = "privat document share"; + path = "/srv/documents"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + pictures = { + comment = "privat picture share"; + path = "/srv/pictures"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + videos = { + comment = "privat video share"; + path = "/srv/videos"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + + backups = { + comment = "privat samba share."; + path = "/srv/backups"; + browseable = "yes"; + writeable = "yes"; + "guest ok" = "no"; + }; + }; + }; +} diff --git a/modules/services/storage/syncthing/default.nix b/modules/services/storage/syncthing/default.nix new file mode 100644 index 0000000..32677d1 --- /dev/null +++ b/modules/services/storage/syncthing/default.nix @@ -0,0 +1,165 @@ +{ + home-manager.users.crstl.home.file = { + # https://docs.syncthing.net/users/ignoring.html + + ".ssh/.stignore".text = '' + config + ''; + + ".gnupg/.stignore".text = '' + scdaemon.conf + gpg-agent.conf + gpg.conf + ''; + + ".mozilla/firefox/.stignore".text = '' + profiles.ini + default/.keep + default/crashes + default/lock + default/user.js + default/saved-telemetry-pings + default/datareporting + Crash\ Reports + Pending\ Pings + ''; + + ".thunderbird/.stignore".text = '' + profiles.ini + default/.keep + default/crashes + default/lock + default/user.js + default/saved-telemetry-pings + default/datareporting + default/ImapMail + Crash\ Reports + Pending\ Pings + ''; + + ".config/FreeTube/.stignore".text = '' + Cache + Code\ Cache + Cookies + Cookies-journal + Crashpad + DawnCache + Dictionaries + GPUCache + history.db + hm_settings.db + Local\ Storage + Network\ Persistent\ State + player_cache + Preferences + Session\ Storage + Shared\ Dictionary + SharedStorage + SingletonCookie + SingletonLock + SingletonSocket + TransportSecurity + Trust\ Tokens + Trust\ Tokens-journal + ''; + }; + + services.syncthing = { + enable = true; + + user = "crstl"; + group = "crstl"; + dataDir = "/home/crstl"; + configDir = "/home/crstl/.config/syncthing"; + + settings = { + devices = { + "srxnb00".id = "4WUQOIU-ZOQ37TB-WY5MVXP-CETPYMW-FX6LY2R-QHLIDS4-EIGNF4G-BLYJNQX"; + "srxws00".id = "PBB2S4Q-ZDZJWA7-3PCEKWO-6AE6QQE-WRTUYFT-KE7PSBK-UXHS5JL-GUWFNQ3"; + "srxws01".id = "LNHCHTQ-HXH23YW-VPUNSTC-O27IIJO-4SH6XWC-EKK4ISR-3TCJ6VX-F2H3HQ7"; + "srxtab00".id = "7TKI7YR-7Y4FDOW-UJI3MB5-UK2XRIG-XOQWCCP-KPZSBQB-6C43AN7-LVQUPQE"; + "srxnas00".id = "6RDN34T-S3QZW3Z-V6TV5LB-EQFHAX4-FUZK6GX-A2IGKNT-6GMF4PE-DBNQPQD"; + "srxnas01".id = "QHM4QIS-KES6PGM-VC4MSQF-L35G7HD-GV6S7FM-JUNLSED-TEU65J4-266IXAC"; + }; + + folders = + let + ignorePerms = false; + devices = [ + "srxnas00" + "srxnas01" + "srxtab00" + "srxnb00" + "srxws00" + "srxws01" + ]; + in + { + downloads = { + path = "/home/crstl/Downloads"; + inherit devices ignorePerms; + }; + + music = { + path = "/home/crstl/Music"; + inherit devices ignorePerms; + }; + + videos = { + path = "/home/crstl/Videos"; + inherit devices ignorePerms; + }; + + documents = { + path = "/home/crstl/Documents"; + inherit devices ignorePerms; + }; + + firefox = { + path = "/home/crstl/.mozilla/firefox"; + inherit devices ignorePerms; + }; + + thunderbird = { + path = "/home/crstl/.thunderbird"; + inherit devices ignorePerms; + }; + + freetube = { + path = "/home/crstl/.config/FreeTube"; + inherit devices ignorePerms; + }; + + keyrings = { + path = "/home/crstl/.local/share/keyrings"; + inherit devices ignorePerms; + }; + + passwords = { + path = "/home/crstl/.password-store"; + inherit devices ignorePerms; + }; + + gpg = { + path = "/home/crstl/.gnupg"; + inherit devices ignorePerms; + }; + + ssh = { + path = "/home/crstl/.ssh"; + inherit devices ignorePerms; + }; + + goa = { + path = "/home/crstl/.config/goa-1.0"; + inherit devices ignorePerms; + }; + + evolution = { + path = "/home/crstl/.local/share/evolution"; + inherit devices ignorePerms; + }; + }; + }; + }; +} diff --git a/modules/services/virtualisation/libvirt.nix b/modules/services/virtualisation/libvirt.nix new file mode 100644 index 0000000..8555f41 --- /dev/null +++ b/modules/services/virtualisation/libvirt.nix @@ -0,0 +1,41 @@ +{ lib, pkgs, config, ... }: +{ + environment.systemPackages = + with pkgs; + [ + virt-top + ssh-askpass-fullscreen + swtpm + ] + ++ lib.optionals config.services.xserver.enable [ + virt-manager + spice-gtk + ]; + + networking.dhcpcd.denyInterfaces = [ "macvtap0@*" ]; + + virtualisation = { + libvirtd = { + enable = true; + + qemu = { + package = pkgs.qemu_kvm; + ovmf = { + enable = true; + packages = [ + (pkgs.OVMF.override { + secureBoot = true; + tpmSupport = true; + }).fd + ]; + }; + swtpm.enable = true; + }; + }; + spiceUSBRedirection.enable = true; + }; + + services.telegraf.extraConfig.inputs.libvirt = lib.mkIf config.services.telegraf.enable { }; + + users.users.telegraf = lib.mkIf config.services.telegraf.enable { extraGroups = [ "libvirtd" ]; }; +} diff --git a/modules/services/virtualisation/microvm.nix b/modules/services/virtualisation/microvm.nix new file mode 100644 index 0000000..e6cbb43 --- /dev/null +++ b/modules/services/virtualisation/microvm.nix @@ -0,0 +1,43 @@ +{ inputs, ... }: +let + inherit (inputs.nixpkgs) lib; +in +{ + imports = [ inputs.microvm.nixosModules.host ]; + + config = { + networking = { + useNetworkd = lib.mkDefault true; + + nat = { + enable = lib.mkDefault true; + enableIPv6 = lib.mkDefault true; + internalInterfaces = [ "microvm" ]; + }; + }; + + systemd.network = { + enable = true; + + netdevs."10-microvm".netdevConfig = { + Kind = "bridge"; + Name = "microvm"; + }; + + networks = { + "10-microvm" = { + matchConfig.Name = "microvm"; + networkConfig = { + DHCPServer = lib.mkDefault true; + IPv6SendRA = lib.mkDefault true; + }; + }; + + "11-microvm" = { + matchConfig.Name = "vm-*"; + networkConfig.Bridge = "microvm"; + }; + }; + }; + }; +} diff --git a/modules/services/web/nginx.nix b/modules/services/web/nginx.nix new file mode 100644 index 0000000..39526ad --- /dev/null +++ b/modules/services/web/nginx.nix @@ -0,0 +1,40 @@ +{ inputs, pkgs, config, lib, ... }: +{ + imports = with inputs; [ + srvos.nixosModules.mixins-nginx + ]; + + services = { + nginx = { + enable = true; + package = pkgs.nginxQuic; + statusPage = true; + clientMaxBodySize = "4096m"; + commonHttpConfig = '' + map $scheme $hsts_header { + https "max-age=31536000; includeSubdomains"; + } + + add_header Strict-Transport-Security $hsts_header; + + proxy_headers_hash_max_size 1024; + proxy_headers_hash_bucket_size 128; + ''; + }; + + prometheus.exporters.nginx.enable = true; + telegraf.extraConfig.inputs.nginx.urls = [ "http://localhost/nginx_status" ]; + }; + + systemd.services.nginx = { + requires = lib.optionals config.services.resolved.enable [ + "systemd-resolved.service" + ]; + after = lib.optionals config.services.resolved.enable [ + "network.target" + "systemd-resolved.service" + ]; + }; + + networking.firewall.allowedUDPPorts = [ 80 443 ]; +} diff --git a/modules/users/default.nix b/modules/users/default.nix new file mode 100644 index 0000000..2f9d4e5 --- /dev/null +++ b/modules/users/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + ./system/root + ./system/automat + ./system/service.nix + ./personal/crstl + ]; +} diff --git a/modules/users/personal/crstl/browser/chromium.nix b/modules/users/personal/crstl/browser/chromium.nix new file mode 100644 index 0000000..5ea46d4 --- /dev/null +++ b/modules/users/personal/crstl/browser/chromium.nix @@ -0,0 +1,17 @@ +{ pkgs, ... }: +{ + programs.chromium = { + enable = true; + package = pkgs.ungoogled-chromium; + commandLineArgs = [ + # https://github.com/ungoogled-software/ungoogled-chromium/blob/master/docs/flags.md + "--enable-logging=stderr" + "--no-service-autorun" + "--password-store=gnome" + ]; + dictionaries = with pkgs.hunspellDictsChromium; [ + en_US + de_DE + ]; + }; +} diff --git a/modules/users/personal/crstl/browser/firefox.nix b/modules/users/personal/crstl/browser/firefox.nix new file mode 100644 index 0000000..e06d0f0 --- /dev/null +++ b/modules/users/personal/crstl/browser/firefox.nix @@ -0,0 +1,242 @@ +{ lib, pkgs, ... }: +let + package = pkgs.firefox-wayland; +in +{ + programs.firefox = { + enable = true; + inherit package; + profiles = { + default = { + isDefault = true; + + settings = { + # https://kb.mozillazine.org/About:config_entries + "app.update.auto" = false; + "browser.newtab.url" = "about:blank"; + "browser.newtabpage.activity-stream.feeds.telemetry" = false; + "browser.newtabpage.activity-stream.section.highlights.includePocket" = false; + "browser.newtabpage.activity-stream.telemetry" = false; + "browser.newtabpage.pinned" = [ + { + title = "NixOS"; + url = "https://nixos.org"; + } + ]; + "browser.ping-centre.telemetry" = false; + "browser.search.isUS" = false; + "browser.search.region" = "DE"; + "browser.shell.checkDefaultBrowser" = false; + "browser.startup.homepage" = "about:blank"; + "browser.uidensity" = 0; + "distribution.searchplugins.defaultLocale" = "en-GB"; + "dom.security.https_only_mode_ever_enabled" = true; + "dom.security.https_only_mode" = true; + "experiments.activeExperiment" = false; + "experiments.enabled" = false; + "experiments.supported" = false; + "extensions.pocket.api" = ""; + "extensions.pocket.enabled" = false; + "extensions.pocket.oAuthConsumerKey" = ""; + "extensions.pocket.showHome" = false; + "extensions.pocket.site" = ""; + "general.smoothScroll" = true; + "general.useragent.locale" = "en-GB"; + "gnomeTheme.normalWidthTabs" = true; + "gnomeTheme.tabsAsHeaderbar" = true; + "network.allow-experiments" = false; + "policies.PasswordManagerEnabled" = true; + "privacy.donottrackheader.enabled" = true; + "privacy.partition.network_state.ocsp_cache" = true; + "privacy.resistFingerprinting" = false; + "privacy.trackingprotection.enabled" = true; + "privacy.trackingprotection.socialtracking.enabled" = true; + "signon.rememberSignons" = false; + "svg.content-properties.content.enabled" = true; + "svg.context-properties.content.enabled" = true; + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; + "toolkit.telemetry.archive.enabled" = false; + "toolkit.telemetry.bhrPing.enabled" = false; + "toolkit.telemetry.enabled" = false; + "toolkit.telemetry.firstShutdownPing.enabled" = false; + "toolkit.telemetry.hybridContent.enabled" = false; + "toolkit.telemetry.newProfilePing.enabled" = false; + "toolkit.telemetry.reportingpolicy.firstRun" = false; + "toolkit.telemetry.shutdownPingSender.enabled" = false; + "toolkit.telemetry.unified" = false; + "toolkit.telemetry.updatePing.enabled" = false; + "webgl.disabled" = true; + }; + + extraConfig = '' + user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); + user_pref("full-screen-api.ignore-widgets", true); + user_pref("media.ffmpeg.vaapi.enabled", true); + user_pref("media.rdd-vpx.enabled", true); + ''; + + search = { + force = true; + default = "Google"; + engines = { + "NixOS Options" = { + urls = [{ + template = "https://search.nixos.org/options"; + params = [ + { + name = "type"; + value = "options"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@no" ]; + }; + + "NixOS Wiki" = { + urls = [{ template = "https://nixos.wiki/index.php?search={searchTerms}"; }]; + iconUpdateURL = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@nw" ]; + }; + + "Nix Home Options" = { + urls = [{ + template = "https://mipmip.github.io/home-manager-option-search"; + params = [ + { + name = "type"; + value = "options"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@nh" ]; + }; + + "Nix Packages" = { + urls = [{ + template = "https://search.nixos.org/packages"; + params = [ + { + name = "type"; + value = "packages"; + } + { + name = "query"; + value = "{searchTerms}"; + } + ]; + }]; + icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@np" ]; + }; + + "Nix Reference Manual" = { + urls = [{ template = "https://nixos.org/manual/nix/stable/?search={searchTerms}"; }]; + iconUpdateURL = "https://nixos.wiki/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@nm" ]; + }; + + "OpenWRT Packages" = { + urls = [{ template = "https://openwrt.org/packages/pkgdata/{searchTerms}"; }]; + iconUpdateURL = "https://openwrt.org/_media/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@ow" ]; + }; + + "OpenWRT Wiki" = { + urls = [{ template = "https://openwrt.org/de/start?do=search&q={searchTerms}"; }]; + iconUpdateURL = "https://openwrt.org/_media/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@ow" ]; + }; + + "Zephyr Documentation" = { + urls = [{ template = "https://docs.zephyrproject.org/latest/search.html?q={searchTerms}"; }]; + iconUpdateURL = "https://zephyrproject.org/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@zd" ]; + }; + + "Zephyr Config" = { + urls = [{ + template = "https://docs.zephyrproject.org/latest/kconfig.html?type=kconfig&query={searchTerms}"; + }]; + iconUpdateURL = "https://zephyrproject.org/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@zc" ]; + }; + + "Docker Image" = { + urls = [{ template = "https://hub.docker.com/search?q={searchTerms}"; }]; + iconUpdateURL = "https://hub.docker.com/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@di" ]; + }; + + "Python Package" = { + urls = [{ template = "https://pypi.org/search/?q={searchTerms}"; }]; + iconUpdateURL = "https://pypi.org/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@pip" ]; + }; + + "Rust Crates" = { + urls = [{ template = "https://crates.io/search?q={searchTerms}"; }]; + iconUpdateURL = "https://www.rust-lang.org/static/images/favicon-32x32.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@rc" ]; + }; + + "Rust Book" = { + urls = [{ template = "https://doc.rust-lang.org/beta/book/index.html?search={searchTerms}"; }]; + iconUpdateURL = "https://www.rust-lang.org/static/images/favicon-32x32.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "@rb" ]; + }; + }; + }; + + # extensions = with firefox-addons.packages; [ + # block-origin + # bitwarden + # gopass-bridge + # react-devtools + # I-still-dont-care-about-cookies + # # dnssec + # # kde_connect + # ponsorblock + # arkreader + # ridactyl + # outube-shorts-block + # ]; + }; + }; + }; + + xdg.mimeApps = { + enable = true; + defaultApplications = { + "application/xhtml+xml" = "firefox.desktop"; + "text/html" = "firefox.desktop"; + "text/xml" = "firefox.desktop"; + "x-scheme-handler/ftp" = "firefox.desktop"; + "x-scheme-handler/http" = "firefox.desktop"; + "x-scheme-handler/https" = "firefox.desktop"; + "x-scheme-handler/about" = "firefox.desktop"; + "x-scheme-handler/unknown" = "firefox.desktop"; + }; + }; + + home.sessionVariables.BROWSER = "${lib.getExe package}"; +} diff --git a/modules/users/personal/crstl/cad/cadquery.nix b/modules/users/personal/crstl/cad/cadquery.nix new file mode 100644 index 0000000..5821b32 --- /dev/null +++ b/modules/users/personal/crstl/cad/cadquery.nix @@ -0,0 +1,4 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ cq-editor ]; +} diff --git a/modules/users/personal/crstl/cad/default.nix b/modules/users/personal/crstl/cad/default.nix new file mode 100644 index 0000000..de0f57a --- /dev/null +++ b/modules/users/personal/crstl/cad/default.nix @@ -0,0 +1,8 @@ +{ + imports = [ + # ./cadquery.nix + # ./kicad.nix + ./openscad.nix + ./slicer.nix + ]; +} diff --git a/modules/users/personal/crstl/cad/kicad.nix b/modules/users/personal/crstl/cad/kicad.nix new file mode 100644 index 0000000..52d633a --- /dev/null +++ b/modules/users/personal/crstl/cad/kicad.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + kicad + # kikit + # kicadAddons.kikit + # kicadAddons.kikit-library + ]; +} diff --git a/modules/users/personal/crstl/cad/openscad.nix b/modules/users/personal/crstl/cad/openscad.nix new file mode 100644 index 0000000..c6ea9f9 --- /dev/null +++ b/modules/users/personal/crstl/cad/openscad.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + openscad + openscad-lsp + sca2d + ]; + + programs.vscode.extensions = with pkgs.vscode-extensions; [ + antyos.openscad + ]; +} diff --git a/modules/users/personal/crstl/cad/slicer.nix b/modules/users/personal/crstl/cad/slicer.nix new file mode 100644 index 0000000..d292706 --- /dev/null +++ b/modules/users/personal/crstl/cad/slicer.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + orca-slicer + super-slicer-latest + ]; +} diff --git a/modules/users/personal/crstl/chat/default.nix b/modules/users/personal/crstl/chat/default.nix new file mode 100644 index 0000000..7d83532 --- /dev/null +++ b/modules/users/personal/crstl/chat/default.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + jitsi-meet-electron + signal-desktop + element-desktop + telegram-desktop + nheko + slack + ]; +} diff --git a/modules/users/personal/crstl/default.nix b/modules/users/personal/crstl/default.nix new file mode 100644 index 0000000..f06c541 --- /dev/null +++ b/modules/users/personal/crstl/default.nix @@ -0,0 +1,111 @@ +{ lib, pkgs, config, ... }: +{ + age.secrets.crstlPassword.file = ./password.age; + + users = { + groups.crstl.gid = config.users.users.crstl.uid; + users.crstl = { + uid = 1000; + isNormalUser = true; + description = "Sebastian Wendel"; + createHome = true; + group = "crstl"; + extraGroups = + [ "users" "wheel" "dialout" ] + ++ lib.optionals config.hardware.i2c.enable [ "i2c" ] + ++ lib.optionals config.networking.networkmanager.enable [ "networkmanager" ] + ++ lib.optionals config.programs.sway.enable [ "input" "video" ] + ++ lib.optionals config.programs.wireshark.enable [ "wireshark" ] + ++ lib.optionals config.sound.enable [ "audio" ] + ++ lib.optionals config.services.unbound.enable [ "unbound" ] + ++ lib.optionals config.services.paperless.enable [ "paperless" ] + ++ lib.optionals config.virtualisation.libvirtd.enable [ "libvirtd" "qemu-libvirtd" ] + ++ lib.optionals config.virtualisation.docker.enable [ "docker" ] + ++ lib.optionals config.virtualisation.podman.enable [ "podman" ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKwyxpc0pVB46j1k5VCSabvI4TUADvAabnxlE5+D5o2l" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6vk3k1p6YMsGLFQ/xABLYK/VJicywkf1MJawnN7oXU" + ]; + shell = lib.mkIf config.programs.zsh.enable pkgs.zsh; + hashedPasswordFile = config.age.secrets.crstlPassword.path; + }; + }; + + nix.settings.trusted-users = [ "crstl" ]; + + home-manager.users.crstl = { + imports = [ + ./terminal/ssh.nix + ./terminal/tmux.nix + ./terminal/kitty.nix + ./terminal/zsh.nix + ./terminal/htop.nix + ./terminal/nix-index.nix + ./terminal/dircolors.nix + ./terminal/bat.nix + ./terminal/starship.nix + ./terminal/lsd.nix + ./terminal/ripgrep.nix + ./editor/neovim.nix + ] ++ lib.optionals config.services.xserver.enable [ + ./gpg + ./terminal/git.nix + ./terminal/imv.nix + ./terminal/jq.nix + ./terminal/lf.nix + ./terminal/rbw.nix + ./terminal/thefuck.nix + ./terminal/yazi.nix + ./terminal/zoxide.nix + ./terminal/awscli.nix + ./system/home-manager.nix + ./system/gtk.nix + ./system/qt.nix + ./system/xdg.nix + ./system/gammastep.nix + ./system/kanshi.nix + ./system/stylix.nix + ./desktop-manager/dconf.nix + ./desktop-manager/blueman-applet.nix + ./desktop-manager/gnome-keyring.nix + ./desktop-manager/kdeconnect.nix + ./desktop-manager/nextcloud-client.nix + ./window-manager/dunst.nix + ./window-manager/rofi.nix + ./window-manager/sway.nix + ./window-manager/swayidle.nix + ./window-manager/waybar.nix + ./browser/firefox.nix + ./browser/chromium.nix + ./chat/default.nix + ./editor/emacs.nix + ./editor/helix.nix + ./editor/vscodium.nix + ./media/mpd.nix + ./media/mpv.nix + ./office/pass.nix + ./packages.nix + ./cad + ]; + + home = { + username = config.users.users.crstl.name; + stateVersion = "22.05"; + shellAliases = { + x = "${pkgs.yt-dlp}/bin/yt-dlp"; + vip = "${pkgs.curl}/bin/curl -s https://am.i.mullvad.net/json | jq"; + mip = "${pkgs.dnsutils}/bin/dig +short myip.opendns.com @208.67.222.222 2>&1"; + tp = "${pkgs.libressl}/bin/nc termbin.com 9999"; + }; + }; + + services.gammastep = { + inherit (config.location) latitude longitude; + }; + + programs = { + obs-studio.enable = lib.mkIf config.services.xserver.enable true; + freetube.enable = lib.mkIf config.services.xserver.enable true; + }; + }; +} diff --git a/modules/users/personal/crstl/desktop-manager/blueman-applet.nix b/modules/users/personal/crstl/desktop-manager/blueman-applet.nix new file mode 100644 index 0000000..061d1c4 --- /dev/null +++ b/modules/users/personal/crstl/desktop-manager/blueman-applet.nix @@ -0,0 +1 @@ +{ services.blueman-applet.enable = true; } diff --git a/modules/users/personal/crstl/desktop-manager/dconf.nix b/modules/users/personal/crstl/desktop-manager/dconf.nix new file mode 100644 index 0000000..2e6de02 --- /dev/null +++ b/modules/users/personal/crstl/desktop-manager/dconf.nix @@ -0,0 +1,103 @@ +{ + dconf.settings = { + "org/gnome/mutter" = { + attach-modal-dialogs = false; + dynamic-workspaces = true; + edge-tiling = false; + focus-change-on-pointer-rest = true; + workspaces-only-on-primary = false; + experimental-features = [ "scale-monitor-framebuffer" ]; + }; + + "org/gnome/desktop/interface" = { + clock-show-date = true; + clock-show-seconds = false; + clock-show-weekday = true; + enable-animations = true; + enable-hot-corners = true; + font-antialiasing = "grayscale"; + font-hinting = "slight"; + gtk-im-module = "ibus"; + locate-pointer = false; + show-battery-percentage = true; + toolkit-accessibility = false; + }; + + "org/gnome/desktop/search-providers" = { + disabled = [ "org.gnome.Eolie.desktop" ]; + enabled = [ "org.gnome.Weather.desktop" ]; + sort-order = [ + "org.gnome.Contacts.desktop" + "org.gnome.Documents.desktop" + "org.gnome.Nautilus.desktop" + ]; + }; + + "org/gnome/desktop/sound" = { + allow-volume-above-100-percent = false; + event-sounds = true; + }; + + "org/gnome/desktop/wm/preferences" = { + action-double-click-titlebar = "toggle-maximize"; + button-layout = "appmenu:close"; + workspace-names = [ + "Workspace 5" + "Workspace 2" + "Workspace 4" + "Workspace 1" + "Workspace 8" + "Workspace 8" + "Workspace 8" + "Workspace 8" + "Workspace 8" + ]; + }; + + "org/gnome/gnome-system-monitor" = { + network-total-in-bits = false; + show-dependencies = false; + show-whose-processes = "user"; + }; + + "org/gnome/settings-daemon/plugins/color" = { + night-light-enabled = true; + night-light-schedule-automatic = true; + night-light-schedule-to = 20.0; + night-light-temperature = "uint32 2883"; + }; + + "org/gnome/settings-daemon/plugins/power" = { + idle-dim = true; + power-button-action = "suspend"; + sleep-inactive-ac-type = "nothing"; + sleep-inactive-battery-timeout = 1200; + sleep-inactive-battery-type = "suspend"; + }; + + "org/gnome/shell/extensions/paperwm" = { + disable-scratch-in-overview = true; + override-hot-corner = false; + }; + + "org/gnome/shell/extensions/paperwm/keybindings" = { + close-window = [ "x" ]; + move-down-workspace = [ "m" ]; + move-up-workspace = [ "n" ]; + new-window = [ "Return" ]; + switch-down = [ "j" ]; + switch-down-workspace = [ "m" ]; + switch-left = [ "h" ]; + switch-right = [ "l" ]; + switch-up = [ "k" ]; + switch-up-workspace = [ "n" ]; + toggle-scratch = [ "Escape" ]; + toggle-scratch-layer = [ "Escape" ]; + toggle-scratch-window = [ ]; + }; + + "org/gnome/system/location" = { + enabled = true; + }; + }; +} diff --git a/modules/users/personal/crstl/desktop-manager/gnome-keyring.nix b/modules/users/personal/crstl/desktop-manager/gnome-keyring.nix new file mode 100644 index 0000000..c29c5f4 --- /dev/null +++ b/modules/users/personal/crstl/desktop-manager/gnome-keyring.nix @@ -0,0 +1,10 @@ +{ + services.gnome-keyring = { + enable = true; + components = [ + "pkcs11" + "secrets" + "ssh" + ]; + }; +} diff --git a/modules/users/personal/crstl/desktop-manager/kdeconnect.nix b/modules/users/personal/crstl/desktop-manager/kdeconnect.nix new file mode 100644 index 0000000..544c162 --- /dev/null +++ b/modules/users/personal/crstl/desktop-manager/kdeconnect.nix @@ -0,0 +1,6 @@ +{ + services.kdeconnect = { + enable = true; + indicator = true; + }; +} diff --git a/modules/users/personal/crstl/desktop-manager/nextcloud-client.nix b/modules/users/personal/crstl/desktop-manager/nextcloud-client.nix new file mode 100644 index 0000000..df49e98 --- /dev/null +++ b/modules/users/personal/crstl/desktop-manager/nextcloud-client.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + libgnome-keyring + nextcloud-client + ]; + + services.nextcloud-client.enable = true; +} diff --git a/modules/users/personal/crstl/editor/emacs.nix b/modules/users/personal/crstl/editor/emacs.nix new file mode 100644 index 0000000..8619502 --- /dev/null +++ b/modules/users/personal/crstl/editor/emacs.nix @@ -0,0 +1,389 @@ +{ pkgs, config, ... }: +{ + services.emacs = { + enable = true; + package = pkgs.emacs29-nox; + # defaultEditor = true; + socketActivation.enable = true; + client.enable = true; + }; + + programs.emacs = { + enable = true; + inherit (config.services.emacs) package; + extraConfig = '' + (setq standard-indent 2) + (setq visible-bell t) + + ;; Initialize package sources + (require 'package) + (setq package-archives '(("melpa" . "https://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/") + ("elpa" . "https://elpa.gnu.org/packages/"))) + (package-initialize) + (unless package-archive-contents + (package-refresh-contents)) + + ;; Initialize use-package on non-Linux platforms + (unless (package-installed-p 'use-package) + (package-install 'use-package)) + + (require 'use-package) + (setq use-package-always-ensure t) + + (column-number-mode) + (global-display-line-numbers-mode t) + + (load-theme 'modus-vivendi t) + + (setq modus-themes-mode-line '(borderless accented)) + (setq modus-themes-region '(accented)) + + ;;(setq modus-themes-italic-constructs t + ;; modus-themes-bold-constructs nil + ;; modus-themes-mixed-fonts t + ;; modus-themes-variable-pitch-ui nil + ;; modus-themes-custom-auto-reload t + ;; modus-themes-disable-other-themes t + + ;; ;; Options for `modus-themes-prompts' are either nil (the + ;; ;; default), or a list of properties that may include any of those + ;; ;; symbols: `italic', `WEIGHT' + ;; modus-themes-prompts '(italic bold) + + ;; ;; The `modus-themes-completions' is an alist that reads two + ;; ;; keys: `matches', `selection'. Each accepts a nil value (or + ;; ;; empty list) or a list of properties that can include any of + ;; ;; the following (for WEIGHT read further below): + ;; ;; + ;; ;; `matches' :: `underline', `italic', `WEIGHT' + ;; ;; `selection' :: `underline', `italic', `WEIGHT' + ;; modus-themes-completions + ;; '((matches . (extrabold)) + ;; (selection . (semibold italic text-also))) + + ;; modus-themes-org-blocks 'gray-background ; {nil,'gray-background,'tinted-background} + + ;; ;; The `modus-themes-headings' is an alist: read the manual's + ;; ;; node about it or its doc string. Basically, it supports + ;; ;; per-level configurations for the optional use of + ;; ;; `variable-pitch' typography, a height value as a multiple of + ;; ;; the base font size (e.g. 1.5), and a `WEIGHT'. + ;; modus-themes-headings + ;; '((1 . (variable-pitch 1.5)) + ;; (2 . (1.3)) + ;; (agenda-date . (1.3)) + ;; (agenda-structure . (variable-pitch light 1.8)) + ;; (t . (1.1)))) + + (use-package doom-modeline + :init (doom-modeline-mode 1) + :custom ((doom-modeline-height 15))) + + (use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) + + (use-package which-key + :init (which-key-mode) + :diminish which-key-mode + :config + (setq which-key-idle-delay 1)) + + (use-package all-the-icons) + + (use-package nerd-icons) + + (use-package nix-mode + :mode "\\.nix\\'") + + (use-package org + :hook (org-mode . efs/org-mode-setup) + :config + (setq org-ellipsis " ▾") + (efs/org-font-setup)) + + (use-package lsp-mode + :init + (setq lsp-keymap-prefix "C-c l") + :hook ( + (python-mode . lsp) + (python-mode . dap-mode) + (python-mode . dap-ui-mode) + (lsp-mode . lsp-enable-which-key-integration)) + :commands lsp) + + (use-package helm-lsp :commands helm-lsp-workspace-symbol) + (use-package lsp-ivy :commands lsp-ivy-workspace-symbol) + (use-package lsp-treemacs :commands lsp-treemacs-errors-list) + + (use-package python-black + :demand t + :after python + :hook (python-mode . python-black-on-save-mode-enable-dwim)) + + (add-hook 'python-mode-hook 'python-isort-on-save-mode) + + (use-package python-pytest) + + (use-package dap-mode + :config + (dap-ui-mode 1) + (require 'dap-node)) + + (use-package docker) + + (use-package helm :config (require 'helm-autoloads)) + + (use-package treemacs + :ensure t + :defer t + :init + ;;(with-eval-after-load 'winum + ;; (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)) + ;;:config + ;;(progn + ;; (setq treemacs-collapse-dirs (if treemacs-python-executable 3 0) + ;; treemacs-deferred-git-apply-delay 0.5 + ;; treemacs-directory-name-transformer #'identity + ;; treemacs-display-in-side-window t + ;; treemacs-eldoc-display 'simple + ;; treemacs-file-event-delay 2000 + ;; treemacs-file-extension-regex treemacs-last-period-regex-value + ;; treemacs-file-follow-delay 0.2 + ;; treemacs-file-name-transformer #'identity + ;; treemacs-follow-after-init t + ;; treemacs-expand-after-init t + ;; treemacs-find-workspace-method 'find-for-file-or-pick-first + ;; treemacs-git-command-pipe "" + ;; treemacs-goto-tag-strategy 'refetch-index + ;; treemacs-header-scroll-indicators '(nil . "^^^^^^") + ;; treemacs-hide-dot-git-directory t + ;; treemacs-indentation 2 + ;; treemacs-indentation-string " " + ;; treemacs-is-never-other-window nil + ;; treemacs-max-git-entries 5000 + ;; treemacs-missing-project-action 'ask + ;; treemacs-move-forward-on-expand nil + ;; treemacs-no-png-images nil + ;; treemacs-no-delete-other-windows t + ;; treemacs-project-follow-cleanup nil + ;; treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory) + ;; treemacs-position 'left + ;; treemacs-read-string-input 'from-child-frame + ;; treemacs-recenter-distance 0.1 + ;; treemacs-recenter-after-file-follow nil + ;; treemacs-recenter-after-tag-follow nil + ;; treemacs-recenter-after-project-jump 'always + ;; treemacs-recenter-after-project-expand 'on-distance + ;; treemacs-litter-directories '("/node_modules" "/.venv" "/.cask") + ;; treemacs-project-follow-into-home nil + ;; treemacs-show-cursor nil + ;; treemacs-show-hidden-files t + ;; treemacs-silent-filewatch nil + ;; treemacs-silent-refresh nil + ;; treemacs-sorting 'alphabetic-asc + ;; treemacs-select-when-already-in-treemacs 'move-back + ;; treemacs-space-between-root-nodes t + ;; treemacs-tag-follow-cleanup t + ;; treemacs-tag-follow-delay 1.5 + ;; treemacs-text-scale nil + ;; treemacs-user-mode-line-format nil + ;; treemacs-user-header-line-format nil + ;; treemacs-wide-toggle-width 70 + ;; treemacs-width 35 + ;; treemacs-width-increment 1 + ;; treemacs-width-is-initially-locked t + ;; treemacs-workspace-switch-cleanup nil) + + ;; ;;(treemacs-resize-icons 44) + ;; (treemacs-follow-mode t) + ;; (treemacs-filewatch-mode t) + ;; (treemacs-fringe-indicator-mode 'always) + ;; (when treemacs-python-executable + ;; (treemacs-git-commit-diff-mode t)) + ;; (pcase (cons (not (null (executable-find "git"))) + ;; (not (null treemacs-python-executable))) + ;; (`(t . t) + ;; (treemacs-git-mode 'deferred)) + ;; (`(t . _) + ;; (treemacs-git-mode 'simple))) + ;; (treemacs-hide-gitignored-files-mode nil)) + ;;:bind + ;;(:map global-map + ;; ("M-0" . treemacs-select-window) + ;; ("C-x t 1" . treemacs-delete-other-windows) + ;; ("C-x t t" . treemacs) + ;; ("C-x t d" . treemacs-select-directory) + ;; ("C-x t B" . treemacs-bookmark) + ;; ("C-x t C-t" . treemacs-find-file) + ;; ("C-x t M-t" . treemacs-find-tag))) + ) + + (use-package treemacs-evil + :after (treemacs evil) + :ensure t) + + (use-package treemacs-icons-dired + :hook (dired-mode . treemacs-icons-dired-enable-once) + :ensure t) + + (use-package treemacs-magit + :after (treemacs magit) + :ensure t) + + (use-package treemacs-persp + :after (treemacs persp-mode) + :ensure t + :config (treemacs-set-scope-type 'Perspectives)) + + (use-package treemacs-tab-bar ;;treemacs-tab-bar if you use tab-bar-mode + :after (treemacs) + :ensure t + :config (treemacs-set-scope-type 'Tabs)) + + (use-package ivy + :diminish + :config + (ivy-mode 1)) + + (setq ivy-use-virtual-buffers t) + (setq enable-recursive-minibuffers t) + + (global-set-key "\C-s" 'swiper) + (global-set-key (kbd "C-c C-r") 'ivy-resume) + (global-set-key (kbd "") 'ivy-resume) + (global-set-key (kbd "M-x") 'counsel-M-x) + (global-set-key (kbd "C-x C-f") 'counsel-find-file) + (global-set-key (kbd " f") 'counsel-describe-function) + (global-set-key (kbd " v") 'counsel-describe-variable) + (global-set-key (kbd " o") 'counsel-describe-symbol) + (global-set-key (kbd " l") 'counsel-find-library) + (global-set-key (kbd " i") 'counsel-info-lookup-symbol) + (global-set-key (kbd " u") 'counsel-unicode-char) + (global-set-key (kbd "C-c g") 'counsel-git) + (global-set-key (kbd "C-c j") 'counsel-git-grep) + (global-set-key (kbd "C-c k") 'counsel-ag) + (global-set-key (kbd "C-x l") 'counsel-locate) + (global-set-key (kbd "C-S-o") 'counsel-rhythmbox) + (define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history) + + ;;(use-package ivy-rich + ;; :init + ;; (ivy-rich-mode 1)) + + (use-package evil + :init + (setq evil-want-integration t) + (setq evil-want-keybinding nil) + (setq evil-want-C-u-scroll t) + (setq evil-want-C-i-jump nil) + :config + (evil-mode 1) + (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state) + (define-key evil-insert-state-map (kbd "C-h") 'evil-delete-backward-char-and-join) + + ;; Use visual line motions even outside of visual-line-mode buffers + (evil-global-set-key 'motion "j" 'evil-next-visual-line) + (evil-global-set-key 'motion "k" 'evil-previous-visual-line) + + (evil-set-initial-state 'messages-buffer-mode 'normal) + (evil-set-initial-state 'dashboard-mode 'normal)) + + (add-hook 'c-mode-hook 'helm-cscope-mode) + (add-hook 'c++-mode-hook 'helm-cscope-mode) + (eval-after-load "helm-cscope" + '(progn + (define-key helm-cscope-mode-map (kbd "M-t") 'helm-cscope-find-symbol) + (define-key helm-cscope-mode-map (kbd "M-r") 'helm-cscope-find-global-definition) + (define-key helm-cscope-mode-map (kbd "M-g M-c") 'helm-cscope-find-called-function) + (define-key helm-cscope-mode-map (kbd "M-g M-p") 'helm-cscope-find-calling-this-funtcion) + (define-key helm-cscope-mode-map (kbd "M-s") 'helm-cscope-select))) + + ;;(add-hook 'prog-mode-hook 'display-line-numbers-mode) + + (menu-bar-mode -1) + (lsp-treemacs-sync-mode 1) + + (global-tree-sitter-mode) + (global-set-key (kbd "") 'keyboard-escape-quit) + ''; + extraPackages = + epkgs: with epkgs; [ + all-the-icons + dap-mode + docker + docker-api + docker-cli + docker-compose-mode + doom-modeline + evil + helm + helm-codesearch + helm-dictionary + helm-directory + # helm-dired-history + helm-dired-recent-dirs + helm-firefox + helm-git + helm-git-grep + helm-gitignore + helm-google + helm-ispell + helm-ls-git + helm-lsp + helm-make + helm-nixos-options + helm-org + helm-pass + helm-proc + helm-pydoc + helm-shell-history + helm-systemd + helm-tree-sitter + helm-wikipedia + helm-xref + ivy + ivy-clipmenu + ivy-emoji + ivy-explorer + ivy-file-preview + ivy-fuz + ivy-historian + ivy-hydra + ivy-pass + ivy-rich + ivy-searcher + ivy-todo + ivy-xref + ivy-youtube + lsp-docker + lsp-ivy + lsp-mode + swiper + lsp-pyright + lsp-treemacs + nerd-icons + nix-mode + org + org-modern + python-black + python-isort + python-mode + python-pytest + rainbow-delimiters + treemacs + treemacs-all-the-icons + treemacs-evil + treemacs-icons-dired + treemacs-magit + treemacs-nerd-icons + treemacs-persp + treemacs-tab-bar + which-key + ]; + }; + home.packages = with pkgs; [ + emacs-all-the-icons-fonts + pyright + ]; +} diff --git a/modules/users/personal/crstl/editor/helix.nix b/modules/users/personal/crstl/editor/helix.nix new file mode 100644 index 0000000..c825ecd --- /dev/null +++ b/modules/users/personal/crstl/editor/helix.nix @@ -0,0 +1,289 @@ +{ lib, pkgs, ... }: +{ + programs.helix = { + enable = true; + defaultEditor = true; + + extraPackages = with pkgs; [ + ansible-language-server + clang-tools + delve + gitFull + go + gopls + jsonnet-language-server + lldb + lua-language-server + marksman + nil + nodePackages.bash-language-server + openscad-lsp + python3Packages.pylsp-mypy + python3Packages.pylsp-rope + python3Packages.python-lsp-server + taplo + terraform-ls + vscode-langservers-extracted + yaml-language-server + ]; + + settings = { + editor = { + shell = [ "zsh" "-c" ]; + line-number = "relative"; + rulers = [ 80 120 ]; + + gutters = [ + "diagnostics" + "line-numbers" + "spacer" + "diff" + ]; + + auto-format = true; + auto-info = true; + + completion-replace = true; + completion-trigger-len = 1; + + idle-timeout = 200; + true-color = true; + + bufferline = "always"; + color-modes = true; + + cursorline = true; + cursor-shape = { + normal = "block"; + insert = "bar"; + select = "underline"; + }; + + statusline = { + left = [ + "mode" + "selections" + "spinner" + "file-name" + "total-line-numbers" + ]; + center = [ ]; + right = [ + "diagnostics" + "file-encoding" + "file-line-ending" + "file-type" + "position-percentage" + "position" + ]; + mode = { + normal = "N "; + insert = " INS"; + select = "SELECT"; + }; + separator = ""; + }; + + lsp.display-messages = true; + }; + + keys.normal = { + space = { + space = "file_picker"; + w = ":w"; + q = ":q"; + }; + esc = [ + "collapse_selection" + "keep_primary_selection" + ]; + }; + }; + + languages = { + language = + let + nodeLsp = [ + { + name = "typescript"; + except-features = [ "format" ]; + } + { + name = "prettier"; + only-features = [ "format" ]; + } + "eslint" + ]; + in + [ + { + name = "bash"; + auto-format = true; + file-types = [ + "sh" + "bash" + ]; + formatter = { + command = "${pkgs.shfmt}/bin/shfmt"; + args = [ + "-i 4" # indent with 2 spaces + "-s" # simplify the code + "-ci" # indent switch cases + "-sr" # add space after redirection + ]; + }; + language-servers = [ "bash" ]; + } + { + name = "typescript"; + language-servers = nodeLsp; + } + { + name = "javascript"; + language-servers = nodeLsp; + } + { + name = "jsx"; + language-servers = nodeLsp; + } + { + name = "tsx"; + language-servers = nodeLsp; + } + { + name = "sql"; + formatter.command = "${pkgs.pgformatter}/bin/pg_format"; + } + { + name = "nix"; + auto-format = true; + formatter.command = "${pkgs.alejandra}/bin/alejandra"; + language-servers = [ "nil" ]; + } + { + name = "go"; + auto-format = true; + formatter.command = "${pkgs.go}/bin/gofmt"; + language-servers = [ "go" ]; + } + { + name = "rust"; + auto-format = true; + language-servers = [ "rust-analyzer" ]; + file-types = [ "rs" ]; + } + { + name = "xml"; + file-types = [ "xml" ]; + formatter = { + command = "${pkgs.yq-go}/bin/yq"; + args = [ + "--input-format" + "xml" + "--output-format" + "xml" + "--indent" + "2" + ]; + }; + } + ]; + + language-server = { + # check: hx --health [LANG] + + bash = with pkgs.nodePackages; { + command = "${bash-language-server}/bin/bash-language-server"; + args = [ "start" ]; + }; + + go = { + command = "${pkgs.gopls}/bin/gopls"; + }; + + nil = { + command = "${pkgs.nil}/bin/nil"; + config.nil = { + formatter.command = "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt"; + nix.flake.autoEvalInputs = true; + }; + }; + + rust-analyzer = { + config.rust-analyzer = { + cargo.loadOutDirsFromCheck = true; + checkOnSave.command = "clippy"; + procMacro.enable = true; + + lens = { + references = true; + methodReferences = true; + }; + + completion.autoimport.enable = true; + experimental.procAttrMacros = true; + }; + }; + + typescript = with pkgs.nodePackages; { + command = "${typescript-language-server}/bin/typescript-language-server"; + args = [ + "--stdio" + "--tsserver-path=${typescript}/lib/node_modules/typescript/lib" + ]; + }; + + prettier = with pkgs; { + command = "${efm-langserver}/bin/efm-langserver"; + config = { + documentFormatting = true; + languages = + lib.genAttrs + [ + "typescript" + "javascript" + "typescriptreact" + "javascriptreact" + "vue" + "json" + "markdown" + ] + (_: [ + { + formatCommand = "${nodePackages.prettier}/bin/prettier --stdin-filepath \${INPUT}"; + formatStdin = true; + } + ]); + }; + }; + + eslint = with pkgs.nodePackages; { + command = "${eslint}/bin/eslint"; + args = [ "--stdio" ]; + config = { + validate = "on"; + packageManager = "yarn"; + useESLintClass = false; + codeActionOnSave.mode = "all"; + format = true; + quiet = false; + onIgnoredFiles = "off"; + rulesCustomizations = [ ]; + run = "onType"; + nodePath = ""; + workingDirectory.mode = "auto"; + experimental = { }; + problems.shortenToSingleLine = false; + codeAction = { + disableRuleComment = { + enable = true; + location = "separateLine"; + }; + showDocumentation.enable = true; + }; + }; + }; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/editor/neovim.nix b/modules/users/personal/crstl/editor/neovim.nix new file mode 100644 index 0000000..13646e4 --- /dev/null +++ b/modules/users/personal/crstl/editor/neovim.nix @@ -0,0 +1,548 @@ +{ pkgs, config, ... }: +{ + programs.neovim = { + enable = true; + + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + + # withNodeJs = lib.mkIf config.services.xserver.enable true; + # withPython3 = lib.mkIf config.services.xserver.enable true; + withRuby = false; + + extraPackages = [ + pkgs.git + pkgs.nil + # ] + # ++ lib.optionals config.services.xserver.enable + # [ + # tree-sitter + pkgs.bat + pkgs.clang + pkgs.delta + pkgs.elmPackages.elm-language-server + pkgs.fzf + pkgs.haskell-language-server + pkgs.luaPackages.lua-lsp + # pkgs.nodePackages.pyright + pkgs.nodePackages.typescript + pkgs.nodePackages.typescript-language-server + pkgs.ripgrep + pkgs.silver-searcher + # sumneko-lua-language-server + ]; + + # config = lib.mkIf cfg.enable { + # # Clear the /tmp directory when the system is rebooted + # boot.cleanTmpDir = lib.mkDefault true; + + # profiles.preferences.customizedVimPlugins = + # pkgs.vimPlugins + # // (with pkgs.vimPlugins; { + # # Code editing: Comment and uncomment + # vim-commentary = { + # plugin = vim-commentary; + # }; + + # # Programming language integrations: Language servers + # nvim-lspconfig = { + # plugin = nvim-lspconfig; + # type = "lua"; + # # plugin = nvim-lspconfig.overrideAttrs (oldAttrs: { + # # dependencies = (old.dependencies or [ ]) ++ [ + # # # lsp_extensions-nvim + # # # lsp_signature-nvim + # # # lua-dev-nvim + # # # SchemaStore-nvim + # # ]; + # # }); + # config = '' + # loadfile('${./neovim/plugins/lspconfig.lua}')() + # ''; + # }; + + # # Code editing: Auto-completion + # nvim-cmp = { + # plugin = nvim-cmp; + # type = "lua"; + # config = + # # Note caveats in the readme regarding native menu + # '' + # local cmp = require('cmp') + # cmp.setup({ + # snippet = { + # -- I don't use snippets but it appears to be required + # expand = function(args) + # require('luasnip').lsp_expand(args.body) + # end, + # }, + # mapping = cmp.mapping.preset.insert({ + # -- Accept the currently selected item + # [''] = cmp.mapping.confirm({ select = true }), + # -- Force auto-completion in insert mode without first typing something + # [''] = cmp.mapping(cmp.mapping.complete(), { 'i', 'c' }), + # }), + # sources = cmp.config.sources({ + # -- Listed in order of preference + # { name = 'nvim_lua' }, + # { name = 'nvim_lsp' }, + # { name = 'luasnip' }, + # { name = 'buffer' }, + # }) + # }) + # vim.opt.completeopt = { + # -- Show the completion menu for a single match so that documentation will always appear + # "menuone", + # -- Don't pop open documentation unless you explicitly navigate the completion menu + # "noselect", + # } + # -- Suppress command-line noise related to completions + # vim.opt.shortmess:append "c" + # ''; + # }; + + # # Code editing: Auto-completion with current buffer contents + # cmp-buffer = { + # plugin = cmp-buffer; + # type = "lua"; + # config = '' + # -- Use buffer as a completion source for search via / + # require('cmp').setup.cmdline('/', { + # sources = { + # { name = 'buffer' } + # } + # }) + # ''; + # }; + + # # Code editing: Auto-completion with language servers + # cmp-nvim-lsp = { + # plugin = cmp-nvim-lsp; + # }; + + # # Code editing: Auto-completion with nvim's lua api + # cmp-nvim-lua = { + # plugin = cmp-nvim-lua; + # }; + + # # Git support + # vim-fugitive = { + # plugin = vim-fugitive; + # }; + + # # Git support: Show changed lines in gutter (replaces gitgutter) + # gitsigns-nvim = { + # plugin = gitsigns-nvim; + # type = "lua"; + # config = '' + # loadfile('${./neovim/plugins/gitsigns.lua}')() + # ''; + # }; + + # # Nix support + # vim-nix = { + # plugin = vim-nix; + # }; + + # # Navigation: Fuzzy finder + # telescope-nvim = { + # plugin = telescope-nvim; + # type = "lua"; + # config = '' + # -- Search file names that are tracked by git + # vim.keymap.set('n', 'o', function() return require('telescope.builtin').git_files() end, { desc = "Search tracked files" }) + # -- Search file names modified relative to HEAD + # vim.keymap.set('n', 'm', function() return require('telescope.builtin').git_status() end, { desc = "Search modified files" }) + # -- Search file names + # vim.keymap.set('n', 'O', function() return require('telescope.builtin').find_files() end, { desc = "Search files" }) + # -- Search file contents + # vim.keymap.set('n', '/', function() return require('telescope.builtin').live_grep() end, { desc = "Search files contents" }) + # -- Search buffer names + # vim.keymap.set('n', 'b', function() return require('telescope.builtin').buffers() end, { desc = "Search open buffers" }) + # -- Search diagnostics in all open buffers + # vim.keymap.set('n', 'D', function() return require('telescope.builtin').diagnostics() end, { desc = "Search workspace diagnostics" }) + # -- Search diagnostics + # vim.keymap.set('n', 'd', function() return require('telescope.builtin').diagnostics({ bufnr = 0 }) end, { desc = "Search diagnostics" }) + # -- Search vim help + # vim.keymap.set('n', 'hh', function() return require('telescope.builtin').help_tags() end, { desc = "Search vim help" }) + # -- Pressing esc twice to cancel is annoying, so map to directly close the popup in insert mode + # local actions = require('telescope.actions') + # require('telescope').setup({ + # defaults = { + # mappings = { + # i = { + # [""] = actions.close, + # }, + # }, + # }, + # }) + # ''; + # }; + # telescope-fzf-native-nvim = { + # # native fzf ostensibly improves performance + # plugin = telescope-fzf-native-nvim; + # type = "lua"; + # config = '' + # require('telescope').load_extension('fzf') + # ''; + # }; + + # # Navigation: File tree + # nvim-tree-lua = { + # plugin = nvim-tree-lua; + # type = "lua"; + # config = '' + # require('nvim-tree').setup({ + # }) + # ''; + # }; + + # # Navigation: Tabline + # bufferline-nvim = { + # plugin = bufferline-nvim; + # type = "lua"; + # config = '' + # require('bufferline').setup({ + # options = { + # -- Needed because vim buffers are different from vim tab pages. + # -- This is the same as setting vim.opt.showtabline = 2. + # always_show_bufferline = true, + # }, + # }) + # ''; + # }; + + # # Aesthetics: Color scheme + # gruvbox-nvim = { + # # faster than gruvbox and gruvbox-community + # plugin = gruvbox-nvim; + # type = "lua"; + # config = '' + # vim.cmd [[colorscheme gruvbox]] + # -- TODO: move to playground + # -- "Hide" the cursor line highlight past column 80 and 120 to hint at potential text wrap. + # vim.o.colorcolumn=vim.fn.join(vim.fn.range(81,121), ',') .. vim.fn.join(vim.fn.range(121,999), ',') + # vim.api.nvim_set_hl(0, 'ColorColumn', { link = 'Normal' }) + # ''; + # }; + + # # Aesthetics: icons + # nvim-web-devicons = { + # plugin = nvim-web-devicons; + # }; + + # # Aesthetics: status/tabline + # lualine-nvim = { + # plugin = lualine-nvim.overrideAttrs (oldAttrs: { + # dependencies = + # (oldAttrs.dependencies or []) + # ++ [ + # lualine-lsp-progress + # ]; + # }); + # type = "lua"; + # config = '' + # require('lualine').setup({ + # sections = { + # lualine_a = { { 'mode', upper = true } }, + # lualine_b = { { 'branch', icon = '' } }, + # lualine_c = { + # { 'filename', file_status = true, path = 1 }, + # { 'diagnostics', sources = { 'nvim_lsp' } }, + # { 'lsp_progress' }, + # }, + # lualine_x = { 'encoding', 'filetype' }, + # lualine_y = { 'progress' }, + # lualine_z = { 'location' }, + # }, + # }) + # -- Suppress mode prefixes like "-- INSERT --" in the command-line + # vim.opt.showmode = false + # ''; + # }; + + # # Vim: key binding feedback + # which-key-nvim = { + # plugin = which-key-nvim; + # type = "lua"; + # config = '' + # require('which-key').setup({ + # }) + # ''; + # }; + + # # Vim: benchmarking + # vim-startuptime = { + # # Run with vim --startuptime + # plugin = vim-startuptime; + # }; + # }); + + # plugins = with config.profiles.preferences.customizedVimPlugins; [ + # # Programming language integrations: Language servers + # nvim-lspconfig + + # # Code editing: Comment and uncomment + # vim-commentary + + # # Code editing: Auto-completion + # nvim-cmp + + # # Code editing: Auto-completion with language servers + # cmp-nvim-lsp + + # # Code editing: Auto-completion with current buffer contents + # cmp-buffer + + # # Code editing: Auto-completion with nvim's lua api + # cmp-nvim-lua + + # # Code editing: Auto-completion with current buffer contents + # cmp-buffer + + # # Git support + # vim-fugitive + + # # Git support: Show changed lines in gutter + # gitsigns-nvim + + # # Nix support + # vim-nix + + # # Navigation: Fuzzy finder + # telescope-nvim + # telescope-fzf-native-nvim + + # # Navigation: File tree + # nvim-tree-lua + + # # Navigation: Buffers + # bufferline-nvim + + # # Aesthetics: Color scheme + # gruvbox-nvim + + # # Aesthetics: icons + # nvim-web-devicons + + # # Aesthetics: Status/tabline + # lualine-lsp-progress + # lualine-nvim + + # # Vim: key binding feedback + # which-key-nvim + + # # Vim: benchmarking + # vim-startuptime + # ]; + + # extraConfig = '' + # let g:loaded_perl_provider = 0 + # :set relativenumber + # :set rnu + # ''; + + plugins = with pkgs; [ + vimPlugins.vim-nix + # ] + # ++ lib.optionals config.services.xserver.enable + # [ + vimPlugins.vim-clap + vimPlugins.fzf-vim + # vimPlugins.nvim-treesitter.withAllGrammars + vimPlugins.cmp-nvim-lsp + vimPlugins.cmp-snippy + vimPlugins.cmp-path + vimPlugins.cmp-cmdline + vimPlugins.cmp-buffer + vimPlugins.cmp-digraphs + vimPlugins.cmp-cmdline-history + vimPlugins.cmp-nvim-lsp-document-symbol + vimPlugins.cmp-nvim-lsp-signature-help + vimPlugins.cmp-git + vimPlugins.vim-airline-themes + { + plugin = vimPlugins.nvim-cmp; + config = '' + set completeopt=menu,menuone,noselect + + lua <'] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.abort(), + [''] = cmp.mapping.confirm({ select = true }), + }), + sources = cmp.config.sources({ + { name = 'nvim_lsp' }, + { name = 'nvim_lsp_document_symbol' }, + { name = 'nvim_lsp_signature_help' }, + { name = 'cmdline_history' }, + { name = 'digraphs' }, + { name = 'path' }, + { name = 'buffer-lines' }, + { name = 'snippy' }, + { name = "git" }, + }, { + { name = 'buffer' }, + }) + }) + + cmp.setup.filetype('gitcommit', { + sources = cmp.config.sources({ + { name = 'cmp_git' }, + }, { + { name = 'buffer' }, + }) + }) + + cmp.setup.cmdline({ '/', '?' }, { + mapping = cmp.mapping.preset.cmdline(), + sources = { + { name = 'buffer' } + } + }) + + cmp.setup.cmdline(':', { + mapping = cmp.mapping.preset.cmdline(), + sources = cmp.config.sources({ + { name = 'path' } + }, { + { name = 'cmdline' } + }) + }) + + local capabilities = require('cmp_nvim_lsp').default_capabilities() + + require'lspconfig'.pyright.setup { + capabilities = capabilities, + } + require'lspconfig'.rnix.setup { + capabilities = capabilities, + } + require'lspconfig'.tsserver.setup { + capabilities = capabilities, + } + require'lspconfig'.clangd.setup { + capabilities = capabilities, + } + EOF + ''; + } + { + plugin = vimPlugins.nvim-snippy; + config = '' + lua << EOF + require('snippy').setup({ + mappings = { + is = { + [''] = 'expand_or_advance', + [''] = 'previous', + }, + nx = { + ['x'] = 'cut_text', + }, + }, + }) + EOF + ''; + } + { + plugin = vimPlugins.nvim-tree-lua; + config = '' + lua << EOF + vim.g.loaded_netrw = 1 + vim.g.loaded_netrwPlugin = 1 + vim.opt.termguicolors = true + require("nvim-tree").setup() + EOF + ''; + } + { + plugin = vimPlugins.vim-airline; + config = '' + let g:airline_powerline_fonts = 1 + let g:airline_theme='base16' + let g:airline#extensions#nvimlsp#enabled = 1 + ''; + } + { + plugin = vimPlugins.vim-which-key; + config = '' + lua << EOF + require("which-key").setup() + EOF + ''; + } + { + plugin = vimPlugins.nvim-autopairs; + config = '' + lua << EOF + require("nvim-autopairs").setup() + EOF + ''; + } + { + plugin = vimPlugins.nvim-lspconfig; + config = '' + lua << EOF + local opts = { noremap=true, silent=true } + vim.keymap.set('n', 'e', vim.diagnostic.open_float, opts) + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) + vim.keymap.set('n', 'q', vim.diagnostic.setloclist, opts) + + local on_attach = function(client, bufnr) + vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') + local bufopts = { noremap=true, silent=true, buffer=bufnr } + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) + vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, bufopts) + vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, bufopts) + vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, bufopts) + vim.keymap.set('n', 'wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, bufopts) + vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, bufopts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, bufopts) + vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) + vim.keymap.set('n', 'f', function() vim.lsp.buf.format { async = true } end, bufopts) + end + + local lsp_flags = { + debounce_text_changes = 150, + } + require('lspconfig')['pyright'].setup{ + on_attach = on_attach, + flags = lsp_flags, + } + require('lspconfig')['rnix'].setup{ + on_attach = on_attach, + flags = lsp_flags, + } + require('lspconfig')['tsserver'].setup{ + on_attach = on_attach, + flags = lsp_flags, + } + EOF + ''; + } + ]; + }; +} diff --git a/modules/users/personal/crstl/editor/vscodium.nix b/modules/users/personal/crstl/editor/vscodium.nix new file mode 100644 index 0000000..6e39654 --- /dev/null +++ b/modules/users/personal/crstl/editor/vscodium.nix @@ -0,0 +1,196 @@ +{ lib, pkgs, ... }: +{ + stylix.targets.vscode.enable = false; + + home = { + packages = with pkgs; [ + # git + gitFull + + # env + direnv + vscode-langservers-extracted + + # nix + nil + nixd + nixpkgs-fmt + nixfmt-rfc-style + deadnix + statix + + # golang + go + goperf + libcap + gcc + + # devops + opentofu + kubectl + kubernetes-helm + ]; + + sessionVariables.GOPATH = "/home/crstl/Development/golang"; + }; + + programs.vscode = { + enable = true; + package = pkgs.vscodium-fhs; + + mutableExtensionsDir = false; + enableUpdateCheck = false; + enableExtensionUpdateCheck = false; + + userSettings = { + telemetry.telemetryLevel = "off"; + gitlens.telemetry.enabled = false; + redhat.telemetry.enabled = false; + + window = { + zoomLevel = 1; + menuBarVisibility = "toggle"; + }; + + editor = { + inlineSuggest.enabled = true; + minimap.enabled = false; + autoIndent = "full"; + autoSurround = "brackets"; + }; + + workbench = { + iconTheme = "material-icon-theme"; + colorTheme = "Material Theme Palenight High Contrast"; + editor.enablePreview = false; + list.smoothScrolling = true; + startupEditor = "none"; + welcomePage.walkthroughs.openOnInstall = false; + }; + + update.showReleaseNotes = false; + + nix = { + enableLanguageServer = true; + serverPath = "${lib.getExe pkgs.nil}"; + serverSettings.nil = { + formatting.command = [ (lib.getExe pkgs.nixpkgs-fmt) ]; + nix = { + binary = lib.getExe pkgs.nix; + maxMemoryMB = 4096; + flake = { + autoArchive = true; + autoEvalInputs = true; + nixpkgsInputName = "nixpkgs"; + }; + }; + }; + }; + + "[jsonc]".editor.defaultFormatter = "vscode.json-language-features"; + "[nix]".editor.defaultFormatter = "jnoortheen.nix-ide"; + + github.copilot.chat.welcomeMessage = "never"; + + genieai = { + promptPrefix = { + explain = "gpt.explain"; + addComments = "gpt.comments"; + completeCode = "gpt.complete"; + optimize = "gpt.optimize"; + findProblems = "gpt.find"; + addTests = "gpt.test"; + }; + openai = { + model = "gpt-4"; + temperature = 0.7; + }; + response = { + showNotification = true; + }; + }; + }; + + extensions = with pkgs.vscode-extensions; [ + # themes & icons + equinusocio.vsc-material-theme + pkief.material-icon-theme + pkief.material-product-icons + + # visualize + ## kamikillerto.vscode-colorize + oderwat.indent-rainbow + + # formater + esbenp.prettier-vscode + formulahendry.auto-close-tag + formulahendry.auto-rename-tag + jkillian.custom-local-formatters + shardulm94.trailing-spaces + tyriar.sort-lines + + # lang + streetsidesoftware.code-spell-checker + + # file + redhat.vscode-yaml + + # env + editorconfig.editorconfig + irongeek.vscode-env + mikestead.dotenv + formulahendry.code-runner + + # git + codezombiech.gitignore + donjayamanne.githistory + mhutchie.git-graph + + # nix + arrterian.nix-env-selector + bbenoist.nix + brettm12345.nixfmt-vscode + jnoortheen.nix-ide + mkhl.direnv + + # golang + golang.go + + # web + astro-build.astro-vscode + bradlc.vscode-tailwindcss + ritwickdey.liveserver + + # markdown + bierner.markdown-mermaid + davidanson.vscode-markdownlint + unifiedjs.vscode-mdx + marp-team.marp-vscode + + # container + ms-kubernetes-tools.vscode-kubernetes-tools + ms-vscode-remote.remote-ssh + ms-vscode-remote.remote-containers + + # devops + hashicorp.hcl + hashicorp.terraform + github.vscode-github-actions + + # ai + github.copilot + github.copilot-chat + genieai.chatgpt-vscode + visualstudioexptteam.vscodeintellicode + visualstudioexptteam.intellicode-api-usage-examples + ]; + + globalSnippets = { + fixme = { + prefix = [ "fixme" ]; + description = "Insert a FIXME remark"; + body = [ "$LINE_COMMENT FIXME: $0" ]; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/gpg/default.nix b/modules/users/personal/crstl/gpg/default.nix new file mode 100644 index 0000000..1a284be --- /dev/null +++ b/modules/users/personal/crstl/gpg/default.nix @@ -0,0 +1,21 @@ +{ pkgs, ... }: +{ + services.gpg-agent = { + enable = true; + enableScDaemon = true; + enableSshSupport = true; + enableExtraSocket = true; + defaultCacheTtl = 34560000; + maxCacheTtl = 34560000; + pinentryPackage = pkgs.pinentry-gnome3; + }; + + programs.gpg = { + enable = true; + settings = { + default-key = "EECAAE75129CF8D1DE4771F471D71CBBEA1E76AD"; + keyserver = "hkps://keys.openpgp.org"; + keyserver-options = "no-honor-keyserver-url"; + }; + }; +} diff --git a/modules/users/personal/crstl/gpg/keyserver.age b/modules/users/personal/crstl/gpg/keyserver.age new file mode 100644 index 0000000..bae0790 --- /dev/null +++ b/modules/users/personal/crstl/gpg/keyserver.age @@ -0,0 +1,44 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw 6ocHTAQUz4I4xpYL/v1oYf4AUScF9TsYzMPWC1xlanI +DUx7menhndw5iep3GksOZQ84JtmVt4Ikm3vaMayapRY +-> ssh-ed25519 JzjriQ gqI71D27jRUKt4dNSrGT4IFLosxyB1knb6SqXTP2wVc +BVSlTYiKoVBGzqMmbWv2K2Mh1iWWa7fJhVmrq6za6DQ +-> ssh-rsa 6hPx7A +Fg+Dk2NyPW7YOK+9KLPlfHYL/Z2/zoQxRTMl3qY7Qtjgp7LIviLKtXrUK91Cwz4u +R/2d0W7QtxMb3qDto1FVBVoWqqIDTjniJeA/32I8I94ewmhGD6RwgLt5bkjrVUqw +EBpCCvAXN3ZXCzTahTv+Y7IAXiZoqWXKKyqKbybcqGN4A0FW/aQYyYJju+Zb3xZU +XsOUTKPwqsDKxpXhViQ6gBYDzpSNX9jyvzQOBoCVL1XgIhOoTTTSFkgAhBtYXGRq +sQXc1/4wtCtxNRE9SI8GKDGsLqW421kYInQBhXmQsvoA+0LfBucmwYYqh2ZWKqay +4BukP4ZO5ldNnYAa8VhqVdhfzulBtWDCaQUHFYBOtn0HlhUj/IJ1YHQ2pTtx/wEt +dQ4f0QkoNRL+crTeypE+HFjDHjLlBzkmxu56cqImnyNOR64KoTw5f9wLFU7Xz0oq +VWjS1/z1l8lY7qc8Eh0mG0FRW1fZikW7173AfLdLOr1L3hw3k5nnqQYA84SKn0/n +jCJ52CsnfOTI9Q4oOs55FnV7gveoRiWaWme8Y4RgK/7cVWrRpTAAQEzT8uIGK/7R +LgdQpcloK0zfHBSkD+fnWmSpMK+hRetEt0H1GpCBDsjI8ylcesDNpO6th1nyfxyr +yTOM35sLya21kKiaRE5hReWGpnxN1yvVpamPOh1IPw0 +-> ssh-ed25519 SiDnLw 2F1Up/osFYuCWJJ7WSA/Ng39JbviF93v9cez6E9HsmM +9zRgy0Yjlh4UoBChzPl4ok9oQBC1Nx6AE+GGS7/ncHU +-> ssh-ed25519 Dfencg 1PJI0ReobErZPcsooAYES8Po+/vc6zozYazCox3iZBc +DB+JYu4FeGKtIFfkRGEchjiaYGy+OptF1BPVTTDhKeo +-> ssh-ed25519 OWgoVA zhndyZqQFzdaM3noqeI7L4Lvww5UbWycFeISo6nyiT4 +B7TKE3Qaz/D4YL0ecvYtyWm2dQ+XKbVSPZqLt2DgZQ8 +-> ssh-ed25519 aP/BWw sBdCAsDidUg9ZQiLxNFRcoW1y2s6e+vf98i2Fc+o2w0 +d3kQ9N70+HRTDSggWpOCcHqWAnWslWiiBY4r0r5wFlY +-> ssh-ed25519 v+/Ozg 1cpZqhjYBggF1FwDTMA7x3+dNSeIGhPcLTKq7KgvFws +Lohl1sDNzuioMlgzcUTyMj0dnFn2KrirBu1jco/o0Nk +-> ssh-ed25519 5VC2zg ZZNCrVED5tOYoJKshBo8e4uyaYl8U3M1KWfM2jZC0VE +Y7lrWbP9Fgo5ItSaU2c0GpJhx4ZMoFIzF4b5K4vGS1s +-> ssh-ed25519 ZeuIrQ CC3+rqvrw/QeW/wJtldrpxj2JqbPVcw2JkHbte9YEW4 +xadAuHXDVQJeQyMmfy12nbXKx1jiunbCfwh88Ix1rxA +-> ssh-ed25519 MrfLnw x0tdBoB2lbs5g1SwtUEj/xjSEkQ0onJ4gE+JUcDAYW8 +UpLeFyDM4Y7WXHJE9EItAXvyYdPioBnCRXHbnGz9xUk +-> ssh-ed25519 xkaJLw wtDFYitAVhBuEFusuX6HcRIajyjXlmnjAwd2Mh/rqxg +gIQiVMg8ZYQMh3k22lskpe1Jf7QuTggabqXjWxq9M5c +-> ssh-ed25519 al5mZw s5ITDTpae53n25VrO3L8SQxNr4ycRJWNQxIcUEIMrX0 +KNwG7WSaCIDfnNnAnl7lXeB5EWv4MmWdc9CCbaoYYFQ +-> ssh-ed25519 Sk9VBA rGfI3xSbon1V5inKsStk1h3cta8J2sLeYeq5Ky/iOjk +5SEDDnfoMMYaCwSVhLZBeAhuhOxArlsnb2mMky/eybc +--- cVx6mTAYi7EOPwkNdTMCwLdjSXY3FFcxv0HtATcDGWc +�r�s�����T��}��nF�l��hd �%�4���QZ-*�6뵻k��t' XJ��@0$E +��{�����������&X�ʚ[�!� +o���W3 +%X��X�#�x �L�f�%?��BR���F���EN� \ No newline at end of file diff --git a/modules/users/personal/crstl/media/mpd.nix b/modules/users/personal/crstl/media/mpd.nix new file mode 100644 index 0000000..6e394dd --- /dev/null +++ b/modules/users/personal/crstl/media/mpd.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: +{ + xdg.userDirs.enable = true; + + services.mpd.enable = true; + + home.packages = with pkgs; [ + cantata + mmtc + rofi-mpd + ]; + + programs.ncmpcpp.enable = true; +} diff --git a/modules/users/personal/crstl/media/mpv.nix b/modules/users/personal/crstl/media/mpv.nix new file mode 100644 index 0000000..b68b1bf --- /dev/null +++ b/modules/users/personal/crstl/media/mpv.nix @@ -0,0 +1,70 @@ +{ + programs.mpv = { + enable = true; + config = { + profile = "gpu-hq"; + gpu-context = "wayland"; + vo = "gpu"; + hwdec = "auto"; + }; + }; + + xdg.mimeApps.defaultApplications = { + "application/mxf" = "mpv.desktop"; + "application/sdp" = "mpv.desktop"; + "application/smil" = "mpv.desktop"; + "application/streamingmedia" = "mpv.desktop"; + "application/vnd.apple.mpegurl" = "mpv.desktop"; + "application/vnd.ms-asf" = "mpv.desktop"; + "application/vnd.rn-realmedia" = "mpv.desktop"; + "application/vnd.rn-realmedia-vbr" = "mpv.desktop"; + "application/x-cue" = "mpv.desktop"; + "application/x-extension-m4a" = "mpv.desktop"; + "application/x-extension-mp4" = "mpv.desktop"; + "application/x-matroska" = "mpv.desktop"; + "application/x-mpegurl" = "mpv.desktop"; + "application/x-ogm" = "mpv.desktop"; + "application/x-ogm-video" = "mpv.desktop"; + "application/x-shorten" = "mpv.desktop"; + "application/x-smil" = "mpv.desktop"; + "application/x-streamingmedia" = "mpv.desktop"; + "video/3gp" = "mpv.desktop"; + "video/3gpp" = "mpv.desktop"; + "video/3gpp2" = "mpv.desktop"; + "video/avi" = "mpv.desktop"; + "video/divx" = "mpv.desktop"; + "video/dv" = "mpv.desktop"; + "video/fli" = "mpv.desktop"; + "video/flv" = "mpv.desktop"; + "video/mkv" = "mpv.desktop"; + "video/mp2t" = "mpv.desktop"; + "video/mp4" = "mpv.desktop"; + "video/mp4v-es" = "mpv.desktop"; + "video/mpeg" = "mpv.desktop"; + "video/msvideo" = "mpv.desktop"; + "video/ogg" = "mpv.desktop"; + "video/quicktime" = "mpv.desktop"; + "video/vnd.divx" = "mpv.desktop"; + "video/vnd.mpegurl" = "mpv.desktop"; + "video/vnd.rn-realvideo" = "mpv.desktop"; + "video/webm" = "mpv.desktop"; + "video/x-avi" = "mpv.desktop"; + "video/x-flc" = "mpv.desktop"; + "video/x-flic" = "mpv.desktop"; + "video/x-flv" = "mpv.desktop"; + "video/x-m4v" = "mpv.desktop"; + "video/x-matroska" = "mpv.desktop"; + "video/x-mpeg2" = "mpv.desktop"; + "video/x-mpeg3" = "mpv.desktop"; + "video/x-ms-afs" = "mpv.desktop"; + "video/x-ms-asf" = "mpv.desktop"; + "video/x-ms-wmv" = "mpv.desktop"; + "video/x-ms-wmx" = "mpv.desktop"; + "video/x-ms-wvxvideo" = "mpv.desktop"; + "video/x-msvideo" = "mpv.desktop"; + "video/x-ogm" = "mpv.desktop"; + "video/x-ogm+ogg" = "mpv.desktop"; + "video/x-theora" = "mpv.desktop"; + "video/x-theora+ogg" = "mpv.desktop"; + }; +} diff --git a/modules/users/personal/crstl/office/pass.nix b/modules/users/personal/crstl/office/pass.nix new file mode 100644 index 0000000..d189ddf --- /dev/null +++ b/modules/users/personal/crstl/office/pass.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: +{ + # services.pass-secret-service.enable = true; + + programs.password-store = { + enable = true; + settings.PASSWORD_STORE_DIR = "$HOME/.password-store"; + }; + + home.packages = with pkgs; [ + gopass + gopass-jsonapi + qtpass + ]; +} diff --git a/modules/users/personal/crstl/packages.nix b/modules/users/personal/crstl/packages.nix new file mode 100644 index 0000000..ea33002 --- /dev/null +++ b/modules/users/personal/crstl/packages.nix @@ -0,0 +1,16 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + appimage-run + filezilla + gimp + inkscape + libreoffice-fresh + meld + remmina + strawberry + transmission_4-gtk + transmission-rss + transmission-remote-gtk + ]; +} diff --git a/modules/users/personal/crstl/password.age b/modules/users/personal/crstl/password.age new file mode 100644 index 0000000..b1ebca1 --- /dev/null +++ b/modules/users/personal/crstl/password.age @@ -0,0 +1,45 @@ +age-encryption.org/v1 +-> ssh-ed25519 jDpDqw 6sZ74uKgsXI8RMtbAgo3ssmJJQRKLgtcD1S5VWYwkGs +r6WgWbM9uIfKT5k8VgAqr943utPfVjLjh5bx/IxADQ4 +-> ssh-ed25519 JzjriQ 0stdqyyMUutffKeFUAI9iXWP1UCpIQAGY/eLBGl1lDE +K66zAzoqkd8eXfD/gO6Ov5pbYrh4ebqsCMP0AaY+jDU +-> ssh-rsa 6hPx7A +GPFUJIGqxeys2GLE6nHy3vww9WPDTHSMnNFJl1S3xxiZjEYaPHDl1TBqU0gH7Och +6nQeu6K+kM3yCkLlPw/Rvr/tpVfac/PEp3TU/4tTitOECQjq2O5U/auEAWXOFYtx +q5ZO6JHZrhIgvqW9o9f7V0ioatpY10tKfXZmXJswFxjNiCAbtk/e5KmWFixVcDRY +38leCz67ES01kqundS7rqEWGLMAw3aemXCWgcRROGjjQs69A7MmcrRIEze0XH8dl +MTqahZHUFNvWVw8OihGYdzGjYht3qLLqjPGuKms1HNLn8nLCLGRDutFdp6GYjvML +OYOclQQx4FtkfFC0CpQscv8DCHuq0wuezXPmp079ktbQ9jaD0CJCpiKoWV2sxLt3 +bRsNKwsoeXlEfcGuvU76KGD3gElZcj0muN72gfOdqJUcn9RTHHZXBm/hbfYKsqvJ +/tzvJuPG9Dv9eozKYX8avFYgMFTg0TcPQJGjGk8BQJ3MVEcJq9fKyNMmg/dWg7YW +oy1CzGxFGdRaRP2bYr6dXrIs4+HiXzIUV0F/2T7pZWqr1W1zaHflK4Of8rLDtfQb +53AiqeAIdZLYLqekjblR5ke9WOovvnAMqrywplY7BgbyH8h9otVg6104EAxcY7Bk +F/x+6gL1tV0OhtWpUwrlxouNrI9rzmtS2dkz4Y5ZVpM +-> ssh-ed25519 IK8+2Q 3eZS/ctGuCI8hJXYzy17uXuIJynHuuJJrQ8qtJ9oOEo +4/M+rssfgYXEUip6PftdOi/4F3kGQccBSY6HktXsObc +-> ssh-ed25519 SiDnLw Ln+El0qOj+3wi4qrRIh3CVcaqZsdGH46V44mn6SS+CE +8NpVQbMkRsndtUYIQNcgYasMV/sC8fqzpQ4ipOQjmXg +-> ssh-ed25519 Dfencg VciwaDfyLsM4WGMAxN/Sab1SxaYwoB2954N/e78ag20 +WjBQn5OdX9eS0+cx5+Dk/Aye1h+BKjdE98elp/zDBB0 +-> ssh-ed25519 OWgoVA VAcwbXGDGCF5KJCrQlh1zefzYpVgSwwilea1y7RG9HE +RWPYnyc8dU2E8NJA3bVt59BctWHjLl7D5jfi0TyCRd4 +-> ssh-ed25519 aP/BWw J5nqEUmVXUTKSkDE9uUa8afy7yjeSyRQeHAxvWoSAxU +fxtKQO5zHnX4Si/Zkki4dunIYAiCtEaBO7awvKq4tqo +-> ssh-ed25519 v+/Ozg FI/PXe8lHiVHeNX0roW8GRx4nCjfVxMpHGdS1jzI8Eo +hdg/5dhzaJ+f1CRiF6RVmEqu3hKtlEVjF3ji7h9pzeA +-> ssh-ed25519 5VC2zg PT0cZntXNiNNFaN27W5F6znrwRNmyKTDKoA/tUTW0mk +UYX/wLXS67culSOHfeVygK80aBmTONxJXcBcf3YAg+s +-> ssh-ed25519 ZeuIrQ hZ0L1lIPmWi7ovl1Byl2pTt8LpmhD4wklPCQcUZSrWE +2W/6GBHGR58YIejZx521j/weWLv5SSwl80xmKnnR4ME +-> ssh-ed25519 MrfLnw zcfOpU8owgizGcBfxvFoi4VWPPUGIFQZQD9ver+smCs +LMdoH+qr32mRsNgHiWj4hi3WPldvywROJlVh4iBugwI +-> ssh-ed25519 TVW7ow IQFBhT+NFHeIfWTjS1JxYV2T5uFS+4lpSif8gRj+JHk +gO40UI4Pt+/ix2JtzsVXsJdW93kQFG67T9A5V8QUfYk +-> ssh-ed25519 xkaJLw D9AnOVBqmwS4g4MU3MlYOlpR+2T2mHIP6ykmhWgFyEE +SSMNkv7UtI3qdVsYSHHU5SRnhwaDQsB1Yq13Dzxk2hE +-> ssh-ed25519 al5mZw oJV7Cho7LLmrv/QJfXdqOxtjYat7bQNGeEwIjwTK8g4 +eQR8tTAhQQsAw4UjjH/b6mPxhEoygjqPuWEmrAoiVuE +-> ssh-ed25519 Sk9VBA EKqk5m4p4gkXOuJEVFw0s6FuEkWcGCuMXojsXx2M2QM +w/YSo95lCL7fxHgXJy7G5ad1/MgEaZRmAQGHDhW3x80 +--- sCbf+ug9guufIwu39hg3eIDsm6dsApmG/gV6zt+SESw +\)#?B&=c2Szދu"S̲EWɞhNGΧbLB^Lod6MUmp,E0H' O? [`|l[] 5w&x&ު#һ \ No newline at end of file diff --git a/modules/users/personal/crstl/system/gammastep.nix b/modules/users/personal/crstl/system/gammastep.nix new file mode 100644 index 0000000..8face6f --- /dev/null +++ b/modules/users/personal/crstl/system/gammastep.nix @@ -0,0 +1,7 @@ +{ + services.gammastep = { + enable = true; + tray = true; + provider = "manual"; + }; +} diff --git a/modules/users/personal/crstl/system/gtk.nix b/modules/users/personal/crstl/system/gtk.nix new file mode 100644 index 0000000..ded3b79 --- /dev/null +++ b/modules/users/personal/crstl/system/gtk.nix @@ -0,0 +1,14 @@ +{ lib, pkgs, ... }: +{ + gtk = { + enable = true; + theme = { + name = lib.mkForce "palenight"; + package = lib.mkForce pkgs.palenight-theme; + }; + iconTheme = { + name = lib.mkForce "Nordzy-purple-dark"; + package = lib.mkForce pkgs.nordzy-icon-theme; + }; + }; +} diff --git a/modules/users/personal/crstl/system/home-manager.nix b/modules/users/personal/crstl/system/home-manager.nix new file mode 100644 index 0000000..a7ef72e --- /dev/null +++ b/modules/users/personal/crstl/system/home-manager.nix @@ -0,0 +1,3 @@ +{ + programs.home-manager.enable = true; +} diff --git a/modules/users/personal/crstl/system/kanshi.nix b/modules/users/personal/crstl/system/kanshi.nix new file mode 100644 index 0000000..1f084fd --- /dev/null +++ b/modules/users/personal/crstl/system/kanshi.nix @@ -0,0 +1,67 @@ +{ + services.kanshi = { + enable = true; + settings = [ + { + profile = { + name = "srxtab00"; + outputs = [{ + criteria = "Sharp Corporation LQ100P1JX51 Unknown"; + scale = 1.1; + }]; + }; + } + { + profile = { + name = "srxws00"; + outputs = [ + { + criteria = "Dell Inc. DELL P3223QE 8HG75P3"; + status = "enable"; + mode = "3840x2160"; + position = "0,950"; + scale = 1.1; + } + { + criteria = "Dell Inc. DELL P3223QE 7HN7BP3"; + status = "enable"; + mode = "3840x2160"; + position = "3480,0"; + transform = "270"; + scale = 1.1; + } + ]; + }; + } + { + profile = { + name = "srxws01"; + outputs = [ + { + criteria = "Dell Inc. DELL U2415 7MT017CQ2NWU"; + status = "enable"; + mode = "1920x1200"; + position = "0,0"; + scale = 1.0; + } + { + criteria = "Dell Inc. DELL U2715H GH85D7920WHS"; + status = "enable"; + mode = "2560x1440"; + position = "1920,0"; + transform = "90"; + scale = 1.0; + } + { + criteria = "Dell Inc. DELL U2415 7MT016C80UAS"; + status = "enable"; + mode = "1920x1200"; + position = "3360,0"; + scale = 1.0; + } + ]; + }; + } + ]; + }; +} diff --git a/modules/users/personal/crstl/system/qt.nix b/modules/users/personal/crstl/system/qt.nix new file mode 100644 index 0000000..985c2b3 --- /dev/null +++ b/modules/users/personal/crstl/system/qt.nix @@ -0,0 +1,6 @@ +{ + qt = { + enable = true; + platformTheme.name = "gtk3"; + }; +} diff --git a/modules/users/personal/crstl/system/stylix.nix b/modules/users/personal/crstl/system/stylix.nix new file mode 100644 index 0000000..6b9e346 --- /dev/null +++ b/modules/users/personal/crstl/system/stylix.nix @@ -0,0 +1,29 @@ +{ + stylix = { + enable = true; + fonts = { + sizes = { + desktop = 12; + applications = 12; + terminal = 12; + popups = 12; + }; + }; + + opacity = { + terminal = 0.9; + applications = 0.9; + popups = 0.9; + desktop = 0.9; + }; + + targets = { + gnome.enable = true; + waybar = { + enableCenterBackColors = true; + enableRightBackColors = true; + enableLeftBackColors = true; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/system/xdg.nix b/modules/users/personal/crstl/system/xdg.nix new file mode 100644 index 0000000..d7e2525 --- /dev/null +++ b/modules/users/personal/crstl/system/xdg.nix @@ -0,0 +1,6 @@ +{ + xdg.userDirs = { + enable = true; + createDirectories = true; + }; +} diff --git a/modules/users/personal/crstl/terminal/alacritty.nix b/modules/users/personal/crstl/terminal/alacritty.nix new file mode 100644 index 0000000..dfb00ea --- /dev/null +++ b/modules/users/personal/crstl/terminal/alacritty.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: +{ + programs.alacritty = { + enable = true; + settings = { + cursor.style = "Beam"; + dynamic_padding = true; + env.TERM = "xterm-256color"; + selection.save_to_clipboard = true; + url.launcher.program = "${pkgs.mimeo}/bin/mimeo"; + colors.draw_bold_text_with_bright_colors = true; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/awscli.nix b/modules/users/personal/crstl/terminal/awscli.nix new file mode 100644 index 0000000..f17e7d5 --- /dev/null +++ b/modules/users/personal/crstl/terminal/awscli.nix @@ -0,0 +1,9 @@ +{ + programs.awscli = { + enable = true; + settings.default = { + region = "eu-central-1"; + output = "json"; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/bat.nix b/modules/users/personal/crstl/terminal/bat.nix new file mode 100644 index 0000000..c253a6f --- /dev/null +++ b/modules/users/personal/crstl/terminal/bat.nix @@ -0,0 +1,27 @@ +{ pkgs, ... }: +{ + home.shellAliases = { + cat = "${pkgs.bat}/bin/bat --style=plain"; + less = "${pkgs.bat}/bin/bat --style=plain"; + }; + + programs.bat = { + enable = true; + config = { + color = "always"; + pager = "less -FR"; + style = "numbers,changes,header"; + map-syntax = [ + "*.hcl:Terraform" + "*.tf.json:Terraform" + "*.ino:C++" + ]; + }; + extraPackages = with pkgs.bat-extras; [ + batdiff + batgrep + batman + batwatch + ]; + }; +} diff --git a/modules/users/personal/crstl/terminal/dircolors.nix b/modules/users/personal/crstl/terminal/dircolors.nix new file mode 100644 index 0000000..b6186c2 --- /dev/null +++ b/modules/users/personal/crstl/terminal/dircolors.nix @@ -0,0 +1,5 @@ +{ + programs.dircolors = { + enable = true; + }; +} diff --git a/modules/users/personal/crstl/terminal/git.nix b/modules/users/personal/crstl/terminal/git.nix new file mode 100644 index 0000000..707f0ca --- /dev/null +++ b/modules/users/personal/crstl/terminal/git.nix @@ -0,0 +1,101 @@ +{ pkgs, lib, config, ... }: +{ + programs = { + git = { + enable = true; + package = pkgs.gitFull; + userName = "Sebastian Wendel"; + userEmail = "swendel@srx.digital"; + aliases = { + amend = "commit --amend -C HEAD"; + authors = + ''!"${pkgs.git}/bin/git log --pretty=format:%aN'' + + " | ${pkgs.coreutils}/bin/sort" + + " | ${pkgs.coreutils}/bin/uniq -c" + + " | ${pkgs.coreutils}/bin/sort -rn\""; + b = "branch --color -v"; + ca = "commit --amend"; + changes = "diff --name-status -r"; + clone = "clone --recursive"; + co = "checkout"; + cp = "cherry-pick"; + dc = "diff --cached"; + dh = "diff HEAD"; + ds = "diff --staged"; + from = "!${pkgs.git}/bin/git bisect start && ${pkgs.git}/bin/git bisect bad HEAD && ${pkgs.git}/bin/git bisect good"; + ls-ignored = "ls-files --exclude-standard --ignored --others"; + rc = "rebase --continue"; + rh = "reset --hard"; + ri = "rebase --interactive"; + rs = "rebase --skip"; + ru = "remote update --prune"; + snap = "!${pkgs.git}/bin/git stash" + " && ${pkgs.git}/bin/git stash apply"; + snaplog = + "!${pkgs.git}/bin/git log refs/snapshots/refs/heads/" + "$(${pkgs.git}/bin/git rev-parse HEAD)"; + spull = + "!${pkgs.git}/bin/git stash" + " && ${pkgs.git}/bin/git pull" + " && ${pkgs.git}/bin/git stash pop"; + su = "submodule update --init --recursive"; + undo = "reset --soft HEAD^"; + w = "status -sb"; + wdiff = "diff --color-words"; + l = + "log --graph --pretty=format:'%Cred%h%Creset" + + " —%Cblue%d%Creset %s %Cgreen(%cr)%Creset'" + + " --abbrev-commit --date=relative --show-notes=*"; + }; + + extraConfig = { + core = { + editr = "${lib.getExe pkgs.vscodium-fhs} --wait"; + pager = "${lib.getExe pkgs.bat}"; + trustctime = false; + logAllRefUpdates = true; + precomposeunicode = false; + whitespace = "trailing-space,space-before-tab"; + }; + branch.autosetupmerge = true; + credential.helper = "${pkgs.pass-git-helper}/bin/pass-git-helper"; + ghi.token = "!${pkgs.pass}/bin/pass show api.github.com | head -1"; + github.user = "SebastianWendel"; + hub.protocol = "${pkgs.openssh}/bin/ssh"; + init.defaultBranch = "main"; + mergetool.keepBackup = true; + pull.rebase = true; + rebase.autosquash = true; + rerere.enabled = true; + color = { + status = "auto"; + diff = "auto"; + branch = "auto"; + interactive = "auto"; + ui = "auto"; + sh = "auto"; + }; + }; + }; + + gitui.enable = true; + }; + + services.git-sync = { + enable = false; + repositories = { + "srx.digital.astro" = { + path = "${config.home.homeDirectory}/Development/web/srx.digital.astro"; + uri = "forgejo@code.srx.digital:srx/srx.infra.nix.history.git"; + }; + "srx.infra.nix" = { + path = "${config.home.homeDirectory}/Development/nix/srx.infra.nix"; + uri = "forgejo@code.srx.digital:srx/srx.infra.nix.history.git"; + }; + "srx.shadow.nix" = { + path = "${config.home.homeDirectory}/Development/nix/srx.shadow.nix"; + uri = "forgejo@code.srx.digital:srx/srx-nixos-shadow.git"; + }; + "nixpkgs" = { + path = "${config.home.homeDirectory}/Development/nix/nixpkgs"; + uri = "git@github.com:SebastianWendel/nixpkgs.git"; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/htop.nix b/modules/users/personal/crstl/terminal/htop.nix new file mode 100644 index 0000000..bf05101 --- /dev/null +++ b/modules/users/personal/crstl/terminal/htop.nix @@ -0,0 +1,32 @@ +{ config, ... }: +{ + programs.htop = { + enable = true; + settings = + { + delay = 10; + show_program_path = false; + show_cpu_frequency = true; + show_cpu_temperature = true; + hide_kernel_threads = true; + } + // ( + with config.lib.htop; + leftMeters [ + (bar "AllCPUs2") + (bar "Memory") + (bar "Swap") + ] + ) + // ( + with config.lib.htop; + rightMeters [ + (text "Hostname") + (text "Tasks") + (text "LoadAverage") + (text "Uptime") + (text "Systemd") + ] + ); + }; +} diff --git a/modules/users/personal/crstl/terminal/imv.nix b/modules/users/personal/crstl/terminal/imv.nix new file mode 100644 index 0000000..f4e8c02 --- /dev/null +++ b/modules/users/personal/crstl/terminal/imv.nix @@ -0,0 +1,78 @@ +{ lib, ... }: +{ + programs.imv = { + enable = true; + settings = { + options.background = "ffffff"; + aliases.x = "close"; + }; + }; + + xdg.mimeApps.defaultApplications = { + "image/bmp" = lib.mkForce "imv.desktop"; + "image/gif" = lib.mkForce "imv.desktop"; + "image/jpeg" = lib.mkForce "imv.desktop"; + "image/jpg" = lib.mkForce "imv.desktop"; + "image/pjpeg" = lib.mkForce "imv.desktop"; + "image/png" = lib.mkForce "imv.desktop"; + "image/tiff" = lib.mkForce "imv.desktop"; + "image/webp" = lib.mkForce "imv.desktop"; + "image/x-3fr" = lib.mkForce "imv.desktop"; + "image/x-adobe-dng" = lib.mkForce "imv.desktop"; + "image/x-arw" = lib.mkForce "imv.desktop"; + "image/x-bay" = lib.mkForce "imv.desktop"; + "image/x-bmp" = lib.mkForce "imv.desktop"; + "image/x-canon-cr2" = lib.mkForce "imv.desktop"; + "image/x-canon-crw" = lib.mkForce "imv.desktop"; + "image/x-cap" = lib.mkForce "imv.desktop"; + "image/x-cr2" = lib.mkForce "imv.desktop"; + "image/x-crw" = lib.mkForce "imv.desktop"; + "image/x-dcr" = lib.mkForce "imv.desktop"; + "image/x-dcraw" = lib.mkForce "imv.desktop"; + "image/x-dcs" = lib.mkForce "imv.desktop"; + "image/x-dng" = lib.mkForce "imv.desktop"; + "image/x-drf" = lib.mkForce "imv.desktop"; + "image/x-eip" = lib.mkForce "imv.desktop"; + "image/x-erf" = lib.mkForce "imv.desktop"; + "image/x-fff" = lib.mkForce "imv.desktop"; + "image/x-fuji-raf" = lib.mkForce "imv.desktop"; + "image/x-iiq" = lib.mkForce "imv.desktop"; + "image/x-k25" = lib.mkForce "imv.desktop"; + "image/x-kdc" = lib.mkForce "imv.desktop"; + "image/x-mef" = lib.mkForce "imv.desktop"; + "image/x-minolta-mrw" = lib.mkForce "imv.desktop"; + "image/x-mos" = lib.mkForce "imv.desktop"; + "image/x-mrw" = lib.mkForce "imv.desktop"; + "image/x-nef" = lib.mkForce "imv.desktop"; + "image/x-nikon-nef" = lib.mkForce "imv.desktop"; + "image/x-nrw" = lib.mkForce "imv.desktop"; + "image/x-olympus-orf" = lib.mkForce "imv.desktop"; + "image/x-orf" = lib.mkForce "imv.desktop"; + "image/x-panasonic-raw" = lib.mkForce "imv.desktop"; + "image/x-pcx" = lib.mkForce "imv.desktop"; + "image/x-pef" = lib.mkForce "imv.desktop"; + "image/x-pentax-pef" = lib.mkForce "imv.desktop"; + "image/x-png" = lib.mkForce "imv.desktop"; + "image/x-portable-anymap" = lib.mkForce "imv.desktop"; + "image/x-portable-bitmap" = lib.mkForce "imv.desktop"; + "image/x-portable-graymap" = lib.mkForce "imv.desktop"; + "image/x-portable-pixmap" = lib.mkForce "imv.desktop"; + "image/x-ptx" = lib.mkForce "imv.desktop"; + "image/x-pxn" = lib.mkForce "imv.desktop"; + "image/x-r3d" = lib.mkForce "imv.desktop"; + "image/x-raf" = lib.mkForce "imv.desktop"; + "image/x-raw" = lib.mkForce "imv.desktop"; + "image/x-rw2" = lib.mkForce "imv.desktop"; + "image/x-rwl" = lib.mkForce "imv.desktop"; + "image/x-rwz" = lib.mkForce "imv.desktop"; + "image/x-sigma-x3f" = lib.mkForce "imv.desktop"; + "image/x-sony-arw" = lib.mkForce "imv.desktop"; + "image/x-sony-sr2" = lib.mkForce "imv.desktop"; + "image/x-sony-srf" = lib.mkForce "imv.desktop"; + "image/x-sr2" = lib.mkForce "imv.desktop"; + "image/x-srf" = lib.mkForce "imv.desktop"; + "image/x-tga" = lib.mkForce "imv.desktop"; + "image/x-x3f" = lib.mkForce "imv.desktop"; + "image/x-xbitmap" = lib.mkForce "imv.desktop"; + }; +} diff --git a/modules/users/personal/crstl/terminal/jq.nix b/modules/users/personal/crstl/terminal/jq.nix new file mode 100644 index 0000000..3c01c41 --- /dev/null +++ b/modules/users/personal/crstl/terminal/jq.nix @@ -0,0 +1 @@ +{ programs.jq.enable = true; } diff --git a/modules/users/personal/crstl/terminal/kitty.nix b/modules/users/personal/crstl/terminal/kitty.nix new file mode 100644 index 0000000..f2cbe5f --- /dev/null +++ b/modules/users/personal/crstl/terminal/kitty.nix @@ -0,0 +1,26 @@ +{ lib, ... }: +{ + programs.kitty = { + enable = true; + shellIntegration = { + enableBashIntegration = true; + enableZshIntegration = true; + }; + font = lib.mkForce { + size = 14; + name = ""; + }; + settings = { + copy_on_select = "clipboard"; + scrollback_lines = 10000; + update_check_interval = 0; + enable_audio_bell = false; + }; + keybindings = { + "ctrl+plus" = "change_font_size all +2.0"; + "ctrl+minus" = "change_font_size all -2.0"; + "ctrl+page_up" = "scroll_page_up"; + "ctrl+page_down" = "scroll_page_down"; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/lf.nix b/modules/users/personal/crstl/terminal/lf.nix new file mode 100644 index 0000000..d668f84 --- /dev/null +++ b/modules/users/personal/crstl/terminal/lf.nix @@ -0,0 +1,25 @@ +{ + programs.lf = { + enable = true; + + settings = { + number = true; + ratios = [ + 1 + 1 + 2 + ]; + tabstop = 4; + + preview = true; + hidden = true; + drawbox = true; + icons = true; + ignorecase = true; + }; + + commands = { + get-mime-type = ''%xdg-mime query filetype "$f"''; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/lsd.nix b/modules/users/personal/crstl/terminal/lsd.nix new file mode 100644 index 0000000..36f93a0 --- /dev/null +++ b/modules/users/personal/crstl/terminal/lsd.nix @@ -0,0 +1,11 @@ +{ + programs.lsd = { + enable = true; + enableAliases = true; + settings = { + layout = "grid"; + hyperlink = "auto"; + sorting.dir-grouping = "first"; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/mpd.nix b/modules/users/personal/crstl/terminal/mpd.nix new file mode 100644 index 0000000..6e394dd --- /dev/null +++ b/modules/users/personal/crstl/terminal/mpd.nix @@ -0,0 +1,14 @@ +{ pkgs, ... }: +{ + xdg.userDirs.enable = true; + + services.mpd.enable = true; + + home.packages = with pkgs; [ + cantata + mmtc + rofi-mpd + ]; + + programs.ncmpcpp.enable = true; +} diff --git a/modules/users/personal/crstl/terminal/nix-index.nix b/modules/users/personal/crstl/terminal/nix-index.nix new file mode 100644 index 0000000..562bbef --- /dev/null +++ b/modules/users/personal/crstl/terminal/nix-index.nix @@ -0,0 +1,5 @@ +{ + # programs.command-not-found.enable = true; + # programs.nix-index.enable = true; + programs.nix-index.enableZshIntegration = true; +} diff --git a/modules/users/personal/crstl/terminal/rbw.nix b/modules/users/personal/crstl/terminal/rbw.nix new file mode 100644 index 0000000..56e64e0 --- /dev/null +++ b/modules/users/personal/crstl/terminal/rbw.nix @@ -0,0 +1,13 @@ +{ pkgs, ... }: +{ + programs.rbw = { + enable = true; + settings = { + email = "swendel@srx.digital"; + base_url = "https://vault.srx.digital/"; + pinentry = pkgs.pinentry-gnome3; + sync_interval = 600; + lock_timeout = 21600; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/ripgrep.nix b/modules/users/personal/crstl/terminal/ripgrep.nix new file mode 100644 index 0000000..0b9550c --- /dev/null +++ b/modules/users/personal/crstl/terminal/ripgrep.nix @@ -0,0 +1,9 @@ +{ + programs.ripgrep = { + enable = true; + arguments = [ + "--max-columns-preview" + "--colors=line:style:bold" + ]; + }; +} diff --git a/modules/users/personal/crstl/terminal/ssh.nix b/modules/users/personal/crstl/terminal/ssh.nix new file mode 100644 index 0000000..699eff7 --- /dev/null +++ b/modules/users/personal/crstl/terminal/ssh.nix @@ -0,0 +1,6 @@ +{ + programs.ssh = { + enable = true; + forwardAgent = true; + }; +} diff --git a/modules/users/personal/crstl/terminal/starship.nix b/modules/users/personal/crstl/terminal/starship.nix new file mode 100644 index 0000000..5122eba --- /dev/null +++ b/modules/users/personal/crstl/terminal/starship.nix @@ -0,0 +1,63 @@ +{ lib, ... }: +{ + programs.starship = { + enable = true; + enableBashIntegration = true; + enableZshIntegration = true; + + settings = { + add_newline = true; + scan_timeout = 10; + + status = { + map_symbol = true; + pipestatus = true; + }; + + format = lib.concatStrings [ + "$all" + "$line_break" + "$character" + ]; + + character = { + success_symbol = " [λ](bold green)"; + error_symbol = " [λ](bold red)"; + }; + + nix_shell.symbol = "❄️ "; + aws.disabled = true; + + directory = { + style = "cyan"; + read_only = " 🔒"; + }; + + battery = { + charging_symbol = "⚡️"; + display = [ + { + threshold = 10; + style = "bold red"; + } + ]; + }; + + cmd_duration.show_notifications = true; + + git_metrics = { + format = "[+$added]($added_style)/[-$deleted]($deleted_style)"; + }; + + git_status = { + ahead = ''⇡''${count}''; + diverged = ''⇕⇡''${ahead_count}⇣''${behind_count}''; + behind = ''⇣''${count}''; + }; + + shlvl = { + symbol = "↕ "; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/thefuck.nix b/modules/users/personal/crstl/terminal/thefuck.nix new file mode 100644 index 0000000..90f592d --- /dev/null +++ b/modules/users/personal/crstl/terminal/thefuck.nix @@ -0,0 +1,9 @@ +{ + programs.thefuck = { + enable = true; + enableBashIntegration = true; + enableFishIntegration = true; + enableZshIntegration = true; + enableInstantMode = true; + }; +} diff --git a/modules/users/personal/crstl/terminal/tmux.nix b/modules/users/personal/crstl/terminal/tmux.nix new file mode 100644 index 0000000..18bf255 --- /dev/null +++ b/modules/users/personal/crstl/terminal/tmux.nix @@ -0,0 +1,12 @@ +{ + programs.tmux = { + enable = true; + aggressiveResize = true; + clock24 = true; + escapeTime = 0; + historyLimit = 10000; + newSession = false; + secureSocket = false; + terminal = "tmux-256color"; + }; +} diff --git a/modules/users/personal/crstl/terminal/yazi.nix b/modules/users/personal/crstl/terminal/yazi.nix new file mode 100644 index 0000000..e015599 --- /dev/null +++ b/modules/users/personal/crstl/terminal/yazi.nix @@ -0,0 +1,12 @@ +{ + programs.yazi = { + enable = true; + enableZshIntegration = true; + settings = { + manager = { + show_hidden = false; + sort_dir_first = true; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/terminal/zoxide.nix b/modules/users/personal/crstl/terminal/zoxide.nix new file mode 100644 index 0000000..439f676 --- /dev/null +++ b/modules/users/personal/crstl/terminal/zoxide.nix @@ -0,0 +1,7 @@ +{ + programs.zoxide = { + enable = true; + enableZshIntegration = true; + enableBashIntegration = true; + }; +} diff --git a/modules/users/personal/crstl/terminal/zsh.nix b/modules/users/personal/crstl/terminal/zsh.nix new file mode 100644 index 0000000..bc67e47 --- /dev/null +++ b/modules/users/personal/crstl/terminal/zsh.nix @@ -0,0 +1,68 @@ +{ pkgs, lib, ... }: +let + mkZshPlugin = + { pkg + , file ? "${pkg.pname}.plugin.zsh" + , + }: + { + name = pkg.pname; + inherit (pkg) src; + inherit file; + }; +in +{ + home.packages = with pkgs; [ thefuck ]; + + programs.zsh = { + enable = lib.mkForce true; + autocd = true; + + autosuggestion.enable = true; + enableCompletion = true; + syntaxHighlighting.enable = true; + enableVteIntegration = true; + + plugins = with pkgs; [ + (mkZshPlugin { pkg = zsh-z; }) + (mkZshPlugin { pkg = zsh-abbr; }) + (mkZshPlugin { pkg = zsh-fzf-tab; }) + (mkZshPlugin { pkg = zsh-autoenv; }) + (mkZshPlugin { pkg = zsh-autopair; }) + (mkZshPlugin { pkg = zsh-nix-shell; }) + (mkZshPlugin { pkg = zsh-completions; }) + (mkZshPlugin { pkg = zsh-you-should-use; }) + (mkZshPlugin { pkg = zsh-autosuggestions; }) + (mkZshPlugin { pkg = zsh-navigation-tools; }) + (mkZshPlugin { pkg = zsh-fzf-history-search; }) + (mkZshPlugin { pkg = zsh-fast-syntax-highlighting; }) + (mkZshPlugin { pkg = zsh-history-substring-search; }) + ]; + + oh-my-zsh = { + enable = true; + plugins = [ + "argocd" + "direnv" + "git" + "golang" + "helm" + "httpie" + "kubectl" + "nomad" + "pass" + "podman" + "ssh-agent" + "systemd" + "terraform" + "vault" + ]; + }; + + history = { + extended = true; + ignoreDups = true; + expireDuplicatesFirst = true; + }; + }; +} diff --git a/modules/users/personal/crstl/window-manager/dunst.nix b/modules/users/personal/crstl/window-manager/dunst.nix new file mode 100644 index 0000000..c745112 --- /dev/null +++ b/modules/users/personal/crstl/window-manager/dunst.nix @@ -0,0 +1,50 @@ +{ + services.dunst = { + enable = true; + settings = { + global = { + markup = "yes"; + plain_text = "no"; + sort = "yes"; + indicate_hidden = "yes"; + alignment = "left"; + bounce_freq = 0; + show_age_threshold = 1; + word_wrap = "yes"; + ignore_newline = "no"; + stack_duplicates = "yes"; + hide_duplicates_count = "no"; + shrink = "no"; + idle_threshold = 0; + transparency = 5; + monitor = "keyboard"; + follow = "mouse"; + sticky_history = "yes"; + history_length = 15; + show_indicators = "yes"; + line_height = 5; + separator_height = 1; + padding = 5; + horizontal_padding = 5; + startup_notification = true; + icon_position = "right"; + max_icon_size = 80; + frame_width = 3; + }; + shortcuts = { + close = "ctrl+space"; + close_all = "ctrl+shift+space"; + context = "mod4+u"; + }; + urgency_low = { + timeout = 3; + }; + urgency_normal = { + timeout = 5; + }; + urgency_critical = { + timeout = 10; + }; + }; + }; +} diff --git a/modules/users/personal/crstl/window-manager/rofi.nix b/modules/users/personal/crstl/window-manager/rofi.nix new file mode 100644 index 0000000..e98aee8 --- /dev/null +++ b/modules/users/personal/crstl/window-manager/rofi.nix @@ -0,0 +1,51 @@ +{ lib +, pkgs +, config +, ... +}: +let + # https://github.com/adi1090x/rofi + style = "4"; + type = "2"; + color = "onedark"; + + rofi-themes-adi1090x = pkgs.stdenv.mkDerivation { + name = "rofi-themes-adi1090x"; + src = pkgs.fetchFromGitHub { + owner = "adi1090x"; + repo = "rofi"; + rev = "ef71554d8b7097cbce1953f56d2d06f536a5826f"; + sha256 = "sha256-RePXizq3I7+u1aJMswOhotIqTVdPhaAGZQqn51lg2jY="; + }; + installPhase = "mkdir -p $out; cp -R * $out/"; + }; + theme = "adi1090x-${style}-${type}-${color}"; +in +{ + home.file = { + "${config.xdg.configHome}/rofi/themes/${theme}.rasi" = { + source = "${rofi-themes-adi1090x}/files/launchers/type-${type}/style-${style}.rasi"; + }; + "${config.xdg.configHome}/rofi/themes/shared/colors.rasi" = { + source = "${rofi-themes-adi1090x}/files/launchers/type-${type}/shared/colors.rasi"; + }; + "${config.xdg.configHome}/rofi/themes/shared/fonts.rasi" = { + source = "${rofi-themes-adi1090x}/files/launchers/type-${type}/shared/fonts.rasi"; + }; + "${config.xdg.configHome}/rofi/colors/${color}.rasi" = { + source = "${rofi-themes-adi1090x}/files/colors/${color}.rasi"; + }; + }; + + + programs.rofi = { + enable = true; + terminal = "${pkgs.alacritty}/bin/alacritty"; + theme = lib.mkForce theme; + extraConfig = { + monitor = -1; + # font = osConfig.stylix.fonts.monospace.name; + modi = "window,drun,run,ssh"; + }; + }; +} diff --git a/modules/users/personal/crstl/window-manager/sway.nix b/modules/users/personal/crstl/window-manager/sway.nix new file mode 100644 index 0000000..f770561 --- /dev/null +++ b/modules/users/personal/crstl/window-manager/sway.nix @@ -0,0 +1,355 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + swayr # A window switcher (and more) for sway + + wdisplays # A graphical application for configuring displays in Wayland compositors + + bemenu # wayland clone of dmenu + mako # notification system developed by swaywm maintainer + #wpaperd # Minimal wallpaper daemon for Wayland + oguri # A very nice animated wallpaper daemon for Wayland compositors + + wl-clipboard # wl-copy and wl-paste for copy/paste from stdin / stdout + clipman # A simple clipboard manager for Wayland + xclip # Tool to access the X clipboard from a console application + xsel # Command-line program for getting and setting the contents of the X selection + + grim # screenshot functionality + slurp # screenshot functionality + + brightnessctl # This program allows you read and control device brightness + playerctl # ommand-line utility and library for controlling media players that implement MPRIS + + wev + ]; + + wayland.windowManager.sway = { + enable = true; + xwayland = true; + wrapperFeatures.gtk = true; + swaynag.enable = true; + + systemd = { + enable = true; + xdgAutostart = true; + }; + + config = rec { + bars = [ ]; + assigns = { }; + + keybindings = { + "${modifier}+1" = "workspace number 1"; + "${modifier}+2" = "workspace number 2"; + "${modifier}+3" = "workspace number 3"; + "${modifier}+4" = "workspace number 4"; + "${modifier}+5" = "workspace number 5"; + "${modifier}+6" = "workspace number 6"; + "${modifier}+7" = "workspace number 7"; + "${modifier}+8" = "workspace number 8"; + "${modifier}+9" = "workspace number 9"; + "${modifier}+a" = "focus parent"; + "${modifier}+d" = menu; + "${modifier}+e" = "exec ${pkgs.swaynag-battery}/bin/swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'"; + "${modifier}+f" = "fullscreen toggle"; + "${modifier}+l" = "exec ${pkgs.swaylock}/bin/swaylock"; + "${modifier}+r" = "mode resize"; + "${modifier}+y" = "floating disable"; + "${modifier}+x" = "floating enable"; + "${modifier}+s" = "layout stacking"; + "${modifier}+u" = "layout toggle split"; + "${modifier}+v" = "splitv"; + "${modifier}+h" = "splith"; + "${modifier}+w" = "layout tabbed"; + "${modifier}+Left" = "focus left"; + "${modifier}+Right" = "focus right"; + "${modifier}+Up" = "focus up"; + "${modifier}+Down" = "focus down"; + "${modifier}+minus" = "scratchpad show"; + "${modifier}+space" = "focus mode_toggle"; + "${modifier}+Return" = terminal; + "${modifier}+Print" = "exec ${pkgs.grim}/bin/grim ~/screenshot_$(date +%Y%m%d_%H%M%S).png"; + "${modifier}+Shift+1" = "move container to workspace number 1"; + "${modifier}+Shift+2" = "move container to workspace number 2"; + "${modifier}+Shift+3" = "move container to workspace number 3"; + "${modifier}+Shift+4" = "move container to workspace number 4"; + "${modifier}+Shift+5" = "move container to workspace number 5"; + "${modifier}+Shift+6" = "move container to workspace number 6"; + "${modifier}+Shift+7" = "move container to workspace number 7"; + "${modifier}+Shift+8" = "move container to workspace number 8"; + "${modifier}+Shift+9" = "move container to workspace number 9"; + "${modifier}+Shift+Left" = "move left"; + "${modifier}+Shift+Right" = "move right"; + "${modifier}+Shift+Up" = "move up"; + "${modifier}+Shift+Down" = "move down"; + "${modifier}+Shift+space" = "floating toggle"; + "${modifier}+Shift+minus" = "move scratchpad"; + "${modifier}+Shift+q" = "kill"; + "${modifier}+Shift+r" = "reload"; + "${modifier}+Shift+s" = "exec ${pkgs.systemd}/bin/systemctl suspend"; + + "Ctrl+${modifier}+Left " = "workspace prev"; + "Ctrl+${modifier}+Right" = "workspace next"; + + "XF86AudioLowerVolume" = "exec ${pkgs.pulseaudioFull}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%"; + "XF86AudioRaiseVolume" = "exec ${pkgs.pulseaudioFull}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%"; + "XF86AudioMute" = "exec ${pkgs.pulseaudioFull}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle"; + + "XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause"; + "XF86AudioPause" = "exec ${pkgs.playerctl}/bin/playerctl play-pause"; + + "XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next"; + "XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl previous"; + + "XF86AudioMicMute" = "exec ${pkgs.ponymix}/bin/ponymix -t source toggle"; + + "XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-"; + "XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%+"; + }; + + modifier = "Mod4"; + menu = "exec ${pkgs.rofi}/bin/rofi -show drun"; + terminal = "exec ${pkgs.kitty}/bin/kitty"; + keycodebindings = { }; + + up = "e"; + down = "n"; + left = "h"; + right = "i"; + + window = { + border = 5; + commands = [ + # swaymsg -t get_tree + { + criteria.app_id = "VirtualBox Machine"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.calendar"; + command = "floating enable"; + } + { + criteria.app_id = "OpenSnitch*"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.appcenter"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.calculator"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.files"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.photos"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.screenshot"; + command = "floating enable"; + } + { + criteria.app_id = "io.elementary.switchboard"; + command = "floating enable"; + } + { + criteria.app_id = "evince"; + command = "floating enable"; + } + { + criteria.app_id = "file-roller"; + command = "floating enable"; + } + { + criteria.app_id = ".blueman-manager-wrapped"; + command = "floating enable"; + } + { + criteria.app_id = "Alacritty"; + command = "opacity set 0.9"; + } + { + criteria.app_id = "Blueman-manager"; + command = "floating enable"; + } + { + criteria.app_id = "Bluetooth-wizard"; + command = "floating enable"; + } + { + criteria.app_id = "cantata"; + command = "floating enable"; + } + { + criteria.app_id = "com.nextcloud.desktopclient.nextcloud"; + command = "floating enable"; + } + { + criteria.app_id = "Element"; + command = "floating enable"; + } + { + criteria.app_id = "Evince"; + command = "floating enable"; + } + { + criteria.app_id = "Evolution-alarm-notify"; + command = "floating enable"; + } + { + criteria.app_id = "Evolution"; + command = "floating enable"; + } + { + criteria.app_id = "Fluffychat"; + command = "floating enable"; + } + { + criteria.app_id = "gnome-calculator"; + command = "floating enable"; + } + { + criteria.app_id = "Jitsi"; + command = "floating enable"; + } + { + criteria.app_id = "MPlayer"; + command = "floating enable"; + } + { + criteria.app_id = "Nautilus"; + command = "floating enable"; + } + { + criteria.app_id = "nm-connection-editor"; + command = "floating enable"; + } + { + criteria.app_id = "org.kde.kdeconnect.app"; + command = "floating enable"; + } + { + criteria.app_id = "org.kde.kdeconnect.sms"; + command = "floating enable"; + } + { + criteria.app_id = "org.kde.kdeconnect-indicator"; + command = "floating enable"; + } + { + criteria.app_id = "org.kde.kdeconnect.handler"; + command = "floating enable"; + } + { + criteria.app_id = "pavucontrol"; + command = "floating enable"; + } + { + criteria.app_id = "Pgadmin3"; + command = "floating enable"; + } + { + criteria.app_id = "Qemu-system-x86_64"; + command = "floating enable"; + } + { + criteria.app_id = "qtpass"; + command = "floating enable"; + } + { + criteria.app_id = "Shotwell"; + command = "floating enable"; + } + { + criteria.app_id = "Simple-scan"; + command = "floating enable"; + } + { + criteria.app_id = "Simplescreenrecorder"; + command = "floating enable"; + } + { + criteria.app_id = "telegramdesktop"; + command = "floating enable"; + } + { + criteria.app_id = "Thunar"; + command = "floating enable"; + } + { + criteria.app_id = "transmission-gtk"; + command = "floating enable"; + } + { + criteria.app_id = "virt-manager"; + command = "floating enable"; + } + { + criteria.app_id = "Wireshark"; + command = "floating enable"; + } + { + criteria.app_id = "X2GoAgent"; + command = "floating enable"; + } + { + criteria.app_id = "x2goclient"; + command = "floating enable"; + } + { + criteria.app_id = "org.gnome.Hamster.GUI"; + command = "floating enable"; + } + { + criteria.class = "Signal"; + command = "floating enable"; + } + { + criteria.app_id = "org.gnome.Calendar"; + command = "floating enable"; + } + { + criteria.app_id = "org.pipewire.Helvum"; + command = "floating enable"; + } + { + criteria.app_id = "org.gnome.Software"; + command = "floating enable"; + } + ]; + hideEdgeBorders = "none"; + titlebar = false; + }; + + workspaceLayout = "default"; + + output = { + "*" = { + # bg = "/home/crstl/Pictures/mems/JOM Optical Switches-920.jpg fill"; + }; + }; + + input = { + "type:keyboard" = { + xkb_layout = "de"; + }; + }; + }; + + # extraConfig = '' + # include /etc/sway/config.d/* + + # exec ${pkgs.swayidle}/bin/swayidle -w \ + # timeout 300 "swaylock -f" \ + # timeout 300 'swaymsg "output * dpms off"' \ + # resume 'swaymsg "output * dpms on"' \ + # before-sleep "swaylock -f" + # ''; + }; +} diff --git a/modules/users/personal/crstl/window-manager/swayidle.nix b/modules/users/personal/crstl/window-manager/swayidle.nix new file mode 100644 index 0000000..cd39894 --- /dev/null +++ b/modules/users/personal/crstl/window-manager/swayidle.nix @@ -0,0 +1,35 @@ +{ pkgs, ... }: +{ + services.swayidle = { + enable = true; + events = [ + { + event = "before-sleep"; + command = "${pkgs.swaylock}/bin/swaylock -efF"; + } + { + event = "after-resume"; + command = ''${pkgs.sway}/bin/swaymsg "output * dpms on"''; + } + { + event = "lock"; + command = "${pkgs.swaylock}/bin/swaylock -efF"; + } + ]; + timeouts = [ + { + timeout = 270; + command = ''${pkgs.libnotify}/bin/notify-send -t 30000 -- "Screen will lock in 30 seconds"''; + } + { + timeout = 300; + command = "${pkgs.swaylock}/bin/swaylock -efF"; + } + { + timeout = 600; + command = ''${pkgs.sway}/bin/swaymsg "output * dpms off"''; + resumeCommand = ''${pkgs.sway}/bin/swaymsg "output * dpms on"''; + } + ]; + }; +} diff --git a/modules/users/personal/crstl/window-manager/waybar.nix b/modules/users/personal/crstl/window-manager/waybar.nix new file mode 100644 index 0000000..70a0345 --- /dev/null +++ b/modules/users/personal/crstl/window-manager/waybar.nix @@ -0,0 +1,209 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ font-awesome ]; + + programs.waybar = { + enable = true; + + # package = pkgs.waybar.override {pulseSupport = true;}; + + systemd = { + enable = true; + target = "graphical-session.target"; + }; + + # font-family: "${osConfig.stylix.fonts.monospace.name}"; + style = '' + * { + font-size: 14px; + border: none; + border-radius: 0; + min-height: 0; + } + ''; + + settings = [ + { + gtk-layer-shell = true; + + layer = "top"; + height = 30; + + tray = { + icon-size = 20; + spacing = 10; + }; + + modules-left = [ + "sway/workspaces" + "sway/mode" + "sway/scratchpad" + "sway/window" + ]; + + modules-center = [ + "custom/launcher" + "clock" + "custom/lock" + "custom/power-menu" + "wireplumber" + ]; + + modules-right = [ + "mpd" + "network" + "battery" + "backlight" + "cpu" + "memory" + "disk" + "temperature" + "tray" + ]; + + "custom/launcher" = { + format = " ❄ "; + on-click = "${pkgs.rofi}/bin/rofi -show drun &"; + }; + + "custom/lock" = { + format = "  "; + on-click = "${pkgs.swaylock}/bin/swaylock"; + tooltip = false; + }; + + "custom/power-menu" = { + format = " ⏻ "; + on-click = "${pkgs.systemd}/bin/loginctl terminate-user $USER"; + }; + + clock = { + format = "{:%d.%m.%Y | %H:%M}"; + tooltip-format = "{calendar}"; + on-click = "${pkgs.gnome.gnome-calendar}/bin/gnome-calendar"; + }; + + battery = { + format = " {icon} {capacity} %"; + format-alt = "{icon} {time}"; + format-charging = " {capacity} %"; + format-discharging = "{icon} {capacity} %"; + format-plugged = " {capacity} %"; + format-icons = [ + "" + "" + "" + "" + "" + ]; + interval = 10; + states = { + good = 80; + warning = 20; + critical = 10; + }; + tooltip = true; + on-click = "${pkgs.gnome.gnome-power-manager}/bin/gnome-power-manager"; + }; + + cpu = { + format = " {usage} %"; + states = { + warning = 70; + critical = 90; + }; + tooltip = true; + interval = 1; + }; + + temperature = { + format = " {temperatureC} °C"; + }; + + memory = { + format = " {percentage} %"; + tooltip-format = "{percentage}% used of {total} GB"; + states = { + warning = 70; + critical = 90; + }; + tooltip = true; + interval = 1; + }; + + disk = { + format = "󰋊 {percentage_free} %"; + path = "/home"; + states = { + warning = 70; + critical = 90; + }; + interval = 1; + tooltip = true; + tooltip-format = "{percentage_free} % are {free} of {total} GB"; + on-click = "${pkgs.gnome.gnome-disk-utility}/bin/gnome.gnome-disk-utility"; + }; + + network = { + format-alt = "{ipaddr}/{cidr}"; + format-disconnected = "⚠ Disconnected"; + format-ethernet = " {ifname}: {ipaddr}/{cidr}"; + format-linked = " {ifname} (No IP)"; + format-wifi = " {essid} ({signalStrength} %)"; + on-click = "${pkgs.networkmanagerapplet}/bin/nm-connection-editor"; + tooltip = true; + interval = 1; + }; + + pulseaudio = { + format = " {icon} {volume} %"; + format-bluetooth = " {icon} {volume} %"; + format-bluetooth-muted = " {icon}"; + format-muted = " {icon}"; + format-source = " {volume} %"; + format-source-muted = " {icon}"; + on-click = "${pkgs.pavucontrol}/bin/pavucontrol"; + on-scroll-up = "${pkgs.ponymix}/bin/ponymix increase 1"; + on-scroll-down = "${pkgs.ponymix}/bin/ponymix decrease 1"; + }; + + wireplumber = { + format = " {icon} {volume} %"; + format-muted = " {icon}"; + format-source = " {volume} %"; + format-source-muted = " {icon}"; + on-click = "${pkgs.pavucontrol}/bin/pavucontrol"; + on-click-right = "${pkgs.helvum}/bin/helvum"; + on-scroll-up = "${pkgs.ponymix}/bin/ponymix increase 1"; + on-scroll-down = "${pkgs.ponymix}/bin/ponymix decrease 1"; + }; + + mpd = { + format-icons = [ "🎜" ]; + on-click = "${pkgs.cantata}/bin/cantata"; + }; + + backlight = { + format = "{icon} {percent} %"; + format-icons = [ + "" + "" + ]; + on-scroll-up = "${pkgs.brillo}/bin/brillo -e -A 0.5"; + on-scroll-down = "${pkgs.brillo}/bin/brillo -e -U 0.5"; + device = "intel_backlight"; + }; + + "wlr/workspaces" = { + all-outputs = true; + format = "{icon}"; + format-icons = { + active = " 󰮯"; + default = ""; + }; + on-click = "activate"; + }; + } + ]; + }; +} diff --git a/modules/users/system/automat/default.nix b/modules/users/system/automat/default.nix new file mode 100644 index 0000000..a4d3ac9 --- /dev/null +++ b/modules/users/system/automat/default.nix @@ -0,0 +1,45 @@ +{ config, pkgs, lib, ... }: +{ + age.secrets.sshPrivateAutomat = { + file = ./ssh-private.age; + owner = "${config.users.users.automat.group}"; + }; + + users = { + users.automat = { + uid = lib.mkForce 1080; + group = "automat"; + description = lib.mkForce "Automat build user"; + createHome = true; + home = "/var/lib/automat"; + extraGroups = + [ "users" ] + ++ lib.optionals config.virtualisation.libvirtd.enable [ "libvirtd" ] + ++ lib.optionals config.virtualisation.docker.enable [ "docker" ] + ++ lib.optionals config.virtualisation.podman.enable [ "podman" ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMm1kAmSNQBTBhhod951FNhPwXeIEz9It7NmHZ2d1LqJ" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPGG175tUqyZmN5a2ImRrEhZA5VtKdyxQMPJmymNCxGd" + ]; + isNormalUser = true; + shell = pkgs.bashInteractive; + }; + + groups.automat.gid = lib.mkForce config.users.users.automat.uid; + }; + + nix.settings.trusted-users = [ "automat" ]; + + services.displayManager.hiddenUsers = [ config.users.users.automat.name ]; + + home-manager = { + users.automat = { + home = { + username = config.users.users.automat.name; + stateVersion = "22.05"; + }; + + programs.home-manager.enable = true; + }; + }; +} diff --git a/modules/users/system/automat/ssh-private.age b/modules/users/system/automat/ssh-private.age new file mode 100644 index 0000000000000000000000000000000000000000..16f6f4893223d73c85e3606e2daafbb844c9e899 GIT binary patch literal 2864 zcmZXV`S0X(8OKHNU^EyMBpm7lNOWz!OwXCt-9_5zG3|7w?M&P0REW;>oKCOlblRCJ zr>KbBF@(4*i$sG*P}r=2#3+J+jk2PVLnJPTN5T)PlX}ya*DbOZN#mIBHJllZNXo1#Ti|9@ zIdG40&_Ub?IYp@2#Zr^4J^)f?QRIWxY@SKI$j##$2>)K*TOE?QjlUgo{tW;!z2ji;44me~TgIQ3B zaOL+iJ6e}X1sG-4TdmvGVl~)=elQ}KH0hJvS{2k;&G!Up+(8ts9qXLlbqH(ILy(1? zqCk6@V~8a1tOoOIC8lQPFbROr7eok$Kut(==R*Qn{n6*W#-<|3guE*-Hs#aVVBHaGL4 z@(OdU$Z$YXbCH1(t5UY%qIwv-tTEG$11MltR2?tq%Zm(ZmKI@0l0(Nf z0&YKkT(u$zoK@&lSxcoFcV^gp)(zsR&|FnDKVi)r(;}s@ocH8V4a}ysy-I7)AyqxL zG|XSKIoDCAQ-jI1beaJpD-CgpO}#i%reF;LfF3z$`Wt7;V`Q+6T2F$>1lNt3IAn%l zuRmVkN~F#_JvBLZ%7buI@k`2;mqmjdvo)qMQ8?EjnWUYyilIeLFa=XY647)yoZuO` z%=`1Xph51&(cv<1$;PVE7JlvqJ+iwBY7<7tqY%|lCYrf+=*tvbtdwR%gDyYRmjjQr z$FVd=a1wtz$8S5zcX0q#>TK%H#%fSDmJ0^=OQ1Q`Q_%;>84y|?WX#v<*sPom!?Iv) zu5+}T5}00Clfsjy{ft=CG;)uIO~i+i zl`^Ay)beN=?QVZjUR_m@iBL%E4U(hZDDGA}q@JLBuoQ%9<;+q0^Na zr%(4CsuYF|F&xVX1C?&M9nrYK&6&)`Bm;EhhITYf8hMFM)>&m7vC!Bj`YfrKF-t6l za|qWE(nr?70^$>01N0PWp`2E;0(*_O9EbGqT;CWm+eTx|h6ictNiHxVl!ze;t<4W< z>uB0UZcwALt~rZfCaeL}7}|!8@L4+V_jmg|>x8yeLCTlTQLvyqa zVMHKUK~MUrvYkn$YowyN8D~l*69r~Deroj9Xkjo$7plURZD63c>GxLu?~S*8>t(JO zm)o;V!LTeHYUNq|Xw=^Db_7QYm@nl1h{S1IC#S0!JM!CJjaUxjsi&hukk!JXYKsI@ zT2LZsCP9umEt*qW`a+`s)H%jCb-O^5vhD%t5Q4%SABBsKLM*^_hu;LIVpN*IH8K}M zo0MQ0oJDIjmRcDxVQX>Bb4^W9S*jRNeli&Af=-3hB!R3x2Btz+JI1&5d?IYy4I;tR zveNaYZS`Q5lIMm#^%_l8pBv*z0*oY8YQcpY77<^YPm8LR5{Nq$Id0YSSy^N99^U65 zXrM?@fdoP?LCC%;9J9$uh(%^u57eq1dR=f(%zz0mOkDwCx@_hWVso$@WhL5LmfH=y zN=T+QHdS=Y`Y0)~3MFRq6c%!cEpT@r&mx-d8hY&NT;5v;$7FIiCv=Le566%v`;}{w zB>>>drLm4j9WV)I>qMJ|5jz+}w3<%`()QiB4GR-f04XG(UByNt#SwNwv?vwkWwwQs z8d<8-Fo|u7tZi*=)d!Pyf{T1psesJhV0lnQoe?(+JBrd-EL9Ox%?^dEJct?Bk{v%g zWABa5hir*^Y3Gh--~7OTPD^h2{3Fm!^cBp%t{j|-U3wMt%&vF7==|&F9jOUpG$u6Mp?Lck%en1$?0O(bwMk z<) z!&~nnF8#yKClCMV7vsYZe)fvf-oN9vrw+dP#*056P0tFnlXkqZ>(Gf;zxT>h@4qE{ z^eggXYvDceQ=dG?-aj7d|2*(;tMj#gAGl^0d+vp2-U9DG`%AA~@zYE8{CIh{bHf9t zWBkGUzj@vtFM96kM}95@J;k(VthOZL0jZgmV=Wcy^<`6%b+;#jtkL-Tv6X#rX z(*B$8ORp;Se)YEN>)&|j-p-u|oX=eF#J%Sp_u%Cjwm$tG?ylxF_j$(?C4KGh_q_Do Soll)|d+l}Vyxrga>;C{kMc&^4 literal 0 HcmV?d00001 diff --git a/modules/users/system/root/default.nix b/modules/users/system/root/default.nix new file mode 100644 index 0000000..780d797 --- /dev/null +++ b/modules/users/system/root/default.nix @@ -0,0 +1,14 @@ +{ config, ... }: +{ + age.secrets.passwordRoot.file = ./password.age; + + users.users.root = { + openssh.authorizedKeys.keys = config.users.users.crstl.openssh.authorizedKeys.keys; + hashedPasswordFile = config.age.secrets.passwordRoot.path; + }; + + home-manager.users.root.home = { + username = config.users.users.root.name; + stateVersion = "23.11"; + }; +} diff --git a/modules/users/system/root/password.age b/modules/users/system/root/password.age new file mode 100644 index 0000000000000000000000000000000000000000..b2f4e43cbd10d1535d7a437eaf753ea8215a5f4e GIT binary patch literal 2570 zcmZXVInV3{6^0QM5pDv_4K!$qAcU+BFXI&ng!kPZ+v9DjcxF7_W^9jln?(o-2og}G zAyA})2GY$B#JAzzHM|_&{9uT1QZ%bw~6nQr9;kT zKLMtHJDzkayUQVFp^2^6vo&b_LJ4f;Z&hSxP>b5j@ICLI($uwRb9;j|>-7YQ;j*Hb zA;>aui~C+F?^fCA4NGKH%@qv1;~Lop{3;V?lRHpXUrivja}+7ONcdS^xvp6i#6Gb2 z-A#}~M?I&tUA!T(-Apoo-|W!bK3zDFWHba1lGBYdd%ANcUg`|Hwt{wyWG4+^thPjI zDi3ELTd`QnHH9n`78n<#@O_~~WUDFtu8PIZOmT`Ut4KIb1*MW{hM2udcy^%PrlCA5 z*$(2b)Z$7qtT@0;OJ@$A4m+%ZapK@yk*O}WG%?(ibtl&Hnpbocjai?1Of=+}?X1&Q zEQ8KlFpq}@0L3_Yt@aTv5;Y$jF-9M^d6LJ=X~ZRahjX?^P;*$qkkN)qdQ#ij*yr=% zW-&Wu(JnyYcEx&W8osgTW9e`N%k}U+KBqFdP=kOa^QgC=J#R~QE6G_k41&es)Ocb? zmoG90;QJi~M@Doq^PEbOaACK6IT{sh9dk`&hlQU5yY$nmdej~K>MvVbgH%U7C$fnY z7aD*A_c-U&-bxHHuEe&XOqSepIKexCig5V#HkjK>t83G7Qx=QN|l;H%%edD9WjTNE(zpGLyNA+O%ZZp4Fgj%QpJpD#v5Sic1Aay31gk>q655U#1c(htXW`g@Rh!I$ll-@ZRBq0&E8rzA}cOIQm4Xr zN^^6*(x=US4!BbedZ3esMMG2~o>%RVi;nyle`Z`fYC+`%@-Kc3>}6%jQX3Ve9wmeG zj_~3|b$JUbgI=RKwIm&b}qH+IHV``MkZBEMe|>j(vNc&;s3*ZS~! zgyw3Y?l`Me2s;5s$25l<*)}?{UG#Fe?s>{#AS5;0%;8|7Pet!8+!D%u!OaTN+GjRk zJO@-kfhW_-{Phsm+JQFC9?Gm7M*E(ON#wlm>!D6zAk5g)>EgtcDn(aV?7{-ar>J7F z*0Jww8ivWh%WHUCoEO~U9mEFHrtu48z(RXGRszl#(Hf`6VEY(3|B~!nGOe&3oaZj6 zmI`o9YRhBKhJ`})tTo+421qe1({xjz z-t==R?smt1yJuv`aZd?dYKjn^jn%NW5zvuiXJlnB!bUKf(1FJWlSN_Ys0fo^Q1@-j zb2e6(ar#1&<35Kz()t}QTGuRXM=Ix|Jm@raB%R1mko_JGk(LWdC;*id<~kte7QQY> zwRVT>F%BMfr8O=P!8wEZM281+w2?! z#>emNm{-{7p1`Yjr*zU*2pXq5`zdYj2V^~MBF4_5WeN&mEs0bv46tr8=c*ZrU^^CA z^Sf0hk@F-mHb6*PXd8)p>{99ose0bT>;jG~Xq>50N;*?MTU;qCX#fA8_`FNzGFBh2 zyY^kin58tvSqI}MZ*R?dDQ0cmdZvrpD0^T9Ygw?H3Xoq+AB#)q;t5ivN(ao(X zdt6)^fF3^fX-2J_hGJcfgyWqwBKzpJkxj6=dFxVaNJW@C@h`Z!CGE4!ridUB;tjtL zWgB(!@gVrpq~YA-!^tna5@q8QB;1kuDY{`TMBh`w9>_jj*u-UB}ItzW*vz5SByeE;p&KmYPqjBfe$$3Oko zUs&(I_3FF#m)?m!dhfO0{O$ex=RX+U{r37N?I$1m)c2OlKYo_{hg&}!@ptyf8~PVM z`@ygN@b|Z#o!/dev/null && menu) + ''; + + commands = [ + { + name = "reload"; + command = "direnv reload"; + help = "Reload the local environment."; + category = "development"; + } + { + name = "fmt"; + command = "nix fmt"; + help = "Run reformating with nix flake."; + category = "development"; + } + { + name = "generate"; + command = "${inputs'.nixos-generators.packages.nixos-generate}/bin/nixos-generate $@"; + help = "Generate NixOS configuration with nixos-generators."; + category = "development"; + } + { + name = "health"; + command = "${lib.getExe pkgs.nix-health}"; + help = "Checking the health of your Nix setup."; + category = "nix"; + } + { + name = "list"; + command = "nix flake show"; + help = "Run nix flake cheshow."; + category = "nix"; + } + { + name = "check"; + command = "nix flake check"; + help = "Run nix flake check."; + category = "nix"; + } + { + name = "build"; + command = "nix build"; + help = "Run nix flake build."; + category = "nix"; + } + { + name = "run"; + command = "nix run .\#run-qemu-vm -- $@"; + help = "Run host build in a qemu vm."; + category = "nix"; + } + { + name = "repl"; + command = "nix repl -f ."; + help = "Evaluate expressions interactive with Nix repl."; + category = "nix"; + } + { + name = "inspect"; + command = "${lib.getExe pkgs.nix-inspect}"; + help = "Inspect NixOS config and Nix expressions."; + category = "nix"; + } + { + name = "cve"; + command = "nix build && ${lib.getExe pkgs.vulnix} ./result"; + help = "Run NixOS security scanner with vulnix."; + category = "security"; + } + { + name = "secrets"; + command = "${pkgs.trivy}/bin/trivy fs ."; + help = "All-in-one security scanner with trivy."; + category = "security"; + } + { + name = "age"; + command = "${pkgs.agenix}/bin/agenix $@"; + help = "Manage NixOS secrets with agenix."; + category = "operations"; + } + { + name = "infect"; + command = "${inputs'.nixos-anywhere.packages.nixos-anywhere}/bin/nixos-anywhere $@"; + help = "Install NixOS everywhere via ssh."; + category = "operations"; + } + { + name = "deploy"; + command = "${pkgs.deploy-rs.deploy-rs}/bin/deploy $@"; + help = "Deploy NixOS remote machines with deploy-rs."; + category = "operations"; + } + { + name = "show"; + command = "terranix --pkgs /run/current-system/nixpkgs terranix/default.nix"; + help = "Show terranix state."; + category = "terraform"; + } + { + name = "validate"; + command = "nix run .\#tf-validate"; + help = "Run terraform validate."; + category = "terraform"; + } + { + name = "apply"; + command = "nix run .\#tf-apply"; + help = "Run terraform apply."; + category = "terraform"; + } + { + name = "destroy"; + command = "nix run .\#tf-destroy"; + help = "Run terraform destroy."; + category = "terraform"; + } + { + name = "state"; + command = "nix run .\#tf-state -- $@"; + help = "Manage terraform state."; + category = "terraform"; + } + ]; + }; + + apps = { + run-qemu-vm = { + type = "app"; + program = toString (pkgs.writers.writeBash "run-qemu-vm" '' + if [[ ! -z "$@" ]]; then + nixos-rebuild build-vm --flake .#$@ + export QEMU_NET_OPTS="hostfwd=tcp::2221-:22" + ./result/bin/run-$@-vm + else + echo "Usage: "$0" " + exit 1 + fi + ''); + }; + + nix-upgrades = { + type = "app"; + program = toString (pkgs.writers.writeBash "nix-upgrades" '' + set -eou pipefail + + NORMAL="\033[0m" + RED="\033[0;31m" + YELLOW="\033[0;33m" + GREEN="\033[0;32m" + SKULL="💀" + CHECK="✅" + WARNING="⚠️" + FIRE="🔥" + MAG="🔍" + + echo + echo -e "$YELLOW$MAG Scanning for upgradable hosts...$NORMAL" + echo + + ${lib.concatMapStringsSep "\n" (host: + let + inherit (self.hosts.${host}) address; + in lib.optionalString (address != null) '' + echo -n -e "${host}: $RED" + RUNNING=$(ssh "${address}" "readlink /run/current-system") + if [ $? = 0 ] && [ -n "$RUNNING" ]; then + CURRENT=$(nix eval --raw ".#nixosConfigurations.${host}.config.system.build.toplevel" 2>/dev/null) + RUNNING_VER=$(basename $RUNNING|rev|cut -d - -f 1|rev) + RUNNING_DATE=$(echo $RUNNING_VER|cut -d . -f 3) + CURRENT_VER=$(basename $CURRENT|rev|cut -d - -f 1|rev) + CURRENT_DATE=$(echo $CURRENT_VER|cut -d . -f 3) + + if [ "$RUNNING" = "$CURRENT" ]; then + echo -e "$GREEN$CHECK Current: $NORMAL $RUNNING_VER" + elif [ $RUNNING_DATE -gt $CURRENT_DATE ]; then + echo -e "$GREEN$FIRE Newer: $NORMAL $RUNNING_VER > $CURRENT_VER" + elif [ "$RUNNING_VER" = "$CURRENT_VER" ]; then + echo -e "$YELLOW$WARNING Modified: $NORMAL $RUNNING_VER" + elif [ -n "$RUNNING_VER" ]; then + echo -e "$RED$SKULL Outdated: $NORMAL $RUNNING_VER < $CURRENT_VER" + else + echo -e "$RED$SKULL Error: $NORMAL $RUNNING_VER" + fi + else + echo -e "$RED$SKULL SSH Connection Failed$NORMAL" + fi + echo -n -e "$NORMAL" + '') (builtins.attrNames self.nixosConfigurations)} + ''); + }; + }; + }; +} diff --git a/nix/home-manager.nix b/nix/home-manager.nix new file mode 100644 index 0000000..cba98b8 --- /dev/null +++ b/nix/home-manager.nix @@ -0,0 +1,49 @@ +{ withSystem, inputs, ... }: +let + inherit (inputs) self home-manager nixpkgs; + inherit (nixpkgs) lib; + + genModules = hostName: { homeDirectory, ... }: { config, ... }: { + imports = [ (../hosts + "/${hostName}") ]; + nix.registry = { + nixpkgs.flake = nixpkgs; + p.flake = nixpkgs; + }; + + home = { + inherit homeDirectory; + sessionVariables.NIX_PATH = lib.concatStringsSep ":" [ "nixpkgs=${config.xdg.dataHome}/nixpkgs" ]; + }; + + xdg = { + dataFile.nixpkgs.source = nixpkgs; + configFile."nix/nix.conf".text = '' + flake-registry = ${config.xdg.configHome}/nix/registry.json + ''; + }; + }; + + genConfiguration = hostName: { hostPlatform, type, ... }@attrs: + withSystem hostPlatform ( + { pkgs, ... }: + home-manager.lib.homeManagerConfiguration { + inherit pkgs; + modules = [ (genModules hostName attrs) ]; + extraSpecialArgs = { + hostType = type; + inherit inputs self; + }; + } + ); +in +{ + flake.homeConfigurations = lib.mapAttrs genConfiguration ( + lib.filterAttrs (_: host: host.type == "home-manager") self.hosts + ); + + perSystem = { lib, self', ... }: { + checks = lib.mapAttrs' + (name: config: lib.nameValuePair "home-manager-${name}" config.activation-script) + (self'.legacyPackages.homeConfigurations or { }); + }; +} diff --git a/nix/hosts.nix b/nix/hosts.nix new file mode 100644 index 0000000..66dd490 --- /dev/null +++ b/nix/hosts.nix @@ -0,0 +1,133 @@ +let + hosts = { + dev-vm = mkHost { + type = "nixos"; + address = "192.168.122.26"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJg26fCklaaX7aakk8YKsBE1cvZmK7BbGRepnlljO0A"; + remoteBuild = false; + }; + srxgp00 = mkHost { + type = "nixos"; + address = "srxgp00.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKTMIY7REnKImy/UZ5SBcFLVywHjNtJB+TkwfnI8oqR3"; + remoteBuild = false; + }; + srxgp01 = mkHost { + type = "nixos"; + address = "srxgp01.vpn.srx.dev"; + hostPlatform = "aarch64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4z3JIB0cwLTHpek2yXvFiUIzBkQf39Y0XE3tG8/02U"; + remoteBuild = false; + }; + srxgp02 = mkHost { + type = "nixos"; + address = "srxgp02.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILOatQqlVBjRGIK6Y95O73XOkvN6BOnn7xPTKA9olJYZ"; + remoteBuild = false; + }; + srxk8s00 = mkHost { + type = "nixos"; + address = "srxk8s00.vpn.srx.dev"; + hostPlatform = "aarch64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKnculMw+8hP3gix/K4OBqGqrx16Cs2ODxM0V52YXNrT"; + remoteBuild = false; + }; + srxnas00 = mkHost { + type = "nixos"; + address = "srxnas00.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHiUYwPlTez18gwbhWC3sB6LoYmDPz0suTF5n3zEGBhg"; + remoteBuild = false; + }; + srxnas01 = mkHost { + type = "nixos"; + address = "srxnas01.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUTiU0WPTLF98yla0Mmit6eIfPpcrDKRemjM1VoHc9w"; + remoteBuild = false; + }; + srxws00 = mkHost { + type = "nixos"; + address = "srxws00.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFlG7m82O7W/Btp98ddipBiIvYkXAy1TP3kyRfYuL0aF"; + remoteBuild = false; + }; + srxnb00 = mkHost { + type = "nixos"; + address = "srxnb00.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII+ylR/an6nDQR1CBlWjPnUGf+2JJ9S3APaERFiZ6exT"; + remoteBuild = false; + }; + srxws01 = mkHost { + type = "nixos"; + address = "srxws01.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM54ABNX402t+q3hNKjJc1rhXLJckgCLlaDug4+7nfN2"; + remoteBuild = false; + }; + srxtab00 = mkHost { + type = "nixos"; + address = "srxtab00.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDJf8iY3QMWoJdYibBsTA9CZE+GQluhp/N+0Vxid7nSP"; + remoteBuild = false; + }; + srxmc00 = mkHost { + type = "nixos"; + address = "srxmc00.vpn.srx.dev"; + hostPlatform = "x86_64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGXv0QxmY2C44SvnV3HZd+wBhxc//ox8YhfDnh2L1k4f"; + remoteBuild = false; + }; + srxfdm00 = mkHost { + type = "nixos"; + address = "srxfdm00.vpn.srx.dev"; + hostPlatform = "aarch64-linux"; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG2Z5iETExjTSn+F1QFwSnyrn5UdSnkn6C+rIM7Dssei"; + remoteBuild = false; + }; + }; + + hasSuffix = + suffix: content: + let + inherit (builtins) stringLength substring; + lenContent = stringLength content; + lenSuffix = stringLength suffix; + in + lenContent >= lenSuffix && substring (lenContent - lenSuffix) lenContent content == suffix; + + mkHost = + { type + , hostPlatform + , address ? null + , pubkey ? null + , homeDirectory ? null + , remoteBuild ? true + , large ? false + , + }: + if type == "nixos" then + assert address != null && pubkey != null; + assert (hasSuffix "linux" hostPlatform); + { inherit type hostPlatform address pubkey remoteBuild large; } + else if type == "darwin" then + assert pubkey != null; + assert (hasSuffix "darwin" hostPlatform); + { inherit type hostPlatform pubkey large; } + else if type == "home-manager" then + assert homeDirectory != null; + { inherit type hostPlatform homeDirectory large; } + else + throw "unknown host type '${type}'"; +in +{ + flake = { + inherit hosts; + }; +} diff --git a/nix/modules.nix b/nix/modules.nix new file mode 100644 index 0000000..a8d6546 --- /dev/null +++ b/nix/modules.nix @@ -0,0 +1,94 @@ +{ self, ... }: +let + inherit (builtins) listToAttrs replaceStrings stringLength substring; + + removeSuffix = suffix: str: + let + sufLen = stringLength suffix; + sLen = stringLength str; + in + if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then + substring 0 (sLen - sufLen) str + else + str; + + exposeModules = baseDir: paths: + let + prefix = stringLength (toString baseDir) + 1; + toPair = path: { + name = replaceStrings [ "/" ] [ "-" ] ( + removeSuffix ".nix" (substring prefix 100000000 (toString path)) + ); + value = path; + }; + in + listToAttrs (map toPair paths); +in +{ + flake = { + modules.nixos = exposeModules ../modules/. [ + ../modules/custom/dns/knot + ../modules/custom/dns/zones + ../modules/filesystems/zfs.nix + ../modules/hardware + ../modules/hardware/bluetooth.nix + ../modules/hardware/cpu/amd.nix + ../modules/hardware/cpu/intel.nix + ../modules/hardware/disk.nix + ../modules/hardware/gpu/amd.nix + ../modules/hardware/gpu/intel.nix + ../modules/hardware/gpu/nvidia.nix + ../modules/hardware/laptop.nix + ../modules/hardware/power.nix + ../modules/hardware/rpi4.nix + ../modules/hardware/security/nitrokey.nix + ../modules/hardware/security/secureboot.nix + ../modules/hardware/security/yubikey.nix + ../modules/hardware/sound/pipewire.nix + ../modules/hardware/sound/pulseaudio.nix + ../modules/roles/core + ../modules/roles/desktop + ../modules/roles/desktop/desktop-manager + ../modules/roles/desktop/desktop-manager/gnome.nix + ../modules/roles/desktop/display-manager + ../modules/roles/desktop/office + ../modules/roles/desktop/system + ../modules/roles/desktop/window-manager + ../modules/roles/media-center + ../modules/roles/nas + ../modules/roles/server + ../modules/roles/workstation + ../modules/services/container + ../modules/services/container/docker.nix + ../modules/services/container/k3s + ../modules/services/container/podman.nix + ../modules/services/database/mysql.nix + ../modules/services/database/postgresql.nix + ../modules/services/dns + ../modules/services/dns/avahi.nix + ../modules/services/dns/knot + ../modules/services/dns/knsupdate.nix + ../modules/services/monitoring + ../modules/services/monitoring/loki.nix + ../modules/services/monitoring/prometheus.nix + ../modules/services/monitoring/promtail.nix + ../modules/services/monitoring/telegraf.nix + ../modules/services/netboot + ../modules/services/netboot/config.nix + ../modules/services/security/clamav + ../modules/services/security/tang + ../modules/services/storage/samba + ../modules/services/storage/syncthing + ../modules/services/virtualisation/libvirt.nix + ../modules/services/virtualisation/microvm.nix + ../modules/services/web/nginx.nix + ../modules/users + ../modules/users/personal/crstl + ../modules/users/system/automat + ../modules/users/system/root + ../modules/users/system/service.nix + ]; + + nixosModules = self.modules.nixos; + }; +} diff --git a/nix/nixos.nix b/nix/nixos.nix new file mode 100644 index 0000000..12110b8 --- /dev/null +++ b/nix/nixos.nix @@ -0,0 +1,40 @@ +{ self, inputs, withSystem, ... }: +let + inherit (inputs) nixpkgs; + inherit (nixpkgs) lib; + + genConfiguration = hostname: { address, hostPlatform, type, ... }: + withSystem hostPlatform ( + { pkgs, ... }: + lib.nixosSystem { + modules = [ + (../hosts + "/${hostname}") + { + nixpkgs.pkgs = pkgs; + nix.registry = { + p.flake = nixpkgs; + nixpkgs.flake = nixpkgs; + }; + nixpkgs.hostPlatform = hostPlatform; + } + ]; + + specialArgs = { + hostType = type; + hostAddress = address; + inherit self inputs; + }; + } + ); +in +{ + flake.nixosConfigurations = lib.mapAttrs genConfiguration ( + lib.filterAttrs (_: host: host.type == "nixos") inputs.self.hosts + ); + + perSystem = { lib, pkgs, system, ... }: { + checks = lib.mapAttrs' + (name: config: lib.nameValuePair "nixos-${name}" config.config.system.build.toplevel) + ((lib.filterAttrs (_: config: config.pkgs.system == system)) self.nixosConfigurations); + }; +} diff --git a/nix/overlay.nix b/nix/overlay.nix new file mode 100644 index 0000000..a9bd412 --- /dev/null +++ b/nix/overlay.nix @@ -0,0 +1,36 @@ +{ inputs, lib, ... }: +let + importLocalOverlay = file: + lib.composeExtensions + (_: _: { __inputs = inputs; }) + (import (../overlays + "/${file}")); + + localOverlays = + lib.mapAttrs' + (f: _: lib.nameValuePair + (lib.removeSuffix ".nix" f) + (importLocalOverlay f) + ) + (builtins.readDir ../overlays); + +in +{ + flake.overlays = { + inherit localOverlays; + + default = lib.composeManyExtensions [ + inputs.agenix.overlays.default + inputs.deploy-rs.overlays.default + inputs.nixvim.overlays.default + inputs.nur.overlay + inputs.vault-secrets.overlays.default + + (final: _prev: { + inherit (inputs.nix-fast-build.packages.${final.stdenv.hostPlatform.system}) nix-fast-build; + inherit (inputs.srx-digital-website.packages.${final.stdenv.hostPlatform.system}) srx-digital; + inherit (inputs.nix-hamburg-website.packages.${final.stdenv.hostPlatform.system}) nix-hamburg; + inherit (inputs.cq-flake.packages.${final.stdenv.hostPlatform.system}) cq-editor; + }) + ]; + }; +} diff --git a/nix/packages.nix b/nix/packages.nix new file mode 100644 index 0000000..1e6900b --- /dev/null +++ b/nix/packages.nix @@ -0,0 +1,40 @@ +{ self, inputs, config, ... }: +{ + flake.hydraJobs = { + inherit (self) checks packages; + }; + + perSystem = { pkgs, self', system, ... }: + let + inherit (config) flake; + inherit (pkgs) lib linkFarm; + nixosDrvs = lib.mapAttrs (_: nixos: nixos.config.system.build.toplevel) flake.nixosConfigurations; + homeDrvs = lib.mapAttrs (_: home: home.activationPackage) flake.homeConfigurations; + hostDrvs = nixosDrvs // homeDrvs; + compatHosts = lib.filterAttrs (_: host: host.hostPlatform == system) flake.hosts; + compatHostDrvs = lib.mapAttrs (name: _: hostDrvs.${name}) compatHosts; + compatHostsFarm = linkFarm "hosts-${system}" (lib.mapAttrsToList (name: path: { inherit name path; }) compatHostDrvs); + packagesAdditional = { inherit (pkgs) nix-fast-build; }; + packagesBlacklist = [ ]; + packages = lib.mapAttrs' (name: lib.nameValuePair "package-${name}") ( + lib.filterAttrs (name: _v: !(builtins.elem name packagesBlacklist)) self'.packages); + in + { + _module.args = { + pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ self.overlays.default ]; + config = { + allowUnfree = true; + allowAliases = true; + }; + }; + }; + + packages = ( + lib.optionalAttrs (compatHosts != { }) { default = compatHostsFarm; } + ) // compatHostDrvs // packagesAdditional; + + checks = packages; + }; +} diff --git a/nix/terranix.nix b/nix/terranix.nix new file mode 100644 index 0000000..8dd2116 --- /dev/null +++ b/nix/terranix.nix @@ -0,0 +1,63 @@ +{ self, lib, nixpkgs, inputs, ... }: +{ + flake.lib.terraform = import ../lib/terraform.nix { inherit self inputs lib nixpkgs; }; + + perSystem = { pkgs, system, inputs', self', ... }: + let + tofuLib = self.lib.terraform { inherit (self'.packages) opentofu; inherit pkgs tufoConfigAst; }; + tufoConfigAst = inputs.terranix.lib.terranixConfigurationAst { + inherit system pkgs; + modules = [ ../terranix ]; + }; + in + { + devShells.opentofu = pkgs.mkShell { + packages = [ + self'.packages.json2nix + self'.packages.opentofu + (inputs'.terranix.packages.terranix.override { nix = pkgs.nixVersions.latest; }) + ]; + }; + + apps = tofuLib.mkApps [ + "init" + "plan" + "apply" + "destroy" + "state" + "import" + ] // { inherit (tofuLib) tf-validate tf2nix; }; + + packages = { + inherit (tofuLib) tf-state; + + opentofu = pkgs.opentofu.withPlugins (tp: [ + tp.github + tp.grafana + tp.hcloud + tp.helm + tp.hydra + tp.keycloak + tp.minio + + (pkgs.opentofu.plugins.mkProvider { + owner = "go-gitea"; + repo = "terraform-provider-gitea"; + rev = "v0.3.0"; + vendorHash = "sha256-+jTenvGCfqI8I3//kc/kCa7kTIyzSGKjJXP6otKJBRA="; + spdx = "MIT"; + hash = "sha256-qUVF3JS3sOisAhgBHvpDsb6rEFXyQTU9Bga1WjetYL0="; + homepage = "https://registry.terraform.io/providers/go-gitea/gitea"; + provider-source-address = "registry.terraform.io/go-gitea/gitea"; + }) + ]); + + json2nix = pkgs.writeScriptBin "json2nix" '' + ${pkgs.python3}/bin/python ${pkgs.fetchurl { + url = "https://gist.githubusercontent.com/Scoder12/0538252ed4b82d65e59115075369d34d/raw/e86d1d64d1373a497118beb1259dab149cea951d/json2nix.py"; + hash = "sha256-ROUIrOrY9Mp1F3m+bVaT+m8ASh2Bgz8VrPyyrQf9UNQ="; + }} $@ + ''; + }; + }; +} diff --git a/overlays/cadquery.nix b/overlays/cadquery.nix new file mode 100644 index 0000000..3bbfcdc --- /dev/null +++ b/overlays/cadquery.nix @@ -0,0 +1,21 @@ +_final: prev: { + opencascade-occt = prev.opencascade-occt_0_17.override { + buildInputs = with prev; [ + tcl + tk + libGL + libGLU + libXext + libXmu + libXi + vtk + xorg.libXt + freetype + freeimage + fontconfig + tbb_2021_11 + rapidjson + glew + ] ++ vtk.buildInputs; + }; +} diff --git a/overlays/nix-latest.nix b/overlays/nix-latest.nix new file mode 100644 index 0000000..f528162 --- /dev/null +++ b/overlays/nix-latest.nix @@ -0,0 +1,18 @@ +final: prev: +let + useLatestNixFor = name: + { inherit name; value = prev.${name}.override { nix = final.nixVersions.latest; }; }; + useLatestNix = names: builtins.listToAttrs (map useLatestNixFor names); +in +(useLatestNix [ + "agenix" + "nix-direnv" + "nix-update" + "nixpkgs-review" +]) // { + # Workaround for electron depending on nix-prefetch-git at build-time via + # prefetch-yarn-deps + nix-prefetch-git = prev.nix-prefetch-git.override { nix = final.nixVersions.latest; }; + nix-prefetch-git-stable = prev.nix-prefetch-git; + prefetch-yarn-deps = prev.prefetch-yarn-deps.override { nix-prefetch-git = final.nix-prefetch-git-stable; }; +} diff --git a/secrets.nix b/secrets.nix new file mode 100644 index 0000000..bf7d263 --- /dev/null +++ b/secrets.nix @@ -0,0 +1,95 @@ +let + inherit (builtins) attrNames attrValues mapAttrs listToAttrs; + hosts = mapAttrs (_: v: v.pubkey) (import ./nix/hosts.nix).flake.hosts; + + srx_signing = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDcf3QwjRB29nYbFTHbtZjiYAwDlLB0tLz8Djo5x/HYg"; + srx_swendel = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6vk3k1p6YMsGLFQ/xABLYK/VJicywkf1MJawnN7oXU"; + hydra_runner = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDjAHH3dWAxIi0ylYt3lEOnOd/Vx7u91F3ZIs+pIsUEC1BLUgULSiUvYgAI99FAPIbavcn2vSaDmHVFexlVltMY7V+I+F4Q/d96wfaTXq1t33PJUGOcbvBSRzspTJw5hRq6sGV7UPf0givVS0ZL8001S4SydziT/C+z+3EJXhk4RMJT2rkxw7KWFWWSRZYT4YsCcsMDjXyvV1GZXAZnTioIJ+JNi3zepUH0AWu/yhKO2k0drYJ3hzSSfbgehOLM9MXozPu90vHNiff7rw557LtzksJqRNNqIwPGZTcaNwuH/RQF7USe3juutf62fS7PCqoaaVIAhHVWq573VImCizwd42+qBqUgIjhaIJlyUAMQv7cQTnUDZoK8k7/gB3WN7a03bU6NcGpJvLR8HAM9RQCQXqCW2gQDLEnuHHOhHS4XsEovpvu3HigSi8FPLKrDtT/0b7ecmizYR/3IoRqiyE3RgUz+mpPGMKvYxKNQLXF5By0T7n4CWYPFdjVm7nM2APGrm3OHkbVyKKFi95YE0v/7P/8GRlVIKpLYU1DMnmDzEfjNOKokXG3JWTK/ZLkVUUNXuBbjNh8Q0cTUI/4NlgLgMecsNGhfxxr8TehDo/sZoxqhCFAPfyGRCJrIpnLSIxjEZmLRt2/wOxoZeaql4FsRQ7EqA579pGUUYTQCmpC1LQ=="; + + secrets = with hosts; { + "hosts/srxgp00/services/coturn/auth-secret.age" = [ srxgp00 ]; + "hosts/srxgp00/services/dendrite/environment.age" = [ srxgp00 ]; + "hosts/srxgp00/services/dendrite/private-key.age" = [ srxgp00 ]; + "hosts/srxgp00/services/forgejo/mailerPassword.age" = [ srxgp00 ]; + "hosts/srxgp00/services/forgejo/runnerToken.age" = [ srxgp00 ]; + "hosts/srxgp00/services/grafana/oidc-secret.age" = [ srxgp00 ]; + "hosts/srxgp00/services/hedgedoc/environment.age" = [ srxgp00 ]; + "hosts/srxgp00/services/hydra/private-key.age" = [ srxgp00 ]; + "hosts/srxgp00/services/hydra/secrets.age" = [ srxgp00 ]; + "hosts/srxgp00/services/keycloak/databasePassword.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-dmarc-client.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-dmarc.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-Ies6sh.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-Oom7oh.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-Osoo5u.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-ugai0U.age" = [ srxgp00 ]; + "hosts/srxgp00/services/mailserver/mailbox-xaev9B.age" = [ srxgp00 ]; + "hosts/srxgp00/services/minio/user_admin.age" = [ srxgp00 ]; + "hosts/srxgp00/services/minio/user_prometheus.age" = [ srxgp00 ]; + "hosts/srxgp00/services/nextcloud/adminpass.age" = [ srxgp00 ]; + "hosts/srxgp00/services/nextcloud/secrets.age" = [ srxgp00 ]; + "hosts/srxgp00/services/oauth2-proxy/secrets.age" = [ srxgp00 ]; + "hosts/srxgp00/services/openldap/ldap-bind-secret.age" = [ srxgp00 ]; + "hosts/srxgp00/services/openldap/ldap-config-secret.age" = [ srxgp00 ]; + "hosts/srxgp00/services/paperless/password.age" = [ srxgp00 ]; + "hosts/srxgp00/services/plausible/mail.age" = [ srxgp00 ]; + "hosts/srxgp00/services/plausible/password.age" = [ srxgp00 ]; + "hosts/srxgp00/services/plausible/secret.age" = [ srxgp00 ]; + "hosts/srxgp00/services/prometheus/alertmanager-env.age" = [ srxgp00 ]; + "hosts/srxgp00/services/restic/repo_key.age" = [ srxgp00 ]; + "hosts/srxgp00/services/restic/repo_ssh.age" = [ srxgp00 ]; + "hosts/srxgp00/services/vaultwarden/secrets.age" = [ srxgp00 ]; + "hosts/srxnb00/services/restic/repo_key.age" = [ srxnb00 ]; + "hosts/srxnb00/services/restic/repo_ssh.age" = [ srxnb00 ]; + "hosts/srxmc00/cifs_nas.age" = [ srxmc00 ]; + "modules/custom/dns/knot/secrets/notify.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/custom/dns/knot/secrets/transfer.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/custom/dns/knot/secrets/tsig_xfr.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/custom/dns/knot/secrets/update_k8s.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/custom/dns/knot/secrets/update_terraform_cicd.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/custom/dns/knot/secrets/update_terraform_swendel.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/custom/dns/knot/secrets/update.age" = [ srxgp00 srxgp01 srxgp02 ]; + "modules/services/container/k3s/k8s_cluster_token.age" = [ srxk8s00 ]; + "modules/services/container/k3s/k8s_dns_update_rfc2136.age" = [ srxk8s00 ]; + "modules/services/container/k3s/k8s_environment.age" = [ srxk8s00 ]; + "modules/services/container/k3s/k8s_traefik_dashboard.age" = [ srxk8s00 ]; + "modules/roles/server/acme.age" = attrValues hosts; + "modules/users/personal/crstl/password.age" = attrValues hosts; + "modules/users/system/automat/ssh-private.age" = attrValues hosts; + "modules/users/system/root/password.age" = attrValues hosts; + }; + + secrets' = mapAttrs + (_: v: { + publicKeys = [ + srx_signing + srx_swendel + hydra_runner + ] ++ v; + }) + secrets; + + allHostSecret = + secretName: + listToAttrs ( + map + (host: { + name = "hosts/${host}/${secretName}.age"; + value.publicKeys = [ + srx_signing + srx_swendel + hydra_runner + hosts.${host} + ]; + }) + (attrNames hosts) + ); +in +secrets' // +allHostSecret "initrd_hostkey" // +allHostSecret "dns_update" // +allHostSecret "vpn_srx" // +allHostSecret "vpn_ccl" // +allHostSecret "vpn_mvd" // +allHostSecret "wifi_client" // +allHostSecret "clevis" diff --git a/terranix/backend.nix b/terranix/backend.nix new file mode 100644 index 0000000..98c8e28 --- /dev/null +++ b/terranix/backend.nix @@ -0,0 +1,14 @@ +{ + terraform.backend.s3 = { + endpoints.s3 = "https://s3.srx.digital"; + bucket = "terraform-state"; + region = "eu-central-1"; + key = "srx.digital.tfstate"; + + skip_credentials_validation = true; + skip_requesting_account_id = true; + skip_metadata_api_check = true; + skip_region_validation = true; + use_path_style = true; + }; +} diff --git a/terranix/default.nix b/terranix/default.nix new file mode 100644 index 0000000..7483fa3 --- /dev/null +++ b/terranix/default.nix @@ -0,0 +1,16 @@ +{ + terraform.required_version = ">= 1.7"; + + imports = [ + ./backend.nix + ./variables.nix + + ./github + ./gitea + ./hcloud + ./hydra + ./minio + ./keycloak + ./grafana + ]; +} diff --git a/terranix/gitea/curious.bio.nix b/terranix/gitea/curious.bio.nix new file mode 100644 index 0000000..1efd189 --- /dev/null +++ b/terranix/gitea/curious.bio.nix @@ -0,0 +1,109 @@ +{ lib, ... }: +{ + variable.GITEA_MIRROR_TOKEN_CCL = { + type = "string"; + sensitive = true; + }; + + resource = { + gitea_org.gitea-org-curious-bio = { + name = "ccl"; + full_name = "Curious Community Labs e. V."; + location = "Hamburg, Germany"; + website = "https://curious.bio/"; + visibility = "public"; + }; + + gitea_repository = { + gitea-mirror-iot-backend = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "iot-backend"; + description = "An Open-Source prototype for collecting, working with and displaying sensor data from MQTT enabled IoT devices. https://wiki.curious.bio/de/Projekte/IoT-Plattform"; + website = "https://code.curious.bio/curious.bio/iot-backend.git"; + migration_clone_address = "https://code.curious.bio/curious.bio/iot-backend.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + + gitea-mirror-infra-nix = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "infra.nix"; + description = "CCL NixOS config"; + website = "https://code.curious.bio/curious.bio/infra.nix"; + migration_clone_address = "https://code.curious.bio/curious.bio/infra.nix"; + migration_service = "gitea"; + migration_service_auth_token = lib.tfRef "var.GITEA_MIRROR_TOKEN_CCL"; + mirror = true; + has_issues = false; + has_wiki = false; + private = true; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + + gitea-mirror-smart-energy-monitor = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "smart-energy-monitor"; + description = "A smart energy monitor to measure the power consumption https://wiki.curious.bio/de/Projekte/IoT-Plattform"; + website = "https://code.curious.bio/curious.bio/smart-energy-monitor.git"; + migration_clone_address = "https://code.curious.bio/curious.bio/smart-energy-monitor.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + + + gitea-mirror-mushlab-iot = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "mushlab-iot"; + website = "https://code.curious.bio/curious.bio/mushlab-iot.git"; + migration_clone_address = "https://code.curious.bio/curious.bio/mushlab-iot.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + + gitea-mirror-vermiloop = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "vermiloop"; + website = "https://code.curious.bio/curious.bio/vermiloop.git"; + migration_clone_address = "https://code.curious.bio/curious.bio/vermiloop.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + + gitea-mirror-planktoscope = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "planktoscope"; + website = "https://code.curious.bio/curious.bio/planktoscope.git"; + migration_clone_address = "https://code.curious.bio/curious.bio/planktoscope.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + + gitea-mirror-nix-cyanovision = { + username = lib.tfRef "gitea_org.gitea-org-curious-bio.name"; + name = "nix-cyanovision"; + website = "https://code.curious.bio/curious.bio/nix-cyanovision.git"; + migration_clone_address = "https://code.curious.bio/curious.bio/nix-cyanovision.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-curious-bio" ]; + }; + }; + }; +} diff --git a/terranix/gitea/default.nix b/terranix/gitea/default.nix new file mode 100644 index 0000000..f4c0ae1 --- /dev/null +++ b/terranix/gitea/default.nix @@ -0,0 +1,14 @@ +{ + terraform.required_providers.gitea = { + source = "registry.terraform.io/go-gitea/gitea"; + version = ">= 0.3.0"; + }; + + imports = [ + ./swendel.nix + ./srx.digital.nix + ./nix-hamburg.de.nix + ./curious.bio.nix + ./octopot.de.nix + ]; +} diff --git a/terranix/gitea/nix-hamburg.de.nix b/terranix/gitea/nix-hamburg.de.nix new file mode 100644 index 0000000..267167f --- /dev/null +++ b/terranix/gitea/nix-hamburg.de.nix @@ -0,0 +1,9 @@ +{ + resource.gitea_org.gitea-org-nix-hamburg = { + name = "nix-hamburg"; + full_name = "Nix Hamburg User Group"; + location = "Hamburg, Germany"; + website = "https://nix-hamburg.de/"; + visibility = "public"; + }; +} diff --git a/terranix/gitea/octopot.de.nix b/terranix/gitea/octopot.de.nix new file mode 100644 index 0000000..3337a31 --- /dev/null +++ b/terranix/gitea/octopot.de.nix @@ -0,0 +1,9 @@ +{ + resource.gitea_org.gitea-org-octopod = { + name = "octopod"; + full_name = "octopod research & development GmbH"; + location = "Hamburg, Germany"; + website = "https://octopod.de"; + visibility = "private"; + }; +} diff --git a/terranix/gitea/srx.digital.nix b/terranix/gitea/srx.digital.nix new file mode 100644 index 0000000..5aca5ca --- /dev/null +++ b/terranix/gitea/srx.digital.nix @@ -0,0 +1,75 @@ +{ lib, ... }: +{ + resource = { + gitea_org.gitea-org-srx-digital = { + name = "srx"; + full_name = "srx development & operations"; + location = "Hamburg, Germany"; + website = "https://srx.digital"; + visibility = "public"; + }; + + gitea_repository = { + gitea-repo-srx-nixos-shadow = { + username = lib.tfRef "gitea_org.gitea-org-srx-digital.name"; + name = "srx-nixos-shadow"; + description = "The hidden part of the srx.digital NixOS platform"; + auto_init = false; + private = true; + }; + + srx-platform-nix = { + username = lib.tfRef "gitea_org.gitea-org-srx-digital.name"; + name = "srx-platform-nix"; + description = "Nix platform repository"; + migration_clone_address = "https://github.com/SebastianWendel/srx-platform-nix"; + migration_service_auth_token = lib.tfRef "var.GITHUB_TOKEN"; + migration_service = "github"; + has_issues = true; + has_wiki = true; + private = false; + mirror = true; + website = "https://srx.digital"; + depends_on = [ "gitea_org.gitea-org-srx-digital" ]; + }; + + gitea-mirror-fcos-drupal-cms-dev-kit = { + username = lib.tfRef "gitea_org.gitea-org-srx-digital.name"; + name = "fcos-drupal-cms-dev-kit"; + description = " FCOS Drupal CMS Development Kit"; + website = "https://gitlab.fabcity.hamburg/software/fcos-drupal-cms-dev-kit.git"; + has_issues = false; + has_wiki = false; + private = false; + mirror = true; + depends_on = [ "gitea_org.gitea-org-srx-digital" ]; + }; + + gitea-mirror-fab-city-os-core-chart = { + username = lib.tfRef "gitea_org.gitea-org-srx-digital.name"; + name = "fab-city-os-core-chart"; + description = "Fab City OS Core Helm Chart for Kubernetes"; + website = "https://gitlab.fabcity.hamburg/software/fab-city-os-core-chart.git"; + migration_clone_address = "https://gitlab.fabcity.hamburg/software/fab-city-os-core-chart.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-srx-digital" ]; + }; + + gitea-mirror-fab-city-software-kit = { + username = lib.tfRef "gitea_org.gitea-org-srx-digital.name"; + name = "fab-city-software-kit"; + description = "Fab City Software Kit for Kubernetes"; + website = "https://gitlab.fabcity.hamburg/software/fab-city-software-kit.git"; + migration_clone_address = "https://gitlab.fabcity.hamburg/software/fab-city-software-kit.git"; + mirror = true; + has_issues = false; + has_wiki = false; + private = false; + depends_on = [ "gitea_org.gitea-org-srx-digital" ]; + }; + }; + }; +} diff --git a/terranix/gitea/swendel.nix b/terranix/gitea/swendel.nix new file mode 100644 index 0000000..9264b5c --- /dev/null +++ b/terranix/gitea/swendel.nix @@ -0,0 +1,64 @@ +{ lib, ... }: +{ + resource = { + gitea_repository = { + gitea-repo-gitHub-profile = { + username = "swendel"; + name = "SebastianWendel"; + description = "My personal GitHub profile."; + website = "https://srx.digital"; + migration_clone_address = "https://github.com/SebastianWendel/SebastianWendel.git"; + migration_service_auth_token = lib.tfRef "var.GITHUB_TOKEN"; + migration_service = "github"; + mirror = true; + has_issues = true; + has_wiki = false; + private = false; + }; + + gitea-mirror-nixpkgs = { + username = "swendel"; + name = "nixpkgs"; + description = "Mirror of nixpkgs"; + website = "https://github.com/SebastianWendel/nixpkgs.git"; + migration_clone_address = "https://github.com/SebastianWendel/nixpkgs.git"; + mirror = true; + has_issues = true; + has_wiki = true; + private = false; + }; + + gitea-mirror-bionet = { + username = "swendel"; + name = "bionet"; + description = "Image classification"; + website = "https://code.curious.bio/swendel/bionet.git"; + migration_clone_address = "https://code.curious.bio/swendel/bionet.git"; + migration_service = "gitea"; + migration_service_auth_token = lib.tfRef "var.GITEA_MIRROR_TOKEN_CCL"; + private = true; + }; + + gitea-mirror-birdnet-nix = { + username = "swendel"; + name = "birdnet-nix"; + description = "Nixified BirdNet"; + website = "https://code.curious.bio/swendel/birdnet-nix.git"; + migration_clone_address = "https://code.curious.bio/swendel/birdnet-nix.git"; + migration_service = "gitea"; + migration_service_auth_token = lib.tfRef "var.GITEA_MIRROR_TOKEN_CCL"; + private = true; + }; + + gitea-mirror-esphome-components = { + username = "swendel"; + name = "esphome-components"; + website = "https://code.curious.bio/swendel/esphome-components.git"; + migration_clone_address = "https://code.curious.bio/swendel/esphome-components.git"; + migration_service = "gitea"; + migration_service_auth_token = lib.tfRef "var.GITEA_MIRROR_TOKEN_CCL"; + private = true; + }; + }; + }; +} diff --git a/terranix/github/default.nix b/terranix/github/default.nix new file mode 100644 index 0000000..3488a19 --- /dev/null +++ b/terranix/github/default.nix @@ -0,0 +1,10 @@ +{ + terraform.required_providers.github = { + source = "registry.terraform.io/integrations/github"; + version = ">= 6.2.1"; + }; + + imports = [ + ./srx.digital.nix + ]; +} diff --git a/terranix/github/srx.digital.nix b/terranix/github/srx.digital.nix new file mode 100644 index 0000000..b7503e8 --- /dev/null +++ b/terranix/github/srx.digital.nix @@ -0,0 +1,28 @@ +{ + resource = { + github_user_ssh_key.swendel = { + title = "swendel"; + key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKwyxpc0pVB46j1k5VCSabvI4TUADvAabnxlE5+D5o2l"; + }; + + github_repository = { + github-repo-profile = { + name = "SebastianWendel"; + description = "My personal GitHub profile."; + homepage_url = "https://srx.digital"; + has_issues = false; + visibility = "public"; + vulnerability_alerts = false; + }; + + srx-platform-nix = { + name = "srx-platform-nix"; + description = "srx.digital - nix platform repository. Mirror of https://code.srx.digital/srx/srx-platform-nix/"; + homepage_url = "https://srx.digital"; + has_issues = false; + visibility = "public"; + vulnerability_alerts = false; + }; + }; + }; +} diff --git a/terranix/grafana/default.nix b/terranix/grafana/default.nix new file mode 100644 index 0000000..e671aeb --- /dev/null +++ b/terranix/grafana/default.nix @@ -0,0 +1,20 @@ +{ lib, ... }: { + terraform.required_providers.grafana = { + source = "registry.terraform.io/grafana/grafana"; + version = ">= 2.14.3"; + }; + + resource = { + grafana_organization.srx = { + name = "srx.digital - Development & Operations"; + admin_user = lib.tfRef "var.USERNAME_ADMIN"; + create_users = false; + }; + + grafana_organization_preferences.srx = { + timezone = "browser"; + week_start = "monday"; + depends_on = [ "grafana_organization.srx" ]; + }; + }; +} diff --git a/terranix/hcloud/default.nix b/terranix/hcloud/default.nix new file mode 100644 index 0000000..beb302c --- /dev/null +++ b/terranix/hcloud/default.nix @@ -0,0 +1,20 @@ +{ lib, ... }: { + terraform.required_providers.hcloud = { + source = "registry.terraform.io/hetznercloud/hcloud"; + version = ">= 1.45.0"; + }; + + resource.hcloud_server.srxk8s00 = { + name = "srxk8s00"; + server_type = "cax21"; + image = "debian-12"; + datacenter = "nbg1-dc3"; + public_net = { + ipv4_enabled = true; + ipv6_enabled = true; + }; + ssh_keys = lib.tfRef "data.hcloud_ssh_keys.all_keys.ssh_keys.*.name"; + }; + + data.hcloud_ssh_keys.all_keys = { }; +} diff --git a/terranix/hydra/default.nix b/terranix/hydra/default.nix new file mode 100644 index 0000000..aee21ec --- /dev/null +++ b/terranix/hydra/default.nix @@ -0,0 +1,12 @@ +{ + terraform.required_providers.hydra = { + source = "registry.terraform.io/DeterminateSystems/hydra"; + version = ">= 0.1.2"; + }; + + provider.hydra = { }; + + imports = [ + ./srx.digital.nix + ]; +} diff --git a/terranix/hydra/srx.digital.nix b/terranix/hydra/srx.digital.nix new file mode 100644 index 0000000..6b1ebb4 --- /dev/null +++ b/terranix/hydra/srx.digital.nix @@ -0,0 +1,63 @@ +{ lib, ... }: { + resource = { + hydra_project.srx = { + name = "srx"; + display_name = "srx.digital"; + description = "srx.digital NixOS Platform"; + homepage = "https://code.srx.digital/srx/"; + owner = lib.tfRef "var.USERNAME_PERSONAL"; + enabled = true; + visible = true; + }; + + hydra_jobset = { + srx-platform-nix = { + name = "srx-platform-nix"; + project = lib.tfRef "hydra_project.srx.name"; + type = "flake"; + flake_uri = "git+ssh://forgejo@code.srx.digital/srx/srx.infra.nix.history.git"; + description = "srx.digital NixOS Platform"; + state = "enabled"; + check_interval = 60; + scheduling_shares = 10000; + keep_evaluations = 5; + visible = true; + email_notifications = true; + email_override = lib.tfRef "var.EMAIL_PUBLIC"; + depends_on = [ "hydra_project.srx" ]; + }; + + srx-website-nix = { + name = "website"; + project = lib.tfRef "hydra_project.srx.name"; + type = "flake"; + flake_uri = "git+ssh://forgejo@code.srx.digital/srx/srx.astro.nix.git"; + description = "A Nix development environment of my portfolio page based on Astro"; + state = "enabled"; + check_interval = 60; + scheduling_shares = 1000; + keep_evaluations = 5; + visible = true; + email_notifications = true; + email_override = lib.tfRef "var.EMAIL_PUBLIC"; + depends_on = [ "hydra_project.srx" ]; + }; + + srx-shadow-nix = { + name = "nixos-shadow"; + project = lib.tfRef "hydra_project.srx.name"; + type = "flake"; + flake_uri = "git+ssh://forgejo@code.srx.digital/srx/srx-nixos-shadow.git"; + description = "The hidden part of the srx.digital NixOS platform"; + state = "enabled"; + check_interval = 60; + scheduling_shares = 1000; + keep_evaluations = 5; + visible = false; + email_notifications = true; + email_override = lib.tfRef "var.EMAIL_PUBLIC"; + depends_on = [ "hydra_project.srx" ]; + }; + }; + }; +} diff --git a/terranix/keycloak/default.nix b/terranix/keycloak/default.nix new file mode 100644 index 0000000..c1d609b --- /dev/null +++ b/terranix/keycloak/default.nix @@ -0,0 +1,12 @@ +{ + terraform.required_providers.keycloak = { + source = "registry.terraform.io/mrparkers/keycloak"; + version = ">= 4.4.0"; + }; + + provider.keycloak = { }; + + imports = [ + ./srx.digital.nix + ]; +} diff --git a/terranix/keycloak/srx.digital.nix b/terranix/keycloak/srx.digital.nix new file mode 100644 index 0000000..10ee194 --- /dev/null +++ b/terranix/keycloak/srx.digital.nix @@ -0,0 +1,114 @@ +{ lib, ... }: +{ + resource = { + keycloak_realm.srx-digital = { + enabled = true; + + realm = "srx-digital"; + display_name = "SRX Digital - Development & Operations"; + login_theme = "keycloak"; + access_code_lifespan = "1h"; + display_name_html = "SRX Digital - Development & Operations"; + + internationalization = [{ + default_locale = "en"; + supported_locales = [ "en" "de" ]; + }]; + + verify_email = true; + reset_password_allowed = true; + login_with_email_allowed = true; + password_policy = "length(20) and upperCase(2) and digits(2) and specialChars(2) and notUsername and passwordHistory(10) and forceExpiredPasswordChange(90)"; + ssl_required = "external"; + + smtp_server = [{ + host = lib.tfRef "var.EMAIL_HOST"; + port = lib.tfRef "var.EMAIL_PORT"; + from = lib.tfRef "var.EMAIL_NO_REPLY"; + from_display_name = lib.tfRef "var.COMPANY_HEADER"; + reply_to = lib.tfRef "var.EMAIL_BILLING"; + reply_to_display_name = lib.tfRef "var.COMPANY_HEADER"; + auth = { + username = lib.tfRef "var.EMAIL_NO_REPLY"; + password = lib.tfRef "var.EMAIL_PASSWORD"; + }; + ssl = true; + }]; + + security_defenses = [{ + headers = [{ + content_security_policy = "frame-src 'self'; frame-ancestors 'self'; object-src 'none';"; + content_security_policy_report_only = ""; + strict_transport_security = "max-age=31536000; includeSubDomains"; + x_content_type_options = "nosniff"; + x_frame_options = "DENY"; + x_robots_tag = "none"; + x_xss_protection = "1; mode=block"; + }]; + + brute_force_detection = [{ + failure_reset_time_seconds = 43200; + max_failure_wait_seconds = 900; + max_login_failures = 30; + minimum_quick_login_wait_seconds = 60; + permanent_lockout = false; + quick_login_check_milli_seconds = 1000; + wait_increment_seconds = 60; + }]; + }]; + }; + + keycloak_openid_client = { + openid_client = { + enabled = true; + client_id = "code"; + name = "SRX Code Base "; + access_type = "CONFIDENTIAL"; + standard_flow_enabled = true; + valid_redirect_uris = [ "https://code.srx.digital/*" ]; + realm_id = "\${keycloak_realm.srx-digital.id}"; + }; + }; + + keycloak_group.operator = { + name = "operator"; + realm_id = "\${keycloak_realm.srx-digital.id}"; + depends_on = [ + "keycloak_realm.srx-digital" + ]; + }; + + keycloak_user.swendel = { + enabled = true; + username = "swendel"; + first_name = "Sebastian"; + last_name = "Wendel"; + email = lib.tfRef "var.EMAIL_PERSONAL"; + + required_actions = [ + "Verify email" + "Update profile" + "Update password" + "Configure OTP" + ]; + + initial_password = { + value = lib.tfRef "var.EMAIL_PERSONAL"; + temporary = true; + }; + + realm_id = "\${keycloak_realm.srx-digital.id}"; + + depends_on = [ + "keycloak_realm.srx-digital" + "keycloak_group.operator" + ]; + }; + + keycloak_user_groups.operator = { + user_id = "\${keycloak_user.swendel.id}"; + group_ids = [ "\${keycloak_group.operator.id}" ]; + realm_id = "\${keycloak_realm.srx-digital.id}"; + }; + }; +} diff --git a/terranix/minio/admins.nix b/terranix/minio/admins.nix new file mode 100644 index 0000000..4cbea78 --- /dev/null +++ b/terranix/minio/admins.nix @@ -0,0 +1,33 @@ +{ + resource = { + minio_iam_user.swendel.name = "swendel"; + + minio_iam_service_account.swendel.target_user = "\${minio_iam_user.swendel.name}"; + + minio_iam_user_policy_attachment.swendel-policy-admin = { + user_name = "\${minio_iam_user.swendel.id}"; + policy_name = "consoleAdmin"; + }; + }; + + output = { + swendel-id.value = "\${minio_iam_user.swendel.id}"; + + swendel-secret = { + value = "\${minio_iam_user.swendel.secret}"; + sensitive = true; + }; + + swendel-status.value = "\${minio_iam_user.nix-hydra.status}"; + + swendel-access-key = { + value = "\${minio_iam_service_account.swendel.access_key}"; + sensitive = true; + }; + + swendel-secret-key = { + value = "\${minio_iam_service_account.swendel.secret_key}"; + sensitive = true; + }; + }; +} diff --git a/terranix/minio/default.nix b/terranix/minio/default.nix new file mode 100644 index 0000000..e7469c2 --- /dev/null +++ b/terranix/minio/default.nix @@ -0,0 +1,14 @@ +{ + terraform.required_providers.minio = { + source = "registry.terraform.io/aminueza/minio"; + version = ">= 2.2.0"; + }; + + provider.minio = { }; + + imports = [ + ./admins.nix + ./terraform.nix + ./hydra.nix + ]; +} diff --git a/terranix/minio/hydra.nix b/terranix/minio/hydra.nix new file mode 100644 index 0000000..b191ad8 --- /dev/null +++ b/terranix/minio/hydra.nix @@ -0,0 +1,65 @@ +{ + resource = { + minio_s3_bucket.nix-cache.bucket = "nix-cache"; + + minio_iam_user.nix-hydra.name = "nix-hydra"; + minio_iam_service_account.nix-hydra.target_user = "\${minio_iam_user.nix-hydra.name}"; + + minio_iam_policy = { + nix-cache-policy-hydra = { + name = "nix-cache-policy-hydra"; + policy = "\${data.minio_iam_policy_document.nix-cache-policy-hydra.json}"; + }; + nix-cache-policy-hydra-read = { + name = "nix-cache-policy-hydra-read"; + policy = "\${data.minio_iam_policy_document.nix-cache-policy-hydra-read.json}"; + }; + }; + minio_iam_user_policy_attachment.nix-cache-policy-hydra = { + user_name = "\${minio_iam_user.nix-hydra.id}"; + policy_name = "\${minio_iam_policy.nix-cache-policy-hydra.id}"; + }; + }; + + data = { + minio_iam_policy_document.nix-cache-policy-hydra-read.statement = { + sid = "AllowDirectReads"; + actions = [ + "s3:GetObject" + "s3:GetBucketLocation" + ]; + effect = "Allow"; + resources = [ + "\${minio_s3_bucket.nix-cache.arn}" + "\${minio_s3_bucket.nix-cache.arn}/*" + ]; + principal = "*"; + }; + + minio_iam_policy_document.nix-cache-policy-hydra.statement = { + sid = "AuthenticatedWrite"; + actions = [ "s3:*" ]; + effect = "Allow"; + resources = [ + "\${minio_s3_bucket.nix-cache.arn}" + "\${minio_s3_bucket.nix-cache.arn}/*" + ]; + principal = "*"; + }; + }; + + output = { + nix-hydra-id.value = "\${minio_iam_user.nix-hydra.id}"; + nix-hydra-secret = { + value = "\${minio_iam_user.nix-hydra.secret}"; + sensitive = true; + }; + nix-hydra-status.value = "\${minio_iam_user.nix-hydra.status}"; + nix-hydra-access-key.value = "\${minio_iam_service_account.nix-hydra.access_key}"; + nix-hydra-secret-key = { + value = "\${minio_iam_service_account.nix-hydra.secret_key}"; + sensitive = true; + }; + nix-cache-url.value = "\${minio_s3_bucket.nix-cache.bucket_domain_name}"; + }; +} diff --git a/terranix/minio/terraform.nix b/terranix/minio/terraform.nix new file mode 100644 index 0000000..62cdcef --- /dev/null +++ b/terranix/minio/terraform.nix @@ -0,0 +1,15 @@ +{ + resource = { + minio_s3_bucket.terraform-state.bucket = "terraform-state"; + + minio_s3_bucket_versioning.terraform-state = { + bucket = "terraform-state"; + versioning_configuration.status = "Enabled"; + depends_on = [ "minio_s3_bucket.terraform-state" ]; + }; + }; + + output = { + terraform-url.value = "\${minio_s3_bucket.terraform-state.bucket_domain_name}"; + }; +} diff --git a/terranix/tfsec.nix b/terranix/tfsec.nix new file mode 100644 index 0000000..f7c5d90 --- /dev/null +++ b/terranix/tfsec.nix @@ -0,0 +1,6 @@ +{ + exclude = [ + "github-repositories-private" + "github-repositories-enable_vulnerability_alerts" + ]; +} diff --git a/terranix/variables.nix b/terranix/variables.nix new file mode 100644 index 0000000..aabc6bd --- /dev/null +++ b/terranix/variables.nix @@ -0,0 +1,57 @@ +{ + variable = { + COMPANY_HEADER = { + type = "string"; + }; + + USERNAME_PERSONAL = { + type = "string"; + default = "guest"; + }; + + USERNAME_ADMIN = { + type = "string"; + default = "admin"; + }; + + EMAIL_HOST = { + type = "string"; + default = "mail.example.com"; + }; + + EMAIL_PORT = { + type = "number"; + default = 465; + }; + + EMAIL_PERSONAL = { + type = "string"; + default = "guest@example.com"; + }; + + EMAIL_PUBLIC = { + type = "string"; + default = "no-reply@example.com"; + }; + + EMAIL_BILLING = { + type = "string"; + default = "no-reply@example.com"; + }; + + EMAIL_NO_REPLY = { + type = "string"; + default = "no-reply@example.com"; + }; + + EMAIL_PASSWORD = { + type = "string"; + sensitive = true; + }; + + GITHUB_TOKEN = { + type = "string"; + sensitive = true; + }; + }; +}