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.
|
||||
|
||||
* [`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-connect-handling`.sh](https://git.hmp.today/pavel.muhortov/openvpn-management#ovpn-connect-handling-sh)
|
||||
|
||||
____
|
||||
|
||||
## `ovpn-cert-expiration`.sh
|
||||
## `ovpn_status`.py
|
||||
|
||||
**Description:**
|
||||
> Checking openvpn server certificates expiration and preparing stats for monitoring.
|
||||
> OpenVPN server status parser.
|
||||
|
||||
**Dependencies:**
|
||||
>
|
||||
> * 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 |
|
||||
|-----------|--------------|------------------------|---------------|
|
||||
| 1 |**[qn]**|execution without pauses||
|
||||
| 2 |**[/path/to/conf]**|openvpn server config file path|/etc/openvpn/server/server.conf|
|
||||
|**[-s, --server_conf]**|path to OpenVPN server configuration file|**REQUIRED**|
|
||||
|**[-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
|
||||
# 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 chmod +x /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_status.py
|
||||
```
|
||||
|
||||
```bash
|
||||
# sudo crontab -e
|
||||
0 * * * * bash /etc/openvpn/server/ovpn-cert-expiration.sh qn
|
||||
# edit sudoers
|
||||
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
|
||||
# check stats
|
||||
watch cat /var/log/openvpn/ovpn-cert-expiration.log
|
||||
# add UserParameter to Zabbix agent
|
||||
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
|
||||
|
@ -92,51 +117,3 @@ sudo ./ovpn del username -f
|
|||
# check journal
|
||||
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