#!/usr/bin/env python3 """Force HTTPS at Cloudflare for otantik.cm (Always Use HTTPS + Flexible SSL).""" from __future__ import annotations import json import os import sys import time import urllib.error import urllib.request TOKEN = os.environ.get("CF_TOKEN", "").strip() ZONE = "47d31b45dbc1d2e461f8d0d9ee84f954" def cf(method: str, path: str, body: dict | None = None, tries: int = 4): data = None if body is None else json.dumps(body).encode() last = None for i in range(tries): req = urllib.request.Request( "https://api.cloudflare.com/client/v4" + path, data=data, method=method, headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}, ) try: with urllib.request.urlopen(req, timeout=90) as resp: parsed = json.loads(resp.read().decode()) if not parsed.get("success"): print("API error", path, parsed.get("errors")) raise SystemExit(1) return parsed.get("result") except urllib.error.HTTPError as e: print("HTTP", e.code, path, e.read().decode("utf-8", "replace")[:1500]) raise SystemExit(1) except Exception as e: last = e print("retry", i + 1, method, path, type(e).__name__) time.sleep(2 + i * 2) print("failed", method, path, last) raise SystemExit(1) def main() -> None: if not TOKEN: raise SystemExit("missing CF_TOKEN") zone = cf("GET", f"/zones/{ZONE}") print("zone", zone.get("name"), zone.get("status")) for key, value in [ ("ssl", "flexible"), ("always_use_https", "on"), ("automatic_https_rewrites", "on"), ("min_tls_version", "1.2"), ]: try: r = cf("PATCH", f"/zones/{ZONE}/settings/{key}", {"value": value}) print("set", key, r.get("value") if isinstance(r, dict) else r) except SystemExit: print("skip/fail", key) recs = cf("GET", f"/zones/{ZONE}/dns_records?per_page=100") or [] print("=== DNS ===") for x in recs: print(x["name"], x["type"], x["content"], "proxied=" + str(x.get("proxied"))) print("DONE") if __name__ == "__main__": main()