diff --git a/cert-manager.py b/cert-manager.py index 739ac26..cf9bf21 100755 --- a/cert-manager.py +++ b/cert-manager.py @@ -25,13 +25,45 @@ DEFAULT_CONFIG = { 'last_common_name': '' } +SYSTEM_TYPES = { + 'proxmox': { + 'name': 'Proxmox VE', + 'deploy_script': 'deploy-proxmox.sh', + 'key_location': '/tmp/{short_name}.key', + 'default_port': '8006' + }, + 'pfsense': { + 'name': 'pfSense', + 'deploy_script': None, # Manual deployment via web interface + 'key_location': '/tmp/{short_name}.key', + 'default_port': '443' + }, + 'truenas': { + 'name': 'TrueNAS', + 'deploy_script': None, # Manual deployment via web interface + 'key_location': '/tmp/{short_name}.key', + 'default_port': '443' + }, + 'ucs': { + 'name': 'Univention Corporate Server', + 'deploy_script': None, + 'key_location': '/tmp/{short_name}.key', + 'default_port': '443' + }, + 'unknown': { + 'name': 'Unknown System', + 'deploy_script': None, + 'key_location': '/tmp/{short_name}.key', + 'default_port': '443' + } +} + def load_config(): """Load configuration from file or return defaults""" if CONFIG_FILE.exists(): try: with open(CONFIG_FILE, 'r') as f: config = json.load(f) - # Merge with defaults to add any new fields return {**DEFAULT_CONFIG, **config} except Exception as e: print(f"Warning: Could not load config: {e}") @@ -66,6 +98,21 @@ def yes_no_prompt(prompt, default=True): return False print("Please answer 'y' or 'n'") +def detect_system_type(target_host, script_dir): + """Detect the type of system on the target host""" + try: + result = subprocess.run( + [str(script_dir / 'detect-system.sh'), target_host], + capture_output=True, + text=True, + timeout=10 + ) + system_type = result.stdout.strip() + return system_type if system_type in SYSTEM_TYPES else 'unknown' + except Exception as e: + print(f"Warning: Could not detect system type: {e}") + return 'unknown' + def main(): print("=" * 60) print("Interactive Certificate Manager") @@ -97,6 +144,15 @@ def main(): print("Error: Target host is required!") sys.exit(1) + # Get script directory + script_dir = Path(__file__).parent.absolute() + + # Detect system type + print(f"\nDetecting system type on {target_host}...") + system_type = detect_system_type(target_host, script_dir) + system_info = SYSTEM_TYPES[system_type] + print(f"✓ Detected: {system_info['name']}") + common_name = prompt_with_default("Common Name (FQDN)", config['last_common_name']) if not common_name: @@ -119,6 +175,7 @@ def main(): print("\n" + "=" * 60) print("Summary:") print("=" * 60) + print(f"System Type: {system_info['name']}") print(f"Target Host: {target_host}") print(f"Common Name: {common_name}") print(f"Country: {country}") @@ -142,9 +199,6 @@ def main(): config['last_common_name'] = common_name save_config(config) - # Get script directory - script_dir = Path(__file__).parent.absolute() - print("\n" + "=" * 60) print("Step 1: Generating CSR on target host") print("=" * 60) @@ -199,14 +253,39 @@ def main(): cert_file = f"{short_name}-cert.pem" - if yes_no_prompt("Do you want to copy the certificate back to the target host?", True): - try: - # Copy certificate to target - subprocess.run(['scp', cert_file, f'root@{target_host}:/tmp/{short_name}.crt'], check=True) - print(f"\n✓ Certificate copied to target host at /tmp/{short_name}.crt") - print(f" Private key is at /tmp/{short_name}.key") - except subprocess.CalledProcessError: - print("\nWarning: Failed to copy certificate to target host") + # Use system-specific deployment if available + if system_info['deploy_script']: + if yes_no_prompt(f"Deploy certificate to {system_info['name']} automatically?", True): + deploy_script = script_dir / system_info['deploy_script'] + key_file = f"/tmp/{short_name}.key" # Key is on remote host + + deploy_cmd = [ + str(deploy_script), + target_host, + cert_file, + key_file, + short_name + ] + + try: + subprocess.run(deploy_cmd, check=True) + except subprocess.CalledProcessError as e: + print(f"\nError: Deployment failed with exit code {e.returncode}") + sys.exit(1) + except FileNotFoundError: + print(f"\nError: {system_info['deploy_script']} not found") + sys.exit(1) + else: + # Generic deployment - just copy files + if yes_no_prompt("Copy certificate back to the target host?", True): + try: + subprocess.run(['scp', cert_file, f'root@{target_host}:/tmp/{short_name}.crt'], check=True) + print(f"\n✓ Certificate copied to target host at /tmp/{short_name}.crt") + print(f" Private key is at /tmp/{short_name}.key") + print(f"\n⚠ Manual installation required for {system_info['name']}") + print(f" Please install the certificate through the web interface.") + except subprocess.CalledProcessError: + print("\nWarning: Failed to copy certificate to target host") print("\n" + "=" * 60) print("✓ Certificate Management Complete!") @@ -217,6 +296,10 @@ def main(): print(f"\nOn target host ({target_host}):") print(f" - /tmp/{short_name}.key (Private Key - {key_bits} bits)") print(f" - /tmp/{short_name}.crt (Certificate)") + + if system_type == 'proxmox': + print(f"\n✓ Access Proxmox at: https://{target_host}:{system_info['default_port']}") + print("\n") if __name__ == '__main__': diff --git a/deploy-proxmox.sh b/deploy-proxmox.sh new file mode 100755 index 0000000..f62ec6c --- /dev/null +++ b/deploy-proxmox.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# Deploy certificate to Proxmox host +# Usage: ./deploy-proxmox.sh + +set -e + +TARGET_HOST="$1" +CERT_FILE="$2" +KEY_FILE="$3" +SHORT_NAME="$4" + +if [ $# -lt 4 ]; then + echo "Usage: $0 " + exit 1 +fi + +echo "==========================================" +echo "Proxmox Certificate Deployment" +echo "==========================================" +echo "Target: $TARGET_HOST" +echo "Certificate: $CERT_FILE" +echo "Key file: $KEY_FILE" +echo "==========================================" +echo "" + +# Backup existing certificates +echo "[1/5] Backing up existing Proxmox certificates..." +ssh root@${TARGET_HOST} "cp /etc/pve/local/pveproxy-ssl.pem /etc/pve/local/pveproxy-ssl.pem.bak.$(date +%Y%m%d-%H%M%S) 2>/dev/null || true" +ssh root@${TARGET_HOST} "cp /etc/pve/local/pveproxy-ssl.key /etc/pve/local/pveproxy-ssl.key.bak.$(date +%Y%m%d-%H%M%S) 2>/dev/null || true" + +# Copy certificate to target +echo "[2/5] Copying certificate to Proxmox..." +scp "$CERT_FILE" root@${TARGET_HOST}:/tmp/${SHORT_NAME}.crt + +# Copy or retrieve key +echo "[3/5] Copying private key to Proxmox..." +if [ -f "$KEY_FILE" ]; then + scp "$KEY_FILE" root@${TARGET_HOST}:/tmp/${SHORT_NAME}.key +else + echo "Note: Key file should already be on target at /tmp/${SHORT_NAME}.key" +fi + +# Install certificate +echo "[4/5] Installing certificate for Proxmox web interface..." +ssh root@${TARGET_HOST} "cat /tmp/${SHORT_NAME}.crt > /etc/pve/local/pveproxy-ssl.pem && \ + cat /tmp/${SHORT_NAME}.key > /etc/pve/local/pveproxy-ssl.key && \ + chmod 640 /etc/pve/local/pveproxy-ssl.pem && \ + chmod 640 /etc/pve/local/pveproxy-ssl.key" + +# Restart Proxmox web service +echo "[5/5] Restarting Proxmox web interface..." +ssh root@${TARGET_HOST} "systemctl restart pveproxy.service" + +echo "" +echo "==========================================" +echo "✓ Proxmox certificate deployed!" +echo "==========================================" +echo "" +echo "Certificate installed at:" +echo " /etc/pve/local/pveproxy-ssl.pem" +echo " /etc/pve/local/pveproxy-ssl.key" +echo "" +echo "Backup created at:" +echo " /etc/pve/local/pveproxy-ssl.pem.bak.*" +echo " /etc/pve/local/pveproxy-ssl.key.bak.*" +echo "" +echo "Access Proxmox at: https://${TARGET_HOST}:8006" +echo "==========================================" diff --git a/detect-system.sh b/detect-system.sh new file mode 100755 index 0000000..d245d90 --- /dev/null +++ b/detect-system.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Detect system type on remote host +# Usage: ./detect-system.sh + +TARGET_HOST="$1" + +if [ -z "$TARGET_HOST" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Try to detect system type +if ssh -o ConnectTimeout=5 root@${TARGET_HOST} "test -f /usr/bin/pvesh" 2>/dev/null; then + echo "proxmox" +elif ssh -o ConnectTimeout=5 root@${TARGET_HOST} "test -f /usr/local/bin/freenas-version || test -f /usr/local/bin/truenas-version" 2>/dev/null; then + echo "truenas" +elif ssh -o ConnectTimeout=5 root@${TARGET_HOST} "test -f /usr/local/sbin/pfSsh.php" 2>/dev/null; then + echo "pfsense" +elif ssh -o ConnectTimeout=5 root@${TARGET_HOST} "test -f /usr/sbin/univention-config-registry" 2>/dev/null; then + echo "ucs" +else + echo "unknown" +fi