def _netbsd_remotes_on(port, which_end): ''' Returns set of ipv4 host addresses of remote established connections on local tcp port port. Parses output of shell 'sockstat' (NetBSD) to get connections $ sudo sockstat -4 -n USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root python2.7 1456 29 tcp *.4505 *.* root python2.7 1445 17 tcp *.4506 *.* root python2.7 1294 14 tcp 127.0.0.1.11813 127.0.0.1.4505 root python2.7 1294 41 tcp 127.0.0.1.61115 127.0.0.1.4506 $ sudo sockstat -4 -c -n -p 4506 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root python2.7 1294 41 tcp 127.0.0.1.61115 127.0.0.1.4506 ''' port = int(port) remotes = set() try: cmd = salt.utils.shlex_split('sockstat -4 -c -n -p {0}'.format(port)) data = subprocess.check_output(cmd) # pylint: disable=minimum-python-version except subprocess.CalledProcessError as ex: log.error('Failed "sockstat" with returncode = {0}'.format( ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['root', 'python2.7', '1456', '37', 'tcp', # '127.0.0.1.4505-', '127.0.0.1.55703'] # print chunks if 'COMMAND' in chunks[1]: continue # ignore header if len(chunks) < 2: continue local = chunks[5].split('.') lport = local.pop() lhost = '.'.join(local) remote = chunks[6].split('.') rport = remote.pop() rhost = '.'.join(remote) if which_end == 'local' and int( lport) != port: # ignore if local port not port continue if which_end == 'remote' and int( rport) != port: # ignore if remote port not port continue remotes.add(rhost) return remotes
def _openbsd_remotes_on(port, which_end): ''' OpenBSD specific helper function. Returns set of ipv4 host addresses of remote established connections on local or remote tcp port. Parses output of shell 'netstat' to get connections $ netstat -nf inet Active Internet connections Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp 0 0 10.0.0.101.4505 10.0.0.1.45329 ESTABLISHED tcp 0 0 10.0.0.101.4505 10.0.0.100.50798 ESTABLISHED ''' remotes = set() try: data = subprocess.check_output(['netstat', '-nf', 'inet']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError: log.error('Failed netstat') raise lines = data.split('\n') for line in lines: if 'ESTABLISHED' not in line: continue chunks = line.split() local_host, local_port = chunks[3].rsplit('.', 1) remote_host, remote_port = chunks[4].rsplit('.', 1) if which_end == 'remote_port' and int(remote_port) != port: continue if which_end == 'local_port' and int(local_port) != port: continue remotes.add(remote_host) return remotes
def _freebsd_remotes_on(port, which_end): ''' Returns set of ipv4 host addresses of remote established connections on local tcp port port. Parses output of shell 'sockstat' (FreeBSD) to get connections $ sudo sockstat -4 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root python2.7 1456 29 tcp4 *:4505 *:* root python2.7 1445 17 tcp4 *:4506 *:* root python2.7 1294 14 tcp4 127.0.0.1:11813 127.0.0.1:4505 root python2.7 1294 41 tcp4 127.0.0.1:61115 127.0.0.1:4506 $ sudo sockstat -4 -c -p 4506 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root python2.7 1294 41 tcp4 127.0.0.1:61115 127.0.0.1:4506 ''' port = int(port) remotes = set() try: cmd = salt.utils.shlex_split('sockstat -4 -c -p {0}'.format(port)) data = subprocess.check_output(cmd) # pylint: disable=minimum-python-version except subprocess.CalledProcessError as ex: log.error('Failed "sockstat" with returncode = {0}'.format(ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['root', 'python2.7', '1456', '37', 'tcp4', # '127.0.0.1:4505-', '127.0.0.1:55703'] # print chunks if 'COMMAND' in chunks[1]: continue # ignore header if len(chunks) < 2: continue # sockstat -4 -c -p 4506 does this with high PIDs: # USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS # salt-master python2.781106 35 tcp4 192.168.12.34:4506 192.168.12.45:60143 local = chunks[-2] remote = chunks[-1] lhost, lport = local.split(':') rhost, rport = remote.split(':') if which_end == 'local' and int(lport) != port: # ignore if local port not port continue if which_end == 'remote' and int(rport) != port: # ignore if remote port not port continue remotes.add(rhost) return remotes
def _netbsd_remotes_on(port, which_end): ''' Returns set of ipv4 host addresses of remote established connections on local tcp port port. Parses output of shell 'sockstat' (NetBSD) to get connections $ sudo sockstat -4 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root python2.7 1456 29 tcp4 *.4505 *.* root python2.7 1445 17 tcp4 *.4506 *.* root python2.7 1294 14 tcp4 127.0.0.1.11813 127.0.0.1.4505 root python2.7 1294 41 tcp4 127.0.0.1.61115 127.0.0.1.4506 $ sudo sockstat -4 -c -p 4506 USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS root python2.7 1294 41 tcp4 127.0.0.1.61115 127.0.0.1.4506 ''' port = int(port) remotes = set() try: cmd = salt.utils.shlex_split('sockstat -4 -c -p {0}'.format(port)) data = subprocess.check_output(cmd) # pylint: disable=minimum-python-version except subprocess.CalledProcessError as ex: log.error('Failed "sockstat" with returncode = {0}'.format(ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['root', 'python2.7', '1456', '37', 'tcp4', # '127.0.0.1.4505-', '127.0.0.1.55703'] # print chunks if 'COMMAND' in chunks[1]: continue # ignore header if len(chunks) < 2: continue local = chunks[5].split('.') lport = local.pop() lhost = '.'.join(local) remote = chunks[6].split('.') rport = remote.pop() rhost = '.'.join(remote) if which_end == 'local' and int(lport) != port: # ignore if local port not port continue if which_end == 'remote' and int(rport) != port: # ignore if remote port not port continue remotes.add(rhost) return remotes
def _linux_remotes_on(port, which_end): ''' Linux specific helper function. Returns set of ip host addresses of remote established connections on local tcp port port. Parses output of shell 'lsof' to get connections $ sudo lsof -iTCP:4505 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Python 9971 root 35u IPv4 0x18a8464a29ca329d 0t0 TCP *:4505 (LISTEN) Python 9971 root 37u IPv4 0x18a8464a29b2b29d 0t0 TCP 127.0.0.1:4505->127.0.0.1:55703 (ESTABLISHED) Python 10152 root 22u IPv4 0x18a8464a29c8cab5 0t0 TCP 127.0.0.1:55703->127.0.0.1:4505 (ESTABLISHED) Python 10153 root 22u IPv4 0x18a8464a29c8cab5 0t0 TCP [fe80::249a]:4505->[fe80::150]:59367 (ESTABLISHED) ''' remotes = set() try: data = subprocess.check_output( ['lsof', '-iTCP:{0:d}'.format(port), '-n', '-P'] # pylint: disable=minimum-python-version ) except subprocess.CalledProcessError as ex: if ex.returncode == 1: # Lsof return 1 if any error was detected, including the failure # to locate Internet addresses, and it is not an error in this case. log.warning( '"lsof" returncode = 1, likely no active TCP sessions.') return remotes log.error('Failed "lsof" with returncode = {0}'.format(ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['Python', '9971', 'root', '37u', 'IPv4', '0x18a8464a29b2b29d', '0t0', # 'TCP', '127.0.0.1:4505->127.0.0.1:55703', '(ESTABLISHED)'] # print chunks if 'COMMAND' in chunks[0]: continue # ignore header if 'ESTABLISHED' not in chunks[-1]: continue # ignore if not ESTABLISHED # '127.0.0.1:4505->127.0.0.1:55703' local, remote = chunks[8].split('->') _, lport = local.rsplit(':', 1) rhost, rport = remote.rsplit(':', 1) if which_end == 'remote_port' and int(rport) != port: continue if which_end == 'local_port' and int(lport) != port: continue remotes.add(rhost.strip("[]")) return remotes
def show_config(jail): ''' Display specified jail's configuration CLI Example: .. code-block:: bash salt '*' jail.show_config <jail name> ''' ret = {} if subprocess.call(["jls", "-nq", "-j", jail]) == 0: jls = subprocess.check_output(["jls", "-nq", "-j", jail]) # pylint: disable=minimum-python-version jailopts = salt.utils.shlex_split(salt.utils.to_str(jls)) for jailopt in jailopts: if '=' not in jailopt: ret[jailopt.strip().rstrip(";")] = '1' else: key = jailopt.split('=')[0].strip() value = jailopt.split('=')[-1].strip().strip("\"") ret[key] = value else: for rconf in ('/etc/rc.conf', '/etc/rc.conf.local'): if os.access(rconf, os.R_OK): with salt.utils.fopen(rconf, 'r') as _fp: for line in _fp: if not line.strip(): continue if not line.startswith('jail_{0}_'.format(jail)): continue key, value = line.split('=') ret[key.split('_', 2)[2]] = value.split('"')[1] for jconf in ('/etc/jail.conf', '/usr/local/etc/jail.conf'): if os.access(jconf, os.R_OK): with salt.utils.fopen(jconf, 'r') as _fp: for line in _fp: line = line.partition('#')[0].strip() if line: if line.split()[-1] == '{': if line.split()[0] != jail and line.split( )[0] != '*': while line.split()[-1] != '}': line = next(_fp) line = line.partition('#')[0].strip() else: continue if line.split()[-1] == '}': continue if '=' not in line: ret[line.strip().rstrip(";")] = '1' else: key = line.split('=')[0].strip() value = line.split('=')[-1].strip().strip( ";'\"") ret[key] = value return ret
def _linux_remotes_on(port, which_end): ''' Linux specific helper function. Returns set of ip host addresses of remote established connections on local tcp port port. Parses output of shell 'lsof' to get connections $ sudo lsof -iTCP:4505 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Python 9971 root 35u IPv4 0x18a8464a29ca329d 0t0 TCP *:4505 (LISTEN) Python 9971 root 37u IPv4 0x18a8464a29b2b29d 0t0 TCP 127.0.0.1:4505->127.0.0.1:55703 (ESTABLISHED) Python 10152 root 22u IPv4 0x18a8464a29c8cab5 0t0 TCP 127.0.0.1:55703->127.0.0.1:4505 (ESTABLISHED) Python 10153 root 22u IPv4 0x18a8464a29c8cab5 0t0 TCP [fe80::249a]:4505->[fe80::150]:59367 (ESTABLISHED) ''' remotes = set() try: data = subprocess.check_output( ['lsof', '-iTCP:{0:d}'.format(port), '-n', '-P'] # pylint: disable=minimum-python-version ) except subprocess.CalledProcessError as ex: if ex.returncode == 1: # Lsof return 1 if any error was detected, including the failure # to locate Internet addresses, and it is not an error in this case. log.warning('"lsof" returncode = 1, likely no active TCP sessions.') return remotes log.error('Failed "lsof" with returncode = {0}'.format(ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['Python', '9971', 'root', '37u', 'IPv4', '0x18a8464a29b2b29d', '0t0', # 'TCP', '127.0.0.1:4505->127.0.0.1:55703', '(ESTABLISHED)'] # print chunks if 'COMMAND' in chunks[0]: continue # ignore header if 'ESTABLISHED' not in chunks[-1]: continue # ignore if not ESTABLISHED # '127.0.0.1:4505->127.0.0.1:55703' local, remote = chunks[8].split('->') _, lport = local.rsplit(':', 1) rhost, rport = remote.rsplit(':', 1) if which_end == 'remote_port' and int(rport) != port: continue if which_end == 'local_port' and int(lport) != port: continue remotes.add(rhost.strip("[]")) return remotes
def remotes_on_local_tcp_port(port): ''' Returns set of ipv4 host addresses of remote established connections on local tcp port port. Parses output of shell 'lsof' to get connections $ sudo lsof -i4TCP:4505 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Python 9971 root 35u IPv4 0x18a8464a29ca329d 0t0 TCP *:4505 (LISTEN) Python 9971 root 37u IPv4 0x18a8464a29b2b29d 0t0 TCP 127.0.0.1:4505->127.0.0.1:55703 (ESTABLISHED) Python 10152 root 22u IPv4 0x18a8464a29c8cab5 0t0 TCP 127.0.0.1:55703->127.0.0.1:4505 (ESTABLISHED) ''' port = int(port) remotes = set() if salt.utils.is_sunos(): return _sunos_remotes_on(port, 'local_port') if salt.utils.is_freebsd(): return _freebsd_remotes_on(port, 'local_port') if salt.utils.is_openbsd(): return _openbsd_remotes_on(port, 'local_port') if salt.utils.is_windows(): return _windows_remotes_on(port, 'local_port') try: data = subprocess.check_output( ['lsof', '-i4TCP:{0:d}'.format(port), '-n']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError as ex: log.error('Failed "lsof" with returncode = {0}'.format(ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['Python', '9971', 'root', '37u', 'IPv4', '0x18a8464a29b2b29d', '0t0', # 'TCP', '127.0.0.1:4505->127.0.0.1:55703', '(ESTABLISHED)'] #print chunks if 'COMMAND' in chunks[0]: continue # ignore header if 'ESTABLISHED' not in chunks[-1]: continue # ignore if not ESTABLISHED # '127.0.0.1:4505->127.0.0.1:55703' local, remote = chunks[8].split('->') lhost, lport = local.split(':') if int(lport) != port: # ignore if local port not port continue rhost, rport = remote.split(':') remotes.add(rhost) return remotes
def remotes_on_local_tcp_port(port): ''' Returns set of ipv4 host addresses of remote established connections on local tcp port port. Parses output of shell 'lsof' to get connections $ sudo lsof -i4TCP:4505 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Python 9971 root 35u IPv4 0x18a8464a29ca329d 0t0 TCP *:4505 (LISTEN) Python 9971 root 37u IPv4 0x18a8464a29b2b29d 0t0 TCP 127.0.0.1:4505->127.0.0.1:55703 (ESTABLISHED) Python 10152 root 22u IPv4 0x18a8464a29c8cab5 0t0 TCP 127.0.0.1:55703->127.0.0.1:4505 (ESTABLISHED) ''' port = int(port) remotes = set() if salt.utils.is_sunos(): return _sunos_remotes_on(port, 'local_port') if salt.utils.is_freebsd(): return _freebsd_remotes_on(port, 'local_port') if salt.utils.is_openbsd(): return _openbsd_remotes_on(port, 'local_port') if salt.utils.is_windows(): return _windows_remotes_on(port, 'local_port') try: data = subprocess.check_output(['lsof', '-i4TCP:{0:d}'.format(port), '-n']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError as ex: log.error('Failed "lsof" with returncode = {0}'.format(ex.returncode)) raise lines = salt.utils.to_str(data).split('\n') for line in lines: chunks = line.split() if not chunks: continue # ['Python', '9971', 'root', '37u', 'IPv4', '0x18a8464a29b2b29d', '0t0', # 'TCP', '127.0.0.1:4505->127.0.0.1:55703', '(ESTABLISHED)'] #print chunks if 'COMMAND' in chunks[0]: continue # ignore header if 'ESTABLISHED' not in chunks[-1]: continue # ignore if not ESTABLISHED # '127.0.0.1:4505->127.0.0.1:55703' local, remote = chunks[8].split('->') lhost, lport = local.split(':') if int(lport) != port: # ignore if local port not port continue rhost, rport = remote.split(':') remotes.add(rhost) return remotes
def show_config(jail): ''' Display specified jail's configuration CLI Example: .. code-block:: bash salt '*' jail.show_config <jail name> ''' ret = {} if subprocess.call(["jls", "-nq", "-j", jail]) == 0: jls = subprocess.check_output(["jls", "-nq", "-j", jail]) # pylint: disable=minimum-python-version jailopts = shlex.split(jls) for jailopt in jailopts: if '=' not in jailopt: ret[jailopt.strip().rstrip(";")] = '1' else: key = jailopt.split('=')[0].strip() value = jailopt.split('=')[-1].strip().strip("\"") ret[key] = value else: for rconf in ('/etc/rc.conf', '/etc/rc.conf.local'): if os.access(rconf, os.R_OK): with salt.utils.fopen(rconf, 'r') as _fp: for line in _fp: if not line.strip(): continue if not line.startswith('jail_{0}_'.format(jail)): continue key, value = line.split('=') ret[key.split('_', 2)[2]] = value.split('"')[1] for jconf in ('/etc/jail.conf', '/usr/local/etc/jail.conf'): if os.access(jconf, os.R_OK): with salt.utils.fopen(jconf, 'r') as _fp: for line in _fp: line = line.partition('#')[0].strip() if line: if line.split()[-1] == '{': if line.split()[0] != jail and line.split()[0] != '*': while line.split()[-1] != '}': line = next(_fp) line = line.partition('#')[0].strip() else: continue if line.split()[-1] == '}': continue if '=' not in line: ret[line.strip().rstrip(";")] = '1' else: key = line.split('=')[0].strip() value = line.split('=')[-1].strip().strip(";'\"") ret[key] = value return ret
def _aix_remotes_on(port, which_end): ''' AIX specific helper function. Returns set of ipv4 host addresses of remote established connections on local or remote tcp port. Parses output of shell 'netstat' to get connections root@la68pp002_pub:/opt/salt/lib/python2.7/site-packages/salt/modules# netstat -f inet -n Active Internet connections Proto Recv-Q Send-Q Local Address Foreign Address (state) tcp4 0 0 172.29.149.95.50093 209.41.78.13.4505 ESTABLISHED tcp4 0 0 127.0.0.1.9514 *.* LISTEN tcp4 0 0 127.0.0.1.9515 *.* LISTEN tcp4 0 0 127.0.0.1.199 127.0.0.1.32779 ESTABLISHED tcp4 0 0 127.0.0.1.32779 127.0.0.1.199 ESTABLISHED tcp4 0 40 172.29.149.95.22 172.29.96.83.41022 ESTABLISHED tcp4 0 0 172.29.149.95.22 172.29.96.83.41032 ESTABLISHED tcp4 0 0 127.0.0.1.32771 127.0.0.1.32775 ESTABLISHED tcp 0 0 127.0.0.1.32775 127.0.0.1.32771 ESTABLISHED tcp4 0 0 127.0.0.1.32771 127.0.0.1.32776 ESTABLISHED tcp 0 0 127.0.0.1.32776 127.0.0.1.32771 ESTABLISHED tcp4 0 0 127.0.0.1.32771 127.0.0.1.32777 ESTABLISHED tcp 0 0 127.0.0.1.32777 127.0.0.1.32771 ESTABLISHED tcp4 0 0 127.0.0.1.32771 127.0.0.1.32778 ESTABLISHED tcp 0 0 127.0.0.1.32778 127.0.0.1.32771 ESTABLISHED ''' remotes = set() try: data = subprocess.check_output(['netstat', '-f', 'inet', '-n']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError: log.error('Failed netstat') raise lines = salt.utils.to_str(data).split('\n') for line in lines: if 'ESTABLISHED' not in line: continue chunks = line.split() local_host, local_port = chunks[3].rsplit('.', 1) remote_host, remote_port = chunks[4].rsplit('.', 1) if which_end == 'remote_port' and int(remote_port) != port: continue if which_end == 'local_port' and int(local_port) != port: continue remotes.add(remote_host) return remotes
def _windows_remotes_on(port, which_end): r''' Windows specific helper function. Returns set of ipv4 host addresses of remote established connections on local or remote tcp port. Parses output of shell 'netstat' to get connections C:\>netstat -n Active Connections Proto Local Address Foreign Address State TCP 10.2.33.17:3007 130.164.12.233:10123 ESTABLISHED TCP 10.2.33.17:3389 130.164.30.5:10378 ESTABLISHED ''' remotes = set() try: data = subprocess.check_output(['netstat', '-n']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError: log.error('Failed netstat') raise lines = salt.utils.to_str(data).split('\n') for line in lines: if 'ESTABLISHED' not in line: continue chunks = line.split() local_host, local_port = chunks[1].rsplit(':', 1) remote_host, remote_port = chunks[2].rsplit(':', 1) if which_end == 'remote_port' and int(remote_port) != port: continue if which_end == 'local_port' and int(local_port) != port: continue remotes.add(remote_host) return remotes
def _sunos_remotes_on(port, which_end): ''' SunOS specific helper function. Returns set of ipv4 host addresses of remote established connections on local or remote tcp port. Parses output of shell 'netstat' to get connections [root@salt-master ~]# netstat -f inet -n TCP: IPv4 Local Address Remote Address Swind Send-Q Rwind Recv-Q State -------------------- -------------------- ----- ------ ----- ------ ----------- 10.0.0.101.4505 10.0.0.1.45329 1064800 0 1055864 0 ESTABLISHED 10.0.0.101.4505 10.0.0.100.50798 1064800 0 1055864 0 ESTABLISHED ''' remotes = set() try: data = subprocess.check_output(['netstat', '-f', 'inet', '-n']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError: log.error('Failed netstat') raise lines = salt.utils.to_str(data).split('\n') for line in lines: if 'ESTABLISHED' not in line: continue chunks = line.split() local_host, local_port = chunks[0].rsplit('.', 1) remote_host, remote_port = chunks[1].rsplit('.', 1) if which_end == 'remote_port' and int(remote_port) != port: continue if which_end == 'local_port' and int(local_port) != port: continue remotes.add(remote_host) return remotes
def _win_remotes_on(port): ''' Windows specific helper function. Returns set of ipv4 host addresses of remote established connections on local or remote tcp port. Parses output of shell 'netstat' to get connections PS C:> netstat -n -p TCP Active Connections Proto Local Address Foreign Address State TCP 10.1.1.26:3389 10.1.1.1:4505 ESTABLISHED TCP 10.1.1.26:56862 10.1.1.10:49155 TIME_WAIT TCP 10.1.1.26:56868 169.254.169.254:80 CLOSE_WAIT TCP 127.0.0.1:49197 127.0.0.1:49198 ESTABLISHED TCP 127.0.0.1:49198 127.0.0.1:49197 ESTABLISHED ''' remotes = set() try: data = subprocess.check_output(['netstat', '-n', '-p', 'TCP']) # pylint: disable=minimum-python-version except subprocess.CalledProcessError: log.error('Failed netstat') raise lines = salt.utils.to_str(data).split('\n') for line in lines: if 'ESTABLISHED' not in line: continue chunks = line.split() remote_host, remote_port = chunks[2].rsplit(':', 1) if int(remote_port) != port: continue remotes.add(remote_host) return remotes