4 A Nagios plugin for checking whether or not an OpenVPN server is
7 We don't actually interact with the OpenVPN server; we merely send it
8 a a magic (heretofore unexplained) byte sequence and ensure that we
9 get some kind of response.
12 from argparse
import ArgumentDefaultsHelpFormatter
, ArgumentParser
13 from datetime
import datetime
16 # Define a few exit codes.
20 parser
= ArgumentParser(description
= __doc__
,
21 formatter_class
= ArgumentDefaultsHelpFormatter
)
23 # Required positional argument.
24 parser
.add_argument('host',
28 parser
.add_argument('-p',
32 help='port number to check')
34 parser
.add_argument('-t',
38 help='use TCP instead of the default UDP')
40 parser
.add_argument('-w',
44 help='set the timeout (in seconds)')
46 parser
.add_argument('-v',
49 help='produce more verbose output')
51 args
= parser
.parse_args()
53 proto
= (socket
.SOCK_DGRAM
, 'udp')
55 proto
= (socket
.SOCK_STREAM
, 'tcp')
58 print("Checking %s:%d (%s)" % (args
.host
, args
.port
, proto
[1]))
60 sock
= socket
.socket(socket
.AF_INET
, proto
[0])
62 # Default to success, change it if anything fails.
66 sock
.settimeout(args
.timeout
)
67 time_start
= datetime
.now()
68 sock
.connect((args
.host
, args
.port
))
70 # This is a magic byte sequence, most likely obtained from a packet
71 # capture. Connections without a TLS auth key will actually return a
72 # response when we send this; however, secured connections will not
73 # (although nothing will fail).
77 # http://serverfault.com/questions/262474
79 magic
= b
"\x38\x01\x00\x00\x00\x00\x00\x00\x00"
82 # If the server uses a TLS auth key, the response will be empty
83 # but at least it will come, preventing a timeout.
84 reply
= sock
.recv(100)
85 time_end
= datetime
.now()
88 # This will be gibberish, but at least you can see that the
89 # server spit something out.
90 hex_reply
= ''.join(['%02x' % ord(byte
) for byte
in reply
])
91 print('Received(hex): %s' % hex_reply
)
93 time_elapsed
= time_end
- time_start
94 print('OK %.3fms' % (time_elapsed
.total_seconds() * 1000))
96 except socket
.timeout
as e
:
97 print('ERROR: connection timed out (%d seconds)' % args
.timeout
)
98 status
= EXIT_CRITICAL
100 except socket
.gaierror
as e
:
101 print('ERROR: ', str(e
.args
[1]))
102 status
= EXIT_CRITICAL
104 except Exception as e
:
105 print('ERROR: ', str(e
))
106 status
= EXIT_CRITICAL