From fc2da07613cc261c13da8e15b948719c93918f1f Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Thu, 4 Jan 2024 22:52:31 +0100 Subject: [PATCH 01/10] update borgmatic config to backup btrfs subvolume --- nixos/modules/backups.nix | 67 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/nixos/modules/backups.nix b/nixos/modules/backups.nix index 331deaa..6478111 100644 --- a/nixos/modules/backups.nix +++ b/nixos/modules/backups.nix @@ -1,39 +1,28 @@ { pkgs, lib, config, ... }: let cfg = config.lab.backups; - snapshotFile = "/tmp/snapshot.qcow2"; - snapshotMount = "/tmp/snapshot"; beforeEverything = pkgs.writeShellScriptBin "beforeEverything" '' - ${pkgs.libvirt}/bin/virsh snapshot-create-as --domain ${cfg.domainName} --name backup-${cfg.domainName} --disk-only --quiesce --no-metadata --diskspec vda,snapshot=no --diskspec vdb,file=${snapshotFile} && ${pkgs.coreutils}/bin/sleep 1 - ${pkgs.coreutils}/bin/mkdir -p ${snapshotMount} - ${pkgs.libguestfs-with-appliance}/bin/guestmount -a ${snapshotFile} -m /dev/sda1 --ro ${snapshotMount} - ''; + if [ -d "${cfg.snapshotLocation}" ]; then + ${pkgs.btrfs-progs}/bin/btrfs subvolume delete ${cfg.snapshotLocation} + fi - afterEverything = pkgs.writeShellScriptBin "afterEverything" '' - set +e - ${pkgs.coreutils}/bin/sleep 10 - ${pkgs.libguestfs-with-appliance}/bin/guestunmount ${snapshotMount} && ${pkgs.coreutils}/bin/sleep 1 - ${pkgs.coreutils}/bin/rm -rf ${snapshotMount} - ${pkgs.libvirt}/bin/virsh blockcommit ${cfg.domainName} vdb --active --verbose --pivot - ${pkgs.coreutils}/bin/rm -f ${snapshotFile} + ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r ${cfg.subvolumeLocation} ${cfg.snapshotLocation} ''; borgmaticConfig = pkgs.writeTextFile { name = "borgmatic-config"; text = '' source_directories: - - ${snapshotMount} + - ${cfg.snapshotLocation} repositories: - path: ${cfg.repoLocation} - label: ${cfg.domainName} + label: nfs keep_daily: 7 keep_weekly: 4 keep_monthly: 6 unknown_unencrypted_repo_access_is_ok: true before_everything: - ${beforeEverything}/bin/beforeEverything - after_everything: - - ${afterEverything}/bin/afterEverything ''; }; in @@ -48,33 +37,44 @@ in }; repoLocation = lib.mkOption { - default = "${config.lab.dataDisk.mountPoint}/backups/thecloud-data.borg"; + # TODO: maybe make sure data disk is enabled? is there an "ensure" method in nix? + default = "${config.lab.dataDisk.mountPoint}/backups/nfs.borg"; type = lib.types.str; description = '' Location of the Borg repository to back up to. ''; }; - domainName = lib.mkOption { - default = "thecloud"; + subvolumeLocation = lib.mkOption { + default = "${config.lab.dataDisk.mountPoint}/nfs"; type = lib.types.str; description = '' - The name of the Libvirt domain with the data disk attached. + Location of the btrfs subvolume holding the data. + ''; + }; + + snapshotLocation = lib.mkOption { + default = "${config.lab.dataDisk.mountPoint}/nfs-backup"; + type = lib.types.str; + description = '' + Location to (temporary) create a snapshot of the subvolume. ''; }; }; config = lib.mkIf cfg.enable { - environment.systemPackages = with pkgs; [ libguestfs-with-appliance borgbackup ]; + environment.systemPackages = with pkgs; [ borgbackup ]; # Converted from: # https://github.com/borgmatic-collective/borgmatic/tree/84823dfb912db650936e3492f6ead7e0e0d32a0f/sample/systemd systemd.services.borgmatic = { description = "borgmatic backup"; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; + unitConfig = { ConditionACPower = true; }; + serviceConfig = { Type = "oneshot"; Nice = 19; @@ -85,22 +85,19 @@ in Restart = "no"; LogRateLimitIntervalSec = 0; }; + preStart = "${pkgs.coreutils}/bin/sleep 1m"; - script = "${pkgs.systemd}/bin/systemd-inhibit --who=\"borgmatic\" --what=\"sleep:shutdown\" --why=\"Prevent interrupting scheduled backup\" ${pkgs.borgmatic}/bin/borgmatic --verbosity -2 --syslog-verbosity 1"; + script = "${pkgs.systemd}/bin/systemd-inhibit --who=\"borgmatic\" --what=\"sleep:shutdown\" --why=\"Prevent interrupting scheduled backup\" ${pkgs.borgmatic}/bin/borgmatic --verbosity -2 --syslog-verbosity 1 -c ${borgmaticConfig}"; }; - environment.etc."borgmatic/config.yaml" = { - source = borgmaticConfig; + systemd.timers.borgmatic = { + description = "Run borgmatic backup"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "*-*-* 3:00:00"; + Persistent = true; + RandomizedDelaySec = "3h"; + }; }; - - # systemd.timers.borgmatic = { - # description = "Run borgmatic backup"; - # wantedBy = [ "timers.target" ]; - # timerConfig = { - # OnCalendar = "*-*-* 3:00:00"; - # Persistent = true; - # RandomizedDelaySec = "3h"; - # }; - # }; }; } From 97fc20e251ca2a84e12ca1d752e22b1b57763c04 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sat, 6 Jan 2024 20:17:45 +0100 Subject: [PATCH 02/10] backup nextcloud and hedgedoc database using borgmatic expose database passwords using agenix install lsof and parted --- nixos/default.nix | 2 ++ nixos/modules/backups.nix | 26 ++++++++++++++++++------ nixos/modules/data-sharing.nix | 4 ++-- nixos/secrets/database_passwords.env.age | 5 +++++ nixos/secrets/secrets.nix | 1 + 5 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 nixos/secrets/database_passwords.env.age diff --git a/nixos/default.nix b/nixos/default.nix index f2b74a4..596a355 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -110,6 +110,8 @@ tree file tcpdump + lsof + parted ]; diff --git a/nixos/modules/backups.nix b/nixos/modules/backups.nix index 6478111..11d838d 100644 --- a/nixos/modules/backups.nix +++ b/nixos/modules/backups.nix @@ -23,6 +23,17 @@ let unknown_unencrypted_repo_access_is_ok: true before_everything: - ${beforeEverything}/bin/beforeEverything + postgresql_databases: + - name: nextcloud + hostname: lewis.dmz + username: nextcloud + password: ''${NEXTCLOUD_DATABASE_PASSWORD} + format: tar + - name: hedgedoc + hostname: lewis.dmz + username: hedgedoc + password: ''${HEDGEDOC_DATABASE_PASSWORD} + format: tar ''; }; in @@ -63,17 +74,16 @@ in }; config = lib.mkIf cfg.enable { - environment.systemPackages = with pkgs; [ borgbackup ]; + environment.systemPackages = with pkgs; [ borgbackup postgresql ]; # Converted from: # https://github.com/borgmatic-collective/borgmatic/tree/84823dfb912db650936e3492f6ead7e0e0d32a0f/sample/systemd systemd.services.borgmatic = { description = "borgmatic backup"; wants = [ "network-online.target" ]; after = [ "network-online.target" ]; - - unitConfig = { - ConditionACPower = true; - }; + unitConfig.ConditionACPower = true; + preStart = "${pkgs.coreutils}/bin/sleep 10s"; + path = with pkgs; [ postgresql ]; serviceConfig = { Type = "oneshot"; @@ -84,9 +94,9 @@ in IOWeight = 100; Restart = "no"; LogRateLimitIntervalSec = 0; + EnvironmentFile = config.age.secrets."database_passwords.env".path; }; - preStart = "${pkgs.coreutils}/bin/sleep 1m"; script = "${pkgs.systemd}/bin/systemd-inhibit --who=\"borgmatic\" --what=\"sleep:shutdown\" --why=\"Prevent interrupting scheduled backup\" ${pkgs.borgmatic}/bin/borgmatic --verbosity -2 --syslog-verbosity 1 -c ${borgmaticConfig}"; }; @@ -99,5 +109,9 @@ in RandomizedDelaySec = "3h"; }; }; + + age.secrets."database_passwords.env" = { + file = ../secrets/database_passwords.env.age; + }; }; } diff --git a/nixos/modules/data-sharing.nix b/nixos/modules/data-sharing.nix index 71f6f49..884cbb8 100644 --- a/nixos/modules/data-sharing.nix +++ b/nixos/modules/data-sharing.nix @@ -71,8 +71,8 @@ in dataDir = cfg.postgresDir; authentication = '' - host nextcloud nextcloud all md5 - host hedgedoc hedgedoc all md5 + host nextcloud nextcloud all md5 + host hedgedoc hedgedoc all md5 ''; }; }; diff --git a/nixos/secrets/database_passwords.env.age b/nixos/secrets/database_passwords.env.age new file mode 100644 index 0000000..29f885b --- /dev/null +++ b/nixos/secrets/database_passwords.env.age @@ -0,0 +1,5 @@ +age-encryption.org/v1 +-> ssh-ed25519 aqswPA nsjKPakYuFVxfbJkPKnhqPytMz07KIT32xgJpiuaRD0 +fv+HZdDb1Evy0LIA5sFMFx+KUbAF7jJojrQXMSSmNAo +--- zJOYXheC2OupvfQNtDfcUCkVMg3TqJQEFjTfAwyi/Pw +ΰmaJ^UZ>f@mG`rOY2#܎oΙ= S_.Ma3HLcBtZנ5c0=LK+!cutRU26ߪ)fPڳAU \ No newline at end of file diff --git a/nixos/secrets/secrets.nix b/nixos/secrets/secrets.nix index 8b05dd6..9ce4ece 100644 --- a/nixos/secrets/secrets.nix +++ b/nixos/secrets/secrets.nix @@ -28,6 +28,7 @@ let encryptedFiles = [ "lewis_host_ed25519.age" "lewis_user_ed25519.age" + "database_passwords.env.age" ]; }; }; From 10dbccae97ed1e1ed0cd336b69876fc23c19c6fb Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sat, 6 Jan 2024 21:45:18 +0100 Subject: [PATCH 03/10] create top-level switch whether a machine holds the application data --- nixos/machines/default.nix | 4 +--- nixos/modules/default.nix | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index c161060..572f87f 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -38,9 +38,7 @@ nixosModule.lab = { disko.osDiskDevice = "/dev/sda"; - backups.enable = true; - networking.allowDMZConnectivity = true; - data-sharing.enable = true; + dataHost.enable = true; dataDisk = { enable = true; diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index 5762b09..dbd248e 100644 --- a/nixos/modules/default.nix +++ b/nixos/modules/default.nix @@ -1,3 +1,7 @@ +{ lib, config, ... }: + +let cfg = config.lab.dataHost; +in { imports = [ ./terraform-database @@ -9,4 +13,20 @@ ./networking.nix ./data-sharing.nix ]; + + options.lab.dataHost.enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether this machine holds application data. + This enables NFS and PostgreSQL to serve this data, and sets up backups. + Also enables networking on the DMZ to enable serving data. + ''; + }; + + config.lab = lib.mkIf cfg.enable { + backups.enable = true; + data-sharing.enable = true; + networking.allowDMZConnectivity = true; + }; } From 7c7b3e667bf6f42df2967ce894480cbedfb25cf2 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sat, 6 Jan 2024 23:07:54 +0100 Subject: [PATCH 04/10] swap disks on jefke fix freshrss NFS volume mount point remove freshrss extensions volume disable vpay node in docker swarm --- .../docker_swarm/ansible/inventory/hosts.yml | 4 ++-- .../ansible/roles/freshrss/docker-stack.yml.j2 | 12 +----------- nixos/machines/default.nix | 9 ++++++--- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/legacy/projects/docker_swarm/ansible/inventory/hosts.yml b/legacy/projects/docker_swarm/ansible/inventory/hosts.yml index 55cb1f8..a7b1508 100644 --- a/legacy/projects/docker_swarm/ansible/inventory/hosts.yml +++ b/legacy/projects/docker_swarm/ansible/inventory/hosts.yml @@ -7,5 +7,5 @@ all: hosts: bancomart: ansible_host: bancomart.dmz - vpay: - ansible_host: vpay.dmz + # vpay: + # ansible_host: vpay.dmz diff --git a/legacy/projects/docker_swarm/ansible/roles/freshrss/docker-stack.yml.j2 b/legacy/projects/docker_swarm/ansible/roles/freshrss/docker-stack.yml.j2 index bf341fd..ac4760a 100644 --- a/legacy/projects/docker_swarm/ansible/roles/freshrss/docker-stack.yml.j2 +++ b/legacy/projects/docker_swarm/ansible/roles/freshrss/docker-stack.yml.j2 @@ -10,12 +10,7 @@ volumes: driver_opts: type: "nfs" o: "addr=lewis.dmz,nolock,soft,rw" - device: ":/mnt/data/freshrss/data" - extensions: - driver_opts: - type: "nfs" - o: "addr=lewis.dmz,nolock,soft,rw" - device: ":/mnt/data/freshrss/extensions" + device: ":/mnt/data/nfs/freshrss/data" services: freshrss: @@ -28,11 +23,6 @@ services: target: /var/www/FreshRSS/data volume: nocopy: true - - type: volume - source: extensions - target: /var/www/FreshRSS/extensions - volume: - nocopy: true environment: TZ: Europe/Amsterdam CRON_MIN: '2,32' diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index 572f87f..9aca512 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -4,10 +4,13 @@ hostName = "jefke.hyp"; nixosModule.lab = { - dataDisk.enable = true; terraformDatabase.enable = true; - # k3s.enable = true; - disko.osDiskDevice = "/dev/nvme0n1"; + disko.osDiskDevice = "/dev/sda"; + + dataDisk = { + enable = true; + devicePath = "/dev/nvme0n1p1"; + }; ssh = { useCertificates = true; From 997d9bb0cb127cb91b4037350b31ae362358ab48 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sat, 6 Jan 2024 23:56:00 +0100 Subject: [PATCH 05/10] create terraform project to setup libvirt on hosts use SATA drive for atlas OS remove thecloud legacy project --- legacy/projects/docker_swarm/vm/main.tf | 14 --- legacy/projects/libvirt_setup/main.tf | 38 ++++++++ legacy/projects/thecloud/README.md | 5 - legacy/projects/thecloud/ansible/ansible.cfg | 8 -- .../ansible/inventory/host_vars/thecloud.yml | 97 ------------------- .../thecloud/ansible/inventory/hosts.yml | 5 - .../thecloud/ansible/requirements.yml | 3 - .../roles/postgresql/handlers/main.yml | 4 - .../ansible/roles/postgresql/tasks/main.yml | 15 --- legacy/projects/thecloud/ansible/share.yml | 25 ----- legacy/projects/thecloud/ansible/thecloud.yml | 31 ------ legacy/projects/thecloud/data/main.tf | 32 ------ legacy/projects/thecloud/vm/main.tf | 40 -------- nixos/machines/default.nix | 7 +- 14 files changed, 44 insertions(+), 280 deletions(-) create mode 100644 legacy/projects/libvirt_setup/main.tf delete mode 100644 legacy/projects/thecloud/README.md delete mode 100644 legacy/projects/thecloud/ansible/ansible.cfg delete mode 100644 legacy/projects/thecloud/ansible/inventory/host_vars/thecloud.yml delete mode 100644 legacy/projects/thecloud/ansible/inventory/hosts.yml delete mode 100644 legacy/projects/thecloud/ansible/requirements.yml delete mode 100644 legacy/projects/thecloud/ansible/roles/postgresql/handlers/main.yml delete mode 100644 legacy/projects/thecloud/ansible/roles/postgresql/tasks/main.yml delete mode 100644 legacy/projects/thecloud/ansible/share.yml delete mode 100644 legacy/projects/thecloud/ansible/thecloud.yml delete mode 100644 legacy/projects/thecloud/data/main.tf delete mode 100644 legacy/projects/thecloud/vm/main.tf diff --git a/legacy/projects/docker_swarm/vm/main.tf b/legacy/projects/docker_swarm/vm/main.tf index 02b1002..340747e 100644 --- a/legacy/projects/docker_swarm/vm/main.tf +++ b/legacy/projects/docker_swarm/vm/main.tf @@ -23,13 +23,6 @@ provider "libvirt" { uri = "qemu+ssh://root@atlas.hyp/system?known_hosts=/etc/ssh/ssh_known_hosts" } -module "setup_jefke" { - source = "../../../terraform_modules/setup" - providers = { - libvirt = libvirt.jefke - } -} - module "bancomart" { source = "../../../terraform_modules/debian" name = "bancomart" @@ -40,13 +33,6 @@ module "bancomart" { } } -module "setup_atlas" { - source = "../../../terraform_modules/setup" - providers = { - libvirt = libvirt.atlas - } -} - module "maestro" { source = "../../../terraform_modules/debian" name = "maestro" diff --git a/legacy/projects/libvirt_setup/main.tf b/legacy/projects/libvirt_setup/main.tf new file mode 100644 index 0000000..02634ab --- /dev/null +++ b/legacy/projects/libvirt_setup/main.tf @@ -0,0 +1,38 @@ +terraform { + backend "pg" { + schema_name = "libvirtsetup" + conn_str = "postgresql://terraform@jefke.hyp/terraformstates" + } + + required_providers { + libvirt = { + source = "dmacvicar/libvirt" + version = "0.7.1" # https://github.com/dmacvicar/terraform-provider-libvirt/issues/1040 + } + } +} + +# https://libvirt.org/uri.html#libssh-and-libssh2-transport +provider "libvirt" { + alias = "jefke" + uri = "qemu+ssh://root@jefke.hyp/system?known_hosts=/etc/ssh/ssh_known_hosts" +} + +provider "libvirt" { + alias = "atlas" + uri = "qemu+ssh://root@atlas.hyp/system?known_hosts=/etc/ssh/ssh_known_hosts" +} + +module "setup_jefke" { + source = "../../terraform_modules/setup" + providers = { + libvirt = libvirt.jefke + } +} + +module "setup_atlas" { + source = "../../terraform_modules/setup" + providers = { + libvirt = libvirt.atlas + } +} diff --git a/legacy/projects/thecloud/README.md b/legacy/projects/thecloud/README.md deleted file mode 100644 index cdfb7bd..0000000 --- a/legacy/projects/thecloud/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# thecloud - -Thecloud is a Debian VM that provides network availability to all our persistent data: -- NFS for network files -- Postgresql for databases \ No newline at end of file diff --git a/legacy/projects/thecloud/ansible/ansible.cfg b/legacy/projects/thecloud/ansible/ansible.cfg deleted file mode 100644 index 3b55258..0000000 --- a/legacy/projects/thecloud/ansible/ansible.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[defaults] -roles_path=../../../ansible_roles:~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:roles -inventory=inventory -vault_password_file=$HOME/.config/home/ansible-vault-secret -interpreter_python=/usr/bin/python3 - -[diff] -always = True diff --git a/legacy/projects/thecloud/ansible/inventory/host_vars/thecloud.yml b/legacy/projects/thecloud/ansible/inventory/host_vars/thecloud.yml deleted file mode 100644 index c2b00aa..0000000 --- a/legacy/projects/thecloud/ansible/inventory/host_vars/thecloud.yml +++ /dev/null @@ -1,97 +0,0 @@ -apt_install_packages: - - postgresql - - python3-psycopg2 - - nfs-kernel-server - - qemu-guest-agent - -nfs_exports: [] - -redis_bind_interface: 0.0.0.0 -redis_requirepass: !vault | - $ANSIBLE_VAULT;1.1;AES256 - 37323965303638333264653936616563323235363463396330363836653865393835346263383838 - 3030386166316365633538353539623066626434313332390a616131303434373264633934356361 - 30356335643638656433326230363462373533396533366261346630353163353137333865303132 - 3536636165366631310a643538353331366130663464386565343331653031333061333330613532 - 34663932653734336239303536323331396435386332666133343033373566386562326136656330 - 63393766353063646361643565323238376334333637363232626139333664643065613237666532 - 31623032613763303136353232323837376637336431306534306336356165363039666634336433 - 30376464323862373833 - -nfs_shares: - - name: nextcloud_data - path: /mnt/data/nextcloud/data - - name: radicale - path: /mnt/data/radicale - - name: freshrss_data - path: /mnt/data/freshrss/data - - name: freshrss_extensions - path: /mnt/data/freshrss/extensions - - name: pihole_data - path: /mnt/data/pihole/data - - name: pihole_dnsmasq - path: /mnt/data/pihole/dnsmasq - - name: hedgedoc_uploads - path: /mnt/data/hedgedoc/uploads - - name: traefik_acme - path: /mnt/data/traefik/acme - - name: seafile_data - path: /mnt/data/seafile/data - - name: seafile_db - path: /mnt/data/seafile/db - - name: mastodon_system - path: /mnt/data/mastodon/system - - name: mastodon_redis - path: /mnt/data/mastodon/redis - - name: forgejo - path: /mnt/data/forgejo - - name: overleaf - path: /mnt/data/overleaf/data - - name: overleaf_redis - path: /mnt/data/overleaf/redis - - name: overleaf_mongodb - path: /mnt/data/overleaf/mongodb - - name: prometheus_data - path: /mnt/data/prometheus/data - - name: elasticsearch_certs - path: /mnt/data/elasticsearch/certs - - name: elasticsearch_data - path: /mnt/data/elasticsearch/data - - name: grafana_data - path: /mnt/data/grafana/data - - name: kitchenowl_data - path: /mnt/data/kitchenowl/data - - name: ampache_mysql - path: /mnt/data/ampache/mysql - - name: ampache_config - path: /mnt/data/ampache/config - - name: music - path: /mnt/data/nextcloud/data/data/pim/files/Music - - name: syncthing_config - path: /mnt/data/syncthing/config - -database_passwords: - nextcloud: !vault | - $ANSIBLE_VAULT;1.1;AES256 - 66326230303135303930363761316534313439383365376231623661316635393839336431313262 - 3832626365376533646561653863316364313135343366330a356136343938666133356532613263 - 39663037623232363266376335643834353735363431636535386566643763386463353962663930 - 3466343563353162320a376437353933656166323364323166376663323531373338656563653463 - 33346263626430616164613937363836343430383233393061643231346661656539623938333631 - 3632373964346139316637663364646132636636373461613534 - hedgedoc: !vault | - $ANSIBLE_VAULT;1.1;AES256 - 63363464666633663762393135333362613966636338623533393132376338343339653431396465 - 6634643863623163366235393434343662313735363438610a373065363361326565633766633835 - 38383637343230363031636634623930666365333739323162313937656239646166613738393965 - 3533666462303563360a313233306335396234393932396331313238376464363964363839396164 - 66366662356135343035363935616664613831626131376330643133313530636431613266636165 - 6265613666616164373637356235396165383662333561393939 - mastodon: !vault | - $ANSIBLE_VAULT;1.1;AES256 - 63616366396665663161376161373735626466353464393963333136336335376662326232613639 - 6166333137376131633761623163306165386562666639640a313136386431373161306331626638 - 34643433396232383962643964386631313632393161316261353331346163333261336666646563 - 6232666231653732630a396638396462323464613033306662313463663262626430363432663465 - 63623935303861663565633739363539326435623561396535623034663735373232336633303037 - 6266323136316238343963613332396261346337646264646162 diff --git a/legacy/projects/thecloud/ansible/inventory/hosts.yml b/legacy/projects/thecloud/ansible/inventory/hosts.yml deleted file mode 100644 index 19e626d..0000000 --- a/legacy/projects/thecloud/ansible/inventory/hosts.yml +++ /dev/null @@ -1,5 +0,0 @@ -all: - hosts: - thecloud: - ansible_user: root - ansible_host: thecloud.dmz diff --git a/legacy/projects/thecloud/ansible/requirements.yml b/legacy/projects/thecloud/ansible/requirements.yml deleted file mode 100644 index 43e6eca..0000000 --- a/legacy/projects/thecloud/ansible/requirements.yml +++ /dev/null @@ -1,3 +0,0 @@ -- name: apt - src: https://github.com/sunscrapers/ansible-role-apt.git - scm: git diff --git a/legacy/projects/thecloud/ansible/roles/postgresql/handlers/main.yml b/legacy/projects/thecloud/ansible/roles/postgresql/handlers/main.yml deleted file mode 100644 index a09812e..0000000 --- a/legacy/projects/thecloud/ansible/roles/postgresql/handlers/main.yml +++ /dev/null @@ -1,4 +0,0 @@ -- name: restart postgres - systemd: - name: postgresql - state: restarted diff --git a/legacy/projects/thecloud/ansible/roles/postgresql/tasks/main.yml b/legacy/projects/thecloud/ansible/roles/postgresql/tasks/main.yml deleted file mode 100644 index d3e811e..0000000 --- a/legacy/projects/thecloud/ansible/roles/postgresql/tasks/main.yml +++ /dev/null @@ -1,15 +0,0 @@ -- name: Open postgres port - ini_file: - path: /etc/postgresql/15/main/postgresql.conf - section: null - option: listen_addresses - value: "'*'" - notify: restart postgres - -- name: Change data directory - ini_file: - path: /etc/postgresql/15/main/postgresql.conf - section: null - option: data_directory - value: "'/mnt/data/postgresql'" - notify: restart postgres diff --git a/legacy/projects/thecloud/ansible/share.yml b/legacy/projects/thecloud/ansible/share.yml deleted file mode 100644 index 7957bf8..0000000 --- a/legacy/projects/thecloud/ansible/share.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: Create databases and NFS shares - hosts: thecloud - handlers: - - name: reload nfs - systemd: - name: nfs-kernel-server - state: restarted - - tasks: - - name: Create nfs shares - with_items: "{{ nfs_shares }}" - copy: - dest: "/etc/exports.d/{{ item.name }}.exports" - content: "{{ item.path }} *(rw,sync,no_subtree_check,no_root_squash)" - notify: reload nfs - - - name: Create databases - with_items: "{{ database_passwords | dict2items }}" - include_role: - name: postgresql_database - vars: - database_name: "{{ item.key }}" - database_user: "{{ item.key }}" - database_password: "{{ item.value }}" diff --git a/legacy/projects/thecloud/ansible/thecloud.yml b/legacy/projects/thecloud/ansible/thecloud.yml deleted file mode 100644 index f019457..0000000 --- a/legacy/projects/thecloud/ansible/thecloud.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -- name: Wait for Cloud-Init to finish - hosts: all - gather_facts: no - roles: - - cloudinit_wait - -- name: Setup NFS - hosts: thecloud - - roles: - - {role: apt, tags: apt} - - {role: postgresql, tags: postgresql} - - post_tasks: - - name: Ensure NFS exports directory exists - file: - path: /etc/exports.d - state: directory - - - name: Start NFS - systemd: - name: nfs-kernel-server - state: started - enabled: true - - - name: Enable Qemu guest agent - systemd: - name: qemu-guest-agent - state: started - enabled: true diff --git a/legacy/projects/thecloud/data/main.tf b/legacy/projects/thecloud/data/main.tf deleted file mode 100644 index cf09328..0000000 --- a/legacy/projects/thecloud/data/main.tf +++ /dev/null @@ -1,32 +0,0 @@ -terraform { - backend "pg" { - schema_name = "thecloud-data" - conn_str = "postgresql://terraform@jefke.hyp/terraformstates" - } - - required_providers { - libvirt = { - source = "dmacvicar/libvirt" - version = "0.7.1" # https://github.com/dmacvicar/terraform-provider-libvirt/issues/1040 - } - } -} - -# https://libvirt.org/uri.html#libssh-and-libssh2-transport -provider "libvirt" { - uri = "qemu+ssh://root@lewis.hyp/system?known_hosts=/etc/ssh/ssh_known_hosts" -} - -module "data_pool" { - source = "../../../terraform_modules/setup/data" -} - -resource "libvirt_volume" "data" { - name = "thecloud-data.qcow2" - pool = "data" - size = 1024 * 1024 * 1024 * 150 -} - -output "data_disk_id" { - value = libvirt_volume.data.id -} diff --git a/legacy/projects/thecloud/vm/main.tf b/legacy/projects/thecloud/vm/main.tf deleted file mode 100644 index 25307cb..0000000 --- a/legacy/projects/thecloud/vm/main.tf +++ /dev/null @@ -1,40 +0,0 @@ -terraform { - backend "pg" { - schema_name = "thecloud" - conn_str = "postgresql://terraform@jefke.hyp/terraformstates" - } - - required_providers { - libvirt = { - source = "dmacvicar/libvirt" - version = "0.7.1" # https://github.com/dmacvicar/terraform-provider-libvirt/issues/1040 - } - } -} - -# https://libvirt.org/uri.html#libssh-and-libssh2-transport -provider "libvirt" { - alias = "lewis" - uri = "qemu+ssh://root@lewis.hyp/system?known_hosts=/etc/ssh/ssh_known_hosts" -} - -module "setup_lewis" { - source = "../../../terraform_modules/setup" - providers = { - libvirt = libvirt.lewis - } -} - -module "thecloud" { - source = "../../../terraform_modules/debian" - name = "thecloud" - ram = 1024 - storage = 25 - mac = "CA:FE:C0:FF:EE:0A" - data_disk = "/mnt/data/volumes/thecloud-data.qcow2" - providers = { - libvirt = libvirt.lewis - } - - depends_on = [ module.setup_lewis ] -} diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index 9aca512..a8d14c3 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -25,7 +25,12 @@ hostName = "atlas.hyp"; nixosModule.lab = { - disko.osDiskDevice = "/dev/nvme0n1"; + disko.osDiskDevice = "/dev/sda"; + + dataDisk = { + enable = true; + devicePath = "/dev/nvme0n1p1"; + }; ssh = { useCertificates = true; From 2804e764f5ad5a9c6d7bc0eb692d300a8ab211b9 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 7 Jan 2024 00:22:44 +0100 Subject: [PATCH 06/10] merge modules into one storage module --- nixos/machines/default.nix | 22 +++---- nixos/modules/backups.nix | 7 +-- nixos/modules/data-disk.nix | 33 ---------- nixos/modules/default.nix | 3 +- nixos/modules/disko.nix | 39 ------------ nixos/modules/storage.nix | 66 ++++++++++++++++++++ nixos/modules/terraform-database/default.nix | 3 +- 7 files changed, 80 insertions(+), 93 deletions(-) delete mode 100644 nixos/modules/data-disk.nix delete mode 100644 nixos/modules/disko.nix create mode 100644 nixos/modules/storage.nix diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index a8d14c3..dfadb75 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -5,11 +5,10 @@ nixosModule.lab = { terraformDatabase.enable = true; - disko.osDiskDevice = "/dev/sda"; - dataDisk = { - enable = true; - devicePath = "/dev/nvme0n1p1"; + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; }; ssh = { @@ -25,11 +24,9 @@ hostName = "atlas.hyp"; nixosModule.lab = { - disko.osDiskDevice = "/dev/sda"; - - dataDisk = { - enable = true; - devicePath = "/dev/nvme0n1p1"; + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; }; ssh = { @@ -45,12 +42,11 @@ hostName = "lewis.hyp"; nixosModule.lab = { - disko.osDiskDevice = "/dev/sda"; dataHost.enable = true; - dataDisk = { - enable = true; - devicePath = "/dev/nvme0n1p1"; + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; }; ssh = { diff --git a/nixos/modules/backups.nix b/nixos/modules/backups.nix index 11d838d..977159a 100644 --- a/nixos/modules/backups.nix +++ b/nixos/modules/backups.nix @@ -48,8 +48,7 @@ in }; repoLocation = lib.mkOption { - # TODO: maybe make sure data disk is enabled? is there an "ensure" method in nix? - default = "${config.lab.dataDisk.mountPoint}/backups/nfs.borg"; + default = "${config.lab.storage.dataMountPoint}/backups/nfs.borg"; type = lib.types.str; description = '' Location of the Borg repository to back up to. @@ -57,7 +56,7 @@ in }; subvolumeLocation = lib.mkOption { - default = "${config.lab.dataDisk.mountPoint}/nfs"; + default = "${config.lab.storage.dataMountPoint}/nfs"; type = lib.types.str; description = '' Location of the btrfs subvolume holding the data. @@ -65,7 +64,7 @@ in }; snapshotLocation = lib.mkOption { - default = "${config.lab.dataDisk.mountPoint}/nfs-backup"; + default = "${config.lab.storage.dataMountPoint}/nfs-backup"; type = lib.types.str; description = '' Location to (temporary) create a snapshot of the subvolume. diff --git a/nixos/modules/data-disk.nix b/nixos/modules/data-disk.nix deleted file mode 100644 index e4bb6d3..0000000 --- a/nixos/modules/data-disk.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ lib, config, ... }: -let cfg = config.lab.dataDisk; -in { - options.lab.dataDisk = { - enable = lib.mkOption { - default = false; - type = lib.types.bool; - description = '' - Whether to automatically mount a disk to be used as a data disk. - ''; - }; - - mountPoint = lib.mkOption { - default = "/mnt/data"; - type = lib.types.str; - description = '' - Mount point of the data disk (if enabled). - ''; - }; - - devicePath = lib.mkOption { - default = "/dev/sda1"; - type = lib.types.str; - description = '' - Path of the device to be used as a data disk. - ''; - }; - }; - - config = lib.mkIf cfg.enable { - fileSystems.${cfg.mountPoint} = { device = cfg.devicePath; }; - }; -} diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index dbd248e..71fef6b 100644 --- a/nixos/modules/default.nix +++ b/nixos/modules/default.nix @@ -4,11 +4,10 @@ let cfg = config.lab.dataHost; in { imports = [ + ./storage.nix ./terraform-database - ./data-disk.nix ./ssh-certificates.nix ./k3s - ./disko.nix ./backups.nix ./networking.nix ./data-sharing.nix diff --git a/nixos/modules/disko.nix b/nixos/modules/disko.nix deleted file mode 100644 index 58f5cc6..0000000 --- a/nixos/modules/disko.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ lib, config, ... }: -let cfg = config.lab.disko; -in { - options.lab.disko.osDiskDevice = lib.mkOption { - type = lib.types.str; - description = '' - The disk device to be used for the operating system. - ''; - }; - - # TODO: rename this to 'osDisk'. Unfortunately, we would need to run nixos-anywhere again then - config.disko.devices.disk.vdb = { - device = cfg.osDiskDevice; - type = "disk"; - content = { - type = "gpt"; - partitions = { - ESP = { - type = "EF00"; - size = "500M"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - }; - root = { - end = "-4G"; - content = { - type = "filesystem"; - format = "btrfs"; - mountpoint = "/"; - }; - }; - swap = { size = "100%"; }; - }; - }; - }; -} diff --git a/nixos/modules/storage.nix b/nixos/modules/storage.nix new file mode 100644 index 0000000..f01b665 --- /dev/null +++ b/nixos/modules/storage.nix @@ -0,0 +1,66 @@ +{ lib, config, ... }: +let cfg = config.lab.storage; +in { + options.lab.storage = { + osDisk = lib.mkOption { + type = lib.types.str; + description = '' + The disk to be used for the machine's operating system. + ''; + }; + + dataPartition = lib.mkOption { + type = lib.types.str; + description = '' + Partition to be used for data storage on this machine. + ''; + }; + + dataMountPoint = lib.mkOption { + default = "/mnt/data"; + type = lib.types.str; + description = '' + Mount point of the machine's data partition. + ''; + }; + }; + + config = { + fileSystems.${cfg.dataMountPoint}.device = cfg.dataPartition; + + # TODO: Rename this to 'osDisk'. Unfortunately, we would need to run nixos-anywhere again then. + disko.devices.disk.vdb = { + device = cfg.osDisk; + type = "disk"; + + content = { + type = "gpt"; + + partitions = { + swap.size = "100%"; + + ESP = { + type = "EF00"; + size = "500M"; + + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + + root = { + end = "-4G"; + + content = { + type = "filesystem"; + format = "btrfs"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; +} diff --git a/nixos/modules/terraform-database/default.nix b/nixos/modules/terraform-database/default.nix index 4cf6f82..db68f34 100644 --- a/nixos/modules/terraform-database/default.nix +++ b/nixos/modules/terraform-database/default.nix @@ -18,8 +18,7 @@ in { package = pkgs.postgresql_15; enableTCPIP = true; - dataDir = lib.mkIf config.lab.dataDisk.enable - "${config.lab.dataDisk.mountPoint}/postgresql/${config.services.postgresql.package.psqlSchema}"; + dataDir = "${config.lab.storage.dataMountPoint}/postgresql/${config.services.postgresql.package.psqlSchema}"; authentication = '' hostssl terraformstates terraform all cert From 914d84ef23cbd0d0e468a31ca72d8dc9dd3012f2 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 7 Jan 2024 15:57:30 +0100 Subject: [PATCH 07/10] encrypt borg repository also backup to AWS EC2 instance --- nixos/default.nix | 1 + nixos/modules/backups.nix | 16 +++++++++++----- nixos/secrets/borg_passphrase.age | 6 ++++++ nixos/secrets/ec2_borg_server.pem.age | Bin 0 -> 599 bytes nixos/secrets/secrets.nix | 3 +++ 5 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 nixos/secrets/borg_passphrase.age create mode 100644 nixos/secrets/ec2_borg_server.pem.age diff --git a/nixos/default.nix b/nixos/default.nix index 596a355..04a4ecd 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -112,6 +112,7 @@ tcpdump lsof parted + borgbackup ]; diff --git a/nixos/modules/backups.nix b/nixos/modules/backups.nix index 977159a..4e4beae 100644 --- a/nixos/modules/backups.nix +++ b/nixos/modules/backups.nix @@ -17,10 +17,13 @@ let repositories: - path: ${cfg.repoLocation} label: nfs + - path: ssh://admin@ec2-3-254-121-39.eu-west-1.compute.amazonaws.com/mnt/data/nfs.borg + label: ec2 + ssh_command: "${pkgs.openssh}/bin/ssh -i ${config.age.secrets."ec2_borg_server.pem".path} -o StrictHostKeychecking=no -o ConnectTimeout=10 -o ConnectionAttempts=3" keep_daily: 7 keep_weekly: 4 keep_monthly: 6 - unknown_unencrypted_repo_access_is_ok: true + encryption_passcommand: "${pkgs.coreutils}/bin/cat ''${BORG_PASSPHRASE_FILE}" before_everything: - ${beforeEverything}/bin/beforeEverything postgresql_databases: @@ -64,7 +67,7 @@ in }; snapshotLocation = lib.mkOption { - default = "${config.lab.storage.dataMountPoint}/nfs-backup"; + default = "${config.lab.storage.dataMountPoint}/snapshot-nfs"; type = lib.types.str; description = '' Location to (temporary) create a snapshot of the subvolume. @@ -73,7 +76,7 @@ in }; config = lib.mkIf cfg.enable { - environment.systemPackages = with pkgs; [ borgbackup postgresql ]; + environment.systemPackages = with pkgs; [ postgresql ]; # Converted from: # https://github.com/borgmatic-collective/borgmatic/tree/84823dfb912db650936e3492f6ead7e0e0d32a0f/sample/systemd systemd.services.borgmatic = { @@ -94,6 +97,7 @@ in Restart = "no"; LogRateLimitIntervalSec = 0; EnvironmentFile = config.age.secrets."database_passwords.env".path; + Environment = "BORG_PASSPHRASE_FILE=${config.age.secrets."borg_passphrase".path}"; }; script = "${pkgs.systemd}/bin/systemd-inhibit --who=\"borgmatic\" --what=\"sleep:shutdown\" --why=\"Prevent interrupting scheduled backup\" ${pkgs.borgmatic}/bin/borgmatic --verbosity -2 --syslog-verbosity 1 -c ${borgmaticConfig}"; @@ -109,8 +113,10 @@ in }; }; - age.secrets."database_passwords.env" = { - file = ../secrets/database_passwords.env.age; + age.secrets = { + "database_passwords.env".file = ../secrets/database_passwords.env.age; + "borg_passphrase".file = ../secrets/borg_passphrase.age; + "ec2_borg_server.pem".file = ../secrets/ec2_borg_server.pem.age; }; }; } diff --git a/nixos/secrets/borg_passphrase.age b/nixos/secrets/borg_passphrase.age new file mode 100644 index 0000000..ccfb7ca --- /dev/null +++ b/nixos/secrets/borg_passphrase.age @@ -0,0 +1,6 @@ +age-encryption.org/v1 +-> ssh-ed25519 aqswPA BWfWJ0Detm+1l0tYnjR9n5rIUBfdHb/wTnZnGoYx6SU +gp5vcIXtJpF6KJ0cHJ6GRpHQvxi7ij//1LH0afFoRuo +--- exwOM8D5yMcDFp0uzRnbD6TWSgs12WmZo7sKlnHYOwY + 4֚0 +e(+}f%^ kbד{WVPnד:6s \ No newline at end of file diff --git a/nixos/secrets/ec2_borg_server.pem.age b/nixos/secrets/ec2_borg_server.pem.age new file mode 100644 index 0000000000000000000000000000000000000000..05f15bcc22ab9804aaafc4e4ec8e2a8a463c6d14 GIT binary patch literal 599 zcmV-d0;v6AXJsvAZewzJaCB*JZZ217* zT4+viIZRMZOgUp~Hdr=PLq<_CR%k?1PiZ%Lb}(Z|WmO6-EiE7`F*r72Gcjs$M^9^c zdU7~)W=&~xMQ1cYNJTesWn(pEG%rvwVpnNdcXtXue3XE(+00wEI#_ii&2mAyJ9JqB zlj}P!qHqC4{{(j(9WUP3KEiCFO<`iAuA<3~{DMbdWj)l@c&AD%bw&&?E~_@qU^%_) z(BG6GlL%JMVkwQZR3%d)m|xw=r~ez$(kC07+=gnFRdc!HDXyE}sG8=z#K2{Mu_)-x z?CMUYy$6Srt{9|)2qDN`fLbp$sC}v}{O+snv_Eh!H`!RiqIy<)sqvI_fR%fdQ zdo8t$*D0Wvc@*%P6Mg<0a$I$zC8%+W@NdByBlUp$ow!MnA)vS!!U6(d&>z;l8ZIeq ze<5N3EX&k}S3{ho<%U=ylx=CeLS;PocRzbz$07=_XMx7%4BQm`9^(RsVF^PHVurvA z|FC{y<2f5#TWR}d8$}0)z4i9gPKdMV@-M3tWfDpzS0a7AVP(nN9teEurRDhfBH_eN z%V(Tb05;oSr3#o=$_YL)pvYHIKqyB==KrL}WD%?^pj{f+QE5mnfQ?TlBmxWSc)(CR ltu`cw36UQRdHQTTb*)R~s~~T6q|Bh!4W?G##qsUD?6sg01Y7_B literal 0 HcmV?d00001 diff --git a/nixos/secrets/secrets.nix b/nixos/secrets/secrets.nix index 9ce4ece..9899923 100644 --- a/nixos/secrets/secrets.nix +++ b/nixos/secrets/secrets.nix @@ -1,3 +1,4 @@ +# TODO: Just encrypt each file with all hosts' public keys (plus our personal public keys) and deploy when demanded. let pkgs = import { }; lib = pkgs.lib; @@ -29,6 +30,8 @@ let "lewis_host_ed25519.age" "lewis_user_ed25519.age" "database_passwords.env.age" + "borg_passphrase.age" + "ec2_borg_server.pem.age" ]; }; }; From d92f27bd03b268be92d17dc9b917bda3f161dedb Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 7 Jan 2024 16:26:11 +0100 Subject: [PATCH 08/10] don't manage database permissions in nix closes #24 --- nixos/modules/terraform-database/default.nix | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nixos/modules/terraform-database/default.nix b/nixos/modules/terraform-database/default.nix index db68f34..e13e50e 100644 --- a/nixos/modules/terraform-database/default.nix +++ b/nixos/modules/terraform-database/default.nix @@ -36,10 +36,7 @@ in { ssl_ca_file = serverCert; }; - ensureUsers = [{ - name = "terraform"; - ensurePermissions = { "DATABASE terraformstates" = "ALL PRIVILEGES"; }; - }]; + ensureUsers = [{ name = "terraform"; }]; }; age.secrets."postgresql_server.key" = { From a152cde165a3a73fde97e097b524ba5f9e5ff64d Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 7 Jan 2024 18:14:44 +0100 Subject: [PATCH 09/10] add authoritative DNS server --- nixos/machines/default.nix | 1 + nixos/modules/default.nix | 1 + nixos/modules/dns.nix | 121 +++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 nixos/modules/dns.nix diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index dfadb75..93736c7 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -43,6 +43,7 @@ nixosModule.lab = { dataHost.enable = true; + dns.enable = true; storage = { osDisk = "/dev/sda"; diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index 71fef6b..6ffb678 100644 --- a/nixos/modules/default.nix +++ b/nixos/modules/default.nix @@ -11,6 +11,7 @@ in ./backups.nix ./networking.nix ./data-sharing.nix + ./dns.nix ]; options.lab.dataHost.enable = lib.mkOption { diff --git a/nixos/modules/dns.nix b/nixos/modules/dns.nix new file mode 100644 index 0000000..dbbe593 --- /dev/null +++ b/nixos/modules/dns.nix @@ -0,0 +1,121 @@ +{ pkgs, lib, config, ... }: +let + cfg = config.lab.dns; + kunisZoneFile = pkgs.writeTextFile { + name = "kunis-zone-file"; + text = '' + $ORIGIN kun.is. + $TTL 1m + + @ IN SOA ns1.kun.is. hostmaster.kun.is. ( + 1704580936 + 1D + 1H + 1W + 1D ) + + IN NS ns1.kun.is. + IN NS ns2.kun.is. + + @ IN MX 10 mail.kun.is. + + + ns IN A 192.145.57.90 + ns1 IN A 192.145.57.90 + ns2 IN A 192.145.57.90 + * IN A 192.145.57.90 + verify.bing.com. IN CNAME fcfe5d31d5b7ae1af0b352a6b4c75d3f + @ IN TXT "\"google-site-verification=sznWJNdSZfiAESJhnDQEJ6hf06W9vndvhMi6wP_HH04\"" + ''; + }; + + geokunisnlZoneFile = pkgs.writeTextFile { + name = "geokunisnl-zone-file"; + text = '' + $ORIGIN geokunis2.nl. + $TTL 1h + + @ IN SOA ns.geokunis2.nl. hostmaster.geokunis2.nl. ( + 1704580936 + 1D + 1H + 1W + 1D ) + + IN NS ns.geokunis2.nl. + IN NS ns0.transip.net. + IN NS ns1.transip.nl. + IN NS ns2.transip.eu. + + @ IN MX 10 mail.geokunis2.nl. + + + @ IN A 192.145.57.90 + @ IN AAAA 2a0d:6e00:1a77:30:b62e:99ff:fe77:1bda + mail IN A 192.145.57.90 + wg IN A 192.145.57.90 + wg IN AAAA 2a0d:6e00:1a77::1 + wg4 IN A 192.145.57.90 + wg6 IN AAAA 2a0d:6e00:1a77::1 + tuindersweijde IN A 192.145.57.90 + ns IN A 192.145.57.90 + ns IN AAAA 2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee07 + cyberchef IN A 192.145.57.90 + cyberchef IN AAAA 2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee03 + inbucket IN A 192.145.57.90 + kms IN A 192.145.57.90 + @ IN CAA 0 issue \"letsencrypt.org\" + ''; + }; +in +{ + options.lab.dns.enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether to enable an authoritative DNS server and DNSmasq for DMZ network. + ''; + }; + + config = lib.mkIf cfg.enable { + networking.firewall = { + allowedTCPPorts = [ 53 ]; + allowedUDPPorts = [ 53 ]; + }; + + services.bind = { + enable = true; + forwarders = [ ]; + # TODO: disable ipv6 for now, as the hosts themselves lack routes it seems. + ipv4Only = true; + + extraOptions = '' + allow-transfer { none; }; + allow-recursion { none; }; + version "No dice."; + ''; + + zones = { + "kun.is" = { + master = true; + file = kunisZoneFile; + allowQuery = [ "any" ]; + extraConfig = '' + notify yes; + allow-update { none; }; + ''; + }; + + "geokunis2.nl" = { + master = true; + file = geokunisnlZoneFile; + allowQuery = [ "any" ]; + extraConfig = '' + notify yes; + allow-update { none; }; + ''; + }; + }; + }; + }; +} From 62bbc7c13de03f5747fb379c3404db3db5ca755a Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 7 Jan 2024 20:24:12 +0100 Subject: [PATCH 10/10] use dns.nix voor zone file generation --- flake.lock | 37 +++++++ flake.nix | 9 +- nixos/modules/default.nix | 2 +- nixos/modules/dns.nix | 121 ----------------------- nixos/modules/dns/default.nix | 65 ++++++++++++ nixos/modules/dns/zones/geokunis2.nl.nix | 47 +++++++++ nixos/modules/dns/zones/kun.is.nix | 28 ++++++ 7 files changed, 185 insertions(+), 124 deletions(-) delete mode 100644 nixos/modules/dns.nix create mode 100644 nixos/modules/dns/default.nix create mode 100644 nixos/modules/dns/zones/geokunis2.nl.nix create mode 100644 nixos/modules/dns/zones/kun.is.nix diff --git a/flake.lock b/flake.lock index e28e088..d5b79c3 100644 --- a/flake.lock +++ b/flake.lock @@ -84,6 +84,27 @@ "type": "github" } }, + "dns": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1635273082, + "narHash": "sha256-EHiDP2jEa7Ai5ZwIf5uld9RVFcV77+2SUxjQXwJsJa0=", + "owner": "kirelagin", + "repo": "dns.nix", + "rev": "c7b9645da9c0ddce4f9de4ef27ec01bb8108039a", + "type": "github" + }, + "original": { + "owner": "kirelagin", + "repo": "dns.nix", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -116,6 +137,21 @@ "type": "github" } }, + "flake-utils": { + "locked": { + "lastModified": 1614513358, + "narHash": "sha256-LakhOx3S1dRjnh0b5Dg3mbZyH0ToC9I8Y2wKSkBaTzU=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5466c5bbece17adaab2d82fae80b46e807611bf3", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "home-manager": { "inputs": { "nixpkgs": [ @@ -213,6 +249,7 @@ "agenix": "agenix", "deploy-rs": "deploy-rs", "disko": "disko", + "dns": "dns", "kubenix": "kubenix", "nixpkgs": "nixpkgs_2", "nixpkgs-unstable": "nixpkgs-unstable" diff --git a/flake.nix b/flake.nix index 68b8ee9..194fbef 100644 --- a/flake.nix +++ b/flake.nix @@ -19,10 +19,15 @@ url = "github:ryantm/agenix"; inputs.nixpkgs.follows = "nixpkgs"; }; + + dns = { + url = "github:kirelagin/dns.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = - { self, nixpkgs, deploy-rs, disko, agenix, kubenix, nixpkgs-unstable, ... }: + { self, nixpkgs, deploy-rs, disko, agenix, kubenix, nixpkgs-unstable, dns, ... }: let system = "x86_64-linux"; pkgs = nixpkgs.legacyPackages.${system}; @@ -65,7 +70,7 @@ nixosConfigurations = mkNixosSystems (machine: { inherit system; - specialArgs = { inherit kubenix; }; + specialArgs = { inherit kubenix dns; }; modules = [ machine.nixosModule disko.nixosModules.disko diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index 6ffb678..8388026 100644 --- a/nixos/modules/default.nix +++ b/nixos/modules/default.nix @@ -11,7 +11,7 @@ in ./backups.nix ./networking.nix ./data-sharing.nix - ./dns.nix + ./dns ]; options.lab.dataHost.enable = lib.mkOption { diff --git a/nixos/modules/dns.nix b/nixos/modules/dns.nix deleted file mode 100644 index dbbe593..0000000 --- a/nixos/modules/dns.nix +++ /dev/null @@ -1,121 +0,0 @@ -{ pkgs, lib, config, ... }: -let - cfg = config.lab.dns; - kunisZoneFile = pkgs.writeTextFile { - name = "kunis-zone-file"; - text = '' - $ORIGIN kun.is. - $TTL 1m - - @ IN SOA ns1.kun.is. hostmaster.kun.is. ( - 1704580936 - 1D - 1H - 1W - 1D ) - - IN NS ns1.kun.is. - IN NS ns2.kun.is. - - @ IN MX 10 mail.kun.is. - - - ns IN A 192.145.57.90 - ns1 IN A 192.145.57.90 - ns2 IN A 192.145.57.90 - * IN A 192.145.57.90 - verify.bing.com. IN CNAME fcfe5d31d5b7ae1af0b352a6b4c75d3f - @ IN TXT "\"google-site-verification=sznWJNdSZfiAESJhnDQEJ6hf06W9vndvhMi6wP_HH04\"" - ''; - }; - - geokunisnlZoneFile = pkgs.writeTextFile { - name = "geokunisnl-zone-file"; - text = '' - $ORIGIN geokunis2.nl. - $TTL 1h - - @ IN SOA ns.geokunis2.nl. hostmaster.geokunis2.nl. ( - 1704580936 - 1D - 1H - 1W - 1D ) - - IN NS ns.geokunis2.nl. - IN NS ns0.transip.net. - IN NS ns1.transip.nl. - IN NS ns2.transip.eu. - - @ IN MX 10 mail.geokunis2.nl. - - - @ IN A 192.145.57.90 - @ IN AAAA 2a0d:6e00:1a77:30:b62e:99ff:fe77:1bda - mail IN A 192.145.57.90 - wg IN A 192.145.57.90 - wg IN AAAA 2a0d:6e00:1a77::1 - wg4 IN A 192.145.57.90 - wg6 IN AAAA 2a0d:6e00:1a77::1 - tuindersweijde IN A 192.145.57.90 - ns IN A 192.145.57.90 - ns IN AAAA 2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee07 - cyberchef IN A 192.145.57.90 - cyberchef IN AAAA 2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee03 - inbucket IN A 192.145.57.90 - kms IN A 192.145.57.90 - @ IN CAA 0 issue \"letsencrypt.org\" - ''; - }; -in -{ - options.lab.dns.enable = lib.mkOption { - default = false; - type = lib.types.bool; - description = '' - Whether to enable an authoritative DNS server and DNSmasq for DMZ network. - ''; - }; - - config = lib.mkIf cfg.enable { - networking.firewall = { - allowedTCPPorts = [ 53 ]; - allowedUDPPorts = [ 53 ]; - }; - - services.bind = { - enable = true; - forwarders = [ ]; - # TODO: disable ipv6 for now, as the hosts themselves lack routes it seems. - ipv4Only = true; - - extraOptions = '' - allow-transfer { none; }; - allow-recursion { none; }; - version "No dice."; - ''; - - zones = { - "kun.is" = { - master = true; - file = kunisZoneFile; - allowQuery = [ "any" ]; - extraConfig = '' - notify yes; - allow-update { none; }; - ''; - }; - - "geokunis2.nl" = { - master = true; - file = geokunisnlZoneFile; - allowQuery = [ "any" ]; - extraConfig = '' - notify yes; - allow-update { none; }; - ''; - }; - }; - }; - }; -} diff --git a/nixos/modules/dns/default.nix b/nixos/modules/dns/default.nix new file mode 100644 index 0000000..fd1c3dc --- /dev/null +++ b/nixos/modules/dns/default.nix @@ -0,0 +1,65 @@ +{ pkgs, lib, config, dns, ... }: +let + cfg = config.lab.dns; + publicIpv4 = "192.145.57.90"; + kunisZoneFile = pkgs.writeTextFile { + name = "kunis-zone-file"; + text = (dns.lib.toString "kun.is" (import ./zones/kun.is.nix { inherit dns publicIpv4; })); + }; + + geokunis2nlZoneFile = pkgs.writeTextFile { + name = "geokunis2nl-zone-file"; + text = (dns.lib.toString "geokunis2.nl" (import ./zones/geokunis2.nl.nix { inherit dns publicIpv4; })); + }; +in +{ + options.lab.dns.enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether to enable an authoritative DNS server and DNSmasq for DMZ network. + ''; + }; + + config = lib.mkIf cfg.enable { + networking.firewall = { + allowedTCPPorts = [ 53 ]; + allowedUDPPorts = [ 53 ]; + }; + + services.bind = { + enable = true; + forwarders = [ ]; + # TODO: disable ipv6 for now, as the hosts themselves lack routes it seems. + ipv4Only = true; + + extraOptions = '' + allow-transfer { none; }; + allow-recursion { none; }; + version "No dice."; + ''; + + zones = { + "kun.is" = { + master = true; + file = kunisZoneFile; + allowQuery = [ "any" ]; + extraConfig = '' + notify yes; + allow-update { none; }; + ''; + }; + + "geokunis2.nl" = { + master = true; + file = geokunis2nlZoneFile; + allowQuery = [ "any" ]; + extraConfig = '' + notify yes; + allow-update { none; }; + ''; + }; + }; + }; + }; +} diff --git a/nixos/modules/dns/zones/geokunis2.nl.nix b/nixos/modules/dns/zones/geokunis2.nl.nix new file mode 100644 index 0000000..29ec2c3 --- /dev/null +++ b/nixos/modules/dns/zones/geokunis2.nl.nix @@ -0,0 +1,47 @@ +{ publicIpv4, dns }: +with dns.lib.combinators; + +{ + SOA = { + nameServer = "ns"; + adminEmail = "hostmaster@geokunis2.nl"; + serial = 1704580936; + }; + + NS = [ + "ns.geokunis2.nl." + "ns0.transip.net." + "ns1.transip.nl." + "ns2.transip.eu." + ]; + + MX = [ (mx.mx 10 "mail.geokunis2.nl.") ]; + + A = [ publicIpv4 ]; + AAAA = [ "2a0d:6e00:1a77:30:b62e:99ff:fe77:1bda" ]; + CAA = letsEncrypt "caa@geokunis2.nl"; + + subdomains = { + mail.A = [ publicIpv4 ]; + wg4.A = [ publicIpv4 ]; + wg6.AAAA = [ "2a0d:6e00:1a77::1" ]; + tuindersweijde.A = [ publicIpv4 ]; + inbucket.A = [ publicIpv4 ]; + kms.A = [ publicIpv4 ]; + + wg = { + A = [ publicIpv4 ]; + AAAA = [ "2a0d:6e00:1a77::1" ]; + }; + + ns = { + A = [ publicIpv4 ]; + AAAA = [ "2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee07" ]; + }; + + cyberchef = { + A = [ publicIpv4 ]; + AAAA = [ "2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee03" ]; + }; + }; +} diff --git a/nixos/modules/dns/zones/kun.is.nix b/nixos/modules/dns/zones/kun.is.nix new file mode 100644 index 0000000..d734902 --- /dev/null +++ b/nixos/modules/dns/zones/kun.is.nix @@ -0,0 +1,28 @@ +{ publicIpv4, dns }: +with dns.lib.combinators; + +{ + CAA = letsEncrypt "caa@kun.is"; + + SOA = { + nameServer = "ns1"; + adminEmail = "webmaster@kun.is"; + serial = 1704580936; + }; + + NS = [ + "ns1.kun.is." + "ns2.kun.is." + ]; + + MX = [ + (mx.mx 10 "mail.kun.is.") + ]; + + subdomains = { + ns.A = [ publicIpv4 ]; + ns1.A = [ publicIpv4 ]; + ns2.A = [ publicIpv4 ]; + "*".A = [ publicIpv4 ]; + }; +}