#!/usr/bin/env python3 """列出 Cloudflare 账号可见的 zone(可选某 zone 的 DNS 记录)——只读。 用法: python3 cf-dns.py [zone名] 凭据: /etc/cloudflare.ini 的 dns_cloudflare_api_token(不打印 token 本身) """ import json import re import subprocess import sys import urllib.request CRED = '/etc/cloudflare.ini' API = 'https://api.cloudflare.com/client/v4' def token(): txt = open(CRED, 'r', encoding='utf-8').read() m = re.search(r'dns_cloudflare_api_token\s*=\s*([A-Za-z0-9_\-]+)', txt) if not m: sys.exit('未在 %s 找到 dns_cloudflare_api_token' % CRED) return m.group(1) def get(path, tok): req = urllib.request.Request(API + path, headers={'Authorization': 'Bearer ' + tok}) with urllib.request.urlopen(req, timeout=20) as resp: return json.loads(resp.read().decode('utf-8')) def short(v, n=44): v = str(v) return v if len(v) <= n else v[: n - 3] + '...' def main(): tok = token() zones = (get('/zones?per_page=100', tok).get('result') or []) print('可见 zone (%d):' % len(zones)) for z in zones: print(' - %s status=%s id=%s...' % (z['name'], z['status'], z['id'][:8])) if len(sys.argv) < 2: return want = sys.argv[1] zid = '' for z in zones: if z['name'] == want: zid = z['id'] if zid == '': print('\nzone %s 不在该 token 权限内(无法管理其 DNS/证书)' % want) return recs = (get('/zones/%s/dns_records?per_page=100' % zid, tok).get('result') or []) print('\n=== %s 的 DNS 记录(%d 条)===' % (want, len(recs))) for r in sorted(recs, key=lambda x: (x['type'], x['name'])): prox = 'on' if r.get('proxied') else 'off' print(' %-6s %-34s -> %-46s proxied=%s' % (r['type'], r['name'], short(r['content']), prox)) if __name__ == '__main__': main()