summary refs log tree commit diff
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-11-13 03:53:10 +0100
committerMel <einebeere@gmail.com>2024-11-13 03:53:10 +0100
commit7dc9db6cbb45ed444f83c108106e7f0f09490903 (patch)
tree728acf7d7ae119328cda2009951d5bfefd472cbd
parent55b29c4d414e53ecadbb76d956d2d97ecbfd621d (diff)
downloadnetwork-7dc9db6cbb45ed444f83c108106e7f0f09490903.tar.zst
network-7dc9db6cbb45ed444f83c108106e7f0f09490903.zip
Automatic Tailscale certificate renewal through ACME
Signed-off-by: Mel <einebeere@gmail.com>
-rw-r--r--machines/renard/default.nix78
1 files changed, 77 insertions, 1 deletions
diff --git a/machines/renard/default.nix b/machines/renard/default.nix
index c882d15..8672da4 100644
--- a/machines/renard/default.nix
+++ b/machines/renard/default.nix
@@ -1,4 +1,4 @@
-{ ... }:
+{ pkgs, lib, ... }:
 
 {
   imports = [
@@ -13,6 +13,72 @@
     ../../services/cgit.nix
   ];
 
+  systemd.services."acme-renard.serval-moth.ts.net" =
+  let
+    oneWeekInSeconds = 7 * 24 * 60 * 60;
+
+    tailscaleRenewScript = pkgs.writeShellScript "tailscale-cert-renew" ''
+      set -euxo pipefail
+
+      check_validity() {
+        pem=$1
+        ${pkgs.openssl}/bin/openssl x509 \
+          -checkend ${toString oneWeekInSeconds} \
+          -noout <$pem
+      }
+
+      try_renew() {
+        ${pkgs.tailscale}/bin/tailscale cert \
+          --cert-file certificates/fullchain.pem \
+          --key-file certificates/key.pem \
+          renard.serval-moth.ts.net
+      }
+
+      cut_out_certificate_authority() {
+        fullchain=$1
+        buf=""
+        while read LINE; do
+          if [[ $LINE == *"BEGIN CERTIFICATE"* ]]; then
+            buf=""
+          fi
+          buf="$buf$LINE"$'\n'
+        done < $fullchain
+        echo "$buf"
+      }
+
+      install_certificates() {
+        touch out/renewed
+        cp -vp 'certificates/fullchain.pem' out/fullchain.pem
+        cp -vp 'certificates/key.pem' out/key.pem
+        ln -sf fullchain.pem out/cert.pem
+        cat out/key.pem out/fullchain.pem > out/full.pem
+        cut_out_certificate_authority out/fullchain.pem > out/chain.pem
+        chown 'acme:nginx' out/*
+        chmod 640 out/*
+      }
+
+      if [[ ! -e 'out/fullchain.pem' ]] || ! check_validity out/fullchain.pem; then
+        echo 1>&2 "attempting tailscale certificate renewal..."
+        if ! try_renew; then
+          echo 1>&2 "renewal failed :("
+          exit 1
+        fi
+        install_certificates
+        echo 1>&2 "successfully renewed certificate :)"
+      else
+        echo 1>&2 "renewal not yet necessary."
+      fi
+    '';
+  in {
+    after = [ "tailscaled.service" ];
+    requires = [ "tailscaled.service" ];
+    serviceConfig = {
+      ExecStart = lib.mkForce "+${tailscaleRenewScript}";
+    };
+  };
+
+  security.acme.preliminarySelfsigned = false;
+
   services.nginx.virtualHosts = {
     "rnrd.eu".locations = {
       # redirect to akkoma on lapin
@@ -36,6 +102,16 @@
       };
     };
 
+    # tailnet internal vhost
+    "renard" = {
+      forceSSL = true;
+      enableACME = true;
+      serverName = "renard.serval-moth.ts.net";
+      listenAddresses = [ "100.75.17.75" ];
+      # point to the default page, for now!
+      locations."/" = { alias = "/var/www/html/"; };
+    };
+
     "sho.rest" = {
       enableACME = true;
       forceSSL = true;