mirror of
https://github.com/kossakovsky/n8n-install.git
synced 2026-03-07 06:13:05 +00:00
docker volume mounts preserve host permissions, and caddy container may run as different uid than host user, causing certificate read failures with restrictive (600) permissions.
256 lines
7.9 KiB
Bash
Executable File
256 lines
7.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# setup_custom_tls.sh - Configure custom TLS certificates for Caddy
|
|
# =============================================================================
|
|
# Updates caddy-addon/tls-snippet.conf to use corporate/internal certificates
|
|
# instead of Let's Encrypt.
|
|
#
|
|
# Usage:
|
|
# bash scripts/setup_custom_tls.sh # Interactive mode
|
|
# bash scripts/setup_custom_tls.sh cert.crt key.key # Non-interactive mode
|
|
# bash scripts/setup_custom_tls.sh --remove # Reset to Let's Encrypt
|
|
#
|
|
# Prerequisites:
|
|
# - Place certificate files in ./certs/ directory
|
|
# - Certificate paths are relative to container (/etc/caddy/certs/)
|
|
# =============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
source "$(dirname "$0")/utils.sh" && init_paths
|
|
|
|
SNIPPET_FILE="$PROJECT_ROOT/caddy-addon/tls-snippet.conf"
|
|
SNIPPET_EXAMPLE="$PROJECT_ROOT/caddy-addon/tls-snippet.conf.example"
|
|
CERTS_DIR="$PROJECT_ROOT/certs"
|
|
|
|
# Legacy file that causes duplicate host errors (must be cleaned up on migration)
|
|
# TODO: Remove OLD_CONFIG and cleanup_legacy_config() after v3.0 release (all users migrated)
|
|
OLD_CONFIG="$PROJECT_ROOT/caddy-addon/custom-tls.conf"
|
|
|
|
# =============================================================================
|
|
# FUNCTIONS
|
|
# =============================================================================
|
|
|
|
cleanup_legacy_config() {
|
|
# Remove old custom-tls.conf that causes duplicate host errors
|
|
# This is needed for users upgrading from older versions
|
|
if [[ -f "$OLD_CONFIG" ]]; then
|
|
log_warning "Removing obsolete custom-tls.conf (causes duplicate host errors)"
|
|
rm -f "$OLD_CONFIG"
|
|
fi
|
|
}
|
|
|
|
show_help() {
|
|
cat << EOF
|
|
Setup Custom TLS Certificates for Caddy
|
|
|
|
Usage: $(basename "$0") [OPTIONS] [CERT_FILE] [KEY_FILE]
|
|
|
|
Options:
|
|
-h, --help Show this help message
|
|
--remove Reset to Let's Encrypt automatic certificates
|
|
|
|
Arguments:
|
|
CERT_FILE Path to certificate file (relative to ./certs/)
|
|
KEY_FILE Path to private key file (relative to ./certs/)
|
|
|
|
Examples:
|
|
$(basename "$0") # Interactive mode
|
|
$(basename "$0") wildcard.crt wildcard.key # Use specific files
|
|
$(basename "$0") --remove # Reset to Let's Encrypt
|
|
|
|
The script will:
|
|
1. Detect certificate files in ./certs/
|
|
2. Update caddy-addon/tls-snippet.conf with your certificate paths
|
|
3. Optionally restart Caddy
|
|
|
|
EOF
|
|
}
|
|
|
|
find_certificates() {
|
|
# Find certificate files in certs directory
|
|
local certs=()
|
|
if [[ -d "$CERTS_DIR" ]]; then
|
|
while IFS= read -r -d '' file; do
|
|
certs+=("$(basename "$file")")
|
|
done < <(find "$CERTS_DIR" -maxdepth 1 -type f \( -name "*.crt" -o -name "*.pem" -o -name "*.cer" \) -print0 2>/dev/null)
|
|
fi
|
|
echo "${certs[*]:-}"
|
|
}
|
|
|
|
find_keys() {
|
|
# Find key files in certs directory
|
|
local keys=()
|
|
if [[ -d "$CERTS_DIR" ]]; then
|
|
while IFS= read -r -d '' file; do
|
|
keys+=("$(basename "$file")")
|
|
done < <(find "$CERTS_DIR" -maxdepth 1 -type f \( -name "*.key" -o -name "*-key.pem" \) -print0 2>/dev/null)
|
|
fi
|
|
echo "${keys[*]:-}"
|
|
}
|
|
|
|
ensure_snippet_exists() {
|
|
# Create tls-snippet.conf from example if it doesn't exist
|
|
# This ensures the file survives git updates (it's gitignored)
|
|
if [[ ! -f "$SNIPPET_FILE" ]]; then
|
|
if [[ -f "$SNIPPET_EXAMPLE" ]]; then
|
|
cp "$SNIPPET_EXAMPLE" "$SNIPPET_FILE"
|
|
log_info "Created tls-snippet.conf from template"
|
|
else
|
|
# Fallback: create default content directly
|
|
remove_config
|
|
fi
|
|
fi
|
|
}
|
|
|
|
generate_config() {
|
|
local cert_file="$1"
|
|
local key_file="$2"
|
|
|
|
cat > "$SNIPPET_FILE" << EOF
|
|
# TLS Configuration Snippet
|
|
# Generated by setup_custom_tls.sh on $(date -Iseconds)
|
|
# Using custom certificates instead of Let's Encrypt.
|
|
# Reset to Let's Encrypt: make setup-tls --remove
|
|
|
|
(service_tls) {
|
|
tls /etc/caddy/certs/$cert_file /etc/caddy/certs/$key_file
|
|
}
|
|
EOF
|
|
|
|
log_success "Generated $SNIPPET_FILE"
|
|
}
|
|
|
|
remove_config() {
|
|
cat > "$SNIPPET_FILE" << 'EOF'
|
|
# TLS Configuration Snippet
|
|
# Imported by all service blocks in the main Caddyfile.
|
|
#
|
|
# Default: Empty (uses Let's Encrypt automatic certificates)
|
|
# Custom: Overwritten by 'make setup-tls' with your certificate paths
|
|
# Reset: Run 'make setup-tls --remove' to restore Let's Encrypt
|
|
|
|
(service_tls) {
|
|
# Default: Let's Encrypt automatic certificates (empty = no override)
|
|
}
|
|
EOF
|
|
|
|
log_success "Reset to Let's Encrypt (automatic certificates)"
|
|
}
|
|
|
|
restart_caddy() {
|
|
if wt_yesno "Restart Caddy" "Do you want to restart Caddy to apply the new configuration?" "yes"; then
|
|
log_info "Restarting Caddy..."
|
|
docker compose -p localai restart caddy
|
|
log_success "Caddy restarted"
|
|
else
|
|
log_info "Skipped Caddy restart. Run manually: docker compose -p localai restart caddy"
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# MAIN
|
|
# =============================================================================
|
|
|
|
main() {
|
|
# Handle arguments
|
|
case "${1:-}" in
|
|
-h|--help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
--remove)
|
|
cleanup_legacy_config
|
|
remove_config
|
|
restart_caddy
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
# Clean up legacy config that causes duplicate hosts
|
|
cleanup_legacy_config
|
|
|
|
# Ensure snippet file exists (survives git updates)
|
|
ensure_snippet_exists
|
|
|
|
# Ensure certs directory exists
|
|
mkdir -p "$CERTS_DIR"
|
|
|
|
local cert_file=""
|
|
local key_file=""
|
|
|
|
# Non-interactive mode
|
|
if [[ $# -ge 2 ]]; then
|
|
cert_file="$1"
|
|
key_file="$2"
|
|
|
|
if [[ ! -f "$CERTS_DIR/$cert_file" ]]; then
|
|
log_error "Certificate not found: $CERTS_DIR/$cert_file"
|
|
exit 1
|
|
fi
|
|
if [[ ! -f "$CERTS_DIR/$key_file" ]]; then
|
|
log_error "Key not found: $CERTS_DIR/$key_file"
|
|
exit 1
|
|
fi
|
|
else
|
|
# Interactive mode
|
|
require_whiptail
|
|
|
|
# Find available certificates
|
|
local certs_arr
|
|
IFS=' ' read -ra certs_arr <<< "$(find_certificates)"
|
|
|
|
if [[ ${#certs_arr[@]} -eq 0 ]]; then
|
|
wt_msg "No Certificates Found" "No certificate files found in ./certs/\n\nPlease place your certificate (.crt, .pem, .cer) and key (.key) files in the certs/ directory first."
|
|
exit 1
|
|
fi
|
|
|
|
# Build menu items for certificates
|
|
local cert_items=()
|
|
for cert in "${certs_arr[@]}"; do
|
|
cert_items+=("$cert" "")
|
|
done
|
|
|
|
cert_file=$(wt_menu "Select Certificate" "Choose your TLS certificate file:" "${cert_items[@]}")
|
|
[[ -z "$cert_file" ]] && exit 1
|
|
|
|
# Find available keys
|
|
local keys_arr
|
|
IFS=' ' read -ra keys_arr <<< "$(find_keys)"
|
|
|
|
if [[ ${#keys_arr[@]} -eq 0 ]]; then
|
|
wt_msg "No Keys Found" "No key files found in ./certs/\n\nPlease place your private key (.key) file in the certs/ directory."
|
|
exit 1
|
|
fi
|
|
|
|
# Build menu items for keys
|
|
local key_items=()
|
|
for key in "${keys_arr[@]}"; do
|
|
key_items+=("$key" "")
|
|
done
|
|
|
|
key_file=$(wt_menu "Select Private Key" "Choose your TLS private key file:" "${key_items[@]}")
|
|
[[ -z "$key_file" ]] && exit 1
|
|
fi
|
|
|
|
log_info "Using certificate: $cert_file"
|
|
log_info "Using key: $key_file"
|
|
|
|
# Ensure certificate files are readable by Caddy container
|
|
# (Docker volume mounts preserve host permissions, Caddy may run as different UID)
|
|
chmod 644 "$CERTS_DIR/$cert_file" "$CERTS_DIR/$key_file"
|
|
|
|
# Generate configuration
|
|
generate_config "$cert_file" "$key_file"
|
|
|
|
echo ""
|
|
log_info "Custom TLS configured successfully!"
|
|
log_info "All services will use: /etc/caddy/certs/$cert_file"
|
|
echo ""
|
|
|
|
# Restart Caddy
|
|
restart_caddy
|
|
}
|
|
|
|
main "$@"
|