diff options
author | Scott Moser <smoser@ubuntu.com> | 2012-08-06 15:59:41 -0400 |
---|---|---|
committer | Scott Moser <smoser@ubuntu.com> | 2012-08-06 15:59:41 -0400 |
commit | 1bb67be5bd8c826717c9757f727406c73c7ef4e8 (patch) | |
tree | 4cdc6d19a3c155d2fb5a1bd7a359770b6745308c /cloudinit | |
parent | 8991867d98e997fa0cdef8bcfb2a5e46d8376af5 (diff) | |
download | vyos-cloud-init-1bb67be5bd8c826717c9757f727406c73c7ef4e8.tar.gz vyos-cloud-init-1bb67be5bd8c826717c9757f727406c73c7ef4e8.zip |
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.
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/util.py | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py index 6eb2a10e..a8c0cceb 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -55,6 +55,7 @@ from cloudinit import url_helper as uhelp from cloudinit.settings import (CFG_BUILTIN) +_DNS_REDIRECT_IP = None LOG = logging.getLogger(__name__) # 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): - """ 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: - 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 except socket.gaierror: return False |