mirror of
https://github.com/chatmail/relay.git
synced 2026-05-20 04:48:06 +00:00
fix(dns): query correct NS if MNAME server is hidden
replaces #870 fix #851
This commit is contained in:
@@ -64,18 +64,22 @@ def get_dkim_entry(mail_domain, pre_command, dkim_selector):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def query_dns(typ, domain):
|
def get_authoritative_ns(domain):
|
||||||
# Get autoritative nameserver from the SOA record.
|
"""Get autoritative nameserver from the SOA record."""
|
||||||
soa_answers = [
|
ns_replies = [
|
||||||
x.split()
|
x.split()
|
||||||
for x in shell(
|
for x in shell(
|
||||||
f"dig -r -q {domain} -t SOA +noall +authority +answer", print=log_progress
|
f"dig -r -q {domain} -t NS +noall +authority +answer", print=log_progress
|
||||||
).split("\n")
|
).split("\n")
|
||||||
]
|
]
|
||||||
soa = [a for a in soa_answers if len(a) >= 3 and a[3] == "SOA"]
|
filtered_replies = [a for a in ns_replies if len(a) >= 3 and a[3] in ("SOA", "NS")]
|
||||||
if not soa:
|
if not filtered_replies:
|
||||||
return
|
return
|
||||||
ns = soa[0][4]
|
return filtered_replies[0][4]
|
||||||
|
|
||||||
|
|
||||||
|
def query_dns(typ, domain):
|
||||||
|
ns = get_authoritative_ns(domain)
|
||||||
|
|
||||||
# Query authoritative nameserver directly to bypass DNS cache.
|
# Query authoritative nameserver directly to bypass DNS cache.
|
||||||
res = shell(f"dig @{ns} -r -q {domain} -t {typ} +short", print=log_progress)
|
res = shell(f"dig @{ns} -r -q {domain} -t {typ} +short", print=log_progress)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import pytest
|
|||||||
|
|
||||||
from cmdeploy import remote
|
from cmdeploy import remote
|
||||||
from cmdeploy.dns import check_full_zone, check_initial_remote_data, parse_zone_records
|
from cmdeploy.dns import check_full_zone, check_initial_remote_data, parse_zone_records
|
||||||
|
from cmdeploy.remote.rdns import get_authoritative_ns
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@@ -14,7 +15,22 @@ def mockdns_base(monkeypatch):
|
|||||||
if command.startswith("dig"):
|
if command.startswith("dig"):
|
||||||
if command == "dig":
|
if command == "dig":
|
||||||
return "."
|
return "."
|
||||||
if "SOA" in command:
|
if "with.public.soa" in command:
|
||||||
|
return (
|
||||||
|
"domain.with.public.soa. 2419 IN SOA ns1.first-ns.de. dns.hetzner.com."
|
||||||
|
" 2026050300 7200 1800 604800 3600"
|
||||||
|
)
|
||||||
|
if "with.hidden.soa" in command and "SOA" in command:
|
||||||
|
return (
|
||||||
|
"domain.with.hidden.soa. 300 IN SOA get.desec.io. get.desec.io."
|
||||||
|
" 2026025451 86400 3600 2419200 3600"
|
||||||
|
)
|
||||||
|
if "with.hidden.soa" in command and "NS" in command:
|
||||||
|
return (
|
||||||
|
"domain.with.hidden.soa. 2137 IN NS ns1.desec.io.\n"
|
||||||
|
"domain.with.hidden.soa. 2137 IN NS ns2.desec.org."
|
||||||
|
)
|
||||||
|
if "NS" in command:
|
||||||
return (
|
return (
|
||||||
"delta.chat. 21600 IN SOA ns1.first-ns.de. dns.hetzner.com."
|
"delta.chat. 21600 IN SOA ns1.first-ns.de. dns.hetzner.com."
|
||||||
" 2025102800 14400 1800 604800 3600"
|
" 2025102800 14400 1800 604800 3600"
|
||||||
@@ -125,6 +141,17 @@ class TestPerformInitialChecks:
|
|||||||
assert not l
|
assert not l
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("domain", "ns"),
|
||||||
|
[
|
||||||
|
("domain.with.public.soa", "ns1.first-ns.de."),
|
||||||
|
("domain.with.hidden.soa", "ns1.desec.io.")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_get_authoritative_ns(domain, ns, mockdns):
|
||||||
|
assert get_authoritative_ns(domain) == ns
|
||||||
|
|
||||||
|
|
||||||
def test_parse_zone_records():
|
def test_parse_zone_records():
|
||||||
text = """
|
text = """
|
||||||
; This is a comment
|
; This is a comment
|
||||||
|
|||||||
Reference in New Issue
Block a user