Last active
April 30, 2022 05:36
-
-
Save rfinnie/4f9f7f229d368a6a981320792d9ab7e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import os | |
import pathlib | |
import random | |
import subprocess | |
import sys | |
import tempfile | |
import yaml | |
BIND_DIR = pathlib.Path("/var/lib/bind/zones") | |
def process_zone(yaml_file): | |
with yaml_file.open() as f: | |
indata = yaml.safe_load(f) | |
zone = indata["zone"] | |
zone_ttl = indata.get("ttl", 3600) | |
intermediate_f = tempfile.NamedTemporaryFile(mode="w") | |
print("$TTL {}".format(zone_ttl), file=intermediate_f) | |
for record in indata["records"]: | |
if isinstance(record, (list, tuple)): | |
name, record_type, record_data = record | |
ttl = zone_ttl | |
record_class = "IN" | |
else: | |
name = record["name"] | |
ttl = record.get("ttl", zone_ttl) | |
record_class = record.get("class", "IN") | |
record_type = record["type"] | |
record_data = record["data"] | |
if name == "@": | |
name = zone | |
elif not name.endswith("."): | |
name = "{}.{}".format(name, zone) | |
print( | |
"{} {} {} {} {}".format(name, ttl, record_class, record_type, record_data), | |
file=intermediate_f, | |
) | |
for key_file in indata.get("key_files", []): | |
print("$INCLUDE {}".format(key_file), file=intermediate_f) | |
intermediate_f.flush() | |
salt = bytearray([random.randint(0, 255) for x in range(8)]).hex() | |
subprocess.check_call( | |
[ | |
"dnssec-signzone", | |
"-A", | |
"-3", | |
salt, | |
"-N", | |
"UNIXTIME", | |
"-o", | |
zone, | |
"-f", | |
zone[:-1], | |
"-t", | |
intermediate_f.name, | |
], | |
cwd=BIND_DIR, | |
) | |
if os.environ["USER"] == "root": | |
print("Do not run as root!", file=sys.stderr) | |
sys.exit(1) | |
for fn in sys.argv[1:]: | |
process_zone(pathlib.Path(fn)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
zone: nocache.vsix.us. | |
ttl: 3600 | |
key_files: [Knocache.vsix.us.+008+41748.key, Knocache.vsix.us.+008+42640.key] | |
records: | |
- ['@', SOA, feh.colobox.com. dns.colobox.com. 0 3600 3600 2419200 3600] | |
- ['@', NS, feh.colobox.com.] | |
- ['@', NS, cromulent.colobox.com.] | |
- {name: '@', type: A, data: 67.207.166.26, ttl: 1} | |
- {name: '@', type: AAAA, data: '2607:f188:0:20::2', ttl: 1} | |
- {name: '*', type: A, data: 67.207.166.26, ttl: 1} | |
- {name: '*', type: AAAA, data: '2607:f188:0:20::2', ttl: 1} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import pathlib | |
import re | |
import sys | |
import yaml | |
zone = sys.argv[1] | |
if not zone.endswith("."): | |
zone = zone + "." | |
out = {"zone": zone, "ttl": 3600} | |
key_files = ( | |
list(pathlib.Path("/etc/bind/zones").glob("K{}*.key".format(zone))) | |
+ list(pathlib.Path("/var/lib/bind/zones").glob("K{}*.key".format(zone))) | |
+ list(pathlib.Path("/etc/bind/zones/reverse").glob("K{}*.key".format(zone))) | |
) | |
if key_files: | |
out["key_files"] = [] | |
for key_file in key_files: | |
out["key_files"].append(key_file.name) | |
out["records"] = [] | |
seen_soa = False | |
for line in sys.stdin.readlines(): | |
line = line.strip() | |
if (not line) or line.startswith(";"): | |
continue | |
(name, ttl, record_class, record_type, record_data) = re.split(r"[\t ]+", line, 4) | |
if record_type in ("NSEC3", "RRSIG", "NSEC3PARAM", "DNSKEY"): | |
continue | |
if record_type == "SOA": | |
if seen_soa: | |
continue | |
seen_soa = True | |
if name == out["zone"]: | |
name = "@" | |
elif name.endswith(".{}".format(out["zone"])): | |
name = name[: (0 - len(out["zone"]) - 1)] | |
ttl = int(ttl) | |
if ttl == out["ttl"] and record_class == "IN": | |
record = [name, record_type, record_data] | |
else: | |
record = {"name": name, "type": record_type, "data": record_data} | |
if ttl != out["ttl"]: | |
record["ttl"] = ttl | |
if record_class != "IN": | |
record["class"] = record_class | |
out["records"].append(record) | |
out["records"].sort(key=lambda x: (x[0] if isinstance(x, (list, tuple)) else x["name"])) | |
yaml.dump(out, sys.stdout, default_flow_style=None, sort_keys=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment