add protection against dns-redirection to is_resolvable
In an effort to make the EC2 Datasource's search under ec2.archive.ubuntu.com resilient against dns redirection, we add some code to is_resolvable. One future enhancement for this would be to protect against server side round robin results. Ie, if 'bogus-entry' returned 10.0.1.1 one time, and then 10.0.1.2 a second time. We could check if results where within the same 3 octets, and assume invalid if they were.
This commit is contained in:
parent
4edd171407
commit
84c7720af5
|
@ -55,6 +55,7 @@ from cloudinit import url_helper as uhelp
|
||||||
from cloudinit.settings import (CFG_BUILTIN)
|
from cloudinit.settings import (CFG_BUILTIN)
|
||||||
|
|
||||||
|
|
||||||
|
_DNS_REDIRECT_IP = None
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Helps cleanup filenames to ensure they aren't FS incompatible
|
# Helps cleanup filenames to ensure they aren't FS incompatible
|
||||||
|
@ -825,9 +826,43 @@ def get_cmdline_url(names=('cloud-config-url', 'url'),
|
||||||
|
|
||||||
|
|
||||||
def is_resolvable(name):
|
def is_resolvable(name):
|
||||||
""" determine if a url is resolvable, return a boolean """
|
""" determine if a url is resolvable, return a boolean
|
||||||
|
This also attempts to be resilent against dns redirection.
|
||||||
|
|
||||||
|
Note, that normal nsswitch resolution is used here. So in order
|
||||||
|
to avoid any utilization of 'search' entries in /etc/resolv.conf
|
||||||
|
we have to append '.'.
|
||||||
|
|
||||||
|
The top level 'invalid' domain is invalid per RFC. And example.com
|
||||||
|
should also not exist. The random entry will be resolved inside
|
||||||
|
the search list.
|
||||||
|
"""
|
||||||
|
global _DNS_REDIRECT_IP # pylint: disable=W0603
|
||||||
|
if _DNS_REDIRECT_IP is None:
|
||||||
|
badips = set()
|
||||||
|
badnames = ("does-not-exist.example.com.", "example.invalid.",
|
||||||
|
rand_str())
|
||||||
|
badresults = {}
|
||||||
|
for iname in badnames:
|
||||||
|
try:
|
||||||
|
result = socket.getaddrinfo(iname, None, 0, 0,
|
||||||
|
socket.SOCK_STREAM, socket.AI_CANONNAME)
|
||||||
|
badresults[iname] = []
|
||||||
|
for (_fam, _stype, _proto, cname, sockaddr) in result:
|
||||||
|
badresults[iname].append("%s: %s" % (cname, sockaddr[0]))
|
||||||
|
badips.add(sockaddr[0])
|
||||||
|
except socket.gaierror:
|
||||||
|
pass
|
||||||
|
_DNS_REDIRECT_IP = badips
|
||||||
|
if badresults:
|
||||||
|
LOG.debug("detected dns redirection: %s" % badresults)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
socket.getaddrinfo(name, None)
|
result = socket.getaddrinfo(name, None)
|
||||||
|
# check first result's sockaddr field
|
||||||
|
addr = result[0][4][0]
|
||||||
|
if addr in _DNS_REDIRECT_IP:
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
except socket.gaierror:
|
except socket.gaierror:
|
||||||
return False
|
return False
|
||||||
|
|
Loading…
Reference in New Issue