From a2fd688865deaa9bcec87e4487274620e29e9594 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Sun, 25 Jan 2026 11:20:04 -0800 Subject: [PATCH] Add Caddy layer4 support for Forgejo SSH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add layer4 TCP proxy configuration to Caddyfile template - Configure SSH service on port 2222 → localhost:2200 (Forgejo) - Switch HTTPS port from 8443 (testing) to 443 (production) - Requires Caddy rebuilt with github.com/mholt/caddy-l4 plugin This enables git+ssh access via forge.ops.eblu.me:2222, accessible from tailnet clients, docker containers, and k8s pods alike. Co-Authored-By: Claude Opus 4.5 --- ansible/roles/caddy/defaults/main.yml | 11 ++++++++--- ansible/roles/caddy/templates/Caddyfile.j2 | 13 +++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/ansible/roles/caddy/defaults/main.yml b/ansible/roles/caddy/defaults/main.yml index 3e1ad0c..8490b54 100644 --- a/ansible/roles/caddy/defaults/main.yml +++ b/ansible/roles/caddy/defaults/main.yml @@ -15,9 +15,8 @@ caddy_gandi_token_file: /Users/erichblume/.config/caddy/gandi-token # Domain configuration caddy_domain: ops.eblu.me -# Listen on Tailscale interface only (port 443) -# Use 8443 during testing to avoid conflicts with Tailscale serve -caddy_https_port: 8443 +# HTTPS port (443 is standard) +caddy_https_port: 443 # Services to proxy # Format: { name: "service", host: "hostname", backend: "url" } @@ -35,3 +34,9 @@ caddy_services: # - name: grafana # host: "grafana.{{ caddy_domain }}" # backend: "http://minikube-ip:nodeport" + +# SSH services (Layer 4 TCP proxy) +# Format: { port: external_port, backend: "host:port" } +caddy_ssh_services: + - port: 2222 + backend: "localhost:2200" # Forgejo SSH diff --git a/ansible/roles/caddy/templates/Caddyfile.j2 b/ansible/roles/caddy/templates/Caddyfile.j2 index 455b49c..36c1c8d 100644 --- a/ansible/roles/caddy/templates/Caddyfile.j2 +++ b/ansible/roles/caddy/templates/Caddyfile.j2 @@ -7,6 +7,19 @@ { # Global options admin off + +{% if caddy_ssh_services %} + # Layer 4 (TCP) routing for SSH services + layer4 { +{% for ssh_svc in caddy_ssh_services %} + :{{ ssh_svc.port }} { + route { + proxy {{ ssh_svc.backend }} + } + } +{% endfor %} + } +{% endif %} } # Wildcard certificate for all services