mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Move dig() to utils.dns
This commit is contained in:
parent
22aa1f2538
commit
8438efa680
5 changed files with 77 additions and 75 deletions
|
@ -8,11 +8,10 @@ from publicsuffixlist import PublicSuffixList
|
|||
|
||||
from moulinette.utils.process import check_output
|
||||
|
||||
from yunohost.utils.network import dig
|
||||
from yunohost.utils.dns import dig, YNH_DYNDNS_DOMAINS
|
||||
from yunohost.diagnosis import Diagnoser
|
||||
from yunohost.domain import domain_list, _build_dns_conf, _get_maindomain
|
||||
|
||||
YNH_DYNDNS_DOMAINS = ["nohost.me", "noho.st", "ynh.fr"]
|
||||
SPECIAL_USE_TLDS = ["local", "localhost", "onion", "test"]
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from moulinette.utils.filesystem import read_yaml
|
|||
from yunohost.diagnosis import Diagnoser
|
||||
from yunohost.domain import _get_maindomain, domain_list
|
||||
from yunohost.settings import settings_get
|
||||
from yunohost.utils.network import dig
|
||||
from yunohost.utils.dns import dig
|
||||
|
||||
DEFAULT_DNS_BLACKLIST = "/usr/share/yunohost/other/dnsbl_list.yml"
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ from moulinette.utils.network import download_json
|
|||
|
||||
from yunohost.utils.error import YunohostError, YunohostValidationError
|
||||
from yunohost.domain import _get_maindomain, _build_dns_conf
|
||||
from yunohost.utils.network import get_public_ip, dig
|
||||
from yunohost.utils.network import get_public_ip
|
||||
from yunohost.utils.dns import dig
|
||||
from yunohost.log import is_unit_operation
|
||||
from yunohost.regenconf import regen_conf
|
||||
|
||||
|
|
|
@ -18,11 +18,82 @@
|
|||
along with this program; if not, see http://www.gnu.org/licenses
|
||||
|
||||
"""
|
||||
import dns.resolver
|
||||
from publicsuffixlist import PublicSuffixList
|
||||
from yunohost.utils.network import dig
|
||||
from moulinette.utils.filesystem import read_file
|
||||
|
||||
YNH_DYNDNS_DOMAINS = ["nohost.me", "noho.st", "ynh.fr"]
|
||||
|
||||
# Lazy dev caching to avoid re-reading the file multiple time when calling
|
||||
# dig() often during same yunohost operation
|
||||
external_resolvers_ = []
|
||||
|
||||
|
||||
def external_resolvers():
|
||||
|
||||
global external_resolvers_
|
||||
|
||||
if not external_resolvers_:
|
||||
resolv_dnsmasq_conf = read_file("/etc/resolv.dnsmasq.conf").split("\n")
|
||||
external_resolvers_ = [
|
||||
r.split(" ")[1] for r in resolv_dnsmasq_conf if r.startswith("nameserver")
|
||||
]
|
||||
# We keep only ipv4 resolvers, otherwise on IPv4-only instances, IPv6
|
||||
# will be tried anyway resulting in super-slow dig requests that'll wait
|
||||
# until timeout...
|
||||
external_resolvers_ = [r for r in external_resolvers_ if ":" not in r]
|
||||
|
||||
return external_resolvers_
|
||||
|
||||
|
||||
def dig(
|
||||
qname, rdtype="A", timeout=5, resolvers="local", edns_size=1500, full_answers=False
|
||||
):
|
||||
"""
|
||||
Do a quick DNS request and avoid the "search" trap inside /etc/resolv.conf
|
||||
"""
|
||||
|
||||
# It's very important to do the request with a qname ended by .
|
||||
# If we don't and the domain fail, dns resolver try a second request
|
||||
# by concatenate the qname with the end of the "hostname"
|
||||
if not qname.endswith("."):
|
||||
qname += "."
|
||||
|
||||
if resolvers == "local":
|
||||
resolvers = ["127.0.0.1"]
|
||||
elif resolvers == "force_external":
|
||||
resolvers = external_resolvers()
|
||||
else:
|
||||
assert isinstance(resolvers, list)
|
||||
|
||||
resolver = dns.resolver.Resolver(configure=False)
|
||||
resolver.use_edns(0, 0, edns_size)
|
||||
resolver.nameservers = resolvers
|
||||
# resolver.timeout is used to trigger the next DNS query on resolvers list.
|
||||
# In python-dns 1.16, this value is set to 2.0. However, this means that if
|
||||
# the 3 first dns resolvers in list are down, we wait 6 seconds before to
|
||||
# run the DNS query to a DNS resolvers up...
|
||||
# In diagnosis dnsrecords, with 10 domains this means at least 12min, too long.
|
||||
resolver.timeout = 1.0
|
||||
# resolver.lifetime is the timeout for resolver.query()
|
||||
# By default set it to 5 seconds to allow 4 resolvers to be unreachable.
|
||||
resolver.lifetime = timeout
|
||||
try:
|
||||
answers = resolver.query(qname, rdtype)
|
||||
except (
|
||||
dns.resolver.NXDOMAIN,
|
||||
dns.resolver.NoNameservers,
|
||||
dns.resolver.NoAnswer,
|
||||
dns.exception.Timeout,
|
||||
) as e:
|
||||
return ("nok", (e.__class__.__name__, e))
|
||||
|
||||
if not full_answers:
|
||||
answers = [answer.to_text() for answer in answers]
|
||||
|
||||
return ("ok", answers)
|
||||
|
||||
|
||||
def get_public_suffix(domain):
|
||||
"""get_public_suffix("www.example.com") -> "example.com"
|
||||
|
||||
|
@ -40,6 +111,7 @@ def get_public_suffix(domain):
|
|||
|
||||
return public_suffix
|
||||
|
||||
|
||||
def get_dns_zone_from_domain(domain):
|
||||
# TODO Check if this function is YNH_DYNDNS_DOMAINS compatible
|
||||
"""
|
||||
|
|
|
@ -22,7 +22,6 @@ import os
|
|||
import re
|
||||
import logging
|
||||
import time
|
||||
import dns.resolver
|
||||
|
||||
from moulinette.utils.filesystem import read_file, write_to_file
|
||||
from moulinette.utils.network import download_text
|
||||
|
@ -124,75 +123,6 @@ def get_gateway():
|
|||
return addr.popitem()[1] if len(addr) == 1 else None
|
||||
|
||||
|
||||
# Lazy dev caching to avoid re-reading the file multiple time when calling
|
||||
# dig() often during same yunohost operation
|
||||
external_resolvers_ = []
|
||||
|
||||
|
||||
def external_resolvers():
|
||||
|
||||
global external_resolvers_
|
||||
|
||||
if not external_resolvers_:
|
||||
resolv_dnsmasq_conf = read_file("/etc/resolv.dnsmasq.conf").split("\n")
|
||||
external_resolvers_ = [
|
||||
r.split(" ")[1] for r in resolv_dnsmasq_conf if r.startswith("nameserver")
|
||||
]
|
||||
# We keep only ipv4 resolvers, otherwise on IPv4-only instances, IPv6
|
||||
# will be tried anyway resulting in super-slow dig requests that'll wait
|
||||
# until timeout...
|
||||
external_resolvers_ = [r for r in external_resolvers_ if ":" not in r]
|
||||
|
||||
return external_resolvers_
|
||||
|
||||
|
||||
def dig(
|
||||
qname, rdtype="A", timeout=5, resolvers="local", edns_size=1500, full_answers=False
|
||||
):
|
||||
"""
|
||||
Do a quick DNS request and avoid the "search" trap inside /etc/resolv.conf
|
||||
"""
|
||||
|
||||
# It's very important to do the request with a qname ended by .
|
||||
# If we don't and the domain fail, dns resolver try a second request
|
||||
# by concatenate the qname with the end of the "hostname"
|
||||
if not qname.endswith("."):
|
||||
qname += "."
|
||||
|
||||
if resolvers == "local":
|
||||
resolvers = ["127.0.0.1"]
|
||||
elif resolvers == "force_external":
|
||||
resolvers = external_resolvers()
|
||||
else:
|
||||
assert isinstance(resolvers, list)
|
||||
|
||||
resolver = dns.resolver.Resolver(configure=False)
|
||||
resolver.use_edns(0, 0, edns_size)
|
||||
resolver.nameservers = resolvers
|
||||
# resolver.timeout is used to trigger the next DNS query on resolvers list.
|
||||
# In python-dns 1.16, this value is set to 2.0. However, this means that if
|
||||
# the 3 first dns resolvers in list are down, we wait 6 seconds before to
|
||||
# run the DNS query to a DNS resolvers up...
|
||||
# In diagnosis dnsrecords, with 10 domains this means at least 12min, too long.
|
||||
resolver.timeout = 1.0
|
||||
# resolver.lifetime is the timeout for resolver.query()
|
||||
# By default set it to 5 seconds to allow 4 resolvers to be unreachable.
|
||||
resolver.lifetime = timeout
|
||||
try:
|
||||
answers = resolver.query(qname, rdtype)
|
||||
except (
|
||||
dns.resolver.NXDOMAIN,
|
||||
dns.resolver.NoNameservers,
|
||||
dns.resolver.NoAnswer,
|
||||
dns.exception.Timeout,
|
||||
) as e:
|
||||
return ("nok", (e.__class__.__name__, e))
|
||||
|
||||
if not full_answers:
|
||||
answers = [answer.to_text() for answer in answers]
|
||||
|
||||
return ("ok", answers)
|
||||
|
||||
def _extract_inet(string, skip_netmask=False, skip_loopback=True):
|
||||
"""
|
||||
Extract IP addresses (v4 and/or v6) from a string limited to one
|
||||
|
|
Loading…
Add table
Reference in a new issue