aboutsummaryrefslogtreecommitdiff
path: root/plugins/check_openvpn_status
blob: f049ef75d43a68127d57f9c160e5b44c570bd58b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python3

# Check openvpn-status.log
# needs status-version 3 set in ovpn config!

import json
import datetime
import dateutil.parser
import sys
import argparse

class Status:
    OK = 0
    WARNING = 1
    CRITICAL = 2
    UNKNOWN = 3

    @staticmethod
    def toString(status):
        return (['OK', 'WARNING', 'CRITICAL', 'UNKNOWN'])[status]

def print_perfdata(perfdata):
    print('|' ,end='')
    for d in perfdata:
        print(f'{d}={perfdata[d]}', end=' ')

def set_status(status):
    if status > STATUS:
        return status
    return STATUS

parser = argparse.ArgumentParser(description='check openvpn-status.log')
parser.add_argument(dest='logfile')
parser.add_argument('-c', dest='max_conns', action='store', type=int, default=0)
parser.add_argument('-u', dest='max_conns_per_user', action='store', type=int, default=0)
parser.add_argument('-t', dest='traffic', action='store_true')

args=parser.parse_args()

STATUS = Status.OK
STATUS_STRINGS = []

FILE = args.logfile

DATA={}
PERFDATA={}

file_lines=[]

with open(FILE, 'r') as f:
    file_lines = f.readlines()

for l in file_lines:
    line_elements = l.split('\t')

    title = line_elements[0].strip()

    if title not in DATA:
        DATA[title] = []

    DATA[title].append(list(map(lambda x: x.strip(), line_elements[1:])))

now = datetime.datetime.now()
status_time = dateutil.parser.parse(DATA['TIME'][0][0])
status_age = int((now-status_time).total_seconds())

PERFDATA['statusage'] = status_age
if status_age > 120:
    STATUS = set_status(Status.UNKNOWN)
    STATUS_STRINGS.append(f'Statusfile is {status_age} seconds old. This should be no more than 60.')

if 'CLIENT_LIST' not in DATA:
    DATA['CLIENT_LIST'] = []

if args.max_conns > 0:
    clients = ', '.join(list(map(lambda x: x[0], DATA['CLIENT_LIST'])))
    clients_cnt = len(DATA['CLIENT_LIST'])

    if clients_cnt >= args.max_conns:
        STATUS = set_status(Status.CRITICAL)
    elif clients_cnt >= (args.max_conns * 0.9):
        STATUS = set_status(Status.WARNING)

    PERFDATA['clients_cnt'] = f'{clients_cnt};{int(args.max_conns*0.9)};{args.max_conns}'
    STATUS_STRINGS.append(f'{clients_cnt} clients logged in ({clients})')


if args.max_conns_per_user > 0:
    user_cnts = {}

    for u in DATA['CLIENT_LIST']:
        uname = u[8]
        if uname in user_cnts:
            user_cnts[uname] += 1
        else:
            user_cnts[uname] = 1

    for u in user_cnts:
        if user_cnts[u] >= args.max_conns_per_user:
            STATUS = set_status(Status.CRITICAL)
        if user_cnts[u] >= (args.max_conns_per_user * 0.8):
            STATUS = set_status(Status.WARNING)
            STATUS_STRINGS.append(f'{u} is logged in {user_cnts[u]} times')
            PERFDATA[f'user_{u}'] = f'{user_cnts[u]};{int(args.max_conns_per_user * 0.8)};{int(args.max_conns_per_user)}'

if args.traffic:
    recv_cnt = 0
    sent_cnt = 0

    for u in DATA['CLIENT_LIST']:
        recv_cnt += int(u[4])
        sent_cnt += int(u[5])

    PERFDATA['recieved_bytes'] = f'{recv_cnt}B'
    PERFDATA['sent_bytes'] = f'{sent_cnt}B'

print(f'OpenVPN {Status.toString(STATUS)}')
for s in STATUS_STRINGS:
    print(s)

print_perfdata(PERFDATA)