summary refs log tree commit diff
path: root/modules/www
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-12-26 17:24:04 +0100
committerMel <einebeere@gmail.com>2024-12-26 17:31:29 +0100
commitce64e6e1990b62451acb3822b7ab914e16b122b6 (patch)
tree3793d855dc49b849e82c919a36d4c376bf00f36f /modules/www
parent98cdef36e124b0b5ae90021a92408bb7899660c2 (diff)
downloadnetwork-ce64e6e1990b62451acb3822b7ab914e16b122b6.tar.zst
network-ce64e6e1990b62451acb3822b7ab914e16b122b6.zip
Pull out web configuration from specific machine modules
Signed-off-by: Mel <einebeere@gmail.com>
Diffstat (limited to 'modules/www')
-rw-r--r--modules/www/default.nix57
-rw-r--r--modules/www/tailnet.nix89
2 files changed, 146 insertions, 0 deletions
diff --git a/modules/www/default.nix b/modules/www/default.nix
new file mode 100644
index 0000000..f6bb4e4
--- /dev/null
+++ b/modules/www/default.nix
@@ -0,0 +1,57 @@
+{ me, ... }:
+
+let
+  rnrdUrl = if me.is.renard then "rnrd.eu" else "${me.name}.rnrd.eu";
+in
+{
+  imports = [ ./tailnet.nix ];
+
+  security.acme = {
+    acceptTerms = true;
+    defaults.email = "einebeere@gmail.com";
+  };
+
+  services.nginx = {
+    enable = true;
+    recommendedGzipSettings = true;
+    recommendedOptimisation = true;
+    recommendedProxySettings = true;
+    recommendedTlsSettings = true;
+
+    statusPage = true;
+
+    commonHttpConfig = ''
+      log_format json_combined escape=json '{'
+      	'"time_local":"$time_local",'
+      	'"remote_addr":"$remote_addr",'
+      	'"remote_user":"$remote_user",'
+      	'"request":"$request",'
+      	'"status": "$status",'
+      	'"body_bytes_sent":"$body_bytes_sent",'
+      	'"request_length":"$request_length",'
+      	'"request_time":"$request_time",'
+      	'"http_referrer":"$http_referer",'
+      	'"http_user_agent":"$http_user_agent",'
+      	'"upstream_response_time":"$upstream_response_time",'
+      	'"upstream_addr":"$upstream_addr",'
+      	'"upstream_status":"$upstream_status"'
+      '}';
+      access_log /var/log/nginx/access.log json_combined;
+      error_log /var/log/nginx/error.log warn;
+    '';
+
+    virtualHosts = {
+      default = {
+        default = true;
+      };
+      ${rnrdUrl} = {
+        root = "/var/www/html";
+        forceSSL = true;
+        enableACME = true;
+        extraConfig = ''
+          access_log /var/log/nginx/base.access.log json_combined;
+        '';
+      };
+    };
+  };
+}
diff --git a/modules/www/tailnet.nix b/modules/www/tailnet.nix
new file mode 100644
index 0000000..df70a55
--- /dev/null
+++ b/modules/www/tailnet.nix
@@ -0,0 +1,89 @@
+{
+  me,
+  lib,
+  pkgs,
+  ...
+}:
+
+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 \
+    ${me.tailscale.domain}
+    }
+
+    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
+{
+  # overwrite default acme behaviour with tailscale
+  systemd.services."acme-${me.tailscale.domain}" = {
+    after = [ "tailscaled.service" ];
+    requires = [ "tailscaled.service" ];
+    serviceConfig = {
+      ExecStart = lib.mkForce "+${tailscaleRenewScript}";
+    };
+  };
+
+  # tailnet internal vhost
+  services.nginx.virtualHosts.tailnet = {
+    forceSSL = true;
+    enableACME = true;
+    serverName = me.tailscale.domain;
+    listenAddresses = [ me.tailscale.ip ];
+    # point to the default page, for now!
+    locations."/" = {
+      alias = "/var/www/html/";
+    };
+    extraConfig = ''
+      access_log /var/log/nginx/tailnet.access.log json_combined;
+    '';
+  };
+}