nixos

NixOS server files. Mirror from https://git.nordgedanken.dev/kubernetes/nixos
git clone git://archive.git.mtrnord.blog/MTRNord/nixos.git
Log | Files | Refs | README

commit abfd56b4d44a0dab510efdfb3adb2dd28fcfa39c
parent c559e252dccfc171d0badef7700c4d62746f9485
Author: MTRNord <mtrnord1@gmail.com>
Date:   Mon,  4 Sep 2023 19:50:23 +0200

Reorganize

Diffstat:
Dnixos/common.nix | 1-
Anixos/common/common.nix | 35+++++++++++++++++++++++++++++++++++
Anixos/common/lib/asterisk.nix | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anixos/common/lib/fail2ban.nix | 25+++++++++++++++++++++++++
Anixos/common/lib/podman.nix | 9+++++++++
Anixos/common/lib/shell.nix | 10++++++++++
Anixos/common/server.nix | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anixos/common/sops.nix | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anixos/worker-1/boot.nix | 34++++++++++++++++++++++++++++++++++
Mnixos/worker-1/configuration.nix | 599++++++++++++-------------------------------------------------------------------
Anixos/worker-1/darlings.nix | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 571 insertions(+), 515 deletions(-)

diff --git a/nixos/common.nix b/nixos/common.nix @@ -1 +0,0 @@ - diff --git a/nixos/common/common.nix b/nixos/common/common.nix @@ -0,0 +1,35 @@ +{ lib, pkgs, config, ... }: +{ + + # General stuff + time.timeZone = "Europe/Berlin"; + + fonts.fontconfig.enable = lib.mkDefault false; + environment.variables.BROWSER = "echo"; + sound.enable = false; + powerManagement.cpuFreqGovernor = "performance"; + + + environment.systemPackages = with pkgs; [ + wget + curl + htop + lsof + git + cargo + clippy + rustc + rustfmt + home-manager + restic + thefuck + dnsutils + jq + compsize + ]; + + # Write known-hosts + programs.ssh.knownHosts = { + "u362507.your-storagebox.de".publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw=="; + }; +} diff --git a/nixos/common/lib/asterisk.nix b/nixos/common/lib/asterisk.nix @@ -0,0 +1,129 @@ +{ lib, pkgs, config, ... }: +{ + nixpkgs = { + # Configure your nixpkgs instance + config = { + asterisk = { + withOpus = true; + }; + }; + }; + services.asterisk = { + enable = true; + confFiles = { + "cel.conf" = '' + [general] + enable = yes + apps=dial,park + events=ALL + ''; + "cdr.conf" = '' + [general] + enable = yes + ''; + "extensions.conf" = '' + [tests] + exten => 100,1,Answer() + same => n,Verbose(0, 1s) + same => n,Wait(1) + same => n,Verbose(0, Playing jazz) + same => n,Playback(/var/lib/asterisk/sounds/music/waiting) + same => n,Hangup() + + [epvpn] + exten => _00XXXX!,1,Set(CALLERID(num)=2903) + same => n,Verbose(0, Going to play hello) + same => n,BackGround(/var/lib/asterisk/sounds/en/calling) + same => n,Verbose(0, Going to dial ''${EXTEN:2}@eventphone) + same => n,Dial(PJSIP/''${EXTEN:2}@eventphone,30,r) + + [internals] + include => epvpn + include => tests + exten => 200,1,Answer() + same => n,Verbose(0, Going to play hello) + same => n,BackGround(/var/lib/asterisk/sounds/en/calling) + same => n,Verbose(0, Going to dial ''${PJSIP_DIAL_CONTACTS(webrtc_client)}) + same => n,Dial(''${PJSIP_DIAL_CONTACTS(webrtc_client)},30,rm) + + exten => 6001,hint,PJSIP/6001 + + exten => i,1,Answer() + same => n,Playback(/var/lib/asterisk/sounds/en/check-number-dial-again) + same => n,Hangup() + + [externals] + exten => 2903,1,Answer() + same => n,BackGround(/var/lib/asterisk/sounds/en/agent-newlocation) + same => n,Verbose(0, Going to wait for exten) + same => n,WaitExten(30) + same => n,Verbose(0, After wait for exten. Hanging up) + same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) + same => n,Hangup() + + ; exten => 7903,1,Answer() + ; same => n,BackGround(/var/lib/asterisk/sounds/en/agent-newlocation) + ; same => n,Verbose(0, Going to wait for exten) + ; same => n,WaitExten(30) + ; same => n,Verbose(0, After wait for exten. Hanging up) + ; same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) + ; same => n,Hangup() + + exten => 1,1,Answer() + same => n,Verbose(0, Routing to 6001) + ;same => n,BackGround(/var/lib/asterisk/sounds/music/waiting) + same => n,Dial(''${PJSIP_DIAL_CONTACTS(6001)},30,rm) + same => n,Verbose(0, Failed to call 6001. Hanging up) + same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) + same => n,Hangup() + + exten => 1-NOANSWER,1,Playback(/var/lib/asterisk/sounds/en/all-circuits-busy-now) + same => n,Hangup() + + exten => i,1,Answer() + same => n,Playback(/var/lib/asterisk/sounds/en/check-number-dial-again) + same => n,Hangup() + + [webrtc] + include => tests + + exten => 6001,1,Answer() + same => n,Verbose(0, Routing to 6001) + same => n,Dial(''${PJSIP_DIAL_CONTACTS(6001)},30,rm) + same => n,Verbose(0, Failed to call 6001. Hanging up) + same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) + same => n,Hangup() + + [unauthorized] + ''; + + "logger.conf" = '' + [general] + + [logfiles] + ; Add debug output to log + syslog.local0 => notice,warning,error,dtmf,debug,verbose + ''; + + "musiconhold.conf" = '' + [general] + [default] + mode=files + directory=/var/lib/asterisk/sounds/music/ + ''; + + "http.conf" = '' + [general] + enabled = yes + bindaddr = 127.0.0.1 + bindport=8088 + + enablestatic=yes + prefix= + sessionlimit=100 + session_inactivity=30000 + session_keep_alive=15000 + ''; + }; + }; +} diff --git a/nixos/common/lib/fail2ban.nix b/nixos/common/lib/fail2ban.nix @@ -0,0 +1,25 @@ +{ lib, pkgs, config, ... }: +{ + services = { + fail2ban = { + enable = true; + + extraPackages = [ pkgs.ipset ]; + banaction = "iptables-ipset-proto6-allports"; + ignoreIP = [ + "148.251.63.154" + "31.17.93.207" + ]; + jails = { + asterisk = '' + enabled = true + filter = asterisk + action = iptables-allports[name=ASTERISK, protocol=all] + maxretry = 2 + findtime = 21600 + bantime = 86400 + ''; + }; + }; + }; +} diff --git a/nixos/common/lib/podman.nix b/nixos/common/lib/podman.nix @@ -0,0 +1,9 @@ +{ lib, pkgs, config, ... }: +{ + virtualisation.podman = { + enable = true; + defaultNetwork.settings = { + dns_enabled = true; + }; + }; +} diff --git a/nixos/common/lib/shell.nix b/nixos/common/lib/shell.nix @@ -0,0 +1,10 @@ +{ lib, pkgs, config, ... }: +{ + environment.systemPackages = with pkgs; [ + zsh + ]; + + # Ensure /etc/shells is setup for zsh + programs.zsh.enable = true; + environment.shells = with pkgs; [ zsh ]; +} diff --git a/nixos/common/server.nix b/nixos/common/server.nix @@ -0,0 +1,61 @@ +{ lib, pkgs, config, ... }: +{ + systemd = { + network.enable = true; + # Given that our systems are headless, emergency mode is useless. + # We prefer the system to attempt to continue booting so + # that we can hopefully still access it remotely. + enableEmergencyMode = false; + # For more detail, see: + # https://0pointer.de/blog/projects/watchdog.html + watchdog = { + # systemd will send a signal to the hardware watchdog at half + # the interval defined here, so every 10s. + # If the hardware watchdog does not get a signal for 20s, + # it will forcefully reboot the system. + runtimeTime = "20s"; + # Forcefully reboot if the final stage of the reboot + # hangs without progress for more than 30s. + # For more info, see: + # https://utcc.utoronto.ca/~cks/space/blog/linux/SystemdShutdownWatchdog + rebootTime = "30s"; + }; + + sleep.extraConfig = '' + AllowSuspend=no + AllowHibernation=no + ''; + }; + + # use TCP BBR has significantly increased throughput and reduced latency for connections + boot = { + kernel.sysctl = { + "net.core.default_qdisc" = "fq"; + "net.ipv4.tcp_congestion_control" = "bbr"; + "net.ipv4.conf.all.forwarding" = true; + "net.ipv6.conf.all.forwarding" = true; + }; + # Ensure a clean & sparkling /tmp on fresh boots. + tmp.cleanOnBoot = true; + # btrfs boot + kernelPackages = pkgs.linuxPackages_latest; + supportedFilesystems = [ "btrfs" ]; + }; + + hardware.enableAllFirmware = true; + + # This setups a SSH server. Very important if you're setting up a headless system. + # Feel free to remove if you don't need it. + services.openssh = { + enable = true; + settings = { + # Forbid root login through SSH. + PermitRootLogin = "no"; + # Use keys only. Remove if you want to SSH using password (not recommended) + PasswordAuthentication = false; + X11Forwarding = false; + KbdInteractiveAuthentication = false; + UseDns = false; + }; + }; +} diff --git a/nixos/common/sops.nix b/nixos/common/sops.nix @@ -0,0 +1,117 @@ +{ lib, pkgs, config, ... }: +{ + # SOPS + sops = { + age = { + sshKeyPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ]; + # This is using an age key that is expected to already be in the filesystem + keyFile = "/persist/var/lib/sops-nix/key.txt"; + # This will generate a new key if the key specified above does not exist + generateKey = true; + }; + gnupg.sshKeyPaths = [ "/persist/etc/ssh/ssh_host_rsa_key" ]; + + + + defaultSopsFile = ./secrets/secrets.yaml; + + # keys + secrets = { + marcel_initial_password.neededForUsers = true; + root_initial_password.neededForUsers = true; + "wireguard/private_key" = { }; + }; + ssh_host_ed25519_key = { + mode = "0600"; + path = "/etc/ssh/ssh_host_ed25519_key"; + }; + ssh_host_ed25519_key_pub = { + mode = "0644"; + path = "/etc/ssh/ssh_host_ed25519_key.pub"; + }; + ssh_host_rsa_key = { + mode = "0600"; + path = "/etc/ssh/ssh_host_rsa_key"; + }; + ssh_host_rsa_key_pub = { + mode = "0644"; + path = "/etc/ssh/ssh_host_rsa_key.pub"; + }; + "ssh/marcel/id_ed25519" = { + mode = "0600"; + owner = config.users.users.marcel.name; + path = "/home/marcel/.ssh/id_ed25519"; + }; + "ssh/marcel/id_ed25519_pub" = { + mode = "0644"; + owner = config.users.users.marcel.name; + path = "/home/marcel/.ssh/id_ed25519.pub"; + }; + "ssh/root/id_ed25519" = { + mode = "0600"; + owner = config.users.users.marcel.name; + path = "/root/.ssh/id_ed25519"; + }; + "ssh/root/id_ed25519_pub" = { + mode = "0644"; + owner = config.users.users.marcel.name; + path = "/root/.ssh/id_ed25519.pub"; + }; + backup_password = { }; + forgejo_runner_token = { }; + # sops.secrets.forgejo_runner_token.owner = config.users."gitea-runner".name; + "asterisk/pjsip_conf" = { + mode = "0777"; + path = "/etc/asterisk/pjsip.conf"; + }; + "asterisk/prometheus_conf" = { + mode = "0777"; + path = "/etc/asterisk/prometheus.conf"; + }; + "asterisk/cel_pgsql_conf" = { + mode = "0777"; + path = "/etc/asterisk/cel_pgsql.conf"; + }; + "asterisk/cdr_pgsql_conf" = { + mode = "0777"; + path = "/etc/asterisk/cdr_pgsql.conf"; + }; + "patroni/replication_username" = { + owner = "patroni"; + group = "patroni"; + }; + "patroni/replication_password" = { + owner = "patroni"; + group = "patroni"; + }; + "patroni/replication_superuser_username" = { + owner = "patroni"; + group = "patroni"; + }; + "patroni/replication_superuser_password" = { + owner = "patroni"; + group = "patroni"; + }; + "discourse/db_password" = { + owner = "discourse"; + group = "discourse"; + }; + "discourse/secret_key_base" = { + owner = "discourse"; + group = "discourse"; + }; + "discourse/admin_password" = { + owner = "discourse"; + group = "discourse"; + }; + "discourse/mail_password" = { + owner = "discourse"; + group = "discourse"; + }; + "discourse/redis_password" = { + owner = "discourse"; + group = "discourse"; + }; + }; + +} diff --git a/nixos/worker-1/boot.nix b/nixos/worker-1/boot.nix @@ -0,0 +1,34 @@ +{ lib, pkgs, config, ... }: +{ + boot = { + loader = { + systemd-boot = { + enable = true; + configurationLimit = 10; + editor = false; + }; + efi.canTouchEfiVariables = true; + }; + kernelParams = [ "ip=dhcp" ]; + initrd = { + network.enable = true; + luks.forceLuksSupportInInitrd = true; + network.ssh = { + enable = true; + # Defaults to 22. + port = 2222; + shell = "/bin/cryptsetup-askpass"; + # The key is generated using `ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key` + # + # Stored in plain text on boot partition, so don't reuse your host + # keys. Also, make sure to use a boot loader with support for initrd + # secrets (e.g. systemd-boot), or this will be exposed in the nix store + # to unprivileged users. + hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ]; + # I'll just authorize all keys authorized post-boot. + authorizedKeys = config.users.users.marcel.openssh.authorizedKeys.keys; + }; + }; + }; + +} diff --git a/nixos/worker-1/configuration.nix b/nixos/worker-1/configuration.nix @@ -18,6 +18,17 @@ # Import your generated (nixos-generate-config) hardware configuration ./hardware-configuration.nix + + ../common/sops.nix + ../common/common.nix + ../common/server.nix + ./darlings.nix + + ../common/lib/boot.nix + ../common/lib/shell.nix + ../common/lib/fail2ban.nix + ../common/lib/podman.nix + ../common/lib/asterisk.nix ]; nixpkgs = { @@ -82,57 +93,6 @@ }; - # General stuff - time.timeZone = "Europe/Berlin"; - - fonts.fontconfig.enable = lib.mkDefault false; - environment.variables.BROWSER = "echo"; - sound.enable = false; - powerManagement.cpuFreqGovernor = "performance"; - - systemd = { - # Given that our systems are headless, emergency mode is useless. - # We prefer the system to attempt to continue booting so - # that we can hopefully still access it remotely. - enableEmergencyMode = false; - # For more detail, see: - # https://0pointer.de/blog/projects/watchdog.html - watchdog = { - # systemd will send a signal to the hardware watchdog at half - # the interval defined here, so every 10s. - # If the hardware watchdog does not get a signal for 20s, - # it will forcefully reboot the system. - runtimeTime = "20s"; - # Forcefully reboot if the final stage of the reboot - # hangs without progress for more than 30s. - # For more info, see: - # https://utcc.utoronto.ca/~cks/space/blog/linux/SystemdShutdownWatchdog - rebootTime = "30s"; - }; - - sleep.extraConfig = '' - AllowSuspend=no - AllowHibernation=no - ''; - }; - - # use TCP BBR has significantly increased throughput and reduced latency for connections - boot.kernel.sysctl = { - "net.core.default_qdisc" = "fq"; - "net.ipv4.tcp_congestion_control" = "bbr"; - "net.ipv4.conf.all.forwarding" = true; - "net.ipv6.conf.all.forwarding" = true; - }; - - # Ensure a clean & sparkling /tmp on fresh boots. - boot.tmp.cleanOnBoot = true; - - # btrfs boot - boot.kernelPackages = pkgs.linuxPackages_latest; - boot.supportedFilesystems = [ "btrfs" ]; - hardware.enableAllFirmware = true; - - systemd.network.enable = true; # Broken systemd.network.wait-online.enable = false; systemd.network = { @@ -157,20 +117,6 @@ }; }; - - - # SOPS - sops.age.sshKeyPaths = [ "/persist/etc/ssh/ssh_host_ed25519_key" ]; - sops.gnupg.sshKeyPaths = [ "/persist/etc/ssh/ssh_host_rsa_key" ]; - # This is using an age key that is expected to already be in the filesystem - sops.age.keyFile = "/persist/var/lib/sops-nix/key.txt"; - # This will generate a new key if the key specified above does not exist - sops.age.generateKey = true; - sops.defaultSopsFile = ./secrets/secrets.yaml; - sops.secrets.marcel_initial_password.neededForUsers = true; - sops.secrets.root_initial_password.neededForUsers = true; - - sops.secrets."wireguard/private_key" = { }; networking = { hostName = "worker-1"; enableIPv6 = true; @@ -288,148 +234,15 @@ + builtins.concatStringsSep "\n" (builtins.map (ip: "ip6tables -D INPUT -s ${ip} -j DROP") blockedV6); }; }; - services.fail2ban.enable = true; - # needed to ban on IPv4 and IPv6 for all ports - services.fail2ban = { - extraPackages = [ pkgs.ipset ]; - banaction = "iptables-ipset-proto6-allports"; - ignoreIP = [ - "148.251.63.154" - "31.17.93.207" - ]; - jails = { - asterisk = '' - enabled = true - filter = asterisk - action = iptables-allports[name=ASTERISK, protocol=all] - maxretry = 2 - findtime = 21600 - bantime = 86400 - ''; - }; - }; # packages that are not flakes environment.systemPackages = with pkgs; [ - wget - curl - htop - lsof - git - cargo - clippy - rustc - rustfmt - home-manager - zsh - restic - thefuck - dnsutils - jq unstable.forgejo-actions-runner - compsize config.services.headscale.package patroni etcd_3_4 ]; - # Ensure /etc/shells is setup for zsh - programs.zsh.enable = true; - environment.shells = with pkgs; [ zsh ]; - - boot.loader = { - systemd-boot = { - enable = true; - configurationLimit = 10; - editor = false; - }; - efi.canTouchEfiVariables = true; - }; - boot.kernelParams = [ "ip=dhcp" ]; - - boot.initrd = { - network.enable = true; - luks.forceLuksSupportInInitrd = true; - network.ssh = { - enable = true; - # Defaults to 22. - port = 2222; - shell = "/bin/cryptsetup-askpass"; - # The key is generated using `ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key` - # - # Stored in plain text on boot partition, so don't reuse your host - # keys. Also, make sure to use a boot loader with support for initrd - # secrets (e.g. systemd-boot), or this will be exposed in the nix store - # to unprivileged users. - hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ]; - # I'll just authorize all keys authorized post-boot. - authorizedKeys = config.users.users.marcel.openssh.authorizedKeys.keys; - }; - }; - - # Write known-hosts - programs.ssh.knownHosts = { - "u362507.your-storagebox.de".publicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw=="; - }; - - # This setups a SSH server. Very important if you're setting up a headless system. - # Feel free to remove if you don't need it. - services.openssh = { - enable = true; - settings = { - # Forbid root login through SSH. - PermitRootLogin = "no"; - # Use keys only. Remove if you want to SSH using password (not recommended) - PasswordAuthentication = false; - X11Forwarding = false; - KbdInteractiveAuthentication = false; - UseDns = false; - }; - }; - sops.secrets.ssh_host_ed25519_key = { - mode = "0600"; - path = "/etc/ssh/ssh_host_ed25519_key"; - }; - sops.secrets.ssh_host_ed25519_key_pub = { - mode = "0644"; - path = "/etc/ssh/ssh_host_ed25519_key.pub"; - }; - sops.secrets.ssh_host_rsa_key = { - mode = "0600"; - path = "/etc/ssh/ssh_host_rsa_key"; - }; - sops.secrets.ssh_host_rsa_key_pub = { - mode = "0644"; - path = "/etc/ssh/ssh_host_rsa_key.pub"; - }; - - sops.secrets."ssh/marcel/id_ed25519" = { - mode = "0600"; - owner = config.users.users.marcel.name; - path = "/home/marcel/.ssh/id_ed25519"; - }; - - sops.secrets."ssh/marcel/id_ed25519_pub" = { - mode = "0644"; - owner = config.users.users.marcel.name; - path = "/home/marcel/.ssh/id_ed25519.pub"; - }; - - sops.secrets."ssh/root/id_ed25519" = { - mode = "0600"; - owner = config.users.users.marcel.name; - path = "/root/.ssh/id_ed25519"; - }; - - sops.secrets."ssh/root/id_ed25519_pub" = { - mode = "0644"; - owner = config.users.users.marcel.name; - path = "/root/.ssh/id_ed25519.pub"; - }; - - sops.secrets.backup_password = { }; - - # Configure your system-wide user settings (groups, etc), add more users as needed. users = { #mutableUsers = false; @@ -443,12 +256,11 @@ extraGroups = [ "wheel" ]; shell = pkgs.zsh; }; + + "root".passwordFile = config.sops.secrets.root_initial_password.path; }; }; - # forgejo - virtualisation.podman.enable = true; - services.gitea-actions-runner = { instances = { nordgedanken = { @@ -464,10 +276,7 @@ systemd.services.gitea-runner-nordgedanken = { serviceConfig.SupplementaryGroups = [ config.users.groups.keys.name ]; }; - sops.secrets.forgejo_runner_token = { }; - # sops.secrets.forgejo_runner_token.owner = config.users."gitea-runner".name; - users.users."root".passwordFile = config.sops.secrets.root_initial_password.path; # Restic Backup services.restic.backups = { @@ -490,44 +299,80 @@ }; }; + security.acme.acceptTerms = true; + security.acme.defaults.email = "support@nordgedanken.dev"; - sops.secrets."patroni/replication_username" = { - owner = "patroni"; - group = "patroni"; - }; - sops.secrets."patroni/replication_password" = { - owner = "patroni"; - group = "patroni"; - }; - sops.secrets."patroni/replication_superuser_username" = { - owner = "patroni"; - group = "patroni"; - }; - sops.secrets."patroni/replication_superuser_password" = { - owner = "patroni"; - group = "patroni"; - }; - sops.secrets."discourse/db_password" = { - owner = "discourse"; - group = "discourse"; - }; - sops.secrets."discourse/secret_key_base" = { - owner = "discourse"; - group = "discourse"; - }; - sops.secrets."discourse/admin_password" = { - owner = "discourse"; - group = "discourse"; - }; - sops.secrets."discourse/mail_password" = { - owner = "discourse"; - group = "discourse"; - }; - sops.secrets."discourse/redis_password" = { - owner = "discourse"; - group = "discourse"; - }; services = { + nginx = { + enable = true; + upstreams = { + "asterisk_webrtc_ws" = { + servers = { + "127.0.0.1:8088" = { }; + }; + }; + }; + virtualHosts = { + "pbx.midnightthoughts.space" = { + forceSSL = true; + enableACME = true; + + locations."/ws" = { + proxyPass = "http://asterisk_webrtc_ws/ws"; + proxyWebsockets = true; + }; + locations."/metrics" = { + proxyPass = "http://asterisk_webrtc_ws/metrics"; + }; + }; + "headscale.midnightthoughts.space" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = + "http://localhost:${toString config.services.headscale.port}"; + proxyWebsockets = true; + }; + }; + "lg.midnightthoughts.space" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = + "http://localhost:5001"; + }; + }; + }; + }; + + haproxy = { + enable = true; + config = '' + global + maxconn 100 + + defaults + log global + mode tcp + retries 2 + timeout client 30m + timeout connect 4s + timeout server 30m + timeout check 5s + + listen postgres + bind 100.64.0.1:5000 + bind 127.0.0.1:5000 + bind 10.100.12.1:5000 + mode tcp + option httpchk + http-check expect status 200 + default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions + server pgsql1 100.64.0.3:5432 maxconn 100 check port 8008 + server pgsql2 100.64.0.1:5432 maxconn 100 check port 8008 + ''; + }; + discourse = { enable = true; database = { @@ -829,280 +674,6 @@ systemd.services.etcd.serviceConfig.ExecStart = lib.mkForce "${pkgs.etcd_3_4}/bin/etcd"; - # Darling Erasure - environment.persistence."/persist" = { - directories = [ - "/var/lib/tailscale" - "/var/lib/asterisk" - "/var/lib/headscale" - "/etc/nixos" - "/var/lib/postgresql/${config.services.patroni.postgresqlPackage.psqlSchema}" - "/var/lib/patroni" - "/var/lib/etcd" - "/var/lib/discourse" - ]; - files = [ - "/etc/machine-id" - #"/etc/NIXOS" - "/etc/secrets/initrd/ssh_host_ed25519_key" - "/etc/secrets/initrd/ssh_host_ed25519_key.pub" - "/var/lib/sops-nix/key.txt" - ]; - }; - security.sudo.extraConfig = '' - # rollback results in sudo lectures after each reboot - Defaults lecture = never - ''; - # Note `lib.mkBefore` is used instead of `lib.mkAfter` here. - boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' - mkdir -p /mnt - - # We first mount the btrfs root to /mnt - # so we can manipulate btrfs subvolumes. - mount -o subvol=/ /dev/mapper/enc /mnt - - # While we're tempted to just delete /root and create - # a new snapshot from /root-blank, /root is already - # populated at this point with a number of subvolumes, - # which makes `btrfs subvolume delete` fail. - # So, we remove them first. - # - # /root contains subvolumes: - # - /root/var/lib/portables - # - /root/var/lib/machines - # - # I suspect these are related to systemd-nspawn, but - # since I don't use it I'm not 100% sure. - # Anyhow, deleting these subvolumes hasn't resulted - # in any issues so far, except for fairly - # benign-looking errors from systemd-tmpfiles. - btrfs subvolume list -o /mnt/root | - cut -f9 -d' ' | - while read subvolume; do - echo "deleting /$subvolume subvolume..." - btrfs subvolume delete "/mnt/$subvolume" - done && - echo "deleting /root subvolume..." && - btrfs subvolume delete /mnt/root - - echo "restoring blank /root subvolume..." - btrfs subvolume snapshot /mnt/root-blank /mnt/root - - # Once we're done rolling back to a blank snapshot, - # we can unmount /mnt and continue on the boot process. - umount /mnt - ''; - - # FIXME: Remove at some point. This is a test tbh - sops.secrets."asterisk/pjsip_conf" = { - mode = "0777"; - path = "/etc/asterisk/pjsip.conf"; - }; - sops.secrets."asterisk/prometheus_conf" = { - mode = "0777"; - path = "/etc/asterisk/prometheus.conf"; - }; - sops.secrets."asterisk/cel_pgsql_conf" = { - mode = "0777"; - path = "/etc/asterisk/cel_pgsql.conf"; - }; - sops.secrets."asterisk/cdr_pgsql_conf" = { - mode = "0777"; - path = "/etc/asterisk/cdr_pgsql.conf"; - }; - services.asterisk = { - enable = true; - confFiles = { - "cel.conf" = '' - [general] - enable = yes - apps=dial,park - events=ALL - ''; - "cdr.conf" = '' - [general] - enable = yes - ''; - "extensions.conf" = '' - [tests] - exten => 100,1,Answer() - same => n,Verbose(0, 1s) - same => n,Wait(1) - same => n,Verbose(0, Playing jazz) - same => n,Playback(/var/lib/asterisk/sounds/music/waiting) - same => n,Hangup() - - [epvpn] - exten => _00XXXX!,1,Set(CALLERID(num)=2903) - same => n,Verbose(0, Going to play hello) - same => n,BackGround(/var/lib/asterisk/sounds/en/calling) - same => n,Verbose(0, Going to dial ''${EXTEN:2}@eventphone) - same => n,Dial(PJSIP/''${EXTEN:2}@eventphone,30,r) - - [internals] - include => epvpn - include => tests - exten => 200,1,Answer() - same => n,Verbose(0, Going to play hello) - same => n,BackGround(/var/lib/asterisk/sounds/en/calling) - same => n,Verbose(0, Going to dial ''${PJSIP_DIAL_CONTACTS(webrtc_client)}) - same => n,Dial(''${PJSIP_DIAL_CONTACTS(webrtc_client)},30,rm) - - exten => 6001,hint,PJSIP/6001 - - exten => i,1,Answer() - same => n,Playback(/var/lib/asterisk/sounds/en/check-number-dial-again) - same => n,Hangup() - - [externals] - exten => 2903,1,Answer() - same => n,BackGround(/var/lib/asterisk/sounds/en/agent-newlocation) - same => n,Verbose(0, Going to wait for exten) - same => n,WaitExten(30) - same => n,Verbose(0, After wait for exten. Hanging up) - same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) - same => n,Hangup() - - ; exten => 7903,1,Answer() - ; same => n,BackGround(/var/lib/asterisk/sounds/en/agent-newlocation) - ; same => n,Verbose(0, Going to wait for exten) - ; same => n,WaitExten(30) - ; same => n,Verbose(0, After wait for exten. Hanging up) - ; same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) - ; same => n,Hangup() - - exten => 1,1,Answer() - same => n,Verbose(0, Routing to 6001) - ;same => n,BackGround(/var/lib/asterisk/sounds/music/waiting) - same => n,Dial(''${PJSIP_DIAL_CONTACTS(6001)},30,rm) - same => n,Verbose(0, Failed to call 6001. Hanging up) - same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) - same => n,Hangup() - - exten => 1-NOANSWER,1,Playback(/var/lib/asterisk/sounds/en/all-circuits-busy-now) - same => n,Hangup() - - exten => i,1,Answer() - same => n,Playback(/var/lib/asterisk/sounds/en/check-number-dial-again) - same => n,Hangup() - - [webrtc] - include => tests - - exten => 6001,1,Answer() - same => n,Verbose(0, Routing to 6001) - same => n,Dial(''${PJSIP_DIAL_CONTACTS(6001)},30,rm) - same => n,Verbose(0, Failed to call 6001. Hanging up) - same => n,Playback(/var/lib/asterisk/sounds/en/cannot-complete-as-dialed) - same => n,Hangup() - - [unauthorized] - ''; - - "logger.conf" = '' - [general] - - [logfiles] - ; Add debug output to log - syslog.local0 => notice,warning,error,dtmf,debug,verbose - ''; - - "musiconhold.conf" = '' - [general] - [default] - mode=files - directory=/var/lib/asterisk/sounds/music/ - ''; - - "http.conf" = '' - [general] - enabled = yes - bindaddr = 127.0.0.1 - bindport=8088 - - enablestatic=yes - prefix= - sessionlimit=100 - session_inactivity=30000 - session_keep_alive=15000 - ''; - }; - }; - - # NGINX - security.acme.acceptTerms = true; - security.acme.defaults.email = "support@nordgedanken.dev"; - services.nginx = { - enable = true; - upstreams = { - "asterisk_webrtc_ws" = { - servers = { - "127.0.0.1:8088" = { }; - }; - }; - }; - virtualHosts = { - "pbx.midnightthoughts.space" = { - forceSSL = true; - enableACME = true; - - locations."/ws" = { - proxyPass = "http://asterisk_webrtc_ws/ws"; - proxyWebsockets = true; - }; - locations."/metrics" = { - proxyPass = "http://asterisk_webrtc_ws/metrics"; - }; - }; - "headscale.midnightthoughts.space" = { - forceSSL = true; - enableACME = true; - locations."/" = { - proxyPass = - "http://localhost:${toString config.services.headscale.port}"; - proxyWebsockets = true; - }; - }; - "lg.midnightthoughts.space" = { - forceSSL = true; - enableACME = true; - locations."/" = { - proxyPass = - "http://localhost:5001"; - }; - }; - }; - }; - - # HAProxy for Postgres - services.haproxy = { - enable = true; - config = '' - global - maxconn 100 - - defaults - log global - mode tcp - retries 2 - timeout client 30m - timeout connect 4s - timeout server 30m - timeout check 5s - - listen postgres - bind 100.64.0.1:5000 - bind 127.0.0.1:5000 - bind 10.100.12.1:5000 - mode tcp - option httpchk - http-check expect status 200 - default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions - server pgsql1 100.64.0.3:5432 maxconn 100 check port 8008 - server pgsql2 100.64.0.1:5432 maxconn 100 check port 8008 - ''; - }; - # https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion system.stateVersion = "23.05"; } diff --git a/nixos/worker-1/darlings.nix b/nixos/worker-1/darlings.nix @@ -0,0 +1,66 @@ +{ lib, pkgs, config, ... }: +{ + # Darling Erasure + environment.persistence."/persist" = { + directories = [ + "/var/lib/tailscale" + "/var/lib/asterisk" + "/var/lib/headscale" + "/etc/nixos" + "/var/lib/postgresql/${config.services.patroni.postgresqlPackage.psqlSchema}" + "/var/lib/patroni" + "/var/lib/etcd" + "/var/lib/discourse" + ]; + files = [ + "/etc/machine-id" + #"/etc/NIXOS" + "/etc/secrets/initrd/ssh_host_ed25519_key" + "/etc/secrets/initrd/ssh_host_ed25519_key.pub" + "/var/lib/sops-nix/key.txt" + ]; + }; + security.sudo.extraConfig = '' + # rollback results in sudo lectures after each reboot + Defaults lecture = never + ''; + # Note `lib.mkBefore` is used instead of `lib.mkAfter` here. + boot.initrd.postDeviceCommands = pkgs.lib.mkBefore '' + mkdir -p /mnt + + # We first mount the btrfs root to /mnt + # so we can manipulate btrfs subvolumes. + mount -o subvol=/ /dev/mapper/enc /mnt + + # While we're tempted to just delete /root and create + # a new snapshot from /root-blank, /root is already + # populated at this point with a number of subvolumes, + # which makes `btrfs subvolume delete` fail. + # So, we remove them first. + # + # /root contains subvolumes: + # - /root/var/lib/portables + # - /root/var/lib/machines + # + # I suspect these are related to systemd-nspawn, but + # since I don't use it I'm not 100% sure. + # Anyhow, deleting these subvolumes hasn't resulted + # in any issues so far, except for fairly + # benign-looking errors from systemd-tmpfiles. + btrfs subvolume list -o /mnt/root | + cut -f9 -d' ' | + while read subvolume; do + echo "deleting /$subvolume subvolume..." + btrfs subvolume delete "/mnt/$subvolume" + done && + echo "deleting /root subvolume..." && + btrfs subvolume delete /mnt/root + + echo "restoring blank /root subvolume..." + btrfs subvolume snapshot /mnt/root-blank /mnt/root + + # Once we're done rolling back to a blank snapshot, + # we can unmount /mnt and continue on the boot process. + umount /mnt + ''; +}