fix(cmdeploy/dns): align zones, add multiline test records

And add requirements to lxc docs
This commit is contained in:
j4n
2026-03-30 08:39:40 +02:00
parent 386364ac70
commit d73a1baf51
5 changed files with 61 additions and 32 deletions

View File

@@ -47,33 +47,40 @@ def get_filled_zone_file(remote_data):
remote_data["sts_id"] = datetime.datetime.now().strftime("%Y%m%d%H%M") remote_data["sts_id"] = datetime.datetime.now().strftime("%Y%m%d%H%M")
d = remote_data["mail_domain"] d = remote_data["mail_domain"]
def rec(name, rtype, rdata, ttl=3600):
return f"{name:<40} {ttl:<6} IN {rtype:<5} {rdata}"
lines = ["; Required DNS entries"] lines = ["; Required DNS entries"]
if remote_data.get("A"): if remote_data.get("A"):
lines.append(f"{d}. 3600 IN A {remote_data['A']}") lines.append(rec(f"{d}.", "A", remote_data["A"]))
if remote_data.get("AAAA"): if remote_data.get("AAAA"):
lines.append(f"{d}. 3600 IN AAAA {remote_data['AAAA']}") lines.append(rec(f"{d}.", "AAAA", remote_data["AAAA"]))
lines.append(f"{d}. 3600 IN MX 10 {d}.") lines.append(rec(f"{d}.", "MX", f"10 {d}."))
if remote_data.get("strict_tls"): if remote_data.get("strict_tls"):
lines.append( lines.append(
f'_mta-sts.{d}. 3600 IN TXT "v=STSv1; id={remote_data["sts_id"]}"' rec(f"_mta-sts.{d}.", "TXT", f'"v=STSv1; id={remote_data["sts_id"]}"')
) )
lines.append(f"mta-sts.{d}. 3600 IN CNAME {d}.") lines.append(rec(f"mta-sts.{d}.", "CNAME", f"{d}."))
lines.append(f"www.{d}. 3600 IN CNAME {d}.") lines.append(rec(f"www.{d}.", "CNAME", f"{d}."))
lines.append(remote_data["dkim_entry"]) lines.append(remote_data["dkim_entry"])
lines.append("") lines.append("")
lines.append("; Recommended DNS entries") lines.append("; Recommended DNS entries")
lines.append(f'{d}. 3600 IN TXT "v=spf1 a ~all"') lines.append(rec(f"{d}.", "TXT", '"v=spf1 a ~all"'))
lines.append(f'_dmarc.{d}. 3600 IN TXT "v=DMARC1;p=reject;adkim=s;aspf=s"') lines.append(rec(f"_dmarc.{d}.", "TXT", '"v=DMARC1;p=reject;adkim=s;aspf=s"'))
if remote_data.get("acme_account_url"): if remote_data.get("acme_account_url"):
lines.append( lines.append(
f"{d}. 3600 IN CAA 0 issue" rec(
f' "letsencrypt.org;accounturi={remote_data["acme_account_url"]}"' f"{d}.",
"CAA",
f'0 issue "letsencrypt.org;accounturi={remote_data["acme_account_url"]}"',
) )
lines.append(f'_adsp._domainkey.{d}. 3600 IN TXT "dkim=discardable"') )
lines.append(f"_submission._tcp.{d}. 3600 IN SRV 0 1 587 {d}.") lines.append(rec(f"_adsp._domainkey.{d}.", "TXT", '"dkim=discardable"'))
lines.append(f"_submissions._tcp.{d}. 3600 IN SRV 0 1 465 {d}.") lines.append(rec(f"_submission._tcp.{d}.", "SRV", f"0 1 587 {d}."))
lines.append(f"_imap._tcp.{d}. 3600 IN SRV 0 1 143 {d}.") lines.append(rec(f"_submissions._tcp.{d}.", "SRV", f"0 1 465 {d}."))
lines.append(f"_imaps._tcp.{d}. 3600 IN SRV 0 1 993 {d}.") lines.append(rec(f"_imap._tcp.{d}.", "SRV", f"0 1 143 {d}."))
lines.append(rec(f"_imaps._tcp.{d}.", "SRV", f"0 1 993 {d}."))
lines.append("") lines.append("")
return "\n".join(lines) return "\n".join(lines)

View File

@@ -57,9 +57,10 @@ def get_dkim_entry(mail_domain, pre_command, dkim_selector):
dkim_value_raw = f"v=DKIM1;k=rsa;p={dkim_pubkey};s=email;t=s" dkim_value_raw = f"v=DKIM1;k=rsa;p={dkim_pubkey};s=email;t=s"
dkim_value = '" "'.join(re.findall(".{1,255}", dkim_value_raw)) dkim_value = '" "'.join(re.findall(".{1,255}", dkim_value_raw))
web_dkim_value = "".join(re.findall(".{1,255}", dkim_value_raw)) web_dkim_value = "".join(re.findall(".{1,255}", dkim_value_raw))
name = f"{dkim_selector}._domainkey.{mail_domain}."
return ( return (
f'{dkim_selector}._domainkey.{mail_domain}. 3600 IN TXT "{dkim_value}"', f'{name:<40} 3600 IN TXT "{dkim_value}"',
f'{dkim_selector}._domainkey.{mail_domain}. 3600 IN TXT "{web_dkim_value}"', f'{name:<40} 3600 IN TXT "{web_dkim_value}"',
) )

View File

@@ -132,11 +132,28 @@ def test_parse_zone_records():
; Another comment ; Another comment
www.some.domain. 3600 IN CNAME some.domain. www.some.domain. 3600 IN CNAME some.domain.
; Multi-word rdata
some.domain. 3600 IN MX 10 mail.some.domain.
; DKIM record (single line, multi-word TXT rdata)
dkim._domainkey.some.domain. 3600 IN TXT "v=DKIM1;k=rsa;p=MIIBIjANBgkqhkiG" "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA"
; Another TXT record
_dmarc.some.domain. 3600 IN TXT "v=DMARC1;p=reject"
""" """
records = list(parse_zone_records(text)) records = list(parse_zone_records(text))
assert records == [ assert records == [
("some.domain", "3600", "A", "1.1.1.1"), ("some.domain", "3600", "A", "1.1.1.1"),
("www.some.domain", "3600", "CNAME", "some.domain."), ("www.some.domain", "3600", "CNAME", "some.domain."),
("some.domain", "3600", "MX", "10 mail.some.domain."),
(
"dkim._domainkey.some.domain",
"3600",
"TXT",
'"v=DKIM1;k=rsa;p=MIIBIjANBgkqhkiG" "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA"',
),
("_dmarc.some.domain", "3600", "TXT", '"v=DMARC1;p=reject"'),
] ]

View File

@@ -15,6 +15,10 @@ as they would on a real Debian server or cloud VPS.
Prerequisites Prerequisites
------------- -------------
- Around 4-5 GiB free disk space
- `systemd-networkd` for the automagic hostname resolution
- No other service occupying Port 53
Install `Incus <https://linuxcontainers.org/incus/>`_ Install `Incus <https://linuxcontainers.org/incus/>`_
(LXC container manager). (LXC container manager).
See the `official installation guide See the `official installation guide