Added DHCP Failover Monitoring, Renamed CARP section to HA

This commit is contained in:
Riccardo Bicelli 2021-01-23 16:54:32 +01:00
parent 7c9c5e66e5
commit 0f279ff310
3 changed files with 283 additions and 8 deletions

View File

@ -42,6 +42,12 @@ mkdir /root/scripts
curl -o /root/scripts/pfsense_zbx.php https://raw.githubusercontent.com/rbicelli/pfsense-zabbix-template/master/pfsense_zbx.php
```
or, from **Diagnostics/Command Prompt** input this one-liner:
```bash
mkdir /root/scripts && curl -o /root/scripts/pfsense_zbx.php https://raw.githubusercontent.com/rbicelli/pfsense-zabbix-template/master/pfsense_zbx.php
```
Then install package "Zabbix Agent 4" on your pfSense Box

View File

@ -26,7 +26,6 @@ require_once('pkg-utils.inc');
//For DHCP
//Testing function, for template creating purpose
function pfz_test(){
$line = "-------------------\n";
@ -666,6 +665,175 @@ function pfz_carp_status($echo = true){
}
// DHCP Checks (copy of status_dhcp_leases.php, waiting for pfsense 2.5)
function pfz_remove_duplicate($array, $field) {
foreach ($array as $sub) {
$cmp[] = $sub[$field];
}
$unique = array_unique(array_reverse($cmp, true));
foreach ($unique as $k => $rien) {
$new[] = $array[$k];
}
return $new;
}
// Get DHCP Arrays (copied from status_dhcp_leases.php, waiting for pfsense 2.5, in order to use system_get_dhcpleases();)
function pfz_dhcp_get($valuekey) {
require_once("config.inc");
$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
$awk = "/usr/bin/awk";
/* this pattern sticks comments into a single array item */
$cleanpattern = "'{ gsub(\"#.*\", \"\");} { gsub(\";\", \"\"); print;}'";
/* We then split the leases file by } */
$splitpattern = "'BEGIN { RS=\"}\";} {for (i=1; i<=NF; i++) printf \"%s \", \$i; printf \"}\\n\";}'";
/* stuff the leases file in a proper format into a array by line */
@exec("/bin/cat {$leasesfile} 2>/dev/null| {$awk} {$cleanpattern} | {$awk} {$splitpattern}", $leases_content);
$leases_count = count($leases_content);
@exec("/usr/sbin/arp -an", $rawdata);
foreach ($leases_content as $lease) {
/* split the line by space */
$data = explode(" ", $lease);
/* walk the fields */
$f = 0;
$fcount = count($data);
/* with less than 20 fields there is nothing useful */
if ($fcount < 20) {
$i++;
continue;
}
while ($f < $fcount) {
switch ($data[$f]) {
case "failover":
$pools[$p]['name'] = trim($data[$f+2], '"');
$pools[$p]['name'] = "{$pools[$p]['name']} (" . convert_friendly_interface_to_friendly_descr(substr($pools[$p]['name'], 5)) . ")";
$pools[$p]['mystate'] = $data[$f+7];
$pools[$p]['peerstate'] = $data[$f+14];
$pools[$p]['mydate'] = $data[$f+10];
$pools[$p]['mydate'] .= " " . $data[$f+11];
$pools[$p]['peerdate'] = $data[$f+17];
$pools[$p]['peerdate'] .= " " . $data[$f+18];
$p++;
$i++;
continue 3;
case "lease":
$leases[$l]['ip'] = $data[$f+1];
$leases[$l]['type'] = $dynamic_string;
$f = $f+2;
break;
case "starts":
$leases[$l]['start'] = $data[$f+2];
$leases[$l]['start'] .= " " . $data[$f+3];
$f = $f+3;
break;
case "ends":
if ($data[$f+1] == "never") {
// Quote from dhcpd.leases(5) man page:
// If a lease will never expire, date is never instead of an actual date.
$leases[$l]['end'] = gettext("Never");
$f = $f+1;
} else {
$leases[$l]['end'] = $data[$f+2];
$leases[$l]['end'] .= " " . $data[$f+3];
$f = $f+3;
}
break;
case "tstp":
$f = $f+3;
break;
case "tsfp":
$f = $f+3;
break;
case "atsfp":
$f = $f+3;
break;
case "cltt":
$f = $f+3;
break;
case "binding":
switch ($data[$f+2]) {
case "active":
$leases[$l]['act'] = $active_string;
break;
case "free":
$leases[$l]['act'] = $expired_string;
$leases[$l]['online'] = $offline_string;
break;
case "backup":
$leases[$l]['act'] = $reserved_string;
$leases[$l]['online'] = $offline_string;
break;
}
$f = $f+1;
break;
case "next":
/* skip the next binding statement */
$f = $f+3;
break;
case "rewind":
/* skip the rewind binding statement */
$f = $f+3;
break;
case "hardware":
$leases[$l]['mac'] = $data[$f+2];
/* check if it's online and the lease is active */
if (in_array($leases[$l]['ip'], $arpdata_ip)) {
$leases[$l]['online'] = $online_string;
} else {
$leases[$l]['online'] = $offline_string;
}
$f = $f+2;
break;
case "client-hostname":
if ($data[$f+1] <> "") {
$leases[$l]['hostname'] = preg_replace('/"/', '', $data[$f+1]);
} else {
$hostname = gethostbyaddr($leases[$l]['ip']);
if ($hostname <> "") {
$leases[$l]['hostname'] = $hostname;
}
}
$f = $f+1;
break;
case "uid":
$f = $f+1;
break;
}
$f++;
}
$l++;
$i++;
/* slowly chisel away at the source array */
array_shift($leases_content);
}
/* remove duplicate items by mac address */
if (count($leases) > 0) {
$leases = pfz_remove_duplicate($leases, "ip");
}
if (count($pools) > 0) {
$pools = pfz_remove_duplicate($pools, "name");
asort($pools);
}
switch ($valuekey){
case "pools":
return $pools;
break;
case "failover":
return $failover;
break;
case "leases":
default:
return $leases;
}
}
function pfz_dhcpfailover_discovery(){
//System functions regarding DHCP Leases will be available in the upcoming release of pfSense, so let's wait
require_once("system.inc");
@ -685,6 +853,29 @@ function pfz_dhcpfailover_discovery(){
echo $json_string;
}
function pfz_dhcp_check_failover(){
// Check DHCP Failover Status
// Returns number of failover pools which state is not normal or
// different than peer state
$failover = pfz_dhcp_get("failover");
$ret = 0;
foreach ($failover as $f){
if ( ($f["mystate"]!="normal") || ($f["mystate"]!=$f["peerstate"])) {
$ret++;
}
}
return $ret;
}
function pfz_dhcp($section, $valuekey=""){
switch ($section){
case "failover":
echo pfz_dhcp_check_failover();
break;
default:
}
}
//Packages
function pfz_packages_uptodate(){
require_once("pkg-utils.inc");
@ -893,6 +1084,9 @@ switch (strtolower($argv[1])){
case "ipsec_ph2":
pfz_ipsec_ph2($argv[2],$argv[3]);
break;
case "dhcp":
pfz_dhcp($argv[2],$argv[3]);
break;
default:
pfz_test();
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
<version>4.0</version>
<date>2021-01-18T15:00:52Z</date>
<date>2021-01-23T15:53:03Z</date>
<groups>
<group>
<name>Templates/Network Devices</name>
@ -21,9 +21,6 @@ https://github.com/rbicelli/pfsense-zabbix-template</description>
</group>
</groups>
<applications>
<application>
<name>CARP</name>
</application>
<application>
<name>CPU</name>
</application>
@ -33,6 +30,9 @@ https://github.com/rbicelli/pfsense-zabbix-template</description>
<application>
<name>Gateways</name>
</application>
<application>
<name>HA</name>
</application>
<application>
<name>Memory</name>
</application>
@ -271,7 +271,7 @@ https://github.com/rbicelli/pfsense-zabbix-template</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>CARP</name>
<name>HA</name>
</application>
</applications>
<valuemap>
@ -745,7 +745,7 @@ https://github.com/rbicelli/pfsense-zabbix-template</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>CARP</name>
<name>HA</name>
</application>
</applications>
<valuemap>
@ -774,6 +774,65 @@ https://github.com/rbicelli/pfsense-zabbix-template</description>
<verify_host>0</verify_host>
<master_item/>
</item>
<item>
<name>DHCP Failover Pool Problems</name>
<type>7</type>
<snmp_community/>
<snmp_oid/>
<key>pfsense.value[dhcp,failover]</key>
<delay>120s</delay>
<history>90d</history>
<trends>365d</trends>
<status>0</status>
<value_type>3</value_type>
<allowed_hosts/>
<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>This value indicates, in a HA scenario, if DHCP failover pool partners are out of sync.</description>
<inventory_link>0</inventory_link>
<applications>
<application>
<name>HA</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>
<master_item/>
</item>
<item>
<name>Gateway Status Raw</name>
<type>7</type>
@ -5254,6 +5313,22 @@ or&#13;
<dependencies/>
<tags/>
</trigger>
<trigger>
<expression>{Template pfSense Active:pfsense.value[carp_status].last()}&gt;2</expression>
<recovery_mode>0</recovery_mode>
<recovery_expression/>
<name>DHCP Failover Problems on {HOST.NAME}</name>
<correlation_mode>0</correlation_mode>
<correlation_tag/>
<url>https://docs.netgate.com/pfsense/en/latest/troubleshooting/ha-dhcp-failover.html</url>
<status>0</status>
<priority>4</priority>
<description>One or more DHCP Pools are experiencing failover problems. This could potentially cause other problems in yourr network.</description>
<type>0</type>
<manual_close>0</manual_close>
<dependencies/>
<tags/>
</trigger>
<trigger>
<expression>{Template pfSense Active:system.uname.diff(0)}&gt;0</expression>
<recovery_mode>0</recovery_mode>
@ -5392,7 +5467,7 @@ or&#13;
<url/>
<status>0</status>
<priority>1</priority>
<description>Notify of new version of packages are available</description>
<description>New version of packages are available</description>
<type>0</type>
<manual_close>0</manual_close>
<dependencies/>