#!/usr/bin/env bash set -euo pipefail # Vigilar — Self-signed TLS certificate generator # Uses mkcert if available, otherwise falls back to openssl. CONFIG_DIR="/etc/vigilar" CERT_DIR="${CONFIG_DIR}/certs" CERT_FILE="${CERT_DIR}/cert.pem" KEY_FILE="${CERT_DIR}/key.pem" CONFIG_FILE="${CONFIG_DIR}/vigilar.toml" VIGILAR_GROUP="vigilar" info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; } ok() { printf '\033[1;32m[ OK ]\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; } fail() { printf '\033[1;31m[FAIL]\033[0m %s\n' "$*" >&2; exit 1; } get_lan_ip() { # Try to detect the primary LAN IP ip -4 route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1)}' | head -1 } generate_with_mkcert() { local lan_ip="$1" info "Using mkcert to generate certificate" local san_args=("vigilar.local" "localhost" "127.0.0.1") if [[ -n "$lan_ip" ]]; then san_args+=("$lan_ip") fi mkcert -cert-file "$CERT_FILE" -key-file "$KEY_FILE" "${san_args[@]}" ok "Certificate generated with mkcert" } generate_with_openssl() { local lan_ip="$1" info "Using openssl to generate self-signed certificate" local san="DNS:vigilar.local,DNS:localhost,IP:127.0.0.1" if [[ -n "$lan_ip" ]]; then san="${san},IP:${lan_ip}" fi openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \ -keyout "$KEY_FILE" \ -out "$CERT_FILE" \ -sha256 -days 3650 -nodes \ -subj "/CN=vigilar.local" \ -addext "subjectAltName=${san}" \ 2>/dev/null ok "Self-signed certificate generated with openssl" } update_config() { if [[ ! -f "$CONFIG_FILE" ]]; then warn "Config file not found at ${CONFIG_FILE}, skipping config update" return fi # Uncomment the tls_cert and tls_key lines if they are commented out if grep -q '^# *tls_cert' "$CONFIG_FILE"; then sudo sed -i 's|^# *tls_cert *=.*|tls_cert = "/etc/vigilar/certs/cert.pem"|' "$CONFIG_FILE" sudo sed -i 's|^# *tls_key *=.*|tls_key = "/etc/vigilar/certs/key.pem"|' "$CONFIG_FILE" ok "Config updated with TLS cert paths" elif grep -q '^tls_cert' "$CONFIG_FILE"; then ok "Config already has TLS cert paths" else # Append after the [web] section port line sudo sed -i '/^\[web\]/,/^$/{/^port/a\tls_cert = "/etc/vigilar/certs/cert.pem"\ntls_key = "/etc/vigilar/certs/key.pem" }' "$CONFIG_FILE" ok "Config updated with TLS cert paths" fi } main() { info "=== Vigilar TLS Certificate Generator ===" sudo mkdir -p "$CERT_DIR" if [[ -f "$CERT_FILE" && -f "$KEY_FILE" ]]; then warn "Certificates already exist at ${CERT_DIR}/" read -rp "Overwrite? [y/N] " answer if [[ ! "$answer" =~ ^[Yy]$ ]]; then info "Keeping existing certificates" exit 0 fi fi local lan_ip lan_ip="$(get_lan_ip)" || lan_ip="" if [[ -n "$lan_ip" ]]; then info "Detected LAN IP: ${lan_ip}" else warn "Could not detect LAN IP, skipping IP SAN" fi if command -v mkcert &>/dev/null; then generate_with_mkcert "$lan_ip" elif command -v openssl &>/dev/null; then generate_with_openssl "$lan_ip" else fail "Neither mkcert nor openssl found. Install one and retry." fi # Set permissions — readable by vigilar group sudo chown root:"${VIGILAR_GROUP}" "$CERT_FILE" "$KEY_FILE" sudo chmod 0640 "$KEY_FILE" sudo chmod 0644 "$CERT_FILE" update_config echo ok "TLS certificate ready" info " Cert: ${CERT_FILE}" info " Key: ${KEY_FILE}" if [[ -n "$lan_ip" ]]; then info " SANs: vigilar.local, localhost, 127.0.0.1, ${lan_ip}" else info " SANs: vigilar.local, localhost, 127.0.0.1" fi } main "$@"