commit abfd56b4d44a0dab510efdfb3adb2dd28fcfa39c
parent c559e252dccfc171d0badef7700c4d62746f9485
Author: MTRNord <mtrnord1@gmail.com>
Date: Mon, 4 Sep 2023 19:50:23 +0200
Reorganize
Diffstat:
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
+ '';
+}