DNS: try other resolvers if the first doesn't have it

This commit is contained in:
missytake
2023-12-13 04:18:25 +01:00
parent 2b731bf909
commit d2fe417715
2 changed files with 45 additions and 31 deletions

View File

@@ -45,11 +45,11 @@ def init_cmd(args, out):
to_print = ["Now you should add %dnsentry% at your DNS provider:\n"] to_print = ["Now you should add %dnsentry% at your DNS provider:\n"]
if not ipaddress: if not ipaddress:
entries += 1 entries += 1
to_print.append(f"\tA\t{args.chatmail_domain}\t\t<your server's IPv4 address>") to_print.append(f"\tA\t{args.chatmail_domain}.\t\t<your server's IPv4 address>")
if not mta_ipadress or mta_ipadress != ipaddress: if not mta_ipadress or mta_ipadress != ipaddress:
entries += 1 entries += 1
to_print.append( to_print.append(
f"\tCNAME\tmta-sts.{args.chatmail_domain}\t{args.chatmail_domain}." f"\tCNAME\tmta-sts.{args.chatmail_domain}.\t{args.chatmail_domain}."
) )
if entries == 1: if entries == 1:
singular = "this entry" singular = "this entry"
@@ -126,11 +126,19 @@ def dns_cmd(args, out):
print() print()
if not dns.check_ptr_record(ipv4, args.config.mail_domain): if not dns.check_ptr_record(ipv4, args.config.mail_domain):
print(f"You should add a PTR/reverse DNS entry for {ipv4}, with the value: {args.config.mail_domain}.") print(
print("You can do so at your hosting provider (maybe this isn't your DNS provider).\n") f"You should add a PTR/reverse DNS entry for {ipv4}, with the value: {args.config.mail_domain}."
)
print(
"You can do so at your hosting provider (maybe this isn't your DNS provider).\n"
)
if not dns.check_ptr_record(ipv6, args.config.mail_domain): if not dns.check_ptr_record(ipv6, args.config.mail_domain):
print(f"You should add a PTR/reverse DNS entry for {ipv6}, with the value: {args.config.mail_domain}.") print(
print("You can do so at your hosting provider (maybe this isn't your DNS provider).\n") f"You should add a PTR/reverse DNS entry for {ipv6}, with the value: {args.config.mail_domain}."
)
print(
"You can do so at your hosting provider (maybe this isn't your DNS provider).\n"
)
to_print = [] to_print = []
with open(template, "r") as f: with open(template, "r") as f:

View File

@@ -1,7 +1,11 @@
import requests import requests
from ipaddress import ip_address from ipaddress import ip_address
url = "https://dns.nextdns.io/dns-query" resolvers = [
"https://dns.nextdns.io/dns-query",
"https://dns.google/resolve",
"https://cloudflare-dns.com/dns-query",
]
dns_types = { dns_types = {
"A": 1, "A": 1,
"AAAA": 28, "AAAA": 28,
@@ -20,36 +24,38 @@ class DNS:
def get(self, typ: str, domain: str) -> str: def get(self, typ: str, domain: str) -> str:
"""Get a DNS entry""" """Get a DNS entry"""
r = self.session.get( for url in resolvers:
url, r = self.session.get(
params={"name": domain, "type": typ}, url,
headers={"accept": "application/dns-json"}, params={"name": domain, "type": typ},
) headers={"accept": "application/dns-json"},
)
j = r.json() j = r.json()
if "Answer" in j: if "Answer" in j:
for answer in j["Answer"]: for answer in j["Answer"]:
if answer["type"] == dns_types[typ]: if answer["type"] == dns_types[typ]:
return answer["data"] return answer["data"]
return "" return ""
def resolve_mx(self, domain: str) -> (str, str): def resolve_mx(self, domain: str) -> (str, str):
"""Resolve an MX entry""" """Resolve an MX entry"""
r = self.session.get( for url in resolvers:
url, r = self.session.get(
params={"name": domain, "type": "MX"}, url,
headers={"accept": "application/dns-json"}, params={"name": domain, "type": "MX"},
) headers={"accept": "application/dns-json"},
)
j = r.json() j = r.json()
if "Answer" in j: if "Answer" in j:
result = (0, None) result = (0, None)
for answer in j["Answer"]: for answer in j["Answer"]:
if answer["type"] == dns_types["MX"]: if answer["type"] == dns_types["MX"]:
prio, server_name = answer["data"].split() prio, server_name = answer["data"].split()
if int(prio) > result[0]: if int(prio) > result[0]:
result = (int(prio), server_name) result = (int(prio), server_name)
return result return result
return None, None return None, None
def resolve(self, domain: str) -> str: def resolve(self, domain: str) -> str: