From d0da687495f283c474a3ba56d62f160a71bccfbf Mon Sep 17 00:00:00 2001 From: Brandon Schneider Date: Fri, 29 May 2026 02:07:18 -0500 Subject: [PATCH] fix: force production LE CA in Caddy + racknerd TLS deploy script k3s-edge.nix: - Added 'ca https://acme-v02.api.letsencrypt.org/directory' to porkbun_tls snippet - Forces production LE instead of staging fix-racknerd-tls.sh: - Checks current Porkbun keys (redacted) - Verifies production LE CA is configured - Provides deploy and restart instructions - Documents how to update Porkbun API keys via sops --- .../k3s-flake/fix-racknerd-tls.sh | 47 +++++++++++++++++++ 4-Infrastructure/k3s-flake/k3s-edge.nix | 34 ++++++++++---- 2 files changed, 72 insertions(+), 9 deletions(-) create mode 100755 4-Infrastructure/k3s-flake/fix-racknerd-tls.sh diff --git a/4-Infrastructure/k3s-flake/fix-racknerd-tls.sh b/4-Infrastructure/k3s-flake/fix-racknerd-tls.sh new file mode 100755 index 00000000..c336091d --- /dev/null +++ b/4-Infrastructure/k3s-flake/fix-racknerd-tls.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Fix Caddy TLS on racknerd +# 1. Update Porkbun API keys via sops +# 2. Deploy updated NixOS config with production LE CA +# 3. Restart Caddy +# +# Usage: ./fix-racknerd-tls.sh +# Prerequisites: sops age key configured, SSH access to racknerd + +set -euo pipefail + +RACKNERD_IP="100.80.39.40" +RACKNERD_SSH="root@${RACKNERD_IP}" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +SECRETS_DIR="${SCRIPT_DIR}/secrets" + +echo "=== Step 1: Check current Porkbun keys ===" +echo "Current keys (redacted):" +sops --input-type yaml --output-type yaml -d "${SECRETS_DIR}/porkbun-env.age" 2>/dev/null | sed 's/pk1_[^ ]*/pk1_***/' | sed 's/sk1_[^ ]*/sk1_***/' + +echo "" +echo "=== Step 2: Verify production LE CA is in config ===" +grep -n "acme-v02" "${SCRIPT_DIR}/k3s-edge.nix" && echo "✅ Production LE CA configured" || echo "❌ Production LE CA missing" + +echo "" +echo "=== Step 3: Deploy to racknerd ===" +echo "To deploy the NixOS config with production LE CA:" +echo " ssh ${RACKNERD_SSH} 'cd /etc/nixos && sudo nixos-rebuild switch'" +echo "" +echo "Or if using deploy-rs:" +echo " deploy .#racknerd --hostname ${RACKNERD_IP}" +echo "" +echo "After deploy, restart Caddy:" +echo " ssh ${RACKNERD_SSH} 'sudo systemctl restart caddy'" +echo "" +echo "Verify:" +echo " ssh ${RACKNERD_SSH} 'sudo journalctl -u caddy -n 20'" +echo " curl -vI https://researchstack.info 2>&1 | grep -i issuer" + +echo "" +echo "=== Step 4: If Porkbun keys are invalid ===" +echo "1. Go to https://porkbun.com/account/api" +echo "2. Generate new API key pair" +echo "3. Edit the secret:" +echo " sops ${SECRETS_DIR}/porkbun-env.age" +echo "4. Replace PORKBUN_API_KEY and PORKBUN_SECRET_KEY" +echo "5. Redeploy (Step 3)" diff --git a/4-Infrastructure/k3s-flake/k3s-edge.nix b/4-Infrastructure/k3s-flake/k3s-edge.nix index d1bbb948..4b0d26a7 100644 --- a/4-Infrastructure/k3s-flake/k3s-edge.nix +++ b/4-Infrastructure/k3s-flake/k3s-edge.nix @@ -1,4 +1,4 @@ -{ config, pkgs, lib, hostName, serverAddr, domain ? "researchstack.info", ... }: +{ config, pkgs, lib, hostName, serverAddr, domain ? "researchstack.info", caddyPorkbun ? pkgs.caddy, ... }: let mailDomain = domain; @@ -142,10 +142,11 @@ in services.caddy = { enable = true; - package = pkgs.caddy; + package = caddyPorkbun; extraConfig = '' (porkbun_tls) { tls { + ca https://acme-v02.api.letsencrypt.org/directory dns porkbun { api_key {$PORKBUN_API_KEY} api_secret_key {$PORKBUN_SECRET_KEY} @@ -193,7 +194,7 @@ in # These exist for bookmark/client compat during migration. status.${domain} { import porkbun_tls - redir https://${domain}/server/status/{uri} 301 + redir https://${domain}/server/status{uri} 301 } dash.${domain}, home.${domain} { @@ -203,32 +204,47 @@ in media.${domain} { import porkbun_tls - redir https://${domain}/apps/jellyfin/{uri} 301 + redir https://${domain}/apps/jellyfin{uri} 301 } books.${domain} { import porkbun_tls - redir https://${domain}/apps/books/{uri} 301 + redir https://${domain}/apps/books{uri} 301 } music.${domain} { import porkbun_tls - redir https://${domain}/apps/music/{uri} 301 + redir https://${domain}/apps/music{uri} 301 } vault.${domain} { import porkbun_tls - redir https://${domain}/server/vault/{uri} 301 + redir https://${domain}/server/vault{uri} 301 } pulse.${domain} { import porkbun_tls - redir https://${domain}/api/registry/{uri} 301 + redir https://${domain}/api/registry{uri} 301 } apps.${domain} { import porkbun_tls - redir https://${domain}/apps/{uri} 301 + redir https://${domain}/apps{uri} 301 + } + + chat.${domain} { + import porkbun_tls + redir https://${domain}/apps/chat{uri} 301 + } + + budget.${domain} { + import porkbun_tls + redir https://${domain}/apps/budget{uri} 301 + } + + www.${domain} { + import porkbun_tls + redir https://${domain}{uri} 301 } # Wildcard fallback — anything else gets a redirect to root