From 81bfa283cc0f47a7f7d7fc7c19a1a93bd07f43c5 Mon Sep 17 00:00:00 2001 From: pika Date: Mon, 10 Mar 2025 11:17:58 +0100 Subject: [PATCH] addet first python script for caddy host entry creation (caddyfile) --- Caddy/addEntry.py | 153 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 Caddy/addEntry.py diff --git a/Caddy/addEntry.py b/Caddy/addEntry.py new file mode 100644 index 0000000..aec9491 --- /dev/null +++ b/Caddy/addEntry.py @@ -0,0 +1,153 @@ +import os +import re + +def get_user_input(prompt, default=None): + """Interactive prompt with default values""" + value = input(f"{prompt} [{default}]: ") or default + return value + +def find_caddyfile(): + """Check if the Caddyfile exists, otherwise ask for the path""" + default_path = "./conf/Caddyfile" + if os.path.exists(default_path): + return default_path + + print("⚠ No Caddyfile found!") + while True: + custom_path = get_user_input("Enter the path to your Caddyfile") + if os.path.exists(custom_path): + return custom_path + print("❌ File not found, please try again.") + +def format_caddy_entry(domain, target_ip, target_port, proxy_type): + """Generate a properly formatted Caddy entry based on proxy type""" + if proxy_type == "standard": + return f""" +{domain} {{ + tls {{ + dns cloudflare {{env.CLOUDFLARE_API_TOKEN}} + }} + reverse_proxy {target_ip}:{target_port} +}} +""" + elif proxy_type == "https_skip_verify": + return f""" +{domain} {{ + tls {{ + dns cloudflare {{env.CLOUDFLARE_API_TOKEN}} + }} + reverse_proxy https://{target_ip}:{target_port} {{ + transport http {{ + tls + tls_insecure_skip_verify + }} + }} +}} +""" + elif proxy_type == "opnsense": + return f""" +{domain} {{ + tls {{ + dns cloudflare {{env.CLOUDFLARE_API_TOKEN}} + }} + reverse_proxy https://{target_ip}:{target_port} {{ + transport http {{ + tls + tls_insecure_skip_verify + versions h1.1 # Enforce HTTP/1.1 + }} + header_up Host {{host}} + header_up X-Real-IP {{remote_host}} + header_up X-Forwarded-Proto {{scheme}} + header_up X-Forwarded-For {{remote}} + header_down Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + + # Remove problematic headers + header_up -Connection + header_up -Upgrade + }} +}} +""" + +def update_existing_entries(caddyfile_path): + """Modify existing entries in the Caddyfile to enforce HTTP/1.1 for OPNsense entries""" + try: + with open(caddyfile_path, "r") as file: + caddyfile_content = file.read() + + # Regex pattern to match existing reverse_proxy blocks for OPNsense-like entries + pattern = re.compile(r'(\s*reverse_proxy\s+https:\/\/[\d\.]+:\d+\s*\{[^}]*\})', re.MULTILINE) + + def modify_proxy_block(match): + """Modify the reverse_proxy block to enforce HTTP/1.1 and remove Upgrade headers""" + proxy_block = match.group(1) + + # Ensure `versions h1.1` is inside the transport block + if "versions h1.1" not in proxy_block: + proxy_block = re.sub(r'(transport http \{)', r'\1\n versions h1.1', proxy_block) + + # Remove `header_up Connection` and `header_up Upgrade` + proxy_block = re.sub(r'header_up Connection[^\n]*\n?', '', proxy_block) + proxy_block = re.sub(r'header_up Upgrade[^\n]*\n?', '', proxy_block) + + return proxy_block + + modified_content = pattern.sub(modify_proxy_block, caddyfile_content) + + with open(caddyfile_path, "w") as file: + file.write(modified_content) + + print("✅ Existing OPNsense entries updated to enforce HTTP/1.1!") + + except Exception as e: + print(f"❌ Error updating Caddyfile: {e}") + +def add_caddy_entry(caddyfile_path): + """Add new Caddy reverse proxy entries""" + while True: + domain = get_user_input("Enter the domain", "sub.example.com") + target_ip = get_user_input("Enter the target IP", "192.168.1.100") + target_port = get_user_input("Enter the target port", "8080") + + print("\nChoose the proxy mode:") + print("1️⃣ Standard (No HTTPS changes)") + print("2️⃣ Internal HTTPS (skip verify)") + print("3️⃣ OPNsense Mode (skip verify + enforce HTTP/1.1)") + mode_choice = get_user_input("Enter option (1/2/3)", "1") + + proxy_type = "standard" + if mode_choice == "2": + proxy_type = "https_skip_verify" + elif mode_choice == "3": + proxy_type = "opnsense" + + new_entry = format_caddy_entry(domain, target_ip, target_port, proxy_type) + + try: + with open(caddyfile_path, "a") as file: + file.write(new_entry) + print(f"\n✅ New entry added: {domain} → {target_ip}:{target_port}") + except Exception as e: + print(f"\n❌ Error writing to Caddyfile: {e}") + return + + # Ask if another entry should be added + more_entries = get_user_input("Do you want to add another entry? (y/n)", "n").lower() == "y" + if not more_entries: + break + + # Ask if existing entries should be updated + update_existing = get_user_input("Do you want to update existing entries? (y/n)", "y").lower() == "y" + if update_existing: + update_existing_entries(caddyfile_path) + + # Restart Caddy container + restart_caddy = get_user_input("Do you want to restart the Caddy container? (y/n)", "y").lower() == "y" + if restart_caddy: + os.system("docker compose restart caddy") + print("🔄 Caddy container restarted!") + +if __name__ == "__main__": + caddyfile_path = find_caddyfile() + add_caddy_entry(caddyfile_path) +