diff --git a/Caddy/addEntry.py b/Caddy/addEntry.py index 01f9d9a..6f010eb 100644 --- a/Caddy/addEntry.py +++ b/Caddy/addEntry.py @@ -19,11 +19,33 @@ def find_caddyfile(): return custom_path print("❌ File not found, please try again.") -def format_caddy_entry(domain, target_ip, target_port, proxy_type): +def parse_existing_entries(caddyfile_path): + """Parse the existing Caddyfile to extract all configured domains""" + existing_entries = {} + try: + with open(caddyfile_path, "r") as file: + content = file.read() + + # Regex to find domain blocks + pattern = re.compile(r"(?P[^\s{]+(?:,\s*[^\s{]+)*)\s*{.*?reverse_proxy\s+(?Phttps?:\/\/[\d\.]+:\d+|[\d\.]+:\d+).*?}", re.DOTALL) + matches = pattern.findall(content) + + for domains, target in matches: + for domain in domains.split(", "): + existing_entries[domain] = target.strip() + + except Exception as e: + print(f"❌ Error reading Caddyfile: {e}") + + return existing_entries + +def format_caddy_entry(domains, target_ip, target_port, proxy_type): """Generate a properly formatted Caddy entry based on proxy type""" + domain_list = ", ".join(domains) # Multiple domains in a single line + if proxy_type == "standard": return f""" -{domain} {{ +{domain_list} {{ tls {{ dns cloudflare {{env.CLOUDFLARE_API_TOKEN}} }} @@ -32,7 +54,7 @@ def format_caddy_entry(domain, target_ip, target_port, proxy_type): """ elif proxy_type == "https_skip_verify": return f""" -{domain} {{ +{domain_list} {{ tls {{ dns cloudflare {{env.CLOUDFLARE_API_TOKEN}} }} @@ -46,7 +68,7 @@ def format_caddy_entry(domain, target_ip, target_port, proxy_type): """ elif proxy_type == "opnsense": return f""" -{domain} {{ +{domain_list} {{ tls {{ dns cloudflare {{env.CLOUDFLARE_API_TOKEN}} }} @@ -69,43 +91,48 @@ def format_caddy_entry(domain, target_ip, target_port, proxy_type): }} """ -def update_existing_entries(caddyfile_path): - """Modify existing entries in the Caddyfile to enforce HTTP/1.1 for OPNsense entries""" +def update_existing_entry(caddyfile_path, domain, new_entry): + """Replace an existing entry for the given domain""" try: with open(caddyfile_path, "r") as file: - caddyfile_content = file.read() + 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) + # Find and replace the domain entry + pattern = re.compile(rf"({domain}\s*\{{.*?reverse_proxy\s+[^\n]+\n.*?\}})", re.DOTALL) + content = pattern.sub(new_entry.strip(), content) with open(caddyfile_path, "w") as file: - file.write(modified_content) + file.write(content) - print("✅ Existing OPNsense entries updated to enforce HTTP/1.1!") + print(f"✅ Updated entry for {domain}") except Exception as e: print(f"❌ Error updating Caddyfile: {e}") def add_caddy_entry(caddyfile_path): - """Add new Caddy reverse proxy entries""" + """Add new Caddy reverse proxy entries, showing existing entries first""" + existing_entries = parse_existing_entries(caddyfile_path) + + print("\n📌 Existing Caddy Entries:") + if existing_entries: + for domain, target in existing_entries.items(): + print(f" 🔹 {domain} → {target}") + else: + print(" ⚠ No entries found.") + while True: - domain = get_user_input("Enter the domain", "sub.example.com") + domain = get_user_input("\nEnter the domain you want to configure", "") + + if not domain: + print("❌ No domain provided. Skipping entry.") + continue + + if domain in existing_entries: + print(f"⚠ The domain {domain} already exists.") + edit_existing = get_user_input("Do you want to edit this entry? (y/n)", "y").lower() == "y" + if not edit_existing: + continue + target_ip = get_user_input("Enter the target IP", "192.168.1.100") target_port = get_user_input("Enter the target port", "8080") @@ -121,28 +148,26 @@ def add_caddy_entry(caddyfile_path): elif mode_choice == "3": proxy_type = "opnsense" - new_entry = format_caddy_entry(domain, target_ip, target_port, proxy_type) + 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 + if domain in existing_entries: + update_existing_entry(caddyfile_path, domain, new_entry) + else: + 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" + more_entries = get_user_input("\nDo you want to add or edit 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" + restart_caddy = get_user_input("\nDo 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!") @@ -150,4 +175,3 @@ def add_caddy_entry(caddyfile_path): if __name__ == "__main__": caddyfile_path = find_caddyfile() add_caddy_entry(caddyfile_path) -