check: udp port reachability through nmap, pass getaddressinfo records where possible

This commit is contained in:
hexa- 2015-02-17 15:36:47 +01:00
parent 423c038a49
commit 52013714c9
3 changed files with 45 additions and 11 deletions

View file

@ -1,5 +1,10 @@
language: python language: python
python: "3.4" python: "3.4"
before_install:
before_install: sudo apt-get install iputils-ping - sudo apt-get install iputils-ping checkinstall
script: scripts/check -s ./hosts/ - wget https://www.linuxlounge.net/~martin/icvpn/nmap_6.47-1_amd64.deb
- sudo dpkg -i nmap_6.47-1_amd64.deb
install:
- pip install -r .travis_requirements.txt
script:
- sudo bash -c "source ~/virtualenv/python3.4/bin/activate && scripts/check -s ./hosts/"

1
.travis_requirements.txt Normal file
View file

@ -0,0 +1 @@
python-nmap

View file

@ -4,6 +4,7 @@ import sys
import os import os
import socket import socket
import subprocess import subprocess
import nmap
from optparse import OptionParser from optparse import OptionParser
@ -14,12 +15,15 @@ def error(*arg):
def check_host_lookup(hostname, port): def check_host_lookup(hostname, port):
try: try:
return socket.getaddrinfo(hostname, port) return socket.getaddrinfo(hostname, port)
except Exception as e: except Exception:
error("DNS Lookup for {hostname} failed".format(hostname=hostname)) error("DNS Lookup for {hostname} failed".format(hostname=hostname))
return [] return []
def check_reachability(host, family): def check_icmp_reachability(gai_record):
host = gai_record[4][0]
family = gai_record[0]
if family is socket.AddressFamily.AF_INET: if family is socket.AddressFamily.AF_INET:
process_name = 'ping' process_name = 'ping'
else: else:
@ -28,8 +32,27 @@ def check_reachability(host, family):
stdout=subprocess.PIPE) stdout=subprocess.PIPE)
child.communicate() child.communicate()
if child.returncode: if child.returncode:
error("Host {host} is unreachable".format(host=host)) error(" - {host} is icmp unreachable".format(host=host))
return 0 if child.returncode == 0 else 1 return True if child.returncode == 0 else False
def check_udp_reachability(gai_record):
host, port = gai_record[4][:2]
family = gai_record[0]
if family is socket.AddressFamily.AF_INET:
arguments = '-sU -PN'
else:
arguments = '-sU -PN -6'
scanner = nmap.PortScanner()
result = scanner.scan(host, str(port), arguments) # -sU requires root
state = result['scan'][host]['udp'][port]['state']
if state == 'closed':
print(" - {host} port {port}/udp is {state}"
.format(host=host, port=port, state=state))
return False if state == 'closed' else True
def get_hosts_data(srcdir): def get_hosts_data(srcdir):
@ -104,11 +127,16 @@ def do_checks(srcdir):
else: else:
for record in records: for record in records:
if record[1] is not socket.SocketType.SOCK_DGRAM: if record[1] is not socket.SocketType.SOCK_DGRAM:
# we get SOCK_STREAM, SOCK_DGRAM and SOCK_RAW # vpn connections are udp based, so skip
# for every IP/Port pair, lets just pick one # everything else
# to have unique ip addresses
continue continue
errcnt += check_reachability(record[4][0], record[0])
if not check_icmp_reachability(record):
errcnt += 1
else:
port_state = check_udp_reachability(record)
if not port_state:
errcnt += 1
print("{errcnt} errors".format(errcnt=errcnt)) print("{errcnt} errors".format(errcnt=errcnt))