diff --git a/Makefile b/Makefile index b807a23e..352473bf 100644 --- a/Makefile +++ b/Makefile @@ -99,6 +99,7 @@ help: @printf "$(BOLD)$(BLUE)Caddy Commands:$(NC)\n" @printf " $(BOLD)$(GREEN)caddy-gen-cert$(NC) : Generate the caddy's mtls certificates.\n" + @printf " $(BOLD)$(GREEN)caddy-del-cert$(NC) : Remove the caddy's mtls certificates.\n" @printf " $(BOLD)$(GREEN)caddy-validate$(NC) : Validates caddy's files syntax.\n" @printf "$(NC)\n" diff --git a/caddy/Caddyfile.prod b/caddy/Caddyfile.prod index 741ff8c3..4e98908e 100644 --- a/caddy/Caddyfile.prod +++ b/caddy/Caddyfile.prod @@ -31,6 +31,11 @@ oullin.io { respond 403 } + @preflight { + method OPTIONS + header Origin * + } + # --- API handler. # - Reverse-proxy all requests to the Go API, forwarding Host + auth headers. # - to: Tell Caddy which upstream to send to. @@ -44,11 +49,6 @@ oullin.io { Access-Control-Expose-Headers "ETag, X-Request-ID" } - @preflight { - method OPTIONS - header Origin * - } - handle @preflight { # Reflect the Origin back so it's always allowed header Access-Control-Allow-Origin "{http.request.header.Origin}" diff --git a/docker-compose.yml b/docker-compose.yml index d01a7670..a648e01a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -49,7 +49,7 @@ services: - caddy_config:/config - ./caddy/Caddyfile.prod:/etc/caddy/Caddyfile - ${CADDY_LOGS_PATH}:/var/log/caddy - - ./caddy/mtls/ca.pem:/etc/caddy/mtls/ca.pem:ro + - ./caddy/mtls:/etc/caddy/mtls:ro networks: - caddy_net diff --git a/metal/makefile/app.mk b/metal/makefile/app.mk index 48a34d9b..2c0cd4f7 100644 --- a/metal/makefile/app.mk +++ b/metal/makefile/app.mk @@ -1,4 +1,4 @@ -.PHONY: fresh destroy audit watch format run-cli validate-caddy test-all run-cli-local +.PHONY: fresh destroy audit watch format run-cli test-all run-cli-local format: gofmt -w -s . diff --git a/metal/makefile/caddy.mk b/metal/makefile/caddy.mk index 26c80801..ad6dcaf9 100644 --- a/metal/makefile/caddy.mk +++ b/metal/makefile/caddy.mk @@ -1,21 +1,40 @@ -.PHONY: caddy-gen-cert caddy-validate +.PHONY: caddy-gen-certs caddy-del-certs caddy-validate CADDY_MTLS_DIR = $(ROOT_PATH)/caddy/mtls APP_CADDY_CONFIG_PROD_FILE ?= caddy/Caddyfile.prod APP_CADDY_CONFIG_LOCAL_FILE ?= caddy/Caddyfile.local -caddy-gen-cert: - openssl genrsa -out $(CADDY_MTLS_DIR)/ca.key 4096 - openssl req -x509 -new -nodes -key $(CADDY_MTLS_DIR)/ca.key -sha256 -days 3650 -subj "/CN=oullin-mtls-ca" -out $(CADDY_MTLS_DIR)/ca.pem - openssl rand -hex 16 | tr '[:lower:]' '[:upper:]' > $(CADDY_MTLS_DIR)/ca.srl - chmod 600 $(CADDY_MTLS_DIR)/ca.key - chmod 644 $(CADDY_MTLS_DIR)/ca.pem - chmod 644 $(CADDY_MTLS_DIR)/ca.srl +caddy-gen-certs: + @set -eu; \ + mkdir -p "$(CADDY_MTLS_DIR)"; chmod 700 "$(CADDY_MTLS_DIR)"; \ + if [ -d "$(CADDY_MTLS_DIR)/ca.pem" ]; then \ + printf "$(RED)✘ ERROR:$(NC) %s is a directory. Move or remove it.\n" "$(CADDY_MTLS_DIR)/ca.pem"; \ + fi; \ + if [ -e "$(CADDY_MTLS_DIR)/ca.key" ] || [ -e "$(CADDY_MTLS_DIR)/ca.pem" ]; then \ + printf "$(YELLOW)⚠️ CA already exists in %s.$(NC)\n" "$(CADDY_MTLS_DIR)"; \ + printf "$(CYAN)👉 Remove it with 'make caddy-clean-certs' if you want to recreate.$(NC)\n"; \ + else \ + umask 077; \ + printf "$(BLUE)🔑 Generating CA private key...$(NC)\n"; \ + openssl genrsa -out "$(CADDY_MTLS_DIR)/ca.key" 4096 >/dev/null 2>&1; \ + printf "$(BLUE)📜 Creating self-signed CA certificate...$(NC)\n"; \ + openssl req -x509 -new -key "$(CADDY_MTLS_DIR)/ca.key" -sha256 -days 3650 \ + -subj "/CN=oullin-mtls-ca" -out "$(CADDY_MTLS_DIR)/ca.pem" >/dev/null 2>&1; \ + printf '01\n' > "$(CADDY_MTLS_DIR)/ca.srl"; \ + chmod 600 "$(CADDY_MTLS_DIR)/ca.key"; \ + chmod 644 "$(CADDY_MTLS_DIR)/ca.pem" "$(CADDY_MTLS_DIR)/ca.srl"; \ + printf "$(GREEN)✅ CA written to %s$(NC)\n" "$(CADDY_MTLS_DIR)"; \ + printf "$(WHITE)🔍 CA fingerprint:$(NC)\n"; \ + openssl x509 -noout -fingerprint -sha256 -in "$(CADDY_MTLS_DIR)/ca.pem" | sed 's/^/ /'; \ + fi + +caddy-del-certs: + @set -eu; \ + rm -f "$(CADDY_MTLS_DIR)/ca.key" "$(CADDY_MTLS_DIR)/ca.pem" "$(CADDY_MTLS_DIR)/ca.srl"; \ + printf "$(BLUE)✅ files removed from [$(NC)$(CADDY_MTLS_DIR)$(BLUE)]$(NC)\n" -# --- Mac: -# Needs to be locally installed: https://formulae.brew.sh/formula/caddy caddy-validate: - caddy fmt --overwrite $(APP_CADDY_CONFIG_PROD_FILE) - caddy validate --config $(APP_CADDY_CONFIG_PROD_FILE) - caddy fmt --overwrite $(APP_CADDY_CONFIG_LOCAL_FILE) - caddy validate --config $(APP_CADDY_CONFIG_LOCAL_FILE) + docker run --rm \ + -v "$(ROOT_PATH)/caddy/Caddyfile.prod:/etc/caddy/Caddyfile:ro" \ + -v "$(ROOT_PATH)/caddy/mtls:/etc/caddy/mtls:ro" \ + caddy:2.10.0 caddy validate --config /etc/caddy/Caddyfile