Preliminary tests of Speedtest

This commit is contained in:
Riccardo Bicelli 2021-07-05 17:56:27 +02:00
parent d784c1f08a
commit ebc9ae34fa
4 changed files with 479 additions and 48 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.backup

View File

@ -12,6 +12,7 @@ Tested with pfSense 2.4.x, Zabbix 4.0, Zabbix 5.0
**Template pfSense Active**
- Network interface Discovery and Monitoring with User Assigned Names
- Scheduled Speedtest on WAN interfaces (via ookla speedtest)
- Gateway Discovery and Monitoring (Gateway Status/RTT)
- OpenVPN Server Discovery and Monitoring (Server Status/Tunnel Status)
- OpenVPN Clients Discovery and Monitoring (Client Status/Tunnel Status)
@ -80,6 +81,35 @@ Possible values are:
This is useful when monitoring services which could stay stopped on CARP Backup Member.
## Setup Speedtest
For running speedtests on WAN interfaces you have to install the speedtest package
From **Diagnostics/Command Prompt** input this commands:
```
pkg update && pkg install -y py37-speedtest-cli
```
Speedtest python package could be broken at the moment, so you could need an extra step: download the latest version from package author's github repo.
```
curl -Lo /usr/local/lib/python3.7/site-packages speedtest.py https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py
```
For testing if speedtest is installed properly you can try it:
```
/usr/local/bin/speedtest
```
Remember that you will need to install the package on *every* pfSense upgrade.
**For speedtest to work you may need to increase Timeout up to its maximum (30)**
## Credits
[Keenton Zabbix Template](https://github.com/keentonsas/zabbix-template-pfsense) for Zabbix Agent freeBSD part.

View File

@ -1,7 +1,7 @@
<?php
/***
pfsense_zbx.php - pfSense Zabbix Interface
Version 1.0.3 - 2022-07-04
Version 1.0.5 - 2021-07-05
Written by Riccardo Bicelli <r.bicelli@gmail.com>
This program is licensed under Apache 2.0 License
@ -89,53 +89,111 @@ function pfz_test(){
// Interface Discovery
// Improved performance
function pfz_interface_discovery($skip_disabled = true, $skip_unconfigured = true) {
function pfz_interface_discovery($is_wan=false) {
$ifdescrs = get_configured_interface_with_descr(true);
$all_hw_ifs = get_interface_arr();
$merged_ifs=array();
$ifaces = get_interface_arr();
$ifcs=array();
$json_string = '{"data":[';
foreach ($ifdescrs as $ifname => $ifdescr){
$ifinfo = get_interface_info($ifname);
$ifinfo["description"] = $ifdescr;
$ifcs[$ifname] = $ifinfo;
}
$output = ['data' => []];
foreach ($ifdescrs as $pfsense_if_name => $user_if_name ) {
$ifinfo = get_interface_info($pfsense_if_name);
$ifinfo["description"] = $user_if_name;
$ifinfo["pfsense_name"] = $pfsense_if_name;
$hwname = $ifinfo['hwif'];
$merged_ifs[$hwname] = $ifinfo;
foreach ($ifaces as $hwif) {
$ifdescr = $hwif;
$has_gw = false;
$is_vpn = false;
foreach($ifcs as $ifc=>$ifinfo){
if ($ifinfo["hwif"] == $hwif){
$ifdescr = $ifinfo["description"];
if (array_key_exists("gateway",$ifinfo)) $has_gw=true;
if (strpos($ifinfo["if"],"ovpn")!==false) $is_vpn=true;
break;
}
}
if ( ($is_wan==false) || (($is_wan==true) && ($has_gw==true) && ($is_vpn==false)) ) {
$json_string .= '{"{#IFNAME}":"' . $hwif . '"';
$json_string .= ',"{#IFDESCR}":"' . $ifdescr . '"';
$json_string .= '},';
}
}
$json_string = rtrim($json_string,",");
$json_string .= "]}";
foreach ($all_hw_ifs as $hwif) {
$record = [];
$record['{#IFNAME}'] = $hwif;
// needed when using interface names in dependent items via jsonpath
$record['{#IFNAMEJ}'] = str_replace('.','_',$hwif);
if (!empty($merged_ifs[ $hwif ])) {
if(true === $skip_disabled && isset($merged_ifs[ $hwif ]['enabled'])) {
if($merged_ifs[ $hwif ]['enabled'] != 1) {
continue;
}
}
$record['{#IFDESCR}'] = $merged_ifs[ $hwif ]['description'];
} else {
if(true === $skip_unconfigured) {
continue;
}
else {
$record['{#IFDESCR}'] = $hwif;
}
}
$output['data'][] = $record;
}
echo json_encode($output);
echo $json_string;
}
function pfz_interface_discovery_all() {
pfz_interface_discovery(false, false);
//Interface Speedtest
function pfz_interface_speedtest_value($ifname, $value){
$ifdescrs = get_configured_interface_with_descr(true);
$ifaces = get_interface_arr();
$pf_interface_name='';
$subvalue=false;
$tvalue = explode(".", $value);
if (count($tvalue)>1) {
$value = $tvalue[0];
$subvalue = $tvalue[1];
}
foreach ($ifdescrs as $ifn => $ifd){
$ifinfo = get_interface_info($ifn);
if($ifinfo['hwif']==$ifname) {
$pf_interface_name = $ifn;
break;
}
}
//If the interface has a gateway is considered WAN, so let's do the speedtest
if (array_key_exists("gateway", $ifinfo)) {
$ipaddr = $ifinfo['ipaddr'];
$speedtest_data = pfz_speedtest_exec($pf_interface_name,$ipaddr);
if (array_key_exists($value,$speedtest_data)) {
if ($subvalue == false)
echo $speedtest_data[$value];
else
echo $speedtest_data[$value][$subvalue];
}
}
}
function pfz_speedtest_exec ($ifname, $ipaddr, $is_cron=false){
$filename = "/tmp/speedtest-$ifname";
$filerun = "/tmp/speedtest-run";
$filecron = "/tmp/speedtest.cron"
if (file_exists($filename)) {
$json_output = json_decode(file_get_contents($filename), true);
if ($json_output==null) @unlink($filename);
return $json_output;
}
if ($is_cron) touch($filecron);
if ( $is_cron==false || file_exists($filecron)) {
if ( (time()-filemtime($filename) > 8 * 3600) || (file_exists($filename)==false) ) {
// file older than 8 Hours
if ( (time()-filemtime($filerun) > 180 ) ) @unlink($filerun);
if (file_exists($filename)==false) {
touch($filerun);
$st_command = "nohup /usr/local/bin/speedtest --source $ipaddr --json > $filename && rm $filerun &";
exec ($st_command);
}
}
}
return false;
}
// OpenVPN Server Discovery
@ -936,7 +994,13 @@ function pfz_get_system_value($section){
}
}
// File is present
function pfz_file_exists($filename) {
if (file_exists($filename))
echo "1";
else
echo "0";
}
// Value mappings
// Each value map is represented by an associative array
@ -1039,6 +1103,9 @@ function pfz_discovery($section){
case "gw":
pfz_gw_discovery();
break;
case "wan":
pfz_interface_discovery(true);
break;
case "openvpn_server":
pfz_openvpn_serverdiscovery();
break;
@ -1054,10 +1121,6 @@ function pfz_discovery($section){
case "interfaces":
pfz_interface_discovery();
break;
<<<<<<< HEAD
case "interfaces_all":
pfz_interface_discovery_all();
=======
case "ipsec_ph1":
pfz_ipsec_discovery_ph1();
break;
@ -1066,7 +1129,6 @@ function pfz_discovery($section){
break;
case "dhcpfailover":
pfz_dhcpfailover_discovery();
>>>>>>> master
break;
}
}
@ -1082,6 +1144,9 @@ switch (strtolower($argv[1])){
case "gw_status":
pfz_gw_rawstatus();
break;
case "if_speedtest_value":
pfz_interface_speedtest_value($argv[2],$argv[3]);
break;
case "openvpn_servervalue":
pfz_openvpn_servervalue($argv[2],$argv[3]);
break;
@ -1115,6 +1180,9 @@ switch (strtolower($argv[1])){
case "dhcp":
pfz_dhcp($argv[2],$argv[3]);
break;
case "file_exists":
pfz_file_exists($argv[2]);
break;
default:
pfz_test();
}

View File

@ -0,0 +1,332 @@
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>4.0</version>
<date>2021-07-05T15:51:20Z</date>
<groups>
<group>
<name>Templates/Network Devices</name>
</group>
</groups>
<templates>
<template>
<template>pfSense Active Speedtest</template>
<name>pfSense Active: Speedtest</name>
<description>Extension for pfSense Active Template.&#13;
Executes Speedtests on WAN Interfaces.&#13;
&#13;
Requires pfsense_zbx.php installed to pfSense Box.&#13;
Version 1.0.5&#13;
&#13;
https://github.com/rbicelli/pfsense-zabbix-template</description>
<groups>
<group>
<name>Templates/Network Devices</name>
</group>
</groups>
<applications>
<application>
<name>Network interfaces</name>
</application>
</applications>
<items/>
<discovery_rules>
<discovery_rule>
<name>WAN Interfaces</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>pfsense.discovery[wan]</key>
<delay>300s</delay>
<status>0</status>
<allowed_hosts/>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<filter>
<evaltype>0</evaltype>
<formula/>
<conditions/>
</filter>
<lifetime>30d</lifetime>
<description>Discover WAN Interfaces</description>
<item_prototypes>
<item_prototype>
<name>Speedtest Download on {#IFDESCR}</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>pfsense.value[if_speedtest_value,{#IFNAME},download]</key>
<delay>3600s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>0</value_type>
<allowed_hosts/>
<units>bps</units>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Download speed determined by Ookla Speedtest package</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Network interfaces</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<timeout>3s</timeout>
<url/>
<query_fields/>
<posts/>
<status_codes>200</status_codes>
<follow_redirects>1</follow_redirects>
<post_type>0</post_type>
<http_proxy/>
<headers/>
<retrieve_mode>0</retrieve_mode>
<request_method>0</request_method>
<output_format>0</output_format>
<allow_traps>0</allow_traps>
<ssl_cert_file/>
<ssl_key_file/>
<ssl_key_password/>
<verify_peer>0</verify_peer>
<verify_host>0</verify_host>
<application_prototypes/>
<master_item/>
</item_prototype>
<item_prototype>
<name>Speedtest Ping on {#IFDESCR}</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>pfsense.value[if_speedtest_value,{#IFNAME},ping]</key>
<delay>3600s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>0</value_type>
<allowed_hosts/>
<units>ms</units>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Ping determined by Ookla Speedtest package</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Network interfaces</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<timeout>3s</timeout>
<url/>
<query_fields/>
<posts/>
<status_codes>200</status_codes>
<follow_redirects>1</follow_redirects>
<post_type>0</post_type>
<http_proxy/>
<headers/>
<retrieve_mode>0</retrieve_mode>
<request_method>0</request_method>
<output_format>0</output_format>
<allow_traps>0</allow_traps>
<ssl_cert_file/>
<ssl_key_file/>
<ssl_key_password/>
<verify_peer>0</verify_peer>
<verify_host>0</verify_host>
<application_prototypes/>
<master_item/>
</item_prototype>
<item_prototype>
<name>Speedtest Upload on {#IFDESCR}</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>pfsense.value[if_speedtest_value,{#IFNAME},upload]</key>
<delay>3600s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>0</value_type>
<allowed_hosts/>
<units>bps</units>
<snmpv3_contextname/>
<snmpv3_securityname/>
<snmpv3_securitylevel>0</snmpv3_securitylevel>
<snmpv3_authprotocol>0</snmpv3_authprotocol>
<snmpv3_authpassphrase/>
<snmpv3_privprotocol>0</snmpv3_privprotocol>
<snmpv3_privpassphrase/>
<params/>
<ipmi_sensor/>
<authtype>0</authtype>
<username/>
<password/>
<publickey/>
<privatekey/>
<port/>
<description>Ping determined by Ookla Speedtest package</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>Network interfaces</name>
</application>
</applications>
<valuemap/>
<logtimefmt/>
<preprocessing/>
<jmx_endpoint/>
<timeout>3s</timeout>
<url/>
<query_fields/>
<posts/>
<status_codes>200</status_codes>
<follow_redirects>1</follow_redirects>
<post_type>0</post_type>
<http_proxy/>
<headers/>
<retrieve_mode>0</retrieve_mode>
<request_method>0</request_method>
<output_format>0</output_format>
<allow_traps>0</allow_traps>
<ssl_cert_file/>
<ssl_key_file/>
<ssl_key_password/>
<verify_peer>0</verify_peer>
<verify_host>0</verify_host>
<application_prototypes/>
<master_item/>
</item_prototype>
</item_prototypes>
<trigger_prototypes/>
<graph_prototypes>
<graph_prototype>
<name>Speedtest metrics on {#IFDESCR}</name>
<width>900</width>
<height>200</height>
<yaxismin>0.0000</yaxismin>
<yaxismax>100.0000</yaxismax>
<show_work_period>1</show_work_period>
<show_triggers>1</show_triggers>
<type>0</type>
<show_legend>1</show_legend>
<show_3d>0</show_3d>
<percent_left>0.0000</percent_left>
<percent_right>0.0000</percent_right>
<ymin_type_1>0</ymin_type_1>
<ymax_type_1>0</ymax_type_1>
<ymin_item_1>0</ymin_item_1>
<ymax_item_1>0</ymax_item_1>
<graph_items>
<graph_item>
<sortorder>0</sortorder>
<drawtype>0</drawtype>
<color>199C0D</color>
<yaxisside>0</yaxisside>
<calc_fnc>7</calc_fnc>
<type>0</type>
<item>
<host>pfSense Active Speedtest</host>
<key>pfsense.value[if_speedtest_value,{#IFNAME},download]</key>
</item>
</graph_item>
<graph_item>
<sortorder>1</sortorder>
<drawtype>0</drawtype>
<color>FFFF00</color>
<yaxisside>0</yaxisside>
<calc_fnc>7</calc_fnc>
<type>0</type>
<item>
<host>pfSense Active Speedtest</host>
<key>pfsense.value[if_speedtest_value,{#IFNAME},upload]</key>
</item>
</graph_item>
<graph_item>
<sortorder>2</sortorder>
<drawtype>0</drawtype>
<color>0040FF</color>
<yaxisside>0</yaxisside>
<calc_fnc>7</calc_fnc>
<type>0</type>
<item>
<host>pfSense Active Speedtest</host>
<key>pfsense.value[if_speedtest_value,{#IFNAME},ping]</key>
</item>
</graph_item>
</graph_items>
</graph_prototype>
</graph_prototypes>
<host_prototypes/>
<jmx_endpoint/>
<timeout>3s</timeout>
<url/>
<query_fields/>
<posts/>
<status_codes>200</status_codes>
<follow_redirects>1</follow_redirects>
<post_type>0</post_type>
<http_proxy/>
<headers/>
<retrieve_mode>0</retrieve_mode>
<request_method>0</request_method>
<allow_traps>0</allow_traps>
<ssl_cert_file/>
<ssl_key_file/>
<ssl_key_password/>
<verify_peer>0</verify_peer>
<verify_host>0</verify_host>
</discovery_rule>
</discovery_rules>
<httptests/>
<macros/>
<templates/>
<screens/>
</template>
</templates>
</zabbix_export>