From 6af6c5412acce8889c65da8be33c65f2244a82e6 Mon Sep 17 00:00:00 2001 From: Jan Wagner Date: Fri, 23 Dec 2016 23:20:59 +0100 Subject: [PATCH] check_openvpn: Update to 20160803 --- check_openvpn/check_openvpn | 89 ++++++++++++++++++++++--------------- check_openvpn/control | 2 +- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/check_openvpn/check_openvpn b/check_openvpn/check_openvpn index d851939..b1e5c1b 100644 --- a/check_openvpn/check_openvpn +++ b/check_openvpn/check_openvpn @@ -1,10 +1,11 @@ -#! /usr/bin/python +#!/usr/bin/env python -# Check if an OpenVPN server runs on a given UDP port. +# Check if an OpenVPN server runs on a given UDP or TCP port. # # Copyright 2013 Roland Wolters +# Copyright 2016 Alarig Le Lay # -# Version 20151106 +# Version 20160803 # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -26,6 +27,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import os +import sys import time import hmac import hashlib @@ -37,32 +39,35 @@ import binascii HMAC_CLIENT_KEY_START = 192 BUFFER_SIZE = 1024 +ALGORITHMS_AVAILABLE = hashlib.algorithms_available \ + if hasattr(hashlib, "algorithms_available") else hashlib.algorithms + def ok(msg): - print 'OK: %s' % msg + print('OK: %s' % msg) return 0 def critical(msg): - print 'CRIT: %s' % msg + print('CRIT: %s' % msg) return 2 def buildpacket(tcp, key, digestmod): packet = 1 ts = int(time.time()) session = os.urandom(8) - + if key: # hmac h = hmac.new(key, digestmod=digestmod) h.update(struct.pack('>I', packet)) # packet id h.update(struct.pack('>I', ts)) # net time - h.update('\x38') # type + h.update(b'\x38') # type h.update(session) # session id h.update(struct.pack('>B', 0)) # message packet id array length h.update(struct.pack('>I', 0)) # message packet id - + # packet - result = '' - result += '\x38' # type + result = b'' + result += b'\x38' # type result += session # session id if key: result += h.digest() # hmac result += struct.pack('>I', packet) # packet id @@ -74,13 +79,19 @@ def buildpacket(tcp, key, digestmod): def checkserver(host, port, tcp, timeout, key, digest): packet = buildpacket(tcp, key, digest) - if tcp: checkserver_tcp(host, port, timeout, packet) - else: checkserver_udp(host, port, timeout, packet) + check = checkserver_tcp if tcp else checkserver_udp + return check(host, port, timeout, packet) def checkserver_udp(host, port, timeout, packet): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.settimeout(timeout) - + # thanks to glucas for the idea + try: + af, socktype, proto, canonname, sa = socket.getaddrinfo(host, port, \ + socket.AF_UNSPEC, socket.SOCK_DGRAM)[0] + s = socket.socket(af, socktype, proto) + s.settimeout(timeout) + except socket.error: + return critical('Unable to create UDP socket') + try: s.sendto(packet, (host, port)) data, _ = s.recvfrom(BUFFER_SIZE) @@ -92,9 +103,14 @@ def checkserver_udp(host, port, timeout, packet): s.close() def checkserver_tcp(host, port, timeout, packet): - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.settimeout(timeout) - + try: + af, socktype, proto, canonname, sa = socket.getaddrinfo(host, port, \ + socket.AF_UNSPEC, socket.SOCK_STREAM)[0] + s = socket.socket(af, socktype, proto) + s.settimeout(timeout) + except socket.error: + return critical('Unable to create TCP socket') + try: s.connect((host, port)) s.send(packet) @@ -121,49 +137,50 @@ def readkey(path): key = key[index_start:index_end].replace('\n', '').replace('\r', '') return key -def optionsparser(args=None): +def optionsparser(argv=None): parser = argparse.ArgumentParser() - parser.add_argument('-p', '--port', help='set port number (default is %%default)', type=int, dest='port', default='1194') + parser.add_argument('-p', '--port', help='set port number (default is %(default)d)', type=int, default=1194) parser.add_argument('-t', '--tcp', help='use tcp instead of udp', action='store_true') - parser.add_argument('--timeout', help='set timeout (default is %%default)', type=int, default='5') - parser.add_argument('--digest', help='set HMAC digest (default is %%default)', type=str, default='sha1') + parser.add_argument('--timeout', help='set timeout (default is %(default)d)', type=int, default=5) + parser.add_argument('--digest', help='set HMAC digest (default is "%(default)s")', default='sha1') parser.add_argument('--digest-size', help='set HMAC digest size', type=int) - parser.add_argument('--digest-key', help='set HMAC key', type=str, default=None) - parser.add_argument('--tls-auth', help='set tls-auth file', type=str, default=None) - parser.add_argument('host', type=str, help='the OpenVPN host name or ip') - return parser.parse_args(args) + parser.add_argument('--digest-key', help='set HMAC key') + parser.add_argument('--tls-auth', help='set tls-auth file') + parser.add_argument('host', help='the OpenVPN host name or IP') + return parser.parse_args(argv) + +def main(argv=None): + args = optionsparser(argv) -def main(): - args = optionsparser() - if args.digest_size and args.digest_size < 0: critical('digest size must be positive') if args.tls_auth and args.digest_key: critical('--tls-auth cannot go with --digest-key') - + key = args.digest_key digest = args.digest digest_size = args.digest_size - + digest = digest.lower() - if digest not in hashlib.algorithms: + if digest not in ALGORITHMS_AVAILABLE: return critical('digest not available') try: digest = getattr(hashlib, digest) if not digest_size: digest_size = digest().digest_size except: return critical('digest creation failed') - + if args.tls_auth: key = readkey(args.tls_auth) if key == None: return critical('cannot read tls auth file') index_start = HMAC_CLIENT_KEY_START * 2 index_end = (HMAC_CLIENT_KEY_START + digest_size) * 2 key = key[index_start:index_end] - + if key: key = binascii.unhexlify(key) - + return checkserver(args.host, args.port, args.tcp, args.timeout, key, digest) if __name__ == '__main__': - main() + code = main() + sys.exit(code) diff --git a/check_openvpn/control b/check_openvpn/control index b9c8a42..b20d560 100644 --- a/check_openvpn/control +++ b/check_openvpn/control @@ -1,6 +1,6 @@ Homepage: https://raw.github.com/liquidat/nagios-icinga-checks/master/check_openvpn Watch: https://raw.github.com/liquidat/nagios-icinga-checks/master/check_openvpn Version\ ([0-9.]+) Recommends: libpython-stdlib -Version: 20151106 +Version: 20160803 Uploaders: Jan Wagner Description: plugin to check if an OpenVPN server runs on a given port