URL: https://github.com/freeipa/freeipa/pull/284 Author: tomaskrizek Title: #284: ipautil: check for open ports on all resolved IPs Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/284/head:pr284 git checkout pr284
From 29b7f6c4d17911f760f0031f31edfa2881e2223d Mon Sep 17 00:00:00 2001 From: Tomas Krizek <[email protected]> Date: Tue, 29 Nov 2016 18:19:07 +0100 Subject: [PATCH] ipautil: check for open ports on all resolved IPs When a hostname is provided to host_port_open, it should check if ports are open for ALL IPs that are resolved from the hostname, instead of checking whether the port is reachable on at least one of the IPs. https://fedorahosted.org/freeipa/ticket/6522 --- install/tools/ipa-replica-conncheck | 5 +++-- ipapython/ipautil.py | 44 ++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck index 934744d..04e23de 100755 --- a/install/tools/ipa-replica-conncheck +++ b/install/tools/ipa-replica-conncheck @@ -381,8 +381,9 @@ def port_check(host, port_list): ports_udp_warning = [] # conncheck could not verify that port is open for port in port_list: try: - port_open = ipautil.host_port_open(host, port.port, - port.port_type, socket_timeout=CONNECT_TIMEOUT) + port_open = ipautil.host_port_open( + host, port.port, port.port_type, + socket_timeout=CONNECT_TIMEOUT, log_errors=True) except socket.gaierror: raise RuntimeError("Port check failed! Unable to resolve host name '%s'" % host) if port_open: diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index f85fa0d..f061e79 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -55,6 +55,12 @@ GEN_TMP_PWD_LEN = 12 # only for OTP password that is manually retyped by user +PROTOCOL_NAMES = { + socket.SOCK_STREAM: 'tcp', + socket.SOCK_DGRAM: 'udp' +} + + class UnsafeIPAddress(netaddr.IPAddress): """Any valid IP address with or without netmask.""" @@ -866,15 +872,21 @@ def user_input(prompt, default = None, allow_empty = True): return ret -def host_port_open(host, port, socket_type=socket.SOCK_STREAM, socket_timeout=None): +def host_port_open(host, port, socket_type=socket.SOCK_STREAM, + socket_timeout=None, log_errors=False): + """ + host: either hostname or IP address; + if hostname is provided, port MUST be open on ALL resolved IPs + + returns True is port is open, False otherwise + """ + port_open = True + + # port has to be open on ALL resolved IPs for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket_type): af, socktype, proto, _canonname, sa = res try: - try: - s = socket.socket(af, socktype, proto) - except socket.error: - s = None - continue + s = socket.socket(af, socktype, proto) if socket_timeout is not None: s.settimeout(socket_timeout) @@ -884,15 +896,27 @@ def host_port_open(host, port, socket_type=socket.SOCK_STREAM, socket_timeout=No if socket_type == socket.SOCK_DGRAM: s.send('') s.recv(512) - - return True except socket.error: - pass + port_open = False + + if log_errors: + msg = ('Failed to connect to port %(port)d %(proto)s on ' + '%(addr)s' % dict(port=port, + proto=PROTOCOL_NAMES[socket_type], + addr=sa[0])) + + # Do not log udp failures as errors (to be consistent with + # the rest of the code that checks for open ports) + if socket_type == socket.SOCK_DGRAM: + root_logger.warning(msg) + else: + root_logger.error(msg) finally: if s: s.close() + s = None - return False + return port_open def reverse_record_exists(ip_address):
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
