generated from pavel.muhortov/template-bash
some shell scripts replaced ovpn_status.py
This commit is contained in:
parent
70a9dd0106
commit
36869d518b
597
OpenVPN_by_Zabbix_agent.yaml
Normal file
597
OpenVPN_by_Zabbix_agent.yaml
Normal file
|
@ -0,0 +1,597 @@
|
||||||
|
zabbix_export:
|
||||||
|
version: '6.0'
|
||||||
|
date: '2023-07-27T10:47:37Z'
|
||||||
|
groups:
|
||||||
|
-
|
||||||
|
uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6
|
||||||
|
name: Templates/Applications
|
||||||
|
templates:
|
||||||
|
-
|
||||||
|
uuid: c3272861e3ff46e2b3daa302066c53c7
|
||||||
|
template: 'OpenVPN by Zabbix agent'
|
||||||
|
name: 'OpenVPN by Zabbix agent'
|
||||||
|
description: 'OpenVPN by Zabbix agent'
|
||||||
|
groups:
|
||||||
|
-
|
||||||
|
name: Templates/Applications
|
||||||
|
items:
|
||||||
|
-
|
||||||
|
uuid: 51151af0bb704668a1bb3b390cee2039
|
||||||
|
name: 'OpenVPN stats'
|
||||||
|
key: discovery.ovpn
|
||||||
|
history: 14d
|
||||||
|
trends: '0'
|
||||||
|
value_type: TEXT
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: raw
|
||||||
|
-
|
||||||
|
uuid: 877b2f94cd4645fcaae13543f42d79be
|
||||||
|
name: 'OpenVPN clients limit'
|
||||||
|
key: ovpn.clients.limit
|
||||||
|
delay: 1h
|
||||||
|
history: 14d
|
||||||
|
units: client
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN server'
|
||||||
|
value: 'clients limit'
|
||||||
|
-
|
||||||
|
uuid: 00c5526a838e4f7791b4edafc20bb094
|
||||||
|
name: 'OpenVPN expiration ca'
|
||||||
|
key: ovpn.expiration.ca
|
||||||
|
delay: 1h
|
||||||
|
history: 14d
|
||||||
|
units: s
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN server'
|
||||||
|
value: expiration
|
||||||
|
triggers:
|
||||||
|
-
|
||||||
|
uuid: 34fbc5a346d0458c8e529b92f0aa39c5
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.ca,#1)<86400'
|
||||||
|
name: 'OpenVPN ca certificate expires in 1 day'
|
||||||
|
priority: DISASTER
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 016c7d7c40b342c883ff81d0a5817b75
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.ca,#1)<604800'
|
||||||
|
name: 'OpenVPN ca certificate expires in 7 days'
|
||||||
|
priority: HIGH
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 2d9f9da08348499ab9b7584a9386abfc
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.ca,#1)<2592000'
|
||||||
|
name: 'OpenVPN ca certificate expires in 30 days'
|
||||||
|
priority: AVERAGE
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 65912ffeb36a4b2c8bae996c0b865f69
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.ca,#1)<7776000'
|
||||||
|
name: 'OpenVPN ca certificate expires in 90 days'
|
||||||
|
priority: WARNING
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 591d03b0553645788c5b178670cb8bc9
|
||||||
|
name: 'OpenVPN expiration cert'
|
||||||
|
key: ovpn.expiration.cert
|
||||||
|
delay: 1h
|
||||||
|
history: 14d
|
||||||
|
units: s
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN server'
|
||||||
|
value: expiration
|
||||||
|
triggers:
|
||||||
|
-
|
||||||
|
uuid: 6a2bc06ed9944e95bfdec45af330bd53
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.cert,#1)<86400'
|
||||||
|
name: 'OpenVPN cert certificate expires in 1 day'
|
||||||
|
priority: DISASTER
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: da6ae766472541e8addb2712584289c7
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.cert,#1)<604800'
|
||||||
|
name: 'OpenVPN cert certificate expires in 7 days'
|
||||||
|
priority: HIGH
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 5571d2aa00a2479889bdd853b37d7160
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.cert,#1)<2592000'
|
||||||
|
name: 'OpenVPN cert certificate expires in 30 days'
|
||||||
|
priority: AVERAGE
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 083b3ed043db4d209b093056c04605c3
|
||||||
|
expression: 'last(/OpenVPN by Zabbix agent/ovpn.expiration.cert,#1)<7776000'
|
||||||
|
name: 'OpenVPN cert certificate expires in 90 days'
|
||||||
|
priority: WARNING
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: expiration
|
||||||
|
-
|
||||||
|
uuid: 5ba0b1d455444ec8851c4cdda408ed24
|
||||||
|
name: 'Clients count'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: ovpn.stats.clients_count
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
units: clients
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- $.clients_count
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: 'clients count'
|
||||||
|
-
|
||||||
|
uuid: 731f61d192f944769aaf82c2fb05676b
|
||||||
|
name: 'Clients found'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: ovpn.stats.clients_found
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
units: clients
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- $.clients_found
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: 'clients found'
|
||||||
|
-
|
||||||
|
uuid: f38e82ba64f14385bd60a1397eda278c
|
||||||
|
name: 'Stats updated'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: ovpn.stats.updated
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
trends: '0'
|
||||||
|
value_type: TEXT
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- $.stats_updated
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: updated
|
||||||
|
discovery_rules:
|
||||||
|
-
|
||||||
|
uuid: f6b3ac3373544c1f820c207234177816
|
||||||
|
name: 'Discovery openvpn clients'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: get.ovpn.stats
|
||||||
|
delay: '0'
|
||||||
|
item_prototypes:
|
||||||
|
-
|
||||||
|
uuid: fc55509717fc4ee7bef6f684932ee01a
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" bytes recieved'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: 'ovpn.client.b_rx.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
units: B
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- '$.data.[?(@.name=="{#OVPN_CLIENT_NAME}")].b_rx.first()'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN client'
|
||||||
|
value: '{#OVPN_CLIENT_NAME}'
|
||||||
|
-
|
||||||
|
uuid: e75ed01ce6cd45e0822e021f6733b115
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" bytes transmitted'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: 'ovpn.client.b_tx.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
units: B
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- '$.data.[?(@.name=="{#OVPN_CLIENT_NAME}")].b_tx.first()'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN client'
|
||||||
|
value: '{#OVPN_CLIENT_NAME}'
|
||||||
|
-
|
||||||
|
uuid: 332feedbbd314a479ba27d43c7bb7523
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" real ip'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: 'ovpn.client.r_ip.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
trends: '0'
|
||||||
|
value_type: TEXT
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- '$.data.[?(@.name=="{#OVPN_CLIENT_NAME}")].r_ip.first()'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN client'
|
||||||
|
value: '{#OVPN_CLIENT_NAME}'
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: 'real ip'
|
||||||
|
-
|
||||||
|
uuid: 0dc7671cdc9b47c6a7c06b47a8de25ca
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" connect duration'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: 'ovpn.client.t_cd.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
units: s
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- '$.data.[?(@.name=="{#OVPN_CLIENT_NAME}")].t_cd.first()'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN client'
|
||||||
|
value: '{#OVPN_CLIENT_NAME}'
|
||||||
|
-
|
||||||
|
uuid: 127fd46950194d9ba5325f183cb6e940
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" connect time'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: 'ovpn.client.t_cs.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
trends: '0'
|
||||||
|
value_type: TEXT
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- '$.data.[?(@.name=="{#OVPN_CLIENT_NAME}")].t_cs.first()'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN client'
|
||||||
|
value: '{#OVPN_CLIENT_NAME}'
|
||||||
|
-
|
||||||
|
uuid: 2bb9be1dd4a041b09e68f7e9022676d4
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" virtual ip'
|
||||||
|
type: DEPENDENT
|
||||||
|
key: 'ovpn.client.v_ip.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
delay: '0'
|
||||||
|
history: 14d
|
||||||
|
trends: '0'
|
||||||
|
value_type: TEXT
|
||||||
|
preprocessing:
|
||||||
|
-
|
||||||
|
type: JSONPATH
|
||||||
|
parameters:
|
||||||
|
- '$.data.[?(@.name=="{#OVPN_CLIENT_NAME}")].v_ip.first()'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN client'
|
||||||
|
value: '{#OVPN_CLIENT_NAME}'
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN stats'
|
||||||
|
value: 'virtual ip'
|
||||||
|
graph_prototypes:
|
||||||
|
-
|
||||||
|
uuid: 0e740374d0d7435990fba99d19211947
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" connect duration'
|
||||||
|
show_work_period: 'NO'
|
||||||
|
show_triggers: 'NO'
|
||||||
|
graph_items:
|
||||||
|
-
|
||||||
|
color: FFBF00
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: 'ovpn.client.t_cd.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
-
|
||||||
|
uuid: 48b62a9621c64082919a6e041defc546
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" traffic'
|
||||||
|
graph_items:
|
||||||
|
-
|
||||||
|
drawtype: GRADIENT_LINE
|
||||||
|
color: 00FF00
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: 'ovpn.client.b_rx.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
-
|
||||||
|
sortorder: '1'
|
||||||
|
drawtype: BOLD_LINE
|
||||||
|
color: 0080FF
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: 'ovpn.client.b_tx.name[{#OVPN_CLIENT_NAME}]'
|
||||||
|
master_item:
|
||||||
|
key: discovery.ovpn
|
||||||
|
lld_macro_paths:
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_NAME}'
|
||||||
|
path: $..name.first()
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_R_IP}'
|
||||||
|
path: $..r_ip.first()
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_V_IP}'
|
||||||
|
path: $..v_ip.first()
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_B_RX}'
|
||||||
|
path: $..b_rx.first()
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_B_TX}'
|
||||||
|
path: $..b_tx.first()
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_T_CS}'
|
||||||
|
path: $..t_cs.first()
|
||||||
|
-
|
||||||
|
lld_macro: '{#OVPN_CLIENT_T_CD}'
|
||||||
|
path: $..t_cd.first()
|
||||||
|
dashboards:
|
||||||
|
-
|
||||||
|
uuid: d25222f632c74c83ac80c8cbce480db0
|
||||||
|
name: OpenVPN
|
||||||
|
auto_start: 'NO'
|
||||||
|
pages:
|
||||||
|
-
|
||||||
|
name: Server
|
||||||
|
widgets:
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
width: '5'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
name: itemid
|
||||||
|
value:
|
||||||
|
key: ovpn.expiration.ca
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
x: '6'
|
||||||
|
width: '5'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
name: itemid
|
||||||
|
value:
|
||||||
|
key: ovpn.expiration.cert
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
type: GRAPH_CLASSIC
|
||||||
|
'y': '2'
|
||||||
|
width: '11'
|
||||||
|
height: '5'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: GRAPH
|
||||||
|
name: graphid
|
||||||
|
value:
|
||||||
|
name: 'OpenVPN certificates expiration'
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
name: Clients
|
||||||
|
widgets:
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
width: '5'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
name: itemid
|
||||||
|
value:
|
||||||
|
key: ovpn.stats.clients_count
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
x: '6'
|
||||||
|
width: '5'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: ITEM
|
||||||
|
name: itemid
|
||||||
|
value:
|
||||||
|
key: ovpn.stats.clients_found
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
type: GRAPH_PROTOTYPE
|
||||||
|
'y': '7'
|
||||||
|
width: '11'
|
||||||
|
height: '5'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: INTEGER
|
||||||
|
name: columns
|
||||||
|
value: '1'
|
||||||
|
-
|
||||||
|
type: GRAPH_PROTOTYPE
|
||||||
|
name: graphid
|
||||||
|
value:
|
||||||
|
name: 'OpenVPN client "{#OVPN_CLIENT_NAME}" traffic'
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
type: GRAPH_CLASSIC
|
||||||
|
'y': '2'
|
||||||
|
width: '11'
|
||||||
|
height: '5'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: GRAPH
|
||||||
|
name: graphid
|
||||||
|
value:
|
||||||
|
name: 'OpenVPN clients sum'
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
-
|
||||||
|
type: URL
|
||||||
|
x: '11'
|
||||||
|
width: '13'
|
||||||
|
height: '12'
|
||||||
|
hide_header: 'YES'
|
||||||
|
fields:
|
||||||
|
-
|
||||||
|
type: STRING
|
||||||
|
name: url
|
||||||
|
value: '/zabbix.php?name=virtual ip&tags%5B0%5D%5Btag%5D=Application&tags%5B0%5D%5Boperator%5D=0&tags%5B0%5D%5Bvalue%5D=OpenVPN&show_tags=0&action=latest.view&kiosk=1'
|
||||||
|
triggers:
|
||||||
|
-
|
||||||
|
uuid: 022e1211349c48a4be951588cda2dba0
|
||||||
|
expression: 'max(/OpenVPN by Zabbix agent/ovpn.stats.clients_count,#1)>=max(/OpenVPN by Zabbix agent/ovpn.clients.limit,#1)'
|
||||||
|
name: 'Maximum number of OpenVPN clients reached'
|
||||||
|
priority: AVERAGE
|
||||||
|
tags:
|
||||||
|
-
|
||||||
|
tag: Application
|
||||||
|
value: OpenVPN
|
||||||
|
-
|
||||||
|
tag: 'OpenVPN server'
|
||||||
|
value: 'clients limit'
|
||||||
|
graphs:
|
||||||
|
-
|
||||||
|
uuid: a23bdc304f5d49e1b42597f9cbd4e840
|
||||||
|
name: 'OpenVPN certificates expiration'
|
||||||
|
graph_items:
|
||||||
|
-
|
||||||
|
drawtype: GRADIENT_LINE
|
||||||
|
color: FFBF00
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: ovpn.expiration.ca
|
||||||
|
-
|
||||||
|
sortorder: '1'
|
||||||
|
drawtype: BOLD_LINE
|
||||||
|
color: FF8000
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: ovpn.expiration.cert
|
||||||
|
-
|
||||||
|
uuid: 94d1e1cc40424214a291067790d3db89
|
||||||
|
name: 'OpenVPN clients sum'
|
||||||
|
graph_items:
|
||||||
|
-
|
||||||
|
color: FF8000
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: ovpn.stats.clients_count
|
||||||
|
-
|
||||||
|
sortorder: '1'
|
||||||
|
color: FFBF00
|
||||||
|
item:
|
||||||
|
host: 'OpenVPN by Zabbix agent'
|
||||||
|
key: ovpn.stats.clients_found
|
101
README.md
101
README.md
|
@ -2,45 +2,70 @@
|
||||||
|
|
||||||
OpenVPN management and monitoring utils.
|
OpenVPN management and monitoring utils.
|
||||||
|
|
||||||
* [`ovpn-cert-expiration`.sh](https://git.hmp.today/pavel.muhortov/openvpn-management#ovpn-cert-expiration-sh)
|
* [`ovpn_status`.py](https://git.hmp.today/pavel.muhortov/openvpn-management#ovpn_status-py)
|
||||||
* [`ovpn-client-management`.sh](https://git.hmp.today/pavel.muhortov/openvpn-management#ovpn-client-management-sh)
|
* [`ovpn-client-management`.sh](https://git.hmp.today/pavel.muhortov/openvpn-management#ovpn-client-management-sh)
|
||||||
* [`ovpn-connect-handling`.sh](https://git.hmp.today/pavel.muhortov/openvpn-management#ovpn-connect-handling-sh)
|
|
||||||
|
|
||||||
____
|
____
|
||||||
|
|
||||||
## `ovpn-cert-expiration`.sh
|
## `ovpn_status`.py
|
||||||
|
|
||||||
**Description:**
|
**Description:**
|
||||||
> Checking openvpn server certificates expiration and preparing stats for monitoring.
|
> OpenVPN server status parser.
|
||||||
|
|
||||||
**Dependencies:**
|
**Dependencies:**
|
||||||
>
|
>
|
||||||
> * privileged rights
|
> * privileged rights
|
||||||
> * [openssl](https://www.openssl.org/) (tested version 1.1.1k on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/))
|
> * [Python 3](https://www.python.org/downloads/) (tested version 3.9.5 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/))
|
||||||
|
> * Existing `status`, `server`, `ca`, `cert` options in [server.conf](https://openvpn.net/community-resources/reference-manual-for-openvpn-2-5/#options)
|
||||||
|
|
||||||
| POSITION | PARAMETERS | DESCRIPTION | DEFAULT |
|
| POSITION | PARAMETERS | DESCRIPTION | DEFAULT |
|
||||||
|-----------|--------------|------------------------|---------------|
|
|-----------|--------------|------------------------|---------------|
|
||||||
| 1 |**[qn]**|execution without pauses||
|
|**[-s, --server_conf]**|path to OpenVPN server configuration file|**REQUIRED**|
|
||||||
| 2 |**[/path/to/conf]**|openvpn server config file path|/etc/openvpn/server/server.conf|
|
|**[-f, --filter]**|client names filter by regex|`.*`|
|
||||||
|
|**[-g, --geo]**|check client real ip geo location (may be slow)|`.*`|
|
||||||
|
|
||||||
Example usage:
|
Example usage with Zabbix agent:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# add options to openvpn server config file
|
||||||
|
sudo tee -a /etc/openvpn/server/server.conf > /dev/null <<'EOF'
|
||||||
|
status /var/log/openvpn/openvpn-status.log
|
||||||
|
status-version 2
|
||||||
|
server 10.0.0.0 255.0.0.0
|
||||||
|
ca /etc/openvpn/easy-rsa/pki/ca.crt
|
||||||
|
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
|
||||||
|
EOF
|
||||||
|
sudo systemctl restart openvpn@server
|
||||||
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# download
|
# download
|
||||||
sudo wget https://git.hmp.today/pavel.muhortov/openvpn-management/raw/branch/master/ovpn-cert-expiration.sh -O /etc/openvpn/server/ovpn-cert-expiration.sh
|
sudo wget https://git.hmp.today/pavel.muhortov/openvpn-management/raw/branch/master/ovpn_status.py -O /etc/openvpn/server/ovpn_status.py
|
||||||
sudo chmod +x /etc/openvpn/server/ovpn-cert-expiration.sh
|
sudo chmod +x /etc/openvpn/server/ovpn_status.py
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# sudo crontab -e
|
# edit sudoers
|
||||||
0 * * * * bash /etc/openvpn/server/ovpn-cert-expiration.sh qn
|
sudo sh -c "echo '
|
||||||
|
zabbix ALL=(ALL) NOPASSWD:/etc/openvpn/server/ovpn_status.py -s /etc/openvpn/server/server.conf
|
||||||
|
' > /etc/sudoers.d/zabbix_agentd"
|
||||||
|
# check permission
|
||||||
|
sudo -u zabbix sudo /etc/openvpn/server/ovpn_status.py -s /etc/openvpn/server/server.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# check stats
|
# add UserParameter to Zabbix agent
|
||||||
watch cat /var/log/openvpn/ovpn-cert-expiration.log
|
sudo sh -c "echo '
|
||||||
|
Timeout=30
|
||||||
|
AllowRoot=0
|
||||||
|
UserParameter=discovery.ovpn, sudo /etc/openvpn/server/ovpn_status.py -s /etc/openvpn/server/server.conf
|
||||||
|
' >> /etc/zabbix/zabbix_agentd.conf"
|
||||||
|
sudo systemctl restart zabbix-agent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Download [OpenVPN_by_Zabbix_agent.yaml](https://git.hmp.today/pavel.muhortov/openvpn-management/raw/branch/master/OpenVPN_by_Zabbix_agent.yaml) template
|
||||||
|
Zabbix Server -> Configuration -> Templates -> Import template
|
||||||
|
|
||||||
____
|
____
|
||||||
|
|
||||||
## `ovpn-client-management`.sh
|
## `ovpn-client-management`.sh
|
||||||
|
@ -92,51 +117,3 @@ sudo ./ovpn del username -f
|
||||||
# check journal
|
# check journal
|
||||||
tail -f /var/log/openvpn/ovpn.log
|
tail -f /var/log/openvpn/ovpn.log
|
||||||
```
|
```
|
||||||
|
|
||||||
____
|
|
||||||
|
|
||||||
## `ovpn-connect-handling`.sh
|
|
||||||
|
|
||||||
**Description:**
|
|
||||||
> Handling client connection and preparing stats for monitoring.
|
|
||||||
|
|
||||||
**Dependencies:**
|
|
||||||
>
|
|
||||||
> * executing by [openvpn](https://openvpn.net/) server (tested version 2.5.1 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/))
|
|
||||||
> * [jq](https://github.com/stedolan/jq) (tested version 1.6 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/))
|
|
||||||
> * [grepcidr](https://github.com/ryantig/grepcidr) (tested version 2.0 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/))
|
|
||||||
> * [Python 3](https://www.python.org/downloads/) (tested version 3.9.5 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/))
|
|
||||||
> * existing [/usr/local/bin/sendmail.py](https://git.hmp.today/pavel.muhortov/utils#sendmail-py)
|
|
||||||
> * [bash](https://www.gnu.org/software/bash/) (tested versions: 5.1.4 on [Debian GNU/Linux 11](http://ftp.debian.org/debian/dists/bullseye/), 5.0.17 on [Ubuntu 20](https://wiki.ubuntu.com/FocalFossa/ReleaseNotes), 4.2.46 on [CentOS 7](https://wiki.centos.org/Manuals/ReleaseNotes/CentOS7.2009))
|
|
||||||
|
|
||||||
| POSITION | PARAMETERS | DESCRIPTION | DEFAULT |
|
|
||||||
|-----------|--------------|------------------------|---------------|
|
|
||||||
| 1 |**inc\|dec**|increment or decrement counter|**REQUIRED**|
|
|
||||||
| 2 |**</path/to/dir>**|root path for counter, names, log|**REQUIRED**|
|
|
||||||
| 3 |**[mail]**|send email notification||
|
|
||||||
| 4 |**[geo]**|check client address geolocation||
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# download
|
|
||||||
sudo wget https://git.hmp.today/pavel.muhortov/openvpn-management/raw/branch/master/ovpn-connect-handling.sh -O /etc/openvpn/server/ovpn-connect-handling.sh
|
|
||||||
sudo chmod +x /etc/openvpn/server/ovpn-connect-handling.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# add options to openvpn server config file
|
|
||||||
sudo tee -a /etc/openvpn/server/server.conf > /dev/null <<'EOF'
|
|
||||||
script-security 2
|
|
||||||
client-connect "/etc/openvpn/server/ovpn-connect-handling.sh inc /var/log/openvpn mail geo"
|
|
||||||
client-disconnect "/etc/openvpn/server/ovpn-connect-handling.sh dec /var/log/openvpn - -"
|
|
||||||
EOF
|
|
||||||
sudo systemctl restart openvpn@server
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# check counter and names
|
|
||||||
watch cat /var/log/openvpn/openvpn-counts.log
|
|
||||||
# check journal
|
|
||||||
tail -f /var/log/openvpn/ovpn-connect-handling.log
|
|
||||||
```
|
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# DESCRIPTION:
|
|
||||||
# checking openvpn server certificates expiration
|
|
||||||
# and
|
|
||||||
# preparing stats for monitoring
|
|
||||||
#
|
|
||||||
# DEPENDENCIES:
|
|
||||||
# - privileged rights
|
|
||||||
# - openssl
|
|
||||||
#
|
|
||||||
# PARAMETERS:
|
|
||||||
# 1: "qn" - execution without pauses
|
|
||||||
# 2: openvpn server config file path
|
|
||||||
#
|
|
||||||
# FUNCTIONS:
|
|
||||||
#
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Print message and add to log.
|
|
||||||
# Globals:
|
|
||||||
# logs
|
|
||||||
# Arguments:
|
|
||||||
# 1: message to print and logging
|
|
||||||
#######################################
|
|
||||||
addtologs() {
|
|
||||||
echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a "${logs}"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Waiting for press [ENTER].
|
|
||||||
# Globals:
|
|
||||||
# None
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
execpause() {
|
|
||||||
read -r -p "Press [ENTER] to continue... "
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Exit procedure.
|
|
||||||
# Globals:
|
|
||||||
# show
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
execquite() {
|
|
||||||
addtologs "execution time is $(($(date +%s)-time)) seconds, exit"
|
|
||||||
if [ "${show}" != "qn" ]; then
|
|
||||||
execpause
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Error exit procedure
|
|
||||||
# Globals:
|
|
||||||
# None
|
|
||||||
# Arguments:
|
|
||||||
# 1: message to print and logging
|
|
||||||
#######################################
|
|
||||||
execerror() {
|
|
||||||
addtologs "error: $1"
|
|
||||||
execquite
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Parsing config file and creating global vars.
|
|
||||||
# Globals:
|
|
||||||
# None
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
getconfig() {
|
|
||||||
cacrpath=$(grep ^ca "${conf}" | cut -d' ' -f2)
|
|
||||||
certpath=$(grep ^cert "${conf}" | cut -d' ' -f2)
|
|
||||||
statfile="$(dirname "$(grep ^log /etc/openvpn/server/server.conf | cut -d' ' -f2)")/$(basename -s .sh "$0").log"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Checking user rights.
|
|
||||||
# Globals:
|
|
||||||
# None
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
# return:
|
|
||||||
# 0 - if privileged rights, 1 - if not privileged rights
|
|
||||||
#######################################
|
|
||||||
checkroot() {
|
|
||||||
if [ "${EUID}" -ne 0 ]; then
|
|
||||||
return 1 # false
|
|
||||||
else
|
|
||||||
return 0 # true
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Print certificate expiration date in epoch
|
|
||||||
# Globals:
|
|
||||||
# None
|
|
||||||
# Arguments:
|
|
||||||
# 1: certificate path
|
|
||||||
#######################################
|
|
||||||
checkcert() {
|
|
||||||
printf '%s\n' "$(date -d "$(openssl x509 -text -noout -in "${1}" | grep 'Not After' | cut -d':' -f2-)" +%s)"
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# VARIABLES:
|
|
||||||
#
|
|
||||||
|
|
||||||
show=$1
|
|
||||||
conf=$2
|
|
||||||
logs=/dev/null
|
|
||||||
if [ -z "${conf}" ] || [ "${conf}" == "-" ]; then
|
|
||||||
conf=/etc/openvpn/server/server.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
time=$(date +%s)
|
|
||||||
cd "$(dirname "$(realpath "$0")")" || execerror
|
|
||||||
if [ ! -e "${conf}" ]; then
|
|
||||||
execerror "${conf} not found"
|
|
||||||
else
|
|
||||||
getconfig
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v openssl &> /dev/null; then
|
|
||||||
execerror "Not found dependencies"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# MAIN:
|
|
||||||
#
|
|
||||||
|
|
||||||
if checkroot; then
|
|
||||||
cacrtime=$(checkcert "${cacrpath}")
|
|
||||||
certtime=$(checkcert "${certpath}")
|
|
||||||
cacrremain=$(( cacrtime - time ))
|
|
||||||
certremain=$(( certtime - time))
|
|
||||||
addtologs "${cacrpath} remains only ${cacrremain} seconds"
|
|
||||||
addtologs "${certpath} remains only ${certremain} seconds"
|
|
||||||
printf '%s\n' "ca=${cacrremain}" > "${statfile}"
|
|
||||||
printf '%s\n' "cert=${certremain}" >> "${statfile}"
|
|
||||||
addtologs "stats wrote to ${statfile}"
|
|
||||||
execquite
|
|
||||||
else
|
|
||||||
execerror "Restart this as root!"
|
|
||||||
fi
|
|
|
@ -1,195 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# DESCRIPTION:
|
|
||||||
# handling client connection
|
|
||||||
# and
|
|
||||||
# preparing stats for monitoring
|
|
||||||
#
|
|
||||||
# DEPENDENCIES:
|
|
||||||
# - executing by openvpn server
|
|
||||||
# - jq
|
|
||||||
# - grepcidr
|
|
||||||
# - Python 3
|
|
||||||
# - existing /usr/local/bin/sendmail.py
|
|
||||||
#
|
|
||||||
# PARAMETERS:
|
|
||||||
# 1: "inc|dec" - increment or decrement counter
|
|
||||||
# 2: root path for counter, names, log
|
|
||||||
# 3: "mail" - send email notification
|
|
||||||
# 4: "geo" - check client address geolocation
|
|
||||||
#
|
|
||||||
# FUNCTIONS:
|
|
||||||
#
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Print message and add to log.
|
|
||||||
# Globals:
|
|
||||||
# logs
|
|
||||||
# Arguments:
|
|
||||||
# 1: message to print and logging
|
|
||||||
#######################################
|
|
||||||
addtologs() {
|
|
||||||
echo "$(date +'%Y.%m.%d-%H:%M:%S') $1" | tee -a "${logs}"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Exit procedure.
|
|
||||||
# Globals:
|
|
||||||
# show
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
execquite() {
|
|
||||||
addtologs "execution time is $(($(date +%s)-time)) seconds, exit"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Error exit procedure
|
|
||||||
# Globals:
|
|
||||||
# None
|
|
||||||
# Arguments:
|
|
||||||
# 1: message to print and logging
|
|
||||||
#######################################
|
|
||||||
execerror() {
|
|
||||||
addtologs "error: $1"
|
|
||||||
execquite
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Incrementing counter with adding client name
|
|
||||||
# Globals:
|
|
||||||
# counts_file
|
|
||||||
# common_name (variable by openvpn server)
|
|
||||||
# ifconfig_pool_remote_ip (variable by openvpn server)
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
incremcounter() {
|
|
||||||
summary_cur=$(grep 'total=' "${counts_file}" | cut -d= -f2)
|
|
||||||
summary_new=${summary_cur} && (( summary_new += 1 ))
|
|
||||||
counts_temp=$(sed -e "s/total=${summary_cur}/total=${summary_new}/g" "${counts_file}" \
|
|
||||||
| sed -e '$a'"${common_name}"'_'"${ifconfig_pool_remote_ip}"'')
|
|
||||||
addtologs "client ${common_name} connected, counter increment to ${summary_new}"
|
|
||||||
printf "%s\n" "${counts_temp}" > "${counts_file}"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Decrementing counter with deleting client name
|
|
||||||
# Globals:
|
|
||||||
# counts_file
|
|
||||||
# common_name (variable by openvpn server)
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
decremcounter(){
|
|
||||||
summary_cur=$(grep 'total=' "${counts_file}" | cut -d= -f2)
|
|
||||||
summary_new=${summary_cur} && (( summary_new -= 1 ))
|
|
||||||
counts_temp=$(sed -e "s/total=${summary_cur}/total=${summary_new}/g" "${counts_file}" \
|
|
||||||
| sed '0,/'"${common_name}"'/{/'"${common_name}"'/d}')
|
|
||||||
addtologs "client ${common_name} disconnected, counter decrement to ${summary_new}"
|
|
||||||
printf "%s\n" "${counts_temp}" > "${counts_file}"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Get information about client address
|
|
||||||
# Globals:
|
|
||||||
# flaggeol
|
|
||||||
# untrusted_ip (variable by openvpn server)
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
# shellcheck disable=SC2154
|
|
||||||
expandaddress() {
|
|
||||||
ipinfo="Source address is ${untrusted_ip}"
|
|
||||||
localnetworks="10.0.0.0/8
|
|
||||||
100.64.0.0/10
|
|
||||||
127.0.0.1/8
|
|
||||||
172.16.0.0/12
|
|
||||||
192.168.0.0/16
|
|
||||||
"
|
|
||||||
if ! grepcidr "${localnetworks}" <(echo "${untrusted_ip}") >/dev/null; then
|
|
||||||
if [ "${flaggeol}" == "geo" ]; then
|
|
||||||
ipinfo=$(curl "https://api.ipbase.com/v1/json/${untrusted_ip}")
|
|
||||||
if [ "$(jq -r '.country_name' <<< "$ipinfo")" != "" ]; then
|
|
||||||
z=$(jq -r '.zip_code' <<< "$ipinfo")
|
|
||||||
c=$(jq -r '.country_name' <<< "$ipinfo")
|
|
||||||
r=$(jq -r '.region_name' <<< "$ipinfo")
|
|
||||||
t=$(jq -r '.city' <<< "$ipinfo")
|
|
||||||
ipinfo="Source address ${untrusted_ip} is from ${z}, ${c}, ${r}, ${t}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
addtologs "client ${common_name} checked. ${ipinfo}"
|
|
||||||
}
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Send email notification about client connect
|
|
||||||
# Globals:
|
|
||||||
# ipinfo
|
|
||||||
# common_name (variable by openvpn server)
|
|
||||||
# ifconfig_pool_remote_ip (variable by openvpn server)
|
|
||||||
# Arguments:
|
|
||||||
# None
|
|
||||||
#######################################
|
|
||||||
startsendmail() {
|
|
||||||
subj="[VPN Connected] $(cat /etc/hostname): ${common_name} connect to ${ifconfig_pool_remote_ip}"
|
|
||||||
(
|
|
||||||
python3 /usr/local/bin/sendmail.py \
|
|
||||||
-u "$(grep "from=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
|
|
||||||
-p "$(grep "pass=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
|
|
||||||
-d "$(grep "dest=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
|
|
||||||
--smtp "$(grep "smtp=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
|
|
||||||
--port "$(grep "port=" /usr/local/bin/sendmail.config | cut -d= -f2)" \
|
|
||||||
--stls "True" \
|
|
||||||
--subj "${subj}" \
|
|
||||||
--text "${ipinfo}" \
|
|
||||||
>> /dev/null 2>&1 &
|
|
||||||
)
|
|
||||||
addtologs "sent mail with subject '${subj}'"
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# VARIABLES:
|
|
||||||
#
|
|
||||||
|
|
||||||
flagmath=$1
|
|
||||||
pathroot=$2
|
|
||||||
flagmail=$3
|
|
||||||
flaggeol=$4
|
|
||||||
|
|
||||||
time=$(date +%s)
|
|
||||||
logs="${pathroot}/$(basename -s .sh "$0").log"
|
|
||||||
counts_file="${pathroot}/ovpn-counts.log"
|
|
||||||
if [ -z "${pathroot}" ]; then
|
|
||||||
logs=/dev/null
|
|
||||||
execerror "Usage example: $0 'inc|dec' '/var/log/openvpn' '-' '-'"
|
|
||||||
elif [ ! -e "${logs}" ]; then
|
|
||||||
touch "${logs}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v curl &> /dev/null || \
|
|
||||||
! command -v /usr/local/bin/sendmail.py &> /dev/null || \
|
|
||||||
! command -v python3 &> /dev/null || \
|
|
||||||
! command -v grepcidr &> /dev/null || \
|
|
||||||
! command -v jq &> /dev/null; then
|
|
||||||
execerror "Not found dependencies"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# MAIN:
|
|
||||||
#
|
|
||||||
|
|
||||||
if [ "${flagmath}" == "inc" ]; then
|
|
||||||
incremcounter
|
|
||||||
expandaddress
|
|
||||||
if [ "${flagmail}" == "mail" ]; then
|
|
||||||
startsendmail
|
|
||||||
fi
|
|
||||||
elif [ "${flagmath}" == "dec" ]; then
|
|
||||||
decremcounter
|
|
||||||
else
|
|
||||||
execerror "Usage example: $0 'inc|dec' '/var/log/openvpn' '-' '-'"
|
|
||||||
fi
|
|
||||||
execquite
|
|
233
ovpn_status.py
Normal file
233
ovpn_status.py
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""It's the OpenVPN server status parser.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from ipaddress import IPv4Network
|
||||||
|
from os import path
|
||||||
|
from cryptography import x509
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def status(stats_file: str, client_filter: str = '.*', client_geo: bool = False) -> dict:
|
||||||
|
"""OpenVPN status log parser.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
stats_file (str): path to OpenVPN status log file.
|
||||||
|
client_filter (str, optional): client names filter by regex. Defaults to '.*'.
|
||||||
|
client_geo (bool, optional): check client real ip geo location Defaults to False.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: {
|
||||||
|
'stats_updated': timestamp,
|
||||||
|
'clients_count': int,
|
||||||
|
'clients_found': int,
|
||||||
|
'data': [
|
||||||
|
{
|
||||||
|
"name": str,
|
||||||
|
"r_ip": str,
|
||||||
|
"v_ip": str,
|
||||||
|
"b_rx": int,
|
||||||
|
"b_tx": int,
|
||||||
|
"t_cs": timestamp,
|
||||||
|
"t_cd": int
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
with open(stats_file, mode='r', encoding='utf-8') as file:
|
||||||
|
stats_data = file.read()
|
||||||
|
|
||||||
|
if re.match("^OpenVPN CLIENT LIST", stats_data):
|
||||||
|
# status-version 1
|
||||||
|
stats_vers = 1
|
||||||
|
dlm = ','
|
||||||
|
elif re.match("^TITLE,", stats_data):
|
||||||
|
# status-version 2
|
||||||
|
stats_vers = 2
|
||||||
|
dlm = ','
|
||||||
|
elif re.match("^TITLE\t", stats_data):
|
||||||
|
# status-version 3
|
||||||
|
stats_vers = 3
|
||||||
|
dlm = '\t'
|
||||||
|
else:
|
||||||
|
stats_vers = 0
|
||||||
|
|
||||||
|
clients_array = []
|
||||||
|
clients_count = -1
|
||||||
|
clients_found = 0
|
||||||
|
stats_updated = -1
|
||||||
|
|
||||||
|
if stats_vers == 0:
|
||||||
|
pass
|
||||||
|
elif stats_vers == 1:
|
||||||
|
updated_r = re.search('Updated' + dlm + '.*', stats_data).group(0)
|
||||||
|
stats_updated = updated_r.replace('Updated' + dlm, '')
|
||||||
|
updated_t = time.mktime(time.strptime(stats_updated, "%Y-%m-%d %H:%M:%S"))
|
||||||
|
|
||||||
|
clients_s = 'Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since'
|
||||||
|
clients_e = 'ROUTING TABLE'
|
||||||
|
clients_r = re.search(clients_s + "(.*)" + clients_e, stats_data, re.DOTALL).group(0)
|
||||||
|
stats_clients = re.sub(clients_s + '\n', '', re.sub(clients_e, '', clients_r))
|
||||||
|
|
||||||
|
routing_s = 'Virtual Address,Common Name,Real Address,Last Ref'
|
||||||
|
routing_e = 'GLOBAL STATS'
|
||||||
|
routing_r = re.search(routing_s + "(.*)" + routing_e, stats_data, re.DOTALL).group(0)
|
||||||
|
stats_routing = re.sub(routing_s + '\n', '', re.sub(routing_e, '', routing_r))
|
||||||
|
|
||||||
|
clients_count = len(stats_clients.splitlines())
|
||||||
|
if clients_count > 0:
|
||||||
|
for client in stats_clients.splitlines():
|
||||||
|
client_name = client.split(dlm)[0]
|
||||||
|
client_r_ip = client.split(dlm)[1].split(':')[0]
|
||||||
|
client_r_cc = '--'
|
||||||
|
if client_geo:
|
||||||
|
client_r_cc = ip_geo(addr=client_r_ip)
|
||||||
|
if re.findall(client_filter, client_name):
|
||||||
|
regex_v_ip = re.compile('.*' + dlm.join(client.split(dlm)[:2]) + '.*')
|
||||||
|
clients_array.append(
|
||||||
|
{
|
||||||
|
'name': client_name,
|
||||||
|
'r_ip': client_r_ip,
|
||||||
|
'r_cc': client_r_cc,
|
||||||
|
'v_ip': regex_v_ip.search(stats_routing).group(0).split(dlm)[0],
|
||||||
|
'b_rx': int(client.split(dlm)[2]),
|
||||||
|
'b_tx': int(client.split(dlm)[3]),
|
||||||
|
't_cs': client.split(dlm)[4],
|
||||||
|
't_cd': int(updated_t) - int(
|
||||||
|
time.mktime(
|
||||||
|
time.strptime(client.split(dlm)[4], "%Y-%m-%d %H:%M:%S")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
clients_found += 1
|
||||||
|
else:
|
||||||
|
updated_r = re.search('TIME' + dlm + '.*', stats_data).group(0)
|
||||||
|
updated_t = updated_r.split(dlm)[2]
|
||||||
|
stats_updated = updated_r.split(dlm)[1]
|
||||||
|
stats_clients = '\n'.join(re.findall("^CLIENT_LIST.*", stats_data, re.MULTILINE))
|
||||||
|
|
||||||
|
clients_count = len(stats_clients.splitlines())
|
||||||
|
if clients_count > 0:
|
||||||
|
for client in stats_clients.splitlines():
|
||||||
|
client_name = client.split(dlm)[1]
|
||||||
|
client_r_ip = client.split(dlm)[2].split(':')[0]
|
||||||
|
client_r_cc = '--'
|
||||||
|
if client_geo:
|
||||||
|
client_r_cc = ip_geo(addr=client_r_ip)
|
||||||
|
if re.search(client_filter, client_name):
|
||||||
|
clients_array.append(
|
||||||
|
{
|
||||||
|
'name': client_name,
|
||||||
|
'r_ip': client_r_ip,
|
||||||
|
'r_cc': client_r_cc,
|
||||||
|
'v_ip': client.split(dlm)[3],
|
||||||
|
'b_rx': int(client.split(dlm)[5]),
|
||||||
|
'b_tx': int(client.split(dlm)[6]),
|
||||||
|
't_cs': client.split(dlm)[7],
|
||||||
|
't_cd': int(updated_t) - int(client.split(dlm)[8])
|
||||||
|
}
|
||||||
|
)
|
||||||
|
clients_found += 1
|
||||||
|
|
||||||
|
clients_stats = {
|
||||||
|
'stats_updated': stats_updated,
|
||||||
|
'clients_count': clients_count,
|
||||||
|
'clients_found': clients_found,
|
||||||
|
'data': clients_array,
|
||||||
|
}
|
||||||
|
return clients_stats
|
||||||
|
|
||||||
|
|
||||||
|
def ip_num(addr: str, mask: (str, int)) -> int:
|
||||||
|
"""OpenVPN client ip limit calculator (without --ifconfig-pool-linear).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
addr (str): server subnet.
|
||||||
|
mask (str, int): server mask.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: ip limit.
|
||||||
|
"""
|
||||||
|
return int(IPv4Network(addr + '/' + mask).num_addresses/4-1)
|
||||||
|
|
||||||
|
|
||||||
|
def ce_exp(cert_path: str) -> int:
|
||||||
|
"""Get certificate expiration time.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cert_path (str): path to certificate file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: certificate expiration time in epoch.
|
||||||
|
"""
|
||||||
|
with open(cert_path, mode='rb') as cert_file:
|
||||||
|
cert_data = x509.load_pem_x509_certificate(cert_file.read())
|
||||||
|
return int(cert_data.not_valid_after.timestamp())
|
||||||
|
|
||||||
|
|
||||||
|
def ip_geo(addr: str) -> str:
|
||||||
|
"""Get ip address geo location.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
addr (str): ip address.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: country code.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
request = 'https://geolocation-db.com/json/' + addr
|
||||||
|
response = requests.get(request, timeout=5)
|
||||||
|
result = json.loads(response.content.decode())
|
||||||
|
return result['country_code']
|
||||||
|
except requests.exceptions.RequestException:
|
||||||
|
return '--'
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = ArgumentParser(
|
||||||
|
prog='ovpn_status',
|
||||||
|
description='OpenVPN server status parser',
|
||||||
|
epilog='Dependencies: '
|
||||||
|
'- Python 3 (tested version 3.9.5), '
|
||||||
|
)
|
||||||
|
args.add_argument('-s', '--server_conf', type=str, required=True,
|
||||||
|
help='path to OpenVPN server configuration file')
|
||||||
|
args.add_argument('-f', '--filter', type=str, default='.*', required=False,
|
||||||
|
help='client names filter by regex')
|
||||||
|
args.add_argument('-g', '--geo', action='store_true', required=False,
|
||||||
|
help='check client real ip geo location (may be slow)')
|
||||||
|
args = vars(args.parse_args())
|
||||||
|
|
||||||
|
if path.exists(args['server_conf']):
|
||||||
|
with open(args['server_conf'], mode='r', encoding='utf-8') as conf_file:
|
||||||
|
conf_data = conf_file.read()
|
||||||
|
|
||||||
|
st_file_conf = re.search(r'status\s+\S*', conf_data, re.MULTILINE).group(0)
|
||||||
|
st_file_path = re.sub(r'status\s+', '', st_file_conf)
|
||||||
|
json_data = status(
|
||||||
|
stats_file=st_file_path,
|
||||||
|
client_filter=args['filter'],
|
||||||
|
client_geo=args['geo']
|
||||||
|
)
|
||||||
|
|
||||||
|
ca_file_conf = re.search(r'ca\s+\S*', conf_data, re.MULTILINE).group(0)
|
||||||
|
ca_file_path = re.sub(r'ca\s+', '', ca_file_conf)
|
||||||
|
json_data['ca_expiration'] = ce_exp(cert_path=ca_file_path)
|
||||||
|
|
||||||
|
ce_file_conf = re.search(r'cert\s+\S*', conf_data, re.MULTILINE).group(0)
|
||||||
|
ce_file_path = re.sub(r'cert\s+', '', ce_file_conf)
|
||||||
|
json_data['ce_expiration'] = ce_exp(cert_path=ce_file_path)
|
||||||
|
|
||||||
|
network_conf = re.search(r'server\s+\S*\s+\S*', conf_data, re.MULTILINE).group(0)
|
||||||
|
network_pool = re.sub(r'server\s+', '', network_conf)
|
||||||
|
network_addr = re.sub(r'\s+\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}', '', network_pool)
|
||||||
|
network_mask = re.sub(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\s+', '', network_pool)
|
||||||
|
json_data['clients_limit'] = ip_num(addr=network_addr, mask=network_mask)
|
||||||
|
|
||||||
|
print(json.dumps(json_data, indent=2))
|
Loading…
Reference in New Issue
Block a user