From 0ee61548f0d7535fe664a2f16584744160710d89 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 15:06:58 +0000 Subject: [PATCH] Deploy to GitHub pages --- Extensions/RRDCached/index.html | 2 +- search/search_index.json | 2 +- sitemap.xml | 262 ++++++++++++++++---------------- sitemap.xml.gz | Bin 1433 -> 1433 bytes 4 files changed, 133 insertions(+), 133 deletions(-) diff --git a/Extensions/RRDCached/index.html b/Extensions/RRDCached/index.html index 23d71933..710004e1 100644 --- a/Extensions/RRDCached/index.html +++ b/Extensions/RRDCached/index.html @@ -3,7 +3,7 @@ C = Create RRD files. U = Update RRD files. T = Tune RRD files. -
Version Shared FS Features
1.4.x Yes G,U
<1.5.5 Yes G,U
>=1.5.5 No G,C,U
>=1.6.x No G,C,U

It is recommended that you monitor your LibreNMS server with LibreNMS so you can view the disk I/O usage delta.

Installation Manual for

  1. RRDCached installation Ubuntu 16
  2. RRDCached installation Debian Buster
  3. RRDCached installation Debian Stretch
  4. RRDCached installation CentOS 7 or 8
  5. RRDCached installation CentOS 6
  6. Securing RRCached

RRDCached installation Ubuntu 16

1: Install rrdcached

sudo apt-get install rrdcached
+
Version Shared FS Features
1.4.x Yes G,U
<1.5.5 Yes G,U
>=1.5.5 No G,C,U
>=1.6.x No G,C,U
>=1.8.x No G,C,U,T

It is recommended that you monitor your LibreNMS server with LibreNMS so you can view the disk I/O usage delta.

Installation Manual for

  1. RRDCached installation Ubuntu 16
  2. RRDCached installation Debian Buster
  3. RRDCached installation Debian Stretch
  4. RRDCached installation CentOS 7 or 8
  5. RRDCached installation CentOS 6
  6. Securing RRCached

RRDCached installation Ubuntu 16

1: Install rrdcached

sudo apt-get install rrdcached
 

2: Edit /etc/default/rrdcached to include:

DAEMON=/usr/bin/rrdcached
 DAEMON_USER=librenms
 DAEMON_GROUP=librenms
diff --git a/search/search_index.json b/search/search_index.json
index 98481d07..1f34bc7a 100644
--- a/search/search_index.json
+++ b/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":"Installing Install LibreNMS Now Install Using Docker Setup Applications Auto Discovery Oxidized RRDCached Alerting Rules Templates Transports More... API Using the API API Endpoints Support FAQ Install validation Performance tweaks More... Developing Getting Started Support for a new OS"},{"location":"API/","title":"Using the API","text":""},{"location":"API/#versioning","title":"Versioning","text":"

Versioning an API is a minefield which saw us looking at numerous options on how to do this.

We have currently settled on using versioning within the API end point itself /api/v0. As the API itself is new and still in active development we also decided that v0 would be the best starting point to indicate it's in development.

"},{"location":"API/#tokens","title":"Tokens","text":"

To access any of the token end points you will be required to authenticate using a token. Tokens can be created directly from within the LibreNMS web interface by going to /api-access/.

  • Click on 'Create API access token'.
  • Select the user you would like to generate the token for.
  • Enter an optional description.
  • Click Create API Token.
"},{"location":"API/#endpoints","title":"Endpoints","text":"

Whilst this documentation will describe and show examples of the end points, we've designed the API so you should be able to traverse through it without knowing any of the available API routes.

You can do this by first calling /api/v0:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0\n

Output:

{\n \"list_bgp\": \"https://librenms.org/api/v0/bgp\",\n  ...\n \"edit_rule\": \"https://librenms.org/api/v0/rules\"\n}\n
"},{"location":"API/#input","title":"Input","text":"

Input to the API is done in three different ways, sometimes a combination of two or three of these.

  • Passing parameters via the api route. For example when obtaining a devices details you will pass the hostname of the device in the route: /api/v0/devices/:hostname.
  • Passing parameters via the query string. For example you can list all devices on your install but limit the output to devices that are currently down: /api/v0/devices?type=down
  • Passing data in via JSON, this will mainly be used when adding or updating information via the API, for instance adding a new device:
curl -X POST -d '{\"hostname\":\"localhost.localdomain\",\"version\":\"v1\",\"community\":\"public\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices\n
"},{"location":"API/#output","title":"Output","text":"

Output from the API currently is via two output types:

  • JSON: Most API responses will output json. As shown in the example for calling the API endpoint.
  • PNG: This is for when the request is for an image such as a graph for a switch port.
"},{"location":"API/#endpoint-categories","title":"Endpoint Categories","text":"
  • Devices
  • DeviceGroups
  • Ports
  • Port_Groups
  • PortGroups
  • Alerts
  • Routing
  • Switching
  • Inventory
  • Bills
  • ARP
  • Services
  • Logs
  • System
  • Locations
"},{"location":"API/ARP/","title":"ARP","text":""},{"location":"API/ARP/#list_arp","title":"list_arp","text":"

Retrieve a specific ARP entry or all ARP entries for a device

Route: /api/v0/resources/ip/arp/:query

Query can be: - An IP address - A MAC address - A CIDR network (192.168.1.0/24) - all and set ?device=hostname (or device id)

Input:

  • device if you specify all for the query then you need to populate this with the hostname or id of the device.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/1.1.1.1\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/192.168.1.0/24\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/all?device=localhost\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"arp\": [\n        {\n            \"port_id\": \"229\",\n            \"mac_address\": \"da160e5c2002\",\n            \"ipv4_address\": \"1.1.1.1\",\n            \"context_name\": \"\"\n        }\n    ]\n}\n
"},{"location":"API/Alerts/","title":"Alerts","text":""},{"location":"API/Alerts/#get_alert","title":"get_alert","text":"

Get details of an alert

Route: /api/v0/alerts/:id

  • id is the alert id, you can obtain a list of alert ids from list_alerts.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts/1\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 7,\n \"alerts\": [\n  {\n   \"hostname\": \"localhost\",\n   \"id\": \"1\",\n   \"device_id\": \"1\",\n   \"rule_id\": \"1\",\n   \"state\": \"1\",\n   \"alerted\": \"1\",\n   \"open\": \"1\",\n   \"timestamp\": \"2014-12-11 14:40:02\"\n  }]\n}\n
"},{"location":"API/Alerts/#ack_alert","title":"ack_alert","text":"

Acknowledge an alert

Route: /api/v0/alerts/:id

  • id is the alert id, you can obtain a list of alert ids from list_alerts.
  • note is the note to add to the alert
  • until_clear is a boolean and if set to false, the alert will re-alert if it worsens/betters.

Input:

-

Example:

curl -X PUT -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts/1\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"message\": \"Alert has been acknowledged\"\n}\n
"},{"location":"API/Alerts/#unmute_alert","title":"unmute_alert","text":"

Unmute an alert

Route: /api/v0/alerts/unmute/:id

  • id is the alert id, you can obtain a list of alert ids from list_alerts.

Input:

-

Example:

curl -X PUT -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts/unmute/1\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"Alert has been unmuted\"\n}\n
"},{"location":"API/Alerts/#list_alerts","title":"list_alerts","text":"

List all alerts

Route: /api/v0/alerts

Input:

  • state: Filter the alerts by state, 0 = ok, 1 = alert, 2 = ack
  • severity: Filter the alerts by severity. Valid values are ok, warning, critical.
  • alert_rule: Filter alerts by alert rule ID.
  • order: How to order the output, default is by timestamp (descending). Can be appended by DESC or ASC to change the order.

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?state=1\n
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?severity=critical\n
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?order=timestamp%20ASC\n
curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?alert_rule=49\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"alerts\": [\n  {\n   \"id\": \"1\",\n   \"device_id\": \"1\",\n   \"rule_id\": \"1\",\n   \"state\": \"1\",\n   \"alerted\": \"1\",\n   \"open\": \"1\",\n   \"timestamp\": \"2014-12-11 14:40:02\"\n  }]\n}\n
"},{"location":"API/Alerts/#rules","title":"Rules","text":""},{"location":"API/Alerts/#get_alert_rule","title":"get_alert_rule","text":"

Get the alert rule details.

Route: /api/v0/rules/:id

  • id is the rule id.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules/1\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"rules\": [\n  {\n   \"id\": \"1\",\n   \"device_id\": \"1\",\n   \"rule\": \"%devices.os != \\\"Juniper\\\"\",\n   \"severity\": \"warning\",\n   \"extra\": \"{\\\"mute\\\":true,\\\"count\\\":\\\"15\\\",\\\"delay\\\":null,\\\"invert\\\":false}\",\n   \"disabled\": \"0\",\n   \"name\": \"A test rule\"\n  }\n ]\n}\n
"},{"location":"API/Alerts/#delete_rule","title":"delete_rule","text":"

Delete an alert rule by id

Route: /api/v0/rules/:id

  • id is the rule id.

Input:

-

Example:

curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules/1\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"message\": \"Alert rule has been removed\"\n}\n
"},{"location":"API/Alerts/#list_alert_rules","title":"list_alert_rules","text":"

List the alert rules.

Route: /api/v0/rules

-

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"rules\": [\n  {\n   \"id\": \"1\",\n   \"device_id\": \"-1\",\n   \"rule\": \"%devices.os != \\\"Juniper\\\"\",\n   \"severity\": \"critical\",\n   \"extra\": \"{\\\"mute\\\":false,\\\"count\\\":\\\"15\\\",\\\"delay\\\":\\\"300\\\",\\\"invert\\\":false}\",\n   \"disabled\": \"0\",\n   \"name\": \"A test rule\"\n  }]\n}\n
"},{"location":"API/Alerts/#add_rule","title":"add_rule","text":"

Add a new alert rule.

Route: /api/v0/rules

-

Input (JSON):

  • devices: This is either an array of device ids or -1 for a global rule
  • builder: The rule which should be in the format entity.condition value (i.e devices.status != 0 for devices marked as down). It must be json encoded in the format rules are currently stored.
  • severity: The severity level the alert will be raised against, Ok, Warning, Critical.
  • disabled: Whether the rule will be disabled or not, 0 = enabled, 1 = disabled
  • count: This is how many polling runs before an alert will trigger and the frequency.
  • delay: Delay is when to start alerting and how frequently. The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
  • interval: How often to re-issue notifications while this alert is active,0 means notify once.The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
  • mute: If mute is enabled then an alert will never be sent but will show up in the Web UI (true or false).
  • invert: This would invert the rules check.
  • name: This is the name of the rule and is mandatory.
  • notes: Some informal notes for this rule

Example:

curl -X POST -d '{\"devices\":[1,2,3], \"name\": \"testrule\", \"builder\":{\"condition\":\"AND\",\"rules\":[{\"id\":\"devices.hostname\",\"field\":\"devices.hostname\",\"type\":\"string\",\"input\":\"text\",\"operator\":\"equal\",\"value\":\"localhost\"}],\"valid\":true},\"severity\": \"critical\",\"count\":15,\"delay\":\"5 m\",\"interval\":\"5 m\",\"mute\":false,\"notes\":\"This a note from the API\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules\n

Output:

{\n \"status\": \"ok\"\n}\n
"},{"location":"API/Alerts/#edit_rule","title":"edit_rule","text":"

Edit an existing alert rule

Route: /api/v0/rules

-

Input (JSON):

  • rule_id: You must specify the rule_id to edit an existing rule, if this is absent then a new rule will be created.
  • devices: This is either an array of device ids or -1 for a global rule
  • builder: The rule which should be in the format entity.condition value (i.e devices.status != 0 for devices marked as down). It must be json encoded in the format rules are currently stored.
  • severity: The severity level the alert will be raised against, Ok, Warning, Critical.
  • disabled: Whether the rule will be disabled or not, 0 = enabled, 1 = disabled
  • count: This is how many polling runs before an alert will trigger and the frequency.
  • delay: Delay is when to start alerting and how frequently. The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
  • interval: How often to re-issue notifications while this alert is active,0 means notify once.The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
  • mute: If mute is enabled then an alert will never be sent but will show up in the Web UI (true or false).
  • invert: This would invert the rules check.
  • name: This is the name of the rule and is mandatory.
  • notes: Some informal notes for this rule

Example:

curl -X PUT -d '{\"rule_id\":1,\"device_id\":\"-1\", \"name\": \"testrule\", \"builder\":{\"condition\":\"AND\",\"rules\":[{\"id\":\"devices.hostname\",\"field\":\"devices.hostname\",\"type\":\"string\",\"input\":\"text\",\"operator\":\"equal\",\"value\":\"localhost\"}],\"valid\":true},\"severity\": \"critical\",\"count\":15,\"delay\":\"5 m\",\"interval\":\"5 m\",\"mute\":false,\"notes\":\"This a note from the API\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules\n

Output:

{\n \"status\": \"ok\"\n}\n
"},{"location":"API/Bills/","title":"Bills","text":""},{"location":"API/Bills/#list_bills","title":"list_bills","text":"

Retrieve the list of bills currently in the system.

Route: /api/v0/bills /api/v0/bills?period=previous

Input:

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills?period=previous\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"bills\": [\n  {\n   \"bill_id\": \"1\",\n   \"bill_name\": \"Router bills\",\n   \"bill_type\": \"cdr\",\n   \"bill_cdr\": \"10000000\",\n   \"bill_day\": \"1\",\n   \"bill_quota\": \"0\",\n   \"rate_95th_in\": \"0\",\n   \"rate_95th_out\": \"0\",\n   \"rate_95th\": \"0\",\n   \"dir_95th\": \"in\",\n   \"total_data\": \"0\",\n   \"total_data_in\": \"0\",\n   \"total_data_out\": \"0\",\n   \"rate_average_in\": \"0\",\n   \"rate_average_out\": \"0\",\n   \"rate_average\": \"0\",\n   \"bill_last_calc\": \"2015-07-02 17:01:26\",\n   \"bill_custid\": \"Router\",\n   \"bill_ref\": \"Router\",\n   \"bill_notes\": \"Bill me\",\n   \"bill_autoadded\": \"0\",\n   \"ports_total\": \"0\",\n   \"allowed\": \"10Mbps\",\n   \"used\": \"0bps\",\n   \"percent\": 0,\n   \"overuse\": \"-\",\n   \"ports\": [\n       {\n           \"device_id\": \"168\",\n           \"port_id\": \"35146\",\n           \"ifName\": \"eth0\"\n       }\n   ]\n  }\n ]\n}\n
"},{"location":"API/Bills/#get_bill","title":"get_bill","text":"

Retrieve a specific bill

Route: /api/v0/bills/:id /api/v0/bills/:id?period=previous /api/v0/bills?ref=:ref /api/v0/bills?ref=:ref&period=previous /api/v0/bills?custid=:custid /api/v0/bills?custid=:custid&period=previous

  • id is the specific bill id
  • ref is the billing reference
  • custid is the customer reference
  • period=previous indicates you would like the data for the last complete period rather than the current period

Input:

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills?ref=:customerref\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills?custid=:custid\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"bills\": [\n  {\n   \"bill_id\": \"1\",\n   \"bill_name\": \"Router bills\",\n   \"bill_type\": \"cdr\",\n   \"bill_cdr\": \"10000000\",\n   \"bill_day\": \"1\",\n   \"bill_quota\": \"0\",\n   \"rate_95th_in\": \"0\",\n   \"rate_95th_out\": \"0\",\n   \"rate_95th\": \"0\",\n   \"dir_95th\": \"in\",\n   \"total_data\": \"0\",\n   \"total_data_in\": \"0\",\n   \"total_data_out\": \"0\",\n   \"rate_average_in\": \"0\",\n   \"rate_average_out\": \"0\",\n   \"rate_average\": \"0\",\n   \"bill_last_calc\": \"2015-07-02 17:01:26\",\n   \"bill_custid\": \"Router\",\n   \"bill_ref\": \"Router\",\n   \"bill_notes\": \"Bill me\",\n   \"bill_autoadded\": \"0\",\n   \"ports_total\": \"0\",\n   \"allowed\": \"10Mbps\",\n   \"used\": \"0bps\",\n   \"percent\": 0,\n   \"overuse\": \"-\",\n   \"ports\": [\n       {\n           \"device_id\": \"168\",\n           \"port_id\": \"35146\",\n           \"ifName\": \"eth0\"\n       }\n   ]\n  }\n ]\n}\n
"},{"location":"API/Bills/#get_bill_graph","title":"get_bill_graph","text":"

Retrieve a graph image associated with a bill.

NB: The graphs returned from this will always be png as they do not come from rrdtool, even if you have SVG set.

Route: `/api/v0/bills/:id/graphs/:graph_type

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits?from=1517443200\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits?from=1517443200&to=1517788800\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/monthly\n

Output:

Graph Image

"},{"location":"API/Bills/#get_bill_graphdata","title":"get_bill_graphdata","text":"

Retrieve the data used to draw a graph so it can be rendered in an external system

Route: /api/v0/bills/:id/graphdata/:graph_type

Input:

The reducefactor parameter is used to reduce the number of data points. Billing data has 5 minute granularity, so requesting a graph for a long time period will result in many data points. If not supplied, it will be automatically calculated. A reducefactor of 1 means return all items, 2 means half of the items etc.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200&to=1517788800\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200&to=1517788800&reducefactor=5\n

Output:

{ \"status\": \"ok\", \"graph_data\": { \"from\": \"1517443200\", \"to\": 1518196161, \"last\": \"1518195901\", \"in_data\": [ 103190525.20999999, 104949255.81 ], \"out_data\": [ 1102059.1299999999, 1079216.46 ], \"tot_data\": [ 104292584.33999999, 106028472.27 ], \"ticks\": [ \"1517750401\", \"1517756101\" ], \"rate_95th\": \"251880417\", \"rate_average\": \"146575554\", \"bill_type\": \"cdr\", \"max_in\": 9888289942, \"max_out\": 75848756, \"ave_in\": 18029660.242105871, \"ave_out\": 196447.38060137472, \"last_in\": 3790227.9500000002, \"last_out\": 122731.63333333333 } }

"},{"location":"API/Bills/#get_bill_history","title":"get_bill_history","text":"

Retrieve the history of specific bill

Route: /api/v0/bills/:id/history

Input:

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history\n

Output:

{\n \"status\": \"ok\",\n \"bill_history\": [\n    {\n        \"bill_hist_id\": \"1\",\n        \"bill_id\": \"1\",\n        \"updated\": \"2018-02-06 17:01:01\",\n        \"bill_datefrom\": \"2018-02-01 00:00:00\",\n        \"bill_dateto\": \"2018-02-28 23:59:59\",\n        \"bill_type\": \"CDR\",\n        \"bill_allowed\": \"100000000\",\n        \"bill_used\": \"229963765\",\n        \"bill_overuse\": \"129963765\",\n        \"bill_percent\": \"229.96\",\n        \"rate_95th_in\": \"229963765\",\n        \"rate_95th_out\": \"1891344\",\n        \"rate_95th\": \"229963765\",\n        \"dir_95th\": \"in\",\n        \"rate_average\": \"136527101\",\n        \"rate_average_in\": \"135123359\",\n        \"rate_average_out\": \"1403743\",\n        \"traf_in\": \"3235123452544\",\n        \"traf_out\": \"33608406566\",\n        \"traf_total\": \"3268731859110\",\n        \"bill_peak_out\": \"2782349290\",\n        \"bill_peak_in\": \"10161119\",\n        \"pdf\": null\n    }\n ],\n \"count\": 1,\n}\n
"},{"location":"API/Bills/#get_bill_history_graph","title":"get_bill_history_graph","text":"

Retrieve a graph of a previous period of a bill

NB: The graphs returned from this will always be png as they do not come from rrdtool, even if you have SVG set.

Route: /api/v0/bills/:id/history/:bill_hist_id/graphs/:graph_type

Input:

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/hour\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/day\n

Output:

(image)

"},{"location":"API/Bills/#get_bill_history_graphdata","title":"get_bill_history_graphdata","text":"

Retrieve the data for a graph of a previous period of a bill, to be rendered in an external system

Route: /api/v0/bills/:id/history/:bill_hist_id/graphdata/:graph_type

Input:

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/hour\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/day\n

Output:

"},{"location":"API/Bills/#delete_bill","title":"delete_bill","text":"

Delete a specific bill and all dependent data

Route: /api/v0/bills/:id

  • id is the specific bill id

Input:

Example:

curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Bill has been removed\"\n}\n
"},{"location":"API/Bills/#create_edit_bill","title":"create_edit_bill","text":"

Creates a new bill or updates an existing one

Route: /api/v0/bills

Method: POST

  • If you send an existing bill_id the call replaces all values it receives. For example if you send 2 ports it will delete the existing ports and add the the 2 new ports. So to add ports you have to get the current ports first and add them to your update call.

Input:

Example (create):

curl -X POST -d '{\"ports\":[ 1021 ],\"bill_name\":\"NEWBILL\",\"bill_day\":\"1\",\"bill_type\":\"quota\",\"bill_quota\":\"2000000000000\",\"bill_custid\":\"1337\",\"bill_ref\":\"reference1\",\"bill_notes\":\"mynote\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills\n

Example (set):

curl -X POST -d '{\"bill_id\":\"32\",\"ports\":[ 1021 ],\"bill_name\":\"NEWNAME\",\"bill_quota\":\"1000000000000\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills\n

Output:

{\n    \"status\": \"ok\",\n    \"bill_id\": 32\n}\n
"},{"location":"API/DeviceGroups/","title":"DeviceGroups","text":""},{"location":"API/DeviceGroups/#get_devicegroups","title":"get_devicegroups","text":"

List all device groups.

Route: /api/v0/devicegroups

Input (JSON):

-

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Found 1 device groups\",\n        \"count\": 1,\n        \"groups\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Testing\",\n            \"desc\": \"Testing\",\n            \"pattern\": \"%devices.status = \\\"1\\\" &&\"\n        }\n        ]\n    }\n]\n
"},{"location":"API/DeviceGroups/#add_devicegroup","title":"add_devicegroup","text":"

Add a new device group. Upon success, the ID of the new device group is returned and the HTTP response code is 201.

Route: /api/v0/devicegroups

Input (JSON):

  • name: required - The name of the device group
  • type: required - should be static or dynamic. Setting this to static requires that the devices input be provided
  • desc: optional - Description of the device group
  • rules: required if type == dynamic - A set of rules to determine which devices should be included in this device group
  • devices: required if type == static - A list of devices that should be included in this group. This is a static list of devices

Examples:

Dynamic Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups \\\n  --data-raw '\n{\n \"name\": \"New Device Group\", \n \"desc\": \"A very fancy dynamic group\",\n \"type\": \"dynamic\", \n \"rules\": \"{\\\"condition\\\":\\\"AND\\\",\\\"rules\\\":[{\\\"id\\\":\\\"access_points.name\\\",\\\"field\\\":\\\"access_points.name\\\",\\\"type\\\":\\\"string\\\",\\\"input\\\":\\\"text\\\",\\\"operator\\\":\\\"equal\\\",\\\"value\\\":\\\"accesspoint1\\\"}],\\\"valid\\\":true}\"\n}\n'\n

Output:

{\n    \"status\": \"ok\",\n    \"id\": 86,\n    \"message\": \"Device group New Device Group created\"\n}\n

Static Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups \\\n  -d '{\"name\":\"New Device Group\",\"type\":\"static\",\"devices\":[261,271]}'\n

Output:

{\n    \"status\": \"ok\",\n    \"id\": 86,\n    \"message\": \"Device group New Device Group created\"\n}\n
"},{"location":"API/DeviceGroups/#update_devicegroup","title":"update_devicegroup","text":"

Updates a device group.

Route: /api/v0/devicegroups/:name

  • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

Input (JSON):

  • name: optional - The name of the device group
  • type: optional - should be static or dynamic. Setting this to static requires that the devices input be provided
  • desc: optional - Description of the device group
  • rules: required if type == dynamic - A set of rules to determine which devices should be included in this device group
  • devices: required if type == static - A list of devices that should be included in this group. This is a static list of devices

Examples:

curl -X PATCH -d '{\"name\": \"NewLinuxServers\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/LinuxServers\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device group LinuxServers updated\"\n}\n
"},{"location":"API/DeviceGroups/#delete_devicegroup","title":"delete_devicegroup","text":"

Deletes a device group.

Route: /api/v0/devicegroups/:name

  • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

Input:

-

Examples:

curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/LinuxServers\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device group LinuxServers deleted\"\n}\n
"},{"location":"API/DeviceGroups/#get_devices_by_group","title":"get_devices_by_group","text":"

List all devices matching the group provided.

Route: /api/v0/devicegroups/:name

  • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

Input (JSON):

  • full: set to any value to return all data for the devices in a given group

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups/LinuxServers\n

Output:

[\n     {\n         \"status\": \"ok\",\n         \"message\": \"Found 3 in group LinuxServers\",\n         \"count\": 3,\n         \"devices\": [\n            {\n                \"device_id\": \"15\"\n            },\n            {\n                \"device_id\": \"18\"\n            },\n            {\n                \"device_id\": \"20\"\n            }\n         ]\n     }\n]\n
"},{"location":"API/DeviceGroups/#maintenance_devicegroup","title":"maintenance_devicegroup","text":"

Set a device group into maintenance mode.

Route: /api/v0/devicegroups/:name/maintenance

Input (JSON):

  • title: optional - Some title for the Maintenance Will be replaced with device group name if omitted
  • notes: optional - Some description for the Maintenance
  • start: optional - start time of Maintenance in full format Y-m-d H:i:00 eg: 2022-08-01 22:45:00 Current system time now() will be used if omitted
  • duration: required - Duration of Maintenance in format H:i / Hrs:Mins eg: 02:00

Example with start time:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups/Cisco%20switches/maintenance/ \\\n  --data-raw '\n{\n \"title\":\"Device group Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with start time\",\n  \"start\":\"2022-08-01 08:00:00\",\n  \"duration\":\"2:00\"\n}\n'\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device group Cisco switches (2) will begin maintenance mode at 2022-08-01 22:45:00 for 2:00h\"\n}\n

Example with no start time:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups/Cisco%20switches/maintenance/ \\\n  --data-raw '\n{\n \"title\":\"Device group Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with no start time\",\n  \"duration\":\"2:00\"\n}\n'\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device group Cisco switches (2) moved into maintenance mode for 2:00h\"\n}\n
"},{"location":"API/DeviceGroups/#add-devices-to-group","title":"Add devices to group","text":"

Add devices to a device group.

Route: /api/v0/devicegroups/:name/devices

  • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

Input (JSON):

  • devices: required - A list of devices to be added to the group.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups/devices \\\n  --data-raw '{\"devices\":[261,271]}'\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Devices added\"\n}\n
"},{"location":"API/DeviceGroups/#remove-devices-from-group","title":"Remove devices from group","text":"

Removes devices from a device group.

Route: /api/v0/devicegroups/:name/devices

  • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

Input (JSON):

  • devices: required - A list of devices to be removed from the group.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X DELETE https://librenms.org/api/v0/devicegroups/devices \\\n  --data-raw '{\"devices\":[261,271]}'\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Devices removed\"\n}\n
"},{"location":"API/Devices/","title":"Devices","text":""},{"location":"API/Devices/#del_device","title":"del_device","text":"

Delete a given device.

Route: /api/v0/devices/:hostname

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Removed device localhost\",\n    \"devices\": [\n        {\n            \"device_id\": \"1\",\n            \"hostname\": \"localhost\",\n            ...\n            \"serial\": null,\n            \"icon\": null\n        }\n    ]\n}\n
"},{"location":"API/Devices/#get_device","title":"get_device","text":"

Get details of a given device.

Route: /api/v0/devices/:hostname

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

Output:

{\n    \"status\": \"ok\",\n    \"devices\": [\n        {\n            \"device_id\": \"1\",\n            \"hostname\": \"localhost\",\n            ...\n            \"serial\": null,\n            \"icon\": null\n        }\n    ]\n}\n
"},{"location":"API/Devices/#discover_device","title":"discover_device","text":"

Trigger a discovery of given device.

Route: /api/v0/devices/:hostname/discover

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/discover\n

Output:

{\n    \"status\": \"ok\",\n    \"result\": {\n        \"status\": 0,\n        \"message\": \"Device will be rediscovered\"\n    },\n    \"count\": 2\n}\n
"},{"location":"API/Devices/#availability","title":"availability","text":"

Get calculated availabilities of given device.

Route: /api/v0/devices/:hostname/availability

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/availability\n

Output:

{\n    \"status\": \"ok\",\n    \"availability\": [\n        {\n            \"duration\": 86400,\n            \"availability_perc\": \"100.000000\"\n        },\n        {\n            \"duration\": 604800,\n            \"availability_perc\": \"100.000000\"\n        },\n        {\n            \"duration\": 2592000,\n            \"availability_perc\": \"99.946000\"\n        },\n        {\n            \"duration\": 31536000,\n            \"availability_perc\": \"99.994000\"\n        }\n    ],\n    \"count\": 4\n}\n
"},{"location":"API/Devices/#outages","title":"outages","text":"

Get detected outages of given device.

Route: /api/v0/devices/:hostname/outages

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/outages\n

Output:

{\n    \"status\": \"ok\",\n    \"outages\": [\n        {\n            \"going_down\": 1593194031,\n            \"up_again\": 1593194388\n        },\n        {\n            \"going_down\": 1593946507,\n            \"up_again\": 1593946863\n        },\n        {\n            \"going_down\": 1594628616,\n            \"up_again\": 1594628968\n        },\n        {\n            \"going_down\": 1594628974,\n            \"up_again\": 1594629339\n        },\n        {\n            \"going_down\": 1594638668,\n            \"up_again\": 1594638992\n        }\n    ],\n    \"count\": 5\n}\n
"},{"location":"API/Devices/#get_graphs","title":"get_graphs","text":"

Get a list of available graphs for a device, this does not include ports.

Route: /api/v0/devices/:hostname/graphs

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 3,\n    \"graphs\": [\n        {\n            \"desc\": \"Poller Time\",\n            \"name\": \"device_poller_perf\"\n        },\n        {\n            \"desc\": \"Ping Response\",\n            \"name\": \"device_ping_perf\"\n        },\n        {\n            \"desc\": \"System Uptime\",\n            \"name\": \"uptime\"\n        }\n    ]\n}\n
"},{"location":"API/Devices/#list_available_health_graphs","title":"list_available_health_graphs","text":"

This function allows to do three things:

  • Get a list of overall health graphs available.
  • Get a list of health graphs based on provided class.
  • Get the health sensors information based on ID.

Route: /api/v0/devices/:hostname/health(/:type)(/:sensor_id)

  • hostname can be either the device hostname or id
  • type (optional) is health type / sensor class
  • sensor_id (optional) is the sensor id to retrieve specific information.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 2,\n    \"graphs\": [\n        {\n            \"desc\": \"Airflow\",\n            \"name\": \"device_airflow\"\n        },\n        {\n            \"desc\": \"Voltage\",\n            \"name\": \"device_voltage\"\n        }\n    ]\n}\n

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_voltage\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 2,\n    \"graphs\": [\n        {\n            \"sensor_id\": \"1\",\n            \"desc\": \"Input Feed A\"\n        },\n        {\n            \"sensor_id\": \"2\",\n            \"desc\": \"Output Feed\"\n        }\n    ]\n}\n

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_voltage/1\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"graphs\": [\n        {\n            \"sensor_id\": \"1\",\n            \"sensor_deleted\": \"0\",\n            \"sensor_class\": \"voltage\",\n            \"device_id\": \"1\",\n            \"poller_type\": \"snmp\",\n            \"sensor_oid\": \".1.3.6.1.4.1.318.1.1.27.1.1.0\",\n            \"sensor_index\": \"1\",\n            \"sensor_type\": \"apc\",\n            \"sensor_descr\": \"Input\",\n            \"sensor_divisor\": \"1\",\n            \"sensor_multiplier\": \"1\",\n            \"sensor_current\": \"1\",\n            \"sensor_limit\": \"1.15\",\n            \"sensor_limit_warn\": null,\n            \"sensor_limit_low\": \"0.85\",\n            \"sensor_limit_low_warn\": null,\n            \"sensor_alert\": \"1\",\n            \"sensor_custom\": \"No\",\n            \"entPhysicalIndex\": null,\n            \"entPhysicalIndex_measured\": null,\n            \"lastupdate\": \"2017-01-13 13:50:26\",\n            \"sensor_prev\": \"1\"\n        }\n    ]\n}\n
"},{"location":"API/Devices/#list_available_wireless_graphs","title":"list_available_wireless_graphs","text":"

This function allows to do three things:

  • Get a list of overall wireless graphs available.
  • Get a list of wireless graphs based on provided class.
  • Get the wireless sensors information based on ID.

Route: /api/v0/devices/:hostname/wireless(/:type)(/:sensor_id)

  • hostname can be either the device hostname or id
  • type (optional) is wireless type / wireless class
  • sensor_id (optional) is the sensor id to retrieve specific information.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/wireless\n

Output:

{\n    \"status\": \"ok\",\n    \"graphs\": [\n        {\n            \"desc\": \"Ccq\",\n            \"name\": \"device_wireless_ccq\"\n        },\n        {\n            \"desc\": \"Clients\",\n            \"name\": \"device_wireless_clients\"\n        }\n    ],\n    \"count\": 2\n}\n

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/wireless/device_wireless_ccq\n

Output:

{\n    \"status\": \"ok\",\n    \"graphs\": [\n        {\n            \"sensor_id\": \"791\",\n            \"desc\": \"SSID: bast (ng)\"\n        },\n        {\n            \"sensor_id\": \"792\",\n            \"desc\": \"SSID: bast (na)\"\n        }\n    ],\n    \"count\": 2\n}\n

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_wireless_ccq/1\n

Output:

{\n    \"status\": \"ok\",\n    \"graphs\": [\n        {\n            \"sensor_id\": \"791\",\n            \"sensor_deleted\": \"0\",\n            \"sensor_class\": \"ccq\",\n            \"device_id\": \"381\",\n            \"sensor_index\": \"0\",\n            \"sensor_type\": \"unifi\",\n            \"sensor_descr\": \"SSID: bast (ng)\",\n            \"sensor_divisor\": \"10\",\n            \"sensor_multiplier\": \"1\",\n            \"sensor_aggregator\": \"sum\",\n            \"sensor_current\": \"100\",\n            \"sensor_prev\": \"100\",\n            \"sensor_limit\": null,\n            \"sensor_limit_warn\": null,\n            \"sensor_limit_low\": null,\n            \"sensor_limit_low_warn\": null,\n            \"sensor_alert\": \"1\",\n            \"sensor_custom\": \"No\",\n            \"entPhysicalIndex\": null,\n            \"entPhysicalIndex_measured\": null,\n            \"lastupdate\": \"2017-12-06 21:26:29\",\n            \"sensor_oids\": \"[\\\".1.3.6.1.4.1.41112.1.6.1.2.1.3.0\\\"]\",\n            \"access_point_id\": null\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Devices/#get_health_graph","title":"get_health_graph","text":"

Get a particular health class graph for a device, if you provide a sensor_id as well then a single sensor graph will be provided. If no sensor_id value is provided then you will be sent a stacked sensor graph.

Route: /api/v0/devices/:hostname/graphs/health/:type(/:sensor_id)

  • hostname can be either the device hostname or id
  • type is the name of the health graph as returned by list_available_health_graphs
  • sensor_id (optional) restricts the graph to return a particular health sensor graph.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/health/device_voltage\n

Output:

Output is a stacked graph for the health type provided.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/health/device_voltage/1\n

Output:

Output is the graph of the particular health type sensor provided.

"},{"location":"API/Devices/#get_wireless_graph","title":"get_wireless_graph","text":"

Get a particular wireless class graph for a device, if you provide a sensor_id as well then a single sensor graph will be provided. If no sensor_id value is provided then you will be sent a stacked wireless graph.

Route: /api/v0/devices/:hostname/graphs/wireless/:type(/:sensor_id)

  • hostname can be either the device hostname or id
  • type is the name of the wireless graph as returned by list_available_wireless_graphs
  • sensor_id (optional) restricts the graph to return a particular wireless sensor graph.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/wireless/device_wireless_ccq\n

Output:

Output is a stacked graph for the wireless type provided.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/wireless/device_wireless_ccq/1\n

Output:

Output is the graph of the particular wireless type sensor provided.

"},{"location":"API/Devices/#get_graph_generic_by_hostname","title":"get_graph_generic_by_hostname","text":"

Get a specific graph for a device, this does not include ports.

Route: /api/v0/devices/:hostname/:type

  • hostname can be either the device hostname or id
  • type is the type of graph you want, use [get_graphs](#function-get_graphs to see the graphs available. Defaults to device uptime.

Input:

  • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • width: The graph width, defaults to 1075.
  • height: The graph height, defaults to 300.
  • output: Set how the graph should be outputted (base64, display), defaults to display.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/device_poller_perf\n

Output:

Output is an image.

"},{"location":"API/Devices/#get_graph_by_service","title":"get_graph_by_service","text":"

Get the graph for a service

Route: /api/v0/devices/:hostname/services/:service_id/graphs/:datasource

  • hostname can be either the device hostname or id
  • service id
  • datasource is the name of the service datasource

Input:

  • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • width: The graph width, defaults to 1075.
  • height: The graph height, defaults to 300.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/localhost/35/graphs/loss\n

Output:

Output is an image.

"},{"location":"API/Devices/#get_port_graphs","title":"get_port_graphs","text":"

Get a list of ports for a particular device.

Route: /api/v0/devices/:hostname/ports

  • hostname can be either the device hostname or id

Input:

  • columns: Comma separated list of columns you want returned.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ports\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 3,\n    \"ports\": [\n        {\n            \"ifName\": \"lo\"\n        },\n        {\n            \"ifName\": \"eth0\"\n        },\n        {\n            \"ifName\": \"eth1\"\n        }\n    ]\n}\n
"},{"location":"API/Devices/#get_device_fdb","title":"get_device_fdb","text":"

Get a list of FDB entries associated with a device.

Route: /api/v0/devices/:hostname/fdb

  • hostname can be either the device hostname or id

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/fdb\n

Output:

{\n    \"status\": \"ok\",\n    \"ports_fdb\": {\n        \"ports_fdb_id\": 10,\n        \"port_id\": 10000,\n        \"mac_address\": \"1aaa2bbb3ccc\",\n        \"vlan_id\": 20000,\n        \"device_id\": 1,\n        \"created_at\": \"2019-01-1 01:01:01\",\n        \"updated_at\": \"2019-01-1 01:01:01\"\n    }\n}\n
"},{"location":"API/Devices/#get_device_ip_addresses","title":"get_device_ip_addresses","text":"

Get a list of IP addresses (v4 and v6) associated with a device.

Route: /api/v0/devices/:hostname/ip

  • hostname can be either the device hostname or id

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ip\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"addresses\": [\n        {\n          \"ipv4_address_id\": \"290\",\n          \"ipv4_address\": \"192.168.99.292\",\n          \"ipv4_prefixlen\": \"30\",\n          \"ipv4_network_id\": \"247\",\n          \"port_id\": \"323\",\n          \"context_name\": \"\"\n        }\n    ]\n}\n
"},{"location":"API/Devices/#get_port_stack","title":"get_port_stack","text":"

Get a list of port mappings for a device. This is useful for showing physical ports that are in a virtual port-channel.

Route: /api/v0/devices/:hostname/port_stack

  • hostname can be either the device hostname or id

Input:

  • valid_mappings: Filter the result by only showing valid mappings (\"0\" values not shown).

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/port_stack?valid_mappings\n

Output:

{\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"count\": 2,\n  \"mappings\": [\n    {\n      \"device_id\": \"3742\",\n      \"port_id_high\": \"1001000\",\n      \"port_id_low\": \"51001\",\n      \"ifStackStatus\": \"active\"\n    },\n    {\n      \"device_id\": \"3742\",\n      \"port_id_high\": \"1001000\",\n      \"port_id_low\": \"52001\",\n      \"ifStackStatus\": \"active\"\n    }\n  ]\n}\n
"},{"location":"API/Devices/#get_components","title":"get_components","text":"

Get a list of components for a particular device.

Route: /api/v0/devices/:hostname/components

  • hostname can be either the device hostname or id

Input:

  • type: Filter the result by type (Equals).
  • id: Filter the result by id (Equals).
  • label: Filter the result by label (Contains).
  • status: Filter the result by status (Equals).
  • disabled: Filter the result by disabled (Equals).
  • ignore: Filter the result by ignore (Equals).

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 3,\n    \"components\": {\n        \"2\": {\n            \"TestAttribute-1\": \"Value1\",\n            \"TestAttribute-2\": \"Value2\",\n            \"TestAttribute-3\": \"Value3\",\n            \"type\": \"TestComponent-1\",\n            \"label\": \"This is a really cool blue component\",\n            \"status\": \"1\",\n            \"ignore\": \"0\",\n            \"disabled\": \"0\"\n        },\n        \"20\": {\n            \"TestAttribute-1\": \"Value4\",\n            \"TestAttribute-2\": \"Value5\",\n            \"TestAttribute-3\": \"Value6\",\n            \"type\": \"TestComponent-1\",\n            \"label\": \"This is a really cool red component\",\n            \"status\": \"1\",\n            \"ignore\": \"0\",\n            \"disabled\": \"0\"\n        },\n        \"27\": {\n            \"TestAttribute-1\": \"Value7\",\n            \"TestAttribute-2\": \"Value8\",\n            \"TestAttribute-3\": \"Value9\",\n            \"type\": \"TestComponent-2\",\n            \"label\": \"This is a really cool yellow widget\",\n            \"status\": \"1\",\n            \"ignore\": \"0\",\n            \"disabled\": \"0\"\n        }\n    }\n}\n
"},{"location":"API/Devices/#add_components","title":"add_components","text":"

Create a new component of a type on a particular device.

Route: /api/v0/devices/:hostname/components/:type

  • hostname can be either the device hostname or id
  • type is the type of component to add

Example:

curl -X POST -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components/APITEST\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"components\": {\n        \"4459\": {\n            \"type\": \"APITEST\",\n            \"label\": \"\",\n            \"status\": 1,\n            \"ignore\": 0,\n            \"disabled\": 0,\n            \"error\": \"\"\n        }\n    }\n}\n
"},{"location":"API/Devices/#edit_components","title":"edit_components","text":"

Edit an existing component on a particular device.

Route: /api/v0/devices/:hostname/components

  • hostname can be either the device hostname or id

In this example we set the label and add a new field: TestField:

curl -X PUT -d '{\"4459\": {\"type\": \"APITEST\",\"label\": \"This is a test label\",\"status\": 1,\"ignore\": 0,\"disabled\": 0,\"error\": \"\",\"TestField\": \"TestData\"}}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1\n}\n

Just take the JSON array from add_components or edit_components, edit as you wish and submit it back to edit components.

"},{"location":"API/Devices/#delete_components","title":"delete_components","text":"

Delete an existing component on a particular device.

Route: /api/v0/devices/:hostname/components/:component

  • hostname can be either the device hostname or id
  • component is the component ID to be deleted.

Example:

curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components/4459\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\"\n}\n
"},{"location":"API/Devices/#get_port_stats_by_port_hostname","title":"get_port_stats_by_port_hostname","text":"

Get information about a particular port for a device.

Route: /api/v0/devices/:hostname/ports/:ifname

  • hostname can be either the device hostname or id
  • ifname can be any of the interface names for the device which can be obtained using get_port_graphs. Please ensure that the ifname is urlencoded if it needs to be (i.e Gi0/1/0 would need to be urlencoded.

Input:

  • columns: Comma separated list of columns you want returned.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ports/eth0\n

Output:

{\n \"status\": \"ok\",\n \"port\": {\n  \"port_id\": \"2\",\n  \"device_id\": \"1\",\n  ...\n  \"poll_prev\": \"1418412902\",\n  \"poll_period\": \"300\"\n }\n}\n
"},{"location":"API/Devices/#get_graph_by_port_hostname","title":"get_graph_by_port_hostname","text":"

Get a graph of a port for a particular device.

Route: /api/v0/devices/:hostname/ports/:ifname/:type

  • hostname can be either the device hostname or id
  • ifname can be any of the interface names for the device which can be obtained using get_port_graphs. Please ensure that the ifname is urlencoded if it needs to be (i.e Gi0/1/0 would need to be urlencoded.
  • type is the port type you want the graph for, you can request a list of ports for a device with get_port_graphs.

Input:

  • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • width: The graph width, defaults to 1075.
  • height: The graph height, defaults to 300.
  • ifDescr: If this is set to true then we will use ifDescr to lookup the port instead of ifName. Pass the ifDescr value you want to search as you would ifName.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ports/eth0/port_bits\n

Output:

Output is an image.

"},{"location":"API/Devices/#list_sensors","title":"list_sensors","text":"

Get a list of all Sensors.

Route: /api/v0/resources/sensors

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/sensors\n

Output:

{\n    \"status\": \"ok\",\n    \"sensors\": [\n        {\n            \"sensor_id\": 218810,\n            \"sensor_deleted\": 0,\n            \"sensor_class\": \"dbm\",\n            \"device_id\": 136,\n            \"poller_type\": \"snmp\",\n            \"sensor_oid\": \".1.3.6.1.4.1.2636.3.60.1.1.1.1.7.919\",\n            \"sensor_index\": \"tx-919\",\n            \"sensor_type\": \"junos\",\n            \"sensor_descr\": \"xe-2/1/4 Tx Power\",\n            \"group\": null,\n            \"sensor_divisor\": 100,\n            \"sensor_multiplier\": 1,\n            \"sensor_current\": -1.81,\n            \"sensor_limit\": 2,\n            \"sensor_limit_warn\": 0.5,\n            \"sensor_limit_low\": -9.7,\n            \"sensor_limit_low_warn\": -8.21,\n            \"sensor_alert\": 1,\n            \"sensor_custom\": \"No\",\n            \"entPhysicalIndex\": \"919\",\n            \"entPhysicalIndex_measured\": \"ports\",\n            \"lastupdate\": \"2019-02-18 02:47:09\",\n            \"sensor_prev\": -1.77,\n            \"user_func\": null\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Devices/#list_devices","title":"list_devices","text":"

Return a list of devices.

Route: /api/v0/devices

Input:

  • order: How to order the output, default is by hostname. Can be prepended by DESC or ASC to change the order.
  • type: can be one of the following to filter or search by:
  • all: All devices
  • active: Only not ignored and not disabled devices
  • ignored: Only ignored devices
  • up: Only devices that are up
  • down: Only devices that are down
  • disabled: Disabled devices
  • os: search by os type
  • mac: search by mac address
  • ipv4: search by IPv4 address
  • ipv6: search by IPv6 address (compressed or uncompressed)
  • location: search by location
  • location_id: search by location_id
  • hostname: search by hostname
  • sysName: search by sysName
  • display: search by display name
  • device_id: exact match by device-id
  • type: search by device type
  • query: If searching by, then this will be used as the input.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices?order=hostname%20DESC&type=down\n

Output:

{\n \"status\": \"ok\",\n \"count\": 1,\n \"devices\": [\n  {\n   \"device_id\": \"1\",\n   \"hostname\": \"localhost\",\n   ...\n   \"serial\": null,\n   \"icon\": null\n  }\n ]\n}\n

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices?type=mac&query=00000c9ff013\n

Output:

{\n \"status\": \"ok\",\n \"count\": 1,\n \"devices\": [\n  {\n   \"device_id\": \"1\",\n   \"hostname\": \"localhost\",\n   ...\n   \"serial\": null,\n   \"icon\": null\n  }\n ]\n}\n
"},{"location":"API/Devices/#device_under_maintenance","title":"device_under_maintenance","text":"

Get the current maintenance status of a device.

Route: /api/v0/devices/:hostname/maintenance

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/maintenance\n

Output:

{\n    \"status\": \"ok\",\n    \"is_under_maintenance\": true\n}\n
"},{"location":"API/Devices/#maintenance_device","title":"maintenance_device","text":"

Set a device into maintenance mode.

Route: /api/v0/devices/:hostname/maintenance

Input (JSON):

  • title: optional - Some title for the Maintenance Will be replaced with hostname if omitted
  • notes: optional - Some description for the Maintenance Will also be added to device notes if user prefs \"Add schedule notes to devices notes\" is set
  • start: optional - start time of Maintenance in full format Y-m-d H:i:00 eg: 2022-08-01 22:45:00 Current system time now() will be used if omitted
  • duration: required - Duration of Maintenance in format H:i / Hrs:Mins eg: 02:00

Example with start time:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devices/localhost/maintenance/ \\\n  --data-raw '\n \"title\":\"Device Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with start time\",\n  \"start\":\"2022-08-01 08:00:00\",\n  \"duration\":\"2:00\"\n}\n'\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device localhost (1) will begin maintenance mode at 2022-08-01 22:45:00 for 2:00h\"\n}\n

Example with no start time:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devices/localhost/maintenance/ \\\n  --data-raw '\n \"title\":\"Device Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with no start time\",\n  \"duration\":\"2:00\"\n}\n'\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device localhost (1) moved into maintenance mode for 2:00h\"\n}\n
"},{"location":"API/Devices/#add_device","title":"add_device","text":"

Add a new device. Most fields are optional. You may omit snmp credentials to attempt each system credential in order. See snmp.version, snmp.community, and snmp.v3

To guarantee device is added, use force_add. This will skip checks for duplicate device and snmp reachability, but not duplicate hostname.

Route: /api/v0/devices

Input (JSON):

Fields:

  • hostname (required): device hostname or IP
  • display: A string to display as the name of this device, defaults to hostname (or device_display_default setting). May be a simple template using replacements: {{ $hostname }}, {{ $sysName }}, {{ $sysName_fallback }}, {{ $ip }}
  • snmpver: SNMP version to use, v1, v2c or v3. During checks detection order is v2c,v3,v1
  • port: SNMP port (defaults to port defined in config).
  • transport: SNMP protocol (udp,tcp,udp6,tcp6) Defaults to transport defined in config.
  • port_association_mode: method to identify ports: ifIndex (default), ifName, ifDescr, ifAlias
  • poller_group: This is the poller_group id used for distributed poller setup. Defaults to 0.
  • location or location_id: set the location by text or location id

Options:

  • force_add: Skip all checks and attempts to detect credentials. Add the device as given directly to the database.
  • ping_fallback: if snmp checks fail, add the device as ping only instead of failing

SNMP v1 or v2c credentials:

  • community: Required for SNMP v1 or v2c.

SNMP v3 credentials:

  • authlevel: SNMP authlevel (noAuthNoPriv, authNoPriv, authPriv).
  • authname: SNMP Auth username
  • authpass: SNMP Auth password
  • authalgo: SNMP Auth algorithm (MD5, SHA) (SHA-224, SHA-256, SHA-384, SHA-512 if supported by your server)
  • cryptopass: SNMP Crypto Password
  • cryptoalgo: SNMP Crypto algorithm (AES, DES)

For ICMP only:

  • snmp_disable: set to true for ICMP only. Disables SNMP checks and polling.
  • os: OS short name for the device (defaults to ping).
  • sysName: sysName for the device.
  • hardware: Device hardware.

Example:

curl -X POST -d '{\"hostname\":\"localhost.localdomain\",\"version\":\"v1\",\"community\":\"public\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device localhost.localdomain (57) has been added successfully\",\n    \"devices\": [\n        {\n            \"device_id\": \"57\",\n            \"hostname\": \"localhost\",\n            ...\n            \"serial\": null,\n            \"icon\": null\n        }\n}\n
"},{"location":"API/Devices/#list_oxidized","title":"list_oxidized","text":"

List devices for use with Oxidized. If you have group support enabled then a group will also be returned based on your config.

LibreNMS will automatically map the OS to the Oxidized model name if they don't match.

Route: /api/v0/oxidized(/:hostname)

Input (JSON):

-

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized\n

Output:

[\n    {\n        \"hostname\": \"localhost\",\n        \"os\": \"linux\"\n    },\n    {\n        \"hostname\": \"otherserver\",\n        \"os\": \"linux\"\n    }\n]\n
"},{"location":"API/Devices/#update_device_field","title":"update_device_field","text":"

Update devices field in the database.

Route: /api/v0/devices/:hostname

  • hostname can be either the device hostname or id

Input (JSON):

  • field: The column name within the database (can be an array of fields)
  • data: The data to update the column with (can be an array of data))

Examples:

curl -X PATCH -d '{\"field\": \"notes\", \"data\": \"This server should be kept online\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Device notes has been updated\"\n    }\n]\n
"},{"location":"API/Devices/#update_device_port_notes","title":"update_device_port_notes","text":"

Update a device port notes field in the devices_attrs database.

Route: /api/v0/devices/:hostname/port/:portid

  • hostname can be either the device hostname or id
  • portid needs to be the port unique id (int).

Input (JSON): - notes: The string data to populate on the port notes field.

Examples:

curl -X PATCH -d '{\"notes\": \"This port is in a scheduled maintenance with the provider.\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/port/5\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Port notes field has been updated\"\n    }\n]\n
curl -X PATCH -d '{\"field\": [\"notes\",\"purpose\"], \"data\": [\"This server should be kept online\", \"For serving web traffic\"]}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Device fields have been updated\"\n    }\n]\n
"},{"location":"API/Devices/#rename_device","title":"rename_device","text":"

Rename device.

Route: /api/v0/devices/:hostname/rename/:new_hostname

  • hostname can be either the device hostname or id

Input:

-

Examples:

curl -X PATCH  -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/rename/localhost2\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Device has been renamed\"\n    }\n]\n
"},{"location":"API/Devices/#get_device_groups","title":"get_device_groups","text":"

List the device groups that a device is matched on.

Route: /api/v0/devices/:hostname/groups

  • hostname can be either the device hostname or id

Input (JSON):

-

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/groups\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Found 1 device groups\",\n        \"count\": 1,\n        \"groups\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Testing\",\n            \"desc\": \"Testing\",\n            \"pattern\": \"%devices.status = \\\"1\\\" &&\"\n        }\n        ]\n    }\n]\n
"},{"location":"API/Devices/#search_oxidized","title":"search_oxidized","text":"

search all oxidized device configs for a string.

Route: api/v0/oxidized/config/search/:searchstring

  • searchstring is the specific string you would like to search for.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized/config/search/vlan10\n

Output:

{\n    \"status\": \"ok\",\n    \"nodes\": [\n        {\n            \"node\": \"asr9k.librenms.org\",\n            \"full_name\": \"cisco\\/ASR9K.Librenms.org\"\n        },\n        {\n            \"node\": \"ios.Librenms.org\",\n            \"full_name\": \"cisco\\/ios.Librenms.org\"\n        }\n    ],\n    \"count\": 2\n}\n

"},{"location":"API/Devices/#get_oxidized_config","title":"get_oxidized_config","text":"

Returns a specific device's config from oxidized.

Route: api/v0/oxidized/config/:hostname

  • hostname is the Hostname or IP of the device used when adding the device to librenms.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized/config/router.corp.com\n

Output:

{\n    \"status\": \"ok\",\n    \"config\": \"DEVICE CONFIG HERE\"\n}\n

"},{"location":"API/Devices/#add_parents_to_host","title":"add_parents_to_host","text":"

Add one or more parents to a host.

Route: /api/v0/devices/:device/parents

Input (JSON):

  • parent_ids: one or more parent ids or hostnames

Example:

curl -X POST -d '{\"parent_ids\":\"15,16,17\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/1/parents\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Device dependencies have been saved\"\n}\n

"},{"location":"API/Devices/#delete_parents_from_host","title":"delete_parents_from_host","text":"

Deletes some or all the parents from a host.

Route: /api/v0/devices/:device/parents

Input (JSON):

  • parent_ids: One or more parent ids or hostnames, if not specified deletes all parents from host.

Example:

curl -X DELETE -d '{\"parent_ids\":\"15,16,17\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/1/parents\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"All device dependencies have been removed\"\n}\n

"},{"location":"API/Devices/#list_parents_of_host","title":"list_parents_of_host","text":"

This is not a seperate API call. Instead, you obtain the list of parents from list_devices. See that entry point for more detailed information.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' 'http://librenms.org/api/v0/devices?type=device_id&query=34'\n

Output:

{\n    \"status\": \"ok\",\n    \"devices\": [\n        {\n            ...\n            \"dependency_parent_id\": \"98,99\",\n            \"dependency_parent_hostname\": \"HOSTNAME1,HOSTNAME2\",\n            ...\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Inventory/","title":"Inventory","text":""},{"location":"API/Inventory/#get_inventory","title":"get_inventory","text":"

Retrieve the inventory for a device. If you call this without any parameters then you will only get part of the inventory. This is because a lot of devices nest each component, for instance you may initially have the chassis, within this the ports - 1 being an sfp cage, then the sfp itself. The way this API call is designed is to enable a recursive lookup. The first call will retrieve the root entry, included within this response will be entPhysicalIndex, you can then call for entPhysicalContainedIn which will then return the next layer of results. To retrieve all items together, see get_inventory_for_device.

Route: /api/v0/inventory/:hostname

  • hostname can be either the device hostname or the device id

Input:

  • entPhysicalClass: This is used to restrict the class of the inventory, for example you can specify chassis to only return items in the inventory that are labelled as chassis.
  • entPhysicalContainedIn: This is used to retrieve items within the inventory assigned to a previous component, for example specifying the chassis (entPhysicalIndex) will retrieve all items where the chassis is the parent.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/inventory/localhost?entPhysicalContainedIn=65536\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"inventory\": [\n        {\n            \"entPhysical_id\": \"2\",\n            \"device_id\": \"32\",\n            \"entPhysicalIndex\": \"262145\",\n            \"entPhysicalDescr\": \"Linux 3.3.5 ehci_hcd RB400 EHCI\",\n            \"entPhysicalClass\": \"unknown\",\n            \"entPhysicalName\": \"1:1\",\n            \"entPhysicalHardwareRev\": \"\",\n            \"entPhysicalFirmwareRev\": \"\",\n            \"entPhysicalSoftwareRev\": \"\",\n            \"entPhysicalAlias\": \"\",\n            \"entPhysicalAssetID\": \"\",\n            \"entPhysicalIsFRU\": \"false\",\n            \"entPhysicalModelName\": \"0x0002\",\n            \"entPhysicalVendorType\": \"zeroDotZero\",\n            \"entPhysicalSerialNum\": \"rb400_usb\",\n            \"entPhysicalContainedIn\": \"65536\",\n            \"entPhysicalParentRelPos\": \"-1\",\n            \"entPhysicalMfgName\": \"0x1d6b\",\n            \"ifIndex\": \"0\"\n        }\n    ]\n}\n
"},{"location":"API/Inventory/#get_inventory_for_device","title":"get_inventory_for_device","text":"

Retrieve the flattened inventory for a device. This retrieves all inventory items for a device regardless of their structure, and may be more useful for devices with with nested components.

Route: /api/v0/inventory/:hostname/all

  • hostname can be either the device hostname or the device id

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/inventory/localhost?entPhysicalContainedIn=65536\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"inventory\": [\n        {\n            \"entPhysical_id\": \"2\",\n            \"device_id\": \"32\",\n            \"entPhysicalIndex\": \"262145\",\n            \"entPhysicalDescr\": \"Linux 3.3.5 ehci_hcd RB400 EHCI\",\n            \"entPhysicalClass\": \"unknown\",\n            \"entPhysicalName\": \"1:1\",\n            \"entPhysicalHardwareRev\": \"\",\n            \"entPhysicalFirmwareRev\": \"\",\n            \"entPhysicalSoftwareRev\": \"\",\n            \"entPhysicalAlias\": \"\",\n            \"entPhysicalAssetID\": \"\",\n            \"entPhysicalIsFRU\": \"false\",\n            \"entPhysicalModelName\": \"0x0002\",\n            \"entPhysicalVendorType\": \"zeroDotZero\",\n            \"entPhysicalSerialNum\": \"rb400_usb\",\n            \"entPhysicalContainedIn\": \"65536\",\n            \"entPhysicalParentRelPos\": \"-1\",\n            \"entPhysicalMfgName\": \"0x1d6b\",\n            \"ifIndex\": \"0\"\n        }\n    ]\n}\n
"},{"location":"API/Locations/","title":"Locations","text":""},{"location":"API/Locations/#list_locations","title":"list_locations","text":"

Return a list of locations.

Route: /api/v0/resources/locations

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/locations\n

Output:

{\n    \"status\": \"ok\",\n    \"locations\": [\n        {\n            \"id\": \"1\",\n            \"location\": \"Example location, Example city, Example Country\",\n            \"lat\": \"-18.911436\",\n            \"lng\": \"47.517446\",\n            \"timestamp\": \"2017-04-01 02:40:05\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Locations/#add_location","title":"add_location","text":"

Add a new location

Route: /api/v0/locations/

Input:

  • location: name of the new location
  • lat: latitude
  • lng: longitude
  • fixed_coordinates: 0 if updated from the device or 1 if the coordinate is fixed (default is fixed if lat and lng are valid)

Example:

curl -X POST -d '{\"location\":\"Google\", \"lat\":\"37.4220041\",\"lng\":\"-122.0862462\"}' -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/locations\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Location added with id #45\"\n}\n
"},{"location":"API/Locations/#delete_location","title":"delete_location","text":"

Deletes an existing location

Route: /api/v0/locations/:location

  • location: name or id of the location to delete

Example:

curl -X DELETE -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/locations/Google\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Location Google has been deleted successfully\"\n\n}\n
"},{"location":"API/Locations/#edit_location","title":"edit_location","text":"

Edits a location

Route: /api/v0/locations/:location

  • location: name or id of the location to edit

Input:

  • lat: latitude
  • lng: longitude

Example:

curl -X PATCH -d '{\"lng\":\"100.0862462\"}' -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/locations/Google\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Location updated successfully\"\n}\n
"},{"location":"API/Locations/#get_location","title":"get_location","text":"

Gets a specific location

Route: /api/v0/location/:location

  • location: name or id of the location to get

Output:

{\n    \"status\": \"ok\",\n    \"get_location\": [\n        {\n            \"id\": 1,\n            \"location\": \"TEST\",\n            \"lat\": 00.000000,\n            \"lng\": 00.000000,\n            \"timestamp\": \"2023-01-01 00:00:00\",\n            \"fixed_coordinates\": 1\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Logs/","title":"Logs","text":"

All the list_*logs calls are aliased to list_logs.

Retrieve all logs or logs for a specific device.

  • id or hostname is the specific device

Input:

  • start: The page number to request.
  • limit: The limit of results to be returned.
  • from: The date and time or the event id to search from.
  • to: The data and time or the event id to search to.
"},{"location":"API/Logs/#list_eventlog","title":"list_eventlog","text":"

Route: /api/v0/logs/eventlog/:hostname

"},{"location":"API/Logs/#list_syslog","title":"list_syslog","text":"

Route: /api/v0/logs/syslog/:hostname

"},{"location":"API/Logs/#list_alertlog","title":"list_alertlog","text":"

Route: /api/v0/logs/alertlog/:hostname

"},{"location":"API/Logs/#list_authlog","title":"list_authlog","text":"

Route: /api/v0/logs/authlog/:hostname

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/eventlog/:hostname\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/syslog/:hostname?limit=20\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/eventlog/:hostname?limit=20&start=5&from=2017-07-22%2023:00:00\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/eventlog/:hostname?sortorder=DESC\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 5,\n    \"total\": \"15\",\n    \"logs\": [\n        {\n            \"hostname\": \"localhost\",\n            \"sysName\": \"web01.1.novalocal\",\n            \"event_id\": \"10050349\",\n            \"host\": \"279\",\n            \"device_id\": \"279\",\n            \"datetime\": \"2017-07-22 19:57:47\",\n            \"message\": \"ifAlias:  ->  <pptp-something-something-tunnel-something>\",\n            \"type\": \"interface\",\n            \"reference\": \"NULL\",\n            \"username\": \"\",\n            \"severity\": \"3\"\n        },\n        ....\n        {\n            \"hostname\": \"localhost\",\n            \"sysName\": \"web01.1.novalocal\",\n            \"event_id\": \"10050353\",\n            \"host\": \"279\",\n            \"device_id\": \"279\",\n            \"datetime\": \"2017-07-22 19:57:47\",\n            \"message\": \"ifHighSpeed:  ->  0\",\n            \"type\": \"interface\",\n            \"reference\": \"NULL\",\n            \"username\": \"\",\n            \"severity\": \"3\"\n        }\n    ]\n}\n
"},{"location":"API/Logs/#syslogsink","title":"syslogsink","text":"

Route: /api/v0/logs/syslogsink

Accept any json messages and passes to further syslog processing. single messages or an array of multiple messages is accepted. see Syslog for more details and logstash integration

Example

curl -L -X POST 'https://sink.librenms.org/api/v0/syslogsink/' -H 'X-Auth-Token: xxxxxxxLibreNMSApiToken' --data-raw '[   \n    {\n        \"msg\": \"kernel: minimum Message\",\n        \"host\": \"mydevice.fqdn.com\"\n    },\n    {\n        \"msg\": \"Line protocol on Interface GigabitEthernet1/0/41, changed state to up\",\n        \"facility\": 23,\n        \"priority\": \"189\",\n        \"program\": \"LINEPROTO-5-UPDOWN\",\n        \"host\": \"172.29.10.24\",\n        \"@timestamp\": \"2022-12-01T20:14:28.257Z\",\n        \"severity\": 5,\n        \"level\": \"ERROR\"\n    },\n    {\n        \"msg\": \"kernel: a unknown host\",\n        \"host\": \"unknown.fqdn.com\"\n    }\n]'\n

"},{"location":"API/PollerGroups/","title":"PollerGroups","text":""},{"location":"API/PollerGroups/#get_poller_group","title":"get_poller_group","text":"

Gets a specific poller group or all if none is specified

Route: /api/v0/poller_group/:poller_group

  • poller_group: optional name or id of the poller group to get

Output:

{\n    \"status\": \"ok\",\n    \"get_poller_group\": [\n        {\n            \"id\": 1,\n            \"group_name\": \"test\",\n            \"descr\": \"test group\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/PortGroups/","title":"PortGroups","text":""},{"location":"API/PortGroups/#get_graph_by_portgroup","title":"get_graph_by_portgroup","text":"

Get the graph based on the group type.

Route: /api/v0/portgroups/:group

  • group is the type of port group graph you want, I.e Transit, Peering, etc. You can specify multiple types comma separated.

Input:

  • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • width: The graph width, defaults to 1075.
  • height: The graph height, defaults to 300.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/portgroups/transit,peering\n

Output:

Output is an image.

"},{"location":"API/PortGroups/#get_graph_by_portgroup_multiport_bits","title":"get_graph_by_portgroup_multiport_bits","text":"

Get the graph based on the multiple port id separated by commas ,.

Route: /api/v0/portgroups/multiport/bits/:id

  • id is a comma separated list of port ids you want, I.e 1,2,3,4, etc. You can specify multiple IDs comma separated.

Input:

  • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
  • width: The graph width, defaults to 1075.
  • height: The graph height, defaults to 300.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/portgroups/multiport/bits/1,2,3\n

Output:

Output is an image.

"},{"location":"API/Port_Groups/","title":"Port_Groups","text":""},{"location":"API/Port_Groups/#get_port_groups","title":"get_port_groups","text":"

List all port groups.

Route: /api/v0/port_groups

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/port_groups\n

Output:

[\n    {\n        \"status\": \"ok\",\n        \"message\": \"Found 1 port groups\",\n        \"count\": 1,\n        \"groups\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Testing\",\n            \"desc\": \"Testing\"\n        }\n        ]\n    }\n]\n
"},{"location":"API/Port_Groups/#get_ports_by_group","title":"get_ports_by_group","text":"

List all ports matching the group provided.

Route: /api/v0/port_groups/:name

  • name Is the name of the port group which can be obtained using get_port_groups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

Params:

  • full: set to any value to return all data for the devices in a given group

Examples:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/port_groups/Billable\n

Output:

{\n    \"status\": \"ok\",\n    \"ports\": [\n        {\n            \"port_id\": 1376\n        },\n        {\n            \"port_id\": 2376\n        }\n    ],\n    \"count\": 2\n}\n
"},{"location":"API/Port_Groups/#add_port_group","title":"add_port_group","text":"

Add a new port group. Upon success, the ID of the new port group is returned and the HTTP response code is 201.

Route: /api/v0/port_groups

Input (JSON):

  • name: required - The name of the port group
  • desc: optional - Description of the port group

Examples:

Dynamic Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST \\\n  -d '{\"name\": \"New Port Group\", \\\n       \"desc\": \"A very fancy port group\"}' \\\n  https://librenms.org/api/v0/port_groups\n

Output:

{\n    \"status\": \"ok\",\n    \"id\": 86,\n    \"message\": \"Port group New Port Group created\"\n}\n
"},{"location":"API/Port_Groups/#assign_port_group","title":"assign_port_group","text":"

Assign a Port Group to a list of Ports

Route: /api/v0/port_groups/:port_group_id/assign

Input (JSON):

  • port_ids: required - List of Port Ids

Examples:

Dynamic Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' -X POST -d '{\"port_ids\": [\"4\",\"34\",\"25,\"983\"]}' https://librenms.org/api/v0/port_groups/3/assign\n

Output:

{\n    \"status\": \"ok\",\n    \"Port Ids 4, 34, 25, 983 have been added to Port Group Id 3\": 200\n}\n
"},{"location":"API/Port_Groups/#remove_port_group","title":"remove_port_group","text":"

Remove a Port Group from a list of Ports

Route: /api/v0/port_groups/:port_group_id/remove

Input (JSON):

  • port_ids: required - List of Port Ids

Examples:

Dynamic Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' -X POST -d '{\"port_ids\": [\"4\",\"34\",\"25,\"983\"]}' https://librenms.org/api/v0/port_groups/3/remove\n

Output:

{\n    \"status\": \"ok\",\n    \"Port Ids 4, 34, 25, 983 have been removed from Port Group Id 3\": 200\n}\n
"},{"location":"API/Ports/","title":"Ports","text":""},{"location":"API/Ports/#get_all_ports","title":"get_all_ports","text":"

Get info for all ports on all devices. Strongly recommend that you use the columns parameter to avoid pulling too much data.

Route: /api/v0/ports

-

Input:

  • columns: Comma separated list of columns you want returned.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports?columns=ifName%2Cport_id\n

Output:

{\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"ports\": [\n        {\n          \"ifName\": \"Gi0/0/0\",\n          \"port_id\": \"1\"\n        },\n        {\n          \"ifName\": \"Gi0/0/1\",\n          \"port_id\": \"2\"\n        },\n        ...\n        {\n          \"ifName\": \"Vlan 3615\",\n          \"port_id\": \"5488\"\n        }\n    ]\n}\n
"},{"location":"API/Ports/#search_ports","title":"search_ports","text":"

Search for ports matching the query.

Route: /api/v0/ports/search/:search

  • search string to search in fields: ifAlias, ifDescr, and ifName

Input:

  • columns: Comma separated list of columns you want returned.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/search/lo\n

Output:

{\n    \"status\": \"ok\",\n    \"ports\": [\n        {\n            \"device_id\": 1,\n            \"port_id\": 1,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 2,\n            \"port_id\": 3,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 3,\n            \"port_id\": 5,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        }\n    ]\n}\n
"},{"location":"API/Ports/#search_ports-in-specific-fields","title":"search_ports in specific field(s)","text":"

Specific search for ports matching the query.

Route: /api/v0/ports/search/:field/:search

  • field: comma separated list of field(s) to search
  • search: string to search in fields

Input:

  • columns: Comma separated list of columns you want returned.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/search/ifName/lo\n

Output:

{\n    \"status\": \"ok\",\n    \"ports\": [\n        {\n            \"device_id\": 1,\n            \"port_id\": 1,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 2,\n            \"port_id\": 3,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 3,\n            \"port_id\": 5,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        }\n    ]\n}\n
"},{"location":"API/Ports/#ports_with_associated_mac","title":"ports_with_associated_mac","text":"

Search for ports matching the search mac.

Route: /api/v0/ports/mac/:search?filter=first

  • search a mac address in fdb and print the ports ordered by the mac count of the associated port.

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/00:11:22:33:44:55\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/001122.334455?filter=first\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/001122334455?filter=first\n

Output:

{\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"port\": [\n    {\n      \"port_id\": \"323\",\n      \"device_id\": \"55\",\n      \"port_descr_type\": null,\n      \"port_descr_descr\": null,\n      \"port_descr_circuit\": null,\n      \"port_descr_speed\": null,\n      \"port_descr_notes\": null,\n      \"ifDescr\": \"GigabitEthernet0/0/0\",\n      \"ifName\": \"Gi0/0/0\",\n      \"portName\": null,\n      \"ifIndex\": \"1\",\n      \"ifSpeed\": \"1000000000\",\n      \"ifConnectorPresent\": \"true\",\n      \"ifPromiscuousMode\": \"false\",\n      \"ifHighSpeed\": \"1000\",\n      \"ifOperStatus\": \"up\",\n      \"ifOperStatus_prev\": null,\n      \"ifAdminStatus\": \"up\",\n      \"ifAdminStatus_prev\": null,\n      \"ifDuplex\": \"fullDuplex\",\n      \"ifMtu\": \"1560\",\n      \"ifType\": \"ethernetCsmacd\",\n      \"ifAlias\": \"ASR Interconnect Trunk\",\n      \"ifPhysAddress\": \"84bf20853e00\",\n      \"ifHardType\": null,\n      \"ifLastChange\": \"42407358\",\n      \"ifVlan\": \"\",\n      \"ifTrunk\": \"\",\n      \"ifVrf\": \"0\",\n      \"counter_in\": null,\n      \"counter_out\": null,\n      \"ignore\": \"0\",\n      \"disabled\": \"0\",\n      \"detailed\": \"0\",\n      \"deleted\": \"0\",\n      \"pagpOperationMode\": null,\n      \"pagpPortState\": null,\n      \"pagpPartnerDeviceId\": null,\n      \"pagpPartnerLearnMethod\": null,\n      \"pagpPartnerIfIndex\": null,\n      \"pagpPartnerGroupIfIndex\": null,\n      \"pagpPartnerDeviceName\": null,\n      \"pagpEthcOperationMode\": null,\n      \"pagpDeviceId\": null,\n      \"pagpGroupIfIndex\": null,\n      \"ifInUcastPkts\": \"128518576\",\n      \"ifInUcastPkts_prev\": \"128517284\",\n      \"ifInUcastPkts_delta\": \"1292\",\n      \"ifInUcastPkts_rate\": \"4\",\n      \"ifOutUcastPkts\": \"128510560\",\n      \"ifOutUcastPkts_prev\": \"128509268\",\n      \"ifOutUcastPkts_delta\": \"1292\",\n      \"ifOutUcastPkts_rate\": \"4\",\n      \"ifInErrors\": \"0\",\n      \"ifInErrors_prev\": \"0\",\n      \"ifInErrors_delta\": \"0\",\n      \"ifInErrors_rate\": \"0\",\n      \"ifOutErrors\": \"0\",\n      \"ifOutErrors_prev\": \"0\",\n      \"ifOutErrors_delta\": \"0\",\n      \"ifOutErrors_rate\": \"0\",\n      \"ifInOctets\": \"12827393730\",\n      \"ifInOctets_prev\": \"12827276736\",\n      \"ifInOctets_delta\": \"116994\",\n      \"ifInOctets_rate\": \"387\",\n      \"ifOutOctets\": \"14957481766\",\n      \"ifOutOctets_prev\": \"14957301765\",\n      \"ifOutOctets_delta\": \"180001\",\n      \"ifOutOctets_rate\": \"596\",\n      \"poll_time\": \"1483779150\",\n      \"poll_prev\": \"1483778848\",\n      \"poll_period\": \"302\"\n    }\n  ]\n}\n
"},{"location":"API/Ports/#get_port_info","title":"get_port_info","text":"

Get all info for a particular port.

Route: /api/v0/ports/:portid

  • portid must be an integer

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323\n

Output:

{\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"port\": [\n    {\n      \"port_id\": \"323\",\n      \"device_id\": \"55\",\n      \"port_descr_type\": null,\n      \"port_descr_descr\": null,\n      \"port_descr_circuit\": null,\n      \"port_descr_speed\": null,\n      \"port_descr_notes\": null,\n      \"ifDescr\": \"GigabitEthernet0/0/0\",\n      \"ifName\": \"Gi0/0/0\",\n      \"portName\": null,\n      \"ifIndex\": \"1\",\n      \"ifSpeed\": \"1000000000\",\n      \"ifConnectorPresent\": \"true\",\n      \"ifPromiscuousMode\": \"false\",\n      \"ifHighSpeed\": \"1000\",\n      \"ifOperStatus\": \"up\",\n      \"ifOperStatus_prev\": null,\n      \"ifAdminStatus\": \"up\",\n      \"ifAdminStatus_prev\": null,\n      \"ifDuplex\": \"fullDuplex\",\n      \"ifMtu\": \"1560\",\n      \"ifType\": \"ethernetCsmacd\",\n      \"ifAlias\": \"ASR Interconnect Trunk\",\n      \"ifPhysAddress\": \"84bf20853e00\",\n      \"ifHardType\": null,\n      \"ifLastChange\": \"42407358\",\n      \"ifVlan\": \"\",\n      \"ifTrunk\": \"\",\n      \"ifVrf\": \"0\",\n      \"counter_in\": null,\n      \"counter_out\": null,\n      \"ignore\": \"0\",\n      \"disabled\": \"0\",\n      \"detailed\": \"0\",\n      \"deleted\": \"0\",\n      \"pagpOperationMode\": null,\n      \"pagpPortState\": null,\n      \"pagpPartnerDeviceId\": null,\n      \"pagpPartnerLearnMethod\": null,\n      \"pagpPartnerIfIndex\": null,\n      \"pagpPartnerGroupIfIndex\": null,\n      \"pagpPartnerDeviceName\": null,\n      \"pagpEthcOperationMode\": null,\n      \"pagpDeviceId\": null,\n      \"pagpGroupIfIndex\": null,\n      \"ifInUcastPkts\": \"128518576\",\n      \"ifInUcastPkts_prev\": \"128517284\",\n      \"ifInUcastPkts_delta\": \"1292\",\n      \"ifInUcastPkts_rate\": \"4\",\n      \"ifOutUcastPkts\": \"128510560\",\n      \"ifOutUcastPkts_prev\": \"128509268\",\n      \"ifOutUcastPkts_delta\": \"1292\",\n      \"ifOutUcastPkts_rate\": \"4\",\n      \"ifInErrors\": \"0\",\n      \"ifInErrors_prev\": \"0\",\n      \"ifInErrors_delta\": \"0\",\n      \"ifInErrors_rate\": \"0\",\n      \"ifOutErrors\": \"0\",\n      \"ifOutErrors_prev\": \"0\",\n      \"ifOutErrors_delta\": \"0\",\n      \"ifOutErrors_rate\": \"0\",\n      \"ifInOctets\": \"12827393730\",\n      \"ifInOctets_prev\": \"12827276736\",\n      \"ifInOctets_delta\": \"116994\",\n      \"ifInOctets_rate\": \"387\",\n      \"ifOutOctets\": \"14957481766\",\n      \"ifOutOctets_prev\": \"14957301765\",\n      \"ifOutOctets_delta\": \"180001\",\n      \"ifOutOctets_rate\": \"596\",\n      \"poll_time\": \"1483779150\",\n      \"poll_prev\": \"1483778848\",\n      \"poll_period\": \"302\"\n    }\n  ]\n}\n
"},{"location":"API/Ports/#get_port_ip_info","title":"get_port_ip_info","text":"

Get all IP info (v4 and v6) for a given port id.

Route: /api/v0/ports/:portid/ip

  • portid must be an integer

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323/ip\n

Output:

{\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"addresses\": [\n    {\n      \"ipv4_address_id\": \"290\",\n      \"ipv4_address\": \"192.168.99.292\",\n      \"ipv4_prefixlen\": \"30\",\n      \"ipv4_network_id\": \"247\",\n      \"port_id\": \"323\",\n      \"context_name\": \"\"\n    }\n  ]\n}\n
"},{"location":"API/Ports/#get_port_description","title":"get_port_description","text":"

Get the description (ifAlias) for a given port id.

Route: /api/v0/ports/:portid/description

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323/description\n

Output:

{\n    \"status\": \"ok\",\n    \"port_description\": \"GigabitEthernet14\"\n}\n
"},{"location":"API/Ports/#update_port_description","title":"update_port_description","text":"

Change the description (ifAlias) for a given port id.

Route: /api/v0/ports/:portid/description

Input (JSON):

  • description: The string data to use as the new port description. Sending an empty string will reset the description to default.

Example:

curl -X PATCH -d '{\"description\": \"Out-of-Band Management Link\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323/description\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Port description updated.\"\n}\n

"},{"location":"API/Routing/","title":"Routing","text":""},{"location":"API/Routing/#list_bgp","title":"list_bgp","text":"

List the current BGP sessions.

Route: /api/v0/bgp

Input:

  • hostname = Either the devices hostname or id.
  • asn = The local ASN you would like to filter by
  • remote_asn = Filter by remote peer ASN
  • remote_address = Filter by remote peer address
  • local_address = Filter by local address
  • bgp_descr = Filter by BGP neighbor description
  • bgp_state = Filter by BGP session state (like established,idle...)
  • bgp_state = Filter by BGP admin state (start,stop,running...)
  • bgp_family = Filter by BGP address Family (4,6)

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?hostname=host.example.com\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?asn=1234\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?remote_asn=1234\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?local_address=1.1.1.1&remote_address=2.2.2.2\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_descr=UPSTREAM\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_state=established\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_adminstate=start\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_family=6\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_state=idle&bgp_descr=CORE&bgp_family=4\n

Output:

{\n \"status\": \"ok\",\n \"message\": \"\",\n \"bgp_sessions\": [\n        {\n            \"bgpPeer_id\": 1260,\n            \"device_id\": 7,\n            \"vrf_id\": null,\n            \"astext\": \"Acme Ltd\",\n            \"bgpPeerIdentifier\": \"2001:0DB8:0000:24cb:0000:0000:0000:0001\",\n            \"bgpPeerRemoteAs\": 65432,\n            \"bgpPeerState\": \"established\",\n            \"bgpPeerAdminStatus\": \"start\",\n            \"bgpPeerLastErrorCode\": 6,\n            \"bgpPeerLastErrorSubCode\": 2,\n            \"bgpPeerLastErrorText\": \"administrative shutdown\",\n            \"bgpPeerIface\": 268,\n            \"bgpLocalAddr\": \"2001:0DB8:0000:24cb:0000:0000:0000:0002\",\n            \"bgpPeerRemoteAddr\": \"0.0.0.0\",\n            \"bgpPeerDescr\": \"Another one #CORE\",\n            \"bgpPeerInUpdates\": 283882969,\n            \"bgpPeerOutUpdates\": 7008,\n            \"bgpPeerInTotalMessages\": 283883031,\n            \"bgpPeerOutTotalMessages\": 1386692,\n            \"bgpPeerFsmEstablishedTime\": 1628487,\n            \"bgpPeerInUpdateElapsedTime\": 0,\n            \"context_name\": \"\"\n        },\n    ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Routing/#get_bgp","title":"get_bgp","text":"

Retrieves a BGP session by ID

Route: /api/v0/bgp/:id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp/4\n

Output:

{\n    \"status\": \"ok\",\n    \"bgp_session\": [\n        {\n            \"bgpPeer_id\": \"4\",\n            \"device_id\": \"2\",\n            \"astext\": \"\",\n            \"bgpPeerIdentifier\": \"1234:1b80:1:12::2\",\n            \"bgpPeerRemoteAs\": \"54321\",\n            \"bgpPeerState\": \"established\",\n            \"bgpPeerAdminStatus\": \"running\",\n            \"bgpLocalAddr\": \"1234:1b80:1:12::1\",\n            \"bgpPeerRemoteAddr\": \"0.0.0.0\",\n            \"bgpPeerInUpdates\": \"3\",\n            \"bgpPeerOutUpdates\": \"1\",\n            \"bgpPeerInTotalMessages\": \"0\",\n            \"bgpPeerOutTotalMessages\": \"0\",\n            \"bgpPeerFsmEstablishedTime\": \"0\",\n            \"bgpPeerInUpdateElapsedTime\": \"0\",\n            \"context_name\": \"\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Routing/#edit_bgp_descr","title":"edit_bgp_descr","text":"

This is a POST type request Set the BGP session description by ID

Route: /api/v0/bgp/:id

Input:

  • id = The id of the BGP Peer Session.
  • bgp_descr = The description for the bgpPeerDescr field on the BGP Session.

Example:

curl -v -H 'X-Auth-Token: YOURAPITOKENHERE' --data '{\"bgp_descr\": \"Your description here\"}' https://librenms.org/api/v0/bgp/4\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"BGP description for peer X.X.X.X on device 1 updated to Your description here\"\n}\n
"},{"location":"API/Routing/#list_cbgp","title":"list_cbgp","text":"

List the current BGP sessions counters.

Route: /api/v0/routing/bgp/cbgp

Input:

  • hostname = Either the devices hostname or id

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/bgp/cbgp\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/bgp/cbgp?hostname=host.example.com\n

Output:

{\n    \"status\": \"ok\",\n    \"bgp_counters\": [\n        {\n            \"device_id\": \"9\",\n            \"bgpPeerIdentifier\": \"192.168.99.31\",\n            \"afi\": \"ipv4\",\n            \"safi\": \"multicast\",\n            \"AcceptedPrefixes\": \"2\",\n            \"DeniedPrefixes\": \"0\",\n            \"PrefixAdminLimit\": \"0\",\n            \"PrefixThreshold\": \"0\",\n            \"PrefixClearThreshold\": \"0\",\n            \"AdvertisedPrefixes\": \"11487\",\n            \"SuppressedPrefixes\": \"0\",\n            \"WithdrawnPrefixes\": \"10918\",\n            \"AcceptedPrefixes_delta\": \"-2\",\n            \"AcceptedPrefixes_prev\": \"2\",\n            \"DeniedPrefixes_delta\": \"0\",\n            \"DeniedPrefixes_prev\": \"0\",\n            \"AdvertisedPrefixes_delta\": \"-11487\",\n            \"AdvertisedPrefixes_prev\": \"11487\",\n            \"SuppressedPrefixes_delta\": \"0\",\n            \"SuppressedPrefixes_prev\": \"0\",\n            \"WithdrawnPrefixes_delta\": \"-10918\",\n            \"WithdrawnPrefixes_prev\": \"10918\",\n            \"context_name\": \"\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Routing/#list_ip_addresses","title":"list_ip_addresses","text":"

List all IPv4 and IPv6 addresses.

Route: /api/v0/resources/ip/addresses

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/addresses\n

Output:

{\n    \"status\": \"ok\",\n    \"ip_addresses\": [\n        {\n            \"ipv4_address_id\": \"69\",\n            \"ipv4_address\": \"127.0.0.1\",\n            \"ipv4_prefixlen\": \"8\",\n            \"ipv4_network_id\": \"55\",\n            \"port_id\": \"135\",\n            \"context_name\": \"\"\n        },\n        ...\n    ],\n    \"count\": 55\n}\n
"},{"location":"API/Routing/#get_network_ip_addresses","title":"get_network_ip_addresses","text":"

Get all IPv4 and IPv6 addresses for particular network.

Route: /api/v0/resources/ip/networks/:id/ip

  • id must be integer

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/networks/55/ip\n

Output:

{\n    \"status\": \"ok\",\n    \"addresses\": [\n        {\n            \"ipv4_address_id\": \"69\",\n            \"ipv4_address\": \"127.0.0.1\",\n            \"ipv4_prefixlen\": \"8\",\n            \"ipv4_network_id\": \"55\",\n            \"port_id\": \"135\",\n            \"context_name\": \"\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Routing/#list_ip_networks","title":"list_ip_networks","text":"

List all IPv4 and IPv6 networks.

Route: /api/v0/resources/ip/networks

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/networks\n

Output:

{\n    \"status\": \"ok\",\n    \"ip_networks\": [\n        {\n            \"ipv4_network_id\": \"1\",\n            \"ipv4_network\": \"127.0.0.0/8\",\n            \"context_name\": \"\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Routing/#list_ipsec","title":"list_ipsec","text":"

List the current IPSec tunnels which are active.

Route: /api/v0/routing/ipsec/data/:hostname

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/ipsec/data/localhost\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 0,\n    \"ipsec\": [\n        \"tunnel_id\": \"1\",\n        \"device_id\": \"1\",\n        \"peer_port\": \"0\",\n        \"peer_addr\": \"127.0.0.1\",\n        \"local_addr\": \"127.0.0.2\",\n        \"local_port\": \"0\",\n        \"tunnel_name\": \"\",\n        \"tunnel_status\": \"active\"\n    ]\n}\n

Please note, this will only show active VPN sessions not all configured.

"},{"location":"API/Routing/#list_ospf","title":"list_ospf","text":"

List the current OSPF neighbours.

Route: /api/v0/ospf

Input:

  • hostname = Either the devices hostname or id.

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ospf\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ospf?hostname=host.example.com\n

Output:

{\n \"status\": \"ok\",\n \"ospf_neighbours\": [\n        {\n            \"device_id\": \"1\",\n            \"port_id\": \"0\",\n            \"ospf_nbr_id\": \"172.16.1.145.0\",\n            \"ospfNbrIpAddr\": \"172.16.1.145\",\n            \"ospfNbrAddressLessIndex\": \"0\",\n            \"ospfNbrRtrId\": \"172.16.0.140\",\n            \"ospfNbrOptions\": \"82\",\n            \"ospfNbrPriority\": \"1\",\n            \"ospfNbrState\": \"full\",\n            \"ospfNbrEvents\": \"5\",\n            \"ospfNbrLsRetransQLen\": \"0\",\n            \"ospfNbmaNbrStatus\": \"active\",\n            \"ospfNbmaNbrPermanence\": \"dynamic\",\n            \"ospfNbrHelloSuppressed\": \"false\",\n            \"context_name\": \"\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Routing/#list_ospf_ports","title":"list_ospf_ports","text":"

List the current OSPF ports.

Route: /api/v0/ospf_ports

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ospf_ports\n

Output:

{\n \"status\": \"ok\",\n \"ospf_ports\": [\n        {\n          \"id\": 189086,\n          \"device_id\": 43,\n          \"port_id\": 2838,\n          \"ospf_port_id\": \"10.10.2.86.0\",\n          \"ospfIfIpAddress\": \"10.10.2.86\",\n          \"ospfAddressLessIf\": 0,\n          \"ospfIfAreaId\": \"0.0.0.0\",\n          \"ospfIfType\": \"pointToPoint\",\n          \"ospfIfAdminStat\": \"enabled\",\n          \"ospfIfRtrPriority\": 128,\n          \"ospfIfTransitDelay\": 1,\n          \"ospfIfRetransInterval\": 5,\n          \"ospfIfHelloInterval\": 10,\n          \"ospfIfRtrDeadInterval\": 40,\n          \"ospfIfPollInterval\": 90,\n          \"ospfIfState\": \"pointToPoint\",\n          \"ospfIfDesignatedRouter\": \"0.0.0.0\",\n          \"ospfIfBackupDesignatedRouter\": \"0.0.0.0\",\n          \"ospfIfEvents\": 33,\n          \"ospfIfAuthKey\": \"\",\n          \"ospfIfStatus\": \"active\",\n          \"ospfIfMulticastForwarding\": \"unicast\",\n          \"ospfIfDemand\": \"false\",\n          \"ospfIfAuthType\": \"0\",\n          \"ospfIfMetricIpAddress\": \"10.10.2.86\",\n          \"ospfIfMetricAddressLessIf\": 0,\n          \"ospfIfMetricTOS\": 0,\n          \"ospfIfMetricValue\": 10,\n          \"ospfIfMetricStatus\": \"active\",\n          \"context_name\": null\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Routing/#list_vrf","title":"list_vrf","text":"

List the current VRFs.

Route: /api/v0/routing/vrf

Input:

  • hostname = Either the devices hostname or id

OR

  • vrfname = The VRF name you would like to filter by

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf?hostname=host.example.com\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf?vrfname=Mgmt-vrf\n

Output:

{\n    \"status\": \"ok\",\n    \"vrfs\": [\n        {\n            \"vrf_id\": \"2\",\n            \"vrf_oid\": \"8.77.103.109.116.45.118.114.102\",\n            \"vrf_name\": \"Mgmt-vrf\",\n            \"mplsVpnVrfRouteDistinguisher\": \"\",\n            \"mplsVpnVrfDescription\": \"\",\n            \"device_id\": \"8\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Routing/#get_vrf","title":"get_vrf","text":"

Retrieves VRF by ID

Route: /api/v0/routing/vrf/:id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf/2\n

Output:

{\n    \"status\": \"ok\",\n    \"vrf\": [\n        {\n            \"vrf_id\": \"2\",\n            \"vrf_oid\": \"8.77.103.109.116.45.118.114.102\",\n            \"vrf_name\": \"Mgmt-vrf\",\n            \"mplsVpnVrfRouteDistinguisher\": \"\",\n            \"mplsVpnVrfDescription\": \"\",\n            \"device_id\": \"8\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Routing/#list_mpls_services","title":"list_mpls_services","text":"

List MPLS services

Route: /api/v0/routing/mpls/services

Input:

  • hostname = Either the devices hostname or id

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/services\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/services?hostname=host.example.com\n

Output:

{\n    \"status\": \"ok\",\n    \"mpls_services\": [\n        {\n            \"svc_id\": 1671,\n            \"svc_oid\": 27,\n            \"device_id\": 4,\n            \"svcRowStatus\": \"active\",\n            \"svcType\": \"tls\",\n            \"svcCustId\": 1,\n            \"svcAdminStatus\": \"up\",\n            \"svcOperStatus\": \"up\",\n            \"svcDescription\": \"\",\n            \"svcMtu\": 9008,\n            \"svcNumSaps\": 1,\n            \"svcNumSdps\": 0,\n            \"svcLastMgmtChange\": 2,\n            \"svcLastStatusChange\": 168,\n            \"svcVRouterId\": 0,\n            \"svcTlsMacLearning\": \"enabled\",\n            \"svcTlsStpAdminStatus\": \"disabled\",\n            \"svcTlsStpOperStatus\": \"down\",\n            \"svcTlsFdbTableSize\": 250,\n            \"svcTlsFdbNumEntries\": 0,\n            \"hostname\": \"host.example.com\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Routing/#list_mpls_saps","title":"list_mpls_saps","text":"

List MPLS SAPs

Route: /api/v0/routing/mpls/saps

Input:

  • hostname = Either the devices hostname or id

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/saps\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/saps?hostname=host.example.com\n

Output:

{\n    \"status\": \"ok\",\n    \"saps\": [\n        {\n            \"sap_id\": 1935,\n            \"svc_id\": 1660,\n            \"svc_oid\": 7,\n            \"sapPortId\": 16108921125,\n            \"ifName\": \"1/1/c2/1\",\n            \"device_id\": 3,\n            \"sapEncapValue\": \"0\",\n            \"sapRowStatus\": \"active\",\n            \"sapType\": \"epipe\",\n            \"sapDescription\": \"\",\n            \"sapAdminStatus\": \"up\",\n            \"sapOperStatus\": \"down\",\n            \"sapLastMgmtChange\": 2,\n            \"sapLastStatusChange\": 0,\n            \"hostname\": \"hostname=host.example.com\"\n         }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Services/","title":"Services","text":""},{"location":"API/Services/#list_services","title":"list_services","text":"

Retrieve all services

Route: /api/v0/services

Input:

  • state: only which have a certain state (valid options are 0=Ok, 1=Warning, 2=Critical).
  • type: service type, used sql LIKE to find services, so for tcp, use type=tcp for http use type=http

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services?state=2\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services?state=0&type=tcp\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"services\": [\n        [\n            {\n                \"service_id\": \"13\",\n                \"device_id\": \"1\",\n                \"service_ip\": \"demo1.yourdomian.net\",\n                \"service_type\": \"ntp_peer\",\n                \"service_desc\": \"NTP\",\n                \"service_param\": \"-H 192.168.1.10\",\n                \"service_ignore\": \"0\",\n                \"service_status\": \"0\",\n                \"service_changed\": \"1470962470\",\n                \"service_message\": \"NTP OK: Offset -0.000717 secs\",\n                \"service_disabled\": \"0\",\n                \"service_ds\": \"{\\\"offset\\\":\\\"s\\\"}\"\n            }\n        ],\n        [\n            {\n                \"service_id\": \"2\",\n                \"device_id\": \"2\",\n                \"service_ip\": \"demo2.yourdomian.net\",\n                \"service_type\": \"esxi_hardware.py\",\n                \"service_desc\": \"vmware hardware\",\n                \"service_param\": \"-H 192.168.1.11 -U USER -P PASS -p\",\n                \"service_ignore\": \"0\",\n                \"service_status\": \"0\",\n                \"service_changed\": \"1471702206\",\n                \"service_message\": \"OK - Server: Supermicro X9SCL/X9SCM s/n: 0123456789 System BIOS: 2.2 2015-02-20\",\n                \"service_disabled\": \"0\",\n                \"service_ds\": \"{\\\"P2Vol_0_Processor_1_Vcore\\\":\\\"\\\",\\\"P2Vol_1_System_Board_1_-12V\\\":\\\"\\\",\\\"P2Vol_2_System_Board_1_12V\\\":\\\"\\\",\\\"P2Vol_3_System_Board_1_3.3VCC\\\":\\\"\\\",\\\"P2Vol_4_System_Board_1_5VCC\\\":\\\"\\\",\\\"P2Vol_5_System_Board_1_AVCC\\\":\\\"\\\",\\\"P2Vol_6_System_Board_1_VBAT\\\":\\\"\\\",\\\"P2Vol_7_System_Board_1_\"\n            }\n        ]\n    ]\n}\n
"},{"location":"API/Services/#get_service_for_host","title":"get_service_for_host","text":"

Retrieve services for device

Route: /api/v0/services/:hostname

  • id or hostname is the specific device

Input:

  • state: only which have a certain state (valid options are 0=Ok, 1=Warning, 2=Critical).
  • type: service type, used sql LIKE to find services, so for tcp, use type=tcp for http use type=http

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/:hostname\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/:hostname?state=2\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/:hostname?state=0&type=tcp\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"services\": [\n        [\n            {\n                \"service_id\": \"2\",\n                \"device_id\": \"2\",\n                \"service_ip\": \"demo2.yourdomian.net\",\n                \"service_type\": \"esxi_hardware.py\",\n                \"service_desc\": \"vmware hardware\",\n                \"service_param\": \"-H 192.168.1.11 -U USER -P PASS -p\",\n                \"service_ignore\": \"0\",\n                \"service_status\": \"0\",\n                \"service_changed\": \"1471702206\",\n                \"service_message\": \"OK - Server: Supermicro X9SCL/X9SCM s/n: 0123456789 System BIOS: 2.2 2015-02-20\",\n                \"service_disabled\": \"0\",\n                \"service_ds\": \"{\\\"P2Vol_0_Processor_1_Vcore\\\":\\\"\\\",\\\"P2Vol_1_System_Board_1_-12V\\\":\\\"\\\",\\\"P2Vol_2_System_Board_1_12V\\\":\\\"\\\",\\\"P2Vol_3_System_Board_1_3.3VCC\\\":\\\"\\\",\\\"P2Vol_4_System_Board_1_5VCC\\\":\\\"\\\",\\\"P2Vol_5_System_Board_1_AVCC\\\":\\\"\\\",\\\"P2Vol_6_System_Board_1_VBAT\\\":\\\"\\\",\\\"P2Vol_7_System_Board_1_\"\n            }\n        ]\n    ]\n}\n
"},{"location":"API/Services/#add_service_for_host","title":"add_service_for_host","text":"

Add a service for device

Route: /api/v0/services/:hostname

  • id or hostname is the specific device

Input:

  • type: service type
  • ip: ip of the service
  • desc: description for the service
  • param: parameters for the service
  • ignore: ignore the service for checks

Example:

curl -X POST -d '{\"type\":\"ping\",\"ip\": \"192.168.1.10\",\"desc\":\"test ping\",\"param\": \"-t 10 -c 5\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/192.168.1.10\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Service ping has been added to device 192.168.1.10 (#10)\"\n}\n
"},{"location":"API/Services/#edit_service_from_host","title":"edit_service_from_host","text":"

Edits a service

Route: /api/v0/services/:service_id

  • service id

Input:

  • id: service id

Example:

curl -X PATCH -d '{\"service_disabled\":\"1\"}' 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/services/5\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Service updated successfully\"\n\n}\n
"},{"location":"API/Services/#delete_service_from_host","title":"delete_service_from_host","text":"

Deletes service from device

Route: /api/v0/services/:service_id

  • service id

Input:

  • id: service id

Example:

curl -X DELETE -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/services/35\n

Output:

{\n    \"status\": \"ok\",\n    \"message\": \"Service has been deleted successfully\"\n}\n
"},{"location":"API/Switching/","title":"Switching","text":""},{"location":"API/Switching/#list_vlans","title":"list_vlans","text":"

Get a list of all VLANs.

Route: /api/v0/resources/vlans

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/vlans\n

Output:

{\n    \"status\": \"ok\",\n    \"vlans\": [\n        {\n            \"vlan_id\": \"31\",\n            \"device_id\": \"10\",\n            \"vlan_vlan\": \"1\",\n            \"vlan_domain\": \"1\",\n            \"vlan_name\": \"default\",\n            \"vlan_type\": \"ethernet\",\n            \"vlan_mtu\": null\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Switching/#get_vlans","title":"get_vlans","text":"

Get a list of all VLANs for a given device.

Route: /api/v0/devices/:hostname/vlans

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/vlans\n

Output:

{\n    \"status\": \"ok\",\n    \"count\": 0,\n    \"vlans\": [\n    {\n   \"vlan_vlan\": \"1\",\n   \"vlan_domain\": \"1\",\n   \"vlan_name\": \"default\",\n   \"vlan_type\": \"ethernet\",\n   \"vlan_mtu\": null\n    }\n  ]\n}\n
"},{"location":"API/Switching/#list_links","title":"list_links","text":"

Get a list of all Links.

Route: /api/v0/resources/links

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/links\n

Output:

{\n    \"status\": \"ok\",\n    \"links\": [\n        {\n            \"id\": 10,\n            \"local_port_id\": 100,\n            \"local_device_id\": 1,\n            \"remote_port_id\": 200,\n            \"active\": 1,\n            \"protocol\": \"lldp\",\n            \"remote_hostname\": \"host2.example.com\",\n            \"remote_device_id\": 2,\n            \"remote_port\": \"xe-0/0/1\",\n            \"remote_platform\": null,\n            \"remote_version\": \"Example Router v.1.0\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Switching/#get_links","title":"get_links","text":"

Get a list of Links per giver device.

Route: /api/v0/devices/:hostname/links

  • hostname can be either the device hostname or id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/links\n

Output:

{\n    \"status\": \"ok\",\n    \"links\": [\n        {\n            \"id\": 10,\n            \"local_port_id\": 100,\n            \"local_device_id\": 1,\n            \"remote_port_id\": 200,\n            \"active\": 1,\n            \"protocol\": \"lldp\",\n            \"remote_hostname\": \"host2.example.com\",\n            \"remote_device_id\": 2,\n            \"remote_port\": \"xe-0/0/1\",\n            \"remote_platform\": null,\n            \"remote_version\": \"Example Router v.1.0\"\n        },\n        ...\n    ],\n    \"count\": 10\n}\n
"},{"location":"API/Switching/#get_link","title":"get_link","text":"

Retrieves Link by ID

Route: /api/v0/resources/links/:id

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/links/10\n

Output:

{\n    \"status\": \"ok\",\n    \"links\": [\n        {\n            \"id\": 10,\n            \"local_port_id\": 100,\n            \"local_device_id\": 1,\n            \"remote_port_id\": 200,\n            \"active\": 1,\n            \"protocol\": \"lldp\",\n            \"remote_hostname\": \"host2.example.com\",\n            \"remote_device_id\": 2,\n            \"remote_port\": \"xe-0/0/1\",\n            \"remote_platform\": null,\n            \"remote_version\": \"Example Router v.1.0\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"API/Switching/#list_fdb","title":"list_fdb","text":"

Get a list of all ports FDB.

Route: /api/v0/resources/fdb/:mac

  • mac is the specific MAC address you would like to query

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/fdb\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/fdb/1aaa2bbb3ccc\n

Output:

{\n    \"status\": \"ok\",\n    \"ports_fdb\": [\n        {\n            \"ports_fdb_id\": 10,\n            \"port_id\": 10000,\n            \"mac_address\": \"1aaa2bbb3ccc\",\n            \"vlan_id\": 20000,\n            \"device_id\": 1,\n            \"created_at\": \"2019-01-1 01:01:01\",\n            \"updated_at\": \"2019-01-1 01:01:01\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
"},{"location":"API/Switching/#list_fdb_detail","title":"list_fdb_detail","text":"

Get a list of all ports FDB with human readable device and interface names.

Route: /api/v0/resources/fdb/:mac/detail

  • mac is the specific MAC address you would like to query

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/fdb/1aaa2bbb3ccc/detail\n

Output:

{\n    'count': 7,\n    'mac': '9c:93:aa:bb:cc:dd',\n    'mac_oui': 'Xerox Corporation',\n    'ports_fdb': [\n        {\n            'hostname': 'hq-core1',\n            'ifName': 'ae10',\n            'last_seen': '2 hours ago',\n            'updated_at': '2023-05-17 03:19:15'\n        },\n        {\n            'hostname': 'hq-sw1',\n            'ifName': 'ge-0/0/0',\n            'last_seen': '3 hours ago',\n            'updated_at': '2023-05-17 02:02:06'\n        },\n        ...\n    ],\n    'status': 'ok'\n}\n

"},{"location":"API/System/","title":"System","text":""},{"location":"API/System/#system","title":"system","text":"

Display Librenms instance information.

Route: /api/v0/system

Input:

-

Example:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/system\n

Output:

{\n    \"status\": \"ok\",\n    \"system\": [\n        {\n            \"local_ver\": \"1.37-234-g19103ee\",\n            \"local_sha\": \"19103ee36f68f009272c15be22e5a7e10a8b0b85\",\n            \"local_date\": \"1526480966\",\n            \"local_branch\": \"master\",\n            \"db_schema\": 249,\n            \"php_ver\": \"7.2.2\",\n            \"database_ver\": \"MariaDB 5.5.56-MariaDB\",\n            \"rrdtool_ver\": \"1.4.8\",\n            \"netsnmp_ver\": \"NET-SNMP 5.7.2\"\n        }\n    ],\n    \"count\": 1\n}\n
"},{"location":"Alerting/","title":"Introduction","text":"

To get started, you first need some alert rules which will react to changes with your devices before raising an alert.

Creating alert rules

After that you also need to tell LibreNMS how to notify you when an alert is raised, this is done using Alert Transports.

Configuring alert transports

The next step is not strictly required but most people find it useful. Creating custom alert templates will help you get the benefit out of the alert system in general. Whilst we include a default template, it is limited in the data that you will receive in the alerts.

Configuring alert templates

"},{"location":"Alerting/#managing-alerts","title":"Managing alerts","text":"

When an alert has triggered you will see these in the Alerts -> Notifications page within the Web UI.

This list has a couple of options available to it and we'll explain what these are here.

"},{"location":"Alerting/#ack","title":"ACK","text":"

This column provides you visibility on the status of the alert:

This alert is currently active and sending alerts. Click this icon to acknowledge the alert.

This alert is currently acknowledged until the alert clears. Click this icon to un-acknowledge the alert.

This alert is currently acknowledged until the alert worsens or gets better, at which stage it will be automatically unacknowledged and alerts will resume. Click this icon to un-acknowledge the alert.

"},{"location":"Alerting/#notes","title":"Notes","text":"

This column will allow you access to the acknowledge/unacknowledge notes for this alert.

"},{"location":"Alerting/Creating-Transport/","title":"Creating a new Transport","text":""},{"location":"Alerting/Creating-Transport/#file-location","title":"File location","text":"

All transports are located in LibreNMS\\Alert\\Transport and the files are named after the Transport name. I.e Discord.php for Discord.

"},{"location":"Alerting/Creating-Transport/#transport-structure","title":"Transport structure","text":"

The following functions are required for a new transport to pass the unit tests:

deliverAlert() - This is function called within alerts to invoke the transport. Here you should do any post processing of the transport config to get it ready for use.

contact$Transport() - This is named after the transport so for Discord it would be contactDiscord(). This is what actually interacts with the 3rd party API, invokes the mail command or whatever you want your alert to do.

configTemplate() - This is used to define the form that will accept the transport config in the webui and then what data should be validated and how. Validation is done using Laravel validation

The following function is not required for new Transports and is for legacy reasons only. deliverAlertOld().

"},{"location":"Alerting/Creating-Transport/#documentation","title":"Documentation","text":"

Please don't forget to update the Transport file to include details of your new transport.

A table should be provided to indicate the form values that we ask for and examples. I.e:

Config Example Discord URL https://discordapp.com/api/webhooks/4515489001665127664/82-sf4385ysuhfn34u2fhfsdePGLrg8K7cP9wl553Fg6OlZuuxJGaa1d54fe Options username=myname"},{"location":"Alerting/Device-Dependencies/","title":"Device Dependencies","text":"

It is possible to set one or more parents for a device. The aim for that is, if all parent devices are down, alert contacts will not receive redundant alerts for dependent devices. This is very useful when you have an outage, say in a branch office, where normally you'd receive hundreds of alerts, but when this is properly configured, you'd only receive an alert for the parent hosts.

There are three ways to configure this feature. First one is from general settings of a device. The other two can be done in the 'Device Dependencies' item under 'Devices' menu. In this page, you can see all devices and with its parents. Clicking on the 'bin' icon will clear the dependency setting. Clicking on the 'pen' icon will let you edit or change the current setting for chosen device. There's also a 'Manage Device Dependencies' button on the top. This will let you set parents for multiple devices at once.

For an intro on getting started with Device Dependencies, take a look at our Youtube video

"},{"location":"Alerting/Entities/","title":"Entities","text":"

Entities as described earlier are based on the table and column names within the database, if you are unsure of what the entity is you want then have a browse around inside MySQL using show tables and desc <tablename>.

Below are some common entities that you can use within the alerting system. This list is not exhaustive and you should look at the MySQL database schema for the full list.

"},{"location":"Alerting/Entities/#devices","title":"Devices","text":"Entity Description devices.hostname The device hostname devices.sysName The device sysName devices.sysDescr The device sysDescr devices.hardware The device hardware devices.version The device os version devices.location The device location devices.status The status of the device, 1 devices.status_reason The reason the device was detected as down (icmp or snmp) devices.ignore If the device is ignored this will be set to 1 devices.disabled If the device is disabled this will be set to 1 devices.last_polled The the last polled datetime (yyyy-mm-dd hh:mm:ss) devices.type The device type such as network, server, firewall, etc."},{"location":"Alerting/Entities/#bgp-peers","title":"BGP Peers","text":"Entity Description bgpPeers.astext This is the description of the BGP Peer bgpPeers.bgpPeerIdentifier The IP address of the BGP Peer bgpPeers.bgpPeerRemoteAs The AS number of the BGP Peer bgpPeers.bgpPeerState The operational state of the BGP session bgpPeers.bgpPeerAdminStatus The administrative state of the BGP session bgpPeers.bgpLocalAddr The local address of the BGP session."},{"location":"Alerting/Entities/#ipsec-tunnels","title":"IPSec Tunnels","text":"Entity Description ipsec_tunnels.peer_addr The remote VPN peer address ipsec_tunnels.local_addr The local VPN address ipsec_tunnels.tunnel_status The VPN tunnels operational status."},{"location":"Alerting/Entities/#memory-pools","title":"Memory pools","text":"

Entity | Description |---|---| mempools.mempool_type | The memory pool type such as hrstorage, cmp and cemp mempools.mempool_descr | The description of the pool such as Physical memory, Virtual memory and System memory mempools.mempool_perc | The used percentage of the memory pool.

"},{"location":"Alerting/Entities/#ports","title":"Ports","text":"Entity Description ports.ifDescr The interface description ports.ifName The interface name ports.ifSpeed The port speed in bps ports.ifHighSpeed The port speed in mbps ports.ifOperStatus The operational status of the port (up or down) ports.ifAdminStatus The administrative status of the port (up or down) ports.ifDuplex Duplex setting of the port ports.ifMtu The MTU setting of the port."},{"location":"Alerting/Entities/#processors","title":"Processors","text":"Entity Description processors.processor_usage The usage of the processor as a percentage processors.processor_descr The description of the processor."},{"location":"Alerting/Entities/#storage","title":"Storage","text":"Entity Description storage.storage_descr The description of the storage storage.storage_perc The usage of the storage as a percentage."},{"location":"Alerting/Entities/#health-sensors","title":"Health / Sensors","text":"Entity Description sensors.sensor_desc The sensors description. sensors.sensor_current The current sensors value. sensors.sensor_prev The previous sensor value. sensors.lastupdate The sensors last updated datetime stamp."},{"location":"Alerting/Macros/","title":"Macros","text":"

Macros are shorthands to either portion of rules or pure SQL enhanced with placeholders.

You can define your own macros in your config.php.

Example macro-implementation of Debian-Devices

$config['alert']['macros']['rule']['is_debian'] = 'devices.features ~ \"@debian@\"';\n

And in the Rule:

...  macros.is_debian = 1 ...\n

This Example-macro is a Boolean-macro, it applies a form of filter to the set of results defined by the rule.

All macros that are not unary should return Boolean.

"},{"location":"Alerting/Macros/#device-boolean","title":"Device (Boolean)","text":"

Entity: macros.device

Description: Only select devices that aren't deleted, ignored or disabled.

Source: (devices.disabled = 0 AND devices.ignore = 0)

"},{"location":"Alerting/Macros/#device-is-up-boolean","title":"Device is up (Boolean)","text":"

Entity: macros.device_up

Description: Only select devices that are up.

Implies: macros.device

Source: (devices.status = 1 AND macros.device)

"},{"location":"Alerting/Macros/#device-is-down-boolean","title":"Device is down (Boolean)","text":"

Entity: macros.device_down

Description: Only select devices that are down.

Implies: macros.device

Source: (devices.status = 0 AND macros.device)

"},{"location":"Alerting/Macros/#port-boolean","title":"Port (Boolean)","text":"

Entity: macros.port

Description: Only select ports that aren't deleted, ignored or disabled.

Source: (ports.deleted = 0 AND ports.ignore = 0 AND ports.disabled = 0)

"},{"location":"Alerting/Macros/#port-is-up-boolean","title":"Port is up (Boolean)","text":"

Entity: macros.port_up

Description: Only select ports that are up and also should be up.

Implies: macros.port

Source: (ports.ifOperStatus = up AND ports.ifAdminStatus = up AND macros.port)

"},{"location":"Alerting/Macros/#port-is-down-boolean","title":"Port is down (Boolean)","text":"

Entity: macros.port_down

Description: Only select ports that are down.

Implies: macros.port

Source: (ports.ifOperStatus != \"up\" AND ports.ifAdminStatus != \"down\" AND macros.port)

"},{"location":"Alerting/Macros/#port-usage-in-percent-decimal","title":"Port-Usage in Percent (Decimal)","text":"

Entity: macros.port_usage_perc

Description: Return port-usage (max value of in and out) in percent.

Source: ((SELECT IF(ports.ifOutOctets_rate>ports.ifInOctets_rate, ports.ifOutOctets_rate, ports.ifInOctets_rate)*8) / ports.ifSpeed)*100

"},{"location":"Alerting/Macros/#time","title":"Time","text":""},{"location":"Alerting/Macros/#now-datetime","title":"Now (Datetime)","text":"

Entity: macros.now

Description: Alias of MySQL's NOW()

Source: NOW()

"},{"location":"Alerting/Macros/#past-n-minutes-datetime","title":"Past N Minutes (Datetime)","text":"

Entity: macros.past_$m

Description: Returns a MySQL Timestamp dated $ Minutes in the past. $ can only be a supported Resolution.

Example: macros.past_5m is Last 5 Minutes.

Resolution: 5,10,15,30,60

Source: DATE_SUB(NOW(),INTERVAL $ MINUTE)

"},{"location":"Alerting/Macros/#sensors-boolean","title":"Sensors (Boolean)","text":"

Entity: macros.sensor

Description: Only select sensors that aren't ignored.

Source: (sensors.sensor_alert = 1)

Entity: macros.sensor_port_link = 1

Description: Only selects sensors that have a port linked to them, the port is up and the device is up.

Source: (sensors.entity_link_type = \"port\" AND sensors.entity_link_index = ports.ifIndex AND macros.port_up AND macros.device_up))

"},{"location":"Alerting/Macros/#state-sensors-boolean","title":"State Sensors (Boolean)","text":"

Entity: macros.state_sensor_ok, macros.state_sensor_warning, macros.state_sensor_critical, macros.state_sensor_unknown

Description: Select state sensors by their generic status ok (0), warning (1), critical (2), unknown (3)

Source: (sensors.sensor_current = state_translations.state_value AND state_translations.state_generic_value = 2)

"},{"location":"Alerting/Macros/#misc-boolean","title":"Misc (Boolean)","text":""},{"location":"Alerting/Macros/#packet-loss","title":"Packet Loss","text":"

Entity: (macros.packet_loss_5m)

Description: Packet loss % value for the device within the last 5 minutes. BROKEN, only return 100 (down) or 0.

Example: macros.packet_loss_5m > 50

Entity: (macros.packet_loss_15m)

Description: Packet loss % value for the device within the last 15 minutes. BROKEN, only return 100 (down) or 0.

Example: macros.packet_loss_15m > 50

"},{"location":"Alerting/Macros/#ports-in-usage-perc-int","title":"Ports in usage perc (Int)","text":"

Entity: ((ports.ifInOctets_rate*8)/ports.ifSpeed)*100

Description: Port in used more than 50%

Example: `macros.port_in_usage_perc > 50

"},{"location":"Alerting/Macros/#ports-out-usage-perc-int","title":"Ports out usage perc (Int)","text":"

Entity: ((ports.ifOutOctets_rate*8)/ports.ifSpeed)*100

Description: Port out used more than 50%

Example: `macros.port_out_usage_perc > 50

"},{"location":"Alerting/Macros/#ports-now-down-boolean","title":"Ports now down (Boolean)","text":"

Entity: ports.ifOperStatus != ports.ifOperStatus_prev AND ports.ifOperStatus_prev = \"up\" AND ports.ifAdminStatus = \"up\"

Description: Ports that were previously up and have now gone down.

Example: macros.port_now_down = 1

"},{"location":"Alerting/Macros/#port-has-xdp-neighbour-boolean","title":"Port has xDP neighbour (Boolean)","text":"

Entity: %macros.port AND %links.local_port_id = %ports.port_id

Description: Ports that have an xDP (lldp, cdp, etc) neighbour.

Example: macros.port_has_xdp_neighbours = 1

"},{"location":"Alerting/Macros/#port-has-xdp-neighbour-already-known-in-librenms-boolean","title":"Port has xDP neighbour already known in LibreNMS (Boolean)","text":"

Entity: %macros.port_has_neighbours AND (%links.remote_port_id IS NOT NULL)

Description: Ports that have an xDP (lldp, cdp, etc) neighbour that is already known in libreNMS.

Example: macros.port_has_xdp_neighbours_device = 1

"},{"location":"Alerting/Macros/#device-component-down-junos","title":"Device component down [JunOS]","text":"

Entity: sensors.sensor_class = \"state\" AND sensors.sensor_current != \"6\" AND sensors.sensor_type = \"jnxFruState\" AND sensors.sensor_current != \"2\"

Description: Device component is down such as Fan, PSU, etc for JunOS devices.

Example: macros.device_component_down_junos = 1

"},{"location":"Alerting/Macros/#device-component-down-cisco","title":"Device component down [Cisco]","text":"

Entity: sensors.sensor_current != 1 AND sensors.sensor_current != 5 AND sensors.sensor_type ~ \"^cisco.*State$\"

Description: Device component is down such as Fan, PSU, etc for Cisco devices.

Example: macros.device_component_down_cisco = 1

"},{"location":"Alerting/Macros/#pdu-over-amperage-apc","title":"PDU over amperage [APC]","text":"

Entity: sensors.sensor_class = \"current\" AND sensors.sensor_descr = \"Bank Total\" AND sensors.sensor_current > sensors.sensor_limit AND devices.os = \"apc\"

Description: APC PDU over amperage

Example: macros.pdu_over_amperage_apc = 1

"},{"location":"Alerting/Rules/","title":"Rules","text":"

Rules are defined using a logical language.

The GUI provides a simple way of creating rules.

Creating more complicated rules which may include maths calculations and MySQL queries can be done using macros

"},{"location":"Alerting/Rules/#syntax","title":"Syntax","text":"

Rules must consist of at least 3 elements: An Entity, a Condition and a Value. Rules can contain braces and Glues. Entities are provided from Table and Field from the database. For Example: ports.ifOperStatus.

Conditions can be any of:

  • Equals =
  • Not Equals !=
  • In IN
  • Not In NOT IN
  • Begins with LIKE ('...%')
  • Doesn't begin with NOT LIKE ('...%')
  • Contains LIKE ('%...%')
  • Doesn't Contain NOT LIKE ('%...%')
  • Ends with LIKE ('%...')
  • Doesn't end with NOT LIKE ('%...')
  • Between BETWEEN
  • Not Between NOT BETWEEN
  • Is Empty = ''
  • Is Not Empty != '''
  • Is Null IS NULL
  • Is Not Null IS NOT NULL
  • Greater >
  • Greater or Equal >=
  • Less <
  • Less or Equal <=
  • Regex REGEXP

Values can be an entity or any data. If using macros as value you must include the macro name into backticks. i.e. `macros.past_60m`

Note: Regex supports MySQL Regular expressions.

Arithmetics are allowed as well.

"},{"location":"Alerting/Rules/#options","title":"Options","text":"

Here are some of the other options available when adding an alerting rule:

  • Rule name: The name associated with the rule.
  • Severity: How \"important\" the rule is.
  • Max alerts: The maximum number of alerts sent for the event. -1 means unlimited.
  • Delay: The amount of time in seconds to wait after a rule is matched before sending an alert out transport.
  • Interval: The interval of time in seconds between alerts for an event until Max alert is reached.
  • Mute alerts: Disables sending alert rule through alert transport. But will still show the alert in the Web UI.
  • Invert match: Invert the matching rule (ie. alert on items that _don't match the rule).
  • Recovery alerts: This will disable the recovery notification from being sent if turned off.
"},{"location":"Alerting/Rules/#advanced","title":"Advanced","text":"

On the Advanced tab, you can specify some additional options for the alert rule:

  • Override SQL: Enable this if you using a custom query
  • Query: The query to be used for the alert.

  • An example of this would be an average rule for all CPUs over 10%

SELECT devices.device_id, devices.status, devices.disabled, devices.ignore, \nAVG(processors.processor_usage) AS cpu_avg  FROM \ndevices INNER JOIN processors ON devices.device_id \n= processors.device_id WHERE devices.device_id \n= ? AND devices.status = 1 AND devices.disabled = \n0 AND devices.ignore = 0 GROUP BY devices.device_id, \ndevices.status, devices.disabled, devices.ignore \nHAVING AVG(processors.processor_usage) \n> 10\n

The 10 would then contain the average CPU usage value, you can change this value to be whatever you like.

  • You will to need copy and paste this into the Alert Rule under Advanced then paste into Query box and switch the Override SQL.
"},{"location":"Alerting/Rules/#procedure","title":"Procedure","text":"

You can associate a rule to a procedure by giving the URL of the procedure when creating the rule. Only links like \"http://\" are supported, otherwise an error will be returned. Once configured, procedure can be opened from the Alert widget through the \"Open\" button, which can be shown/hidden from the widget configuration box.

"},{"location":"Alerting/Rules/#examples","title":"Examples","text":"

Alert when:

  • Device goes down: devices.status != 1
  • Any port changes: ports.ifOperStatus != 'up'
  • Root-directory gets too full: storage.storage_descr = '/' AND storage.storage_perc >= '75'
  • Any storage gets fuller than the 'warning': storage.storage_perc >= storage_perc_warn
  • If device is a server and the used storage is above the warning level, but ignore /boot partitions: storage.storage_perc > storage.storage_perc_warn AND devices.type = \"server\" AND storage.storage_descr != \"/boot\"
  • VMware LAG is not using \"Source ip address hash\" load balancing: devices.os = \"vmware\" AND ports.ifType = \"ieee8023adLag\" AND ports.ifDescr REGEXP \"Link Aggregation .*, load balancing algorithm: Source ip address hash\"
  • Syslog, authentication failure during the last 5m: syslog.timestamp >= macros.past_5m AND syslog.msg REGEXP \".*authentication failure.*\"
  • High memory usage: macros.device_up = 1 AND mempools.mempool_perc >= 90 AND mempools.mempool_descr REGEXP \"Virtual.*\"
  • High CPU usage(per core usage, not overall): macros.device_up = 1 AND processors.processor_usage >= 90
  • High port usage, where description is not client & ifType is not softwareLoopback: macros.port_usage_perc >= 80 AND port.port_descr_type != \"client\" AND ports.ifType != \"softwareLoopback\"
  • Alert when mac address is located on your network ipv4_mac.mac_address = \"2c233a756912\"
"},{"location":"Alerting/Rules/#alert-rules-collection","title":"Alert Rules Collection","text":"

You can also select Alert Rule from the Alerts Collection. These Alert Rules are submitted by users in the community :) If would like to submit your alert rules to the collection, please submit them here Alert Rules Collection

"},{"location":"Alerting/Templates/","title":"Templates","text":"

This page is for installs running version 1.42 or later. You can find the older docs here

Templates can be assigned to a single or a group of rules and can contain any kind of text. There is also a default template which is used for any rule that isn't associated with a template. This template can be found under Alert Templates page and can be edited. It also has an option revert it back to its default content.

To attach a template to a rule just open the Alert Templates settings page, choose the template to assign and click the yellow button in the Actions column. In the appearing popupbox select the rule(s) you want the template to be assigned to and click the Attach button. You might hold down the CTRL key to select multiple rules at once.

The templating engine in use is Laravel Blade. We will cover some of the basics here, however the official Laravel docs will have more information here

"},{"location":"Alerting/Templates/#syntax","title":"Syntax","text":"

Controls:

  • if-else (Else can be omitted): @if ($alert->placeholder == 'value') Some Text @else Other Text @endif
  • foreach-loop: @foreach ($alert->faults as $key => $value) Key: $key Value: $value @endforeach

Placeholders:

Placeholders are special variables that if used within the template will be replaced with the relevant data, I.e:

The device {{ $alert->hostname }} has been up for {{ $alert->uptime }} seconds would result in the following The device localhost has been up for 30344 seconds.

When using placeholders to echo data, you need to wrap the placeholder in {{ }}. I.e {{ $alert->hostname }}.

  • Device ID: $alert->device_id
  • Hostname of the Device: $alert->hostname
  • sysName of the Device: $alert->sysName
  • sysDescr of the Device: $alert->sysDescr
  • display name of the Device: $alert->display
  • sysContact of the Device: $alert->sysContact
  • OS of the Device: $alert->os
  • Type of Device: $alert->type
  • IP of the Device: $alert->ip
  • Hardware of the Device: $alert->hardware
  • Software version of the Device: $alert->version
  • Features of the Device: $alert->features
  • Serial number of the Device: $alert->serial
  • Location of the Device: $alert->location
  • uptime of the Device (in seconds): $alert->uptime
  • Short uptime of the Device (28d 22h 30m 7s): $alert->uptime_short
  • Long uptime of the Device (28 days, 22h 30m 7s): $alert->uptime_long
  • Description (purpose db field) of the Device: $alert->description
  • Notes of the Device: $alert->notes
  • Notes of the alert (ack notes): $alert->alert_notes
  • ping timestamp (if icmp enabled): $alert->ping_timestamp
  • ping loss (if icmp enabled): $alert->ping_loss
  • ping min (if icmp enabled): $alert->ping_min
  • ping max (if icmp enabled): $alert->ping_max
  • ping avg (if icmp enabled): $alert->ping_avg
  • debug (array)
  • Title for the Alert: $alert->title
  • Time Elapsed, Only available on recovery ($alert->state == 0): $alert->elapsed
  • Rule Builder (the actual rule) (use {!! $alert->builder !!}): $alert->builder
  • Alert-ID: $alert->id
  • Unique-ID: $alert->uid
  • Faults, Only available on alert ($alert->state != 0), must be iterated in a foreach (@foreach ($alert->faults as $key => $value) @endforeach). Holds all available information about the Fault, accessible in the format $value['Column'], for example: $value['ifDescr']. Special field $value['string'] has most Identification-information (IDs, Names, Descrs) as single string, this is the equivalent of the default used and must be encased in {{ }}
  • State: $alert->state
  • Severity: $alert->severity
  • Rule: $alert->rule
  • Rule-Name: $alert->name
  • Procedure URL: $alert->proc
  • Timestamp: $alert->timestamp
  • Transport type: $alert->transport
  • Transport name: $alert->transport_name
  • Contacts, must be iterated in a foreach, $key holds email and $value holds name: $alert->contacts

Placeholders can be used within the subjects for templates as well although $faults is most likely going to be worthless.

The Default Template is a 'one-size-fit-all'. We highly recommend defining your own templates for your rules to include more specific information.

"},{"location":"Alerting/Templates/#base-templates","title":"Base Templates","text":"

If you'd like to reuse a common template for your alerts follow below

A default file is located in resources/views/alerts/templates/default.blade.php Displays the following:

<html>\n    <head>\n        <title>LibreNMS Alert</title>\n    </head>\n    <body>\n        <div class=\"container\">\n            @yield('content')\n        </div>\n    </body>\n</html>\n

The important part being the @yield('content')

You can use plain text or html as per Alert templates and this will form the basis of your common template, feel free to make as many templates in the directory as needed.

In your alert template just use

@extends('alerts.templates.default')\n\n@section('content')\n  {{ $alert->title }}\n  Severity: {{ $alert->severity }}\n  ...\n@endsection\n

More info: https://laravel.com/docs/blade#extending-a-layout

"},{"location":"Alerting/Templates/#examples","title":"Examples","text":""},{"location":"Alerting/Templates/#default-template","title":"Default Template","text":"
{{ $alert->title }}\nSeverity: {{ $alert->severity }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nUnique-ID: {{ $alert->uid }}\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif\n@if ($alert->faults) Faults:\n@foreach ($alert->faults as $key => $value)\n  {{ $key }}: {{ $value['string'] }}\n@endforeach\n@endif\nAlert sent to:\n@foreach ($alert->contacts as $key => $value)\n  {{ $value }} <{{ $key }}>\n@endforeach\n
"},{"location":"Alerting/Templates/#ports-utilization-template","title":"Ports Utilization Template","text":"
{{ $alert->title }}\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif\n@foreach ($alert->faults as $key => $value)\nPhysical Interface: {{ $value['ifDescr'] }}\nInterface Description: {{ $value['ifAlias'] }}\nInterface Speed: {{ ($value['ifSpeed']/1000000000) }} Gbs\nInbound Utilization: {{ (($value['ifInOctets_rate']*8)/$value['ifSpeed'])*100 }}\nOutbound Utilization: {{ (($value['ifOutOctets_rate']*8)/$value['ifSpeed'])*100 }}\n@endforeach\n
"},{"location":"Alerting/Templates/#storage","title":"Storage","text":"
{{ $alert->title }}\n\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\nUptime: {{ $alert->uptime_short }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nLocation: {{ $alert->location }}\nDescription: {{ $alert->description }}\nFeatures: {{ $alert->features }}\nNotes: {{ $alert->notes }}\n\nServer: {{ $alert->sysName }}\n@foreach ($alert->faults as $key => $value)\nMount Point: {{ $value['storage_descr'] }}\nPercent Utilized: {{ $value['storage_perc'] }}\n@endforeach\n
"},{"location":"Alerting/Templates/#value-sensors-temperature-humidity-fanspeed","title":"Value Sensors (Temperature, Humidity, Fanspeed, ...)","text":"
{{ $alert->title }}\n\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\nTimestamp: {{ $alert->timestamp }}\nUptime: {{ $alert->uptime_short }}\n@if ($alert->state == 0)\nTime elapsed: {{ $alert->elapsed }}\n@endif\nLocation: {{ $alert->location }}\nDescription: {{ $alert->description }}\nFeatures: {{ $alert->features }}\nNotes: {{ $alert->notes }}\n\nRule: {{ $alert->name ?? $alert->rule }}\n@if ($alert->faults)\nFaults:\n@foreach ($alert->faults as $key => $value)\n@php($unit = __(\"sensors.${value[\"sensor_class\"]}.unit\"))\n#{{ $key }}: {{ $value['sensor_descr'] ?? 'Sensor' }}\n\nCurrent: {{ $value['sensor_current'].$unit }}\nPrevious: {{ $value['sensor_prev'].$unit }}\nLimit: {{ $value['sensor_limit'].$unit }}\nOver Limit: {{ round($value['sensor_current']-$value['sensor_limit'], 2).$unit }}\n\n@endforeach\n@endif\n
"},{"location":"Alerting/Templates/#memory-alert","title":"Memory Alert","text":"
{{ $alert->title }}\n\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\nUptime: {{ $alert->uptime_short }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nLocation: {{ $alert->location }}\nDescription: {{ $alert->description }}\nNotes: {{ $alert->notes }}\n\nServer: {{ $alert->hostname }}\n@foreach ($alert->faults as $key => $value)\nMemory Description: {{ $value['mempool_descr'] }}\nPercent Utilized: {{ $value['mempool_perc'] }}\n@endforeach\n
"},{"location":"Alerting/Templates/#advanced-options","title":"Advanced options","text":""},{"location":"Alerting/Templates/#conditional-formatting","title":"Conditional formatting","text":"

Conditional formatting example, will display a link to the host in email or just the hostname in any other transport:

@if ($alert->transport == 'mail')<a href=\"https://my.librenms.install/device/device={{ $alert->hostname }}/\">{{ $alert->hostname }}</a>\n@else\n{{ $alert->hostname }}\n@endif\n
"},{"location":"Alerting/Templates/#traceroute-debugs","title":"Traceroute debugs","text":"
@if ($alert->status == 0)\n    @if ($alert->status_reason == 'icmp')\n        {{ $alert->debug['traceroute'] }}\n    @endif\n@endif\n
"},{"location":"Alerting/Templates/#examples-html","title":"Examples HTML","text":"

Note: To use HTML emails you must set HTML email to Yes in the WebUI under Global Settings > Alerting Settings > Email transport > Use HTML emails

"},{"location":"Alerting/Templates/#graphs","title":"Graphs","text":"

There are two helpers for graphs that will use a signed url to allow secure external access. Anyone using the signed url will be able to view the graph.

  • Your LibreNMS web must be accessible from the location where the graph is viewed. Some alert transports require publicly accessible urls.
  • APP_URL must be set in .env to use signed graphs.
  • Changing APP_KEY will invalidate all previously issued singed urls.

You may specify the graph one of two ways, a php array of parameters, or a direct url to a graph.

Note that to and from can be specified either as timestamps with time() or as relative time -3d or -36h. When using relative time, the graph will show based on when the user views the graph, not when the event happened. Sharing a graph image with a relative time will always give the recipient access to current data, where a specific timestamp will only allow access to that timeframe.

"},{"location":"Alerting/Templates/#signedgraphtag","title":"@signedGraphTag","text":"

This will insert a specially formatted html img tag linking to the graph. Some transports may search the template for this tag to attach images properly for that transport.

@signedGraphTag([\n    'id' => $value['port_id'],\n    'type' => 'port_bits',\n    'from' => time() - 43200,\n    'to' => time(),\n    'width' => 700, \n    'height' => 250\n])\n

Output:

<img class=\"librenms-graph\" src=\"https://librenms.org/graph?from=1662176216&amp;height=250&amp;id=20425&amp;to=1662219416&amp;type=port_bits&amp;width=700&amp;signature=f6e516e8fd893c772eeaba165d027cb400e15a515254de561a05b63bc6f360a4\">\n

Specific graph using url input:

@signedGraphTag('https://librenms.org/graph.php?type=device_processor&from=-2d&device=2&legend=no&height=400&width=1200')\n
"},{"location":"Alerting/Templates/#signedgraphurl","title":"@signedGraphUrl","text":"

This is used when you need the url directly. One example is using the API Transport, you may want to include the url only instead of a html tag.

@signedGraphUrl([\n    'id' => $value['port_id'],\n    'type' => 'port_bits',\n    'from' => time() - 43200,\n    'to' => time(),\n])\n
"},{"location":"Alerting/Templates/#using-models-for-optional-data","title":"Using models for optional data","text":"

If some value does not exist within the $faults[]-array, you may query fields from the database using Laravel models. You may use models to query additional values and use them on the template by placing the model and the value to search for within the braces. For example, ISIS-alerts do have a port_id value associated with the alert but ifName is not directly accessible from the $faults[]-array. If the name of the port was needed, it's value could be queried using a template such as:

{{ $alert->title }}\nSeverity: {{ $alert->severity }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif\n@if ($alert->faults) Faults:\n@foreach ($alert->faults as $key => $value)\n  Local interface: {{ \\App\\Models\\Port::find($value['port_id'])->ifName }}\n  Adjacent IP: {{ $value['isisISAdjIPAddrAddress'] }}\n  Adjacent state: {{ $value['isisISAdjState'] }}\n\n@endforeach\n@endif\n
"},{"location":"Alerting/Templates/#service-alert","title":"Service Alert","text":"
<div style=\"font-family:Helvetica;\">\n<h2>@if ($alert->state == 1) <span style=\"color:red;\">{{ $alert->severity }} @endif\n@if ($alert->state == 2) <span style=\"color:goldenrod;\">acknowledged @endif</span>\n@if ($alert->state == 3) <span style=\"color:green;\">recovering @endif</span>\n@if ($alert->state == 0) <span style=\"color:green;\">recovered @endif</span>\n</h2>\n<b>Host:</b> {{ $alert->hostname }}<br>\n<b>Duration:</b> {{ $alert->elapsed }}<br>\n<br>\n\n@if ($alert->faults)\n@foreach ($alert->faults as $key => $value) <b>{{ $value['service_desc'] }} - {{ $value['service_type'] }}</b><br>\n{{ $value['service_message'] }}<br>\n<br>\n@endforeach\n@endif\n</div>\n
"},{"location":"Alerting/Templates/#processor-alert-with-graph","title":"Processor Alert with Graph","text":"
{{ $alert->title }} <br>\nSeverity: {{ $alert->severity }}  <br>\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }} <br>\nAlert-ID: {{ $alert->id }} <br>\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif <br>\n@if ($alert->faults) Faults:\n@foreach ($alert->faults as $key => $value)\n{{ $key }}: {{ $value['string'] }}<br>\n@endforeach\n@if ($alert->faults) <b>Faults:</b><br>\n@foreach ($alert->faults as $key => $value)\n@signedGraphTag(['device' => $value['device_id'], 'type' => 'device_processor', 'width' => 459, 'height' => 213, 'from' => time() - 259200])<br>\nhttps://server/graphs/device={{ $value['device_id'] }}/type=device_processor/<br>\n@endforeach\nTemplate: CPU alert <br>\n@endif\n@endif\n
"},{"location":"Alerting/Templates/#included","title":"Included","text":"

We include a few templates for you to use, these are specific to the type of alert rules you are creating. For example if you create a rule that would alert on BGP sessions then you can assign the BGP template to this rule to provide more information.

The included templates apart from the default template are:

  • BGP Sessions
  • Ports
  • Temperature
"},{"location":"Alerting/Templates/#other-examples","title":"Other Examples","text":""},{"location":"Alerting/Templates/#microsoft-teams-markdown","title":"Microsoft Teams - Markdown","text":"
[{{ $alert->title }}](https://your.librenms.url/device/device={{ $alert->device_id }}/)\n**Device name:** {{ $alert->sysName }}\n**Severity:** {{ $alert->severity }}\n@if ($alert->state == 0)\n**Time elapsed:** {{ $alert->elapsed }}\n@endif\n**Timestamp:** {{ $alert->timestamp }}\n**Unique-ID:** {{ $alert->uid }}\n@if ($alert->name)\n**Rule:** {{ $alert->name }}\n@else\n**Rule:** {{ $alert->rule }}\n@endif\n@if ($alert->faults)\n**Faults:**@foreach ($alert->faults as $key => $value) {{ $key }}: {{ $value['string'] }}\n@endforeach\n@endif\n
"},{"location":"Alerting/Templates/#microsoft-teams-json","title":"Microsoft Teams - JSON","text":"
{\n    \"@context\": \"https://schema.org/extensions\",\n    \"@type\": \"MessageCard\",\n    \"title\": \"{{ $alert->title }}\",\n@if ($alert->state === 0)\n    \"themeColor\": \"00FF00\",\n@elseif ($alert->state === 1)\n    \"themeColor\": \"FF0000\",\n@elseif ($alert->state === 2)\n    \"themeColor\": \"337AB7\",\n@elseif ($alert->state === 3)\n    \"themeColor\": \"FF0000\",\n@elseif ($alert->state === 4)\n    \"themeColor\": \"F0AD4E\",\n@else\n    \"themeColor\": \"337AB7\",\n@endif\n    \"summary\": \"LibreNMS\",\n    \"sections\": [\n        {\n@if ($alert->name)\n            \"facts\": [\n                {\n                    \"name\": \"Rule:\",\n                    \"value\": \"[{{ $alert->name }}](https://your.librenms.url/device/device={{ $alert->device_id }}/tab=alert/)\"\n                },\n@else\n                {\n                    \"name\": \"Rule:\",\n                    \"value\": \"[{{ $alert->rule }}](https://your.librenms.url/device/device={{ $alert->device_id }}/tab=alert/)\"\n                },\n@endif\n                {\n                    \"name\": \"Severity:\",\n                    \"value\": \"{{ $alert->severity }}\"\n                },\n                {\n                    \"name\": \"Unique-ID:\",\n                    \"value\": \"{{ $alert->uid }}\"\n                },\n                {\n                    \"name\": \"Timestamp:\",\n                    \"value\": \"{{ $alert->timestamp }}\"\n                },\n@if ($alert->state == 0)\n                {\n                    \"name\": \"Time elapsed:\",\n                    \"value\": \"{{ $alert->elapsed }}\"\n                },\n@endif\n                {\n                    \"name\": \"Hostname:\",\n                    \"value\": \"[{{ $alert->hostname }}](https://your.librenms.url/device/device={{ $alert->device_id }}/)\"\n                },\n                {\n                    \"name\": \"Hardware:\",\n                    \"value\": \"{{ $alert->hardware }}\"\n                },\n                {\n                    \"name\": \"IP:\",\n                    \"value\": \"{{ $alert->ip }}\"\n                },\n                {\n                    \"name\": \"Faults:\",\n                    \"value\": \" \"\n                }\n            ]\n@if ($alert->faults)\n@foreach ($alert->faults as $key => $value)\n        },\n        {\n            \"facts\": [\n                {\n                    \"name\": \"Port:\",\n                    \"value\": \"[{{ $value['ifName'] }}](https://your.librenms.url/device/device={{ $alert->device_id }}/tab=port/port={{ $value['port_id'] }}/)\"\n                },\n                {\n                    \"name\": \"Description:\",\n                    \"value\": \"{{ $value['ifAlias'] }}\"\n                },\n@if ($alert->state != 0)\n                {\n                    \"name\": \"Status:\",\n                    \"value\": \"down\"\n                }\n            ]\n@else\n                {\n                    \"name\": \"Status:\",\n                    \"value\": \"up\"\n                }\n            ]\n@endif\n@endforeach\n@endif\n        }\n    ]\n}\n
"},{"location":"Alerting/Testing/","title":"Rules","text":"

The simplest way of testing if an alert rule will match a device is by going to the device, clicking edit (the cog), select Capture. From this new screen choose Alerts and click run.

The output will cycle through all alerts applicable to this device and show you the Rule name, rule, MySQL query and if the rule matches.

See Device Troubleshooting

"},{"location":"Alerting/Testing/#transports","title":"Transports","text":"

You can test your transports by forcing an actual active alert to run regardless of the interval or delay values.

./scripts/test-alert.php. This script accepts -r for the rule id, -h for the device id or hostname and -d for debug.

"},{"location":"Alerting/Testing/#templates","title":"Templates","text":"

It's possible to test your new template before assigning it to a rule. To do so you can run ./scripts/test-template.php. The script will provide the help info when ran without any parameters.

As an example, if you wanted to test template ID 10 against localhost running rule ID 2 then you would run:

./scripts/test-template.php -t 10 -d -h localhost -r 2

If the rule is currently alerting for localhost then you will get the full template as expected to see on email, if it's not then you will just see the template without any fault information.

"},{"location":"Alerting/Transports/","title":"Transports","text":"

Transports are located within LibreNMS/Alert/Transport/ and can be configured within the WebUI under Alerts -> Alert Transports.

Contacts will be gathered automatically and passed to the configured transports. By default the Contacts will be only gathered when the alert triggers and will ignore future changes in contacts for the incident. If you want contacts to be re-gathered before each dispatch, please set 'Updates to contact email addresses not honored' to Off in the WebUI.

The contacts will always include the SysContact defined in the Device's SNMP configuration and also every LibreNMS user that has at least read-permissions on the entity that is to be alerted.

At the moment LibreNMS only supports Port or Device permissions.

You can exclude the SysContact by toggling 'Issue alerts to sysContact'.

To include users that have Global-Read, Administrator or Normal-User permissions it is required to toggle the options:

  • Issue alerts to admins.
  • Issue alerts to read only users
  • Issue alerts to normal users.
"},{"location":"Alerting/Transports/#using-a-proxy","title":"Using a Proxy","text":"

Proxy Configuration

"},{"location":"Alerting/Transports/#using-a-amqp-based-transport","title":"Using a AMQP based Transport","text":"

You need to install an additional php module : bcmath

"},{"location":"Alerting/Transports/#alerta","title":"Alerta","text":"

The alerta monitoring system is a tool used to consolidate and de-duplicate alerts from multiple sources for quick \u2018at-a-glance\u2019 visualisation. With just one system you can monitor alerts from many other monitoring tools on a single screen.

Example:

Config Example API Endpoint http://alerta.example.com/api/alert Environment Production Apy key api key with write permission Alert state critical Recover state cleared"},{"location":"Alerting/Transports/#alertops","title":"AlertOps","text":"

Using AlertOps integration with LibreNMS, you can seamlessly forward alerts to AlertOps with detailed information. AlertOps acts as a dispatcher for LibreNMS alerts, allowing you to determine the right individuals or teams to notify based on on-call schedules. Notifications can be sent via various channels including email, text messages (SMS), phone calls, and mobile push notifications for iOS & Android devices. Additionally, AlertOps provides escalation policies to ensure alerts are appropriately managed until they are assigned or closed. You can also filter out/aggregate alerts based on different values.

To set up the integration:

  • Create a LibreNMS Integration: Sign up for an AlertOps account and create a LibreNMS integration from the integrations page. This will generate an Inbound Integration Endpoint URL that you'll need to copy to LibreNMS.

  • Configure LibreNMS Integration: In LibreNMS, navigate to the integration settings and paste the inbound integration URL obtained from AlertOps.

Example:

Config Example WebHook URL https://url/path/to/webhook"},{"location":"Alerting/Transports/#alertmanager","title":"Alertmanager","text":"

Alertmanager is an alert handling software, initially developed for alert processing sent by Prometheus.

It has built-in functionality for deduplicating, grouping and routing alerts based on configurable criteria.

LibreNMS uses alert grouping by alert rule, which can produce an array of alerts of similar content for an array of hosts, whereas Alertmanager can group them by alert meta, ideally producing one single notice in case an issue occurs.

It is possible to configure as many label values as required in Alertmanager Options section. Every label and its value should be entered as a new line.

Labels can be a fixed string or a dynamic variable from the alert. To set a dynamic variable your label must start with extra_ then complete with the name of your label (only characters, figures and underscore are allowed here). The value must be the name of the variable you want to get (you can see all the variables in Alerts->Notifications by clicking on the Details icon of your alert when it is pending). If the variable's name does not match with an existing value the label's value will be the string you provided just as it was a fixed string.

Multiple Alertmanager URLs (comma separated) are supported. Each URL will be tried and the search will stop at the first success.

Basic HTTP authentication with a username and a password is supported. If you let those value blank, no authentication will be used.

Alertmanager Docs

Example:

Config Example Alertmanager URL(s) http://alertmanager1.example.com,http://alertmanager2.example.com Alertmanager Username myUsername Alertmanager Password myPassword Alertmanager Options: source=librenms customlabel=value extra_dynamic_value=variable_name"},{"location":"Alerting/Transports/#api","title":"API","text":"

The API transport allows to reach any service provider using POST, PUT or GET URLs (Like SMS provider, etc). It can be used in multiple ways:

  • The same text built from the Alert template is available in the variable

$msg, which can then be sent as an option to the API. Be carefull that HTTP GET requests are usually limited in length.

  • The API-Option fields can be directly built from the variables defined in Template-Syntax but without the 'alert->' prefix. For instance, $alert->uptime is available as $uptime in the API transport

  • The API-Headers allows you to add the headers that the api endpoint requires.

  • The API-body allow sending data in the format required by the API endpoint.

A few variables commonly used :

Variable Description {{ $hostname\u00a0}} Hostname {{ $sysName\u00a0}} SysName {{ $sysDescr\u00a0}} SysDescr {{ $os\u00a0}} OS of device (librenms defined) {{ $type\u00a0}} Type of device (librenms defined) {{ $ip\u00a0}} IP Address {{ $hardware\u00a0}} Hardware {{ $version\u00a0}} Version {{ $uptime\u00a0}} Uptime in seconds {{ $uptime_short\u00a0}} Uptime in human-readable format {{ $timestamp\u00a0}} Timestamp of alert {{ $description\u00a0}} Description of device {{ $title\u00a0}} Title (as built from the Alert Template) {{ $msg\u00a0}} Body text (as built from the Alert Template)

Example:

The example below will use the API named sms-api of my.example.com and send the title of the alert to the provided number using the provided service key. Refer to your service documentation to configure it properly.

Config Example API Method GET API URL http://my.example.com/sms-api API Options rcpt=0123456789 key=0987654321abcdef msg=(LNMS) {{ $title }} API Username myUsername API Password myPassword

The example below will use the API named wall-display of my.example.com and send the title and text of the alert to a screen in the Network Operation Center.

Config Example API Method POST API URL http://my.example.com/wall-display API Options title={{ $title }} msg={{ $msg }}

The example below will use the API named component of my.example.com with id 1, body as json status value and headers send token authentication and content type required.

Config Example API Method PUT API URL http://my.example.com/comonent/1 API Headers X-Token=HASH Content-Type=application/json API Body { \"status\": 2 }"},{"location":"Alerting/Transports/#aspsms","title":"aspSMS","text":"

aspSMS is a SMS provider that can be configured by using the generic API Transport. You need a token you can find on your personnal space.

aspSMS docs

Example:

Config Example Transport type Api API Method POST API URL https://soap.aspsms.com/aspsmsx.asmx/SimpleTextSMS Options UserKey=USERKEYPassword=APIPASSWORDRecipient=RECIPIENT Originator=ORIGINATORMessageText={{ $msg }}"},{"location":"Alerting/Transports/#browser-push","title":"Browser Push","text":"

Browser push notifications can send a notification to the user's device even when the browser is not open. This requires HTTPS, the PHP GMP extension, Push API support, and permissions on each device to send alerts.

Simply configure an alert transport and allow notification permission on the device(s) you wish to receive alerts on. You may disable alerts on a browser on the user preferences page.

"},{"location":"Alerting/Transports/#canopsis","title":"Canopsis","text":"

Canopsis is a hypervision tool. LibreNMS can send alerts to Canopsis which are then converted to canopsis events.

Canopsis Docs

Example:

Config Example Hostname www.xxx.yyy.zzz Port Number 5672 User admin Password my_password Vhost canopsis"},{"location":"Alerting/Transports/#cisco-spark-aka-webex-teams","title":"Cisco Spark (aka Webex Teams)","text":"

Cisco Spark (now known as Webex Teams). LibreNMS can send alerts to a Cisco Spark room. To make this possible you need to have a RoomID and a token. You can also choose to send alerts using Markdown syntax. Enabling this option provides for more richly formatted alerts, but be sure to adjust your alert template to account for the Markdown syntax.

For more information about Cisco Spark RoomID and token, take a look here :

  • Getting started
  • Rooms

Example:

Config Example API Token ASd23r23edewda RoomID 34243243251 Use Markdown? x"},{"location":"Alerting/Transports/#clickatell","title":"Clickatell","text":"

Clickatell provides a REST-API requiring an Authorization-Token and at least one Cellphone number.

Clickatell Docs

Here an example using 3 numbers, any amount of numbers is supported:

Example:

Config Example Token dsaWd3rewdwea Mobile Numbers +1234567890,+1234567891,+1234567892"},{"location":"Alerting/Transports/#discord","title":"Discord","text":"

The Discord transport will POST the alert message to your Discord Incoming WebHook. Simple html tags are stripped from the message.

The only required value is for url, without this no call to Discord will be made. The Options field supports the JSON/Form Params listed in the Discord Docs below.

Discord Docs

Example:

Config Example Discord URL https://discordapp.com/api/webhooks/4515489001665127664/82-sf4385ysuhfn34u2fhfsdePGLrg8K7cP9wl553Fg6OlZuuxJGaa1d54fe Options username=myname"},{"location":"Alerting/Transports/#elasticsearch","title":"Elasticsearch","text":"

You can have LibreNMS send alerts to an elasticsearch database. Each fault will be sent as a separate document.

Example:

Config Example Host 127.0.0.1 Port 9200 Index Pattern \\l\\i\\b\\r\\e\\n\\m\\s-Y.m.d"},{"location":"Alerting/Transports/#gitlab","title":"GitLab","text":"

LibreNMS will create issues for warning and critical level alerts however only title and description are set. Uses Personal access tokens to authenticate with GitLab and will store the token in cleartext.

Example:

Config Example Host http://gitlab.host.tld Project ID 1 Personal Access Token AbCdEf12345"},{"location":"Alerting/Transports/#grafana-oncall","title":"Grafana Oncall","text":"

Send alerts to Grafana Oncall using a Formatted Webhook

Example:

Config Example Webhook URL https://a-prod-us-central-0.grafana.net/integrations/v1/formatted_webhook/m12xmIjOcgwH74UF8CN4dk0Dh/"},{"location":"Alerting/Transports/#hipchat","title":"HipChat","text":"

See the HipChat API Documentation for rooms/message for details on acceptable values.

You may notice that the link points at the \"deprecated\" v1 API. This is because the v2 API is still in beta.

Example:

Config Example API URL https://api.hipchat.com/v1/rooms/message?auth_token=109jawregoaihj Room ID 7654321 From Name LibreNMS Options color=red

At present the following options are supported: color.

Note: The default message format for HipChat messages is HTML. It is recommended that you specify the text message format to prevent unexpected results, such as HipChat attempting to interpret angled brackets (< and >).

"},{"location":"Alerting/Transports/#irc","title":"IRC","text":"

The IRC transports only works together with the LibreNMS IRC-Bot. Configuration of the LibreNMS IRC-Bot is described here.

Example:

Config Example IRC enabled"},{"location":"Alerting/Transports/#jira","title":"JIRA","text":"

You can have LibreNMS create issues on a Jira instance for critical and warning alerts using either the Jira REST API or webhooks. Custom fields allow you to add any required fields beyond summary and description fields in case mandatory fields are required by your Jira project/issue type configuration. Custom fields are defined in JSON format but ustom fields allow you to add any required fields beyond summary and description fields in case mandatory fields are required by your Jira project/issue type configuration. Custom fields are defined in JSON format. Currently http authentication is used to access Jira and Jira username and password will be stored as cleartext in the LibreNMS database.

"},{"location":"Alerting/Transports/#rest-api","title":"REST API","text":"

The config fields that need to set for Jira REST API are: Jira Open URL, Jira username, Jira password, Project key, and issue type.

Note: REST API is that it is only able to open new tickets.

"},{"location":"Alerting/Transports/#webhooks","title":"Webhooks","text":"

The config fields that need to set for webhooks are: Jira Open URL, Jira Close URL, Jira username, Jira password and webhook ID.

Note: Webhooks allow more control over how alerts are handled in Jira. With webhooks, recovery messages can be sent to a different URL than alerts. Additionally, a custom conditional logic can be built using the webhook payload and ID to automatically close an open ticket if predefined conditions are met.

Jira Issue Types Jira Webhooks

Example:

Config Example Project Key JIRAPROJECTKEY Issue Type Myissuetype Open URL https://myjira.mysite.com / https://webhook-open-url Close URL https://webhook-close-url Jira Username myjirauser Jira Password myjirapass Enable webhook ON/OFF Webhook ID alert_id Custom Fileds {\"components\":[{\"id\":\"00001\"}], \"source\": \"LibrenNMS\"}"},{"location":"Alerting/Transports/#jira-service-management","title":"Jira Service Management","text":"

Using Jira Service Management LibreNMS integration, LibreNMS forwards alerts to Jira Service Management with detailed information. Jira Service Management acts as a dispatcher for LibreNMS alerts, determines the right people to notify based on on-call schedules and notifies via email, text messages (SMS), phone calls and iOS & Android push notifications. Then escalates alerts until the alert is acknowledged or closed.

:warning: If the feature isn\u2019t available on your site, keep checking Jira Service Management for updates.

Example:

Config Example WebHook URL https://url/path/to/webhook"},{"location":"Alerting/Transports/#line-messaging-api","title":"LINE Messaging API","text":"

LINE Messaging API Docs

Here is the step for setup a LINE bot and using it in LibreNMS.

  1. Use your real LINE account register in developer protal.

  2. Add a new channel, choose Messaging API and continue fill up the forms, note that Channel name cannot edit later.

  3. Go to \"Messaging API\" tab of your channel, here listing some important value.

    • Bot basic ID and QR code is your LINE bot's ID and QR code.
    • Channel access token (long-lived), will use it in LibreNMS, keep it safe.
  4. Use your real Line account add your LINE bot as a friend.

  5. Recipient ID can be groupID, userID or roomID, it will be used in LibreNMS to send message to a group or a user. Use the following NodeJS program and ngrok for temporally https webhook to listen it.

    LINE-bot-RecipientFetcher

  6. Run the program and using ngrok expose port to public

    $ node index.js\n$ ngrok http 3000\n
  7. Go to \"Messaging API\" tab of your channel, fill up Webhook URL to https://<your ngrok domain>/webhook

  8. If you want to let LINE bot send message to a yourself, use your real account to send a message to your LINE bot. Program will print out the userID in console.

    sample value:

    {\"type\":\"user\",\"userId\":\"U527xxxxxxxxxxxxxxxxxxxxxxxxxc0ee\"}\n
  9. If you want to let LINE bot send message to a group, do the following steps.

    • Add your LINE bot into group
    • Use your real account to send a message to group

    Program will print out the groupID in console, it will be Recipient ID, keep it safe.

    sample value:

    {\"type\":\"group\",\"groupId\":\"Ce51xxxxxxxxxxxxxxxxxxxxxxxxxx6ef\",\"userId\":\"U527xxxxxxxxxxxxxxxxxxxxxxxxxc0ee\"} ```\n

Example:

Config Example Access token fhJ9vH2fsxxxxxxxxxxxxxxxxxxxxlFU= Recipient (groupID, userID or roomID) Ce51xxxxxxxxxxxxxxxxxxxxxxxxxx6ef"},{"location":"Alerting/Transports/#line-notify","title":"LINE Notify","text":"

LINE Notify

LINE Notify API Document

Example:

Config Example Token AbCdEf12345"},{"location":"Alerting/Transports/#mail","title":"Mail","text":"

The E-Mail transports uses the same email-configuration as the rest of LibreNMS. As a small reminder, here is its configuration directives including defaults:

Emails will attach all graphs included with the @signedGraphTag directive. If the email format is set to html, they will be embedded. To disable attaching images, set email_attach_graphs to false.

alerting/email

lnms config:set email_html true\nlnms config:set email_attach_graphs false\n

Example:

Config Example Email me@example.com"},{"location":"Alerting/Transports/#matrix","title":"Matrix","text":"

For using the Matrix transports, you have to create a room on the Matrix-server. The provided Auth_token belongs to an user, which is member of this room. The Message, sent to the matrix-room can be built from the variables defined in Template-Syntax but without the 'alert->' prefix. See API-Transport. The variable $msg is contains the result of the Alert template.The Matrix-Server URL is cutted before the beginning of the _matrix/client/r0/... API-part.

Example:

Config Example Matrix-Server URL https://matrix.example.com/ Room !ajPbbPalmVbNuQoBDK:example.com Auth_token: MDAyYmxvY2F0aW9uI...z1DCn6lz_uOhtW3XRICg Message: Alert: {{ $msg }} https://librenms.example.com"},{"location":"Alerting/Transports/#messagebird","title":"Messagebird","text":"

LibreNMS can send text messages through Messagebird Rest API transport.

Config Example Api Key Api rest key given in the messagebird dashboard Originator E.164 formatted originator Recipient E.164 formatted recipient for multi recipents comma separated Character limit Range 1..480 (max 3 split messages)"},{"location":"Alerting/Transports/#messagebird-voice","title":"Messagebird Voice","text":"

LibreNMS can send messages through Messagebird voice Rest API transport (text to speech).

Config Example Api Key Api rest key given in the messagebird dashboard Originator E.164 formatted originator Recipient E.164 formatted recipient for multi recipents comma separated Language Select box for options Spoken voice Female or Male Repeat X times the message is repeated"},{"location":"Alerting/Transports/#microsoft-teams","title":"Microsoft Teams","text":"

LibreNMS can send alerts to Microsoft Teams Incoming Webhooks which are then posted to a specific channel. Microsoft recommends using markdown formatting for connector cards. Administrators can opt to compose the MessageCard themselves using JSON to get the full functionality.

Example:

Config Example WebHook URL https://outlook.office365.com/webhook/123456789 Use JSON? x"},{"location":"Alerting/Transports/#nagios-compatible","title":"Nagios Compatible","text":"

The nagios transport will feed a FIFO at the defined location with the same format that nagios would. This allows you to use other alerting systems with LibreNMS, for example Flapjack.

Example:

Config Example Nagios FIFO /path/to/my.fifo"},{"location":"Alerting/Transports/#opsgenie","title":"OpsGenie","text":"

Using OpsGenie LibreNMS integration, LibreNMS forwards alerts to OpsGenie with detailed information. OpsGenie acts as a dispatcher for LibreNMS alerts, determines the right people to notify based on on-call schedules and notifies via email, text messages (SMS), phone calls and iOS & Android push notifications. Then escalates alerts until the alert is acknowledged or closed.

Create a LibreNMS Integration from the integrations page once you signup. Then copy the API key from OpsGenie to LibreNMS.

If you want to automatically ack and close alerts, leverage Marid integration. More detail with screenshots is available in OpsGenie LibreNMS Integration page.

Example:

Config Example WebHook URL https://url/path/to/webhook"},{"location":"Alerting/Transports/#osticket","title":"osTicket","text":"

LibreNMS can send alerts to osTicket API which are then converted to osTicket tickets.

Example:

Config Example API URL http://osticket.example.com/api/http.php/tickets.json API Token 123456789"},{"location":"Alerting/Transports/#pagerduty","title":"PagerDuty","text":"

LibreNMS can make use of PagerDuty, this is done by utilizing an API key and Integraton Key.

API Keys can be found under 'API Access' in the PagerDuty portal.

Integration Keys can be found under 'Integration' for the particular Service you have created in the PagerDuty portal.

Example:

Config Example API Key randomsample Integration Key somerandomstring"},{"location":"Alerting/Transports/#philips-hue","title":"Philips Hue","text":"

Want to spice up your noc life? LibreNMS will flash all lights connected to your philips hue bridge whenever an alert is triggered.

To setup, go to the you http://your-bridge-ip/debug/clip.html

  • Update the \"URL:\" field to /api
  • Paste this in the \"Message Body\" {\"devicetype\":\"librenms\"}
  • Press the round button on your philips Hue Bridge
  • Click on POST
  • In the Command Response You should see output with your username. Copy this without the quotes

More Info: Philips Hue Documentation

Example:

Config Example Host http://your-bridge-ip Hue User username Duration 1 Second"},{"location":"Alerting/Transports/#playsms","title":"PlaySMS","text":"

PlaySMS is an open source SMS-Gateway that can be used via their HTTP API using a Username and WebService Token. Please consult PlaySMS's documentation regarding number formatting.

PlaySMS Docs

Here an example using 3 numbers, any amount of numbers is supported:

Example:

Config Example PlaySMS https://localhost/index.php User user1 Token MYFANCYACCESSTOKEN From My Name Mobiles +1234567892,+1234567890,+1234567891"},{"location":"Alerting/Transports/#pushbullet","title":"Pushbullet","text":"

Get your Access Token from your Pushbullet's settings page and set it in your transport:

Example:

Config Example Access Token MYFANCYACCESSTOKEN"},{"location":"Alerting/Transports/#pushover","title":"Pushover","text":"

If you want to change the default notification sound for all notifications then you can add the following in Pushover Options:

sound=falling

You also have the possibility to change sound per severity: sound_critical=falling sound_warning=siren sound_ok=magic

Enabling Pushover support is fairly easy, there are only two required parameters.

Firstly you need to create a new Application (called LibreNMS, for example) in your account on the Pushover website (https://pushover.net/apps).

Now copy your API Key and obtain your User Key from the newly created Application and setup the transport.

Pushover Docs

Example:

Config Example Api Key APPLICATIONAPIKEYGOESHERE User Key USERKEYGOESHERE Pushover Options sound_critical=falling sound_warning=siren sound_ok=magic"},{"location":"Alerting/Transports/#rocketchat","title":"Rocket.chat","text":"

The Rocket.chat transport will POST the alert message to your Rocket.chat Incoming WebHook using the attachments option. Simple html tags are stripped from the message. All options are optional, the only required value is for url, without this then no call to Rocket.chat will be made.

Rocket.chat Docs

Example:

Config Example Webhook URL https://rocket.url/api/v1/chat.postMessage Rocket.chat Options channel=#Alerting username=myname icon_url=http://someurl/image.gif icon_emoji=:smirk:"},{"location":"Alerting/Transports/#sensu","title":"Sensu","text":"

The Sensu transport will POST an Event to the Agent API upon an alert being generated.

It will be categorised (ok, warning or critical), and if you configure the alert to send recovery notifications, Sensu will also clear the alert automatically. No configuration is required - as long as you are running the Sensu Agent on your poller with the HTTP socket enabled on tcp/3031, LibreNMS will start generating Sensu events as soon as you create the transport.

Acknowledging alerts within LibreNMS is not directly supported, but an annotation (acknowledged) is set, so a mutator or silence, or even the handler could be written to look for it directly in the handler. There is also an annotation (generated-by) set, to allow you to treat LibreNMS events differently from agent events.

The 'shortname' option is a simple way to reduce the length of device names in configs. It replaces the last 3 domain components with single letters (e.g. websrv08.dc4.eu.corp.example.net gets shortened to websrv08.dc4.eu.cen).

"},{"location":"Alerting/Transports/#limitations","title":"Limitations","text":"
  • Only a single namespace is supported
  • Sensu will reject rules with special characters - the Transport will attempt to fix up rule names, but it's best to stick to letters, numbers and spaces
  • The transport only deals in absolutes - it ignores the got worse/got better states
  • The agent will buffer alerts, but LibreNMS will not - if your agent is offline, alerts will be dropped
  • There is no backchannel between Sensu and LibreNMS - if you make changes in Sensu to LibreNMS alerts, they'll be lost on the next event (silences will work)

Example:

Config Example Sensu Endpoint http://localhost:3031 Sensu Namespace eu-west Check Prefix lnms Source Key hostname"},{"location":"Alerting/Transports/#signl4","title":"SIGNL4","text":"

SIGNL4 offers critical alerting, incident response and service dispatching for operating critical infrastructure. It alerts you persistently via app push, SMS text, voice calls, and email including tracking, escalation, on-call duty scheduling and collaboration.

Integrating SIGNL4 with LibreNMS to forward critical alerts with detailed information to responsible people or on-call teams. The integration supports triggering as well as closing alerts.

In the configuration for your SIGNL4 alert transport you just need to enter your SIGNL4 webhook URL including team or integration secret.

Example:

Config Example Webhook URL https://connect.signl4.com/webhook/{team-secret}

You can find more information about the integration here.

"},{"location":"Alerting/Transports/#slack","title":"Slack","text":"

The Slack transport will POST the alert message to your Slack Incoming WebHook using the attachments option, you are able to specify multiple webhooks along with the relevant options to go with it. Simple html tags are stripped from the message. All options are optional, the only required value is for url, without this then no call to Slack will be made.

We currently support the following attachment options:

  • author_name

We currently support the following global message options:

  • channel_name : Slack channel name (without the leading '#') to which the alert will go
  • icon_emoji : Emoji name in colon format to use as the author icon

Slack docs

The alert template can make use of Slack markdown. In the Slack markdown dialect, custom links are denoted with HTML angled brackets, but LibreNMS strips these out. To support embedding custom links in alerts, use the bracket/parentheses markdown syntax for links. For example if you would typically use this for a Slack link:

<https://www.example.com|My Link>

Use this in your alert template:

[My Link](https://www.example.com)

Example:

Config Example Webhook URL https://slack.com/url/somehook Channel network-alerts Author Name LibreNMS Bot Icon :scream:"},{"location":"Alerting/Transports/#smseagle","title":"SMSEagle","text":"

SMSEagle is a hardware SMS Gateway that can be used via their HTTP API using a Username and password.

Destination numbers are one per line, with no spaces. They can be in either local or international dialling format.

SMSEagle Docs

Example:

Config Example SMSEagle Host ip.add.re.ss User smseagle_user Password smseagle_user_password Mobiles +3534567890 0834567891"},{"location":"Alerting/Transports/#smsmode","title":"SMSmode","text":"

SMSmode is a SMS provider that can be configured by using the generic API Transport. You need a token you can find on your personnal space.

SMSmode docs

Example:

Config Example Transport type Api API Method POST API URL http://api.smsmode.com/http/1.6/sendSMS.do Options accessToken=PUT_HERE_YOUR_TOKEN numero=PUT_HERE_DESTS_NUMBER_COMMA_SEPARATEDmessage={{ $msg }}"},{"location":"Alerting/Transports/#splunk","title":"Splunk","text":"

LibreNMS can send alerts to a Splunk instance and provide all device and alert details.

Example output:

Feb 21 15:21:52 nms  hostname=\"localhost\", sysName=\"localhost\", \nsysDescr=\"\", sysContact=\"\", os=\"fortigate\", type=\"firewall\", ip=\"localhost\", \nhardware=\"FGT_50E\", version=\"v5.6.9\", serial=\"\", features=\"\", location=\"\", \nuptime=\"387\", uptime_short=\" 6m 27s\", uptime_long=\" 6 minutes 27 seconds\", \ndescription=\"\", notes=\"\", alert_notes=\"\", device_id=\"0\", rule_id=\"0\", \nid=\"0\", proc=\"\", status=\"1\", status_reason=\"\", ping_timestamp=\"\", ping_loss=\"0\", \nping_min=\"25.6\", ping_max=\"26.8\", ping_avg=\"26.3\", \ntitle=\"localhost recovered from  Device up/down  \", elapsed=\"14m 54s\", uid=\"0\", \nalert_id=\"0\", severity=\"critical\", name=\"Device up/down\", \ntimestamp=\"2020-02-21 15:21:33\", state=\"0\", device_device_id=\"0\", \ndevice_inserted=\"\", device_hostname=\"localhost\", device_sysName=\"localhost\", \ndevice_ip=\"localhost\", device_overwrite_ip=\"\", device_timeout=\"\", device_retries=\"\", \ndevice_snmp_disable=\"0\", device_bgpLocalAs=\"0\", \ndevice_sysObjectID=\"\", device_sysDescr=\"\", \ndevice_sysContact=\"\", device_version=\"v5.6.9\", device_hardware=\"FGT_50E\", \ndevice_features=\"build1673\", device_location_id=\"\", device_os=\"fortigate\", \ndevice_status=\"1\", device_status_reason=\"\", device_ignore=\"0\", device_disabled=\"0\", \ndevice_uptime=\"387\", device_agent_uptime=\"0\", device_last_polled=\"2020-02-21 15:21:33\", \ndevice_last_poll_attempted=\"\", device_last_polled_timetaken=\"7.9\", \ndevice_last_discovered_timetaken=\"11.77\", device_last_discovered=\"2020-02-21 13:16:42\", \ndevice_last_ping=\"2020-02-21 15:21:33\", device_last_ping_timetaken=\"26.3\", \ndevice_purpose=\"\", device_type=\"firewall\", device_serial=\"FGT50EXXX\", \ndevice_icon=\"images/os/fortinet.svg\", device_poller_group=\"0\", \ndevice_override_sysLocation=\"0\", device_notes=\"\", device_port_association_mode=\"1\", \ndevice_max_depth=\"0\", device_disable_notify=\"0\", device_location=\"\", \ndevice_vrf_lites=\"Array\", device_lat=\"\", device_lng=\"\", - \nsysObjectID => \"\"; `\n

Each alert will be sent as a separate message.

Example:

Config Example Host 127.0.0.1 UDP Port 514"},{"location":"Alerting/Transports/#syslog","title":"Syslog","text":"

You can have LibreNMS emit alerts as syslogs complying with RFC 3164.

More information on RFC 3164 can be found here: https://tools.ietf.org/html/rfc3164

Example output: <26> Mar 22 00:59:03 librenms.host.net librenms[233]: [Critical] network.device.net: Port Down - port_id => 98939; ifDescr => xe-1/1/0;

Each fault will be sent as a separate syslog.

Example:

Config Example Host 127.0.0.1 Port 514 Facility 3"},{"location":"Alerting/Transports/#telegram","title":"Telegram","text":"

Thank you to snis for these instructions.

  1. First you must create a telegram account and add BotFather to you list. To do this click on the following url: https://telegram.me/botfather

  2. Generate a new bot with the command \"/newbot\" BotFather is then asking for a username and a normal name. After that your bot is created and you get a HTTP token. (for more options for your bot type \"/help\")

  3. Add your bot to telegram with the following url: http://telegram.me/<botname> to use app or https://web.telegram.org/<botname> to use in web, and send some text to the bot.

  4. The BotFather should have responded with a token, copy your token code and go to the following page in chrome: https://api.telegram.org/bot<tokencode>/getUpdates (this could take a while so continue to refresh until you see something similar to below)

  5. You see a json code with the message you sent to the bot. Copy the Chat id. In this example that is \u201c-9787468\u201d within this example: \"message\":{\"message_id\":7,\"from\":\"id\":656556,\"first_name\":\"Joo\",\"last_name\":\"Doo\",\"username\":\"JohnDoo\"},\"chat\":{\"id\":-9787468,\"title\":\"Telegram Group\"},\"date\":1435216924,\"text\":\"Hi\"}}]}.

  6. Now create a new \"Telegram transport\" in LibreNMS (Global Settings -> Alerting Settings -> Telegram transport). Click on 'Add Telegram config' and put your chat id and token into the relevant box.

  7. If want to use a group to receive alerts, you need to pick the Chat ID of the group chat, and not of the Bot itself.

Telegram Docs

Example:

Config Example Chat ID 34243432 Token 3ed32wwf235234 Format HTML or MARKDOWN"},{"location":"Alerting/Transports/#twilio-sms","title":"Twilio SMS","text":"

Twilio will send your alert via SMS. From your Twilio account you will need your account SID, account token and your Twilio SMS phone number that you would like to send the alerts from. Twilio's APIs are located at: https://www.twilio.com/docs/api?filter-product=sms

Example:

Config Example SID ACxxxxxxxxxxxxxxxxxxxxxxxxxxxx Token 7xxxx573acxxxbc2xxx308d6xxx652d32 Twilio SMS Number 8888778660"},{"location":"Alerting/Transports/#ukfast-pss","title":"UKFast PSS","text":"

UKFast PSS tickets can be raised from alerts using the UKFastPSS transport. This required an API key with PSS write permissions

Example:

Config Example API Key ABCDefgfg12 Author 5423 Priority Critical Secure true"},{"location":"Alerting/Transports/#victorops","title":"VictorOps","text":"

VictorOps provide a webHook url to make integration extremely simple. To get the URL required login to your VictorOps account and go to:

Settings -> Integrations -> REST Endpoint -> Enable Integration.

The URL provided will have $routing_key at the end, you need to change this to something that is unique to the system sending the alerts such as librenms. I.e:

https://alert.victorops.com/integrations/generic/20132414/alert/2f974ce1-08fc-4dg8-a4f4-9aee6cf35c98/librenms

Example:

Config Example Post URL https://alert.victorops.com/integrations/generic/20132414/alert/2f974ce1-08fc-4dg8-a4f4-9aee6cf35c98/librenms"},{"location":"Alerting/Transports/#kayako-classic","title":"Kayako Classic","text":"

LibreNMS can send alerts to Kayako Classic API which are then converted to tickets. To use this module, you need REST API feature enabled in Kayako Classic and configured email account at LibreNMS. To enable this, do this:

AdminCP -> REST API -> Settings -> Enable API (Yes)

Also you need to know the department id to provide tickets to appropriate department and a user email to provide, which is used as ticket author. To get department id: navigate to appropriate department name at the departments list page in Admin CP and watch the number at the end of url. Example: http://servicedesk.example.com/admin/Base/Department/Edit/17. Department ID is 17

As a requirement, you have to know API Url, API Key and API Secret to connect to servicedesk

Kayako REST API Docs

Example:

Config Example Kayako URL http://servicedesk.example.com/api/ Kayako API Key 8cc02f38-7465-4a0c-8730-bb3af122167b Kayako API Secret Y2NhZDIxNDMtNjVkMi0wYzE0LWExYTUtZGUwMjJiZDI0ZWEzMmRhOGNiYWMtNTU2YS0yODk0LTA1MTEtN2VhN2YzYzgzZjk5 Kayako Department 1"},{"location":"Alerting/Transports/#signal-cli","title":"Signal CLI","text":"

Use the Signal Mesenger for Alerts. Run the Signal CLI with the D-Bus option.

GitHub Project

Example:

Config Example Path /opt/signal-cli/bin/signal-cli Recipient type Group Recipient dfgjsdkgljior4345=="},{"location":"Alerting/Transports/#smsfeedback","title":"SMSFeedback","text":"

SMSFeedback is a SAAS service, which can be used to deliver Alerts via API, using API url, Username & Password.

They can be in international dialling format only.

SMSFeedback Api Docs

Example:

Config Example User smsfeedback_user Password smsfeedback_password Mobiles 71234567890 Sender name CIA"},{"location":"Alerting/Transports/#zenduty","title":"Zenduty","text":"

Leveraging LibreNMS<>Zenduty Integration, users can send new LibreNMS alerts to the right team and notify them based on on-call schedules via email, SMS, Phone Calls, Slack, Microsoft Teams and mobile push notifications. Zenduty provides engineers with detailed context around the LibreNMS alert along with playbooks and a complete incident command framework to triage, remediate and resolve incidents with speed.

Create a LibreNMS Integration from inside Zenduty, then copy the Webhook URL from Zenduty to LibreNMS.

For a detailed guide with screenshots, refer to the LibreNMS documentation at Zenduty.

Example:

Config Example WebHook URL https://www.zenduty.com/api/integration/librenms/integration-key/"},{"location":"Developing/Application-Notes/","title":"Notes On Application Development","text":""},{"location":"Developing/Application-Notes/#librenms-json-snmp-extends","title":"LibreNMS JSON SNMP Extends","text":"

The polling function json_app_get makes it easy to poll complex data using SNMP extends and JSON.

The following exceptions are provided by it.

It takes three parameters, in order in the list below.

  • Integer :: Device ID to fetch it for.
  • String :: The extend name. For example, if 'zfs' is passed it will be converted to 'nsExtendOutputFull.3.122.102.115'.
  • Integer :: Minimum expected version of the JSON return.

The required keys for the returned JSON are as below.

  • version :: The version of the snmp extend script. Should be numeric and at least 1.
  • error :: Error code from the snmp extend script. Should be > 0 (0 will be ignored and negatives are reserved)
  • errorString :: Text to describe the error.
  • data :: An key with an array with the data to be used.

The supported exceptions are as below.

  • JsonAppPollingFailedException :: Empty return from SNMP.
  • JsonAppParsingFailedException :: Could not parse the JSON
  • JsonAppBlankJsonException :: Blank JSON.
  • JsonAppMissingKeysException :: Missing required keys.
  • JsonAppWrongVersionException :: Older version than supported.
  • JsonAppExtendErroredException :: Polling and parsing was good, but the returned data has an error set. This may be checked via $e->getParsedJson() and then checking the keys error and errorString.

The error value can be accessed via $e->getCode(). The output can be accessed via $->getOutput() Only returned JsonAppParsingFailedException. The parsed JSON can be access via $e->getParsedJson().

An example below from includes/polling/applications/zfs.inc.php...

try {\n    $zfs = json_app_get($device, $name, 1)['data'];\n} catch (JsonAppMissingKeysException $e) {\n    //old version with out the data key\n    $zfs = $e->getParsedJson();\n} catch (JsonAppException $e) {\n    echo PHP_EOL . $name . ':' . $e->getCode() . ':' . $e->getMessage() . PHP_EOL;\n    update_application($app, $e->getCode() . ':' . $e->getMessage(), []);\n\n    return;\n}\n
"},{"location":"Developing/Application-Notes/#compression","title":"Compression","text":"

Also worth noting that json_app_get supports compressed data via base64 encoded gzip. If base64 encoding is detected on the the SNMP return, it will be gunzipped and then parsed.

https://github.com/librenms/librenms-agent/blob/master/utils/librenms_return_optimizer may be used to optimize JSON returns.

"},{"location":"Developing/Application-Notes/#application-data-storage","title":"Application Data Storage","text":"

The $app model is supplied for each application poller and graph. You may access and update the $app->data field to store arrays of data the Application model.

When you call update_application() the $app model will be saved along with any changes to the data field.

// set the varaible data to $foo\n$app->data = [\n    'item_A' => 123,\n    'item_B' => 4.5,\n    'type' => 'foo',\n    'other_items' => [ 'a', 'b', 'c' ],\n];\n\n// save the change\n$app->save();\n\n// var_dump the contents of the variable\nvar_dump($app->data);\n
"},{"location":"Developing/Code-Structure/","title":"Code structure","text":"

This document will try and provide a good overview of how the code is structured within LibreNMS. We will go through the main directories and provide information on how and when they are used. LibreNMS now uses Laravel for much of it's frontend (webui) and database code. Much of the Laravel documentation applies: https://laravel.com/docs/structure

Directories from the (filtered) structure tree below are some of the directories that will be most interesting during development:

.\n\u251c\u2500 app\n\u251c\u2500 database\n\u2502  \u2514\u2500 migrations\n\u251c\u2500 doc\n\u251c\u2500 html\n\u2502  \u251c\u2500 css\n\u2502  \u2502  \u2514\u2500 custom\n\u2502  \u2514\u2500 js\n\u251c\u2500 includes\n\u2502  \u251c\u2500 definitions\n\u2502  \u251c\u2500 discovery\n\u2502  \u251c\u2500 html\n\u2502  \u2502  \u251c\u2500 forms\n\u2502  \u2502  \u251c\u2500 graphs\n\u2502  \u2502  \u251c\u2500 pages\n\u2502  \u2502  \u2514\u2500 reports\n\u2502  \u2514\u2500 polling\n\u251c\u2500 LibreNMS\n\u251c\u2500 logs\n\u251c\u2500 mibs\n\u2514\u2500 rrd\n
"},{"location":"Developing/Code-Structure/#doc","title":"doc/","text":"

This is the location of all the documentation for LibreNMS, this is in GitHub markdown format and can be viewed online

"},{"location":"Developing/Code-Structure/#app","title":"app/","text":"

Most Laravel and Eloquent classes should be under this directory.

"},{"location":"Developing/Code-Structure/#librenms","title":"LibreNMS/","text":"

Classes that don't belong to the Laravel application belong in this directory, with a directory structure that matches the namespace. One class per file. See PSR-0 for details.

"},{"location":"Developing/Code-Structure/#html","title":"html/","text":"

All legacy web accessible files are located here. New pages should follow the Laravel conventions.

"},{"location":"Developing/Code-Structure/#htmlapi_v0php","title":"html/api_v0.php","text":"

This is the API routing file which directs users to the correct API function based on the API endpoint call.

"},{"location":"Developing/Code-Structure/#htmlindexphp","title":"html/index.php","text":"

This is the main file which all links within LibreNMS are parsed through. It loads the majority of the relevant includes needed for the control panel to function. CSS and JS files are also loaded here.

"},{"location":"Developing/Code-Structure/#htmlcss","title":"html/css/","text":"

All used CSS files are located here.

"},{"location":"Developing/Code-Structure/#htmlcsscustom","title":"html/css/custom/","text":"

This is a directory you can put custom css files into that won't interfere with auto updates

"},{"location":"Developing/Code-Structure/#htmljs","title":"html/js/","text":"

All used JS files are located here.

"},{"location":"Developing/Code-Structure/#includes","title":"includes/","text":"

This directory is quite big and contains all the files to make the cli and polling / discovery to work. This code is not currently accessible from Laravel code (intentionally).

"},{"location":"Developing/Code-Structure/#includesdiscovery-includespolling","title":"includes/discovery/, includes/polling/","text":"

All the discovery and polling code. The format is usually quite similar between discovery and polling. Both are made up of modules and the files within the relevant directories will match that module. So for instance if you want to update the os detection for a device, you would look in includes/discovery/os/ for a file named after the operating system such as linux: includes/discovery/linux.inc.php. Within here you would update or add support for newer OS'. This is the same for polling as well.

"},{"location":"Developing/Code-Structure/#includeshtml","title":"includes/html/","text":"

This is where the majority of the website core files are located. These tend to be files that contain functions or often used code segments that can be included where needed rather than duplicating code.

"},{"location":"Developing/Code-Structure/#includeshtmlforms","title":"includes/html/forms/","text":"

This directory contains all of the files that are dynamically included from an ajax call to ajax/form.

"},{"location":"Developing/Code-Structure/#includeshtmlapi_functionsincphp","title":"includes/html/api_functions.inc.php","text":"

All of the functions and calls for the API are located here.

"},{"location":"Developing/Code-Structure/#includeshtmlfunctionsincphp","title":"includes/html/functions.inc.php","text":"

This contains the majority of functions used throughout the standard web ui.

"},{"location":"Developing/Code-Structure/#includeshtmlgraphs","title":"includes/html/graphs/","text":"

This directory contains global and OS specific graph definitions.

"},{"location":"Developing/Code-Structure/#includeshtmlreports","title":"includes/html/reports/","text":"

In here is a list of of files that generate PDF reports available to the user. These are dynamically called in from html/pdf.php based on the report the user requests.

"},{"location":"Developing/Code-Structure/#includeshtmltable","title":"includes/html/table/","text":"

This directory contains all of the ajax calls when generating the table of data. Most have been converted over so if you are planning to add a new table of data then you will do so here for all of the back end data calls.

"},{"location":"Developing/Code-Structure/#includeshtmlpages","title":"includes/html/pages/","text":"

This directory contains the URL structure when browsing the Web UI. So for example /devices/ is actually a call to includes/html/pages/devices.inc.php, /device/tab=ports/ is includes/html/pages/device/ports.inc.php.

"},{"location":"Developing/Code-Structure/#logs","title":"logs/","text":"

Contains the main librenms.log file by default, but can also contain your web server's logs, poller logs, and other items.

"},{"location":"Developing/Code-Structure/#mibs","title":"mibs/","text":"

Here is where all of the mibs are located. Generally standard mibs should be in the root directory and specific vendor mibs should be in their own subdirectory.

"},{"location":"Developing/Code-Structure/#rrd","title":"rrd/","text":"

Simple enough, this is where all of the rrd files are created. They are stored in directory based on the device hostname.

"},{"location":"Developing/Code-Structure/#databasemigrations","title":"database/migrations","text":"

Contains all the database migrations. See Laravel docs for additional info: https://laravel.com/docs/migrations

In general to create a new table you should run:

php artisan make:model ModelName -m -c -r\n
"},{"location":"Developing/Creating-Documentation/","title":"Creating Documentation","text":"

One of the goals of the LibreNMS project is to enable users to get all of the help they need from our documentation.

The documentation uses the markdown markup language and is generated with mkdocs. To edit or create markdown you only need a text editor, but it is recommended to build your docs before submitting, in order to check them visually. The section on this page has instructions for this step.

"},{"location":"Developing/Creating-Documentation/#writing-docs","title":"Writing docs","text":"

When you are adding a new feature or extension, we need to have full documentation to go along with it. It's quite simple to do this:

  • Find the relevant directory to store your new document in, General, Support and Extensions are the most likely choices.
  • Think of a descriptive name that's not too long, it should match what they may be looking for or describes the feature.
  • Add the new document into the nav section of mkdocs.yml if it needs to appear in the table of contents
  • Ensure the first line contains: source: path/to/file.md - don't include the initial doc/.
  • In the body of the document, be descriptive but keep things simple. Some tips:
  • If the document could cover different distros like CentOS and Ubuntu please try and include the information for them all. If that's not possible then at least put a placeholder in asking for contributions.
  • Ensure you use the correct formatting for commands and code blocks by wrapping one liners in backticks or blocks in ```.
  • Put content into sub-headings where possible to organise the content.
  • If you rename a file, please add a redirect for the old file in mkdocs.yml like so:
      - redirects:\n      redirect_maps:\n        'old/page.md': 'new/page.md'\n

Please ensure you add the document to the relevant section within pages of mkdocs.yml so that it's in the correct menu and is built. Forgetting this step will result in your document never seeing the light of day :)

"},{"location":"Developing/Creating-Documentation/#formatting-docs","title":"Formatting docs","text":"

Our docs are based on Markdown using mkdocs which adheres to markdown specs and nothing more, because of that we also import a couple of extra libraries:

  • pymdownx.tasklist
  • pymdownx.tilde

This means you can use:

  • ~~strikethrough~~ to perform strikethrough
  • - [X] List items
  • Url's can be made [like this](https://www.librenms.org) like this
  • Code can be placed in `` for single line or ``` for multiline.
  • # Can be used for main headings which translates to a <h1> tag, increasing the #'s will increase the hX tags.
  • ### Can be used for sub-headings which will appear in the TOC to the left.
  • Settings should be prefixed with !!! setting \"<webui setting path>\"

Markdown CheatSheet Link

"},{"location":"Developing/Creating-Documentation/#building-docs","title":"Building docs","text":"

This is achieved with mkdocs, a python package.

  1. Install the required packages.

pip install mkdocs mkdocs-exclude mkdocs-material mkdocs-macros-plugin mkdocs-minify-plugin mkdocs-redirects\n
If you encounter permissions issues, these might be reoslved by using the user option, with whatever user you are building as, e.g. -u librenms

  1. A configuration file for building LibreNMS docs is already included in the distribution: /opt/librenms/mkdocs.yml. The various configuration directives are documented here.

  2. Build from the librenms base directory: cd /opt/librenms.

  3. Building is simple:

mkdocs build\n

This will output all the documentation in html format to /opt/librenms/out (this folder will be ignored from any commits).

"},{"location":"Developing/Creating-Documentation/#viewing-docs","title":"Viewing docs","text":"

mkdocs includes it's own light-weight webserver for this purpose.

Viewing is as simple as running the following command:

$ mkdocs serve\nINFO    -  Building documentation...\n<..>\nINFO    -  Documentation built in 12.54 seconds\n<..>\nINFO    -  Serving on http://127.0.0.1:8000\n<..>\nINFO    -  Start watching changes\n

Now you will find the complete set of LibreNMS documentation by opening your browser to localhost:8000.

Note it is not necessary to build before viewing as the serve command will do this for you. Also the server will update the documents it is serving whenever changes to the markdown are made, such as in another terminal.

"},{"location":"Developing/Creating-Documentation/#viewing-docs-from-another-machine","title":"Viewing docs from another machine","text":"

By default the server will only listen for connections from the local machine. If you are building on a different machine you can use the following directive to listen on all interfaces:

mkdocs serve --dev-addr=0.0.0.0:8000\n

WARNING: this is not a secure webserver, do this at your own risk, with appropriate host security and do not leave the server running.

"},{"location":"Developing/Creating-Release/","title":"Creating a release","text":""},{"location":"Developing/Creating-Release/#github","title":"GitHub","text":"

You can create a new release on GitHub.

Enter the tag version that month, i.e for September 2016 you would enter 201609.

Enter a title, we usually use August 2016 Release

Enter a placeholder for the body, we will edit this later.

"},{"location":"Developing/Creating-Release/#create-changelog","title":"Create changelog","text":"

For this, we assume you are using the master branch to create the release against.

We now generate the changelog using the GitHub API itself so it shouldn't matter what state your local branch is in so long as it has the code to generate the changelog itself.

Using the GitHub API means we can use the labels associated with merged pull requests to categorise the changelog. We also then record who made the pull request to thank them in the changelog itself.

You will be asked for a GitHub personal access token. You can generate this here. No permissions should be needed so just give it a name and click Generate Token. You can then export the token as an environment variable GH_TOKEN or place it in your .env file.

The basic command to run is by using artisan. Here you pass new tag (1.41) and previous tag (1.40). For further help run php artisan release:tag --help. This will generate a changelog up to the latest master branch, if you want it to be done against something else then pass the latest pull request number with --pr $PR_NUMBER.

php artisan release:tag 1.41 1.40\n
  • Now commit and push the change that has been made to doc/General/Changelog.md.
  • Once the pull request has been merged in for the Changelog, you can create a new release on GitHub.
  • Create two threads on the community site:
  • A changelog thread example
  • An info thread example
  • Tweet it
  • Facebook it
  • Google Plus it
  • LinkedIn it
"},{"location":"Developing/Dynamic-Config/","title":"Adding new config settings","text":"

Adding support for users to update a new config option via the WebUI is now a lot easier for general options. This document shows you how to add a new config option and even section to the WebUI.

Config settings are defined in misc/config_definitions.json

You should give a little thought to the name of your config setting. For example: a good setting for snmp community, would be snmp.community. The dot notation is path and when the config is hydrated, it is converted to a nested array. If the user is overriding the option in config.php it would use the format $config['snmp']['community']

"},{"location":"Developing/Dynamic-Config/#translation","title":"Translation","text":"

The config definition system inherently supports translation. You must add the English names in the resoures/lang/en/settings.php file (and other languages if you can).

To update the javascript translation files, run:

./lnms translation:generate\n
"},{"location":"Developing/Dynamic-Config/#definition-format","title":"Definition Format","text":"

For snmp.community, this is the definition:

\"snmp.community\": {\n    \"group\": \"poller\",\n    \"section\": \"snmp\",\n    \"order\": 2,\n    \"type\": \"array\",\n    \"default\": [\n        \"public\"\n    ]\n}\n
"},{"location":"Developing/Dynamic-Config/#fields","title":"Fields","text":"

All fields are optional. To show in the web ui, group and section are required, order is recommended.

  • type: Defines the type, there are a few predefined types and custom types can be defined and implemented in a vue.js component
  • default: the default value for this setting
  • options: the options for the select type. An object with {\"value1\": \"display string\", \"value2\": \"display string\"}
  • validate: Defines more complex validation than the default simple type check. Uses Laravel validation syntax.
  • group: The web ui tab this is under
  • section: A panel grouping settings in the web ui
  • order: The order to display this setting within the section
"},{"location":"Developing/Dynamic-Config/#predefined-types","title":"Predefined Types","text":"
  • string: A string
  • integer: A number
  • boolean: A simple toggle switch
  • array: A list of values that can be added, removed, and re-ordered.
  • select: A dropdown box with predefined options. Requires the option field.
  • email: Will validate the input is the correct format for an email
  • password: Will mask the value of the input (but does not keep it fully private)
"},{"location":"Developing/Dynamic-Config/#custom-types","title":"Custom Types","text":"

You may set the type field to a custom type and define a Vue.js component to display it to the user.

The Vue.js component should be named as \"SettingType\" where type is the custom type entered with the first letter capitalized. Vue.js components exist in the resources/js/components directory.

Here is an empty component named SettingType (make sure to rename it). It pulls in BaseSetting mixin for basic setting code to reuse. You should review the BaseSetting component.

<template>\n    <div></div>\n</template>\n\n<script>\n    import BaseSetting from \"./BaseSetting\";\n\n    export default {\n        name: \"SettingType\",\n        mixins: [BaseSetting]\n    }\n</script>\n\n<style scoped>\n\n</style>\n

Using Vue.js is beyond the scope of this document. Documentation can be found at vuejs.org.

"},{"location":"Developing/Getting-Started/","title":"Get ready to contribute to LibreNMS","text":"

This document is intended to help you get your local environment set up to contribute code to the LibreNMS project.

"},{"location":"Developing/Getting-Started/#setting-up-a-development-environment","title":"Setting up a development environment","text":"

When starting to develop, it may be tempting to just make changes on your production server, but that will make things harder for you. Taking a little time to set up somewhere to work on code changes can really help.

Possible options:

  • A Linux computer, VM, or container
  • Another directory on your LibreNMS server
  • Windows Subsystem for Linux
"},{"location":"Developing/Getting-Started/#set-up-your-development-git-clone","title":"Set up your development git clone","text":"
  1. Follow the documentation on using git

  2. Install development dependencies ./scripts/composer_wrapper.php install

  3. Set variables in .env, including database settings. Which could be a local or remote MySQL server including your production DB.

APP_ENV=local\nAPP_DEBUG=true\n...\n
  1. Start a development webserver ./lnms serve

  2. Access the Web UI at http://localhost:8000

"},{"location":"Developing/Getting-Started/#automated-testing","title":"Automated testing","text":"

LibreNMS uses continuous integration to test code changes to help reduce bugs. This also helps guarantee the changes you contribute won't be broken in the future. You can find out more in our Validating Code Documentation

The default database connection for automated testing is testing.

To override the database parameters for unit tests, configure your .env file accordingly. The defaults (from config/database.php) are:

DB_TEST_DRIVER=\"mysql\"   # PDO driver\nDB_TEST_HOST=\"localhost\" # hostname or IP address\nDB_TEST_PORT=\"\"          # port\nDB_TEST_DATABASE=\"librenms_phpunit_78hunjuybybh\" # database\nDB_TEST_USERNAME=\"root\"  # username\nDB_TEST_PASSWORD=\"\"      # password\nDB_TEST_SOCKET=\"\"        # unix socket path\n
"},{"location":"Developing/Getting-Started/#polling-debug-output","title":"Polling debug output","text":"

You can see detailed info by running your polling code in debug mode by adding a -d flag.

./discovery.php -d -h HOSTNAME\nlnms device:poll HOSTNAME -vv\n
"},{"location":"Developing/Getting-Started/#inspecting-variables","title":"Inspecting variables","text":"

Sometimes you want to find out what a variable contains (such as the data return from an snmpwalk). You can dump one or more variables and halt execution with the dd() function.

dd($variable1, $variable2);\n
"},{"location":"Developing/Getting-Started/#inspecting-web-pages","title":"Inspecting web pages","text":"

Installing the development dependencies and setting APP_DEBUG enables the Laravel Debugbar This will allow you to inspect page generation and errors right in your web browser.

"},{"location":"Developing/Getting-Started/#better-code-completion-in-ides-and-editors","title":"Better code completion in IDEs and editors","text":"

You can generate some files to improve code completion. (These file are not updated automatically, so you may need to re-run these command periodically)

./lnms ide-helper:generate\n./lnms ide-helper:models -N\n
"},{"location":"Developing/Getting-Started/#emulating-devices","title":"Emulating devices","text":"

You can capture and emulate devices using Snmpsim. LibreNMS has a set of scripts to make it easier to work with snmprec files. LibreNMS Snmpsim helpers

"},{"location":"Developing/Getting-Started/#laravel-documentation","title":"Laravel documentation","text":"

You can find a lot of how LibreNMS works by following the Laravel Documentation

"},{"location":"Developing/Merging-Pull-Requests/","title":"Merging Pull Requests","text":""},{"location":"Developing/Merging-Pull-Requests/#github","title":"GitHub","text":"

We will now build the monthly change log from our GitHub commits. When merging a commit, please ensure you:

  • Click the Merge pull request button
  • Give the merge a descriptive but short title
  • For the commit message prepend it with one of the following tags for the pull request to appear in the changelog:
  • devices: or newdevice: For new device support.
  • feature: or feat: To indicate this is a new or updated feature
  • webui: or web: To indicate this is an update to the WebUI
  • fix: or bugfix: To show this is a bug fix.
  • refactoring: or refactor: When the changes are refactoring a large portion of code
  • You can reference an issue number with #xyz, i.e #1234
  • Use the Confirm squash and merge button to merge.
"},{"location":"Developing/Merging-Pull-Requests/#example-commits","title":"Example commits","text":""},{"location":"Developing/Merging-Pull-Requests/#feature","title":"Feature","text":"

feature: Added new availability map #4401

"},{"location":"Developing/Merging-Pull-Requests/#new-device","title":"New device","text":"

newdevice: Added support for Cisco ASA #4402

"},{"location":"Developing/SNMP-Traps/","title":"Creating snmp trap handlers","text":"

You must have a working snmptrapd. See SNMP TRAP HANDLER

Make sure the MIB is loaded from the trap you are adding. Edit /etc/systemd/system/snmptrapd.service.d/mibs.conf to add it then restart snmptrapd.

MIBDIRS option is not recursive, so you need to specify each directory individually.

Create a new class in LibreNMS\\Snmptrap\\Handlers that implements the LibreNMS\\Interfaces\\SnmptrapHandler interface. For example:

<?php\n/**\n * ColdBoot.php\n *\n * Handles the SNMPv2-MIB::coldStart trap\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <https://www.gnu.org/licenses/>.\n *\n * @package    LibreNMS\n * @link       https://www.librenms.org\n */\n\nnamespace LibreNMS\\Snmptrap\\Handlers;\n\nuse App\\Models\\Device;\nuse LibreNMS\\Enum\\Severity;\nuse LibreNMS\\Interfaces\\SnmptrapHandler;\nuse LibreNMS\\Snmptrap\\Trap;\n\nclass ColdBoot implements SnmptrapHandler\n{\n    /**\n     * Handle snmptrap.\n     * Data is pre-parsed and delivered as a Trap.\n     *\n     * @param Device $device\n     * @param Trap $trap\n     * @return void\n     */\n    public function handle(Device $device, Trap $trap)\n    {\n        $trap->log('SNMP Trap: Device ' . $device->displayName() . ' cold booted', $device->device_id, 'reboot', Severity::Warning);\n    }\n}\n

where number on the end means color of the eventlog:

Severity::Ok = green\nSeverity::Info = cyan\nSeverity::Notice = blue\nSeverity::Warning = yellow\nSeverity::Error = red\n

Register the mapping in the config/snmptraps.php file. Make sure to use the full trap OID and correct class.

'SNMPv2-MIB::coldStart' => \\LibreNMS\\Snmptrap\\Handlers\\ColdBoot::class,\n

The handle function inside your new class will receive a LibreNMS/Snmptrap/Trap object containing the parsed trap. It is common to update the database and create event log entries within the handle function.

"},{"location":"Developing/SNMP-Traps/#getting-information-from-the-trap","title":"Getting information from the Trap","text":""},{"location":"Developing/SNMP-Traps/#source-information","title":"Source information","text":"
$trap->getDevice();   // gets Device model for the device associated with this trap\n$trap->ip;            // gets source IP of this trap\n$trap->getTrapOid();  // returns the string you registered your class with\n
"},{"location":"Developing/SNMP-Traps/#retrieving-data-from-the-trap","title":"Retrieving data from the Trap","text":"
$trap->getOidData('IF-MIB::ifDescr.114');\n

getOidData() requires the full name including any additional index. You can use these functions to search the OID keys.

$trap->findOid('ifDescr');  // returns the first oid key that contains the string\n$trap->findOids('ifDescr'); // returns all oid keys containing the string\n
"},{"location":"Developing/SNMP-Traps/#advanced","title":"Advanced","text":"

If the above isn't adequate, you can get the entire trap text:

$trap->raw;\n
"},{"location":"Developing/SNMP-Traps/#tests","title":"Tests","text":"

Submitting new traps requires them to be fully tested. You can find many examples in the tests/Feature/SnmpTraps/ directory.

Here is a basic example of a test that trap handler only creates a log message. If your trap modifies the database, you should also test that it does so.

<?php\n\nnamespace LibreNMS\\Tests\\Feature\\SnmpTraps;\n\nclass ColdStratTest extends SnmpTrapTestCase\n{\n    public function testColdStart(): void\n    {\n        $this->assertTrapLogsMessage(rawTrap: <<<'TRAP'\n{{ hostname }}\nUDP: [{{ ip }}]:44298->[192.168.5.5]:162\nDISMAN-EVENT-MIB::sysUpTimeInstance 0:0:1:12.7\nSNMPv2-MIB::snmpTrapOID.0 SNMPv2-MIB::coldStart\nTRAP,\n            log: 'SNMP Trap: Device {{ hostname }} cold booted', // The log message sent\n            failureMessage: 'Failed to handle SNMPv2-MIB::coldStart', // an informative message to let user know what failed\n            args: [4, 'reboot'], // the additional arguments to the log method\n        );\n    }\n}\n
"},{"location":"Developing/Sensor-State-Support/","title":"Sensor State Support","text":""},{"location":"Developing/Sensor-State-Support/#introduction","title":"Introduction","text":"

In this section we are briefly going to walk through, what it takes to write sensor state support. We will also briefly get around the concepts of the current sensor state monitoring.

"},{"location":"Developing/Sensor-State-Support/#logic","title":"Logic","text":"

For sensor state monitoring, we have 4 DB tables we need to concentrate about.

  • sensors
  • state_indexes
  • state_translations
  • sensors_to_state_indexes

We will just briefly tie a comment to each one of them.

"},{"location":"Developing/Sensor-State-Support/#sensors","title":"Sensors","text":"

Each time a sensor needs to be polled, the system needs to know which sensor is it that it need to poll, at what oid is this sensor located and what class the sensor is etc. This information is fetched from the sensors table.

"},{"location":"Developing/Sensor-State-Support/#state_indexes","title":"state_indexes","text":"

Is where we keep track of which state sensors we monitor.

"},{"location":"Developing/Sensor-State-Support/#state_translations","title":"state_translations","text":"

Is where we map the possible returned state sensor values to a generic LibreNMS value, in order to make displaying and alerting more generic. We also map these values to the actual state sensor(state_index) where these values are actually returned from.

The LibreNMS generic states are derived from Nagios:

0 = OK\n1 = Warning\n2 = Critical\n3 = Unknown\n
"},{"location":"Developing/Sensor-State-Support/#sensors_to_state_indexes","title":"sensors_to_state_indexes","text":"

Is as you might have guessed, where the sensor_id is mapped to a state_index_id.

"},{"location":"Developing/Sensor-State-Support/#example","title":"Example","text":"

For YAML based state discovery:

mib: NETBOTZV2-MIB\nmodules:\n    sensors:\n        state:\n            data:\n                -\n                    oid: dryContactSensorTable\n                    value: dryContactSensorValue\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.1.1.2.{{ $index }}'\n                    descr: dryContactSensorLabel\n                    group: Contact Sensors\n                    index: 'dryContactSensor.{{ $index }}'\n                    state_name: dryContactSensor\n                    states:\n                        - { value: -1, generic: 3, graph: 0, descr: 'null' }\n                        - { value:  0, generic: 0, graph: 0, descr: open }\n                        - { value:  1, generic: 2, graph: 0, descr: closed }\n                -\n                    oid: doorSwitchSensorTable\n                    value: doorSwitchSensorValue\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.2.1.2.{{ $index }}'\n                    descr: doorSwitchSensorLabel\n                    group: Switch Sensors\n                    index: 'doorSwitchSensor.{{ $index }}'\n                    state_name: doorSwitchSensor\n                    states:\n                        - { value: -1, generic: 3, graph: 0, descr: 'null' }\n                        - { value:  0, generic: 0, graph: 0, descr: open }\n                        - { value:  1, generic: 2, graph: 0, descr: closed }\n                -\n                    oid: cameraMotionSensorTable\n                    value: cameraMotionSensorValue\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.3.1.2.{{ $index }}'\n                    descr: cameraMotionSensorLabel\n                    group: Camera Motion Sensors\n                    index: 'cameraMotionSensor.{{ $index }}'\n                    state_name: cameraMotionSensor\n                    states:\n                        - { value: -1, generic: 3, graph: 0, descr: 'null' }\n                        - { value:  0, generic: 0, graph: 0, descr: noMotion }\n                        - { value:  1, generic: 2, graph: 0, descr: motionDetected }\n                -\n                    oid: otherStateSensorTable\n                    value: otherStateSensorErrorStatus\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.10.1.3.{{ $index }}'\n                    descr: otherStateSensorLabel\n                    index: '{{ $index }}'\n                    state_name: otherStateSensorErrorStatus\n                    states:\n                        - { value: 0, generic: 0, graph: 0, descr: normal }\n                        - { value: 1, generic: 1, graph: 0, descr: info }\n                        - { value: 2, generic: 1, graph: 0, descr: warning }\n                        - { value: 3, generic: 2, graph: 0, descr: error }\n                        - { value: 4, generic: 2, graph: 0, descr: critical }\n                        - { value: 5, generic: 2, graph: 0, descr: failure }\n
"},{"location":"Developing/Sensor-State-Support/#advanced-example","title":"Advanced Example","text":"

For advanced state discovery:

This example will be based on a Cisco power supply sensor and is all it takes to have sensor state support for Cisco power supplies in Cisco switches. The file should be located in /includes/discovery/sensors/state/cisco.inc.php.

<?php\n\n$oids = snmpwalk_group($device, 'ciscoEnvMonSupplyStatusTable', 'CISCO-ENVMON-MIB');\n\nif (!empty($oids)) {\n    //Create State Index\n    $state_name = 'ciscoEnvMonSupplyState';\n    $states = [\n        ['value' => 1, 'generic' => 0, 'graph' => 0, 'descr' => 'normal'],\n        ['value' => 2, 'generic' => 1, 'graph' => 0, 'descr' => 'warning'],\n        ['value' => 3, 'generic' => 2, 'graph' => 0, 'descr' => 'critical'],\n        ['value' => 4, 'generic' => 3, 'graph' => 0, 'descr' => 'shutdown'],\n        ['value' => 5, 'generic' => 3, 'graph' => 0, 'descr' => 'notPresent'],\n        ['value' => 6, 'generic' => 2, 'graph' => 0, 'descr' => 'notFunctioning'],\n    ];\n    create_state_index($state_name, $states);\n\n    $num_oid = '.1.3.6.1.4.1.9.9.13.1.5.1.3.';\n    foreach ($oids as $index => $entry) {\n        //Discover Sensors\n        discover_sensor($valid['sensor'], 'state', $device, $num_oid.$index, $index, $state_name, $entry['ciscoEnvMonSupplyStatusDescr'], '1', '1', null, null, null, null, $entry['ciscoEnvMonSupplyState'], 'snmp', $index);\n\n        //Create Sensor To State Index\n        create_sensor_to_state_index($device, $state_name, $index);\n    }\n}\n
"},{"location":"Developing/Support-New-OS/","title":"Intro","text":"

This document is broken down into the relevant sections depending on what support you are adding. During all of these examples we will be using the OS of pulse as the example OS we will add.

  • Adding the initial detection.
  • Adding Memory and CPU information.
  • Adding Health / Sensor information.
  • Adding Wireless Sensor information.
  • Adding custom graphs.
  • Adding Unit tests (required).
  • Optional Settings

We currently have a script in pre-beta stages that can help speed up the process of deploying a new OS. It has support for add sensors in a basic form (except state sensors).

In this example, we will add a new OS called test-os using the device ID 101 that has already been added. It will be of the type network and belongs to the vendor, Cisco:

./scripts/new-os.php -h 101 -o test-os -t network -v cisco

The process will then step you through the process with some more questions. Please be warned, this is currently pre-beta and may cause some issues. Please let us know of any on Discord.

"},{"location":"Developing/Using-Git/","title":"Using Git","text":"

Git can have a bit of a steep learning curve, stick with it as it is worth learning the basics2 at least.

If you want to help develop LibreNMS and haven't really used Git before then this quick primer will help you get started.

Some assumptions:

  • Work is being done on a Linux box.
  • LibreNMS is to be installed in /opt/librenms
  • You have git installed.
  • You have a GitHub Account.
  • You are using ssh to connect to GitHub (If not, replace git@github.com:/yourusername/librenms.git with https://github.com/yourusername/librenms.git.

** Replace yourusername with your GitHub username. **

"},{"location":"Developing/Using-Git/#fork-librenms-repo","title":"Fork LibreNMS repo","text":"

You do this directly within GitHub, click the 'Fork' button near the top right.

If you are associated with multiple organisations within GitHub then you might need to select which account you want to push the fork to.

"},{"location":"Developing/Using-Git/#prepare-your-git-environment","title":"Prepare your git environment","text":"

These are the defaults that are recommended.

git config branch.autosetupmerge true\ngit config --global user.name \"John Doe\"\ngit config --global user.email johndoe@example.com\n
"},{"location":"Developing/Using-Git/#clone-the-repo","title":"Clone the repo","text":"

Ok so now that you have forked the repo, you now need to clone it to your local install where you can then make the changes you need and submit them back.

cd /opt/\ngit clone git@github.com:/yourusername/librenms.git\n
"},{"location":"Developing/Using-Git/#add-upstream-repo","title":"Add Upstream repo","text":"

To be able to pull in changes from the master LibreNMS repo you need to have it setup on your system.

git remote add upstream https://github.com/librenms/librenms.git\n

Now you have two configured remotes:

  • origin: This is your repository, you can push and pull changes here.
  • upstream: This is the main LibreNMS repository and you can only pull changes.
"},{"location":"Developing/Using-Git/#workflow-guide","title":"Workflow guide","text":"

As you become more familiar you may find a better workflow that fits your needs, until then this should be a safe workflow for you to follow.

Before you start work on a new branch / feature. Make sure you are up to date.

cd /opt/librenms\ngit checkout master\ngit pull upstream master\ngit push origin master\n

At this stage it's worth pointing out that we have some standard checks that are performed when you submit a pull request, you can run these checks yourself to be sure no issues are present in your pull request.

Now, create a new branch to do you work on. It's important that you do this as you are then able to work on more than one feature at a time and submit them as pull requests individually. If you did all your work in the master branch then it gets a bit messy!

You need to give your branch a name. If an issue is open (or closed on GitHub) then you can use that, in this example if the issue number is 123 then we will use issue-123. If a post exists on the community forum then you can use the post id like community-123. You're also welcome to use any arbitrary name for your branch but try and make it relevant to what the branch is.

git checkout -b issue-123\n

Now, code away. Make the changes you need, test, change and test again :) When you are ready to submit the updates as a pull request then commit away.

git add path/to/new/files/or/folders\ngit commit -a -m 'Added feature to do X, Y and Z'\ngit push origin issue-123\n

If you need to rebase against master then you can do this with:

git pull upstream master\ngit push origin issue-123\n

If after do this you get some merge conflicts then you need to resolve these before carrying on.

Please try to squash all commits into one, this isn't essential as we can do this when we merge but it would be helpful to do this before you submit your pull request.

Now you will be ready to submit a pull request from within GitHub. To do this, go to your GitHub page for the LibreNMS repo. Now select the branch you have just been working on (issue-123) from the drop down to the left and then click 'Pull Request'. Fill in the details to describe the work you have done and click 'Create pull request'.

Thanks for your first pull request :)

Ok, that should get you started on the contributing path. If you have any other questions then stop by our Discord Server

"},{"location":"Developing/Using-Git/#hints-and-tips","title":"Hints and tips","text":"

Undo last commit

git reset --soft 'HEAD^'

Remove specific commit

git revert <HASH>

Restore deleted file

git checkout $(git rev-list -n 1 HEAD -- \"$file\")^ -- \"$file\"

Merge last two commits

git rebase --interactive HEAD~2

In the text file that opens, change the last commit to squash from pick then save an exit.

For more tips take a look at Oh shit, git!

"},{"location":"Developing/Validating-Code/","title":"Validating Code","text":""},{"location":"Developing/Validating-Code/#validating-code","title":"Validating Code","text":"

As part of the pull request process with GitHub we run some automated build tests to ensure that the code is error free, standards compliant and our test suite builds successfully.

Rather than submit a pull request and wait for the results, you can run these checks yourself to ensure a more seamless merge.

All of these commands should be run from within the librenms directory and can be run as the librenms user unless otherwise noted.

Install composer (you can skip this if composer is already installed).

curl -sS https://getcomposer.org/installer | php

Composer will now be installed into /opt/librenms/composer.phar.

Now install the dependencies we require:

./composer.phar install

Once composer is installed you can now run the code validation script:

./lnms dev:check

If you see Tests ok, submit away :) then all is well. If you see other output then it should contain what you need to resolve the issues and re-test.

"},{"location":"Developing/Validating-Code/#git-hooks","title":"Git Hooks","text":"

Git has a hook system which you can use to trigger checks at various stages. Utilising the ./lnms dev:check you can make this part of your commit process.

Add ./lnms dev:check to your .git/hooks/pre-commit:

echo \"/opt/librenms/lnms dev:check\" >> /opt/librenms/.git/hooks/pre-commit\nchmod +x /opt/librenms/.git/hooks/pre-commit\n
"},{"location":"Developing/os/Custom-Graphs/","title":"Custom Graphs","text":"

First we define our graphs in includes/definitions.inc.php to share our work and contribute in the development of LibreNMS. :-) (or place in config.php if you don't plan to contribute)

// Pulse Secure Graphs\n$config['graph_types']['device']['pulse_sessions'] = ['section' => 'firewall', 'order' => 0, 'descr' => 'Active Sessions'];\n$config['graph_types']['device']['pulse_users'] = ['section' => 'firewall', 'order' => 0, 'descr' => 'Active Users'];\n
"},{"location":"Developing/os/Custom-Graphs/#polling-os","title":"Polling OS","text":"

OS polling is not necessarily where custom polling should be done, please speak to one of the core devs in Discord for guidance.

Let's update our example file to add additional polling:

includes/polling/os/pulse.inc.php\n

We declare two specific graphs for users and sessions numbers. Theses two graphs will be displayed on the firewall section of the graphs tab as it was written in the definition include file.

<?php\n\nuse LibreNMS\\RRD\\RrdDefinition;\n\n$users = snmp_get($device, 'iveConcurrentUsers.0', '-OQv', 'PULSESECURE-PSG-MIB');\n\nif (is_numeric($users)) {\n    $rrd_def = RrdDefinition::make()->addDataset('users', 'GAUGE', 0);\n\n    $fields = array(\n        'users' => $users,\n    );\n\n    $tags = compact('rrd_def');\n    data_update($device, 'pulse_users', $tags, $fields);\n    $os->enableGraph('pulse_users');\n}\n\n$sessions = snmp_get($device, 'iveConcurrentUsers.0', '-OQv', 'PULSESECURE-PSG-MIB');\n\nif (is_numeric($sessions)) {\n    $rrd_def = RrdDefinition::make()->addDataset('sessions', 'GAUGE', 0);\n\n    $fields = array(\n        'sessions' => $sessions,\n    );\n\n    $tags = compact('rrd_def');\n    data_update($device, 'pulse_sessions', $tags, $fields);\n    $os->enableGraph('pulse_sessions');\n}\n
"},{"location":"Developing/os/Custom-Graphs/#displaying","title":"Displaying","text":"

The specific graphs are not displayed automatically so we need to write the following PHP code:

Pulse Sessions

includes/html/graphs/device/pulse_sessions.inc.php\n
<?php\n\n$rrd_filename = Rrd::name($device['hostname'], 'pulse_sessions');\n\nrequire 'includes/html/graphs/common.inc.php';\n\n$ds = 'sessions';\n\n$colour_area = '9999cc';\n$colour_line = '0000cc';\n\n$colour_area_max = '9999cc';\n\n$graph_max = 1;\n\n$unit_text = 'Sessions';\n\nrequire 'includes/graphs/generic_simplex.inc.php';\n

Pulse Users

includes/html/graphs/device/pulse_users.inc.php\n
<?php\n\n$rrd_filename = Rrd::name($device['hostname'], 'pulse_users');\n\nrequire 'includes/html/graphs/common.inc.php';\n\n$ds = 'users';\n\n$colour_area = '9999cc';\n$colour_line = '0000cc';\n\n$colour_area_max = '9999cc';\n\n$graph_max = 1;\n\n$unit_text = 'Users';\n\nrequire 'includes/html/graphs/generic_simplex.inc.php';\n

That should be it, after data has started to be collected graphs should appear in the WebUI.

"},{"location":"Developing/os/Health-Information/","title":"Health Information","text":""},{"location":"Developing/os/Health-Information/#sensors","title":"Sensors","text":"

This document will guide you through adding health / sensor information for your new device.

Currently, we have support for the following health metrics along with the values we expect to see the data in:

Class Measurement airflow cfm ber ratio charge % chromatic_dispersion ps/nm cooling W count # current A dbm dBm delay s eer eer fanspeed rpm frequency Hz humidity % load % loss % power W power_consumed kWh power_factor ratio pressure kPa quality_factor dB runtime Min signal dBm snr SNR state # temperature C tv_signal dBmV bitrate bps voltage V waterflow l/m percent %"},{"location":"Developing/os/Health-Information/#simple-health-discovery","title":"Simple health discovery","text":"

We have support for defining health / sensor discovery using YAML files so that you don't need to know how to write PHP.

Please note that DISPLAY-HINTS are disabled so ensure you use the correct divisor / multiplier if applicable.

All yaml files are located in includes/definitions/discovery/$os.yaml. Defining the information here is not always possible and is heavily reliant on vendors being sensible with the MIBs they generate. Only snmp walks are supported, and you must provide a sane table that can be traversed and contains all the data you need. We will use netbotz as an example here.

includes/definitions/discovery/netbotz.yaml

mib: NETBOTZV2-MIB\nmodules:\n    sensors:\n        airflow:\n            options:\n                skip_value_lt: 0\n            data:\n                -\n                    oid: airFlowSensorTable\n                    value: airFlowSensorValue\n                    divisor: 10\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.1.5.1.2.{{ $index }}'\n                    descr: '{{ $airFlowSensorLabel }}'\n                    index: 'airFlowSensorValue.{{ $index }}'\n

At the top you can define one or more mibs to be used in the lookup of data:

mib: NETBOTZV2-MIB For use of multiple MIB files separate them with a colon: mib: NETBOTZV2-MIB:SECOND-MIB

For data: you have the following options:

The only sensor we have defined here is airflow. The available options are as follows:

  • oid (required): This is the name of the table you want to snmp walk for data.
  • value (optional): This is the key within the table that contains the value. If not provided will use oid
  • num_oid (required for PullRequests): If not provided, this parameter should be computed automatically by discovery process. This parameter is still required to submit a pull request. This is the numerical OID that contains value. This should usually include {{ $index }}. In case the index is a string, {{ $str_index_as_numeric }} can be used instead and will convert the string to the equivalent OID representation.
  • divisor (optional): This is the divisor to use against the returned value.
  • multiplier (optional): This is the multiplier to use against the returned value.
  • low_limit (optional): This is the critical low threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
  • low_warn_limit (optional): This is the warning low threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
  • warn_limit (optional): This is the warning high threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
  • high_limit (optional): This is the critical high threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
  • descr (required): The visible label for this sensor. It can be a key with in the table or a static string, optionally using {{ index }}.
  • group (optional): Groups sensors together under in the webui, displaying this text. Not specifying this will put the sensors in the default group.
  • index (optional): This is the index value we use to uniquely identify this sensor. {{ $index }} will be replaced by the index from the snmp walk.
  • skip_values (optional): This is an array of values we should skip over (see note below).
  • skip_value_lt (optional): If sensor value is less than this, skip the discovery.
  • skip_value_gt (optional): If sensor value is greater than this, skip the discovery.
  • entPhysicalIndex and entPhysicalIndex_measured (optional) : If the sensor belongs to a physical entity then you can link them here. The currently supported variants are :
    • entPhysicalIndex contains the entPhysicalIndex from entPhysical table, and entPhysicalIndex_measured is NULL
    • entPhysicalIndex contains \"ifIndex\" value of the linked port and entPhysicalIndex_measured contains \"ports\"
  • user_func (optional): You can provide a function name for the sensors value to be processed through (i.e. Convert fahrenheit to celsius use fahrenheit_to_celsius)
  • snmp_flags (optional): this sets the flags to be sent to snmpwalk, it overrides flags set on the sensor type and os. The default is '-OQUb'. A common issue is dealing with string indexes, setting '-OQUsbe' will change them to numeric oids. Setting ['-OQUsbe', '-Pu'] will also allow _ in oid names. You can find more in the Man Page
  • rrd_type (optional): You can change the type of the RRD file that will be created to store the data. By default, type GAUGE is used. More details can be found here: https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html

For options: you have the following available:

  • divisor: This is the divisor to use against the returned value.
  • multiplier: This is the multiplier to use against the returned value.
  • skip_values: This is an array of values we should skip over (see note below).
  • skip_value_lt: If sensor value is less than this, skip the discovery.
  • skip_value_gt: If sensor value is greater than this, skip the discovery.

Multiple variables can be used in the sensor's definition. The syntax is {{ $variable }}. Any oid in the current table can be used, as well as pre_cached data. The index ($index) and the sub_indexes (in case the oid is indexed multiple times) are also available: if $index=\"1.20\", then $subindex0=\"1\" and $subindex1=\"20\".

When referencing an oid in another table the full index will be used to match the other table. If this is undesirable, you may use a single sub index by appending the sub index after a colon to the variable name. Example {{ $ifName:2 }}

skip_values can also compare items within the OID table against values. The index of the sensor is used to retrieve the value from the OID, unless a target index is appended to the OID. Additionally, you may check fields from the device. Comparisons behave on a logical OR basis when chained, so only one of them needs to be matched for that particular sensor to be skipped during discovery. An example of this is below:

                    skip_values:\n                    -\n                      oid: sensUnit\n                      op: '!='\n                      value: 4\n                    -\n                      oid: sensConfig.0\n                      op: '!='\n                      value: 1\n                    -\n                      device: hardware\n                      op: 'contains'\n                      value: 'rev2'\n

op can be any of the following operators :

=, !=, ==, !==, <=, >=, <, >, starts, ends, contains, regex, in_array, not_starts, not_ends, not_contains, not_regex, not_in_array, exists

Example:

                    skip_values:\n                    -\n                      oid: sensorName\n                      op: 'not_in_array'\n                      value: ['sensor1', 'sensor2']\n
                    skip_values:\n                    -\n                      oid: sensorOptionalOID\n                      op: 'exists'\n                      value: false\n
        temperature:\n            data:\n                -\n                    oid: hwOpticalModuleInfoTable\n                    value: hwEntityOpticalTemperature\n                    descr: '{{ $entPhysicalName }}'\n                    index: '{{ $index }}'\n                    skip_values:\n                        -\n                            oid: hwEntityOpticalMode\n                            op: '='\n                            value: '1'\n

If you aren't able to use yaml to perform the sensor discovery, you will most likely need to use Advanced health discovery.

"},{"location":"Developing/os/Health-Information/#advanced-health-discovery","title":"Advanced health discovery","text":"

If you can't use the yaml files as above, then you will need to create the discovery code in php. If it is possible to create via yaml, php discovery will likely be rejected due to the much higher chance of later problems, so it is highly suggested to use yaml.

The directory structure for sensor information is includes/discovery/sensors/$class/$os.inc.php. The format of all the sensors follows the same code format which is to collect sensor information via SNMP and then call the discover_sensor() function; except state sensors which requires additional code. Sensor information is commonly found in an ENTITY mib supplied by device's vendor in the form of a table. Other mib tables may be used as well. Sensor information is first collected by includes/discovery/sensors/pre_cache/$os.inc.php. This program will pull in data from mib tables into a $pre_cache array that can then be used in includes/discovery/sensors/$class/$os.inc.php to extract specific values which are then passed to discover_sensor().

discover_sensor() Accepts the following arguments:

  • &$valid = This is always $valid['sensor'], do not pass any other values.
  • $class = Required. This is the sensor class from the table above (i.e humidity).
  • $device = Required. This is the $device array.
  • $oid = Required. This must be the numerical OID for where the data can be found, i.e .1.2.3.4.5.6.7.0
  • $index = Required. This must be unique for this sensor class, device and type. Typically it's the index from the table being walked, or it could be the name of the OID if it's a single value.
  • $type = Required. This should be the OS name, i.e. pulse.
  • $descr = Required. This is a descriptive value for the sensor. Some devices will provide names to use.
  • $divisor = Defaults to 1. This is used to divide the returned value.
  • $multiplier = Defaults to 1. This is used to multiply the returned value.
  • $low_limit = Defaults to null. Sets the low threshold limit for the sensor, used in alerting to report out range sensors.
  • $low_warn_limit = Defaults to null. Sets the low warning limit for the sensor, used in alerting to report near out of range sensors.
  • $warn_limit = Defaults to null. Sets the high warning limit for the sensor, used in alerting to report near out of range sensors.
  • $high_limit = Defaults to null. Sets the high limit for the sensor, used in alerting to report out range sensors.
  • $current = Defaults to null. Can be used to set the current value on discovery. Poller will update this on the next poll cycle anyway.
  • $poller_type = Defaults to snmp. Things like the unix-agent can set different values but for the most part this should be left as snmp.
  • $entPhysicalIndex = Defaults to null. Sets the entPhysicalIndex to be used to look up further hardware if available.
  • $entPhysicalIndex_measured = Defaults to null. Sets the type of entPhysicalIndex used, i.e ports.
  • $user_func = Defaults to null. You can provide a function name for the sensors value to be processed through (i.e. Convert fahrenheit to celsius use fahrenheit_to_celsius)
  • $group = Defaults to null. Groups sensors together under in the webui, displaying this text.
  • $rrd_type = Default to 'GAUGE'. Allows to change the type of the RRD file created for this sensor. More details can be found here in the RRD documentation: https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html

For the majority of devices, this is all that's required to add support for a sensor. Polling is done based on the data gathered using discover_sensor(). If custom polling is needed then the file format is similar to discovery: includes/polling/sensors/$class/$os.inc.php. Whilst it's possible to perform additional snmp queries within polling this should be avoided where possible. The value for the OID is already available as $sensor_value.

Graphing is performed automatically for sensors, no custom graphing is required or supported.

"},{"location":"Developing/os/Health-Information/#adding-a-new-sensor-class","title":"Adding a new sensor class","text":"

You will need to add code for your new sensor class in the following existing files:

  • app/Models/Sensor.php: add a free icon from Font Awesome in the $icons array.
  • doc/Developing/os/Health-Information.md: documentation for every sensor class is mandatory.
  • includes/discovery/sensors.inc.php: add the sensor class to the $run_sensors array.
  • includes/discovery/functions.inc.php: optional - if sensible low_limit and high_limit values are guessable when a SNMP-retrievable threshold is not available, add a case for the sensor class to the sensor_limit() and/or sensor_low_limit() functions.
  • LibreNMS/Util/ObjectCache.php: optional - choose menu grouping for the sensor class.
  • includes/html/pages/device/health.inc.php: add a dbFetchCell(), $datas[], and $type_text[] entry for the sensor class.
  • includes/html/pages/device/overview.inc.php: add require 'overview/sensors/$class.inc.php' in the desired order for the device overview page.
  • includes/html/pages/health.inc.php: add a $type_text[] entry for the sensor class.
  • lang/en/sensors.php: add human-readable names and units for the sensor class in English, feel free to do so for other languages as well.

Create and populate new files for the sensor class in the following places:

  • includes/discovery/sensors/$class/: create the folder where advanced php-based discovery files are stored. Not used for yaml discovery. =======
  • includes/html/pages/device/health.inc.php: add a dbFetchCell(), $datas[], and $type_text[] entry for the sensor class.
  • includes/html/pages/device/overview.inc.php: add require 'overview/sensors/$class.inc.php' in the desired order for the device overview page.
  • includes/html/pages/health.inc.php: add a $type_text[] entry for the sensor class.
  • lang/en/sensors.php: add human-readable names and units for the sensor class in English, feel free to do so for other languages as well.

Create and populate new files for the sensor class in the following places:

  • includes/discovery/sensors/$class/: create the folder where advanced php-based discovery files are stored. Not used for yaml discovery.
  • includes/html/graphs/device/$class.inc.php: define unit names used in RRDtool graphs.
  • includes/html/graphs/sensor/$class.inc.php: define various parameters for RRDtool graphs.
  • includes/html/pages/device/health/$class.inc.php
  • includes/html/pages/device/overview/sensors/$class.inc.php
  • includes/html/pages/health/$class.inc.php
"},{"location":"Developing/os/Health-Information/#advanced-health-sensor-example","title":"Advanced health sensor example","text":"

This example shows how to build sensors using the advanced method. In this example we will be collecting optical power level (dBm) from Adva FSP150CC family MetroE devices. This example will assume an understanding of SNMP and MIBs.

First we setup includes/discovery/sensors/pre_cache/adva_fsp150.inc as shown below. The first line walks the cmEntityObject table to get information about the chassis and line cards. From this information we extract the model type which will identify which tables in the CM-Facility-Mib the ports are populated in. The program then reads the appropriate table into the $pre_cache array adva_fsp150_ports. This array will have OID indexies for each port, which we will use later to identify our sensor OIDs.

$pre_cache['adva_fsp150'] = snmpwalk_cache_multi_oid($device, 'cmEntityObjects', [], 'CM-ENTITY-MIB', null, '-OQUbs');\n$neType = $pre_cache['adva_fsp150'][1]['neType'];\n\nif ($neType == 'ccxg116pro') {\n    $pre_cache['adva_fsp150_ports'] = snmpwalk_cache_multi_oid($device, 'cmEthernetTrafficPortTable', $pre_cache['adva_fsp150_ports'], 'CM-FACILITY-MIB', null, '-OQUbs');\n} else {\n    $pre_cache['adva_fsp150_ports'] = snmpwalk_cache_multi_oid($device, 'cmEthernetNetPortTable', $pre_cache['adva_fsp150_ports'], 'CM-FACILITY-MIB', null, '-OQUbs');\n    $pre_cache['adva_fsp150_ports'] = snmpwalk_cache_multi_oid($device, 'cmEthernetAccPortTable', $pre_cache['adva_fsp150_ports'], 'CM-FACILITY-MIB', null, '-OQUbs');\n}\n

Next we are going to build our sensor discovery code. These are optical readings, so the file will be created as the dBm sensor type in includes/discover/sensors/dbm/adva_fsp150.inc.php. Below is a snippet of the code:

foreach ($pre_cache['adva_fsp150_ports'] as $index => $entry) {\n    if ($entry['cmEthernetTrafficPortMediaType'] == 'fiber') {\n        //Discover received power level\n        $oidRx = '.1.3.6.1.4.1.2544.1.12.5.1.21.1.34.' . $index . '.3';\n        $oidTx = '.1.3.6.1.4.1.2544.1.12.5.1.21.1.33.' . $index . '.3';\n        $currentRx = snmp_get($device, $oidRx, '-Oqv', 'CM-PERFORMANCE-MIB', '/opt/librenms/mibs/adva');\n        $currentTx = snmp_get($device, $oidTx, '-Oqv', 'CM-PERFORMANCE-MIB', '/opt/librenms/mibs/adva');\n        if ($currentRx != 0 || $currentTx != 0) {\n            $entPhysicalIndex = $entry['cmEthernetTrafficPortIfIndex'];\n            $entPhysicalIndex_measured = 'ports';\n            $descrRx = dbFetchCell('SELECT `ifName` FROM `ports` WHERE `ifIndex`= ? AND `device_id` = ?', [$entry['cmEthernetTrafficPortIfIndex'], $device['device_id']]) . ' Rx Power';\n\n            discover_sensor(\n                $valid['sensor'],\n                'dbm',\n                $device,\n                $oidRx,\n                'cmEthernetTrafficPortStatsOPR.' . $index,\n                'adva_fsp150',\n                $descrRx,\n                $divisor,\n                $multiplier,\n                null,\n                null,\n                null,\n                null,\n                $currentRx,\n                'snmp',\n                $entPhysicalIndex,\n                $entPhysicalIndex_measured\n            );\n\n            $descrTx = dbFetchCell('SELECT `ifName` FROM `ports` WHERE `ifIndex`= ? AND `device_id` = ?', [$entry['cmEthernetTrafficPortIfIndex'], $device['device_id']]) . ' Tx Power';\n\n            discover_sensor(\n                $valid['sensor'],\n                'dbm',\n                $device,\n                $oidTx,\n                'cmEthernetTrafficPortStatsOPT.' . $index,\n                'adva_fsp150',\n                $descrTx,\n                $divisor,\n                $multiplier,\n                null,\n                null,\n                null,\n                null,\n                $currentTx,\n                'snmp',\n                $entPhysicalIndex,\n                $entPhysicalIndex_measured\n            );\n        }\n    }\n}\n

First the program will loop through each port's index value. In the case of Advas, the ports are names Ethernet 1-1-1-1, 1-1-1-2, etc, and they are indexed as oid.1.1.1.1, oid.1.1.1.2, etc in the mib.

Next the program checks which table the port exists in and that the connector type is 'fiber'. There are other port tables in the full code that were ommitted from the example for brevity. Copper media won't have optical readings, so if the media type isn't fiber we skip discovery for that port.

The next two lines build the OIDs for getting the optical receive and transmit values using the $index for the port. Using the OIDs the program gets the current receive and transmit values ($currentRx and $currentTx repectively) to verify the values are not 0. Not all SFPs collect digital optical monitoring (DOM) data, in the case of Adva the value of both transmit and recieve will be 0 if DOM is not available. While 0 is a valid value for optical power, its extremely unlikely that both will be 0 if DOM is present. If DOM is not available, then the program stops discovery for that port. Note that while this is the case with Adva, other vendors may differ in how they handle optics that do not supply DOM. Please check your vendor's mibs.

Next the program assigns the values of $entPhysicalIndex and $entPhysicalIndex_measured. In this case $entPhysicalIndex is set to the value of the cmEthernetTrafficPortIfIndex so that it is associated with port. This will also allow the sensor graphs to show up on the associated port's page in the GUI in addition to the Health page.

Following that the program uses a database call to get the description of the port which will be used as the title for the graph in the GUI.

Lastly the program calls discover_sensor() and passes the information collected in the previous steps. The null values are for low, low warning, high, and high warning values, which are not collected in the Adva's MIB.

You can manually run discovery to verify the code works by running ./discovery.php -h $device_id -m sensors. You can use -v to see what calls are being used during discovery and -d to see debug output. In the output under #### Load disco module sensors #### you can see a list of sensors types. If there is a + a sensor is added, if there is a - one was deleted, and a . means no change. If there is nothing next to the sensor type then the sensor was not discovered. There is is also information about changes to the database and RRD files at the bottom.

[librenms@nms-test ~]$ ./discovery.php -h 2 -m sensors\nLibreNMS Discovery\n164.113.194.250 2 adva_fsp150\n\n#### Load disco module core ####\n\n>> Runtime for discovery module 'core': 0.0240 seconds with 66536 bytes\n>> SNMP: [2/0.06s] MySQL: [3/0.00s] RRD: [0/0.00s]\n#### Unload disco module core ####\n\n\n#### Load disco module sensors ####\nPre-cache adva_fsp150:\n ENTITY-SENSOR: Caching OIDs: entPhysicalDescr entPhysicalName entPhySensorType entPhySensorScale entPhySensorPrecision entPhySensorValue entPhySensorOperStatus\nAirflow:\nCurrent: .\nCharge:\nDbm: Adva FSP-150 dBm..\nFanspeed:\nFrequency:\nHumidity:\nLoad:\nPower:\nPower_consumed:\nPower_factor:\nRuntime:\nSignal:\nState:\nCount:\nTemperature: ..\nTv_signal:\nBitrate:\nVoltage: .\nSnr:\nPressure:\nCooling:\nDelay:\nQuality_factor:\nChromatic_dispersion:\nBer:\nEer:\nWaterflow:\nPercent:\n\n>> Runtime for discovery module 'sensors': 3.9340 seconds with 190024 bytes\n>> SNMP: [16/3.89s] MySQL: [36/0.03s] RRD: [0/0.00s]\n#### Unload disco module sensors ####\n\nDiscovered in 5.521 seconds\n\nSNMP [18/3.96s]: Get[8/0.81s] Getnext[0/0.00s] Walk[10/3.15s]\nMySQL [41/0.03s]: Cell[10/0.01s] Row[-4/-0.00s] Rows[31/0.02s] Column[0/0.00s] Update[2/0.00s] Insert[2/0.00s] Delete[0/0.00s]\nRRD [0/0.00s]: Update[0/0.00s] Create [0/0.00s] Other[0/0.00s]\n
"},{"location":"Developing/os/Initial-Detection/","title":"Initial Detection","text":"

This document will provide the information you should need to add basic detection for a new OS.

"},{"location":"Developing/os/Initial-Detection/#discovery","title":"Discovery","text":"

OS discovery is how LibreNMS detects which OS should be used for a device. Generally detection should use sysObjectID or sysDescr, but you can also snmpget an oid and check for a value. snmpget is discouraged because it slows down all os detections, not just the added os.

To begin, create the new OS file which should be called includes/definitions/pulse.yaml. Here is a working example:

os: pulse\ntext: 'Pulse Secure'\ntype: firewall\nicon: pulse\nover:\n    - { graph: device_bits, text: 'Device Traffic' }\n    - { graph: device_processor, text: 'CPU Usage' }\n    - { graph: device_mempool, text: 'Memory Usage' }\ndiscovery:\n    - sysObjectID:\n        - .1.3.6.1.4.1.12532.\n

over: This is a list of the graphs which will be shown within the device header bar (mini graphs top right).

discovery: Here we are detecting this new OS using sysObjectID, this is the preferred method for detection. Other options are available:

  • sysObjectID The preferred operator. Checks if the sysObjectID starts with one of the strings under this item
  • sysDescr Use this in addition to sysObjectID if required. Check that the sysDescr contains one of the strings under this item
  • sysObjectID_regex Please avoid use of this. Checks if the sysObjectID matches one of the regex statements under this item
  • sysDescr_regex Please avoid use of this. Checks if the sysDescr matches one of the regex statements under this item
  • snmpget Do not use this unless none of the other methods work. Fetch an oid and compare it against a value.
    discovery:\n    -\n      snmpget:\n        - oid: <someoid>\n        - op: <[\"=\",\"!=\",\"==\",\"!==\",\"<=\",\">=\",\"<\",\">\",\"starts\",\"ends\",\"contains\",\"regex\",\"not_starts\",\"not_ends\",\"not_contains\",\"not_regex\",\"in_array\",\"not_in_array\",\"exists\"]>\n        - value: <'string' | boolean>\n
  • _except You can add this to any of the above to exclude that element. As an example:
discovery:\n    -\n      sysObjectID:\n          - .1.3.6.1.4.1.12532.\n      sysDescr_except:\n          - 'Not some pulse'\n

group: You can group certain OS' together by using group, for instance ios, nx-os, iosxr are all within a group called cisco.

bad_ifXEntry: This is a list of models for which to tell LibreNMS that the device doesn't support ifXEntry and to ignore it:

 bad_ifXEntry:\n     - cisco1941\n     - cisco886Va\n     - cisco2811\n

mib_dir: You can use this to specify an additional directory to look in for MIBs. An array is not accepted, only one directory may be specified.

mib_dir: juniper\n

poller_modules: This is a list of poller modules to either enable (1) or disable (0). Check misc/config_definitions.json to see which modules are enabled/disabled by default.

poller_modules:\n    cisco-ace-serverfarms: false\n    cisco-ace-loadbalancer: false\n

discovery_modules: This is the list of discovery modules to either enable (1) or disable (0). Check misc/config_definitions.json to see which modules are enabled/disabled by default.

discovery_modules:\n     cisco-cef: true\n     slas: true\n     cisco-mac-accounting: false\n
"},{"location":"Developing/os/Initial-Detection/#discovery-logic","title":"Discovery Logic","text":"

YAML is converted to an array in PHP. Consider the following YAML:

discovery:\n  - sysObjectID: foo\n  -\n    sysDescr: [ snafu, exodar ]\n    sysObjectID: bar\n

This is how the discovery array would look in PHP:

[\n     [\n       \"sysObjectID\" => \"foo\",\n     ],\n     [\n       \"sysDescr\" => [\n         \"snafu\",\n         \"exodar\",\n       ],\n       \"sysObjectID\" => \"bar\",\n     ]\n]\n

The logic for the discovery is as follows:

  1. One of the first level items must match
  2. ALL of the second level items must match (sysObjectID, sysDescr)
  3. One of the third level items (foo, [snafu,exodar], bar) must match

So, considering the example:

  • sysObjectID: foo, sysDescr: ANYTHING matches
  • sysObjectID: bar, sysDescr: ANYTHING does not match
  • sysObjectID: bar, sysDescr: exodar matches
  • sysObjectID: bar, sysDescr: snafu matches
"},{"location":"Developing/os/Initial-Detection/#os-discovery","title":"OS discovery","text":"

OS discovery collects additional standardized data about the OS. These are specified in the discovery yaml includes/definitions/discovery/<os>.yaml or LibreNMS/OS/<os>.php if more complex collection is required.

  • version The version of the OS running on the device.
  • hardware The hardware version for the device. For example: 'WS-C3560X-24T-S'
  • features Features for the device, for example a list of enabled software features.
  • serial The main serial number of the device.
"},{"location":"Developing/os/Initial-Detection/#yaml-based-os-discovery","title":"Yaml based OS discovery","text":"
  • sysDescr_regex apply a regex or list of regexes to the sysDescr to extract named groups, this data has the lowest precedence
  • <field> specify an oid or list of oids to attempt to pull the data from, the first non-empty response will be used
  • <field>_regex parse the value out of the returned oid data, must use a named group
  • <field>_template combine multiple oid results together to create a final string value. The result is trimmed.
  • <field>_replace An array of replacements ['search regex', 'replace'] or regex to remove
  • hardware_mib MIB used to translate sysObjectID to get hardware. hardware_regex can process the result.
modules:\n    os:\n        sysDescr_regex: '/(?<hardware>MSM\\S+) .* Serial number (?<serial>\\S+) - Firmware version (?<version>\\S+)/'\n        features: UPS-MIB::upsIdentAttachedDevices.0\n        hardware:\n            - ENTITY-MIB::entPhysicalName.1\n            - ENTITY-MIB::entPhysicalHardwareRev.1\n        hardware_template: '{{ ENTITY-MIB::entPhysicalName.1 }} {{ ENTITY-MIB::entPhysicalHardwareRev.1 }}'\n        serial: ENTITY-MIB::entPhysicalSerialNum.1\n        version: ENTITY-MIB::entPhysicalSoftwareRev.1\n        version_regex: '/V(?<version>.*)/'\n
"},{"location":"Developing/os/Initial-Detection/#php-based-os-discovery","title":"PHP based OS discovery","text":"
public function discoverOS(\\App\\Models\\Device $device): void\n{\n    $info = snmp_getnext_multi($this->getDeviceArray(), ['enclosureModel', 'enclosureSerialNum', 'entPhysicalFirmwareRev'], '-OQUs', 'NAS-MIB:ENTITY-MIB');\n    $device->version = $info['entPhysicalFirmwareRev'];\n    $device->hardware = $info['enclosureModel'];\n    $device->serial = $info['enclosureSerialNum'];\n}\n
"},{"location":"Developing/os/Initial-Detection/#mibs","title":"MIBs","text":"

If the device has MIBs available and you use it in the detection then you can add these in. It is highly recommended that you add mibs to a vendor specific directory. For instance HP mibs are in mibs/hp. Please ensure that these directories are specified in the yaml detection file, see mib_dir above.

"},{"location":"Developing/os/Initial-Detection/#icon-and-logo","title":"Icon and Logo","text":"

It is highly recommended to use SVG images where possible, these scale and provide a nice visual image for users with HiDPI screens. If you can't find SVG images then please use png.

Create an SVG image of the icon and logo. Legacy PNG bitmaps are also supported but look bad on HiDPI.

  • A vector image should not contain padding.
  • The file should not be larger than 20 Kb. Simplify paths to reduce large files.
  • Use plain SVG without gzip compression.
  • The SVG root element must not contain length and width attributes, only viewBox.
"},{"location":"Developing/os/Initial-Detection/#icon","title":"Icon","text":"
  • Save the icon SVG to html/images/os/$os.svg.
  • Icons should look good when viewed at 32x32 px.
  • Square icons are preferred to full logos with text.
  • Remove small ornaments that are almost not visible when displayed with 32px width (e.g. \u00ae or \u2122).
"},{"location":"Developing/os/Initial-Detection/#logo","title":"Logo","text":"
  • Save the logo SVG to html/images/logos/$os.svg.
  • Logos can be any dimension, but often are wide and contain the company name.
  • If a logo is not present, the icon will be used.
"},{"location":"Developing/os/Initial-Detection/#hints","title":"Hints","text":"

Hints for Inkscape:

  • You can open a PDF or EPS to extract the logo.
  • Ungroup elements to isolate the logo.
  • Use Path -> Simplify to simplify paths of large files.
  • Use File -> Document Properties\u2026 -> Resize page to content\u2026 to remove padding.
  • Use File -> Clean up document to remove unused gradients, patterns, or markers.
  • Use File -> Save As -> Plain SVG to save the final image.

By optimizing the SVG you can shrink the file size in some cases to less than 20 %. SVG Optimizer does a great job. There is also an online version.

"},{"location":"Developing/os/Initial-Detection/#the-final-check","title":"The final check","text":"

Discovery

./discovery.php -d -h HOSTNAME\n

Polling

lnms device:poll HOSTNAME\n

At this step we should see all the values retrieved in LibreNMS.

Note: If you have made a number of changes to either the OS's Discovery files, it's possible earlier edits have been cached. As such, if you do not get expected behaviour when completing the final check above, try removing the cache file first:

rm -f cache/os_defs.cache\n
"},{"location":"Developing/os/Mem-CPU-Information/","title":"Mem/CPU Information","text":"

This document will guide you through adding detection for Memory / Processor for your new device.

"},{"location":"Developing/os/Mem-CPU-Information/#memory","title":"Memory","text":"

LibreNMS will attempt to detect memory statistics using the standard HOST-RESOURCES-MIB and UCD-SNMP-MIB MIBs. To detect non-standard MIBs, they can be defined via Yaml.

"},{"location":"Developing/os/Mem-CPU-Information/#yaml","title":"YAML","text":"

In order to successfully detect memory amount and usage, two of the for keys below are required. Some OS only provide a usage percentage, which will work, but a total RAM amount will not be displayed.

  • total
  • used
  • free
  • percent_used

includes/definitions/discovery/mempools/arubaos.yaml

mempools:\n    data:\n        -\n            total: WLSX-SWITCH-MIB::sysXMemorySize\n            used: WLSX-SWITCH-MIB::sysXMemoryUsed\n            precision: 1024\n

The code can also interpret table based OIDs and supports many of the same features as Health Sensors including {{ }} parsing, skip_values, and precache.

Valid data entry keys:

  • oid oid to walk to collect processor data
  • total oid or integer total memory size in bytes (or precision)
  • used oid memory used in bytes (or precision)
  • free oid memory free in bytes (or precision)
  • percent_used oid of percentage of used memory
  • descr A visible description of the memory measurement defaults to \"Memory\"
  • warn_percent Usage percentage to used for alert purposes
  • precision precision for all byte values, typically a power of 2 (1024 for example)
  • classused to generate rrd filename, defaults to system. If system, buffers, and cached exist they will be combined to calculate available memory.
  • type used to generate rrd filename, defaults to the os name
  • index used to generate rrd filename, defaults to the oid index
  • skip_values skip values see Health Sensors for specification
  • snmp_flags additional net-snmp flags
"},{"location":"Developing/os/Mem-CPU-Information/#custom-processor-discovery-and-polling","title":"Custom Processor Discovery and Polling","text":"

If you need to implement custom discovery or polling you can implement the MempoolsDiscovery interface and the MempoolsPolling interface in the OS class. MempoolsPolling is optional, standard polling will be used based on OIDs stored in the database.

OS Class files reside under LibreNMS\\OS

<?php\n\nnamespace LibreNMS\\OS;\n\nuse LibreNMS\\Interfaces\\Discovery\\MempoolsDiscovery;\nuse LibreNMS\\Interfaces\\Polling\\MempoolsPolling;\n\nclass Example extends \\LibreNMS\\OS implements MempoolsDiscovery, MempoolsPolling\n{\n    /**\n     * Discover a Collection of Mempool models.\n     * Will be keyed by mempool_type and mempool_index\n     *\n     * @return \\Illuminate\\Support\\Collection \\App\\Models\\Mempool\n     */\n    public function discoverMempools()\n    {\n        // TODO: Implement discoverMempools() method.\n    }\n\n    /**\n     * @param \\Illuminate\\Support\\Collection $mempools \\App\\Models\\Mempool\n     * @return \\Illuminate\\Support\\Collection \\App\\Models\\Mempool\n     */\n    public function pollMempools($mempools)\n    {\n        // TODO: Implement pollMempools() method.\n    }\n}\n
"},{"location":"Developing/os/Mem-CPU-Information/#processor","title":"Processor","text":"

Detection for processors is done via a yaml file unless custom processing of data is required.

"},{"location":"Developing/os/Mem-CPU-Information/#yaml_1","title":"YAML","text":"

includes/definitions/discovery/pulse.yaml

mib: PULSESECURE-PSG-MIB\nmodules:\n    processors:\n          data:\n              -\n                  oid: iveCpuUtil\n                  num_oid: '.1.3.6.1.4.1.12532.10.{{ $index }}'\n                  type: pulse\n

Available yaml data keys:

Key Default Description oid required The string based oid to fetch data, could be a table or a single value num_oid optional The numerical oid to fetch data from when polling, usually should be appended by {{ $index }}. Computed by discovery process if not provided. value optional Oid to retrieve data from, primarily used for tables precision 1 The multiplier to multiply the data by. If this is negative, the data will be multiplied then subtracted from 100. descr Processor Description of this processor, may be an oid or plain string. Helpful values {{ $index }} and {{$count}} type Name of this sensor. This is used with the index to generate a unique id for this sensor. index {{ $index }} The index of this sensor, defaults to the index of the oid. skip_values optional Do not detect this sensor if the value matches

Accessing values within yaml:

{{ $index }} The index after the given oid {{ $count }} The count of entries (starting with 1) {{ $oid }} Any oid in the table or pre-fetched"},{"location":"Developing/os/Mem-CPU-Information/#custom-processor-discovery-and-polling_1","title":"Custom Processor Discovery and Polling","text":"

If you need to implement custom discovery or polling you can implement the ProcessorDiscovery interface and the ProcessorPolling interface in the OS class.

OS Class files reside under LibreNMS\\OS

<?php\nnamespace LibreNMS\\OS;\n\nuse LibreNMS\\Device\\Processor;\nuse LibreNMS\\Interfaces\\Discovery\\ProcessorDiscovery;\nuse LibreNMS\\Interfaces\\Polling\\ProcessorPolling;\nuse LibreNMS\\OS;\n\nclass ExampleOS extends OS implements ProcessorDiscovery, ProcessorPolling\n{\n    /**\n     * Discover processors.\n     * Returns an array of LibreNMS\\Device\\Processor objects that have been discovered\n     *\n     * @return array Processors\n     */\n    public function discoverProcessors()\n    {\n        // discovery code here\n    }\n\n    /**\n     * Poll processor data.  This can be implemented if custom polling is needed.\n     *\n     * @param array $processors Array of processor entries from the database that need to be polled\n     * @return array of polled data\n     */\n    public function pollProcessors(array $processors)\n    {\n        // polling code here\n    }\n}\n
"},{"location":"Developing/os/Settings/","title":"Optional OS Settings","text":"

This page documents settings that can be set in the os yaml files or in config.php. All settings listed here are optional. If they are not set, the global default will be used.

"},{"location":"Developing/os/Settings/#user-override-in-configphp","title":"User override in config.php","text":"

Users can override these settings in their config.php.

For example, to set an alternate icon for ios:

$config['os']['ios']['icon'] = 'fuzzybunny';\n
"},{"location":"Developing/os/Settings/#ignoring-sensors","title":"Ignoring Sensors","text":"

It is possible to filter some sensors from the configuration:

  • Filter all 'current' sensors for Operating System 'vrp'.
$config['os']['vrp']['disabled_sensors']['current'] = true;\n
  • Filter all sensors with description matching regexp '/PEM Iout/' for Operating System iosxe.
$config['os']['iosxe']['disabled_sensors_regex'][] = '/PEM Iout/';\n
  • Filter all 'power' sensors with description matching regexp '/ Power [TR]x /' for Operating System iosxr.
$config['os']['iosxr']['disabled_sensors_regex']['power'][] = '/ Power [TR]x /';\n
  • Ignore all temperature sensors
$config['disabled_sensors']['temperature'] = true;\n
  • Filter all sensors matching with description regexp '/PEM Iout/'.
$config['disabled_sensors_regex'][] = '/PEM Iout/';\n
"},{"location":"Developing/os/Settings/#ignoring-interfaces","title":"Ignoring Interfaces","text":"

See also: Global Ignoring Interfaces Config

These settings are merged with the global settings, so you can only undo global ones with good_if

empty_ifdescr: false # allow empty ifDescr\nbad_if: # ifDescr (substring, case insensitive)\n    - lp0\nbad_if_regexp: # ifDescr (regex, case insensitive)\n    - \"/^ng[0-9]+$/\"\nbad_ifname_regexp: # ifName (regex, case insensitive)\n    - \"/^xdsl_channel /\"\nbad_ifalias_regexp: # ifAlias (regex, case insensitive)\n    - \"/^vlan/\"\nbad_iftype: # ifType (substring)\n    - sonet\ngood_if: # ignore all other bad_if settings ifDescr (substring, case insensitive)\n    - virtual\nbad_ifoperstatus # IfOperStatus (substring, case insensitive)\n    - notPresent\n
"},{"location":"Developing/os/Settings/#controlling-interface-labels","title":"Controlling interface labels","text":"

By default we use ifDescr to label ports/interfaces. Setting either ifname or ifalias will override that. Only set one of these. ifAlias is user supplied. ifindex will append the ifindex to the port label.

ifname: true\nifalias: true\n\nifindex: true\n
"},{"location":"Developing/os/Settings/#poller-and-discovery-modules","title":"Poller and Discovery Modules","text":"

The various discovery and poller modules can be enabled or disabled per OS. The defaults are usually reasonable, so likely you won't want to change more than a few. These modules can be enabled or disabled per-device in the webui and per os or globally in config.php. Usually, a poller module will not work if it's corresponding discovery module is not enabled.

You should avoid setting these to false in the OS definitions unless it has a significant negative impact on polling. Setting modules in the definition reduces user control of modules.

poller_modules:\n    bgp-peers: true\ndiscovery_modules:\n    arp-table: false\n
"},{"location":"Developing/os/Settings/#snmp-settings","title":"SNMP Settings","text":""},{"location":"Developing/os/Settings/#disable-snmpbulkwalk","title":"Disable snmpbulkwalk","text":"

Some devices have buggy snmp implementations and don't respond well to the more efficient snmpbulkwalk. To disable snmpbulkwalk and only use snmpwalk for an OS set the following.

snmp_bulk: false\n

If only some specific OIDs fail with snmpbulkwalk. You can disable just those OIDs. This needs to match exactly the OID being walked by LibreNMS. MIB::oid is preferred to prevent name collisions.

oids:\n    no_bulk:\n        - UCD-SNMP-MIB::laLoadInt\n
"},{"location":"Developing/os/Settings/#limit-the-oids-per-snmpget","title":"Limit the oids per snmpget","text":"
snmp_max_oid: 8\n
"},{"location":"Developing/os/Settings/#storage-settings","title":"Storage Settings","text":"

See also: Global Storage Config

ignore_mount_array: # exact match\n    - /var/run\nignore_mount_string: # substring\n    - run\nignore_mount_regexp: # regex\n    - \"/^\\/var/\"\n
"},{"location":"Developing/os/Test-Units/","title":"Tests","text":"

Tests ensure LibreNMS works as expected, now and in the future. New OS should provide as much test data as needed and added test data for existing OS is welcome.

Saved snmp data can be found in tests/snmpsim/*.snmprec and saved database data can be found in tests/data/*.json. Please review this for any sensitive data before submitting. When replacing data, make sure it is modified in a consistent manner.

We utilise snmpsim to do unit testing. For OS discovery, we can mock snmpsim, but for other tests you will need it installed and functioning. We run snmpsim during our integration tests, but not by default when running lnms dev:check. You can install snmpsim with the command pip3 install snmpsim.

"},{"location":"Developing/os/Test-Units/#capturing-test-data","title":"Capturing test data","text":"If test data already exists

If test data already exists, but is for a different device/configuration with the same OS. Then you should use the --variant (-v) option to specify a different variant of the OS, this will be tested completely separate from other variants. If there is only one variant, please do not specify one.

"},{"location":"Developing/os/Test-Units/#1-collect-snmp-data","title":"1. Collect SNMP data","text":"

./scripts/collect-snmp-data.php is provided to make it easy to collect data for tests. Running collect-snmp-data.php with the --hostname (-h) allows you to capture all data used to discover and poll a device already added to LibreNMS. Make sure to re-run the script if you add additional support. Check the command-line help for more options.

"},{"location":"Developing/os/Test-Units/#2-save-test-data","title":"2. Save test data","text":"

After you have collected snmp data, run ./scripts/save-test-data.php with the --os (-o) option to dump the post discovery and post poll database entries to json files. This step requires snmpsim, if you are having issues, the maintainers may help you generate it from the snmprec you created in the previous step.

Generally, you will only need to collect data once. After you have the data you need in the snmprec file, you can just use save-test-data.php to update the database dump (json) after that.

"},{"location":"Developing/os/Test-Units/#running-tests","title":"Running tests","text":"

Note: To run tests, ensure you have executed ./scripts/composer_wrapper.php install from your LibreNMS root directory. This will read composer.json and install any dependencies required.

After you have saved your test data, you should run lnms dev:check verify they pass.

To run the full suite of tests enable database and snmpsim reliant tests: lnms dev:check unit --db --snmpsim

"},{"location":"Developing/os/Test-Units/#specific-os","title":"Specific OS","text":"

lnms dev:check unit -o osname

"},{"location":"Developing/os/Test-Units/#specific-module","title":"Specific Module","text":"

lnms dev:check unit -m modulename

"},{"location":"Developing/os/Test-Units/#using-snmpsim-for-testing","title":"Using snmpsim for testing","text":"

You can run snmpsim to access test data by running

lnms dev:simulate\n

You may then run snmp queries against it using the os (and variant) as the community and 127.1.6.1:1161 as the host.

snmpget -v 2c -c ios_c3560e 127.1.6.1:1161 sysDescr.0\n
"},{"location":"Developing/os/Test-Units/#snmprec-format","title":"Snmprec format","text":"

Snmprec files are simple files that store the snmp data. The data format is simple with three columns: numeric oid, type code, and data. Here is an example snippet.

1.3.6.1.2.1.1.1.0|4|Pulse Secure,LLC,MAG-2600,8.0R14 (build 41869)\n1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.12532.254.1.1\n

During testing LibreNMS will use any info in the snmprec file for snmp calls. This one provides sysDescr (.1.3.6.1.2.1.1.1.0, 4 = Octet String) and sysObjectID (.1.3.6.1.2.1.1.2.0, 6 = Object Identifier), which is the minimum that should be provided for new snmprec files.

To look up the numeric OID and type of an string OID with snmptranslate:

snmptranslate -On -Td SNMPv2-MIB::sysDescr.0\n

List of SNMP data types:

Type Value OCTET STRING 4 HEX STRING 4x Integer32 2 NULL 5 OBJECT IDENTIFIER 6 IpAddress 64 Counter32 65 Gauge32 66 TimeTicks 67 Opaque 68 Counter64 70

Hex encoded strings (4x) should be used for any strings that contain line returns.

"},{"location":"Developing/os/Test-Units/#new-discoverypoller-modules","title":"New discovery/poller modules","text":"

New discovery or poller modules should define database capture parameters in /tests/module_tables.yaml.

"},{"location":"Developing/os/Test-Units/#example-workflow","title":"Example workflow","text":"

If the base os (.snmprec) already contains test data for the module you are testing or that data conflicts with your new data, you must use a variant to store your test data (-v)."},{"location":"Developing/os/Test-Units/#add-initial-detection","title":"Add initial detection","text":"

  1. Add device to LibreNMS. It is generic and device_id = 42
  2. Run ./scripts/collect-snmp-data.php -h 42, initial snmprec will be created
  3. Add initial detection for example-os
  4. Run discovery to make sure it detects properly ./discovery.php -h 42
  5. Add any additional os items like version, hardware, features, or serial.
  6. If there is additional snmp data required, run ./scripts/collect-snmp-data.php -h 42
  7. Run ./scripts/save-test-data.php -o example-os to update the dumped database data.
  8. Review data. If you modified the snmprec or code (don't modify json manually) run ./scripts/save-test-data.php -o example-os -m os
  9. Run lnms dev:check unit --db --snmpsim
  10. If the tests succeed submit a pull request
"},{"location":"Developing/os/Test-Units/#additional-module-support-or-test-data","title":"Additional module support or test data","text":"
  1. Add code to support module or support already exists.
  2. ./scripts/collect-snmp-data.php -h 42 -m <module>, this will add more data to the snmprec file
  3. Review data. If you modified the snmprec (don't modify json manually) run ./scripts/save-test-data.php -o example-os -m <module>
  4. Run lnms dev:check unit --db --snmpsim
  5. If the tests succeed submit a pull request
"},{"location":"Developing/os/Test-Units/#json-application-test-writing-using-scriptsjson-app-toolphp","title":"JSON Application Test Writing Using ./scripts/json-app-tool.php","text":"
  1. First you will need a good example JSON output produced via SNMP extend in question.
  2. Read the help via ./scripts/json-app-tool.php -h.
  3. Generate the SNMPrec data via ./scripts/json-app-tool.php -a appName -s > ./tests/snmpsim/linux_appName-v1.snmprec. If the SNMP extend name OID different than the application name, then you will need to pass the -S flag for over riding that.
  4. Generate the test JSON data via ./scripts/json-app-tool.php -a appName -t > ./tests/data/linux_appName-v1.json.
  5. Update the generated './tests/data/linux_appName-v1.json' making sure that all the expected metrics are present. This assumes that everything under .data in the JSON will be collapsed and used.

During test runs if it does not appear to be detecting the app and it has a different app name and SNMP extend name OID, make sure that -S is set properly and that 'includes/discovery/applications.inc.php' has been updated.

"},{"location":"Developing/os/Wireless-Sensors/","title":"Wireless Sensors","text":"

This document will guide you through adding wireless sensors for your new wireless device.

Currently we have support for the following wireless metrics along with the values we expect to see the data in:

Type Measurement Interface Description ap-count % WirelessApCountDiscovery The number of APs attached to this controller capacity % WirelessCapacityDiscovery The % of operating rate vs theoretical max ccq % WirelessCcqDiscovery The Client Connection Quality channel count WirelessChannelDiscovery The channel, use of frequency is preferred cell count WirelessCellDiscovery The cell in a multicell technology clients count WirelessClientsDiscovery The number of clients connected to/managed by this device distance km WirelessDistanceDiscovery The distance of a radio link in Kilometers error-rate bps WirelessErrorRateDiscovery The rate of errored packets or bits, etc error-ratio % WirelessErrorRatioDiscovery The percent of errored packets or bits, etc errors count WirelessErrorsDiscovery The total bits of errored packets or bits, etc frequency MHz WirelessFrequencyDiscovery The frequency of the radio in MHz, channels can be converted mse dB WirelessMseDiscovery The Mean Square Error noise-floor dBm WirelessNoiseFloorDiscovery The amount of noise received by the radio power dBm WirelessPowerDiscovery The power of transmit or receive, including signal level quality % WirelessQualityDiscovery The % of quality of the link, 100% = perfect link rate bps WirelessRateDiscovery The negotiated rate of the connection (not data transfer) rssi dBm WirelessRssiDiscovery The Received Signal Strength Indicator snr dB WirelessSnrDiscovery The Signal to Noise ratio, which is signal - noise floor sinr dB WirelessSinrDiscovery The Signal-to-Interference-plus-Noise Ratio rsrq dB WirelessRsrqDiscovery The Reference Signal Received Quality rsrp dBm WirelessRsrpDiscovery The Reference Signals Received Power xpi dBm WirelessXpiDiscovery The Cross Polar Interference values ssr dB WirelessSsrDiscovery The Signal strength ratio, the ratio(or difference) of Vertical rx power to Horizontal rx power utilization % WirelessUtilizationDiscovery The % of utilization compared to the current rate

You will need to create a new OS class for your os if one doesn't exist under LibreNMS/OS. The name of this file should be the os name in camel case for example airos -> Airos, ios-wlc -> IosWlc.

Your new OS class should extend LibreNMS\\OS and implement the interfaces for the sensors your os supports.

namespace LibreNMS\\OS;\n\nuse LibreNMS\\Device\\WirelessSensor;\nuse LibreNMS\\Interfaces\\Discovery\\Sensors\\WirelessClientsDiscovery;\nuse LibreNMS\\OS;\n\nclass Airos extends OS implements WirelessClientsDiscovery\n{\n    public function discoverWirelessClients()\n    {\n        $oid = '.1.3.6.1.4.1.41112.1.4.5.1.15.1'; //UBNT-AirMAX-MIB::ubntWlStatStaCount.1\n        return array(\n            new WirelessSensor('clients', $this->getDeviceId(), $oid, 'airos', 1, 'Clients')\n        );\n    }\n}\n

All discovery interfaces will require you to return an array of WirelessSensor objects.

new WirelessSensor() Accepts the following arguments:

  • $type = Required. This is the sensor class from the table above (i.e humidity).
  • $device_id = Required. You can get this value with $this->getDeviceId()
  • $oids = Required. This must be the numerical OID for where the data can be found, i.e .1.2.3.4.5.6.7.0. If this is an array of oids, you should probably specify an $aggregator.
  • $subtype = Required. This should be the OS name, i.e airos.
  • $index = Required. This must be unique for this sensor type, device and subtype. Typically it's the index from the table being walked or it could be the name of the OID if it's a single value.
  • $description = Required. This is a descriptive value for the sensor. Shown to the user, if this is a per-ssid statistic, using SSID: $ssid here is appropriate
  • $current = Defaults to null. Can be used to set the current value on discovery. If this is null the values will be polled right away and if they do not return valid value(s), the sensor will not be discovered. Supplying a value here implies you have already verified this sensor is valid.
  • $multiplier = Defaults to 1. This is used to multiply the returned value.
  • $divisor = Defaults to 1. This is used to divided the returned value.
  • $aggregator = Defaults to sum. Valid values: sum, avg. This will combine multiple values from multiple oids into one.
  • $access_point_id = Defaults to null. If this is a wireless controller, you can link sensors to entries in the access_points table.
  • $high_limit = Defaults to null. Sets the high limit for the sensor, used in alerting to report out range sensors.
  • $low_limit = Defaults to null. Sets the low threshold limit for the sensor, used in alerting to report out range sensors.
  • $high_warn = Defaults to null. Sets the high warning limit for the sensor, used in alerting to report near out of range sensors.
  • $low_warn = Defaults to null. Sets the low warning limit for the sensor, used in alerting to report near out of range sensors.
  • $entPhysicalIndex = Defaults to null. Sets the entPhysicalIndex to be used to look up further hardware if available.
  • $entPhysicalIndexMeasured = Defaults to null. Sets the type of entPhysicalIndex used, i.e ports.

Polling is done automatically based on the discovered data. If for some reason you need to override polling, you can implement the required polling interface in LibreNMS/Interfaces/Polling/Sensors. Using the polling interfaces should be avoided if possible.

Graphing is performed automatically for wireless sensors, no custom graphing is required or supported.

"},{"location":"Extensions/Agent-Setup/","title":"Check_MK Setup","text":"

The agent can be used to gather data from remote systems you can use LibreNMS in combination with check_mk (found here). The agent can be extended to include data about applications on the remote system.

"},{"location":"Extensions/Agent-Setup/#installation","title":"Installation","text":""},{"location":"Extensions/Agent-Setup/#linux-bsd","title":"Linux / BSD","text":"

Make sure that systemd or xinetd is installed on the host you want to run the agent on.

The agent uses TCP-Port 6556, please allow access from the LibreNMS host and poller nodes if you're using the Distributed Polling setup.

On each of the hosts you would like to use the agent on, you need to do the following:

1: Clone the librenms-agent repository:

cd /opt/\ngit clone https://github.com/librenms/librenms-agent.git\ncd librenms-agent\n

2: Copy the relevant check_mk_agent to /usr/bin:

linux freebsd cp check_mk_agent /usr/bin/check_mk_agent cp check_mk_agent_freebsd /usr/bin/check_mk_agent
chmod +x /usr/bin/check_mk_agent\n

3: Copy the service file(s) into place.

xinetd systemd cp check_mk_xinetd /etc/xinetd.d/check_mk cp check_mk@.service check_mk.socket /etc/systemd/system

4: Create the relevant directories.

mkdir -p /usr/lib/check_mk_agent/plugins /usr/lib/check_mk_agent/local\n

5: Copy each of the scripts from agent-local/ into /usr/lib/check_mk_agent/local that you require to be graphed. You can find detail setup instructions for specific applications above.

6: Make each one executable that you want to use with chmod +x /usr/lib/check_mk_agent/local/$script

7: Enable the check_mk service

xinetd systemd /etc/init.d/xinetd restart systemctl enable check_mk.socket && systemctl start check_mk.socket

8: Login to the LibreNMS web interface and edit the device you want to monitor. Under the modules section, ensure that unix-agent is enabled.

9: Then under Applications, enable the apps that you plan to monitor.

10: Wait for around 10 minutes and you should start seeing data in your graphs under Apps for the device.

"},{"location":"Extensions/Agent-Setup/#restrict-the-devices-on-which-the-agent-listens-linux-systemd","title":"Restrict the devices on which the agent listens: Linux systemd","text":"

If you want to restrict which network adapter the agent listens on, do the following:

1: Edit /etc/systemd/system/check_mk.socket

2: Under the [Socket] section, add a new line BindToDevice= and the name of your network adapter.

3: If the script has already been enabled in systemd, you may need to issue a systemctl daemon-reload and then systemctl restart check_mk.socket

"},{"location":"Extensions/Agent-Setup/#windows","title":"Windows","text":"
  1. Grab version 1.2.6b5 of the check_mk agent from the check_mk github repo (exe/msi or compile it yourself depending on your usage): https://github.com/tribe29/checkmk/tree/v1.2.6b5/agents/windows
  2. Run the msi / exe
  3. Make sure your LibreNMS instance can reach TCP port 6556 on your target.
"},{"location":"Extensions/Applications/","title":"Applications","text":"

You can use Application support to graph performance statistics of many applications.

Different applications support a variety of ways to collect data:

  1. By direct connection to the application
  2. snmpd extend
  3. The agent.

The monitoring of applications could be added before or after the hosts have been added to LibreNMS.

If multiple methods of collection are listed you only need to enable one.

"},{"location":"Extensions/Applications/#snmp-extend","title":"SNMP Extend","text":"

When using the snmp extend method, the application discovery module will pick up which applications you have set up for monitoring automatically, even if the device is already in LibreNMS. The application discovery module is enabled by default for most *nix operating systems, but in some cases you will need to manually enable the application discovery module.

"},{"location":"Extensions/Applications/#sudo","title":"SUDO","text":"

One major thing to keep in mind when using SNMP extend is these run as the snmpd user that can be an unprivileged user. In these situations you need to use sudo.

To test if you need sudo, first check the user snmpd is running as. Then test if you can run the extend script as that user without issue. For example if snmpd is running as 'Debian-snmp' and we want to run the extend for proxmox, we check that the following run without error:

sudo -u Debian-snmp /usr/local/bin/proxmox\n

If it doesn't work, then you will need to use sudo with the extend command. For the example above, that would mean adding the line below to the sudoers file:

Debian-snmp ALL = NOPASSWD: /usr/local/bin/proxmox\n

Finally we would need to add sudo to the extend command, which would look like that for proxmox:

extend proxmox /usr/bin/sudo /usr/local/bin/proxmox\n
"},{"location":"Extensions/Applications/#json-return-optimization-using-librenms_return_optimizer","title":"JSON Return Optimization Using librenms_return_optimizer","text":"

While the json_app_get does allow for more complex and larger data to be easily returned by a extend and the data to then be worked with, this can also sometimes result in large returns that occasionally don't play nice with SNMP on some networks.

librenms_return_optimizer fixes this via taking the extend output piped to it, gzipping it, and then converting it to base64. The later is needed as net-snmp does not play that nice with binary data, converting most of the non-printable characters to .. This does add a bit of additional overhead to the gzipped data, but still tends to be result in a return that is usually a third of the size for JSONs items.

The change required is fairly simply. So for the portactivity example below...

extend portactivity /etc/snmp/extends/portactivity smtps,http,imap,imaps,postgresql,https,ldap,ldaps,nfsd,syslog-conn,ssh,matrix,gitea\n

Would become this...

extend portactivity /usr/local/bin/lnms_return_optimizer -- /etc/snmp/extends/portactivity smtps,http,imap,imaps,postgresql,https,ldap,ldaps,nfsd,syslog-conn,ssh,matrix,gitea\n

The requirements for this are Perl, MIME::Base64, and Gzip::Faster.

Installing on FreeBSD...

pkg install p5-MIME-Base64 p5-Gzip-Faster wget\nwget https://raw.githubusercontent.com/librenms/librenms-agent/master/utils/librenms_return_optimizer -O /usr/local/bin/librenms_return_optimizer\nchmod +x /usr/local/bin/librenms_return_optimizer\n

Installing on Debian...

apt-get install zlib1g-dev cpanminus wget\ncpanm Gzip::Faster\ncpanm MIME::Base64\nwget https://raw.githubusercontent.com/librenms/librenms-agent/master/utils/librenms_return_optimizer -O /usr/local/bin/librenms_return_optimizer\nchmod +x /usr/local/bin/librenms_return_optimizer\n

Currently supported applications as are below.

  • backupninja
  • certificate
  • chronyd
  • dhcp-stats
  • docker
  • fail2ban
  • fbsd-nfs-client
  • fbsd-nfs-server
  • gpsd
  • mailcow-postfix
  • mdadm
  • ntp-client
  • ntp-server
  • portactivity
  • powerdns
  • powermon
  • puppet-agent
  • pureftpd
  • redis
  • seafile
  • supervisord
  • ups-apcups
  • zfs

The following apps have extends that have native support for this, if congiured to do so.

  • suricata
"},{"location":"Extensions/Applications/#enable-the-application-discovery-module","title":"Enable the application discovery module","text":"
  1. Edit the device for which you want to add this support
  2. Click on the Modules tab and enable the applications module.
  3. This will be automatically saved, and you should get a green confirmation pop-up message.

After you have enabled the application module, it would be wise to then also enable which applications you want to monitor, in the rare case where LibreNMS does not automatically detect it.

Note: Only do this if an application was not auto-discovered by LibreNMS during discovery and polling.

"},{"location":"Extensions/Applications/#enable-the-applications-to-be-discovered","title":"Enable the application(s) to be discovered","text":"
  1. Go to the device you have just enabled the application module for.
  2. Click on the Applications tab and select the applications you want to monitor.
  3. This will also be automatically saved, and you should get a green confirmation pop-up message.
"},{"location":"Extensions/Applications/#agent","title":"Agent","text":"

The unix-agent does not have a discovery module, only a poller module. That poller module is always disabled by default. It needs to be manually enabled if using the agent. Some applications will be automatically enabled by the unix-agent poller module. It is better to ensure that your application is enabled for monitoring. You can check by following the steps under the SNMP Extend heading.

"},{"location":"Extensions/Applications/#apache","title":"Apache","text":"

Either use SNMP extend or use the agent.

Note that you need to install and configure the Apache mod_status module before trying the script.

"},{"location":"Extensions/Applications/#snmp-extend_1","title":"SNMP Extend","text":"
  1. Download the script onto the desired host (the host must be added to LibreNMS devices)

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/apache-stats.py -O /etc/snmp/apache-stats.py\n

  2. Make the script executable

    chmod +x /etc/snmp/apache-stats.py\n

  3. Create the cache directory, '/var/cache/librenms/' and make sure that it is owned by the user running the SNMP daemon.

    mkdir -p /var/cache/librenms/\n

  4. Verify it is working by running /etc/snmp/apache-stats.py Package urllib3 for python3 needs to be installed. In Debian-based systems for example you can achieve this by issuing:

    apt-get install python3-urllib3\n

  5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend apache /etc/snmp/apache-stats.py\n

  6. Restart snmpd on your host

  7. Test by running

    snmpwalk <various options depending on your setup> localhost NET-SNMP-EXTEND-MIB::nsExtendOutput2Table\n

"},{"location":"Extensions/Applications/#agent_1","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the apache script to /usr/lib/check_mk_agent/local/

  1. Verify it is working by running /usr/lib/check_mk_agent/local/apache (If you get error like \"Can't locate LWP/Simple.pm\". libwww-perl needs to be installed: apt-get install libwww-perl)

  2. Create the cache directory, '/var/cache/librenms/' and make sure that it is owned by the user running the SNMP daemon.

    mkdir -p /var/cache/librenms/\n

  3. On the device page in Librenms, edit your host and check the Apache under the Applications tab.

"},{"location":"Extensions/Applications/#asterisk","title":"Asterisk","text":"

A small shell script that reports various Asterisk call status.

"},{"location":"Extensions/Applications/#snmp-extend_2","title":"SNMP Extend","text":"
  1. Download the asterisk script to /etc/snmp/ on your asterisk server.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/asterisk -O /etc/snmp/asterisk\n

  2. Make the script executable

    chmod +x /etc/snmp/asterisk\n

  3. Configure ASCLI in the script.

  4. Verify it is working by running /etc/snmp/asterisk

  5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend asterisk /etc/snmp/asterisk\n

  6. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#backupninja","title":"backupninja","text":"

A small shell script that reports status of last backupninja backup.

"},{"location":"Extensions/Applications/#snmp-extend_3","title":"SNMP Extend","text":"
  1. Download the backupninja script to /etc/snmp/backupninja.py on your backuped server.
    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/backupninja.py -O /etc/snmp/backupninja.py`\n
  2. Make the script executable:

    chmod +x /etc/snmp/backupninja.py\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend backupninja /etc/snmp/backupninja.py\n

  4. Restart snmpd on your host

"},{"location":"Extensions/Applications/#bind9-aka-named","title":"BIND9 aka named","text":"
  1. Create stats file with appropriate permissions:

    touch /var/cache/bind/stats\nchown bind:bind /var/cache/bind/stats\n
    Change user:group to the user and group that's running bind/named.

  2. Bind/named configuration:

    options {\n    ...\n    statistics-file \"/var/cache/bind/stats\";\n    zone-statistics yes;\n    ...\n};\n

  3. Restart your bind9/named after changing the configuration.

  4. Verify that everything works by executing rndc stats && cat /var/cache/bind/stats. In case you get a Permission Denied error, make sure you changed the ownership correctly.

  5. Also be aware that this file is appended to each time rndc stats is called. Given this it is suggested you setup file rotation for it. Alternatively you can also set zero_stats to 1 in the config.

  6. The script for this also requires the Perl module File::ReadBackwards.

    FreeBSD       => p5-File-ReadBackwards\nCentOS/RedHat => perl-File-ReadBackwards\nDebian/Ubuntu => libfile-readbackwards-perl\n

If it is not available, it can be installed by cpan -i File::ReadBackwards.

  1. You may possibly need to configure the agent/extend script as well.

The config file's path defaults to the same path as the script, but with .config appended. So if the script is located at /etc/snmp/bind, the config file will be /etc/snmp/bind.config. Alternatively you can also specify a config via -c $file.

Anything starting with a # is comment. The format for variables are $variable=$value. Empty lines are ignored. Spaces and tabs at either the start or end of a line are ignored.

Content of an example /etc/snmp/bind.config . Please edit with your own settings.

rndc = The path to rndc. Default: /usr/bin/env rndc\ncall_rndc = A 0/1 boolean on whether or not to call rndc stats.\n    Suggest to set to 0 if using netdata. Default: 1\nstats_file = The path to the named stats file. Default: /var/cache/bind/stats\nagent = A 0/1 boolean for if this is being used as a LibreNMS\n    agent or not. Default: 0\nzero_stats = A 0/1 boolean for if the stats file should be zeroed\n    first. Default: 0 (1 if guessed)\n

If you want to guess at the configuration, call the script with -g and it will print out what it thinks it should be.

"},{"location":"Extensions/Applications/#snmp-extend_4","title":"SNMP Extend","text":"
  1. Copy the bind shell script, to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/bind -O /etc/snmp/bind\n

  2. Make the script executable

    chmod +x /etc/snmp/bind\n

  3. Edit your snmpd.conf file and add:

    extend bind /etc/snmp/bind\n

  4. Restart snmpd on the host in question.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_2","title":"Agent","text":"
  1. Install the agent on this device if it isn't already and copy the script to /usr/lib/check_mk_agent/local/bind via wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/bind -O /usr/lib/check_mk_agent/local/bind

  2. Make the script executable

    chmod +x /usr/lib/check_mk_agent/local/bind\n

  3. Set the variable 'agent' to '1' in the config.

"},{"location":"Extensions/Applications/#bird2","title":"BIRD2","text":"

The BIRD Internet Routing Daemon (BGP)

Due to the lack of SNMP support in the BIRD daemon, this application extracts all configured BGP protocols and parses it into LibreNMS. This application supports both IPv4 and IPv6 Peer processing.

"},{"location":"Extensions/Applications/#snmp-extend_5","title":"SNMP Extend","text":"
  1. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:
extend bird2 '/usr/bin/sudo /usr/sbin/birdc -r show protocols all'\n
  1. Edit your sudo users (usually visudo) and add at the bottom:
Debian-snmp ALL=(ALL) NOPASSWD: /usr/sbin/birdc\n

If your snmp daemon is running on a user that isnt Debian-snmp make sure that user has the correct permission to execute birdc

  1. Verify the time format for bird2 is defined. Otherwise iso short ms (hh:mm:ss) is the default value that will be used. Which is not compatible with the datetime parsing logic used to parse the output from the bird show command. timeformat protocol is the one important to be defibned for the bird2 app parsing logic to work.

Example starting point using Bird2 shorthand iso long (YYYY-MM-DD hh:mm:ss):

timeformat base iso long;\ntimeformat log iso long;\ntimeformat protocol iso long;\ntimeformat route iso long;\n

Timezone can be manually specified, example \"%F %T %z\" (YYYY-MM-DD hh:mm:ss +11:45). See the Bird 2 docs for more information

  1. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#certificate","title":"Certificate","text":"

A small python3 script that checks age and remaining validity of certificates

This script needs following packages on Debian/Ubuntu Systems:

  • python3
  • python3-openssl

Content of an example /etc/snmp/certificate.json . Please edit with your own settings.

{\"domains\": [\n    {\"fqdn\": \"www.mydomain.com\"},\n    {\"fqdn\": \"some.otherdomain.org\",\n     \"port\": 8443},\n    {\"fqdn\": \"personal.domain.net\"},\n    {\"fqdn\": \"selfsignedcert_host.domain.com\",\n     \"cert_location\": \"/etc/pki/tls/certs/localhost.pem\"}\n]\n}\n
a. (Required): Key 'domains' contains a list of domains to check. b. (Optional): You can define a port. By default it checks on port 443. c. (Optional): You may define a certificate location for self-signed certificates.

"},{"location":"Extensions/Applications/#snmp-extend_6","title":"SNMP Extend","text":"
  1. Copy the shell script to the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/certificate.py -O /etc/snmp/certificate.py\n

  2. Make the script executable

    chmod +x /etc/snmp/certificate.py\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend certificate /etc/snmp/certificate.py\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#borgbackup","title":"BorgBackup","text":""},{"location":"Extensions/Applications/#snmp-extend_7","title":"SNMP Extend","text":"
  1. Copy the shell script to the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/borgbackup -O /etc/snmp/borgbackup\n

  2. Make the script executable

    chmod +x /etc/snmp/borgbackup\n

  3. Install depends.

    # FreeBSD\npkg p5-Config-Tiny p5-JSON p5-File-Slurp p5-MIME-Base64 p5-String-ShellQuote\n# Debian\napt-get install libconfig-tiny-perl libjson-perl libfile-slurp-perl libmime-base64-perl libstring-shellquote-perl\n# generic cpanm\ncpanm Config::Tiny File::Slurp JSON MIME::Base64 String::ShellQuote\n

  4. Set it up in cron.

    */5 * * * /etc/snmp/borgbackup 2> /dev/null > /dev/null\n

  5. Configure it. See further down below or /etc/snmp/borgbackup --help.

  6. Add the following to the SNMPD config.

    extend borgbackup /bin/cat /var/cache/borgbackup_extend/extend_return\n

  7. Restart SNMPD and wait for the device to rediscover or tell it to manually.

"},{"location":"Extensions/Applications/#config","title":"Config","text":"

The config file is a ini file and handled by Config::Tiny.

- mode :: single or multi, for if this is a single repo or for\n        multiple repos.\n    - Default :: single\n\n- repo :: Directory for the borg backup repo.\n    - Default :: undef\n\n- passphrase :: Passphrase for the borg backup repo.\n    - Default :: undef\n\n- passcommand :: Passcommand for the borg backup repo.\n    - Default :: undef\n

For single repos all those variables are in the root section of the config, so lets the repo is at '/backup/borg' with a passphrase of '1234abc'.

repo=/backup/borg\nrepo=1234abc\n

For multi, each section outside of the root represents a repo. So if there is '/backup/borg1' with a passphrase of 'foobar' and '/backup/derp' with a passcommand of 'pass show backup' it would be like below.

mode=multi\n\n[borg1]\nrepo=/backup/borg1\npassphrase=foobar\n\n[derp]\nrepo=/backup/derp\npasscommand=pass show backup\n

If 'passphrase' and 'passcommand' are both specified, then passcommand is used.

"},{"location":"Extensions/Applications/#metrics","title":"Metrics","text":"

The metrics are all from .data.totals in the extend return.

Value Type Description errored repos Total number of repos that info could not be fetched for. locked repos Total number of locked repos locked_for seconds Longest time any repo has been locked. time_since_last_modified seconds Largest time - mtime for the repo nonce total_chunks chunks Total number of chunks total_csize bytes Total compressed size of all archives in all repos. total_size byes Total uncompressed size of all archives in all repos. total_unique_chunks chunks Total number of unique chuckes in all repos. unique_csize bytes Total deduplicated size of all archives in all repos. unique_size chunks Total number of chunks in all repos."},{"location":"Extensions/Applications/#capev2","title":"CAPEv2","text":"
  1. Copy the shell script to the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/cape -O /etc/snmp/cape\n

  2. Make the script executable

    chmod +x /etc/snmp/cape\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend cape /etc/snmp/cape\n

  4. Install the required packages.

    apt-get install libfile-readbackwards-perl libjson-perl libconfig-tiny-perl libdbi-perl libfile-slurp-perl libstatistics-lite-perl\n

  5. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#chip","title":"C.H.I.P","text":"

C.H.I.P. is a $9 R8 based tiny computer ideal for small projects. Further details: https://getchip.com/pages/chip

  1. Copy the shell script to the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/chip.sh -O /etc/snmp/power-stat.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/power-stat.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend power-stat /etc/snmp/power-stat.sh\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#docker-stats","title":"Docker Stats","text":"

It gathers metrics about the docker containers, including: - cpu percentage - memory usage - container size - uptime - Totals per status

This script requires python3 and the pip module python-dateutil

"},{"location":"Extensions/Applications/#snmp-extend_8","title":"SNMP Extend","text":"
  1. Install pip module

    pip3 install python-dateutil\n

  2. Copy the shell script to the desired host. By default, it will only show the status for containers that are running. To include all containers modify the constant in the script at the top of the file and change it to ONLY_RUNNING_CONTAINERS = False

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/docker-stats.py -O /etc/snmp/docker-stats.py\n

  3. Make the script executable

    chmod +x /etc/snmp/docker-stats.py\n

  4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend docker /etc/snmp/docker-stats.py\n

  5. If your run Debian, you need to add the Debian-snmp user to the docker group

    usermod -a -G docker Debian-snmp\n

  6. Restart snmpd on your host

    systemctl restart snmpd\n

"},{"location":"Extensions/Applications/#entropy","title":"Entropy","text":"

A small shell script that checks your system's available random entropy.

"},{"location":"Extensions/Applications/#snmp-extend_9","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/entropy.sh -O /etc/snmp/entropy.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/entropy.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend entropy /etc/snmp/entropy.sh\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#exim-stats","title":"EXIM Stats","text":"

SNMP extend script to get your exim stats data into your host.

"},{"location":"Extensions/Applications/#snmp-extend_10","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/exim-stats.sh -O /etc/snmp/exim-stats.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/exim-stats.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend exim-stats /etc/snmp/exim-stats.sh\n

  4. If you are using sudo edit your sudo users (usually visudo) and add at the bottom:

    snmp ALL=(ALL) NOPASSWD: /etc/snmp/exim-stats.sh, /usr/bin/exim*\n

  5. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#fail2ban","title":"Fail2ban","text":""},{"location":"Extensions/Applications/#snmp-extend_11","title":"SNMP Extend","text":"
  1. Copy the shell script, fail2ban, to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/fail2ban -O /etc/snmp/fail2ban\n

  2. Make the script executable

    chmod +x /etc/snmp/fail2ban\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend fail2ban /etc/snmp/fail2ban\n

    1. If you want to use the cache, it is as below, by using the -c switch.

      extend fail2ban /etc/snmp/fail2ban -c\n

    2. If you want to use the cache and update it if needed, this can by using the -c and -U switches.

      extend fail2ban /etc/snmp/fail2ban -c -U\n

    3. If you need to specify a custom location for the fail2ban-client, that can be done via the -f switch.

      extend fail2ban /etc/snmp/fail2ban -f /foo/bin/fail2ban-client\n
      If not specified, \"/usr/bin/env fail2ban-client\" is used.

  4. Restart snmpd on your host

  5. If you wish to use caching, add the following to /etc/crontab and restart cron.

    */3    *    *    *    *    root    /etc/snmp/fail2ban -u\n

  6. Restart or reload cron on your system.

If you have more than a few jails configured, you may need to use caching as each jail needs to be polled and fail2ban-client can't do so in a timely manner for than a few. This can result in failure of other SNMP information being polled.

For additional details of the switches, please see the POD in the script it self at the top.

"},{"location":"Extensions/Applications/#freebsd-nfs-client","title":"FreeBSD NFS Client","text":"

Superseded by the generalized NFS support.

"},{"location":"Extensions/Applications/#snmp-extend_12","title":"SNMP Extend","text":"
  1. Copy the shell script, fbsdnfsserver, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/fbsdnfsclient -O /etc/snmp/fbsdnfsclient\n

  2. Make the script executable

    chmod +x /etc/snmp/fbsdnfsclient\n

  3. Edit your snmpd.conf file and add:

    extend fbsdnfsclient /etc/snmp/fbsdnfsclient\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#freebsd-nfs-server","title":"FreeBSD NFS Server","text":"

Superseded by the generalized NFS support.

"},{"location":"Extensions/Applications/#snmp-extend_13","title":"SNMP Extend","text":"
  1. Copy the shell script, fbsdnfsserver, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/fbsdnfsserver -O /etc/snmp/fbsdnfsserver\n

  2. Make the script executable

    chmod +x /etc/snmp/fbsdnfsserver\n

  3. Edit your snmpd.conf file and add:

    extend fbsdnfsserver /etc/snmp/fbsdnfsserver\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#freeradius","title":"FreeRADIUS","text":"

The FreeRADIUS application extension requires that status_server be enabled in your FreeRADIUS config. For more information see: https://wiki.freeradius.org/config/Status

You should note that status requests increment the FreeRADIUS request stats. So LibreNMS polls will ultimately be reflected in your stats/charts.

  1. Go to your FreeRADIUS configuration directory (usually /etc/raddb or /etc/freeradius).

  2. cd sites-enabled

  3. ln -s ../sites-available/status status

  4. Restart FreeRADIUS.

  5. You should be able to test with the radclient as follows...

    echo \"Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type = 31, Response-Packet-Type = Access-Accept\" | \\\nradclient -x localhost:18121 status adminsecret\n

Note that adminsecret is the default secret key in status_server. Change if you've modified this.

"},{"location":"Extensions/Applications/#snmp-extend_14","title":"SNMP Extend","text":"
  1. Copy the freeradius shell script, to the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/freeradius.sh -O /etc/snmp/freeradius.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/freeradius.sh\n

  3. If you've made any changes to the FreeRADIUS status_server config (secret key, port, etc.) edit freeradius.sh and adjust the config variable accordingly.

  4. Edit your snmpd.conf file and add:

    extend freeradius /etc/snmp/freeradius.sh\n

  5. Restart snmpd on the host in question.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_3","title":"Agent","text":"
  1. Install the script to your agent

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/freeradius.sh -O /usr/lib/check_mk_agent/local/freeradius.sh`\n

  2. Make the script executable

    chmod +x /usr/lib/check_mk_agent/local/freeradius.sh\n

  3. If you've made any changes to the FreeRADIUS status_server config (secret key, port, etc.) edit freeradius.sh and adjust the config variable accordingly.

  4. Edit the freeradius.sh script and set the variable 'AGENT' to '1' in the config.

"},{"location":"Extensions/Applications/#freeswitch","title":"Freeswitch","text":"

A small shell script that reports various Freeswitch call status.

"},{"location":"Extensions/Applications/#agent_4","title":"Agent","text":"
  1. Install the agent on this device if it isn't already and copy the freeswitch script to /usr/lib/check_mk_agent/local/

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/freeswitch -O /usr/lib/check_mk_agent/local/freeswitch`\n

  2. Make the script executable

    chmod +x /usr/lib/check_mk_agent/local/freeswitch\n

  3. Configure FSCLI in the script. You may also have to create an /etc/fs_cli.conf file if your fs_cli command requires authentication.

  4. Verify it is working by running /usr/lib/check_mk_agent/local/freeswitch

"},{"location":"Extensions/Applications/#snmp-extend_15","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/agent-local/freeswitch -O /etc/snmp/freeswitch\n

  2. Make the script executable

    chmod +x /etc/snmp/freeswitch\n

  3. Configure FSCLI in the script. You may also have to create an /etc/fs_cli.conf file if your fs_cli command requires authentication.

  4. Verify it is working by running /etc/snmp/freeswitch

  5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend freeswitch /etc/snmp/freeswitch\n

  6. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#gpsd","title":"GPSD","text":""},{"location":"Extensions/Applications/#snmp-extend_16","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/gpsd -O /etc/snmp/gpsd\n

  2. Make the script executable

    chmod +x /etc/snmp/gpsd\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend gpsd /etc/snmp/gpsd\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading at the top of the page.

"},{"location":"Extensions/Applications/#agent_5","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the gpsd script to /usr/lib/check_mk_agent/local/

You may need to configure $server or $port.

Verify it is working by running /usr/lib/check_mk_agent/local/gpsd

"},{"location":"Extensions/Applications/#hv-monitor","title":"HV Monitor","text":"

HV Monitor provides a generic way to monitor hypervisors. Currently CBSD+bhyve on FreeBSD and Libvirt+QEMU on Linux are support.

For more information see HV::Monitor on Github or MetaCPAN.

"},{"location":"Extensions/Applications/#snmp-extend_17","title":"SNMP Extend","text":"
  1. Install the SNMP Extend.

For Debian based systems this is as below.

apt-get install zlib1g-dev cpanminus libjson-perl\ncpanm HV::Monitor\n

And on FreeBSD as below.

pkg install p5-App-cpanminus p5-JSON p5-MIME-Base64 p5-Gzip-Faster\ncpanm HV::Monitor\n
  1. Set it up to be be ran by cron by root. Yes, you can directly call this script from SNMPD, but be aware, especially with Libvirt, there is a very real possibility of the snmpget timing out, especially if a VM is spinning up/down as virsh domstats can block for a few seconds or so then.
*/5 * * * * /usr/local/bin/hv_monitor > /var/cache/hv_monitor.json -c 2> /dev/null\n
  1. Setup snmpd.conf as below.
extend hv-monitor /bin/cat\n/var/cache/hv_monitor.json\n
  1. Restart SNMPD.

  2. Either wait for it to be re-discovered or manually enable it.

"},{"location":"Extensions/Applications/#icecast","title":"Icecast","text":"

Shell script that reports load average/memory/open-files stats of Icecast

"},{"location":"Extensions/Applications/#snmp-extend_18","title":"SNMP Extend","text":"
  1. Copy the shell script, icecast-stats.sh, to the desired host (the host must be added to LibreNMS devices)

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/icecast-stats.sh -O /etc/snmp/icecast-stats.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/icecast-stats.sh\n

  3. Verify it is working by running /etc/snmp/icecast-stats.sh

  4. Edit your snmpd.conf file (usually /etc/snmp/icecast-stats.sh) and add:

    extend icecast /etc/snmp/icecast-stats.sh\n

"},{"location":"Extensions/Applications/#isc-dhcp-stats","title":"ISC DHCP Stats","text":"

A small python3 script that reports current DHCP leases stats and pool usage of ISC DHCP Server.

Also you have to install the dhcpd-pools and the required Perl modules. Under Ubuntu/Debian just run apt install cpanminus ; cpanm Net::ISC::DHCPd::Leases Mime::Base64 File::Slurp or under FreeBSD pkg install p5-JSON p5-MIME-Base64 p5-App-cpanminus p5-File-Slurp ; cpanm Net::ISC::DHCPd::Leases.

"},{"location":"Extensions/Applications/#snmp-extend_19","title":"SNMP Extend","text":"
  1. Copy the shell script to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/dhcp -O /etc/snmp/dhcp\n

  2. Make the script executable

    chmod +x /etc/snmp/dhcp\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    # without using cron\nextend dhcpstats /etc/snmp/dhcp -Z\n# using cron\nextend dhcpstats /bin/cat /var/cache/dhcp_extend\n

  4. If on a slow system running it via cron may be needed.

    */5 * * * * /etc/snmp/dhcp -Z -w /var/cache/dhcp_extend\n

The following options are also supported.

Option Description -c $file Path to dhcpd.conf. -l $file Path to lease file. -Z Enable GZip+Base64 compression. -d Do not de-dup. -w $file File to write it out to.
  1. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#logsize","title":"Logsize","text":""},{"location":"Extensions/Applications/#snmp-extend_20","title":"SNMP Extend","text":"
  1. Download the script and make it executable.
wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/logsize -O /etc/snmp/logsize\nchmod +x /etc/snmp/logsize\n
  1. Install the requirements.
# FreeBSD\npkg install p5-File-Find-Rule p5-JSON p5-TOML p5-Time-Piece p5-MIME-Base64 p5-File-Slurp p5-Statistics-Lite\n# Debian\napt-get install cpanminus\ncpanm File::Find::Rule JSON TOML Time::Piece MIME::Base64 File::Slurp Statistics::Lite\n
  1. Configure the config at /usr/local/etc/logsize.conf. You can find the documentation for the config file in the extend. Below is a small example.
# monitor log sizes of logs directly udner /var/log\n[sets.var_log]\ndir=\"/var/log/\"\n\n# monitor remote logs from network devices\n[sets.remote_network]\ndir=\"/var/log/remote/network/\"\n\n# monitor remote logs from windows sources\n[sets.remote_windows]\ndir=\"/var/log/remote/windows/\"\n\n# monitor suricata flows logs sizes\n[sets.suricata_flows]\ndir=\"/var/log/suricata/flows/current\"\n
  1. If the directories all readable via SNMPD, this script can be ran via snmpd. Otherwise it needs setup in cron. Similarly is processing a large number of files, it may also need setup in cron if it takes the script awhile to run.
*/5 * * * * /etc/snmp/logsize -b 2> /dev/null > /dev/null\n
  1. Make sure that /var/cache/logsize_extend exists and is writable by the user running the extend.
mkdir -p /var/cache/logsize_extend\n
  1. Configure it in the SNMPD config.
# if not using cron\nextend logsize  /etc/snmp/logsize -b\n# if using cron\nextend logsize /bin/cat /var/cache/logsize_extend/extend_return\n
"},{"location":"Extensions/Applications/#linux_config_files","title":"linux_config_files","text":"

linux_config_files is an application intended to monitor a Linux distribution's configuration files via that distribution's configuration management tool/system. At this time, ONLY RPM-based (Fedora/RHEL) SYSTEMS ARE SUPPORTED utilizing the rpmconf tool. The linux_config_files application collects and graphs the total count of configuration files that are out of sync and graphs that number.

Fedora/RHEL: Rpmconf is a utility that analyzes rpm configuration files using the RPM Package Manager. Rpmconf reports when a new configuration file standard has been issued for an upgraded/downgraded piece of software. Typically, rpmconf is used to provide a diff of the current configuration file versus the new, standard configuration file. The administrator can then choose to install the new configuration file or keep the old one.

"},{"location":"Extensions/Applications/#snmp-extend_21","title":"SNMP Extend","text":"
  1. Copy the python script, linux_config_files.py, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/linux_config_files.py -O /etc/snmp/linux_config_files.py\n

  2. Make the script executable

    chmod +x /etc/snmp/linux_config_files.py\n

  3. Edit your snmpd.conf file and add:

    extend linux_config_files /etc/snmp/linux_config_files.py\n

  4. (Optional on an RPM-based distribution) Create a /etc/snmp/linux_config_files.json file and specify the following:

    1. \"pkg_system\" - String designating the distribution name of the system. At the moment only \"rpm\" is supported [\"rpm\"]
    2. \"pkg_tool_cmd\" - String path to the package tool binary [\"/sbin/rpmconf\"]
      {\n    \"pkg_system\": \"rpm\",\n    \"pkg_tool_cmd\": \"/bin/rpmconf\",\n}\n
  5. Restart snmpd.

"},{"location":"Extensions/Applications/#linux-softnet-stat","title":"Linux Softnet Stat","text":""},{"location":"Extensions/Applications/#snmp-extend_22","title":"SNMP Extend","text":"

1: Install the depends, which on a Debian based system would be as below.

apt-get install -y cpanminus zlib1g-dev\ncpanm File::Slurp MIME::Base64 JSON Gzip::Faster\n

  1. Download the script into the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/linux_softnet_stat -O /etc/snmp/linux_softnet_stat\n

  2. Make the script executable

    chmod +x /etc/snmp/linux_softnet_stat\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend linux_softnet_stat /etc/snmp/linux_softnet_stat -b\n

Then either enable the application Linux Softnet Stat or wait for it to be re-discovered.

"},{"location":"Extensions/Applications/#mailcow-dockerized-postfix","title":"mailcow-dockerized postfix","text":""},{"location":"Extensions/Applications/#snmp-extend_23","title":"SNMP Extend","text":"
  1. Download the script into the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mailcow-dockerized-postfix -O /etc/snmp/mailcow-dockerized-postfix\n

  2. Make the script executable

    chmod +x /etc/snmp/mailcow-dockerized-postfix\n

    Maybe you will need to install pflogsumm on debian based OS. Please check if you have package installed.

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend mailcow-postfix /etc/snmp/mailcow-dockerized-postfix\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#mailscanner","title":"Mailscanner","text":""},{"location":"Extensions/Applications/#snmp-extend_24","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mailscanner.php -O /etc/snmp/mailscanner.php\n

  2. Make the script executable

    chmod +x /etc/snmp/mailscanner.php\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend mailscanner /etc/snmp/mailscanner.php\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#mdadm","title":"Mdadm","text":"

It allows you to checks mdadm health and array data

This script require: jq

"},{"location":"Extensions/Applications/#snmp-extend_25","title":"SNMP Extend","text":"
  1. Install jq

    sudo apt install jq\n

  2. Download the script onto the desired host.

    sudo wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mdadm -O /etc/snmp/mdadm\n

  3. Make the script executable

    sudo chmod +x /etc/snmp/mdadm\n

  4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend mdadm /etc/snmp/mdadm\n

  5. Verify it is working by running

    sudo /etc/snmp/mdadm\n

  6. Restart snmpd on your host

    sudo service snmpd restart\n

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#megaraid","title":"MegaRAID","text":"

This software from Broadcom/LSI let you monitor MegaRAID controller.

  1. Download the external software and follow the included install instructions.

  2. Add the following line to your snmpd.conf file (usually /etc/snmp/snmpd.conf)

    pass .1.3.6.1.4.1.3582 /usr/sbin/lsi_mrdsnmpmain\n

  3. Restart snmpd on your host

"},{"location":"Extensions/Applications/#memcached","title":"Memcached","text":""},{"location":"Extensions/Applications/#snmp-extend_26","title":"SNMP Extend","text":"
  1. Copy the memcached script to /etc/snmp/ on your remote server.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/memcached -O /etc/snmp/memcached\n

  2. Make the script executable:

    chmod +x /etc/snmp/memcached\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend memcached /etc/snmp/memcached\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#mojo-cape-submit","title":"Mojo CAPE Submit","text":""},{"location":"Extensions/Applications/#snmp","title":"SNMP","text":"

This assumes you've already configured mojo_cape_submit from CAPE::Utils.

  1. Add the following to snmpd.conf and restarted SNMPD
    extend mojo_cape_submit /usr/local/bin/mojo_cape_submit_extend\n

Then just wait for the machine in question to be rediscovered or enabled it in the device settings app page.

"},{"location":"Extensions/Applications/#munin","title":"Munin","text":""},{"location":"Extensions/Applications/#agent_6","title":"Agent","text":"
  1. Install the script to your agent:

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/munin -O /usr/lib/check_mk_agent/local/munin\n

  2. Make the script executable

    chmod +x /usr/lib/check_mk_agent/local/munin\n

  3. Create the munin scripts dir:

    mkdir -p /usr/share/munin/munin-scripts\n

  4. Install your munin scripts into the above directory.

To create your own custom munin scripts, please see this example:

#!/bin/bash\nif [ \"$1\" = \"config\" ]; then\n    echo 'graph_title Some title'\n    echo 'graph_args --base 1000 -l 0' #not required\n    echo 'graph_vlabel Some label'\n    echo 'graph_scale no' #not required, can be yes/no\n    echo 'graph_category system' #Choose something meaningful, can be anything\n    echo 'graph_info This graph shows something awesome.' #Short desc\n    echo 'foobar.label Label for your unit' # Repeat these two lines as much as you like\n    echo 'foobar.info Desc for your unit.'\n    exit 0\nfi\necho -n \"foobar.value \" $(date +%s) #Populate a value, here unix-timestamp\n
"},{"location":"Extensions/Applications/#mysql","title":"MySQL","text":"

Create the cache directory, '/var/cache/librenms/' and make sure that it is owned by the user running the SNMP daemon.

mkdir -p /var/cache/librenms/\n

The MySQL script requires PHP-CLI and the PHP MySQL extension, so please verify those are installed.

CentOS (May vary based on PHP version)

yum install php-cli php-mysql\n

Debian (May vary based on PHP version)

apt-get install php-cli php-mysql\n

Unlike most other scripts, the MySQL script requires a configuration file mysql.cnf in the same directory as the extend or agent script with following content:

<?php\n$mysql_user = 'root';\n$mysql_pass = 'toor';\n$mysql_host = 'localhost';\n$mysql_port = 3306;\n

Note that depending on your MySQL installation (chrooted install for example), you may have to specify 127.0.0.1 instead of localhost. Localhost make a MySQL connection via the mysql socket, while 127.0.0.1 make a standard IP connection to mysql.

Note also if you get a mysql error Uncaught TypeError: mysqli_num_rows(): Argument #1, this is because you are using a newer mysql version which doesnt support UNBLOCKING for slave statuses, so you need to also include the line $chk_options['slave'] = false; into mysql.cnf to skip checking slave statuses

"},{"location":"Extensions/Applications/#agent_7","title":"Agent","text":"

Install the agent on this device if it isn't already

and copy the mysql script to /usr/lib/check_mk_agent/local/

Verify it is working by running /usr/lib/check_mk_agent/local/mysql

"},{"location":"Extensions/Applications/#snmp-extend_27","title":"SNMP extend","text":"
  1. Copy the mysql script to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/mysql -O /etc/snmp/mysql\n

  2. Make the file executable

    chmod +x /etc/snmp/mysql\n

  3. Edit /etc/snmp/mysql to set your MySQL connection constants or declare them in /etc/snmp/mysql.cnf (new file)

  4. Edit your snmpd.conf file and add:

    extend mysql /etc/snmp/mysql\n

  5. Restart snmpd.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#nginx","title":"NGINX","text":"

NGINX is a free, open-source, high-performance HTTP server: https://www.nginx.org/

It's required to have the following directive in your nginx configuration responsible for the localhost server:

location /nginx-status {\n    stub_status on;\n    access_log  off;\n    allow 127.0.0.1;\n    allow ::1;\n    deny  all;\n}\n

"},{"location":"Extensions/Applications/#snmp-extend_28","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/nginx -O /etc/snmp/nginx\n

  2. Make the script executable

    chmod +x /etc/snmp/nginx\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend nginx /etc/snmp/nginx\n

  4. (Optional) If you have SELinux in Enforcing mode, you must add a module so the script can request /nginx-status:

    cat << EOF > snmpd_nginx.te\nmodule snmpd_nginx 1.0;\n\nrequire {\n        type httpd_t;\n        type http_port_t;\n        type snmpd_t;\n        class tcp_socket name_connect;\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t http_port_t:tcp_socket name_connect;\nEOF\ncheckmodule -M -m -o snmpd_nginx.mod snmpd_nginx.te\nsemodule_package -o snmpd_nginx.pp -m snmpd_nginx.mod\nsemodule -i snmpd_nginx.pp\n

  5. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_8","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the nginx script to /usr/lib/check_mk_agent/local/

"},{"location":"Extensions/Applications/#nfs","title":"NFS","text":"

Provides both NFS client and server support.

Currently supported OSes are as below.

  • FreeBSD
  • Linux
"},{"location":"Extensions/Applications/#snmpd-extend","title":"SNMPd extend","text":"
  1. Download the extend.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/nfs -O /etc/snmp/nfs\n

  2. Make it executable.

    chmod +x /etc/snmp/nfs\n

  3. Add it to snmpd.conf.

    extend nfs /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /etc/snmp/nfs\n

  4. Restart snmpd on your host

  5. Either wait for it to be rediscovered, rediscover it, or enable it.

If using SELinux, the following is needed.

  1. setsebool -P nis_enabled 1

  2. Make a file (snmp_nfs.te) with the following contents and install the policy with the command semodule -i snmp_nfs.te.

    module snmp_nfs 1.0;\n\nrequire {\n        type mountd_port_t;\n        type snmpd_t;\n        type hi_reserved_port_t;\n        class tcp_socket { name_bind name_connect };\n        class udp_socket name_bind;\n}\n\n#============= snmpd_t ==============\nallow snmpd_t hi_reserved_port_t:tcp_socket name_bind;\nallow snmpd_t hi_reserved_port_t:udp_socket name_bind;\nallow snmpd_t mountd_port_t:tcp_socket name_connect;\n

"},{"location":"Extensions/Applications/#linux-nfs-server","title":"Linux NFS Server","text":"

Superseded by the generalized NFS support.

Export the NFS stats from as server.

"},{"location":"Extensions/Applications/#snmp-extend_29","title":"SNMP Extend","text":"
  1. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add :

    extend nfs-server /bin/cat /proc/net/rpc/nfsd\n

    find out where cat is located using : which cat

  2. reload snmpd service to activate the configuration

"},{"location":"Extensions/Applications/#ntp-client","title":"NTP Client","text":"

A shell script that gets stats from ntp client.

"},{"location":"Extensions/Applications/#snmp-extend_30","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/ntp-client -O /etc/snmp/ntp-client\n

  2. Make the script executable

    chmod +x /etc/snmp/ntp-client\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend ntp-client /etc/snmp/ntp-client\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#ntp-server-aka-ntpd","title":"NTP Server aka NTPD","text":"

A shell script that gets stats from ntp server (ntpd).

"},{"location":"Extensions/Applications/#snmp-extend_31","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/ntp-server.sh -O /etc/snmp/ntp-server.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/ntp-server.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend ntp-server /etc/snmp/ntp-server.sh\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#chronyd","title":"Chronyd","text":"

A shell script that gets the stats from chronyd and exports them with SNMP Extend.

"},{"location":"Extensions/Applications/#snmp-extend_32","title":"SNMP Extend","text":"
  1. Download the shell script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/chrony -O /etc/snmp/chrony\n

  2. Make the script executable

    chmod +x /etc/snmp/chrony\n

  3. Edit the snmpd.conf file to include the extend by adding the following line to the end of the config file:

    extend chronyd /etc/snmp/chrony\n

Note: Some distributions need sudo-permissions for the script to work with SNMP Extend. See the instructions on the section SUDO for more information.

  1. Restart snmpd service on the host

Application should be auto-discovered and its stats presented on the Apps-page on the host. Note: Applications module needs to be enabled on the host or globally for the statistics to work as intended.

"},{"location":"Extensions/Applications/#nvidia-gpu","title":"Nvidia GPU","text":""},{"location":"Extensions/Applications/#snmp-extend_33","title":"SNMP Extend","text":"
  1. Copy the shell script, nvidia, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/nvidia -O /etc/snmp/nvidia\n

  2. Make the script executable

    chmod +x /etc/snmp/nvidia\n

  3. Edit your snmpd.conf file and add:

    extend nvidia /etc/snmp/nvidia\n

  4. Restart snmpd on your host.

  5. Verify you have nvidia-smi installed, which it generally should be if you have the driver from Nvida installed.

The GPU numbering on the graphs will correspond to how the nvidia-smi sees them as being.

For questions about what the various values are/mean, please see the nvidia-smi man file under the section covering dmon.

"},{"location":"Extensions/Applications/#opensearchelasticsearch","title":"Opensearch\\Elasticsearch","text":""},{"location":"Extensions/Applications/#snmp-extend_34","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/opensearch -O /etc/snmp/opensearch\n

  2. Make it executable

    chmod +x /etc/snmp/opensearch\n

  3. Install the required Perl dependencies.

    # FreeBSD\npkg install p5-JSON p5-libwww\n# Debian/Ubuntu\napt-get install libjson-perl libwww-perl\n# cpanm\ncpanm JSON Libwww\n

  4. Update your snmpd.conf.

    extend opensearch /bin/cat /var/cache/opensearch.json\n

  5. Update root crontab with. This is required as it will this will likely time out otherwise. Use */1 if you want to have the most recent stats when polled or to */5 if you just want at exactly a 5 minute interval.

    */5 * * * * /etc/snmp/opensearch > /var/cache/opensearch.json\n

  6. Enable it or wait for the device to be re-disocvered.

"},{"location":"Extensions/Applications/#open-grid-scheduler","title":"Open Grid Scheduler","text":"

Shell script to track the OGS/GE jobs running on clusters.

"},{"location":"Extensions/Applications/#snmp-extend_35","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/rocks.sh -O /etc/snmp/rocks.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/rocks.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend ogs /etc/snmp/rocks.sh\n

  4. Restart snmpd.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#opensips","title":"Opensips","text":"

Script that reports load-average/memory/open-files stats of Opensips

"},{"location":"Extensions/Applications/#snmp-extend_36","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/opensips-stats.sh -O /etc/snmp/opensips-stats.sh\n

  2. Make the script executable:

    chmod +x /etc/snmp/opensips-stats.sh\n

  3. Verify it is working by running /etc/snmp/opensips-stats.sh

  4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend opensips /etc/snmp/opensips-stats.sh\n

"},{"location":"Extensions/Applications/#os-updates","title":"OS Updates","text":"

A small shell script that checks your system package manager for any available updates. Supports apt-get/pacman/yum/zypper package managers.

For pacman users automatically refreshing the database, it is recommended you use an alternative database location --dbpath=/var/lib/pacman/checkupdate

"},{"location":"Extensions/Applications/#snmp-extend_37","title":"SNMP Extend","text":"
  1. Download the script onto the desired host.

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/osupdate -O /etc/snmp/osupdate\n

  2. Make the script executable

    chmod +x /etc/snmp/osupdate\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend osupdate /etc/snmp/osupdate\n

  4. Restart snmpd on your host

Note: apt-get depends on an updated package index. There are several ways to have your system run apt-get update automatically. The easiest is to create /etc/apt/apt.conf.d/10periodic and pasting the following in it: APT::Periodic::Update-Package-Lists \"1\";. If you have apticron, cron-apt or apt-listchanges installed and configured, chances are that packages are already updated periodically .

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_9","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the osupdate script to /usr/lib/check_mk_agent/local/

Then uncomment the line towards the top marked to be uncommented if using it as a agent.

"},{"location":"Extensions/Applications/#php-fpm","title":"PHP-FPM","text":""},{"location":"Extensions/Applications/#snmp-extend_38","title":"SNMP Extend","text":"
  1. Copy the shell script, phpfpmsp, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/php-fpm -O /etc/snmp/php-fpm\n

  2. Make the script executable

    chmod +x /etc/snmp/php-fpm\n

  3. Install the depends.

    # FreeBSD\npkg install p5-File-Slurp p5-JSON p5-String-ShellQuote p5-MIME-Base64\n# Debian\napt-get install libfile-slurp-perl libjson-perl libstring-shellquote-perl libmime-base64-perl\n

  4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend phpfpmsp /etc/snmp/php-fpm\n

  5. Create the config file /usr/local/etc/php-fpm_extend.json. Alternate locations may be specified using the the -f switch. Akin to like below. For more information, see /etc/snmp/php-fpm --help.

    {\n\"pools\":{\n         \"thefrog\": \"https://thefrog/fpm-status\",\n         \"foobar\": \"https://foo.bar/fpm-status\"\n    }\n}\n

  6. Restart snmpd on the host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_10","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the phpfpmsp script to /usr/lib/check_mk_agent/local/

"},{"location":"Extensions/Applications/#pi-hole","title":"Pi-hole","text":""},{"location":"Extensions/Applications/#snmp-extend_39","title":"SNMP Extend","text":"
  1. Copy the shell script, pi-hole, to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/pi-hole -O /etc/snmp/pi-hole\n

  2. Make the script executable

    chmod +x /etc/snmp/pi-hole\n

  3. Edit your snmpd.conf file and add:

    extend pi-hole /etc/snmp/pi-hole\n

  4. To get all data you must get your API auth token from Pi-hole server and change the API_AUTH_KEY entry inside the snmp script.

  5. Restard snmpd.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#portactivity","title":"Portactivity","text":""},{"location":"Extensions/Applications/#snmp-extend_40","title":"SNMP Extend","text":"
  1. Install missing packages - Ubuntu is shown below.

    apt install libparse-netstat-perl\napt install libjson-perl\n

  2. Copy the Perl script to the desired host (the host must be added to LibreNMS devices)

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/portactivity -O /etc/snmp/portactivity\n

  3. Make the script executable

    chmod +x /etc/snmp/portactivity\n

  4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend portactivity /etc/snmp/portactivity -p http,ldap,imap\n

    Will monitor HTTP, LDAP, and IMAP. The -p switch specifies what ports to use. This is a comma seperated list.

    These must be found in '/etc/services' or where ever NSS is set to fetch it from. If not, it will throw an error.

    If you want to JSON returned by it to be printed in a pretty format use the -P flag.

  5. Restart snmpd on your host.

Please note that for only TCP[46] services are supported.

"},{"location":"Extensions/Applications/#postfix","title":"Postfix","text":""},{"location":"Extensions/Applications/#snmp-extend_41","title":"SNMP Extend","text":"
  1. Copy the shell script, postfix-queues, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/postfix-queues -O /etc/snmp/postfix-queues\n

  2. Copy the Perl script, postfixdetailed, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/postfixdetailed -O /etc/snmp/postfixdetailed\n

  3. Make both scripts executable

    chmod +x /etc/snmp/postfixdetailed /etc/snmp/postfix-queues\n

  4. Edit your snmpd.conf file and add:

    extend mailq /etc/snmp/postfix-queues\nextend postfixdetailed /etc/snmp/postfixdetailed\n

  5. Restart snmpd.

  6. Install pflogsumm for your OS.

  7. Make sure the cache file in /etc/snmp/postfixdetailed is some place that snmpd can write too. This file is used for tracking changes between various values between each time it is called by snmpd. Also make sure the path for pflogsumm is correct.

  8. Run /etc/snmp/postfixdetailed to create the initial cache file so you don't end up with some crazy initial starting value. Please note that each time /etc/snmp/postfixdetailed is ran, the cache file is updated, so if this happens in between LibreNMS doing it then the values will be thrown off for that polling period.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

NOTE: If using RHEL for your postfix server, qshape must be installed manually as it is not officially supported. CentOs 6 rpms seem to work without issues.

"},{"location":"Extensions/Applications/#postgres","title":"Postgres","text":""},{"location":"Extensions/Applications/#snmp-extend_42","title":"SNMP Extend","text":"
  1. Copy the shell script, postgres, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/postgres -O /etc/snmp/postgres\n

  2. Make the script executable

    chmod +x /etc/snmp/postgres\n

  3. Edit your snmpd.conf file and add:

    extend postgres /etc/snmp/postgres\n

  4. Restart snmpd on your host

  5. Install the Nagios check check_postgres.pl on your system: https://github.com/bucardo/check_postgres

  6. Verify the path to check_postgres.pl in /etc/snmp/postgres is correct.

  7. (Optional) If you wish to change the DB username (default: pgsql), enable the postgres DB in totalling (e.g. set ignorePG to 0, default: 1), or set a hostname for check_postgres.pl to connect to (default: the Unix Socket postgresql is running on), then create the file /etc/snmp/postgres.config with the following contents (note that not all of them need be defined, just whichever you'd like to change):

    DBuser=monitoring\nignorePG=0\nDBhost=localhost\n

Note that if you are using netdata or the like, you may wish to set ignorePG to 1 or otherwise that total will be very skewed on systems with light or moderate usage.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#poudriere","title":"Poudriere","text":""},{"location":"Extensions/Applications/#snmp-extend_43","title":"SNMP Extend","text":"
  1. Copy the extend into place

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/poudriere -O /usr/local/etc/snmp/poudriere\n

  2. Make it executable.

    chmod +x /usr/local/etc/snmp/poudriere\n

  3. Install the depends

    pkg install p5-Data-Dumper p5-JSON p5-MIME-Base64 p5-File-Slurp\n

  4. Setup the cronjob. The extend needs to be ran as root. See poudriere --help for option info.

    4/5 * * * * root /usr/local/etc/snmp/poudriere -q -a -w -z\n

  5. Add the extend to snmpd.conf and restart snmpd

    extend poudriere cat /var/cache/poudriere.json.snmp\n

"},{"location":"Extensions/Applications/#powerdns","title":"PowerDNS","text":"

An authoritative DNS server: https://www.powerdns.com/auth.html

"},{"location":"Extensions/Applications/#snmp-extend_44","title":"SNMP Extend","text":"
  1. Copy the shell script, powerdns.py, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns.py -O /etc/snmp/powerdns.py\n

  2. Make the script executable

    chmod +x /etc/snmp/powerdns.py\n

  3. Edit your snmpd.conf file and add:

    extend powerdns /etc/snmp/powerdns.py\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_11","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the powerdns script to /usr/lib/check_mk_agent/local/

"},{"location":"Extensions/Applications/#powerdns-recursor","title":"PowerDNS Recursor","text":"

A recursive DNS server: https://www.powerdns.com/recursor.html

"},{"location":"Extensions/Applications/#direct","title":"Direct","text":"

The LibreNMS polling host must be able to connect to port 8082 on the monitored device. The web-server must be enabled, see the Recursor docs: https://doc.powerdns.com/md/recursor/settings/#webserver

"},{"location":"Extensions/Applications/#variables","title":"Variables","text":"

$config['apps']['powerdns-recursor']['api-key'] required, this is defined in the Recursor config

$config['apps']['powerdns-recursor']['port'] numeric, defines the port to connect to PowerDNS Recursor on. The default is 8082

$config['apps']['powerdns-recursor']['https'] true or false, defaults to use http.

"},{"location":"Extensions/Applications/#snmp-extend_45","title":"SNMP Extend","text":"
  1. Copy the shell script, powerdns-recursor, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns-recursor -O /etc/snmp/powerdns-recursor\n

  2. Make the script executable

    chmod +x /etc/snmp/powerdns-recursor\n

  3. Edit your snmpd.conf file and add:

    extend powerdns-recursor /etc/snmp/powerdns-recursor\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#agent_12","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the powerdns-recursor script to /usr/lib/check_mk_agent/local/

This script uses rec_control get-all to collect stats.

"},{"location":"Extensions/Applications/#powerdns-dnsdist","title":"PowerDNS-dnsdist","text":""},{"location":"Extensions/Applications/#snmp-extend_46","title":"SNMP Extend","text":"
  1. Copy the BASH script to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns-dnsdist -O /etc/snmp/powerdns-dnsdist\n

  2. Make the script executable

    chmod +x /etc/snmp/powerdns-dnsdist\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend powerdns-dnsdist /etc/snmp/powerdns-dnsdist\n

  4. Restart snmpd on your host.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#powermon","title":"PowerMon","text":"

PowerMon tracks the power usage on your host and can report on both consumption and cost, using a python script installed on the host.

PowerMon consumption graph

Currently the script uses one of two methods to determine current power usage:

  • ACPI via libsensors

  • HP-Health (HP Proliant servers only)

The ACPI method is quite unreliable as it is usually only implemented by battery-powered devices, e.g. laptops. YMMV. However, it's possible to support any method as long as it can return a power value, usually in Watts.

TIP: You can achieve this by adding a method and a function for that method to the script. It should be called by getData() and return a dictionary.

Because the methods are unreliable for all hardware, you need to declare to the script which method to use. The are several options to assist with testing, see --help.

"},{"location":"Extensions/Applications/#snmp-extend_47","title":"SNMP Extend","text":""},{"location":"Extensions/Applications/#initial-setup","title":"Initial setup","text":"
  1. Download the python script onto the host:

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/powermon-snmp.py -O /usr/local/bin/powermon-snmp.py\n

  2. Make the script executable:

    chmod +x /usr/local/bin/powermon-snmp.py\n

  3. Edit the script and set the cost per kWh for your supply. You must uncomment this line for the script to work:

    vi /usr/local/bin/powermon-snmp.py\n#costPerkWh = 0.15\n

  4. Choose you method below:

    Method 1. sensorsMethod 2. hpasmcli
    • Install dependencies:

      dnf install lm_sensors\npip install PySensors\n

    • Test the script from the command-line. For example:

      $ /usr/local/bin/powermon-snmp.py -m sensors -n -p\n{\n  \"meter\": {\n    \"0\": {\n      \"reading\": 0.0\n    }\n  },\n  \"psu\": {},\n  \"supply\": {\n    \"rate\": 0.15\n  },\n  \"reading\": \"0.0\"\n}\n

    If you see a reading of 0.0 it is likely this method is not supported for your system. If not, continue.

    • Obtain the hp-health package for your system. Generally there are three options:

      • Standalone package from HPE Support
      • From the HP Management Component Pack (MCP).
      • Included in the HP Service Pack for Proliant (SPP)
    • If you've downloaded the standalone package, install it. For example:

      rpm -ivh hp-health-10.91-1878.11.rhel8.x86_64.rpm\n

    • Check the service is running:

      systemctl status hp-health\n

    • Test the script from the command-line. For example:

      $ /usr/local/bin/powermon-snmp.py -m hpasmcli -n -p\n{\n  \"meter\": {\n    \"1\": {\n      \"reading\": 338.0\n    }\n  },\n  \"psu\": {\n    \"1\": {\n      \"present\": \"Yes\",\n      \"redundant\": \"No\",\n      \"condition\": \"Ok\",\n      \"hotplug\": \"Supported\",\n      \"reading\": 315.0\n    },\n    \"2\": {\n      \"present\": \"Yes\",\n      \"redundant\": \"No\",\n      \"condition\": \"FAILED\",\n      \"hotplug\": \"Supported\"\n    }\n  },\n  \"supply\": {\n    \"rate\": 0.224931\n  },\n  \"reading\": 338.0\n}\n

    If you see a reading of 0.0 it is likely this method is not supported for your system. If not, continue.

  5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add the following:

    extend  powermon   /usr/local/bin/powermon-snmp.py -m hpasmcli\n

    NOTE: Avoid using other script options in the snmpd config as the results may not be interpreted correctly by LibreNMS.

  6. Reload your snmpd service:

    systemctl reload snmpd\n

  7. You're now ready to enable the application in LibreNMS.

"},{"location":"Extensions/Applications/#finishing-up","title":"Finishing Up","text":""},{"location":"Extensions/Applications/#privoxy","title":"Privoxy","text":"

For this to work, the following log items need enabled for Privoxy.

debug     2 # show each connection status\ndebug   512 # Common Log Format\ndebug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.\ndebug  4096 # Startup banner and warnings\ndebug  8192 # Non-fatal errors\n
"},{"location":"Extensions/Applications/#snmp-extend_48","title":"SNMP Extend","text":"
  1. Download the extend and make sure it is executable.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/privoxy -O /etc/snmp/privoxy\nchmod +x /etc/snmp/privoxy\n

  2. Install the depdenencies.

    # FreeBSD\npkg install p5-File-ReadBackwards p5-Time-Piece p5-JSON p5-IPC-Run3 p5-Gzip-Faster p5-MIME-Base64\n# Debian\napt-get install cpanminus zlib1g\ncpanm File::ReadBackwards Time::Piece JSON IPC::Run3 MIME::Base64 Gzip::Faster\n

  3. Add the extend to snmpd.conf and restart snmpd.

    extend privoxy /etc/snmp/privoxy\n

If your logfile is not at /var/log/privoxy/logfile, that may be changed via the -f option.

If privoxy-log-parser.pl is not found in your standard $PATH setting, you may will need up call the extend via /usr/bin/env with a $PATH set to something that includes it.

Once that is done, just wait for the server to be rediscovered or just enable it manually.

"},{"location":"Extensions/Applications/#pwrstatd","title":"Pwrstatd","text":"

Pwrstatd (commonly known as powerpanel) is an application/service available from CyberPower to monitor their PSUs over USB. It is currently capable of reading the status of only one PSU connected via USB at a time. The powerpanel software is available here: https://www.cyberpowersystems.com/products/software/power-panel-personal/

"},{"location":"Extensions/Applications/#snmp-extend_49","title":"SNMP Extend","text":"
  1. Copy the python script, pwrstatd.py, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/pwrstatd.py -O /etc/snmp/pwrstatd.py\n

  2. Make the script executable

    chmod +x /etc/snmp/pwrstatd.py\n

  3. Edit your snmpd.conf file and add:

    extend pwrstatd /etc/snmp/pwrstatd.py\n

  4. (Optional) Create a /etc/snmp/pwrstatd.json file and specify the path to the pwrstat executable [the default path is /sbin/pwrstat]:

    {\n    \"pwrstat_cmd\": \"/sbin/pwrstat\"\n}\n

  5. Restart snmpd.

"},{"location":"Extensions/Applications/#proxmox","title":"Proxmox","text":"
  1. For Proxmox 4.4+ install the libpve-apiclient-perl package

    apt install libpve-apiclient-perl\n

  2. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/proxmox -O /usr/local/bin/proxmox\n

  3. Make the script executable

    chmod +x /usr/local/bin/proxmox\n

  4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend proxmox /usr/local/bin/proxmox\n

  5. Note: if your snmpd doesn't run as root, you might have to invoke the script using sudo and modify the \"extend\" line

extend proxmox /usr/bin/sudo /usr/local/bin/proxmox\n

after, edit your sudo users (usually visudo) and add at the bottom:

Debian-snmp ALL=(ALL) NOPASSWD: /usr/local/bin/proxmox\n
  1. Restart snmpd on your host
"},{"location":"Extensions/Applications/#puppet-agent","title":"Puppet Agent","text":"

SNMP extend script to get your Puppet Agent data into your host.

"},{"location":"Extensions/Applications/#snmp-extend_50","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/puppet_agent.py -O /etc/snmp/puppet_agent.py\n

  2. Make the script executable

    chmod +x /etc/snmp/puppet_agent.py\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend puppet-agent /etc/snmp/puppet_agent.py\n

The Script needs python3-yaml package to be installed.

Per default script searches for on of this files:

  • /var/cache/puppet/state/last_run_summary.yaml
  • /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml

optionally you can add a specific summary file with creating /etc/snmp/puppet.json

{\n     \"agent\": {\n        \"summary_file\": \"/my/custom/path/to/summary_file\"\n     }\n}\n
custom summary file has highest priority

  1. Restart snmpd on the host
"},{"location":"Extensions/Applications/#pureftpd","title":"PureFTPd","text":"

SNMP extend script to monitor PureFTPd.

"},{"location":"Extensions/Applications/#snmp-extend_51","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/pureftpd.py -O /etc/snmp/pureftpd.py\n

  2. Make the script executable

    chmod +x /etc/snmp/pureftpd.py\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend pureftpd sudo /etc/snmp/pureftpd.py\n

  4. Edit your sudo users (usually visudo) and add at the bottom:

    snmp ALL=(ALL) NOPASSWD: /etc/snmp/pureftpd.py\n
    or the path where your pure-ftpwho is located

  5. If pure-ftpwho is not located in /usr/sbin

you will also need to create a config file, which is named

pureftpd.json. The file has to be located in /etc/snmp/.

{\"pureftpwho_cmd\": \"/usr/sbin/pure-ftpwho\"\n}\n
  1. Restart snmpd on your host
"},{"location":"Extensions/Applications/#raspberry-pi","title":"Raspberry PI","text":"

SNMP extend script to get your PI data into your host.

"},{"location":"Extensions/Applications/#snmp-extend_52","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/raspberry.sh -O /etc/snmp/raspberry.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/raspberry.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend raspberry /usr/bin/sudo /bin/sh /etc/snmp/raspberry.sh\n

  4. Edit your sudo users (usually visudo) and add at the bottom:

    snmp ALL=(ALL) NOPASSWD: /bin/sh /etc/snmp/raspberry.sh\n

Note: If you are using Raspian, the default user is Debian-snmp. Change snmp above to Debian-snmp. You can verify the user snmpd is using with ps aux | grep snmpd

  1. Restart snmpd on PI host
"},{"location":"Extensions/Applications/#raspberry-pi-gpio-monitor","title":"Raspberry Pi GPIO Monitor","text":"

SNMP extend script to monitor your IO pins or sensor modules connected to your GPIO header.

"},{"location":"Extensions/Applications/#snmp-extend_53","title":"SNMP Extend","text":"

1: Make sure you have wiringpi installed on your Raspberry Pi. In Debian-based systems for example you can achieve this by issuing:

apt-get install wiringpi\n

2: Download the script to your Raspberry Pi. wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/rpigpiomonitor.php -O /etc/snmp/rpigpiomonitor.php

3: (optional) Download the example configuration to your Raspberry Pi. wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/rpigpiomonitor.ini -O /etc/snmp/rpigpiomonitor.ini

4: Make the script executable: chmod +x /etc/snmp/rpigpiomonitor.php

5: Create or edit your rpigpiomonitor.ini file according to your needs.

6: Check your configuration with rpigpiomonitor.php -validate

7: Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

extend rpigpiomonitor /etc/snmp/rpigpiomonitor.php\n

8: Restart snmpd on your Raspberry Pi and, if your Raspberry Pi is already present in LibreNMS, perform a manual rediscover.

"},{"location":"Extensions/Applications/#redis","title":"Redis","text":"

Script to monitor your Redis Server

"},{"location":"Extensions/Applications/#snmp-extend_54","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/redis.py -O /etc/snmp/redis.py\n

  2. Make the script executable

    chmod +x /etc/snmp/redis.py\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend redis /etc/snmp/redis.py\n

  4. (Optional) If you have SELinux in Enforcing mode, you must add a module so the script can get redis informations and write them:

    cat << EOF > snmpd_redis.te\nmodule snmpd_redis 1.0;\n\nrequire {\n        type tmp_t;\n        type redis_port_t;\n        type snmpd_t;\n        class tcp_socket name_connect;\n        class dir { add_name write };\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t redis_port_t:tcp_socket name_connect;\nallow snmpd_t tmp_t:dir { write add_name };\nEOF\ncheckmodule -M -m -o snmpd_redis.mod snmpd_redis.te\nsemodule_package -o snmpd_redis.pp -m snmpd_redis.mod\nsemodule -i snmpd_redis.pp\n

"},{"location":"Extensions/Applications/#agent_13","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the redis script to /usr/lib/check_mk_agent/local/

"},{"location":"Extensions/Applications/#rrdcached","title":"RRDCached","text":"

Install/Setup: For Install/Setup Local Librenms RRDCached: Please see RRDCached

Will collect stats by: 1. Connecting directly to the associated device on port 42217 2. Monitor thru snmp with SNMP extend, as outlined below 3. Connecting to the rrdcached server specified by the rrdcached setting

SNMP extend script to monitor your (remote) RRDCached via snmp

"},{"location":"Extensions/Applications/#snmp-extend_55","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/rrdcached -O /etc/snmp/rrdcached\n

  2. Make the script executable

    chmod +x /etc/snmp/rrdcached\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend rrdcached /etc/snmp/rrdcached\n

"},{"location":"Extensions/Applications/#sdfs-info","title":"SDFS info","text":"

A small shell script that exportfs SDFS volume info.

"},{"location":"Extensions/Applications/#snmp-extend_56","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/sdfsinfo -O /etc/snmp/sdfsinfo\n

  2. Make the script executable

    chmod +x /etc/snmp/sdfsinfo\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend sdfsinfo /etc/snmp/sdfsinfo\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#seafile","title":"Seafile","text":"

SNMP extend script to monitor your Seafile Server

"},{"location":"Extensions/Applications/#snmp-extend_57","title":"SNMP Extend","text":"
  1. Copy the Python script, seafile.py, to the desired host
    wget https://github.com/librenms/librenms-agent/raw/master/snmp/seafile.py -O /etc/snmp/seafile.py\n

Also you have to install the requests Package for Python3. Under Ubuntu/Debian just run apt install python3-requests

  1. Make the script executable

    chmod +x /etc/snmp/seafile.py\n

  2. Edit your snmpd.conf file and add:

    extend seafile /etc/snmp/seafile.py\n

  3. You will also need to create the config file, which is named seafile.json . The script has to be located at /etc/snmp/.

    {\"url\": \"https://seafile.mydomain.org\",\n \"username\": \"some_admin_login@mail.address\",\n \"password\": \"password\",\n \"account_identifier\": \"name\"\n \"hide_monitoring_account\": true\n}\n

The variables are as below.

url = Url how to get access to Seafile Server\nusername = Login to Seafile Server.\n           It is important that used Login has admin privileges.\n           Otherwise most API calls will be denied.\npassword = Password to the configured login.\naccount_identifier = Defines how user accounts are listed in RRD Graph.\n                     Options are: name, email\nhide_monitoring_account = With this Boolean you can hide the Account which you\n                          use to access Seafile API\n

Note:It is recommended to use a dedicated Administrator account for monitoring.

"},{"location":"Extensions/Applications/#smart","title":"SMART","text":""},{"location":"Extensions/Applications/#snmp-extend_58","title":"SNMP Extend","text":"
  1. Copy the Perl script, smart, to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/smart-v1 -O /etc/snmp/smart\n

  2. Install the depends.

    # FreeBSD\npkg install p5-JSON p5-MIME-Base64 smartmontools\n# Debian\napt-get install cpanminus smartmontools\ncpanm MIME::Base64 JSON\n# CentOS\ndnf install smartmontools perl-JSON perl-MIME-Base64\n

  3. Make the script executable

    chmod +x /etc/snmp/smart\n

  4. Setup a cronjob to run it. This ensures slow to poll disks won't result in errors.

 */5 * * * * /etc/snmp/smart -u -Z\n
  1. Edit your snmpd.conf file and add:

    extend smart /bin/cat /var/cache/smart\n

  2. You will also need to create the config file, which defaults to the same path as the script, but with .config appended. So if the script is located at /etc/snmp/smart, the config file will be /etc/snmp/smart.config. Alternatively you can also specific a config via -c.

Anything starting with a # is comment. The format for variables is $variable=$value. Empty lines are ignored. Spaces and tabes at either the start or end of a line are ignored. Any line with out a matched variable or # are treated as a disk.

#This is a comment\ncache=/var/cache/smart\nsmartctl=/usr/bin/env smartctl\nuseSN=1\nada0\nada1\nda5 /dev/da5 -d sat\ntwl0,0 /dev/twl0 -d 3ware,0\ntwl0,1 /dev/twl0 -d 3ware,1\ntwl0,2 /dev/twl0 -d 3ware,2\n

The variables are as below.

cache = The path to the cache file to use. Default: /var/cache/smart\nsmartctl = The path to use for smartctl. Default: /usr/bin/env smartctl\nuseSN = If set to 1, it will use the disks SN for reporting instead of the device name.\n        1 is the default. 0 will use the device name.\n

A disk line is can be as simple as just a disk name under /dev/. Such as in the config above The line \"ada0\" would resolve to \"/dev/ada0\" and would be called with no special argument. If a line has a space in it, everything before the space is treated as the disk name and is what used for reporting and everything after that is used as the argument to be passed to smartctl.

If you want to guess at the configuration, call it with -g and it will print out what it thinks it should be.

  1. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

  1. Optionally setup nightly self tests for the disks. The exend will run the specified test on all configured disks if called with the -t flag and the name of the SMART test to run.
 0 0 * * * /etc/snmp/smart -t long\n
"},{"location":"Extensions/Applications/#sneck","title":"Sneck","text":"

This is for replacing Nagios/Icinga or the LibreNMS service integration in regards to NRPE. This allows LibreNMS to query what checks were ran on the server and keep track of totals of OK, WARNING, CRITICAL, and UNKNOWN statuses.

The big advantage over this compared to a NRPE are as below.

  • It does not need to know what checks are configured on it.
  • Also does not need to wait for the tests to run as sneck is meant to be ran via cron and the then return the cache when queried via SNMP, meaning a lot faster response time, especially if slow checks are being performed.
  • Works over proxied SNMP connections.

Included are alert examples. Although for setting up custom ones, the metrics below are provided.

Metric Description ok Total OK checks warning Total WARNING checks critical Total CRITICAL checks unknown Total UNKNOWN checks errored Total checks that errored time_to_polling Differnce in seconds between when polling data was generated and when polled time_to_polling_abs The absolute value of time_to_polling. check_$CHECK Exit status of a specific check $CHECK is equal to the name of the check in question. So foo would be check_foo

The standard Nagios/Icinga style exit codes are used and those are as below.

Exit Meaning 0 okay 1 warning 2 critical 3+ unknown

To use time_to_polling, it will need to enabled via setting the config item below. The default is false. Unless set to true, this value will default to 0. If enabling this, one will want to make sure that NTP is in use every were or it will alert if it goes over a difference of 540s.

lnms config:set app.sneck.polling_time_diff true\n

For more information on Sneck, check it out at MetaCPAN or Github.

For poking systems using Sneck, also check out boop_snoot if one wants to query those systems via the CLI. Docs on it at MetaCPAN and Github.

"},{"location":"Extensions/Applications/#snmp-extend_59","title":"SNMP Extend","text":"
  1. Install the extend.
# FreeBSD\npkg install p5-JSON p5-File-Slurp p5-MIME-Base64 p5-Gzip-Faster p5-App-cpanminus\ncpanm Monitoring::Sneck\n# Debian based systems\napt-get install zlib1g-dev cpanminus\ncpanm Monitoring::Sneck\n
  1. Configure any of the checks you want to run in /usr/local/etc/sneck.conf. You con find it documented here.

  2. Set it up in cron. This will mean you don't need to wait for all the checks to complete when polled via SNMP, which for like SMART or other long running checks will mean it timing out. Also means it does not need called via sudo as well.

*/5 * * * * /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /usr/local/bin/sneck -u 2> /dev/null > /dev/null\n
  1. Set it up in the snmpd config and restart snmpd. The -c flag will tell read it to read from cache instead of rerunning the checks.
extend sneck /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /usr/local/bin/sneck -c\n
  1. In LibreNMS, enable the application for the server in question or wait for auto discovery to find it.
"},{"location":"Extensions/Applications/#squid","title":"Squid","text":""},{"location":"Extensions/Applications/#snmp-proxy","title":"SNMP Proxy","text":"
  1. Enable SNMP for Squid like below, if you have not already, and restart it.

    acl snmppublic snmp_community public\nsnmp_port 3401\nsnmp_access allow snmppublic localhost\nsnmp_access deny all\n

  2. Restart squid on your host.

  3. Edit your snmpd.conf file and add, making sure you have the same community, host, and port as above:

    proxy -v 2c -Cc -c public 127.0.0.1:3401 1.3.6.1.4.1.3495\n

For more advanced information on Squid and SNMP or setting up proxying for net-snmp, please see the links below.

http://wiki.squid-cache.org/Features/Snmp http://www.net-snmp.org/wiki/index.php/Snmpd_proxy

"},{"location":"Extensions/Applications/#supervisord","title":"Supervisord","text":"

It shows you the totals per status and also the uptime per process. That way you can add alerts for instance when there are process in state FATAL.

"},{"location":"Extensions/Applications/#snmp-extend_60","title":"SNMP Extend","text":"
  1. Copy the python script to the desired host.

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/supervisord.py -O /etc/snmp/supervisord.py\n
    Notice that this will use the default unix socket path. Modify the unix_socket_path variable in the script if your path differs from the default.

  2. Make the script executable

    chmod +x /etc/snmp/supervisord.py\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend supervisord /etc/snmp/supervisord.py\n

  4. Restart snmpd on your host

    systemctl restart snmpd\n

"},{"location":"Extensions/Applications/#sagan","title":"Sagan","text":"

For metrics the stats are migrated as below from the stats JSON.

f_drop_percent and drop_percent are computed based on the found data.

Instance Key Stats JSON Key uptime .stats.uptime total .stats.captured.total drop .stats.captured.drop ignore .stats.captured.ignore threshold .stats.captured.theshold after .stats.captured.after match .stats.captured.match bytes .stats.captured.bytes_total bytes_ignored .stats.captured.bytes_ignored max_bytes_log_line .stats.captured.max_bytes_log_line eps .stats.captured.eps f_total .stats.flow.total f_dropped .stats.flow.dropped

Those keys are appended with the name of the instance running with _ between the instance name and instance metric key. So uptime for ids would be ids_uptime.

The default is named 'ids' unless otherwise specified via the extend.

There is a special instance name of .total which is the total of all the instances. So if you want the total eps, the metric would be .total_eps. Also worth noting that the alert value is the highest one found among all the instances.

"},{"location":"Extensions/Applications/#snmp-extend_61","title":"SNMP Extend","text":"
  1. Install the extend.

    cpanm Sagan::Monitoring\n

  2. Setup cron. Below is a example.

    */5 * * * * /usr/local/bin/sagan_stat_check > /dev/null\n

  3. Configure snmpd.conf

    extend sagan-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin sagan_stat_check -c\n

  4. Restart snmpd on your system.

You will want to make sure that sagan is setup to with the values set below for stats-json processor, for a single instance setup..

enabled: yes\ntime: 300\nsubtract_old_values: true\nfilename: \"$LOG_PATH/stats.json\"\n

Any configuration of sagan_stat_check should be done in the cron setup. If the default does not work, check the docs for it at MetaCPAN for sagan_stat_check

"},{"location":"Extensions/Applications/#socket-statistics-ss","title":"Socket Statistics (ss)","text":"

The Socket Statistics application polls ss and scrapes socket statuses. Individual sockets and address-families may be filtered out within the script's optional configuration JSON file.

  1. The following socket types are polled directly. Filtering a socket type will disable direct polling as-well-as indirect polling within any address-families that list the socket type as their child:

    dccp (also exists within address-families \"inet\" and \"inet6\")\nmptcp (also exists within address-families \"inet\" and \"inet6\")\nraw (also exists within address-families \"inet\" and \"inet6\")\nsctp (also exists within address-families \"inet\" and \"inet6\")\ntcp (also exists within address-families \"inet\" and \"inet6\")\nudp (also exists within address-families \"inet\" and \"inet6\")\nxdp\n

  2. The following socket types are polled within an address-family only:

    inet6 (within address-family \"inet6\")\np_dgr (within address-family \"link\")\np_raw (within address-family \"link\")\nti_dg (within address-family \"tipc\")\nti_rd (within address-family \"tipc\")\nti_sq (within address-family \"tipc\")\nti_st (within address-family \"tipc\")\nv_dgr (within address-family \"vsock\")\nv_str (within address-family \"vsock\")\nunknown (within address-families \"inet\", \"inet6\", \"link\", \"tipc\", and \"vsock\")\n

  3. The following address-families are polled directly and have their child socket types tab-indented below them. Filtering a socket type (see \"1\" above) will filter it from the address-family. Filtering an address-family will filter out all of its child socket types. However, if those socket types are not DIRECTLY filtered out (see \"1\" above), then they will continue to be monitored either directly or within other address-families in which they exist:

    inet\n    dccp\n    mptcp\n    raw\n    sctp\n    tcp\n    udp\n    unknown\ninet6\n    dccp\n    icmp6\n    mptcp\n    raw\n    sctp\n    tcp\n    udp\n    unknown\nlink\n    p_dgr\n    p_raw\n    unknown\nnetlink\ntipc\n    ti_dg\n    ti_rd\n    ti_sq\n    ti_st\n    unknown\nunix\n    u_dgr\n    u_seq\n    u_str\nvsock\n    v_dgr\n    v_str\n    unknown\n

"},{"location":"Extensions/Applications/#snmp-extend_62","title":"SNMP Extend","text":"
  1. Copy the python script, ss.py, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/ss.py -O /etc/snmp/ss.py\n

  2. Make the script executable

    chmod +x /etc/snmp/ss.py\n

  3. Edit your snmpd.conf file and add:

    extend ss /etc/snmp/ss.py\n

  4. (Optional) Create a /etc/snmp/ss.json file and specify:

    1. \"ss_cmd\" - String path to the ss binary: [\"/sbin/ss\"]
    2. \"socket_types\" - A comma-delimited list of socket types to include. The following socket types are valid: dccp, icmp6, mptcp, p_dgr, p_raw, raw, sctp, tcp, ti_dg, ti_rd, ti_sq, ti_st, u_dgr, u_seq, u_str, udp, unknown, v_dgr, v_dgr, xdp. Please note that the \"unknown\" socket type is represented in /sbin/ss output with the netid \"???\". Please also note that the p_dgr and p_raw socket types are specific to the \"link\" address family; the ti_dg, ti_rd, ti_sq, and ti_st socket types are specific to the \"tipc\" address family; the u_dgr, u_seq, and u_str socket types are specific to the \"unix\" address family; and the v_dgr and v_str socket types are specific to the \"vsock\" address family. Filtering out the parent address families for the aforementioned will also filter out their specific socket types. Specifying \"all\" includes all of the socket types. For example: to include only tcp, udp, icmp6 sockets, you would specify \"tcp,udp,icmp6\": [\"all\"]
    3. \"addr_families\" - A comma-delimited list of address families to include. The following families are valid: inet, inet6, link, netlink, tipc, unix, vsock. As mentioned above under (b), filtering out the link, tipc, unix, or vsock address families will also filter out their respective socket types. Specifying \"all\" includes all of the families. For example: to include only inet and inet6 families, you would specify \"inet,inet6\": [\"all\"]
      {\n    \"ss_cmd\": \"/sbin/ss\",\n    \"socket_types\": \"all\"\n    \"addr_families\": \"all\"\n}\n
      In order to filter out uncommon/unused socket types, the following JSON configuration is recommended:
      {\n    \"ss_cmd\": \"/sbin/ss\",\n    \"socket_types\": \"icmp6,p_dgr,p_raw,raw,tcp,u_dgr,u_seq,u_str,udp\",\n    \"addr_families\": \"inet,inet6,link,netlink,unix\"\n}\n
  5. (Optional) If SELinux is in Enforcing mode, you must add a module so the script can poll sockets:

    cat << EOF > snmpd_ss.te\nmodule snmp_ss 1.0;\n\nrequire {\n    type snmpd_t;\n    class netlink_tcpdiag_socket { bind create getattr nlmsg_read read setopt write };\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t self:netlink_tcpdiag_socket { bind create getattr nlmsg_read read setopt write };\nEOF\ncheckmodule -M -m -o snmpd_ss.mod snmpd_ss.te\nsemodule_package -o snmpd_ss.pp -m snmpd_ss.mod\nsemodule -i snmpd_ss.pp\n

  6. Restart snmpd.

"},{"location":"Extensions/Applications/#suricata","title":"Suricata","text":""},{"location":"Extensions/Applications/#snmp-extend_63","title":"SNMP Extend","text":"
  1. Install the extend.

    cpanm Suricata::Monitoring\n

  2. Setup cron. Below is a example.

    */5 * * * * /usr/local/bin/suricata_stat_check > /dev/null\n

  3. Configure snmpd.conf

    extend suricata-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin suricata_stat_check -c\n

Or if you want to use try compressing the return via Base64+GZIP...

extend suricata-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin suricata_stat_check -c -b\n
  1. Restart snmpd on your system.

You will want to make sure Suricata is set to output the stats to the eve file once a minute. This will help make sure that it won't be to far back in the file and will make sure it is recent when the cronjob runs.

Any configuration of suricata_stat_check should be done in the cron setup. If the default does not work, check the docs for it at MetaCPAN for suricata_stat_check

"},{"location":"Extensions/Applications/#suricata-extract","title":"Suricata Extract","text":""},{"location":"Extensions/Applications/#snmp_1","title":"SNMP","text":"
  1. Add the following to your snmpd config and restart. Path may have to be adjusted depending on where suricata_extract_submit_extend is installed to.
    extend suricata_extract /usr/local/bin/suricata_extract_submit_extend\n

Then just wait for the system to be rediscovered or enable it manually for the server in question.

"},{"location":"Extensions/Applications/#systemd","title":"Systemd","text":"

The systemd application polls systemd and scrapes systemd units' load, activation, and sub states.

"},{"location":"Extensions/Applications/#snmp-extend_64","title":"SNMP Extend","text":"
  1. Copy the python script, systemd.py, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/systemd.py -O /etc/snmp/systemd.py\n

  2. Make the script executable

    chmod +x /etc/snmp/systemd.py\n

  3. Edit your snmpd.conf file and add:

    extend systemd /etc/snmp/systemd.py\n

  4. (Optional) Create a /etc/snmp/systemd.json file and specify:

    1. \"systemctl_cmd\" - String path to the systemctl binary [Default: \"/usr/bin/systemctl\"]
    2. \"include_inactive_units\" - True/False string to include inactive units in results [Default: \"False\"]
      {\n    \"systemctl_cmd\": \"/bin/systemctl\",\n    \"include_inactive_units\": \"True\"\n}\n
  5. (Optional) If you have SELinux in Enforcing mode, you must add a module so the script can access systemd state:

    cat << EOF > snmpd_systemctl.te\nmodule snmpd_systemctl 1.0;\n\nrequire {\n        type snmpd_t;\n        type systemd_systemctl_exec_t;\n        type init_t;\n        class file { execute execute_no_trans map open read };\n        class unix_stream_socket connectto;\n        class system status;\n}\n\n#============= snmpd_t ==============\nallow snmpd_t init_t:system status;\nallow snmpd_t init_t:unix_stream_socket connectto;\nallow snmpd_t systemd_systemctl_exec_t:file { execute execute_no_trans map open read };\nEOF\ncheckmodule -M -m -o snmpd_systemctl.mod snmpd_systemctl.te\nsemodule_package -o snmpd_systemctl.pp -m snmpd_systemctl.mod\nsemodule -i snmpd_systemctl.pp\n

  6. Restart snmpd.

"},{"location":"Extensions/Applications/#tinydns-aka-djbdns","title":"TinyDNS aka djbdns","text":""},{"location":"Extensions/Applications/#agent_14","title":"Agent","text":"

Install the agent on this device if it isn't already and copy the tinydns script to /usr/lib/check_mk_agent/local/

Note: We assume that you use DJB's Daemontools to start/stop tinydns. And that your tinydns instance is located in /service/dns, adjust this path if necessary.

  1. Replace your log's run file, typically located in /service/dns/log/run with:

    #!/bin/sh\nexec setuidgid dnslog tinystats ./main/tinystats/ multilog t n3 s250000 ./main/\n

  2. Create tinystats directory and chown:

    mkdir /service/dns/log/main/tinystats\nchown dnslog:nofiles /service/dns/log/main/tinystats\n

  3. Restart TinyDNS and Daemontools: /etc/init.d/svscan restart Note: Some say svc -t /service/dns is enough, on my install (Gentoo) it doesn't rehook the logging and I'm forced to restart it entirely.

"},{"location":"Extensions/Applications/#unbound","title":"Unbound","text":"

Unbound configuration:

# Enable extended statistics.\nserver:\n        extended-statistics: yes\n        statistics-cumulative: yes\n\nremote-control:\n        control-enable: yes\n        control-interface: 127.0.0.1\n

Restart your unbound after changing the configuration, verify it is working by running unbound-control stats.

"},{"location":"Extensions/Applications/#option-1-snmp-extend-preferred-and-easiest-method","title":"Option 1. SNMP Extend (Preferred and easiest method)","text":"
  1. Copy the shell script, unbound, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/unbound -O /etc/snmp/unbound\n

  2. Make the script executable

    chmod +x /etc/snmp/unbound\n

  3. Edit your snmpd.conf file and add:

    extend unbound /usr/bin/sudo /etc/snmp/unbound\n

  4. Restart snmpd.

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#option-2-agent","title":"Option 2. Agent","text":"

Install the agent on this device if it isn't already and copy the unbound.sh script to /usr/lib/check_mk_agent/local/

"},{"location":"Extensions/Applications/#ups-nut","title":"UPS-nut","text":"

A small shell script that exports nut ups status.

"},{"location":"Extensions/Applications/#snmp-extend_65","title":"SNMP Extend","text":"
  1. Copy the shell script, unbound, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/ups-nut.sh -O /etc/snmp/ups-nut.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/ups-nut.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend ups-nut /etc/snmp/ups-nut.sh\n

  4. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

Optionally if you have multiple UPS or your UPS is not named APCUPS you can specify its name as an argument into /etc/snmp/ups-nut.sh

extend ups-nut /etc/snmp/ups-nut.sh ups1\nextend ups-nut /etc/snmp/ups-nut.sh ups2\n

"},{"location":"Extensions/Applications/#ups-apcups","title":"UPS-apcups","text":"

A small shell script that exports apcacess ups status.

"},{"location":"Extensions/Applications/#snmp-extend_66","title":"SNMP Extend","text":"
  1. Copy the shell script, unbound, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/ups-apcups -O /etc/snmp/ups-apcups\n

  2. Make the script executable

    chmod +x /etc/snmp/ups-apcups\n

  3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

    extend ups-apcups /etc/snmp/ups-apcups\n

If 'apcaccess' is not in the PATH enviromental variable snmpd is using, you may need to do something like below.

extend ups-apcups/usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /etc/snmp/ups-apcups\n
  1. Restart snmpd on your host

The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

"},{"location":"Extensions/Applications/#voip-monitor","title":"Voip-monitor","text":"

Shell script that reports cpu-load/memory/open-files files stats of Voip Monitor

"},{"location":"Extensions/Applications/#snmp-extend_67","title":"SNMP Extend","text":"
  1. Download the script onto the desired host

    wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/voipmon-stats.sh -O /etc/snmp/voipmon-stats.sh\n

  2. Make the script executable

    chmod +x /etc/snmp/voipmon-stats.sh\n

  3. Edit your snmpd.conf file (usually /etc/snmp/voipmon-stats.sh) and add:

    extend voipmon /etc/snmp/voipmon-stats.sh\n

"},{"location":"Extensions/Applications/#wireguard","title":"Wireguard","text":"

The Wireguard application polls the Wireguard service and scrapes all client statistics for all interfaces configured as Wireguard interfaces.

"},{"location":"Extensions/Applications/#snmp-extend_68","title":"SNMP Extend","text":"
  1. Copy the python script, wireguard.py, to the desired host

    wget https://github.com/librenms/librenms-agent/raw/master/snmp/wireguard.pl -O /etc/snmp/wireguard.pl\n

  2. Install the depends.

    # FreeBSD\npkg install p5-JSON p5-File-Slurp p5-MIME-Base64\n# Debian\napt-get install libjson-perl libmime-base64-perl libfile-slurp-perl\n

  3. Make the script executable

    chmod +x /etc/snmp/wireguard.pl\n

  4. Edit your snmpd.conf file and add:

    extend wireguard /etc/snmp/wireguard.pl\n

  5. Create the optional config file, /usr/local/etc/wireguard_extend.json.

key default description include_pubkey 0 Include the pubkey with the return. use_short_hostname 1 If the hostname should be shortened to just the first part. public_key_to_arbitrary_name {} A hash of pubkeys to name mappings. pubkey_resolvers Resolvers to use for the pubkeys.

The default for pubkey_resolvers is config,endpoint_if_first_allowed_is_subnet_use_hosts,endpoint_if_first_allowed_is_subnet_use_ip,first_allowed_use_hosts,first_allowed_use_ip.

resolver description config Use the mappings from .public_key_to_arbitrary_name . endpoint_if_first_allowed_is_subnet_use_hosts If the first allowed IP is a subnet, see if a matching IP can be found in hosts for the endpoint. endpoint_if_first_allowed_is_subnet_use_getent If the first allowed IP is a subnet, see if a hit can be found for the endpoint IP via getent hosts. endpoint_if_first_allowed_is_subnet_use_ip If the first allowed IP is a subnet, use the endpoint IP for the name. first_allowed_use_hosts See if a match can be found in hosts for the first allowed IP. first_allowed_use_getent Use getent hosts to see try to fetch a match for the first allowed IP. first_allowed_use_ip Use the first allowed IP as the name.
  1. Restart snmpd.
"},{"location":"Extensions/Applications/#zfs","title":"ZFS","text":""},{"location":"Extensions/Applications/#snmp-extend_69","title":"SNMP Extend","text":"

1: Install the depends.

### FreeBSD\npkg install p5-JSON p5-MIME-Base64 p5-Gzip-Faster p5-File-Slurp\n### Debian\napt-get install -y cpanminus zlib1g-dev\ncpanm Mime::Base64 JSON Gzip::Faster\n

2: Fetch the script in question and make it executable.

wget https://github.com/librenms/librenms-agent/raw/master/snmp/zfs -O /etc/snmp/zfs\nchmod +x /etc/snmp/zfs\n

3: Add the following to snmpd.conf and restart snmpd.

extend zfs /etc/snmp/zfs\n

"},{"location":"Extensions/Authentication/","title":"Authentication Options","text":"

LibreNMS supports multiple authentication modules along with Two Factor Auth. Here we will provide configuration details for these modules. Alternatively, you can use Socialite Providers which supports a wide variety of social/OAuth/SAML authentication methods.

"},{"location":"Extensions/Authentication/#available-authentication-modules","title":"Available authentication modules","text":"
  • MySQL: mysql

  • Active Directory: active_directory

  • LDAP: ldap

  • Radius: radius

  • HTTP Auth: http-auth, ad_authorization, ldap_authorization

  • Single Sign-on: sso

\u26a0\ufe0f When enabling a new authentication module, the local users will no longer be available to log in.

"},{"location":"Extensions/Authentication/#enable-authentication-module","title":"Enable authentication module","text":"

To enable a particular authentication module you need to set this up in config.php. Please note that only ONE module can be enabled. LibreNMS doesn't support multiple authentication mechanisms at the same time.

auth/general

lnms config:set auth_mechanism mysql\n
"},{"location":"Extensions/Authentication/#user-levels-and-user-account-type","title":"User levels and User account type","text":"
  • 1: Normal User: You will need to assign device / port permissions for users at this level.

  • 5: Global Read: Read only Administrator.

  • 10: Administrator: This is a global read/write admin account.

  • 11: Demo Account: Provides full read/write with certain restrictions (i.e can't delete devices).

Note Oxidized configs can often contain sensitive data. Because of that only Administrator account type can see configs.

"},{"location":"Extensions/Authentication/#note-for-selinux-users","title":"Note for SELinux users","text":"

When using SELinux on the LibreNMS server, you need to allow Apache (httpd) to connect LDAP/Active Directory server, this is disabled by default. You can use SELinux Booleans to allow network access to LDAP resources with this command:

setsebool -P httpd_can_connect_ldap=1\n
"},{"location":"Extensions/Authentication/#testing-authentication","title":"Testing authentication","text":"

You can test authentication with this script:

./scripts/auth_test.php\n

Enable debug output to troubleshoot issues

"},{"location":"Extensions/Authentication/#mysql-authentication","title":"MySQL Authentication","text":"

auth/general

lnms config:set auth_mechanism mysql\n

This is default option with LibreNMS so you should have already have the following configuration setup in your environment file (.env).

DB_HOST=HOSTNAME\nDB_DATABASE=DBNAME\nDB_USERNAME=DBUSER\nDB_PASSWORD=\"DBPASS\"\n
"},{"location":"Extensions/Authentication/#active-directory-authentication","title":"Active Directory Authentication","text":"

auth/general

lnms config:set auth_mechanism active_directory\n

Install php-ldap or php8.1-ldap, making sure to install the same version as PHP.

If you have issues with secure LDAP try setting

auth/ad

lnms config:set auth_ad_check_certificates 0\n

this will ignore certificate errors.

"},{"location":"Extensions/Authentication/#require-actual-membership-of-the-configured-groups","title":"Require actual membership of the configured groups","text":"

auth/ad

lnms config:set auth_ad_require_groupmembership 1\n

If you set auth_ad_require_groupmembership to 1, the authenticated user has to be a member of the specific group. Otherwise all users can authenticate, and will be either level 0 or you may set auth_ad_global_read to 1 and all users will have read only access unless otherwise specified.

"},{"location":"Extensions/Authentication/#old-account-cleanup","title":"Old account cleanup","text":"

Cleanup of old accounts is done by checking the authlog. You will need to set the number of days when old accounts will be purged AUTOMATICALLY by daily.sh.

Please ensure that you set the authlog_purge value to be greater than active_directory.users_purge otherwise old users won't be removed.

"},{"location":"Extensions/Authentication/#sample-configuration","title":"Sample configuration","text":"

auth/general

lnms config:set auth_mechanism active_directory\nlnms config:set auth_ad_url ldaps://server.example.com\nlnms config:set auth_ad_domain\nlnms config:set auth_ad_base_dn dc=example,dc=com\nlnms config:set auth_ad_check_certificates true\nlnms config:set auth_ad_binduser examplebinduser\nlnms config:set auth_ad_bindpassword examplepassword\nlnms config:set auth_ad_timeout 5\nlnms config:set auth_ad_debug false\nlnms config:set active_directory.users_purge 30\nlnms config:set auth_ad_require_groupmembership true\nlnms config:set auth_ad_groups.ad-admingroup.level 10\nlnms config:set auth_ad_groups.ad-usergroup.level 5\n

Replace ad-admingroup with your Active Directory admin-user group and ad-usergroup with your standard user group. It is highly suggested to create a bind user, otherwise \"remember me\", alerting users, and the API will not work.

"},{"location":"Extensions/Authentication/#active-directory-redundancy","title":"Active Directory redundancy","text":"

You can set two Active Directory servers by editing the auth_ad_url setting like this example:

auth/ad

lnms config:set auth_ad_url \"ldaps://dc1.example.com ldaps://dc2.example.com\"\n
"},{"location":"Extensions/Authentication/#active-directory-ldap-filters","title":"Active Directory LDAP filters","text":"

You can add an LDAP filter to be ANDed with the builtin user filter ((sAMAccountName=$username)).

The defaults are:

auth/ad

lnms config:set auth_ad_user_filter \"(objectclass=user)\"\nlnms config:set auth_ad_group_filter \"(objectclass=group)\"\n

This yields (&(objectclass=user)(sAMAccountName=$username)) for the user filter and (&(objectclass=group)(sAMAccountName=$group)) for the group filter.

"},{"location":"Extensions/Authentication/#selinux-configuration","title":"SELinux configuration","text":"

On RHEL / CentOS / Fedora, in order for LibreNMS to reach Active Directory, you need to allow LDAP requests in SELinux:

setsebool -P httpd_can_connect_ldap 1\n

"},{"location":"Extensions/Authentication/#ldap-authentication","title":"LDAP Authentication","text":"

auth/general

lnms config:set auth_mechanism ldap\n

Install php_ldap or php7.0-ldap, making sure to install the same version as PHP.

For the below, keep in mind the auth DN is composed using a string join of auth_ldap_prefix, the username, and auth_ldap_suffix. This means it needs to include = in the prefix and , in the suffix. So lets say we have a prefix of uid=, the user derp, and the suffix of ,ou=users,dc=foo,dc=bar, then the result is uid=derp,ou=users,dc=foo,dc=bar.

"},{"location":"Extensions/Authentication/#standard-config","title":"Standard config","text":"

auth/ldap

lnms config:set auth_ldap_server ldap.example.com\nlnms config:set auth_ldap_suffix ',ou=People,dc=example,dc=com'\nlnms config:set auth_ldap_groupbase 'ou=groups,dc=example,dc=com'\nlnms config:set auth_ldap_groups.admin.level 10\nlnms config:set auth_ldap_groups.pfy.level 5\nlnms config:set auth_ldap_groups.support.level 1\n
"},{"location":"Extensions/Authentication/#additional-options-usually-not-needed","title":"Additional options (usually not needed)","text":"

auth/ldap

lnms config:set auth_ldap_version 3\nlnms config:set auth_ldap_port 389\nlnms config:set auth_ldap_starttls true\nlnms config:set auth_ldap_prefix 'uid='\nlnms config:set auth_ldap_group 'cn=groupname,ou=groups,dc=example,dc=com'\nlnms config:set auth_ldap_groupmemberattr memberUid\nlnms config:set auth_ldap_groupmembertype username\nlnms config:set auth_ldap_uid_attribute uidnumber\nlnms config:set auth_ldap_timeout 5\nlnms config:set auth_ldap_emailattr mail\nlnms config:set auth_ldap_attr.uid uid\nlnms config:set auth_ldap_debug false\nlnms config:set auth_ldap_userdn true\nlnms config:set auth_ldap_userlist_filter service=informatique\nlnms config:set auth_ldap_wildcard_ou false\nlnms config:set auth_ldap_cacertfile /opt/librenms/ldap-ca-cert\nlnms config:set auth_ldap_ignorecert false\n
"},{"location":"Extensions/Authentication/#ldap-bind-user-optional","title":"LDAP bind user (optional)","text":"

If your ldap server does not allow anonymous bind, it is highly suggested to create a bind user, otherwise \"remember me\", alerting users, and the API will not work.

auth/ldap

lnms config:set auth_ldap_binduser ldapbind\nlnms config:set auth_ldap_binddn 'CN=John.Smith,CN=Users,DC=MyDomain,DC=com'\nlnms config:set auth_ldap_bindpassword password\n
"},{"location":"Extensions/Authentication/#ldap-server-redundancy","title":"LDAP server redundancy","text":"

You can set two LDAP servers by editing the auth_ldap_server like this example:

auth/ldap

lnms config:set auth_ldap_server ldaps://dir1.example.com ldaps://dir2.example.com\n

An example config setup for use with Jumpcloud LDAP as a service is:

auth/ldap

lnms config:set auth_mechanism ldap\nlnms config:set auth_ldap_version 3\nlnms config:set auth_ldap_server ldap.jumpcloud.com\nlnms config:set auth_ldap_port 389\nlnms config:set auth_ldap_prefix 'uid=';\nlnms config:set auth_ldap_suffix ',ou=Users,o={id},dc=jumpcloud,dc=com'\nlnms config:set auth_ldap_groupbase 'ou=Users,o={id},dc=jumpcloud,dc=com'\nlnms config:set auth_ldap_groupmemberattr member\nlnms config:set auth_ldap_groups.{group}.level 10\nlnms config:set auth_ldap_userdn true\n

Replace {id} with the unique ID provided by Jumpcloud. Replace {group} with the unique group name created in Jumpcloud. This field is case sensitive.

Note: If you have multiple user groups to define individual access levels replace the auth_ldap_groups line with the following:

auth/ldap

lnms config:set auth_ldap_groups.{admin_group}.level 10]\nlnms config:set auth_ldap_groups.global_readonly_group.level 5\n
"},{"location":"Extensions/Authentication/#selinux-configuration_1","title":"SELinux configuration","text":"

On RHEL / CentOS / Fedora, in order for LibreNMS to reach LDAP, you need to allow LDAP requests in SELinux:

setsebool -P httpd_can_connect_ldap 1\n

"},{"location":"Extensions/Authentication/#radius-authentication","title":"Radius Authentication","text":"

Please note that a mysql user is created for each user the logs in successfully. Users are assigned the user role by default, unless radius sends a reply attribute with a role.

You can change the default role(s) by setting

auth/radius

lnms config:set radius.default_roles '[\"csr\"]'\n

The attribute Filter-ID is a standard Radius-Reply-Attribute (string) that can be assigned a specially formatted string to assign a single role to the user.

The string to send in Filter-ID reply attribute must start with librenms_role_ followed by the role name. For example to set the admin role send librenms_role_admin.

The following strings correspond to the built-in roles, but any defined role can be used: - librenms_role_normal - Sets the normal user level. - librenms_role_admin - Sets the administrator level. - librenms_role_global-read - Sets the global read level

LibreNMS will ignore any other strings sent in Filter-ID and revert to default role that is set in your config.

$config['radius']['hostname']      = 'localhost';\n$config['radius']['port']          = '1812';\n$config['radius']['secret']        = 'testing123';\n$config['radius']['timeout']       = 3;\n$config['radius']['users_purge']   = 14;  // Purge users who haven't logged in for 14 days.\n$config['radius']['default_level'] = 1;  // Set the default user level when automatically creating a user.\n
"},{"location":"Extensions/Authentication/#radius-huntgroup","title":"Radius Huntgroup","text":"

Freeradius has a function called Radius Huntgroup which allows to send different attributes based on NAS. This may be utilized if you already use Filter-ID in your environment and also want to use radius with LibreNMS.

"},{"location":"Extensions/Authentication/#old-account-cleanup_1","title":"Old account cleanup","text":"

Cleanup of old accounts is done by checking the authlog. You will need to set the number of days when old accounts will be purged AUTOMATICALLY by daily.sh.

Please ensure that you set the $config['authlog_purge'] value to be greater than $config['radius']['users_purge'] otherwise old users won't be removed.

"},{"location":"Extensions/Authentication/#http-authentication","title":"HTTP Authentication","text":"

Config option: http-auth

LibreNMS will expect the user to have authenticated via your webservice already. At this stage it will need to assign a userlevel for that user which is done in one of two ways:

  • A user exists in MySQL still where the usernames match up.

  • A global guest user (which still needs to be added into MySQL:

$config['http_auth_guest'] = \"guest\";\n

This will then assign the userlevel for guest to all authenticated users.

"},{"location":"Extensions/Authentication/#http-authentication-ad-authorization","title":"HTTP Authentication / AD Authorization","text":"

Config option: ad-authorization

This module is a combination of http-auth and active_directory

LibreNMS will expect the user to have authenticated via your webservice already (e.g. using Kerberos Authentication in Apache) but will use Active Directory lookups to determine and assign the userlevel of a user. The userlevel will be calculated by using AD group membership information as the active_directory module does.

The configuration is the same as for the active_directory module with two extra, optional options: auth_ad_binduser and auth_ad_bindpassword. These should be set to a AD user with read capabilities in your AD Domain in order to be able to perform searches. If these options are omitted, the module will attempt an anonymous bind (which then of course must be allowed by your Active Directory server(s)).

There is also one extra option for controlling user information caching: auth_ldap_cache_ttl. This option allows to control how long user information (user_exists, userid, userlevel) are cached within the PHP Session. The default value is 300 seconds. To disable this caching (highly discourage) set this option to 0.

$config['auth_ad_binduser']     = \"ad_binduser\";\n$config['auth_ad_bindpassword'] = \"ad_bindpassword\";\n$config['auth_ldap_cache_ttl']  = 300;\n
"},{"location":"Extensions/Authentication/#http-authentication-ldap-authorization","title":"HTTP Authentication / LDAP Authorization","text":"

Config option: ldap-authorization

This module is a combination of http-auth and ldap

LibreNMS will expect the user to have authenticated via your webservice already (e.g. using Kerberos Authentication in Apache) but will use LDAP to determine and assign the userlevel of a user. The userlevel will be calculated by using LDAP group membership information as the ldap module does.

The configuration is similar to the ldap module with one extra option: auth_ldap_cache_ttl. This option allows to control how long user information (user_exists, userid, userlevel) are cached within the PHP Session. The default value is 300 seconds. To disabled this caching (highly discourage) set this option to 0.

"},{"location":"Extensions/Authentication/#standard-config_1","title":"Standard config","text":"
$config['auth_mechanism'] = 'ldap-authorization';\n$config['auth_ldap_server'] = 'ldap.example.com';               // Set server(s), space separated. Prefix with ldaps:// for ssl\n$config['auth_ldap_suffix'] = ',ou=People,dc=example,dc=com';   // appended to usernames\n$config['auth_ldap_groupbase'] = 'ou=groups,dc=example,dc=com'; // all groups must be inside this\n$config['auth_ldap_groups']['admin']['roles'] = ['admin'];             // set admin group to admin role\n$config['auth_ldap_groups']['pfy']['roles'] = ['global-read'];                // set pfy group to global read only role\n$config['auth_ldap_groups']['support']['roles'] = ['user'];            // set support group as a normal user\n
"},{"location":"Extensions/Authentication/#additional-options-usually-not-needed_1","title":"Additional options (usually not needed)","text":"
$config['auth_ldap_version'] = 3; # v2 or v3\n$config['auth_ldap_port'] = 389;                    // 389 or 636 for ssl\n$config['auth_ldap_starttls'] = True;               // Enable TLS on port 389\n$config['auth_ldap_prefix'] = 'uid=';               // prepended to usernames\n$config['auth_ldap_group']  = 'cn=groupname,ou=groups,dc=example,dc=com'; // generic group with level 0\n$config['auth_ldap_groupmemberattr'] = 'memberUid'; // attribute to use to see if a user is a member of a group\n$config['auth_ldap_groupmembertype'] = 'username';  // username type to find group members by, either username (default), fulldn or puredn\n$config['auth_ldap_emailattr'] = 'mail';            // attribute for email address\n$config['auth_ldap_attr.uid'] = 'uid';              // attribute to check username against\n$config['auth_ldap_userlist_filter'] = 'service=informatique'; // Replace 'service=informatique' by your ldap filter to limit the number of responses if you have an ldap directory with thousand of users\n$config['auth_ldap_cache_ttl'] = 300;\n
"},{"location":"Extensions/Authentication/#ldap-bind-user-optional_1","title":"LDAP bind user (optional)","text":"

If your ldap server does not allow anonymous bind, it is highly suggested to create a bind user, otherwise \"remember me\", alerting users, and the API will not work.

$config['auth_ldap_binduser'] = 'ldapbind'; // will use auth_ldap_prefix and auth_ldap_suffix\n#$config['auth_ldap_binddn'] = 'CN=John.Smith,CN=Users,DC=MyDomain,DC=com'; // overrides binduser\n$config['auth_ldap_bindpassword'] = 'password';\n
"},{"location":"Extensions/Authentication/#viewembedded-graphs-without-being-logged-into-librenms","title":"View/embedded graphs without being logged into LibreNMS","text":"

webui/graph

```bash lnms config:set allow_unauth_graphs_cidr ['127.0.0.1/32'] lnms config:set allow_unauth_graphs true

```

"},{"location":"Extensions/Authentication/#single-sign-on","title":"Single Sign-on","text":"

The single sign-on mechanism is used to integrate with third party authentication providers that are managed outside of LibreNMS - such as ADFS, Shibboleth, EZProxy, BeyondCorp, and others. A large number of these methods use SAML the module has been written assuming the use of SAML, and therefore these instructions contain some SAML terminology, but it should be possible to use any software that works in a similar way.

In order to make use of the single sign-on module, you need to have an Identity Provider up and running, and know how to configure your Relying Party to pass attributes to LibreNMS via header injection or environment variables. Setting these up is outside of the scope of this documentation.

As this module deals with authentication, it is extremely careful about validating the configuration - if it finds that certain values in the configuration are not set, it will reject access rather than try and guess.

"},{"location":"Extensions/Authentication/#basic-configuration","title":"Basic Configuration","text":"

To get up and running, all you need to do is configure the following values:

$config['auth_mechanism']        = \"sso\";\n$config['sso']['mode']           = \"env\";\n$config['sso']['group_strategy'] = \"static\";\n$config['sso']['static_level']   = 10;\n

This, along with the defaults, sets up a basic Single Sign-on setup that:

  • Reads values from environment variables
  • Automatically creates users when they're first seen
  • Automatically updates users with new values
  • Gives everyone privilege level 10

This happens to mimic the behaviour of http-auth, so if this is the kind of setup you want, you're probably better of just going and using that mechanism.

"},{"location":"Extensions/Authentication/#security","title":"Security","text":"

If there is a proxy involved (e.g. EZProxy, Azure AD Application Proxy, NGINX, mod_proxy) it's essential that you have some means in place to prevent headers being injected between the proxy and the end user, and also prevent end users from contacting LibreNMS directly.

This should also apply to user connections to the proxy itself - the proxy must not be allowed to blindly pass through HTTP headers. modsecurity_ should be considered a minimum, with a full WAF being strongly recommended. This advice applies to the IDP too.

The mechanism includes very basic protection, in the form of an IP whitelist with should contain the source addresses of your proxies:

$config['sso']['trusted_proxies'] = ['127.0.0.1/8', '::1/128', '192.0.2.0', '2001:DB8::'];\n

This configuration item should contain an array with a list of IP addresses or CIDR prefixes that are allowed to connect to LibreNMS and supply environment variables or headers.

"},{"location":"Extensions/Authentication/#advanced-configuration-options","title":"Advanced Configuration Options","text":""},{"location":"Extensions/Authentication/#user-attribute","title":"User Attribute","text":"

If for some reason your relying party doesn't store the username in REMOTE_USER, you can override this choice.

$config['sso']['user_attr'] = 'HTTP_UID';\n

Note that the user lookup is a little special - normally headers are prefixed with HTTP_, however this is not the case for remote user - it's a special case. If you're using something different you need to figure out of the HTTP_ prefix is required or not yourself.

"},{"location":"Extensions/Authentication/#automatic-user-createupdate","title":"Automatic User Create/Update","text":"

These are enabled by default:

$config['sso']['create_users'] = true;\n$config['sso']['update_users'] = true;\n

If these are not enabled, user logins will be (somewhat silently) rejected unless an administrator has created the account in advance. Note that in the case of SAML federations, unless release of the users true identity has been negotiated with the IDP, the username (probably ePTID) is not likely to be predicable.

"},{"location":"Extensions/Authentication/#personalisation","title":"Personalisation","text":"

If the attributes are being populated, you can instruct the mechanism to add additional information to the user's database entry:

$config['sso']['email_attr']    = \"mail\";\n$config['sso']['realname_attr'] = \"displayName\";\n$config['sso']['descr_attr']    = \"unscoped-affiliation\n
"},{"location":"Extensions/Authentication/#group-strategies","title":"Group Strategies","text":""},{"location":"Extensions/Authentication/#static","title":"Static","text":"

As used above, static gives every single user the same privilege level. If you're working with a small team, or don't need access control, this is probably suitable.

"},{"location":"Extensions/Authentication/#attribute","title":"Attribute","text":"
$config['sso']['group_strategy'] = \"attribute\";\n$config['sso']['level_attr']     = \"entitlement\";\n

If your Relying Party is capable of calculating the necessary privilege level, you can configure the module to read the privilege number straight from an attribute. sso_level_attr should contain the name of the attribute that the Relying Party exposes to LibreNMS - as long as sso_mode is correctly set, the mechanism should find the value.

"},{"location":"Extensions/Authentication/#group-map","title":"Group Map","text":"

This is the most flexible (and complex) way of assigning privileges.

$config['sso']['group_strategy']  = \"map\";\n$config['sso']['group_attr']      = \"member\";\n$config['sso']['group_level_map'] = ['librenms-admins' => 10, 'librenms-readers' => 1, 'librenms-billingcontacts' => 5];\n$config['sso']['group_delimiter'] = ';';\n

This mechanism expects to find a delimited list of groups within the attribute that sso_group_attr points to. This should be an associative array of group name keys, with privilege levels as values. The mechanism will scan the list and find the highest privilege level that the user is entitled to, and assign that value to the user.

If there are no matches between the user's groups and the sso_group_level_map, the user will be assigned the privilege level specified in the sso_static_level variable, with a default of 0 (no access). This feature can be used to provide a default access level (such as read-only) to all authenticated users.

Additionally, this format may be specific to Shibboleth; other relying party software may need changes to the mechanism (e.g. mod_auth_mellon may create pseudo arrays).

There is an optional value for sites with large numbers of groups:

$config['sso']['group_filter']  = \"/librenms-(.*)/i\";\n

This filter causes the mechanism to only consider groups matching a regular expression.

"},{"location":"Extensions/Authentication/#logout-behaviour","title":"Logout Behaviour","text":"

LibreNMS has no capability to log out a user authenticated via Single Sign-On - that responsibility falls to the Relying Party.

If your Relying Party has a magic URL that needs to be called to end a session, you can configure LibreNMS to direct the user to it:

# Example for Shibboleth\n$config['auth_logout_handler'] = '/Shibboleth.sso/Logout';\n\n# Example for oauth2-proxy\n$config['auth_logout_handler'] = '/oauth2/sign_out';\n

This option functions independently of the Single Sign-on mechanism.

"},{"location":"Extensions/Authentication/#complete-configuration","title":"Complete Configuration","text":"

This configuration works on my deployment with a Shibboleth relying party, injecting environment variables, with the IDP supplying a list of groups.

$config['auth_mechanism'] = 'sso';\n$config['auth_logout_handler'] = '/Shibboleth.sso/Logout';\n$config['sso']['mode'] = 'env';\n$config['sso']['create_users'] = true;\n$config['sso']['update_users'] = true;\n$config['sso']['realname_attr'] = 'displayName';\n$config['sso']['email_attr'] = 'mail';\n$config['sso']['group_strategy'] = 'map';\n$config['sso']['group_attr'] = 'member';\n$config['sso']['group_filter'] = '/(librenms-.*)/i';\n$config['sso']['group_delimiter'] = ';';\n$config['sso']['group_level_map'] = ['librenms-demo' => 11, 'librenms-globaladmin' => 10, 'librenms-globalread' => 5, 'librenms-lowpriv'=> 1];\n
"},{"location":"Extensions/Auto-Discovery/","title":"Auto Discovery Support","text":""},{"location":"Extensions/Auto-Discovery/#getting-started","title":"Getting Started","text":"

LibreNMS provides the ability to automatically add devices on your network, we can do this via a few methods which will be explained below and also indicate if they are enabled by default.

All discovery methods run when discovery runs (every 6 hours by default and within 5 minutes for new devices).

Please note that you need at least ONE device added before auto-discovery will work.

The first thing to do though is add the required configuration options to config.php.

"},{"location":"Extensions/Auto-Discovery/#snmp-details","title":"SNMP Details","text":"

To add devices automatically we need to know your snmp details, examples of SNMP v1, v2c and v3 are below:

// v1 or v2c\n$config['snmp']['community'][] = \"my_custom_community\";\n$config['snmp']['community'][] = \"another_community\";\n\n// v3\n$config['snmp']['v3'][0]['authlevel'] = 'authPriv';\n$config['snmp']['v3'][0]['authname'] = 'my_username';\n$config['snmp']['v3'][0]['authpass'] = 'my_password';\n$config['snmp']['v3'][0]['authalgo'] = 'SHA';\n$config['snmp']['v3'][0]['cryptopass'] = 'my_crypto';\n$config['snmp']['v3'][0]['cryptoalgo'] = 'AES';\n

These details will be attempted when adding devices, you can specify any mixture of these.

"},{"location":"Extensions/Auto-Discovery/#allowed-networks","title":"Allowed Networks","text":""},{"location":"Extensions/Auto-Discovery/#your-networks","title":"Your Networks","text":"

To add devices, we need to know what are your subnets so we don't go blindly attempting to add devices not under your control.

discovery/networks

lnms config:set nets.+ '192.168.0.0/24'\nlnms config:set nets.+ '172.2.4.0/22'\n
"},{"location":"Extensions/Auto-Discovery/#exclusions","title":"Exclusions","text":"

If you have added a network as above but a single device exists within it that you can't auto add, then you can exclude this with the following:

discovery/networks

lnms config:set autodiscovery.nets-exclude.+ '192.168.0.1/32'\n
"},{"location":"Extensions/Auto-Discovery/#additional-options","title":"Additional Options","text":""},{"location":"Extensions/Auto-Discovery/#discovering-devices-by-ip","title":"Discovering devices by IP","text":"

By default we don't add devices by IP address, we look for a reverse dns name to be found and add with that. If this fails and you would like to still add devices automatically then you will need to set $config['discovery_by_ip'] = true;

"},{"location":"Extensions/Auto-Discovery/#short-hostnames","title":"Short hostnames","text":"

If your devices only return a short hostname such as lax-fa0-dc01 but the full name should be lax-fa0-dc01.example.com then you can set

discovery/general

lnms config:set mydomain example.com\n
"},{"location":"Extensions/Auto-Discovery/#allow-duplicate-sysname","title":"Allow Duplicate sysName","text":"

By default we require unique sysNames when adding devices (this is returned over snmp by your devices). If you would like to allow devices to be added with duplicate sysNames then please set

discovery/discovery_modules

lnms config:set allow_duplicate_sysName true\n
"},{"location":"Extensions/Auto-Discovery/#discovery-methods","title":"Discovery Methods","text":"

Below are the methods for auto discovering devices. Each one can be enabled or disabled and may have additional configuration options.

"},{"location":"Extensions/Auto-Discovery/#arp","title":"ARP","text":"

Disabled by default.

Adds devices that are listed in another device's arp table. This module depends on the arp-table module being enabled and returning data.

To enable, switch on globally the discovery_modules.discovery-arp or per device within the Modules section.

discovery/discovery_modules

lnms config:set discovery_modules.discovery-arp true\n
"},{"location":"Extensions/Auto-Discovery/#xdp","title":"XDP","text":"

Enabled by default.

$config['autodiscovery']['xdp'] = false; to disable.

This includes FDP, CDP and LLDP support based on the device type.

The LLDP/xDP links with neighbours will always be discovered as soon as the discovery module is enabled. However, LibreNMS will only try to add the new devices discovered with LLDP/xDP if $config['autodiscovery']['xdp'] = true;.

Devices may be excluded from xdp discovery by sysName and sysDescr.

//Exclude devices by name\n$config['autodiscovery']['xdp_exclude']['sysname_regexp'][] = '/host1/';\n$config['autodiscovery']['xdp_exclude']['sysname_regexp'][] = '/^dev/';\n\n//Exclude devices by description\n$config['autodiscovery']['xdp_exclude']['sysdesc_regexp'][] = '/Vendor X/';\n$config['autodiscovery']['xdp_exclude']['sysdesc_regexp'][] = '/Vendor Y/';\n

Devices may be excluded from cdp discovery by platform.

//Exclude devices by platform(Cisco only)\n$config['autodiscovery']['cdp_exclude']['platform_regexp'][] = '/WS-C3750G/';\n

These devices are excluded by default:

$config['autodiscovery']['xdp_exclude']['sysdesc_regexp'][] = '/-K9W8/'; // Cisco Lightweight Access Point\n$config['autodiscovery']['cdp_exclude']['platform_regexp'][] = '/^Cisco IP Phone/'; //Cisco IP Phone\n
"},{"location":"Extensions/Auto-Discovery/#ospf","title":"OSPF","text":"

Enabled by default.

$config['autodiscovery']['ospf'] = false; to disable.

"},{"location":"Extensions/Auto-Discovery/#bgp","title":"BGP","text":"

Enabled by default.

$config['autodiscovery']['bgp'] = false; to disable.

This module is invoked from bgp-peers discovery module.

"},{"location":"Extensions/Auto-Discovery/#snmp-scan","title":"SNMP Scan","text":"

Apart from the aforementioned Auto-Discovery options, LibreNMS is also able to proactively scan a network for SNMP-enabled devices using the configured version/credentials.

SNMP Scan will scan nets by default and respects autodiscovery.nets-exclude.

To run the SNMP-Scanner you need to execute the snmp-scan.py from within your LibreNMS installation directory.

Here the script's help-page for reference:

usage: snmp-scan.py [-h] [-t THREADS] [-g GROUP] [-l] [-v] [--ping-fallback] [--ping-only] [-P] [network ...]\n\nScan network for snmp hosts and add them to LibreNMS.\n\npositional arguments:\n  network          CIDR noted IP-Range to scan. Can be specified multiple times\n                   This argument is only required if 'nets' config is not set\n                   Example: 192.168.0.0/24\n                   Example: 192.168.0.0/31 will be treated as an RFC3021 p-t-p network with two addresses, 192.168.0.0 and 192.168.0.1\n                   Example: 192.168.0.1/32 will be treated as a single host address\n\noptional arguments:\n  -h, --help       show this help message and exit\n  -t THREADS       How many IPs to scan at a time.  More will increase the scan speed, but could overload your system. Default: 32\n  -g GROUP         The poller group all scanned devices will be added to. Default: The first group listed in 'distributed_poller_group', or 0 if not specificed\n  -l, --legend     Print the legend.\n  -v, --verbose    Show debug output. Specifying multiple times increases the verbosity.\n  --ping-fallback  Add the device as an ICMP only device if it replies to ping but not SNMP.\n  --ping-only      Always add the device as an ICMP only device.\n  -P, --ping       Deprecated. Use --ping-fallback instead.\n
"},{"location":"Extensions/Auto-Discovery/#discovered-devices","title":"Discovered devices","text":"

Newly discovered devices will be added to the default_poller_group, this value defaults to 0 if unset.

When using distributed polling, this value can be changed locally by setting $config['default_poller_group'] in config.php or globally by using lnms config:set.

"},{"location":"Extensions/Availability-Map/","title":"Availability Map","text":"

LibreNMS has the following page to show an availability map:

  • Overview -> Maps -> Availability

This map will show all devices on a single page, with each device having either a box or a coloured square representing its status.

"},{"location":"Extensions/Availability-Map/#widget","title":"Widget","text":"

There is an availability map widget that can be added to a dashboard to give a quick overview of the status of all devices on the network.

"},{"location":"Extensions/Availability-Map/#settings","title":"Settings","text":"
# Set the compact view mode for the availability map\nlnms config:set webui.availability_map_compact false\n\n# Size of the box for each device in the availability map (not compact)\nlnms config:set webui.availability_map_box_size 165\n\n# Sort by status instead of hostname\nlnms config:set webui.availability_map_sort_status false\n\n# Show the device group drop-down on the availabiltiy map page\nlnms config:set webui.availability_map_use_device_groups true\n
"},{"location":"Extensions/Billing-Module/","title":"Billing Module","text":"

With the billing module you can create a bill, assign a quota to it and add ports to it. It then tracks the ports usage and shows you the usage in the bill, including any overage. Accounting by both total transferred data and 95th percentile is supported.

To enable and use the billing module you need to perform the following steps:

Edit config.php and add (or enable) the following line near the end of the config

$config['enable_billing'] = 1; # Enable Billing\n

Edit /etc/cron.d/librenms and add the following:

*/5 * * * * librenms /opt/librenms/poll-billing.php >> /dev/null 2>&1\n01  * * * * librenms /opt/librenms/billing-calculate.php >> /dev/null 2>&1\n

Create billing graphs as required.

"},{"location":"Extensions/Billing-Module/#data-retention","title":"Data Retention","text":"

Billing data is stored in the MySQL database, and you may wish to purge the detailed stats for old data (per-month totals will always be kept). To enable this, add the following to config.php:

$config['billing_data_purge'] = 12;     // Number of months to retain\n

Data for the last complete billing cycle will always be retained - only data older than this by the configured number of months will be removed. This task is performed in the daily cleanup tasks.

"},{"location":"Extensions/Billing-Module/#95th-percentile-calculation","title":"95th Percentile Calculation","text":"

For 95th Percentile billing, the default behavior is to use the highest of the input or output 95th Percentile calculation.

To instead use the combined total of inout + output to derive the 95th percentile, This can be changed on a per bill basis by setting 95th Calculation to \"Aggregate\".

To change the default option to Aggregate, add the following the config.php:

$config['billing']['95th_default_agg'] = 1;  // Set aggregate 95th as default\n

This configuration setting is cosmetic and only changes the default selected option when adding a new bill.

"},{"location":"Extensions/Component/","title":"About","text":"

The Component extension provides a generic database storage mechanism for discovery and poller modules. The Driver behind this extension was to provide the features of ports, in a generic manner to discovery/poller modules.

It provides a status (Nagios convention), the ability to Disable (do not poll), or Ignore (do not Alert).

"},{"location":"Extensions/Component/#database-structure","title":"Database Structure","text":"

The database structure contains the component table:

mysql> select * from component limit 1;\n+----+-----------+------+------------+--------+----------+--------+-------+\n| id | device_id | type | label      | status | disabled | ignore | error |\n+----+-----------+------+------------+--------+----------+--------+-------+\n|  9 |         1 | TEST | TEST LABEL |      0 |        1 |      1 |       |\n+----+-----------+------+------------+--------+----------+--------+-------+\n1 row in set (0.00 sec)\n

These fields are described below:

  • id - ID for each component, unique index
  • device_id - device_id from the devices table
  • type - name from the component_type table
  • label - Display label for the component
  • status - The status of the component, retrieved from the device
  • disabled - Should this component be polled?
  • ignore - Should this component be alerted on
  • error - Error message if in Alert state

The component_prefs table holds custom data in an Attribute/Value format:

mysql> select * from component_prefs limit 1;\n+----+-----------+-----------+-----------+\n| id | component | attribute | value     |\n+----+-----------+-----------+-----------+\n|  4 |         9 | TEST_ATTR | TEST_ATTR |\n+----+-----------+-----------+-----------+\n2 rows in set (0.00 sec)\n
"},{"location":"Extensions/Component/#reserved-fields","title":"Reserved Fields","text":"

When this data from both the component and component_prefs tables is returned in one single consolidated array, there is the potential for someone to attempt to set an attribute (in the component_prefs) table that is used in the component table. Because of this all fields of the component table are reserved, they cannot be used as custom attributes, if you update these the module will attempt to write them to the component table, not the component_prefs table.

"},{"location":"Extensions/Component/#using-components","title":"Using Components","text":"

Create an instance of the component class:

$COMPONENT = new LibreNMS\\Component();\n
"},{"location":"Extensions/Component/#retrieving-components","title":"Retrieving Components","text":"

Now you can retrieve an array of the available components:

$ARRAY = $COMPONENT->getComponents($DEVICE_ID, $OPTIONS);\n

getComponents takes 2 arguments:

  • DEVICE_ID or null for all devices.
  • OPTIONS - an array of various options.

getComponents will return an array containing components in the following format:

Array\n(\n    [X] => Array\n    (\n        [Y1] => Array\n        (\n            [device_id] => 1\n            [TEST_ATTR] => TEST_ATTR\n            [type] => TEST\n            [label] => TEST LABEL\n            [status] => 0\n            [ignore] => 1\n            [disabled] => 1\n            [error] =>\n        ),\n        [Y2] => Array\n        (\n            [device_id] => 1\n            [TEST_ATTR] => TEST_ATTR\n            [type] => TESTING\n            [label] => TEST LABEL\n            [status] => 0\n            [ignore] => 1\n            [disabled] => 0\n            [error] =>\n        ),\n    )\n)\n

Where X is the Device ID and Y1/Y2 is the Component ID. In the example above, TEST_ATTR is a custom field, the rest are reserved fields.

"},{"location":"Extensions/Component/#options","title":"Options","text":"

Options can be supplied to getComponents to influence which and how components are returned.

"},{"location":"Extensions/Component/#filtering","title":"Filtering","text":"

You can filter on any of the reserved fields. Filters are created in the following format:

$options['filter']['FIELD'] = array ('OPERATOR', 'CRITERIA');\n

Where:

  • FIELD - The reserved field to filter on
  • OPERATOR - 'LIKE' or '=', are we checking if the FIELD equals or contains the CRITERIA.
  • CRITERIA - The criteria to search on

There are 2 filtering shortcuts:

$DEVICE_ID is a synonym for:

$OPTIONS['filter']['device_id'] = array ('=', $DEVICE_ID);\n

$OPTIONS['type'] = $TYPE is a synonym for:

$OPTIONS['filter']['type'] = array ('=', $TYPE);\n
"},{"location":"Extensions/Component/#sorting","title":"Sorting","text":"

You can sort the records that are returned by specifying the following option:

$OPTIONS['sort'][FIELD] = 'DIRECTION';\n

Where Direction is one of:

  • ASC - Ascending, from Low to High
  • DESC - Descending, from High to Low
"},{"location":"Extensions/Component/#creating-components","title":"Creating Components","text":"

To create a new component, run the createComponent function.

$ARRAY = $COMPONENT->createComponent($DEVICE_ID, $TYPE);\n

createComponent takes 2 arguments:

  • DEVICE_ID - The ID of the device to attach the component to.
  • TYPE - The unique type for your module.

This will return a new, empty array with a component ID and Type set, all other fields will be set to defaults.

Array\n(\n    [1] => Array\n    (\n        [type] => TESTING\n        [label] =>\n        [status] => 1\n        [ignore] => 0\n        [disabled] => 0\n        [error] =>\n    )\n)\n
"},{"location":"Extensions/Component/#deleting-components","title":"Deleting Components","text":"

When a component is no longer needed, it can be deleted.

$COMPONENT->deleteComponent($COMPONENT_ID)\n

This will return True on success or False on failure.

"},{"location":"Extensions/Component/#editing-components","title":"Editing Components","text":"

To edit a component, the procedure is:

  1. Get the Current Components
  2. Edit the array
  3. Write the components
"},{"location":"Extensions/Component/#edit-the-array","title":"Edit the Array","text":"

Once you have a component array from getComponents the first thing to do is extract the components for only the single device you are editing. This is required because the setComponentPrefs function only saves a single device at a time.

$ARRAY = $COMPONENT->getComponents($DEVICE_ID, $OPTIONS);\n$ARRAY = $ARRAY[$DEVICE_ID];\n

Then simply edit this array to suit your needs. If you need to add a new Attribute/Value pair you can:

$ARRAY[COMPONENT_ID]['New Attribute'] = \"Value\";\n

If you need to delete a previously set Attribute/Value pair you can:

unset($ARRAY[COMPONENT_ID]['New Attribute']);\n

If you need to edit a previously set Attribute/Value pair you can:

$ARRAY[COMPONENT_ID]['Existing Attribute'] = \"New Value\";\n
"},{"location":"Extensions/Component/#write-the-components","title":"Write the components","text":"

To write component changes back to the database simply:

$COMPONENT->setComponentPrefs($DEVICE_ID, $ARRAY)\n

When writing the component array there are several caveats to be aware of, these are:

  • $ARRAY must be in the format of a single device ID - $ARRAY[$COMPONENT_ID][Attribute] = 'Value'; NOT in the multi device format returned by getComponents - $ARRAY[$DEVICE_ID][$COMPONENT_ID][Attribute] = 'Value';
  • You cannot edit the Component ID or the Device ID
  • reserved fields can not be removed
  • if a change is found an entry will be written to the eventlog.
"},{"location":"Extensions/Component/#api","title":"API","text":"

Component details are available via the API. Please see the API-Docs for details.

"},{"location":"Extensions/Component/#alerting","title":"Alerting","text":"

It is intended that discovery/poller modules will detect the status of a component during the polling cycle. Status is logged using the Nagios convention for status codes, where:

0 = Ok,\n1 = Warning,\n2 = Critical\n

If you are creating a poller module which can detect a fault condition simply set STATUS to something other than 0 and ERROR to a message that indicates the problem.

To actually raise an alert, the user will need to create an alert rule. To assist with this several Alerting Macro's have been created:

  • %macro.component_normal - A component that is not disabled or ignored and in a Normal state.
  • %macro.component_warning - A component that is not disabled or ignored and NOT in a Warning state.
  • %macro.component_critical - A component that is not disabled or ignored and NOT in a Critical state.

To raise alerts for components, the following rules could be created:

  • %macros.component_critical = \"1\" - To alert on all Critical components
  • %macros.component_critical = \"1\" && %component.type = \"<Type of Component>\" - To alert on all Critical components of a particular type.

If there is a particular component you would like excluded from alerting, simply set the ignore field to 1.

The data that is written to each alert when it is raised is in the following format:

COMPONENT_TYPE - LABEL - ERROR

"},{"location":"Extensions/Component/#example-code","title":"Example Code","text":"

To see an example of how the component module can used, please see the following modules:

  • Cisco CBQoS
  • includes/discovery/cisco-cbqos.inc.php
  • includes/polling/cisco-cbqos.inc.php
  • html/includes/graphs/device/cbqos_traffic.inc.php
  • Cisco OTV
  • includes/discovery/cisco-otv.inc.php
  • includes/polling/cisco-otv.inc.php
  • html/includes/graphs/device/cisco-otv-mac.inc.php
  • html/pages/routing/cisco-otv.inc.php
"},{"location":"Extensions/Custom-Map/","title":"Custom Map","text":"

LibreNMS has the ability to create custom maps to give a quick overview of parts of the network including up/down status of devices and link utilisation. These are also referred to as weather maps.

"},{"location":"Extensions/Custom-Map/#viewer","title":"Viewer","text":"

Once some maps have been created, they will be visible to any users who have read access to all devices on a given map. Custom maps are available through the Overview -> Maps -> Custom Maps menu.

Some key points about the viewer are:

  • Nodes will change colour if they are down or disabled
  • Links are only associated with a single network interface
  • Link utilisation can only be shown if the link speed is known
  • Link speed is decoded from SNMP if possible (Upload/Download) and defaults to the physical speed if SNMP data is not available, or cannot be decoded
  • Links will change colour as follows:
  • Black if the link is down, or the max speed is unknown
  • Green at 0% utilisation, with a gradual change to
  • Yellow at 50% utilisation, with a gradual change to
  • Orange at 75% utilisation, with a gradual change to
  • Red at 100% utilisation, with a gradual change to
  • Purple at 150% utilisation and above
"},{"location":"Extensions/Custom-Map/#viewer-url-options","title":"Viewer URL options","text":"

You can manually add the following parameters to a URL to alter the display of a custom map.

The following URL options are available:

  • bare=yes : Removes the control bar from the top of the page.
  • screenshot=yes : Removes all labels from the nodes and links

e.g. If you want bare and screenshot enabled, https://nmsserver/maps/custom/2 becomes https://nmsserver/maps/custom/2?bare=yes&screenshot=yes

"},{"location":"Extensions/Custom-Map/#editor","title":"Editor","text":"

To access the custom map editor, a user must be an admin. The editor is accessed through the Overview -> Maps -> Custom Map Editor menu.

Once you are in the editor, you will be given a drop-down list of all the custom maps so you can choose one to edit, or select \"Create New Map\" to create a new map.

"},{"location":"Extensions/Custom-Map/#map-settings","title":"Map Settings","text":"

When you create a new map, you will be presented with a page to set some global map settings. These are:

  • Name: The name for the map
  • Width: The width of the map in pixels
  • Height: The height of the map in pixels
  • Node Alignment: When devices are added to the map, this will align the devices to an invisible grid this many pixels wide, which can help to make the maps look better. This can be set to 0 to disable.
  • Background: An image (PNG/JPG) up to 2MB can be uploaded as a background.

These settings can be changed at any stage by clicking on the \"Edit Map Settings\" button in the top-left of the editor.

"},{"location":"Extensions/Custom-Map/#nodes","title":"Nodes","text":"

Once you have a map, you can start by adding \"nodes\" to the map. A node represents a device, or an external point in the network (e.g. the internet) To add a node, you click on the \"Add Node\" button in the control bar, then click on the map area where you want to add the node. You will then be aked for the following information:

  • Label: The text to display on this point in the network
  • Device: If this node represents a device, you can select the device from the drop-down. This will overwrite the label, which you can then change if you want to.
  • Style: You can select the style of the node. If a device has been selected you can choose the LibreNMS icon by choosing \"Device Image\". You can also choose \"Icon\" to select an image for the device.
  • Icon: If you choose \"Icon\" in the style box, you can select from a list of images to represent this node

There are also options to choose the size and colour of the node and the font.

Once you have finished choosing the options for the node, you can press Save to add it to the map. NOTE: This does not save anything to the database immediately. You need to click on the \"Save Map\" button in the top-right to save your changes to the database.

You can edit a node at any time by selecting it on the map and clicking on the \"Edit Node\" button in the control bar.

You can also modify the default settings for all new nodes by clicking on the \"Edit Node Default\" button at the top of the page.

"},{"location":"Extensions/Custom-Map/#edges","title":"Edges","text":"

Once you have 2 or more nodes, you can add links between the nodes. These are called edges in the editor. To add a link, click on the \"Add Edge\" button in the control bar, then click on one of the nodes you want to link and drag the cursor to the second node that you want to link. You will then be prompted for the following information:

  • From: The node that the link runs from (it will default to first node you selected)
  • To: The node that the link runs to (it will default to the second node you selected)
  • Port: If the From or To node is linked to a device, you can select an interface from one of the devices and the custom map will show traffic utilisation for the selected interface.
  • Reverse Port Direction: If the selected port displays data in the wrong direction for the link, you can reverse it by toggling this option.
  • Line Style: You can try different line styles, especially if you are running multiple links between the same 2 nodes
  • Show percent usage: Choose whether to have text on the lines showing the link utilisation as a percentage
  • Recenter Line: If you tick this box, the centre point of the line will be moved back to half way between the 2 nodes when you click on the save button.

Once you have finished choosing the options for the node, you can press Save to add it to the map. NOTE: This does not save anything to the database immediately. You need to click on the \"Save Map\" button in the top-right to save your changes to the database.

Once you press save, you it will create 3 objects on the screen, 2 arrows and a round node in the middle. Having the 3 objects allows you to move the mid point of the line off centre, and also allows us to display bandwidth information for both directions of the link.

You can edit an edge at any time by selecting it on the map and clicking on the \"Edit Edge\" button in the control bar.

You can also modify the default settings for all new edges by clicking on the \"Edit Edge Default\" button at the top of the page.

"},{"location":"Extensions/Custom-Map/#re-render","title":"Re-Render","text":"

When you drag items around the map, some of the lines will bend. This will cause a \"Re-Render Map\" button to appear at the top-right of the page. This button can be clicked on to cause all lines to be re-drawn the way they will be shown in the viewer.

"},{"location":"Extensions/Custom-Map/#save-map","title":"Save Map","text":"

Once you are happy with a set of changes that you have made, you can click on the \"Save Map\" button in the top-right of the page to commit changes to the database. This will cause anyone viewing the map to see the new version the next time their page refreshes.

"},{"location":"Extensions/Custom-Map/#adding-images","title":"Adding Images","text":"

You can add your own images to use on the custom map by copying files into the html/images/custommap/icons/ directory. Any files with a .svg, .png or .jpg extension will be shown in the image selection drop-down in the custom map editor.

"},{"location":"Extensions/Customizing-the-Web-UI/","title":"Customizing the Web UI","text":""},{"location":"Extensions/Customizing-the-Web-UI/#custom-menu-entry","title":"Custom menu entry","text":"

Create the file resources/views/menu/custom.blade.php

Example contents:

<li class=\"dropdown\">\n    <a href=\"#\" class=\"dropdown-toggle\" data-hover=\"dropdown\" data-toggle=\"dropdown\"><i class=\"fa fa-star fa-fw fa-lg fa-nav-icons hidden-md\" aria-hidden=\"true\"></i>\n        <span class=\"hidden-sm\">Custom Menu</span></a>\n    <ul class=\"dropdown-menu\">\n        @admin\n            <li><a href=\"plugins/Weathermap/output/history/index.html\"><i class=\"fa fa-film fa-fw fa-lg\" aria-hidden=\"true\"></i> Weathermap Animation</a></li>\n            <li role=\"presentation\" class=\"divider\"></li>\n            <li><a href=\"#\"><i class=\"fa fa-database fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 1</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-smile-o fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 2</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-anchor fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 3</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-plug fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 4</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-code-fork fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 5</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-truck fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 63</a></li>\n        @else\n            <li><a href=\"#\">You need admin rights to see this</a></li>\n        @endadmin\n    </ul>\n</li>\n
"},{"location":"Extensions/Customizing-the-Web-UI/#custom-device-menu-action","title":"Custom device menu action","text":"

You can add custom external links in the menu on the device page.

This feature allows you to easily link applications to related systems, as shown in the example of Open-audIT.

The url value is parsed by the Laravel Blade templating engine. You can access device variables such as $device->hostname, $device->sysName and use full PHP.

settings/webui/device

lnms config:set html.device.links.+ '{\"url\": \"http://atssrv/open-audit/index/devices/{{ $device->sysName }}\", \"title\": \"Open-AudIT\"}'\n
Field Description url Url blade template resulting in valid url. Required. title Title text displayed in the menu. Required. icon Font Awesome icon class. Default: fa-external-link external Open link in new window. Default: true action Show as action on device list. Default: false"},{"location":"Extensions/Customizing-the-Web-UI/#launching-windows-programs-from-the-librenms-device-menu","title":"Launching Windows programs from the LibreNMS device menu","text":"

You can launch windows programs from links in LibreNMS, but it does take some registry entries on the client device. Save the following as winbox.reg, edit for your winbox.exe path and double click to add to your registry.

Windows Registry Editor Version 5.00\n[HKEY_CLASSES_ROOT\\winbox]\n@=\"URL:Winbox Protocol\"\n\"URL Protocol\"=\"\"\n[HKEY_CLASSES_ROOT\\winbox\\shell]\n[HKEY_CLASSES_ROOT\\winbox\\shell\\open]\n[HKEY_CLASSES_ROOT\\winbox\\shell\\open\\command]\n@=\"C:\\Windows\\System32\\WindowsPowerShell\u000b1.0\\powershell.exe -Command \"$val='%l'; $val = $val.TrimEnd('/');if ($val.StartsWith('winbox://' { $val = $val.SubString(9) }; & 'C:\\Program Files\\winbox64.exe' \"$val\"\"\"\n

Now we can use that in the device menu entry to open winbox.

settings/webui/device

lnms config:set html.device.links.+ '{\"url\": \"winbox://{{ $device->hostname }}\", \"title\": \"Winbox\"}'\n
"},{"location":"Extensions/Customizing-the-Web-UI/#setting-the-primary-device-menu-action","title":"Setting the primary device menu action","text":"

You can change the icon that is clickable in the device without having to open the dropdown menu. The primary button is edit device by default.

settings/webui/device

lnms config:set html.device.primary_link web\n
Value Description edit Edit device web Connect to the device via https/http ssh launch ssh:// protocol to the device, make sure you have a handler registered telnet launch telnet:// protocol to the device capture Link to the device capture page custom1 Custom Link 1 custom2 Custom Link 2 custom3 Custom Link 3 custom4 Custom Link 4 custom5 Custom Link 5 custom6 Custom Link 6 custom7 Custom Link 7 custom8 Custom Link 8

!!! Custom http, ssh, telnet ports

Custom ports can be set through the device setting misc tab and will be appended to the Uri. Empty value will not append anything and automatically default to the standard. - custom ssh port set to 2222 will result in ssh://10.0.0.0:2222 - custom telnet port set to 2323 will result in telnet://10.0.0.0:2323

"},{"location":"Extensions/Dashboards/","title":"Dashboards","text":"

Create customised dashboards in LibreNMS per user. You can share dashboards with other users. You can also make a custom dashboard and default it for all users in LibreNMS.

Example Dashboard

"},{"location":"Extensions/Dashboards/#widgets","title":"Widgets","text":"

LibreNMS has a whole list of Widgets to select from.

  • Alerts Widget: Displays all alert notifications.
  • Availability Map: Displays all devices with colored tiles, green up, yellow for warning (device has been restarted in last 24 hours), red for down. You can also list all services and ignored/disabled devices in this widget.
  • Components Status: List all components Ok state, Warning state, Critical state.
  • Device Summary horizontal: List device totals, up, down, ignored, disabled. Same for ports and services.
  • Device Summary vertical: List device totals, up, down, ignored, disabled. Same for ports and services.
  • Eventlog: Displays all events with your devices and LibreNMS.
  • External Image: can be used to show external images on your dashboard. Or images from inside LibreNMS.
  • Globe Map: Will display map of the globe.
  • Graph: Can be used to display graphs from devices.
  • Graylog: Displays all Graylog's syslog entries.
  • Notes: use for html tags, embed links and external web pages. Or just notes in general.
  • Server Stats: Will display gauges for CPU, Memory, Storage usage. Note the device type has to be listed as \"Server\".
  • Syslog: Displays all syslog entries.
  • Top Devices: By Traffic, or Uptime, or Response time, or Poller Duration, or Processor load, or Memory Usage, or Storage Usage.
  • Top Interfaces: Lists top interfaces by traffic utilization.
  • World Map: displays all your devices locations. From syslocation or from override sysLocation.

List of Widgets:

"},{"location":"Extensions/Dashboards/#dashboard-permissions","title":"Dashboard Permissions","text":"
  • Private: Sets the dashboard to only the user that created the dashboard can view and edit.
  • Shared Read: Sets the dashboard to allow other users to view the dashboard, but cant make changes to the dashboard.
  • Shared: Allows all users to view the dashboard and make changes.
"},{"location":"Extensions/Dashboards/#setting-a-global-default-dashboard","title":"Setting a global default dashboard","text":"

Step 1: Set the dashboard to either shared read or shared, depending on what you want the users access to change.

Step 2: Then go to Settings -> WebUI settings -> Dashboard Settings and set the global default dashboard.

"},{"location":"Extensions/Dashboards/#setting-embedded-webpage","title":"Setting embedded webpage","text":"

Using the Notes Widget.

<iframe src=\"your_url\" frameBorder=\"0\" width=\"100%\" height = \"100%\">\n  <p>Your browser does not support iframes.</p>\n</iframe>\n

Note you may need to play with the width and height and also size your widget properly.

src=\"url\" needs to be URL to webpage you are linking to. Also some web pages may not support html embedded or iframe.

"},{"location":"Extensions/Dashboards/#how-to-create-ports-graph","title":"How to create ports graph","text":"

In the dashboard, you want to create an interface graph select the widget called

'Graph' then select \"Port\" -> \"Bits\"

Note: you can map the port by description or the alias or by port id. You will need to know this in order to map the port to the graph.

"},{"location":"Extensions/Dashboards/#dimension-parameter-replacement-for-generic-image-widget","title":"Dimension parameter replacement for Generic-image widget","text":"

When using the Generic-image widget you can provide the width and height of the widget with your request. This will ensure that the image will fit nicely with the dimensions if the Generic-image widget. You can add @AUTO_HEIGHT@ and @AUTO_WIDTH@ to the Image URL as parameters.

Examples:

  • http://librenms.example.com/graph.php?id=333%2C444&type=multiport_bits_separate&legend=no&absolute=1&from=-14200&width=@AUTO_WIDTH@&height=@AUTO_HEIGHT@
  • http://example.com/myimage.php?size=@AUTO_WIDTH@x@AUTO_HEIGHT@
"},{"location":"Extensions/Dell-OpenManage/","title":"Dell OpenManage Support","text":"

For Dell OpenManage support you will need to install Dell OpenManage (yeah - really :)) (minimum 5.1) onto the device you want to monitor. Ensure that net-snmp is using srvadmin, you should see something similar to:

master agentx\nview all included .1\naccess notConfigGroup \"\" any noauth exact all none none\nsmuxpeer .1.3.6.1.4.1.674.10892.1\n

Restart net-snmp:

service snmpd restart\n

Ensure that srvadmin is started, this is usually done by executing:

/opt/dell/srvadmin/sbin/srvadmin-services.sh start\n

Once this has been done, add the device to LibreNMS as normal and you will start to receive Temperatures and Fan speed data.

"},{"location":"Extensions/Dell-OpenManage/#windows","title":"Windows","text":"

Download OpenManage from Dell's support page Link and install OpenManage on your windows server. Make sure you have SNMP setup and running on your windows server.

"},{"location":"Extensions/Dependency-Map/","title":"Dependency Map","text":"

LibreNMS has the ability to show you a dynamic network map based on device dependencies that have been configure. These maps are accessed through the following menu options:

  • Overview -> Maps -> Device Dependency
  • Overview -> Maps -> Device Groups Dependencies
"},{"location":"Extensions/Dependency-Map/#settings","title":"Settings","text":"

The map display can be configured by altering the VisJS-Config.md

"},{"location":"Extensions/Device-Groups/","title":"Grouping Devices","text":"

LibreNMS supports grouping your devices together in much the same way as you can configure alerts. This document will hopefully help you get started.

"},{"location":"Extensions/Device-Groups/#dynamic-groups","title":"Dynamic Groups","text":""},{"location":"Extensions/Device-Groups/#rule-editor","title":"Rule Editor","text":"

The rule is based on the MySQL structure your data is in. Such as tablename.columnname. If you already know the entity you want, you can browse around inside MySQL using show tables and desc <tablename>.

As a working example and a common question, let's assume you want to group devices by hostname. If your hostname format is dcX.[devicetype].example.com. You would use the field devices.hostname.

If you want to group them by device type, you would add a rule for routers of devices.hostname endswith rtr.example.com.

If you want to group them by DC, you could use the rule devices.hostname regex dc1\\..*\\.example\\.com (Don't forget to escape periods in the regex)

"},{"location":"Extensions/Device-Groups/#static-groups","title":"Static Groups","text":"

You can create static groups (and convert dynamic groups to static) to put specific devices in a group. Just select static as the type and select the devices you want in the group.

You can now select this group from the Devices -> All Devices link in the navigation at the top. You can also use the group to map alert rules to by creating an alert mapping Overview -> Alerts -> Rule Mapping.

"},{"location":"Extensions/Dispatcher-Service/","title":"Dispatcher Service","text":"

Status: Release Candidate

The LibreNMS dispatcher service (librenms-service.py) is a new method of running the poller service at set times. It does not replace the php scripts, just the cron entries running them.

"},{"location":"Extensions/Dispatcher-Service/#external-requirements","title":"External Requirements","text":""},{"location":"Extensions/Dispatcher-Service/#a-recent-version-of-python","title":"A recent version of Python","text":"

The LibreNMS service requires Python 3 and some features require behaviour only found in Python3.4+.

"},{"location":"Extensions/Dispatcher-Service/#python-modules","title":"Python modules","text":"
  • PyMySQL is recommended as it requires no C compiler to install. MySQLclient can also be used, but does require compilation.
  • python-dotenv .env loader
  • redis-py 4.0+ and Redis 5.0+ server (if using distributed polling)
  • psutil

These can be obtained from your OS package manager, or from PyPI with the below commands.

pip3 install -r requirements.txt\n
"},{"location":"Extensions/Dispatcher-Service/#redis-distributed-polling","title":"Redis (distributed polling)","text":"

If you want to use distributed polling, you'll need a Redis instance to coordinate the nodes. It's recommended that you do not share the Redis database with any other system - by default, Redis supports up to 16 databases (numbered 0-15). You can also use Redis on a single host if you want

It's strongly recommended that you deploy a resilient cluster of redis systems, and use redis-sentinel.

You should not rely on the password for the security of your system. See https://redis.io/topics/security

"},{"location":"Extensions/Dispatcher-Service/#memcached-distributed-polling","title":"Memcached (distributed polling)","text":"

LibreNMS can still use memcached as a locking mechanism when using distributed polling. So you can configure memcached for this purpose unless you have updates disabled.

See Locking Mechanisms at https://docs.librenms.org/Extensions/Distributed-Poller/

"},{"location":"Extensions/Dispatcher-Service/#mysql","title":"MySQL","text":"

You should already have this, but the pollers do need access to the SQL database. The LibreNMS service runs faster and more aggressively than the standard poller, so keep an eye on the number of open connections and other important health metrics.

"},{"location":"Extensions/Dispatcher-Service/#configuration","title":"Configuration","text":"

Connection settings are required in .env. The .env file is generated after composer install and APP_KEY and NODE_ID are set. Remember that the APP_KEY value must be the same on all your pollers.

#APP_KEY=   #Required, generated by composer install\n#NODE_ID=   #Required, generated by composer install\n\nDB_HOST=localhost\nDB_DATABASE=librenms\nDB_USERNAME=librenms\nDB_PASSWORD=\n
"},{"location":"Extensions/Dispatcher-Service/#distributed-polling-configuration","title":"Distributed Polling Configuration","text":"

Once you have your Redis database set up, configure it in the .env file on each node. Configure the redis cache driver for distributed locking.

There are a number of options - most of them are optional if your redis instance is standalone and unauthenticated (neither recommended).

##\n## Standalone\n##\nREDIS_HOST=127.0.0.1\nREDIS_PORT=6379\nREDIS_DB=0\nREDIS_TIMEOUT=60\n\n# If requirepass is set in redis set everything above as well as: (recommended)\nREDIS_PASSWORD=PasswordGoesHere\n\n# If ACL's are in use, set everything above as well as: (highly recommended)\nREDIS_USERNAME=UsernameGoesHere\n\n##\n## Sentinel\n##\nREDIS_SENTINEL=redis-001.example.org:26379,redis-002.example.org:26379,redis-003.example.org:26379\nREDIS_SENTINEL_SERVICE=mymaster\n\n# If requirepass is set in sentinel, set everything above as well as: (recommended)\nREDIS_SENTINEL_PASSWORD=SentinelPasswordGoesHere\n\n# If ACL's are in use, set everything above as well as: (highly recommended)\nREDIS_SENTINEL_USERNAME=SentinelUsernameGoesHere\n

For more information on ACL's, see https://redis.io/docs/management/security/acl/

Note that if you use Sentinel, you may still need REDIS_PASSWORD, REDIS_USERNAME, REDIS_DB and REDIS_TIMEOUT - Sentinel just provides the address of the instance currently accepting writes and manages failover. It's possible (and recommended) to have authentication both on Sentinel and the managed Redis instances.

"},{"location":"Extensions/Dispatcher-Service/#basic-configuration","title":"Basic Configuration","text":"

Additional configuration settings can be set in your config.

The defaults are shown here - it's recommended that you at least tune the number of workers.

poller/distributed

lnms config:set service_poller_workers 24\nlnms config:set service_services_workers 8\nlnms config:set service_discovery_workers 16\n

Optional Settings

poller/distributed

lnms config:set service_poller_frequency 300\nlnms config:set service_services_frequency 300\nlnms config:set service_discovery_frequency 21600\nlnms config:set service_billing_frequency 300\nlnms config:set service_billing_calculate_frequency 60\nlnms config:set service_poller_down_retry 60\nlnms config:set service_loglevel INFO\nlnms config:set service_update_frequency 86400\n

There are also some SQL options, but these should be inherited from your LibreNMS web UI configuration.

Logs are sent to the system logging service (usually journald or rsyslog) - see https://docs.python.org/3/library/logging.html#logging-levels for the options available.

$config['distributed_poller']                    = true;            # Set to true to enable distributed polling\n$config['distributed_poller_name']               = php_uname('n');  # Uniquely identifies the poller instance\n$config['distributed_poller_group']              = 0;               # Which group to poll\n
"},{"location":"Extensions/Dispatcher-Service/#tuning-the-number-of-workers","title":"Tuning the number of workers","text":"

See https://your_librenms_install/poller

You want to keep Consumed Worker Seconds comfortably below Maximum Worker Seconds. The closer the values are to each other, the flatter the CPU graph of the poller machine. Meaning that you are utilizing your CPU resources well. As long as Consumed WS stays below Maximum WS and Devices Pending is 0, you should be ok.

If Consumed WS is below Maximum WS and Devices Pending is > 0, your hardware is not up to the task.

Maximum WS equals the number of workers multiplied with the number of seconds in the polling period. (default 300)

"},{"location":"Extensions/Dispatcher-Service/#fast-ping","title":"Fast Ping","text":"

The fast ping scheduler is disabled by default. You can enable it by setting the following:

$config['service_ping_enabled'] = true;\n
"},{"location":"Extensions/Dispatcher-Service/#watchdog","title":"Watchdog","text":"

The watchdog scheduler is disabled by default. You can enable it by setting the following:

$config['service_watchdog_enabled'] = true;\n

The watchdog scheduler will check that the poller log file has been written to within the last poll period. If there is no change to the log file since, the watchdog will restart the polling service. The poller log file is set by $config['log_file'] and defaults to ./logs/librenms.log

"},{"location":"Extensions/Dispatcher-Service/#cron-scripts","title":"Cron Scripts","text":"

Once the LibreNMS service is installed, the cron scripts used by LibreNMS to start alerting, polling, discovery and maintenance tasks are no longer required and must be disabled either by removing or commenting them out. The service handles these tasks when enabled.

"},{"location":"Extensions/Dispatcher-Service/#service-installation","title":"Service Installation","text":"

A systemd unit file is provided - You must adapt ExecStart and WorkingDirectory if you did not install librenms in /opt/librenms

The sysv and upstart init scripts could also be used with a little modification.

"},{"location":"Extensions/Dispatcher-Service/#systemd-service","title":"systemd service","text":"

A systemd unit file can be found in misc/librenms.service. To install run:

cp /opt/librenms/misc/librenms.service /etc/systemd/system/librenms.service && systemctl enable --now librenms.service\n

"},{"location":"Extensions/Dispatcher-Service/#systemd-service-with-watchdog","title":"systemd service with watchdog","text":"

This service file is an alternative to the above service file. It uses the systemd WatchdogSec= option to restart the service if it does not receive a keep-alive from the running process.

A systemd unit file can be found in misc/librenms-watchdog.service. To install run:

cp /opt/librenms/misc/librenms-watchdog.service /etc/systemd/system/librenms.service && systemctl enable --now librenms.service\n

This requires: python3-systemd (or python-systemd on older systems) or https://pypi.org/project/systemd-python/ If you run this systemd service without python3-systemd it will restart every 30 seconds.

"},{"location":"Extensions/Dispatcher-Service/#os-specific-instructions","title":"OS-Specific Instructions","text":""},{"location":"Extensions/Dispatcher-Service/#rhelcentos","title":"RHEL/CentOS","text":"

To get the LibreNMS service running under python3.4+ on RHEL-derivatives with minimal fuss, you can use the software collections build:

First, enable SCL's on your system:

"},{"location":"Extensions/Dispatcher-Service/#centos-7","title":"CentOS 7","text":"
# yum install centos-release-scl\n
"},{"location":"Extensions/Dispatcher-Service/#rhel-7","title":"RHEL 7","text":"
# subscription-manager repos --enable rhel-server-rhscl-7-rpms\n

Then install and configure the runtime and service:

# yum install gcc rh-python36 rh-python36-python-devel epel-release\n# yum --enablerepo=remi install redis\n# vi /opt/librenms/config.php\n# vi /etc/redis.conf\n# systemctl enable --now redis.service\n# scl enable rh-python36 bash\n# change directory to librenms (default /opt/librenms)\n# pip3 install -r requirements.txt\n# cp /opt/librenms/misc/librenms.service.scl /etc/systemd/system/librenms.service\n# systemctl enable --now librenms.service\n

If you want to use another version of python 3, change rh-python36 in the unit file and the commands above to match the name of the replacement scl.

"},{"location":"Extensions/Dispatcher-Service/#debianubuntu","title":"Debian/Ubuntu","text":""},{"location":"Extensions/Dispatcher-Service/#debian-11-bullseye","title":"Debian 11 (Bullseye)","text":"

Warning: Bullseye provide PHP 7.4 that is too old to run LibreNMS.

"},{"location":"Extensions/Dispatcher-Service/#debian-12-bookworm","title":"Debian 12 (Bookworm)","text":"

Install dependancies

apt install python3 python3-mysqldb python3-dotenv\n

Add the python3-systemd package for service with watchdog.

"},{"location":"Extensions/Distributed-Poller/","title":"Distributed Poller","text":"

A normal install contains all parts of LibreNMS:

  • Poller/Discovery/etc workers
  • RRD (Time series data store) *
  • Database *
  • Webserver (Web UI/API) *

* may only be installed on one server (however, some can be clustered)

Distributed Polling allows the workers to be spread across additional servers for horizontal scaling. Distributed polling is not intended for remote polling.

Devices can be grouped together into a poller_group to pin these devices to a single or a group of designated pollers.

All pollers need to write to the same set of RRD files, preferably via RRDcached.

It is also a requirement that at least one locking service is in place to which all pollers can connect. There are currently three locking mechanisms available

  • memcached
  • redis (preferred)
  • sql locks (default)

All of the above locking mechanisms are natively supported in LibreNMS. If none are specified, it will default to using SQL.

"},{"location":"Extensions/Distributed-Poller/#requirements-for-distributed-polling","title":"Requirements for distributed polling","text":"

These requirements are above the normal requirements for a full LibreNMS install.

  • rrdtool version 1.4 or above
  • At least one locking mechanism configured
  • a rrdcached install

By default, all hosts are shared and have the poller_group = 0. To pin a device to a poller, set it to a value greater than 0 and set the same value in the poller's config with distributed_poller_group. One can also specify a comma separated string of poller groups in distributed_poller_group. The poller will then poll devices from any of the groups listed. If new devices get added from the poller they will be assigned to the first poller group in the list unless the group is specified when adding the device.

The following is a standard config, combined with a locking mechanism below:

poller/distributed

lnms config:set distributed_poller true\nlnms config:set distributed_poller_group 0\n

If you want to customise the hostname for the poller then you will need to set this in config.php:

$config['distributed_poller_name']           = php_uname('n');\n
"},{"location":"Extensions/Distributed-Poller/#locking-mechanisms","title":"Locking mechanisms","text":"

Pick one of the following setups, do not use all of them at the same time.

"},{"location":"Extensions/Distributed-Poller/#using-redis","title":"Using REDIS","text":"

In your .env file you will need to specify a redis server, port and the driver.

REDIS_HOST=HOSTNAME or IP\nREDIS_PORT=6379\nCACHE_DRIVER=redis\n
"},{"location":"Extensions/Distributed-Poller/#using-memcached","title":"Using Memcached","text":"

Preferably you should set the memcached server settings via the web UI. Under Settings > Global Settings > Distributed poller, you fill out the memcached host and port, and then in your .env file you will need to add:

CACHE_DRIVER=memcached\n
If you want to use memcached, you will also need to install an additional Python 3 python-memcached package.

"},{"location":"Extensions/Distributed-Poller/#example-setups","title":"Example Setups","text":""},{"location":"Extensions/Distributed-Poller/#openstack","title":"OpenStack","text":"

Below is an example setup based on a real deployment which at the time of writing covers over 2,500 devices and 50,000 ports. The setup is running within an OpenStack environment with some commodity hardware for remote pollers. Here's a diagram of how you can scale LibreNMS out:

"},{"location":"Extensions/Distributed-Poller/#esxi","title":"ESXi","text":"

This is a distributed setup that I created for a regional hybrid ISP (fixed wireless/fiber optic backhaul). It was created at around the ~4,000 device mark to transition from multiple separate instances to one more central. When I left the company, it was monitoring: * 10,800 devices * 307,700 ports * 37,000 processors * 17,000 wireless sensors * ~480,000 other objects/sensors.

As our goal was more to catch alerts and monitor overall trends we went with a 10 minute polling cycle. Polling the above would take roughly 8 minutes and 120GHz worth of CPU across all VMs. CPUs were older Xeons (E5). The diagram below shows the CPU and RAM utilization of each VM during polling. Disk space utilization for SQL/RRD is also included.

Device discovery was split off into its own VM as that process would take multiple hours.

Workers were assigned in the following way:

  • Web/RRD Server:
  • alerting: 1
  • billing: 2
  • discovery: 0
  • ping: 1
  • poller: 10
  • services: 16
  • Discovery Server:
  • alerting: 1
  • billing: 2
  • discovery: 60
  • ping: 1
  • poller: 5
  • services: 8
  • Pollers
  • alerting: 1
  • billing: 2
  • discovery: 0
  • ping: 1
  • poller: 40
  • services: 8

Each poller had on average 19,500/24,000 worker seconds consumed.

RRDCached is incredibly important; this setup ran on spinning disks due to the wonders of caching.

I very strongly recommend setting up recursive DNS on your discovery and polling servers. While I used DNSMASQ there are many options.

SQL tuner will help you quite a bit. You'll also want to increase your maximum connections amount to support the pollers. This setup was at 500. Less important, but putting ~12GB of the database in RAM was reported to have helped web UI performance as well as some DB-heavy Tableau reports. RAM was precious in this environment or it would've been more, but it wasn't necessary either.

Be careful with keeping the default value for 'Device Down Retry' as it can eat up quite a lot of poller activity. I freed up over 20,000 worker seconds when setting this to only happen once or twice per 10-minute polling cycle. The impact of this will vary depending on the percentage of down device in your system. This example had it set at 400 seconds.

Also be wary of keeping event log and syslog entries for too long as it can have a pretty negative effect on web UI performance.

To resolve an issue with large device groups the php fpm max input vars was increased to 20000.

All of these VMs were within the same physical data center so latency was minimal.

The decision of redis over the other locking methods was arbitrary but in over 2 years I never had to touch that VM aside from security updates.

This install used the service instead of cron.

"},{"location":"Extensions/Distributed-Poller/#architecture","title":"Architecture","text":"

How you set the distribution up is entirely up to you. You can choose to host the majority of the required services on a single virtual machine or server and then a poller to actually query the devices being monitored, all the way through to having a dedicated server for each of the individual roles. Below are notes on what you need to consider both from the software layer, but also connectivity.

"},{"location":"Extensions/Distributed-Poller/#web-api-layer","title":"Web / API Layer","text":"

This is typically Apache but we have setup guides for both Nginx and Lighttpd which should work perfectly fine. There is nothing unique about the role this service is providing except that if you are adding devices from this layer then the web service will need to be able to connect to the end device via SNMP and perform an ICMP test.

It is advisable to run RRDCached within this setup so that you don't need to share the rrd folder via a remote file share such as NFS. The web service can then generate rrd graphs via RRDCached. If RRDCached isn't an option then you can mount the rrd directory to read the RRD files directly.

"},{"location":"Extensions/Distributed-Poller/#database-server","title":"Database Server","text":"

MySQL / MariaDB - At the moment these are the only database servers that are supported.

The pollers, web and API layers should all be able to access the database server directly.

"},{"location":"Extensions/Distributed-Poller/#rrd-storage","title":"RRD Storage","text":"

Central storage should be provided so all RRD files can be read from and written to in one location. As suggested above, it's recommended that RRD Cached is configured and used.

For this example, we are running RRDCached to allow all pollers and web/api servers to read/write to the rrd files with the rrd directory also exported by NFS for simple access and maintenance.

"},{"location":"Extensions/Distributed-Poller/#pollers","title":"Pollers","text":"

Pollers can be installed and run from anywhere, the only requirements are:

  • They can access the Memcache instance
  • They can create RRD files via some method such as a shared filesystem or RRDTool >=1.5.5
  • They can access the MySQL server

You can either assign pollers into groups and set a poller group against certain devices, this will mean that those devices will only be processed by certain pollers (default poller group is 0) or you can assign all pollers to the default poller group for them to process any and all devices.

This will provide the ability to have a single poller behind a NAT firewall monitor internal devices and report back to your central system. You will then be able to monitor those devices from the Web UI as normal.

Another benefit to this is that you can provide N+x pollers, i.e if you know that you require three pollers to process all devices within 300 seconds then adding a 4th poller will mean that should any one single poller fail then the remaining three will complete polling in time. You could also use this to take a poller out of service for maintenance, i.e OS updates and software updates.

It is extremely advisable to either run a central recursive dns server such as pdns-recursor and have all of your pollers use this or install a recursive dns server on each poller - the volume of DNS requests on large installs can be significant and will slow polling down enough to cause issues with a large number of devices.

A last note to make sure of, is that all pollers writing to the same DB need to have the same APP_KEY value set in the .env file.

"},{"location":"Extensions/Distributed-Poller/#discovery","title":"Discovery","text":"

Depending on your setup will depend on how you configure your discovery processes.

Cron based polling

It's not necessary to run discovery services on all pollers. In fact, you should only run one discovery process per poller group. Designate a single poller to run discovery (or a separate server if required).

If you run billing, you can do this in one of two ways:

  1. Run poll-billing.php and calculate-billing.php on a single poller which will create billing information for all bills. Please note this poller must have snmp access to all of your devices which have ports within a bill.
  2. The other option is to enable $config['distributed_billing'] = true; in config.php. Then run poll-billing.php on a single poller per group. You can run calculate-billing.php on any poller but only one poller overall.

Dispatcher service When using the dispatcher service, discovery can run on all nodes.

"},{"location":"Extensions/Distributed-Poller/#configuration","title":"Configuration","text":"

Settings in config.php should be copied to all servers as they only apply locally.

One way around this is to set settings in the database via the web ui or ./lnms config:set

"},{"location":"Extensions/Distributed-Poller/#config-sample","title":"Config sample","text":"

The following config is taken from a live setup which consists of a Web server, DB server, RRDCached server and 3 pollers.

Web Server:

Running Apache and an install of LibreNMS in /opt/librenms

poller/distributed

lnms config:set distributed_poller true\n

poller/rrdtool

lnms config:set rrdcached \"example.com:42217\"\n

Database Server: Running Memcache and MariaDB

  • Memcache

Ubuntu (/etc/memcached.conf)

-d\n-m 64\n-p 11211\n-u memcache\n-l ip.ip.ip.ip\n

RRDCached Server: Running RRDCached

  • RRDCached

Ubuntu (/etc/default/rrdcached)

OPTS=\"-l 0:42217\"\nOPTS=\"$OPTS -j /var/lib/rrdcached/journal/ -F\"\nOPTS=\"$OPTS -b /opt/librenms/rrd -B\"\nOPTS=\"$OPTS -w 1800 -z 900\"\n

Ubuntu (/etc/default/rrdcached) - RRDCached 1.5.5 and above.

BASE_OPTIONS=\"-l 0:42217\"\nBASE_OPTIONS=\"$BASE_OPTIONS -R -j /var/lib/rrdcached/journal/ -F\"\nBASE_OPTIONS=\"$BASE_OPTIONS -b /opt/librenms/rrd -B\"\nBASE_OPTIONS=\"$BASE_OPTIONS -w 1800 -z 900\"\n

Poller 1: Running an install of LibreNMS in /opt/librenms

config.php

$config['distributed_poller_name']           = php_uname('n');\n$config['distributed_poller_group']          = '0';\n$config['distributed_billing']               = true;\n

poller/distributed

lnms config:set distributed_poller_memcached_host \"example.com\"\nlnms config:set distributed_poller_memcached_port 11211\nlnms config:set distributed_poller true\n

poller/rrdtool

lnms config:set rrdcached \"example.com:42217\"\n

/etc/cron.d/librenms

Runs discovery and polling for group 0, daily.sh to deal with notifications and DB cleanup and alerts.

33   */6  * * *   librenms    /opt/librenms/cronic /opt/librenms/discovery-wrapper.py 1\n*/5  *    * * *   librenms    /opt/librenms/discovery.php -h new >> /dev/null 2>&1\n*/5  *    * * *   librenms    /opt/librenms/cronic /opt/librenms/poller-wrapper.py 16\n15   0    * * *   librenms    /opt/librenms/daily.sh >> /dev/null 2>&1\n*    *    * * *   librenms    /opt/librenms/alerts.php >> /dev/null 2>&1\n

Poller 2: Running an install of LibreNMS in /opt/librenms

config.php

$config['distributed_poller_name']           = php_uname('n');\n$config['distributed_poller_group']          = '0';\n$config['distributed_billing']               = true;\n

poller/distributed

lnms config:set distributed_poller_memcached_host \"example.com\"\nlnms config:set distributed_poller_memcached_port 11211\nlnms config:set distributed_poller true\n

poller/rrdtool

lnms config:set rrdcached \"example.com:42217\"\n

/etc/cron.d/librenms

Runs billing as well as polling for group 0.

*/5 * * * * librenms /opt/librenms/poller-wrapper.py 16 >> /opt/librenms/logs/wrapper.log\n*/5 * * * * librenms /opt/librenms/poll-billing.php >> /dev/null 2>&1\n01  * * * * librenms /opt/librenms/billing-calculate.php >> /dev/null 2>&1\n15  0 * * * librenms    /opt/librenms/daily.sh >> /dev/null 2>&1\n

Poller 3: Running an install of LibreNMS in /opt/librenms

config.php

$config['distributed_poller_name']           = php_uname('n');\n$config['distributed_poller_group']          = '2,3';\n$config['distributed_billing']               = true;\n

poller/distributed

lnms config:set distributed_poller_memcached_host \"example.com\"\nlnms config:set distributed_poller_memcached_port 11211\nlnms config:set distributed_poller true\n

poller/rrdtool

lnms config:set rrdcached \"example.com:42217\"\n

/etc/cron.d/librenms Runs discovery and polling for groups 2 and 3.

33  */6 * * *   librenms    /opt/librenms/cronic /opt/librenms/discovery-wrapper.py 1\n*/5 *   * * *   librenms    /opt/librenms/discovery.php -h new >> /dev/null 2>&1\n*/5 *   * * *   librenms    /opt/librenms/poll-billing.php >> /dev/null 2>&1\n*/5 *   * * *   librenms    /opt/librenms/cronic /opt/librenms/poller-wrapper.py 16\n15  0   * * *   librenms    /opt/librenms/daily.sh >> /dev/null 2>&1\n
"},{"location":"Extensions/Fast-Ping-Check/","title":"Fast up/down checking","text":"

Normally, LibreNMS sends an ICMP ping to the device before polling to check if it is up or down. This check is tied to the poller frequency, which is normally 5 minutes. This means it may take up to 5 minutes to find out if a device is down.

Some users may want to know if devices stop responding to ping more quickly than that. LibreNMS offers a ping.php script to run ping checks as quickly as possible without increasing snmp load on your devices by switching to 1 minute polling.

WARNING: If you do not have an alert rule that alerts on device status, enabling this will be a waste of resources. You can find one in the Alert Rules Collection.

"},{"location":"Extensions/Fast-Ping-Check/#setting-the-ping-check-to-1-minute","title":"Setting the ping check to 1 minute","text":"

1: If you are using RRDCached, stop the service.

- This will flush all pending writes so that the rrdstep.php script can change the steps.\n

2: Change the ping_rrd_step setting in config.php

poller/rrdtool

lnms config:set ping_rrd_step 60\n

3: Update the rrd files to change the step (step is hardcoded at file creation in rrd files)

./scripts/rrdstep.php -h all\n

4: Add the following line to /etc/cron.d/librenms to allow 1 minute ping checks

*    *    * * *   librenms    /opt/librenms/ping.php >> /dev/null 2>&1\n

5: If applicable: Start the RRDCached service

NOTE: If you are using distributed pollers you can restrict a poller to a group by appending -g to the cron entry. Alternatively, you should only run ping.php on a single node.

"},{"location":"Extensions/Fast-Ping-Check/#sub-minute-ping-check","title":"Sub minute ping check","text":"

Cron only has a resolution of one minute, so for sub-minute ping checks we need to adapt both ping and alerts entries. We add two entries per function, but add a delay before one of these entries.

Remember, you need to remove the original ping.php and alerts.php entries in crontab before proceeding!

1: Set ping_rrd_step

poller/rrdtool

lnms config:set ping_rrd_step 30\n

2: Update the rrd files

./scripts/rrdstep.php -h all\n

3: Update cron (removing any other ping.php or alert.php entries)

*    *    * * *   librenms    /opt/librenms/ping.php >> /dev/null 2>&1\n*    *    * * *   librenms    sleep 30 && /opt/librenms/ping.php >> /dev/null 2>&1\n*    *    * * *   librenms    sleep 15 && /opt/librenms/alerts.php >> /dev/null 2>&1\n*    *    * * *   librenms    sleep 45 && /opt/librenms/alerts.php >> /dev/null 2>&1\n
"},{"location":"Extensions/Fast-Ping-Check/#device-dependencies","title":"Device dependencies","text":"

The ping.php script respects device dependencies, but the main poller does not (for technical reasons). However, using this script does not disable the icmp check in the poller and a child may be reported as down before the parent.

"},{"location":"Extensions/Fast-Ping-Check/#settings","title":"Settings","text":"

ping.php uses much the same settings as the poller fping with one exception: retries is used instead of count. ping.php does not measure loss and avg response time, only up/down, so once a device responds it stops pinging it.

poller/ping

lnms config:set fping_options.retries 2\nlnms config:set fping_options.timeout 500\nlnms config:set fping_options.interval 500\n
"},{"location":"Extensions/Galera-Cluster/","title":"MariaDB Galera Cluster","text":"

This is currently being tested, use at your own risk.

LibreNMS can be used with a MariaDB Galera Cluster. This is a Multi Master cluster, meaning each node in the cluster can read and write to the database. They all have the same ability. LibreNMS will randomly choose a working node to read and write requests to.

For more information see https://laravel.com/docs/database#read-and-write-connections

"},{"location":"Extensions/Galera-Cluster/#getting-started","title":"Getting Started","text":"
  • It is best practice to have a minimum of 3 nodes in the cluster, A odd number of nodes is recommended in the event nodes have a disagreement on data, they will have a tie breaker.
  • It's recommended that all servers be similar in hardware performance, cluster performance can be affected by the slowest server in the cluster.
  • Backup the database before starting, and backing up the database regularly is still recommended even in a working cluster environment.
"},{"location":"Extensions/Galera-Cluster/#install-and-configure-galera","title":"Install and Configure Galera","text":""},{"location":"Extensions/Galera-Cluster/#install-galera4-and-mariadb-server","title":"Install Galera4 and MariaDB Server","text":"

These can be obtained from your OS package manager. For example in Ubuntu.

sudo apt-get install mariadb-server mariadb-client galera-4\n

"},{"location":"Extensions/Galera-Cluster/#create-galera-config","title":"Create Galera Config","text":"

Create a new file /etc/mysql/conf.d/galera.conf on each node

[mysqld]\nbinlog_format=ROW\ndefault-storage-engine=innodb\ninnodb_autoinc_lock_mode=2\nbind-address=0.0.0.0\n\n# Galera Provider Configuration\nwsrep_on=ON\nwsrep_provider=/usr/lib/galera/libgalera_smm.so\n\n# Galera Cluster Configuration\nwsrep_cluster_name=\"librenms_cluster\"\nwsrep_cluster_address=\"gcomm://192.168.1.35,192.168.1.36,192.168.1.37,192.168.1.38,192.168.1.39\"\n\n# Galera Synchronization Configuration\nwsrep_sst_method=rsync\n\n# Galera Node Configuration\nwsrep_node_address=\"192.168.1.35\"\nwsrep_node_name=\"librenms1.35\"\n
Change the following values for your environment. * wsrep_cluster_address - All the IP address's of your nodes. * wsrep_cluster_name - Name of cluster, should be the same for all nodes * wsrep_node_address - IP address of this node. * wsrep_node_name - Name of this node.

"},{"location":"Extensions/Galera-Cluster/#edit-librenms-env","title":"Edit LibreNMS .env","text":"

LibreNMS supports up to 9 galera nodes, you define these nodes in the .env file. For each node we have the ability to define if this librenms installation/poller is able to write, read or both to that node. The galera nodes you define here can be the same or differnt for each librenms poller. If you have a poller you only want to write/read to one galera node, you would simply add one DB_HOST, and omit all the rest. This allows you to precisely control what galera nodes a librenms poller is reading and or writing too.

  • DB_HOST is always set to read/write.
  • DB_HOST must be set, however, it does not have to be the same on each poller, it can be different as long as it's part of the same galera cluster.
  • If the node that is set to DB_HOST is down, things like lnms db command no longer work, as they only use DB_HOST and don't failover to other nodes.
  • Set DB_CONNECTION=mysql_cluster to enable
  • DB_STICKY can be used if you are pulling out of sync data form the database in a read request. For more information see https://laravel.com/docs/database#the-sticky-option

The below example setting up 5 nodes

DB_HOST=192.168.1.35\nDB_HOST_R2=192.168.1.36\nDB_HOST_R3=192.168.1.37\nDB_HOST_R4=192.168.1.38\nDB_HOST_R5=192.168.1.39\nDB_HOST_W2=192.168.1.36\nDB_HOST_W3=192.168.1.37\n\nDB_STICKY=true\nDB_CONNECTION=mysql_cluster\nDB_DATABASE=librenms\nDB_USERNAME=librenms\nDB_PASSWORD=password\n
The above .env on a librenms installation/poller would communicate to each galera node as follows.

  • 192.168.1.35 - Read/Write
  • 192.168.1.36 - Read/Write
  • 192.168.1.37 - Read/Write
  • 192.168.1.38 - Read Only
  • 192.168.1.39 - Read Only
"},{"location":"Extensions/Galera-Cluster/#starting-galera-cluster-for-the-first-time","title":"Starting Galera Cluster for the first time.","text":"

1) Shutdown MariaDB server on ALL nodes.

sudo systemctl stop mariadb-server\n
2) On the server with your existing database or any mariadb server if you are starting without existing data, run the following command
sudo galera_new_cluster\n
3) Start the rest of the nodes normally.
sudo systemctl start mariadb-server\n

"},{"location":"Extensions/Galera-Cluster/#galera-cluster-status","title":"Galera Cluster Status","text":"

To see some stats on how the Galera cluster is preforming run the following.

lnms db\n
In the database run following mysql query
SHOW GLOBAL STATUS LIKE 'wsrep_%';\n

Variable Name Value Notes ----------------------------------- ---------------------------------------------------------------- --------------------------------------------------------- wsrep_cluster_size 2 Current number of nodes in Cluster wsrep_cluster_state_uuid e71582f3-cf14-11eb-bcf6-a23029e16405 Last Transaction UUID, Should be the same for each node wsrep_connected On On = Connected with other nodes wsrep_local_state_comment Synced Synced with other nodes"},{"location":"Extensions/Galera-Cluster/#restarting-the-entire-cluster","title":"Restarting the Entire Cluster","text":"

In a cluster environment, steps should be taken to ensure that ALL nodes are not offline at the same time. Failed nodes can recover without issue as long as one node remains online. In the event that ALL nodes are offline, the following should be done to ensure you are starting the cluster with the most up-to-date database. To do this login to each node and running the following

sudo cat /var/lib/data/grastate.dat\n
# GALERA saved state\nversion: 2.1\nuuid:    e71582f3-cf14-11eb-bcf6-a23029e16405\nseqno:   -1\nsafe_to_bootstrap: 1\n

If the safe_to_bootstrap = 1, then Galera determined that this node has the most up-to-date database and can be safeley used to start the cluster.

Once you have found a node that can be used for starting the cluster, follow the steps in starting for the first time.

"},{"location":"Extensions/Gateone/","title":"GateOne integration","text":"

We have simple integration for GateOne, you will be redirected to your Gateone command line frontend to access your equipment. (Currently this only works with SSH)

GateOne itself isn't included within LibreNMS, you will need to install this separately either on the same infrastructure as LibreNMS or as a totally standalone appliance. The installation is beyond the scope of this document.

Config is simple, include the following in your config.php:

$config['gateone']['server'] = 'http://<your_gateone_url/';\n

Note: You must use the full url including the trailing /!

We also support prefixing the currently logged in Librenms user to the SSH connection URL that is created, eg. ssh://admin@localhost To enable this, put the following in your config.php:

$config['gateone']['use_librenms_user'] = true;\n
"},{"location":"Extensions/Graylog/","title":"Graylog integration","text":"

We have simple integration for Graylog, you will be able to view any logs from within LibreNMS that have been parsed by the syslog input from within Graylog itself. This includes logs from devices which aren't in LibreNMS still, you can also see logs for a specific device under the logs section for the device.

Currently, LibreNMS does not associate shortnames from Graylog with full FQDNS. If you have your devices in LibreNMS using full FQDNs, such as hostname.example.com, be aware that rsyslogd, by default, sends the shortname only. To fix this, add

$PreserveFQDN on

to your rsyslog config to send the full FQDN so device logs will be associated correctly in LibreNMS. Also see near the bottom of this document for tips on how to enable/suppress the domain part of hostnames in syslog-messages for some platforms.

Graylog itself isn't included within LibreNMS, you will need to install this separately either on the same infrastructure as LibreNMS or as a totally standalone appliance.

Config is simple, here's an example based on Graylog 2.4:

external/graylog

lnms config:set graylog.server 'http://127.0.0.1'\nlnms config:set graylog.port 9000\nlnms config:set graylog.username admin\nlnms config:set graylog.password 'admin'\nlnms config:set graylog.version 2.4\n
"},{"location":"Extensions/Graylog/#timezone","title":"Timezone","text":"

Graylog messages are stored using GMT timezone. You can display graylog messages in LibreNMS webui using your desired timezone by setting the following option using lnms config:set:

external/graylog

lnms config:set graylog.timezone 'Europe/Bucharest'\n

Timezone must be PHP supported timezones, available at: https://php.net/manual/en/timezones.php

"},{"location":"Extensions/Graylog/#graylog-version","title":"Graylog Version","text":"

If you are running a version earlier than Graylog then please set

external/graylog

lnms config:set graylog.version 2.1\n

to the version number of your Graylog install. Earlier versions than 2.1 use the default port 12900

"},{"location":"Extensions/Graylog/#uri","title":"URI","text":"

If you have altered the default uri for your Graylog setup then you can override the default of /api/ using

external/graylog

lnms config:set graylog.base_uri '/somepath/'\n
"},{"location":"Extensions/Graylog/#user-credentials","title":"User Credentials","text":"

If you don't want to use an admin account for connection to Graylog Log into http:///api/api-browser/global/index.html using graylog admin credentials Browse to: Roles: User roles Click on: Create a new role In JSON body paste this:

{\n    \"name\": \"LibreNMS-Read\",\n    \"description\": \"Extended reading permissions for LibreNMS\",\n    \"permissions\" : [\n        \"searches:relative\",\n        \"streams:read\"\n    ]\n}\n
Press \u201cTry it out\u201d Log into graylog web ui as admin and add the role to the user

Otherwise you must give the user \"admin\" permissions from within Graylog, \"read\" permissions alone are not sufficient.

"},{"location":"Extensions/Graylog/#tls-certificate","title":"TLS Certificate","text":"

If you have enabled TLS for the Graylog API and you are using a self-signed certificate, please make sure that the certificate is trusted by your LibreNMS host, otherwise the connection will fail. Additionally, the certificate's Common Name (CN) has to match the FQDN or IP address specified in

external/graylog

lnms config:set graylog.server example.com\n
"},{"location":"Extensions/Graylog/#match-any-address","title":"Match Any Address","text":"

If you want to match the source address of the log entries against any IP address of a device instead of only against the primary address and the host name to assign the log entries to a device, you can activate this function using

lnms config:set graylog.match-any-address true\n
"},{"location":"Extensions/Graylog/#recent-devices","title":"Recent Devices","text":"

There are 2 configuration parameters to influence the behaviour of the \"Recent Graylog\" table on the overview page of the devices.

external/graylog

lnms config:set graylog.device-page.rowCount 10\n

Sets the maximum number of rows to be displayed (default: 10)

external/graylog

lnms config:set graylog.device-page.loglevel 7\n

You can set which loglevels that should be displayed on the overview page. (default: 7, min: 0, max: 7)

external/graylog

lnms config:set graylog.device-page.loglevel 4\n

Shows only entries with a log level less than or equal to 4 (Emergency, Alert, Critical, Error, Warning).

You can set a default Log Level Filter with

lnms config:set graylog.loglevel 7\n
(applies to /graylog and /device/device=/tab=logs/section=graylog/ (min: 0, max: 7)

"},{"location":"Extensions/Graylog/#domain-and-hostname-handling","title":"Domain and hostname handling","text":"

Suppressing/enabling the domain part of a hostname for specific platforms

You should see if what you get in syslog/Graylog matches up with your configured hosts first. If you need to modify the syslog messages from specific platforms, this may be of assistance:

"},{"location":"Extensions/Graylog/#ios-cisco","title":"IOS (Cisco)","text":"
router(config)# logging origin-id hostname\n

or

router(config)# logging origin-id string\n
"},{"location":"Extensions/Graylog/#junos-juniper-networks","title":"JunOS (Juniper Networks)","text":"
set system syslog host yourlogserver.corp log-prefix YOUR_PREFERRED_STRING\n
"},{"location":"Extensions/Graylog/#panos-palo-alto-networks","title":"PanOS (Palo Alto Networks)","text":"
set deviceconfig setting management hostname-type-in-syslog hostname\n

or

set deviceconfig setting management hostname-type-in-syslog FQDN\n
"},{"location":"Extensions/IRC-Bot-Extensions/","title":"IRC Bot Extensions","text":"

Okay this is a very quick walk-through in writing your own commands for the IRC-Bot.

First of all, create a file in includes/ircbot, the file-name should be in this format: command.inc.php.

When editing the file, do not open nor close PHP-tags. Any variable you assign will be discarded as soon as your command returns. Some variables, specially all listed under $this->, have special meanings or effects. Before a command is executed, the IRC-Bot ensures that the MySQL-Socket is working, that $this->user points to the right user and that the user is authenticated. Below you will find a table with related functions and attributes. You can chain-load any built-in command by calling $this->_command(\"My Parameters\"). You cannot chain-load external commands.

To enable your command, edit your config.php and add something like this:

   ...\n   $config['irc_external'][] = \"mycommand\";\n   ...\n

See: Example

"},{"location":"Extensions/IRC-Bot-Extensions/#functions-and-attributes","title":"Functions and Attributes","text":"

... that are accessible from within an extension

"},{"location":"Extensions/IRC-Bot-Extensions/#functions","title":"Functions","text":"Function( (Type) $Variable [= Default] [,...] ) Returns Description $this->getChan( ) String Returns channel of current event. $this->getData( (boolean) $Block = false ) String/Boolean Returns a line from the IRC-Buffer if it's not matched against any other command. If $Block is true, wait until a suitable line is returned. $this->getUser( ) String Returns nick of current user. Not to confuse with $this->user! $this->get_user( ) Array See $this->user in Attributes. $this->irc_raw( (string) $Protocol ) Boolean Sends raw IRC-Protocol. $this->isAuthd( ) Boolean true if the user is authenticated. $this->joinChan( (string) $Channel ) Boolean Joins given $Channel. $this->log( (string) $Message ) Boolean Logs given $Message into STDOUT. $this->read( (string) $Buffer ) String/Boolean Returns a line from given $Buffer or false if there's nothing suitable inside the Buffer. Please use $this->getData() for handler-safe data retrieval. $this->respond( (string) $Message ) Boolean Responds to the request auto-detecting channel or private message."},{"location":"Extensions/IRC-Bot-Extensions/#attributes","title":"Attributes","text":"Attribute Type Description $params String Contains all arguments that are passed to the .command. $this->chan Array Channels that are configured. $this->commands Array Contains accessible commands. $this->config Array Contains $config from config.php. $this->data String Contains raw IRC-Protocol. $this->debug Boolean Debug-Flag. $this->external Array Contains loaded extra commands. $this->nick String Bot's nick on the IRC. $this->pass String IRC-Server's passphrase. $this->port Int IRC-Server's port-number. $this->server String IRC-Server's hostname. $this->ssl Boolean SSL-Flag. $this->tick Int Interval to check buffers in microseconds. $this->user Array Array containing details about the user that sent the request."},{"location":"Extensions/IRC-Bot-Extensions/#example","title":"Example","text":"

includes/ircbot/join-ng.inc.php

   if( $this->user['level'] != 10 ) {\n      return $this->respond(\"Sorry only admins can make me join.\");\n   }\n   if( $this->getChan() == \"#noc\") {\n      $this->respond(\"Joining $params\");\n      $this->joinChan($params);\n   } else {\n      $this->respond(\"Sorry, only people from #noc can make join.\");\n   }\n

config.php

   ...\n   $config['irc_external'][] = \"join-ng\";\n   ...\n
"},{"location":"Extensions/IRC-Bot/","title":"IRC Bot","text":"

LibreNMS has an easy to use IRC-Interface for basic tasks like viewing last log-entry, current device/port status and such.

By default the IRC-Bot will not start when executed and will return an error until at least $config['irc_host'] and $config['irc_port'] has been specified inside config.php. (To start the IRC-Bot run ./irc.php )

If no channel has been specified with $config['irc_chan'], ##librenms will be used. The default Nick for the bot is LibreNMS.

The Bot will reply the same way it's being called. If you send it the commands via Query, it will respond in the Query. If you send the commands via a Channel, then it will respond in the Channel.

"},{"location":"Extensions/IRC-Bot/#configuration-defaults","title":"Configuration & Defaults","text":"Option Default-Value Notes $config['irc_alert'] false Optional; Enables Alerting-Socket. EXPERIMENTAL $config['irc_alert_chan'] false Optional; Multiple channels can be defined as Array or delimited with ,. EXPERIMENTAL $config['irc_alert_utf8'] false Optional; Enables use of strikethrough in alerts via UTF-8 encoded characters. Might cause trouble for some clients. $config['irc_alert_short'] false Optional; Send a one line alert summary instead of multi-line detailed alert. $config['irc_authtime'] 3 Optional; Defines how long in Hours an auth-session is valid. $config['irc_chan'] ##librenms Optional; Multiple channels can be defined as Array or delimited with ,. Passwords are defined after a space-character. $config['irc_debug'] false Optional; Enables debug output (Wall of text) $config['irc_external'] Optional; Array or , delimited string with commands to include from includes/ircbot/*.inc.php $config['irc_host'] Required; Domain or IP to connect. If it's an IPv6 Address, embed it in []. (Example: [::1]) $config['irc_maxretry'] 5 Optional; How many connection attempts should be made before giving up $config['irc_nick'] LibreNMS Optional; $config['irc_pass'] Optional; This sends the IRC-PASS Sequence to IRC-Servers that require Password on Connect $config['irc_port'] 6667 Required; To enable SSL append a + before the Port. (Example: +6697) $config['irc_ctcp'] false Optional; Enable/disable ctcp-replies from the bot (currently VERSION, PING and TIME). $config['irc_ctcp_version'] LibreNMS IRCbot. https://www.librenms.org/ Optional; Reply-string to CTCP VERSION requests $config['irc_auth'] Optional; Array of hostmasks that are automatically authenticated."},{"location":"Extensions/IRC-Bot/#irc-commands","title":"IRC-Commands","text":"Command Description .auth <User/Token> If <user>: Request an Auth-Token. If <token>: Authenticate session. .device <hostname> Prints basic information about given hostname. .down List hostnames that are down, if any. .help List available commands. .join <channel> Joins <channel> if user has admin-level. .listdevices Lists the hostnames of all known devices. .log [<N>] Prints N lines or last line of the eventlog. .port <hostname> <ifname> Prints Port-related information from ifname on given hostname. .quit Disconnect from IRC and exit. .reload Reload configuration. .status <type> Prints status information for given type. Type can be devices, services, ports. Shorthands are: dev,srv,prt .version Prints $this->config['project_name_version'].

( /!\\ All commands are case-insensitive but their arguments are case-sensitive)

"},{"location":"Extensions/IRC-Bot/#examples","title":"Examples","text":""},{"location":"Extensions/IRC-Bot/#server-examples","title":"Server examples","text":"

Unencrypted Connection to irc.libera.chat:

   ...\n   $config['irc_host'] = \"irc.libera.chat\";\n   $config['irc_port'] = 6667;\n   ...\n

SSL-Encrypted Connection to irc.libera.chat:

   ...\n   $config['irc_host'] = \"irc.libera.chat\";\n   $config['irc_port'] = \"+6697\";\n   ...\n

SSL-Encrypted Connection to irc.localdomain with Server-Password and odd port:

   ...\n   $config['irc_host'] = \"irc.localdomain\";\n   $config['irc_port'] = \"+12345\";\n   $config['irc_pass'] = \"Super Secret Passphrase123\";\n   ...\n
"},{"location":"Extensions/IRC-Bot/#channel-notations","title":"Channel notations","text":"

Channels can be defined using Array-Notation like:

   ...\n   $config['irc_chan'][] = \"#librenms\";\n   $config['irc_chan'][] = \"#otherchan\";\n   $config['irc_chan'][] = \"#noc\";\n   ...\n

Or using a single string using , as delimiter between various channels:

   ...\n   $config['irc_chan'] = \"#librenms,#otherchan,#noc\";\n   ...\n
"},{"location":"Extensions/IRC-Bot/#hostmask-authentication","title":"Hostmask authentication","text":"
   ...\n   $config['irc_auth']['admin'][] = \"*!root@nms.host.invalid\";\n   $config['irc_auth']['admin'][] = \"*!*peter@peters.computer.invalid\";\n   $config['irc_auth']['john][] = \"john!doe@login.server.invalid\";\n   ...\n

Any client matching one of the first two hostmasks will automatically be authenticated as the \"admin\" user in LibreNMS, and clients matching the last line will be authenticated as the user \"john\" in LibreNMS, without using .auth and a waiting for a valid token.

"},{"location":"Extensions/IRC-Bot/#extensions","title":"Extensions?!","text":"

The bot is coded in a unified way. This makes writing extensions by far less painful. Simply add your command to the $config['irc_external'] directive and create a file called includes/ircbot/command.inc.php containing your code. The string behind the call of .command is passed as $params. The user who requested something is accessible via $this->user. Send your reply/ies via $this->respond($string).

A more detailed documentation of the functions and variables available for extensions can be found at IRC-Bot Extensions;

Confused? Here an Echo-Example:

File: config.php

   ...\n   $config['irc_external'][] = \"echo\";\n   ...\n

File: includes/ircbot/echo.inc.php

   //Prefix everything with `You said: '...'`  and return what was sent.\n   if( $this->user['name'] != \"root\" ) {\n      return $this->respond(\"You said: '\".$params.\"'\");\n   } else {\n      return $this->respond(\"root shouldn't be online so late!\");\n   }\n
"},{"location":"Extensions/IRC-Bot/#systemd-start-up-script","title":"Systemd start up script","text":"

Basic systemd start up script to be placed in /etc/systemd/system/ to start irc service at boot.

librenms-irc.service script is located at /opt/librenms/misc/

Once copied to /etc/systemd/system/ you must run the following commands:

a) chmod 664 /etc/systemd/system/librenms-irc.service

b) systemctl daemon-reload

c) systemctl enable librenms-irc.service

d) systemctl start librenms-irc.service

It can be stopped or started just like any other systemd script such as systemctl start librenms-irc.service

"},{"location":"Extensions/Interface-Description-Parsing/","title":"Interface Description Parsing","text":"

Librenms can interpret, display and group certain additional information on ports. This is done based on the format that the port description is written although it's possible to customise the parser to be specific for your setup.

"},{"location":"Extensions/Interface-Description-Parsing/#keywords","title":"Keywords","text":"

See examples for formats.

  • Keywords
  • Cust - Customer
  • Transit - Transit link
  • Peering - Peering link
  • Core - Infrastructure link (non-customer)
  • Info-keywords
  • () contains a note
  • {} contains your circuit id
  • [] contains the service type or speed
"},{"location":"Extensions/Interface-Description-Parsing/#examples","title":"Examples","text":"

Cisco IOS / NXOS / IOSXR:

interface Gi0/1\ndescr Transit: Example Provider (AS65000)\ninterface Gi0/2\ndescr Peering: Peering Exchange\ninterface Gi0/3\ndescr Core: core.router01 FastEthernet0/0 (Telco X CCID023141)\ninterface Gi0/4\ndescr Cust: Example Customer [10Mbit] (T1 Telco Y CCID129031) {EXAMP0001}\n

Unix / Linux:

This requires an additional script to be setup

# eth3: Cust: Example Customer [10Mbit] (T1 Telco Y CCID129031) {EXAMP0001}\n# eth0: Transit: Example Provider (AS65000)\n# eth1: Core: core.router01 FastEthernet0/0 (Telco X CCID023141)\n# eth2: Peering: Peering Exchange\n
"},{"location":"Extensions/Interface-Description-Parsing/#customisation","title":"Customisation","text":"

The following config options can be set to enable more custom types:

webui/port-descr

lnms config:set customers_descr.+ 'cust'\nlnms config:set transit_descr.+ 'transit'\nlnms config:set peering_descr.+ 'peering'\";'\nlnms config:set core_descr.+ 'core'\nlnms config:set custom_descr.+ 'something_made_up'\n
"},{"location":"Extensions/Interface-Description-Parsing/#custom-interface-parser","title":"Custom interface parser","text":"

It's also possible to write your own parser, the existing one is: includes/port-descr-parser.inc.php

Once you've created your own then you can enable it with:

$config['port_descr_parser'] = \"includes/custom/my-port-descr-parser.inc.php\";\n
"},{"location":"Extensions/Interface-Description-Parsing/#setup","title":"Setup","text":"

For Unix / Linux based systems, you need to run an additional script to support the parsing of interface information.

  • Add ifAlias from /opt/librenms/scripts/ or download it from here to the Server and make it executable chmod +x /path/to/ifAlias
  • Add to snmpd.conf something like: pass .1.3.6.1.2.1.31.1.1.1.18 /path/to/ifAlias
  • Add aliasses with
  • iproute2 package like: ip link set eth0.427 alias 'Cust: CustomerA'
  • in /etc/network/interfaces or /etc/network/interfaces.d/* with a comment like: # eth0.427: Cust CustomerA

  • Restart snmpd - systemctl restart snmpd

There are no changes to be made or additions to install for the polling librenms.

Now you can set up your keywords in your aliases.

"},{"location":"Extensions/Metric-Storage/","title":"Metric storage","text":"

By default we ship all metrics to RRD files, either directly or via RRDCached. On top of this you can ship metrics to Graphite, InfluxDB (v1 or v2 API), OpenTSDB or Prometheus. At present you can't use these backends to display graphs within LibreNMS and will need to use something like Grafana.

For further information on configuring LibreNMS to ship data to one of the other backends then please see the documentation below.

  • Graphite
  • InfluxDB
  • InfluxDBv2
  • OpenTSDB
  • Prometheus
"},{"location":"Extensions/NFSen/","title":"NFSen","text":"

The installation of NFSen is out of scope for this document / LibreNMS

"},{"location":"Extensions/NFSen/#configuration","title":"Configuration","text":"

The following is the configuration that can be used:

external/nfsen

lnms config:set nfsen_enable true\nlnms config:set nfsen_split_char '_'\nlnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/live/'\nlnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat'\nlnms config:set nfsen_base.+ '/var/nfsen/'\nlnms config:set nfsen_suffix '_yourdomain_com'\n

Set lnms config:set nfsen_enable true to enable NFSen support.

nfsen_rrds This value tells us where your NFSen rrd files live. This can also be an array to specify more directories like:

external/nfsen

lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/sitea/'\nlnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/siteb/'\n

Although for most setups, it will look like below, with the profiles-stat/live directory being where it stores the general RRDs for data sources.

external/nfsen

lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/live'\n

If you wish to render info for configure channels for a device, you need add the various profile-stat directories your system uses, which for most systems will be as below.

external/nfsen

lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat'\n

When adding sources to nfsen.conf, it is important to use the hostname that matches what is configured in LibreNMS, because the rrd files NfSen creates is named after the source name (ident), and it doesn't allow you to use an IP address instead. However, in LibreNMS, if your device is added by an IP address, add your source with any name of your choice, and create a symbolic link to the rrd file.

cd /var/nfsen/profiles-stat/sitea/\nln -s mychannel.rrd librenmsdeviceIP.rrd\n

external/nfsen

lnms config:set nfsen_split_char '_'\n

This value tells us what to replace the full stops . in the devices hostname with.

external/nfsen

lnms config:set nfsen_suffix '_yourdomain_com'\n

The above is a very important bit as device names in NfSen are limited to 21 characters. This means full domain names for devices can be very problematic to squeeze in, so therefor this chunk is usually removed.

On a similar note, NfSen profiles for channels should be created with the same name.

"},{"location":"Extensions/NFSen/#stats-defaults-and-settings","title":"Stats Defaults and Settings","text":"

Below are the default settings used with nfdump for stats.

For more defaulted information on that, please see nfdump(1). The default location for nfdump is /usr/bin/nfdump. If nfdump is located elsewhere, set it with

external/binaries

```bash lnms config:set nfdump /usr/local/bin/nfdump

```

external/nfsen

lnms config:set nfsen_last_max 153600\nlnms config:set nfsen_top_max 500\nlnms config:set nfsen_top_N '[10, 20, 50, 100, 200, 500]'\nlnms config:set nfsen_top_default 20\nlnms config:set nfsen_stat_default srcip\nlnms config:set nfsen_order_default packets\nlnms config:set nfsen_last_default 900\nlnms config:set nfsen_lasts \"{'300':'5 minutes', '600':'10 minutes', '900':'15 minutes', '1800':'30 minutes', '3600':'1 hour', '9600':'3 hours', '38400':'12 hours', '76800':'24 hours', '115200':'36 hours', '153600':'48 hours'}\"\n

external/nfsen

lnms config:set nfsen_last_max 153600\n

The above is the max value in seconds one may pull stats for. The higher this is, the more CPU and disk intensive the search will be.

Numbers larger than this will be set to this.

external/nfsen

lnms config:set nfsen_top_max 500\n

The above is max number of items to be displayed.

Numbers larger than this will be set to this.

external/nfsen

lnms config:set nfsen_top_N '[10, 20, 50, 100, 200, 500]'\n

The above is a array containing a list for the drop down menu how many top items should be returned.

external/nfsen

lnms config:set nfsen_top_default 20\n

The above sets default top number to use from the drop down.

external/nfsen

lnms config:set nfsen_stat_default srcip\n

The above sets default stat type to use from the drop down.

record   Flow Records\nip       Any IP Address\nsrcip    SRC IP Address\ndstip    DST IP Address\nport     Any Port\nsrcport  SRC Port\ndstport  DST Port\nsrctos   SRC TOS\ndsttos   DST TOS\ntos      TOS\nas       AS\nsrcas    SRC AS\ndstas    DST AS\n

external/nfsen

lnms config:set nfsen_order_default packets\n

The above sets default order type to use from the drop down. Any of the following below are currently supported.

flows    Number of total flows for the time period.\npacket   Number of total packets for the time period.\nbytes    Number of total bytes for the time period.\npps      Packets Per Second\nbps      Bytes Per Second\nbpp      Bytes Per Packet\n

external/nfsen

lnms config:set nfsen_last_default 900\n

The above is the last default to use from the drop down.

external/nfsen

lnms config:set nfsen_lasts \"{'300':'5 minutes', '600':'10 minutes', '900':'15 minutes', '1800':'30 minutes', '3600':'1 hour', '9600':'3 hours', '38400':'12 hours', '76800':'24 hours', '115200':'36 hours', '153600':'48 hours'}\"\n

The above associative array contains time intervals for how far back to go. The keys are the length in seconds and the value is just a description to display.

"},{"location":"Extensions/Network-Map/","title":"Network Map","text":"

LibreNMS has the ability to show you a dynamic network map based on data collected from devices. These maps are accessed through the following menu options:

  • Overview -> Maps -> Network
  • Overview -> Maps -> Device Group Maps
  • The Neighbours -> Map tab when viewing a single device (the Neighbours tab will only show if a device has xDP neighbours)

These network maps can be based on:

  • xDP Discovery
  • MAC addresses (ARP entries matching interface IP and MAC)

By default, both are are included but you can enable / disable either one using the following config option:

lnms config:set network_map_items '[\"mac\",\"xdp\"]'\n

Either remove mac or xdp depending on which you want. XDP is based on FDP, CDP and LLDP support based on the device type.

It is worth noting that the global map could lead to a large network map that is slow to render and interact with. The network map on the device neighbour page, or building device groups and using the device group maps will be more usable on large networks.

"},{"location":"Extensions/Network-Map/#settings","title":"Settings","text":"

The map display can be configured by altering the Vis JS Options

"},{"location":"Extensions/OAuth-SAML/","title":"OAuth and SAML Support","text":""},{"location":"Extensions/OAuth-SAML/#introduction","title":"Introduction","text":"

LibreNMS has support for Laravel Socialite to try and simplify the use of OAuth 1 or 2 providers such as using GitHub, Microsoft, Twitter + many more and SAML.

Socialite Providers supports more than 100+ 3rd parties so you will most likely find support for the SAML or OAuth provider you need without too much trouble.

Please do note however, these providers are not maintained by LibreNMS so we cannot add support for new ones and we can only provide you basic help with general configuration. See the Socialite Providers website for more information on adding a new OAuth provider.

Below we will guide you on how to install SAML or some of these OAth providers, you should be able to use these as a guide on how to install any others you may need but please, please, ensure you read the Socialite Providers documentation carefully.

GitHub Provider Microsoft Provider Okta Provider SAML2

"},{"location":"Extensions/OAuth-SAML/#requirements","title":"Requirements","text":"

LibreNMS version 22.3.0 or later.

Please ensure you set APP_URL within your .env file so that callback URLs work correctly with the identify provider.

Note

Once you have configured your OAuth or SAML2 provider, please ensure you check the Post configuration settings section at the end.

"},{"location":"Extensions/OAuth-SAML/#github-and-microsoft-examples","title":"GitHub and Microsoft Examples","text":""},{"location":"Extensions/OAuth-SAML/#install-plugin","title":"Install plugin","text":"

Note

First we need to install the plugin itself. The plugin name can be slightly different so be sure to check the Socialite Providers documentation and look for this line, composer require socialiteproviders/github which will give you the name you need for the command, i.e: socialiteproviders/github.

GitHubMicrosoftOkta

lnms plugin:add socialiteproviders/github

lnms plugin:add socialiteproviders/microsoft

lnms plugin:add socialiteproviders/okta

"},{"location":"Extensions/OAuth-SAML/#find-the-provider-name","title":"Find the provider name","text":"

Next we need to find the provider name and writing it down

Note

It's almost always the name of the provider in lowercase but can be different so check the Socialite Providers documentation and look for this line, github => [ which will give you the name you need for the above command: github.

GitHubMicrosoftOkta

For GitHub we can find the line:

'github' => [\n  'client_id' => env('GITHUB_CLIENT_ID'),\n  'client_secret' => env('GITHUB_CLIENT_SECRET'),\n  'redirect' => env('GITHUB_REDIRECT_URI')\n],\n
So our provider name is github, write this down.

For Microsoft we can find the line:

'microsoft' => [\n  'client_id' => env('MICROSOFT_CLIENT_ID'),\n  'client_secret' => env('MICROSOFT_CLIENT_SECRET'),\n  'redirect' => env('MICROSOFT_REDIRECT_URI')\n],\n
So our provider name is microsoft, write this down.

For Okta we can find the line:

'okta' => [\n  'base_url' => env('OKTA_BASE_URL'),\n  'client_id' => env('OKTA_CLIENT_ID'),\n  'client_secret' => env('OKTA_CLIENT_SECRET'),\n  'redirect' => env('OKTA_REDIRECT_URI')\n],\n
So our provider name is okta, write this down.

"},{"location":"Extensions/OAuth-SAML/#register-oauth-application","title":"Register OAuth application","text":""},{"location":"Extensions/OAuth-SAML/#register-a-new-application","title":"Register a new application","text":"

Now we need some values from the OAuth provider itself, in most cases you need to register a new \"OAuth application\" at the providers site. This will vary from provider to provider but the process itself should be similar to the examples below.

Note

The callback URL is always: https://your-librenms-url/auth/provider/callback It doesn't need to be a public available site, but it almost always needs to support TLS (https)!

GitHubMicrosoftOkta

For our example with GitHub we go to GitHub Developer Settings and press \"Register a new application\":

Fill out the form accordingly (with your own values):

For our example with Microsoft we go to \"Azure Active Directory\" > \"App registrations\" and press \"New registration\"

Fill out the form accordingly using your own values):

Copy the value of the Application (client) ID and Directory (tenant) ID and save them, you will need them in the next step.

For our example with Okta, we go to Applications>Create App Integration, Select OIDC - OpenID Connect, then Web Application.

Fill in the Name, Logo, and Assignments based on your preferred settings. Leave the Sign-In Redirect URI field, this is where you will edit this later:

Note your Okta domain or login url. Sometimes this can be a vanity url like login.company.com, or sometimes just company.okta.com.

Click save.

"},{"location":"Extensions/OAuth-SAML/#generate-a-new-client-secret","title":"Generate a new client secret","text":"GitHubMicrosoftOkta

Press 'Generate a new client secret' to get a new client secret.

Copy the Client ID and Client secret

In the example above it is:

Client ID: 7a41f1d8215640ca6b00 Client secret: ea03957288edd0e590be202b239e4f0ff26b8047

Select Certificates & secrets under Manage. Select the 'New client secret' button. Enter a value in Description and select one of the options for Expires and select 'Add'.

Copy the client secret Value (not Secret ID!) before you leave this page. You will need it in the next step.

This step is done for you when creating the app. All you have to do is copy down the client secret. You will need it in the next step.

"},{"location":"Extensions/OAuth-SAML/#saving-configuration","title":"Saving configuration","text":"

Now we need to set the configuration options for your provider within LibreNMS itself. Please replace the values in the examples below with the values you collected earlier:

The format of the configuration string is auth.socialite.configs.*provider name*.*value*

GitHubMicrosoftOkta

settings/auth/socialite

lnms config:set auth.socialite.configs.github.client_id 7a41f1d8215640ca6b00\nlnms config:set auth.socialite.configs.github.client_secret ea03957288edd0e590be202b239e4f0ff26b8047\n

settings/auth/socialite

lnms config:set auth.socialite.configs.microsoft.client_id 7983ac13-c955-40e9-9b85-5ba27be52a52\nlnms config:set auth.socialite.configs.microsoft.client_secret J9P7Q~K2F5C.L243sqzbGj.cOOcjTBgAPak_l\nlnms config:set auth.socialite.configs.microsoft.tenant a15edc05-152d-4eb4-973c-14f1fdc57d8b\n

settings/auth/socialite

lnms config:set auth.socialite.configs.okta.client_id 0oa1c08tti8D7xgXb697\nlnms config:set auth.socialite.configs.okta.client_secret sWew90IKqKDmURj1XLsCPjXjre0U3zmJuFR6SzsG\nlnms config:set auth.socialite.configs.okta.base_url \"https://<okta_login_url>\"\n
"},{"location":"Extensions/OAuth-SAML/#add-provider-event-listener","title":"Add provider event listener","text":"

The final step is to now add an event listener.

Note

It's important to copy exactly the right value here, It should begin with a \\ and end before the ::class.'@handle'

GitHubMicrosoftOkta

Find the section looking like:

protected $listen = [\n    \\SocialiteProviders\\Manager\\SocialiteWasCalled::class => [\n        // ... other providers\n        \\SocialiteProviders\\GitHub\\GitHubExtendSocialite::class.'@handle',\n    ],\n];\n

Copy the part: \\SocialiteProviders\\GitHub\\GitHubExtendSocialite and run;

settings/auth/socialite

lnms config:set auth.socialite.configs.github.listener \"\\SocialiteProviders\\GitHub\\GitHubExtendSocialite\"\n

Don't forget the initial backslash (\\) !

Find the section looking like:

protected $listen = [\n    \\SocialiteProviders\\Manager\\SocialiteWasCalled::class => [\n        // ... other providers\n        \\SocialiteProviders\\Microsoft\\MicrosoftExtendSocialite::class.'@handle',\n    ],\n];\n

Copy the part: \\SocialiteProviders\\Microsoft\\MicrosoftExtendSocialite and run;

settings/auth/socialite

lnms config:set auth.socialite.configs.microsoft.listener \"\\SocialiteProviders\\Microsoft\\MicrosoftExtendSocialite\"\n

Don't forget the initial backslash (\\) !

Find the section looking like:

protected $listen = [\n\\SocialiteProviders\\Manager\\SocialiteWasCalled::class => [\n    // ... other providers\n    \\SocialiteProviders\\Okta\\OktaExtendSocialite::class.'@handle',\n],\n];\n

Copy the part: \\SocialiteProviders\\Okta\\OktaExtendSocialite and run;

settings/auth/socialite

lnms config:set auth.socialite.configs.okta.listener \"\\SocialiteProviders\\Okta\\OktaExtendSocialite\"\n

Don't forget the initial backslack (\\) !

Now you are done with setting up the OAuth provider! If it doesn't work, please double check your configuration values by using the config:get command below.

settings/auth/socialite

lnms config:get auth.socialite\n
"},{"location":"Extensions/OAuth-SAML/#default-role","title":"Default Role","text":"

Since most Socialite Providers don't provide Authorization only Authentication it is possible to set the default User Role for Authorized users. Appropriate care should be taken.

  • none: No Access: User has no access

  • normal: Normal User: You will need to assign device / port permissions for users at this level.

  • global-read: Global Read: Read only Administrator.

  • admin: Administrator: This is a global read/write admin account.

settings/auth/socialite

lnms config:set auth.socialite.default_role global-read\n
"},{"location":"Extensions/OAuth-SAML/#claims-access-scopes","title":"Claims / Access Scopes","text":"

Socialite can specifiy scopes that should be included with in the authentication request. (see Larvel docs )

For example, if Okta is configured to expose group information it is possible to use these group names to configure User Roles.

This requires configuration in Okta. You can set the 'Groups claim type' to 'Filter' and supply a regex of which groups should be returned which can be mapped below.

First enable sending the 'groups' claim (along with the normal openid, profile, and email claims). Be aware that the scope name must match the claim name. For identity providers where the scope does not match (e.g. Keycloak: roles -> groups) you need to configure a custom scope.

settings/auth/socialite

lnms config:set auth.socialite.scopes.+ groups\n

Then setup mappings from the returned claim arrays to the User levels you want

settings/auth/socialite

lnms config:set auth.socialite.claims.RETURN_FROM_CLAIM.roles '[\"admin\"]'\nlnms config:set auth.socialite.claims.OTHER_RETURN_FROM_CLAIM.roles '[\"global-read\",\"cleaner\"]'\n
"},{"location":"Extensions/OAuth-SAML/#saml2-example","title":"SAML2 Example","text":""},{"location":"Extensions/OAuth-SAML/#install-plugin_1","title":"Install plugin","text":"

The first step is to install the plugin itself.

lnms plugin:add socialiteproviders/saml2\n
"},{"location":"Extensions/OAuth-SAML/#add-configuration","title":"Add configuration","text":"

Depending on what your identity provider (Google, Azure, ...) supports, the configuration could look different from what you see next so please use this as a rough guide. It is up the IdP to provide the relevant details that you will need for configuration.

GoogleAzure

Go to https://admin.google.com/ac/apps/unified

Press \"DOWNLOAD METADATA\" and save the file somewhere accessible by your LibreNMS server

ACS URL = https://your-librenms-url/auth/saml2/callback Entity ID = https://your-librenms-url/auth/saml2 Name ID format = PERSISTANT Name ID = Basic Information > Primary email

First name = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname Last name = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname Primary email = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.metadata \"$(cat /tmp/GoogleIDPMetadata.xml)\"\n

Alternatively, you can copy the content of the file and run it like so, this will result in the exact same result as above.

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.metadata '''<?xml version=\"1.0\" encoding\n...\n...\n</md:EntityDescriptor>'''\n

echo \"SESSION_SAME_SITE_COOKIE=none\" >> .env\nlnms plugin:add socialiteproviders/saml2\nlnms config:set auth.socialite.redirect true\nlnms config:set auth.socialite.register true\nlnms config:set auth.socialite.configs.saml2.acs https://login.microsoftonline.com/xxxidfromazurexxx/saml2\nlnms config:set auth.socialite.configs.saml2.entityid https://sts.windows.net/xxxidfromazurexxx/\nlnms config:set auth.socialite.configs.saml2.certificate xxxcertinonelinexxx\nlnms config:set auth.socialite.configs.saml2.listener \"\\SocialiteProviders\\Saml2\\Saml2ExtendSocialite\"\nlnms config:set auth.socialite.configs.saml2.metadata https://nexus.microsoftonline-p.com/federationmetadata/saml20/federationmetadata.xml\nlnms config:set auth.socialite.configs.saml2.sp_default_binding_method urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\nlnms config:clear\n

"},{"location":"Extensions/OAuth-SAML/#using-an-identity-provider-metadata-url","title":"Using an Identity Provider metadata URL","text":"

Note

This is the prefered and easiest way, if your IdP supports it!

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.metadata https://idp.co/metadata/xml\n
"},{"location":"Extensions/OAuth-SAML/#using-an-identity-provider-metadata-xml-file","title":"Using an Identity Provider metadata XML file","text":"

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.metadata \"$(cat GoogleIDPMetadata.xml)\"\n
"},{"location":"Extensions/OAuth-SAML/#manually-configuring-the-identity-provider-with-a-certificate-string","title":"Manually configuring the Identity Provider with a certificate string","text":"

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.acs https://idp.co/auth/acs\nlnms config:set auth.socialite.configs.saml2.entityid http://saml.to/trust\nlnms config:set auth.socialite.configs.saml2.certificate MIIC4jCCAcqgAwIBAgIQbDO5YO....\n
"},{"location":"Extensions/OAuth-SAML/#manually-configuring-the-identity-provider-with-a-certificate-file","title":"Manually configuring the Identity Provider with a certificate file","text":"

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.acs https://idp.co/auth/acs\nlnms config:set auth.socialite.configs.saml2.entityid http://saml.to/trust\nlnms config:set auth.socialite.configs.saml2.certificate \"$(cat /path/to/certificate.pem)\"\n
"},{"location":"Extensions/OAuth-SAML/#add-provider-event-listener_1","title":"Add provider event listener","text":"

Now we just need to define the listener service within LibreNMS:

settings/auth/socialite

lnms config:set auth.socialite.configs.saml2.listener \"\\SocialiteProviders\\Saml2\\Saml2ExtendSocialite\"\n
"},{"location":"Extensions/OAuth-SAML/#session_same_site_cookie","title":"SESSION_SAME_SITE_COOKIE","text":"

You most likely will need to set SESSION_SAME_SITE_COOKIE=none in .env if you use SAML2! If you get an error with http code 419, you should try to remove SESSION_SAME_SITE_COOKIE=none from your .env.

Note

Don't forget to run lnms config:clear after you modify .env to flush the config cache

"},{"location":"Extensions/OAuth-SAML/#service-provider-metadata","title":"Service provider metadata","text":"

Your identify provider might ask you for your Service Provider (SP) metadata. LibreNMS exposes all of this information from your LibreNMS install

"},{"location":"Extensions/OAuth-SAML/#troubleshooting","title":"Troubleshooting","text":"

If it doesn't work, please double check your configuration values by using the config:get command below.

settings/auth/socialite

lnms config:get auth.socialite\n
"},{"location":"Extensions/OAuth-SAML/#redirect-url","title":"Redirect URL","text":"

If you have a need to, then you can override redirect url with the following commands:

OAuthSAML2

Replace github and the relevant URL below with your identity provider details. lnms config:set auth.socialite.configs.github.redirect https://demo.librenms.org/auth/github/callback

lnms config:set auth.socialite.configs.saml2.sp_acs auth/saml2/callback

"},{"location":"Extensions/OAuth-SAML/#post-configuration-settings","title":"Post configuration settings","text":"

settings/auth/socialite

From here you can configure the settings for any identity providers you have configured along with some bespoke options.

Redirect Login page: This setting will skip your LibreNMS login and take the end user straight to the first idP you configured.

Allow registration via provider: If this setting is disabled, new users signing in via the idP will not be authenticated. This setting allows a local user to be automatically created which permits their login.

"},{"location":"Extensions/Oxidized/","title":"Oxidized","text":"

Integrating LibreNMS with Oxidized brings the following benefits:

  • Config viewing: Current, History, and Diffs all under the Configs tab of each device
  • Automatic addition of devices to Oxidized: Including filtering and grouping to ease credential management
  • Configuration searching (Requires oxidized-web 0.8.0 or newer)

First you will need to install Oxidized following their documentation.

Then you can procede to the LibreNMS Web UI and go to Oxidized Settings in the External Settings section of Global Settings. Enable it and enter the url to your oxidized instance.

To have devices automatically added, you will need to configure oxidized to pull them from LibreNMS Feeding Oxidized Note: this means devices will be controlled by the LibreNMS API, and not router.db, passwords will still need to be in the oxidized config file.

LibreNMS will automatically map the OS to the Oxidized model name if they don't match. this means you shouldn't need to use the model_map config option within Oxidized.

"},{"location":"Extensions/Oxidized/#detailed-integration-information","title":"Detailed integration information","text":"

This is a straight forward use of Oxidized, it relies on you having a working Oxidized setup which is already taking config snapshots for your devices. When you have that, you only need the following config to enable the display of device configs within the device page itself:

external/oxidized

lnms config:set oxidized.enabled true\nlnms config:set oxidized.url http://127.0.0.1:8888\n

LibreNMS supports config versioning if Oxidized does. This is known to work with the git output module.

external/oxidized

lnms config:set oxidized.features.versioning true\n

Oxidized supports various ways to utilise credentials to login to devices, you can specify global username/password within Oxidized, Group level username/password or per device. LibreNMS currently supports sending groups back to Oxidized so that you can then define group credentials within Oxidized. To enable this support please switch on 'Enable the return of groups to Oxidized':

external/oxidized

lnms config:set oxidized.group_support true\n

You can set a default group that devices will fall back to with:

external/oxidized

lnms config:set oxidized.default_group default\n

You can ignore specific groups

external/oxidized

lnms config:set oxidized.ignore_groups '[\"badgroup\", \"nobackup\"]'\n

One trick you can do to ignore all ungrouped devices is set both of these settings

external/oxidized

lnms config:set oxidized.default_group nobackup\nlnms config:set oxidized.ignore_groups.+ nobackup\n
"},{"location":"Extensions/Oxidized/#selinux","title":"SELinux","text":"

If you're running SELinux, you'll need to allow httpd to connect outbound to the network, otherwise Oxidized integration in the web UI will silently fail:

setsebool -P httpd_can_network_connect 1\n
"},{"location":"Extensions/Oxidized/#feeding-oxidized","title":"Feeding Oxidized","text":"

Oxidized has support for feeding devices into it via an API call, support for Oxidized has been added to the LibreNMS API. A sample config for Oxidized is provided below.

You will need to configure default credentials for your devices in the Oxidized config, LibreNMS doesn't provide login credentials at this time.

      source:\n        default: http\n        debug: false\n        http:\n          url: https://librenms/api/v0/oxidized\n          map:\n            name: hostname\n            model: os\n            group: group\n          headers:\n            X-Auth-Token: '01582bf94c03104ecb7953dsadsadwed'\n

LibreNMS is able to reload the Oxidized list of nodes, each time a device is added to LibreNMS. To do so, edit the option in Global Settings>External Settings>Oxidized Integration or add the following to your config.

external/oxidized

lnms config:set oxidized.reload_nodes true\n
"},{"location":"Extensions/Oxidized/#creating-overrides","title":"Creating overrides","text":"

To return an override to Oxidized you can do this by providing the override key, followed by matching a lookup for a host (or hosts), and finally by defining the overriding value itself. LibreNMS does not check for the validity of these attributes but will deliver them to Oxidized as defined.

Matching of hosts can be done using hostname, sysname, os, location, sysDescr, hardware, purpose or notes and including either a 'match' key and value, or a 'regex' key and value. The order of matching is:

  • hostname
  • sysName
  • sysDescr
  • hardware
  • os
  • location
  • ip
  • purpose
  • notes

To match on the device hostnames or sysNames that contain 'lon-sw' or if the location contains 'London' then you would set the following:

external/oxidized

lnms config:set oxidized.maps.group.hostname.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-switches\"}'\nlnms config:set oxidized.maps.group.sysName.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-switches\"}'\nlnms config:set oxidized.maps.group.location.+ '{\"regex\": \"/london/\", \"value\": \"london-switches\"}'\n

To match on a device os of edgeos then please use the following:

external/oxidized

lnms config:set oxidized.maps.group.os.+ '{\"match\": \"edgeos\", \"value\": \"wireless\"}'\n

Matching on OS requires system name of the OS. For example, \"match\": \"RouterOS\" will not work, while \"match\": \"routeros\" will.

To match on a device purpose or device notes that contains 'lon-net' then you would set the following:

external/oxidized

lnms config:set oxidized.maps.group.purpose.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-network\"}'\nlnms config:set oxidized.maps.group.notes.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-network\"}'\n

To edit an existing map, you must use the index to override it.

external/oxidized

lnms config:get oxidized.maps.os.os\n[\n    {\n        \"match\": \"airos-af-ltu\",\n        \"value\": \"airfiber\"\n    },\n    {\n        \"match\": \"airos-af\",\n        \"value\": \"airfiber\"\n    },\n]\n\nlnms config:set oxidized.maps.os.os.1 '{\"match\": \"airos-af\", \"value\": \"something-else\"}'\n

To override the IP Oxidized uses to poll the device, set the following:

external/oxidized

lnms config:set oxidized.maps.ip.sysName.+ '{\"regex\": \"/^my.node/\", \"value\": \"192.168.1.10\"}'\nlnms config:set oxidized.maps.ip.sysName.+ '{\"match\": \"my-other.node\", \"value\": \"192.168.1.20\"}'\n

This allows extending the configuration further by providing a completely flexible model for custom flags and settings, for example, below shows the ability to add an ssh_proxy host within Oxidized simply by adding the below to your configuration:

external/oxidized

lnms config:set oxidized.maps.ssh_proxy.sysName.+ '{\"regex\": \"/^my.node/\", \"value\": \"my-ssh-gateway.node\"}'\n

Or of course, any custom value that could be needed or wanted can be applied, for example, setting a \"myAttribute\" to \"Super cool value\" for any configured and enabled \"routeros\" device.

external/oxidized

lnms config:set oxidized.maps.myAttribute.os.+ '{\"match\": \"routeros\", \"value\": \"Super cool value\"}'\n

Verify the return of groups by querying the API:

curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized\n

If you need to, you can specify credentials for groups by using the following in your Oxidized config:

groups:\n  <groupname>:\n    username: <user>\n    password: <password>\n
"},{"location":"Extensions/Oxidized/#miscellaneous","title":"Miscellaneous","text":"

If you have devices which you do not wish to appear in Oxidized then you can edit those devices in Device -> Edit -> Misc and enable \"Exclude from Oxidized?\"

The use of custom ssh and telnet ports can be set through device settings misc tab, and can be passed on to oxidized with the following vars_map

      source:\n        http:\n          map:\n            name: hostname\n            model: os\n            group: group\n          vars_map:\n            ssh_port: ssh_port\n            telnet_port: telnet_port\n

It's also possible to exclude certain device types and OS' from being output via the API.

external/oxidized

lnms config:set oxidized.ignore_types '[\"server\", \"power\"]'\nlnms config:set oxidized.ignore_os '[\"linux\", \"windows\"]'\n

You can also ignore whole groups of devices

external/oxidized

lnms config:set oxidized.ignore_groups '[\"london-switches\", \"default\"]'\n
"},{"location":"Extensions/Oxidized/#trigger-configuration-backups","title":"Trigger configuration backups","text":"

Using the Oxidized REST API and Syslog Hooks, Oxidized can trigger configuration downloads whenever a configuration change event has been logged. An example script to do this is included in ./scripts/syslog-notify-oxidized.php. Oxidized can spawn a new worker thread and perform the download immediately with the following configuration

next_adds_job: true\n
"},{"location":"Extensions/Oxidized/#validate-oxidized-config","title":"Validate Oxidized config","text":"

You can perform basic validation of the Oxidized configuration by going to the Overview -> Tools -> Oxidized link and in the Oxidized config validation page, paste your yaml file into the input box and click 'Validate YAML'.

We check for yaml syntax errors and also actual config values to ensure they are used in the correct location.

"},{"location":"Extensions/Oxidized/#accessing-configuration-of-a-disabledremoved-device","title":"Accessing configuration of a disabled/removed device","text":"

When you're disabling or removing a device from LibreNMS, the configuration will no longer be available via the LibreNMS web interface. You can gain access to these configurations directly in the Git repository of Oxidized (if using Git for version control).

1: Check in your Oxidized where are stored your Git repositories:

/home/oxidized/.config/oxidized/config\n

2: Go the correct Git repository for the needed device (the .git one) and get the list of devices using this command:

git ls-files -s\n

3: Save the object ID of the device, and run the command to get the file content:

git cat-file -p <object id>\n
"},{"location":"Extensions/Oxidized/#remove-disabledremoved-device","title":"Remove disabled/removed device","text":"

If you want to purge saved config of a device that is not in LibreNMS anymore, you can run the following command:

git rm --cached <object id>\n
"},{"location":"Extensions/PeeringDB/","title":"PeeringDB Support","text":"

LibreNMS has integration with PeeringDB to match up your BGP sessions with the peering exchanges you are connected to.

To enable the integration please do so within the WebUI

external/peeringdb

lnms config:set peeringdb.enabled true\n

Data will be collated the next time daily.sh is run or you can manually force this by running php daily.php -f peeringdb, the initial collection is delayed for a random amount of time to avoid overloading the PeeringDB API.

Once enabled you will have an additional menu item under Routing -> PeeringDB

"},{"location":"Extensions/Plugin-System/","title":"Developing for the Plugin System","text":"

With plugins you can extend LibreNMS with special functions that are specific to your setup or are not relevant or interesting for all community members.

You are able to intervene in defined places in the behavior of the website, without it coming to problems with future updates.

This documentation will give you a basis for writing a plugin for LibreNMS. An example plugin is included in the LibreNMS distribution.

"},{"location":"Extensions/Plugin-System/#version-2-plugin-system-structure","title":"Version 2 Plugin System structure","text":"

Plugins in version 2 need to be installed into app/Plugins

Note: Plugins are disabled when the have an error, to show errors instead set plugins.show_errors

The structure of a plugin is follows:

app/Plugins\n            /PluginName\n                       /DeviceOverview.php\n                       /Menu.php\n                       /Page.php\n                       /PortTab.php\n                       /Settings.php\n                       /resources/views\n                                       /device-overview.blade.php\n                                       /menu.blade.php\n                                       /page.blade.php\n                                       /port-tab.blade.php\n                                       /settings.blade.php\n

The above structure is checked before a plugin can be installed.

All file/folder names are case sensitive and must match the structure.

Only the blade files that are really needed need to be created. A plugin manager will then load a hook that has a basic functionality.

If you want to customize the basic behavior of the hooks, you can create a class in 'app/Plugins/PluginName' and overload the hook methods.

  • device-overview.blade.php :: This is called in the Device Overview page. You receive the $device as a object per default, you can do your work here and display your results in a frame.
<div class=\"row\">\n    <div class=\"col-md-12\">\n        <div class=\"panel panel-default panel-condensed\">\n            <div class=\"panel-heading\">\n                <strong>{{ $title }}</strong>\n            </div>\n            <div class=\"panel-body\">\n                <div class=\"row\">\n                    <div class=\"col-sm-12\">\n                         {{ $device->hostname }}\n                 <!-- Do you stuff here -->\n                    </div>\n        </div>\n        </div>\n    </div>\n    </div>\n</div>\n
  • port-tab.blade.php :: This is called in the Port page, in the \"Plugins\" menu_option that will appear when your plugin gets enabled. In this blade, you can do your work and display your results in a frame.

  • menu.blade.php :: For a menu entry

  • page.blade.pho :: Here is a good place to add a own LibreNMS page without dependence with a device. A good place to create your own lists with special requirements and behavior.

  • settings.blade.php :: If you need your own settings and variables, you can have a look in the ExamplePlugin.

"},{"location":"Extensions/Plugin-System/#php-hooks-customization","title":"PHP Hooks customization","text":"

PHP code should run inside your hooks method and not your blade view. The built in hooks support authorize and data methods.

These methods are called with Dependency Injection Hooks with relevant database models will include them in these calls. Additionally, the settings argument may be included to inject the plugin settings into the method.

"},{"location":"Extensions/Plugin-System/#data","title":"Data","text":"

You can overrid the data method to supply data to your view. You should also do any processing here. You can do things like access the database or configuration settings and more.

In the data method we are injecting settings here to count how many we have for display in the menu entry blade view. Note that you must specify a default value (= [] here) for any arguments that don't exist on the parent method.

class Menu extends MenuEntryHook\n{\n    public function data(array $settings = []): array\n    {\n        return [\n            'count' => count($settings),\n        ];\n    }\n}\n
"},{"location":"Extensions/Plugin-System/#authorize","title":"Authorize","text":"

By default hooks are always shown, but you may control when the user is authorized to view the hook content.

As an example, you could imagine that the device-overview.blade.php should only be displayed when the device is in maintanence mode and the current user has the admin role.

class DeviceOverview extends DeviceOverviewHook\n{\n    public function authorize(User $user, Device $device): bool\n    {\n        return $user->can('admin') && $device->isUnderMaintenance();\n    }\n}\n
"},{"location":"Extensions/Plugin-System/#full-plugin","title":"Full plugin","text":"

You may create a full plugin that can publish multiple routes, views, database migrations and more. Create a package according to the Laravel documentation you may call any of the supported hooks to tie into LibreNMS.

https://laravel.com/docs/packages

This is untested, please come to discord and share any expriences and update this documentation!

"},{"location":"Extensions/Plugin-System/#version-1-plugin-system-structure-legacy-version","title":"Version 1 Plugin System structure (legacy version)","text":"

Plugins need to be installed into html/plugins

The structure of a plugin is follows:

html/plugins\n            /PluginName\n                       /PluginName.php\n                       /PluginName.inc.php\n

The above structure is checked before a plugin can be installed.

All files / folder names are case sensitive and must match.

PluginName - This is a directory and needs to be named as per the plugin you are creating.

  • PluginName.php :: This file is used to process calls into the plugin from the main LibreNMS install. Here only functions within the class for your plugin that LibreNMS calls will be executed. For a list of currently enabled system hooks, please see further down. The minimum code required in this file is (replace Test with the name of your plugin):
<?php\n\nclass Test {\n}\n\n?>\n
  • PluginName.inc.php :: This file is the main included file when browsing to the plugin itself. You can use this to display / edit / remove whatever you like. The minimum code required in this file is:
<?php\n\n?>\n
"},{"location":"Extensions/Plugin-System/#system-hooks","title":"System Hooks","text":"

System hooks are called as functions within your plugin class. The following system hooks are currently available:

  • menu() :: This is called to build the plugin menu system and you can use this to link to your plugin (you don't have to).
    public static function menu() {\n        echo('<li><a href=\"plugin/p='.get_class().'\">'.get_class().'</a></li>');\n    }\n
  • device_overview_container($device) :: This is called in the Device Overview page. You receive the $device as a parameter, can do your work here and display your results in a frame.
    public static function device_overview_container($device) {\n        echo('<div class=\"container-fluid\"><div class=\"row\"> <div class=\"col-md-12\"> <div class=\"panel panel-default panel-condensed\"> <div class=\"panel-heading\"><strong>'.get_class().' Plugin </strong> </div>');\n        echo('  Example plugin in \"Device - Overview\" tab <br>');\n        echo('</div></div></div></div>');\n    }\n
  • port_container($device, $port) :: This is called in the Port page, in the \"Plugins\" menu_option that will appear when your plugin gets enabled. In this function, you can do your work and display your results in a frame.
    public static function port_container($device, $port) {\n        echo('<div class=\"container-fluid\"><div class=\"row\"> <div class=\"col-md-12\"> <div class=\"panel panel-default panel-condensed\"> <div class=\"panel-heading\"><strong>'.get_class().' plugin in \"Port\" tab</strong> </div>');\n        echo ('Example display in Port tab</br>');\n        echo('</div></div></div></div>');\n    }\n
"},{"location":"Extensions/Proxmox/","title":"Proxmox graphing","text":"

It is possible to create graphs of the Proxmox VMs that run on your monitored machines. Currently, only traffic graphs are created. One for each interface on each VM. Possibly, IO graphs will be added later on.

The ultimate goal is to be able to create traffic bills for VMs, no matter on which physical machine that VM runs.

"},{"location":"Extensions/Proxmox/#enabling-proxmox-graphs","title":"Enabling Proxmox graphs","text":"

To enable Proxmox graphs, do the following:

In config.php, enable Proxmox:

$config['enable_proxmox'] = 1;\n

Then, install git and librenms-agent on the machines running Proxmox and enable the Proxmox-script using:

cp /opt/librenms-agent/agent-local/proxmox /usr/lib/check_mk_agent/local/proxmox\nchmod +x /usr/lib/check_mk_agent/local/proxmox\n

Then, enable and start the check_mk service using systemd

cp /opt/librenms-agent/check_mk@.service /opt/librenms-agent/check_mk.socket /etc/systemd/system\nsystemctl daemon-reload\nsystemctl enable check_mk.socket && systemctl start check_mk.socket\n

Then in LibreNMS active the librenms-agent and proxmox application flag for the device you are monitoring. You should now see an application in LibreNMS, as well as a new menu-item in the topmenu, allowing you to choose which cluster you want to look at.

"},{"location":"Extensions/Proxmox/#note-if-you-want-to-use-use-xinetd-instead-of-systemd","title":"Note, if you want to use use xinetd instead of systemd","text":"

Its possible to use the librenms-agent started by xinetd instead of systemd. One use case is if you are forced to use a old Proxmox installation. After installing the librenms-agent (see above) please copy enable the xinetd config, then restart the xinetd service:

cp check_mk_xinetd /etc/xinetd.d/check_mk\n/etc/init.d/xinetd restart\n
"},{"location":"Extensions/RRDCached/","title":"Setting up RRDCached","text":"

This document will explain how to set up RRDCached for LibreNMS.

Since version 1.5, rrdtool / rrdcached now supports creating rrd files over rrdcached. If you have rrdcached 1.5.5 or above, you can also tune over rrdcached. To enable this set the following config:

poller/rrdtool

lnms config:set rrdtool_version '1.5.5'\n

This setting has to be the exact version of rrdtool you are running.

NOTE: This feature requires your client version of rrdtool to be 1.5.5 or newer, in addition to your rrdcached version.

"},{"location":"Extensions/RRDCached/#distributed-poller-support-matrix","title":"Distributed Poller Support Matrix","text":"

Shared FS: Is a shared filesystem required?

Features: Supported features in the version indicated.

G = Graphs.\nC = Create RRD files.\nU = Update RRD files.\nT = Tune RRD files.\n
Version Shared FS Features 1.4.x Yes G,U <1.5.5 Yes G,U >=1.5.5 No G,C,U >=1.6.x No G,C,U

It is recommended that you monitor your LibreNMS server with LibreNMS so you can view the disk I/O usage delta.

"},{"location":"Extensions/RRDCached/#installation-manual-for","title":"Installation Manual for","text":"
  1. RRDCached installation Ubuntu 16
  2. RRDCached installation Debian Buster
  3. RRDCached installation Debian Stretch
  4. RRDCached installation CentOS 7 or 8
  5. RRDCached installation CentOS 6
  6. Securing RRCached
"},{"location":"Extensions/RRDCached/#rrdcached-installation-ubuntu-16","title":"RRDCached installation Ubuntu 16","text":"

1: Install rrdcached

sudo apt-get install rrdcached\n

2: Edit /etc/default/rrdcached to include:

DAEMON=/usr/bin/rrdcached\nDAEMON_USER=librenms\nDAEMON_GROUP=librenms\nWRITE_THREADS=4\nWRITE_TIMEOUT=1800\nWRITE_JITTER=1800\nBASE_PATH=/opt/librenms/rrd/\nJOURNAL_PATH=/var/lib/rrdcached/journal/\nPIDFILE=/run/rrdcached.pid\nSOCKFILE=/run/rrdcached.sock\nSOCKGROUP=librenms\nBASE_OPTIONS=\"-B -F -R\"\n

2: Fix permissions

chown librenms:librenms /var/lib/rrdcached/journal/\n

3: Restart the rrdcached service

systemctl restart rrdcached.service\n

5: Edit your config to include:

poller/rrdtool

lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n
"},{"location":"Extensions/RRDCached/#rrdcached-installation-debian-buster","title":"RRDCached installation Debian Buster","text":"

(rrdcached 1.7.1)

1: Install rrdcached

sudo apt-get install rrdcached\n

2; Edit /etc/default/rrdcached to include:

DAEMON=/usr/bin/rrdcached\nWRITE_TIMEOUT=1800\nWRITE_JITTER=1800\nWRITE_THREADS=4\nBASE_PATH=/opt/librenms/rrd/\nJOURNAL_PATH=/var/lib/rrdcached/journal/\nPIDFILE=/var/run/rrdcached.pid\nSOCKFILE=/run/rrdcached.sock\nSOCKGROUP=librenms\nDAEMON_GROUP=librenms\nDAEMON_USER=librenms\nBASE_OPTIONS=\"-B -F -R\"\n

3: Fix permissions

chown librenms:librenms /var/lib/rrdcached/journal/\n

4: Restart the rrdcached service

systemctl restart rrdcached.service\n

5: Edit your config to include:

For local RRDCached server

poller/rrdtool

lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n

For remote RRDCached server make sure you have network option in /var/default/rrdcached

NETWORK_OPTIONS=\"-L\"\n

poller/rrdtool

lnms config:set rrdcached \"IPADDRESS:42217\"\n

NOTE: change IPADDRESS to the ip the rrdcached server is listening on.

"},{"location":"Extensions/RRDCached/#rrdcached-installation-debian-stretch","title":"RRDCached installation Debian Stretch","text":"

(rrdcached 1.6.0)

1: Install rrdcached

sudo apt-get install rrdcached\n

2; Edit /etc/default/rrdcached to include:

DAEMON=/usr/bin/rrdcached\nWRITE_TIMEOUT=1800\nWRITE_JITTER=1800\nWRITE_THREADS=4\nBASE_PATH=/opt/librenms/rrd/\nJOURNAL_PATH=/var/lib/rrdcached/journal/\nPIDFILE=/var/run/rrdcached.pid\nSOCKFILE=/run/rrdcached.sock\nSOCKGROUP=librenms\nDAEMON_GROUP=librenms\nDAEMON_USER=librenms\nBASE_OPTIONS=\"-B -F -R\"\n

3: Fix permissions

chown librenms:librenms /var/lib/rrdcached/journal/\n

4: Restart the rrdcached service

systemctl restart rrdcached.service\n

5: Edit your config to include:

For local RRDCached server

poller/rrdtool

lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n

For remote RRDCached server make sure you have network option in /var/default/rrdcached

NETWORK_OPTIONS=\"-L\"\n

poller/rrdtool

lnms config:set rrdcached \"IPADDRESS:42217\"\n

NOTE: change IPADDRESS to the ip the rrdcached server is listening on.

"},{"location":"Extensions/RRDCached/#rrdcached-installation-centos-7-or-8","title":"RRDCached installation CentOS 7 or 8","text":"

1: Create /etc/systemd/system/rrdcached.service with this content:

[Unit]\nDescription=Data caching daemon for rrdtool\nAfter=network.service\n\n[Service]\nType=forking\nPIDFile=/run/rrdcached.pid\nExecStart=/usr/bin/rrdcached -w 1800 -z 1800 -f 3600 -s librenms -U librenms -G librenms -B -R -j /var/tmp -l unix:/run/rrdcached.sock -t 4 -F -b /opt/librenms/rrd/\n\n[Install]\nWantedBy=default.target\n

2: Configure SELinux for RRDCached

cat > rrdcached_librenms.te << EOF\nmodule rrdcached_librenms 1.0;\n\nrequire {\n        type var_run_t;\n        type tmp_t;\n        type httpd_t;\n        type rrdcached_t;\n        type httpd_sys_rw_content_t;\n        class dir { add_name getattr open read remove_name rmdir search write };\n        class file { create getattr open read rename setattr unlink write map lock };\n        class sock_file { create setattr unlink write };\n        class capability { fsetid sys_resource };\n        class unix_stream_socket connectto;\n}\n\n#============= rrdcached_t ==============\n\nallow rrdcached_t httpd_sys_rw_content_t:dir { add_name getattr remove_name search write };\nallow rrdcached_t httpd_sys_rw_content_t:file { create getattr open read rename setattr unlink write map lock };\nallow rrdcached_t self:capability fsetid;\nallow rrdcached_t var_run_t:sock_file { create setattr unlink };\nallow httpd_t var_run_t:sock_file write;\nallow httpd_t rrdcached_t:unix_stream_socket connectto;\nEOF\n\ncheckmodule -M -m -o rrdcached_librenms.mod rrdcached_librenms.te\nsemodule_package -o rrdcached_librenms.pp -m rrdcached_librenms.mod\nsemodule -i rrdcached_librenms.pp\n

3: Start rrdcached

systemctl enable --now rrdcached.service\n

4: Edit your config to include:

poller/rrdtool

lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n
"},{"location":"Extensions/RRDCached/#rrdcached-installation-centos-6","title":"RRDCached installation CentOS 6","text":"

This example is based on a fresh LibreNMS install, on a minimal CentOS 6 installation. In this example, we'll use the Repoforge repository.

rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm\nvi /etc/yum.repos.d/rpmforge.repo\n
  • Enable the Extra repo
yum update rrdtool\nvi /etc/yum.repos.d/rpmforge.repo\n
  • Disable the [rpmforge] and [rpmforge-extras] repos again
vi /etc/sysconfig/rrdcached\n\n# Settings for rrdcached\nOPTIONS=\"-w 1800 -z 1800 -f 3600 -s librenms -U librenms -G librenms -B -R -j /var/tmp -l unix:/run/rrdcached.sock -t 4 -F -b /opt/librenms/rrd/\"\nRRDC_USER=librenms\n\nmkdir /var/run/rrdcached\nchown librenms:librenms /var/run/rrdcached/\nchown librenms:librenms /var/rrdtool/\nchown librenms:librenms /var/rrdtool/rrdcached/\nchkconfig rrdcached on\nservice rrdcached start\n
  • Edit your config to include:

poller/rrdtool

lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n
"},{"location":"Extensions/RRDCached/#verify","title":"Verify","text":"

Check to see if the graphs are being drawn in LibreNMS. This might take a few minutes. After at least one poll cycle (5 mins), check the LibreNMS disk I/O performance delta. Disk I/O can be found under the menu Devices>All Devices>[localhost hostname]>Health>Disk I/O.

Depending on many factors, you should see the Ops/sec drop by ~30-40%.

"},{"location":"Extensions/RRDCached/#securing-rrcached","title":"Securing RRCached","text":"

According to the man page, under \"SECURITY CONSIDERATIONS\", rrdcached has no authentication or security except for running under a unix socket. If you choose to use a network socket instead of a unix socket, you will need to secure your rrdcached installation. To do so you can proxy rrdcached using nginx to allow only specific IPs to connect.

Using the same setup above, using nginx version 1.9.0 or later, you can follow this setup to proxy the default rrdcached port to the local unix socket.

(You can use ./conf.d for your configuration as well)

mkdir /etc/nginx/streams-{available,enabled}

add the following to your nginx.conf file:

#/etc/nginx/nginx.conf\n...\nstream {\n    include /etc/nginx/streams-enabled/*;\n}\n

Add this to /etc/nginx/streams-available/rrd

server {\n    listen 42217;\n\n    error_log  /var/log/nginx/rrd.stream.error.log;\n\n    allow $LibreNMS_IP;\n    deny all;\n\n    proxy_pass unix:/run/rrdcached.sock;\n}\n

Replace $LibreNMS_IP with the ip of the server that will be using rrdcached. You can specify more than one allow statement. This will bind nginx to TCP 42217 (the default rrdcached port), allow the specified IPs to connect, and deny all others.

next, we'll symlink the config to streams-enabled: ln -s /etc/nginx/streams-{available,enabled}/rrd

and reload nginx service nginx reload

"},{"location":"Extensions/RRDTune/","title":"RRDTune","text":"

When we create rrd files for ports, we currently do so with a max value of 12500000000 (100G). Because of this if a device sends us bad data back then it can appear as though a 100M port is doing 40G+ which is impossible. To counter this you can enable the rrdtool tune option which will fix the max value to the interfaces physical speed (minimum of 10M).

To enable this you can do so in three ways!

  • Globally under Global Settings -> Poller -> Datastore: RRDTool
  • For the actual device, Edit Device -> Misc
  • For each port, Edit Device -> Port Settings

Now when a port interface speed changes (this can happen because of a physical change or just because the device has misreported) the max value is set. If you don't want to wait until a port speed changes then you can run the included script:

./scripts/tune_port.php -h <hostname> -p <ifName>

Wildcards are supported using *, i.e:

./scripts/tune_port.php -h local* -p eth*

This script will then perform the rrdtool tune on each port found using the provided ifSpeed for that port.

Run ./scripts/tune_port.php to see help page.

"},{"location":"Extensions/Rancid/","title":"Rancid","text":"

Librenms can generate a list of hosts that can be monitored by RANCID. We assume you have currently a running Rancid, and you just need to create and update the file 'router.db'

"},{"location":"Extensions/Rancid/#included-rancid-script","title":"Included Rancid script","text":"

To generate the config file (maybe even add a cron to schedule this). We've assumed a few locations for Rancid, the config file you want to call it and where LibreNMS is:

cd /opt/librenms/scripts/\nphp ./gen_rancid.php > /the/path/where/is/rancid/core/router.db\n

Sample cron:

15   0    * * * root cd /opt/librenms/scripts && php ./gen_rancid.php > /the/path/where/is/rancid/core/router.db\n

Now configure LibreNMS (make sure you point dir to your rancid data directory):

$config['rancid_configs']['core'] = '/the/path/where/is/rancid/core';\n$config['rancid_ignorecomments'] = 0;\n

After that, you should see some \"config\" tab on routers that have a rancid update.

"},{"location":"Extensions/Rancid/#ubuntu-rancid-install","title":"Ubuntu Rancid Install","text":"

The options shown below also contains the default values.

NOTE - This is Only for Ubuntu 16.04 at this time, and may not work on other distros!

sudo apt-get install rancid subversion

Edit Rancid config file to use subversion or git instead of default cvs, and adds a group: sudo vi /etc/rancid/rancid.conf

LIST_OF_GROUPS=\"librenms\"

Now change these two lines:

CVSROOT=$BASEDIR/CVS; export CVSROOT\nRCSSYS=cvs; export RCSSYS\n

to:

CVSROOT=$BASEDIR/SVN; export CVSROOT\nRCSSYS=svn; export RCSSYS\n

NOTE - This only creates 1 group! You can of course make more when you get the hang of it, this is just a basic 'Need it to work\" deal.

sudo su -c /var/lib/rancid/bin/rancid-cvs -s /bin/bash -l rancid

NOTE - do NOT change cvs to svn here! Leave command as is!

Get a list of devices from Librenms you can pull configs from:

cd /opt/librenms/scripts\nsudo ./gen_rancid.php\n

Copy the output. Replace all \":\" with \";\" example:

alphcr1:cisco:up will change to:\nalphcr1;cisco;up\n

copy and past results into the below file: sudo vi /var/lib/rancid/librenms/router.db

NOTE - This ONLY applies to newer RANCID versions and Linux distros. Older versions will need to retain the : and not the ;

Create/edit rancids login file:

sudo vi /var/lib/rancid/.cloginrc

Add following at minimum:

add user * <your username here>\nadd password * <your password here>\nadd method * ssh\nadd noenable * {1}                         ******This disables the enable when using radius etc *******\n

Grant permissions for rancid:

sudo chown rancid /var/lib/rancid/.cloginrc\nsudo chmod 600 /var/lib/rancid/.cloginrc\n

Test config: sudo /usr/lib/rancid/bin/clogin -f /var/lib/rancid/.cloginrc <device hostname>

NOTE: IF you run into a 'diffie-hellmen' kind of error, then it is because your Linux distro is using newer encryption methods etc. This is basically just letting you know that the device you tested on is running an outdated encryption type. I recommend updating downstream device if able. If not, the following should fix:

sudo vi /etc/ssh/ssh_config

Add:

KexAlgorithms diffie-hellman-group1-sha1

Re-try logging into your device again

Upon success, run rancid:

sudo su -c /var/lib/rancid/bin/rancid-run -s /bin/bash -l rancid

Ensure your configs pulled:

sudo su - rancid\ncd librenms/configs/\nls\n

Make sure your config files are there :-)

sudo usermod -a -G rancid librenms\n

Add Rancid into LibreNMS config.php:

### Rancid\n$config['rancid_configs'][]             = '/var/lib/rancid/librenms/configs/';\n$config['rancid_repo_type']             = 'svn';  //'svn' or 'git'\n$config['rancid_ignorecomments']        = 0;\n

Now restart apache sudo /etc/init.d/apache2 restart

"},{"location":"Extensions/SNMP-Proxy/","title":"SNMP Proxy","text":"

If you have machines that you want to monitor but are not reachable directly, you can use SNMPD Proxy. This will use the reachable SNMPD to proxy requests to the unreachable SNMPD.

"},{"location":"Extensions/SNMP-Proxy/#example-configuration","title":"Example configuration","text":"

We want to poll 'unreachable.example.com' via

'hereweare.example.com'. Use the following config:

On 'hereweare.example.com':

        view all included .1\n        com2sec -Cn ctx_unreachable readonly <poller-ip> unreachable\n        access MyROGroup ctx_unreachable any noauth prefix all none none\n        proxy -Cn ctx_unreachable -v 2c -c private unreachable.example.com  .1.3\n

On 'unreachable.example.com':

        view all included .1                               80\n        com2sec readonly <hereweare.example.com ip address> private\n        group MyROGroup v1 readonly\n        group MyROGroup v2c readonly\n        group MyROGroup usm readonly\n        access MyROGroup \"\" any noauth exact all none none\n

You can now poll community 'private' on 'unreachable.example.com' via community 'unreachable' on host 'hereweare.example.com'. Please note that requests on 'unreachable.example.com' will be coming from 'hereweare.example.com', not your poller.

"},{"location":"Extensions/SNMP-Trap-Handler/","title":"SNMP trap handling","text":"

Currently, LibreNMS supports a lot of trap handlers. You can check them on GitHub here. To add more see Adding new SNMP Trap handlers. Traps are handled via snmptrapd.

snmptrapd is an SNMP application that receives and logs SNMP TRAP and INFORM messages.

The default is to listen on UDP port 162 on all IPv4 interfaces. Since 162 is a privileged port, snmptrapd must typically be run as root.

"},{"location":"Extensions/SNMP-Trap-Handler/#configure-snmptrapd","title":"Configure snmptrapd","text":"

Install snmptrapd via your package manager.

For example (Debian based systems):

sudo apt install snmptrapd -y\n

In /etc/snmp/snmptrapd.conf, add :

disableAuthorization yes\nauthCommunity log,execute,net COMMUNITYSTRING\ntraphandle default /opt/librenms/snmptrap.php\n

To enable snmptrapd to properly parse traps, we will need to add MIBs to service.

"},{"location":"Extensions/SNMP-Trap-Handler/#option-1","title":"Option 1","text":"

Make the folder /etc/systemd/system/snmptrapd.service.d/ and edit the file /etc/systemd/system/snmptrapd.service.d/mibs.conf and add the following content.

You may want to tweak to add vendor directories for devices you care about. In the example below, standard and cisco directories are defined, and only IF-MIB is loaded.

[Service]\nEnvironment=MIBDIRS=+/opt/librenms/mibs:/opt/librenms/mibs/cisco\nEnvironment=MIBS=+IF-MIB\n

For non-systemd systems, you can edit TRAPDOPTS in the init script in /etc/init.d/snmptrapd.

TRAPDOPTS=\"-Lsd -M /opt/librenms/mibs -m IF-MIB -f -p $TRAPD_PID\"

Along with any necessary configuration to receive the traps from your devices (community, etc.)

"},{"location":"Extensions/SNMP-Trap-Handler/#option-2","title":"Option 2","text":"

Tested on Ubuntu 18

Just set up your service like:

[Unit]\nDescription=Simple Network Management Protocol (SNMP) Trap Daemon.\nAfter=network.target\nConditionPathExists=/etc/snmp/snmptrapd.conf\n\n[Service]\nEnvironment=\"MIBSDIR=/opt/librenms/mibs\"\nType=simple\nExecStart=/usr/sbin/snmptrapd -f -m IF-MIB -M /opt/librenms/mibs\nExecReload=/bin/kill -HUP $MAINPID\n\n[Install]\nWantedBy=multi-user.target\n

In Ubuntu 18 is service located by default in /etc/systemd/system/multi-user.target.wants/snmptrapd.service

Here is a list of snmptrapd options:

Option Description -a Ignore authenticationFailure traps. [OPTIONAL] -f Do not fork from the shell -n Use numeric addresses instead of attempting hostname lookups (no DNS) [OPTIONAL] -m MIBLIST: use MIBLIST (FILE1-MIB:FILE2-MIB). ALL = Load all MIBS in DIRLIST. (usually fails) -M DIRLIST: use DIRLIST as the list of locations to look for MIBs. Option is not recursive, so you need to specify each DIR individually, separated by :. (For example: /opt/librenms/mibs:/opt/librenms/mibs/cisco:/opt/librenms/mibs/edgecos)

Good practice is to avoid -m ALL because then it will try to load all the MIBs in DIRLIST, which will typically fail (snmptrapd cannot load that many mibs). Better is to specify the exact MIB files defining the traps you are interested in, for example for LinkDown and LinkUp as well as BGP traps, use -m IF-MIB:BGP4-MIB. Multiple files can be added, separated with :.

If you want to test or store original TRAPS in log then:

Create a folder for storing traps for example in file traps.log

sudo mkdir /var/log/snmptrap\n

Add the following config to your snmptrapd.service after ExecStart=/usr/sbin/snmptrapd -f -m ALL -M /opt/librenms/mibs

-tLf /var/log/snmptrap/traps.log\n

On SELinux, you need to configure SELinux for SNMPd to communicate to LibreNMS:

cat > snmptrap.te << EOF\nmodule snmptrap 1.0;\n\nrequire {\n        type httpd_sys_rw_content_t;\n        type snmpd_t;\n        class file { append getattr open read };\n        class capability dac_override;\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t httpd_sys_rw_content_t:file { append getattr open read };\nallow snmpd_t self:capability dac_override;\nEOF\ncheckmodule -M -m -o snmptrap.mod snmptrap.te\nsemodule_package -o snmptrap.pp -m snmptrap.mod\nsemodule -i snmptrap.pp\n

After successfully configuring the service, reload service files, enable, and start the snmptrapd service:

sudo systemctl daemon-reload\nsudo systemctl enable snmptrapd\nsudo systemctl restart snmptrapd\n
"},{"location":"Extensions/SNMP-Trap-Handler/#testing","title":"Testing","text":"

The easiest test is to generate a trap from your device. Usually, changing the configuration on a network device, or plugging/unplugging a network cable (LinkUp, LinkDown) will generate a trap. You can confirm it using a with tcpdump, tshark or wireshark.

You can also generate a trap using the snmptrap command from the LibreNMS server itself (if and only if the LibreNMS server is monitored).

"},{"location":"Extensions/SNMP-Trap-Handler/#how-to-send-snmp-v2-trap","title":"How to send SNMP v2 Trap","text":"

The command below takes the form of:

snmptrap -v <snmp_version> -c <community> <destination_host> <uptime> <OID_or_MIB> <object> <value_type> <value>\n

Using OID's:

snmptrap -v 2c -c public localhost '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456\n

If you have configured logging of traps to /var/log/snmptrap/traps.log then you will see in traps.log new entry:

2020-03-09 16:22:59 localhost [UDP: [127.0.0.1]:58942->[127.0.0.1]:162]:\nSNMPv2-MIB::sysUpTime.0 = Timeticks: (149721964) 17 days, 7:53:39.64    SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.8072.2.3.0.1   SNMPv2-SMI::enterprises.8072.2.3.2.1 = INTEGER: 123456\n

and in LibreNMS your localhost device eventlog like:

2020-03-09 16:22:59             SNMP trap received: SNMPv2-SMI::enterprises.8072.2.3.0.1\n
"},{"location":"Extensions/SNMP-Trap-Handler/#why-we-need-uptime","title":"Why we need Uptime","text":"

When you send a trap, it must of course conform to a set of standards. Every trap needs an uptime value. Uptime is how long the system has been running since boot. Sometimes this is the operating system, other devices might use the SNMP engine uptime. Regardless, a value will be sent.

So what value should you type in the commands below? Oddly enough, simply supplying no value by using two single quotes '' will instruct the command to obtain the value from the operating system you are executing this on.

"},{"location":"Extensions/SNMP-Trap-Handler/#event-logging","title":"Event logging","text":"

You can configure generic event logging for snmp traps. This will log an event of the type trap for received traps. These events can be used for alerting. By default, only the TrapOID is logged. But you can enable the \"detailed\" variant, and all the data received with the trap will be logged.

The parameter can be found in General Settings / External / SNMP Traps Integration.

It can also be configured in your config.

external/snmptrapd

lnms config:set snmptraps.eventlog 'unhandled'\nlnms config:set snmptraps.eventlog_detailed false\n

Valid options are:

  • unhandled only unhandled traps will be logged (default value)
  • all log all traps
  • none no traps will create a generic event log (handled traps may still log events)
"},{"location":"Extensions/Services/","title":"Nagios Plugins - Services","text":"

Services within LibreNMS provides the ability to leverage Nagios plugins to perform additional monitoring outside of SNMP. Services can also be used in conjunction with your SNMP monitoring for larger monitoring functionality.

"},{"location":"Extensions/Services/#setting-up-services","title":"Setting up Services","text":"

Services must be tied to a device to function properly. A good generic option is to use localhost, but it is suggested to attach the check to the device you are monitoring.

"},{"location":"Extensions/Services/#nagios-plugins-source","title":"Nagios plugins source","text":"

Plugins come from two main sources:

  • monitoring-plugins
  • pkg-nagios-plugins-contrib

Note: Plugins will only load if they are prefixed with check_. The check_ prefix is stripped out when displaying in the \"Add Service\" GUI \"Type\" dropdown list.

"},{"location":"Extensions/Services/#service-templates","title":"Service Templates","text":"

Service Templates within LibreNMS provides the same ability as Nagios does with Host Groups. Known as Device Groups in LibreNMS. They are applied devices that belong to the specified Device Group.

Use the Apply buttons to manually create or update Services for the Service Template. Use the Remove buttons to manually remove Services for the Service Template.

After you Edit a Service Template, and then use Apply, all relevant changes are pushed to existing Services previously created.

You can also enable Service Templates Auto Discovery to have Services added / removed / updated on regular discover intervals.

When a Device is a member of multiple Device Groups, templates from all of those Device Groups are applied.

If a Device is added or removed from a Device Group, when the Apply button is used or Auto Discovery runs Services will be added / removed as appropriate.

Service Templates are tied into Device Groups, you need at least one Device Group to be able to add Service Templates - You can define a dummy one. The Device Group does not need members to add Service Templates.

"},{"location":"Extensions/Services/#service-auto-discovery","title":"Service Auto Discovery","text":"

To automatically create services for devices with available checks.

You need to enable the discover services within config.php with the following:

$config['discover_services']           = true;\n
"},{"location":"Extensions/Services/#service-templates-auto-discovery","title":"Service Templates Auto Discovery","text":"

To automatically create services for devices with configured Service Templates.

You need to enable the discover services within config.php with the following:

$config['discover_services_templates']           = true;\n
"},{"location":"Extensions/Services/#setup","title":"Setup","text":"

Service checks are now distributable if you run a distributed setup. To leverage this, use the dispatch service. Alternatively, you could also replace check-services.php with services-wrapper.py in cron instead to run across all polling nodes.

If you need to debug the output of services-wrapper.py then you can add -d to the end of the command - it is NOT recommended to do this in cron.

Firstly, install Nagios plugins.

Debian / Ubuntu: sudo apt install monitoring-plugins Centos: yum install nagios-plugins-all

Note: The plugins are bundled with the pre-build VM and Docker images.

Next, you need to enable the services within config.php with the following:

$config['show_services']           = 1;\n

This will enable a new service menu within your navbar.

Debian/Ubuntu:

$config['nagios_plugins']   = \"/usr/lib/nagios/plugins\";\n

Centos:

$config['nagios_plugins']   = \"/usr/lib64/nagios/plugins\";\n

This will point LibreNMS at the location of the nagios plugins - please ensure that any plugins you use are set to executable. For example:

Debian/Ubuntu:

chmod +x /usr/lib/nagios/plugins/*\n

Centos:

chmod +x /usr/lib64/nagios/plugins/*\n

Finally, you now need to add services-wrapper.py to the current cron file (/etc/cron.d/librenms typically) like:

*/5 * * * * librenms /opt/librenms/services-wrapper.py 1\n

Now you can add services via the main Services link in the navbar, or via the 'Add Service' link within the device, services page.

Note that some services (procs, inodes, load and similar) will always poll the local LibreNMS server it's running on, regardless of which device you add it to.

"},{"location":"Extensions/Services/#performance-data","title":"Performance data","text":"

By default, the check-services script will collect all performance data that the Nagios script returns and display each datasource on a separate graph. LibreNMS expects scripts to return using Nagios convention for the response message structure: AEN200

However for some modules it would be better if some of this information was consolidated on a single graph. An example is the ICMP check. This check returns: Round Trip Average (rta), Round Trip Min (rtmin) and Round Trip Max (rtmax). These have been combined onto a single graph.

If you find a check script that would benefit from having some datasources graphed together, please log an issue on GitHub with the debug information from the script, and let us know which DS's should go together. Example below:

    ./check-services.php -d\n    -- snip --\n    Nagios Service - 26\n    Request:  /usr/lib/nagios/plugins/check_icmp localhost\n    Perf Data - DS: rta, Value: 0.016, UOM: ms\n    Perf Data - DS: pl, Value: 0, UOM: %\n    Perf Data - DS: rtmax, Value: 0.044, UOM: ms\n    Perf Data - DS: rtmin, Value: 0.009, UOM: ms\n    Response: OK - localhost: rta 0.016ms, lost 0%\n    Service DS: {\n        \"rta\": \"ms\",\n        \"pl\": \"%\",\n        \"rtmax\": \"ms\",\n        \"rtmin\": \"ms\"\n    }\n    OK u:0.00 s:0.00 r:40.67\n    RRD[update /opt/librenms/rrd/localhost/services-26.rrd N:0.016:0:0.044:0.009]\n    -- snip --\n
"},{"location":"Extensions/Services/#alerting","title":"Alerting","text":"

Services uses the Nagios Alerting scheme where exit code:

    0 = Ok,\n    1 = Warning,\n    2 = Critical,\n

To create an alerting rule to alert on service=critical, your alerting rule would look like:

    %services.service_status = \"2\"\n
"},{"location":"Extensions/Services/#debug","title":"Debug","text":"

Change user to librenms for example

su - librenms\n

then you can run the following command to help troubleshoot services.

./check-services.php -d\n
"},{"location":"Extensions/Services/#related-polling-discovery-options","title":"Related Polling / Discovery Options","text":"

These settings are related and should be investigated and set accordingly. The below values are not defaults or recommended.

$config['service_poller_enabled']           = true;\n
$config['service_poller_workers']           = 16;\n
$config['service_poller_frequency']         = 300;\n
$config['service_poller_down_retry']        = 5;\n
$config['service_discovery_enabled']        = true;\n
$config['service_discovery_workers']        = 16;\n
$config['service_discovery_frequency']      = 3600;\n
$config['service_services_enabled']         = true;\n
$config['service_services_workers']         = 16;\n
$config['service_services_frequency']       = 60;\n

"},{"location":"Extensions/Services/#service-checks-polling-logic","title":"Service checks polling logic","text":"

Service check is skipped when the associated device is not pingable, and an appropriate entry is populated in the event log. Service check is polled if it's IP address parameter is not equal to associated device's IP address, even when the associated device is not pingable.

To override the default logic and always poll service checks, you can disable ICMP testing for any device by switching Disable ICMP Test setting (Edit -> Misc) to ON.

Service checks will never be polled on disabled devices.

"},{"location":"Extensions/Services/#check_mrpe","title":"CHECK_MRPE","text":"

In most cases, only Nagios plugins that run against a remote host with the -H option are available as services. However, if you're remote host is running the Check_MK agent you may be able to use MRPE to monitor Nagios plugins that only execute locally as services.

For example, consider the fairly common check_cpu.sh Nagios plugin. If you added..

cpu_check /usr/lib/nagios/plugins/check_cpu.sh -c 95 -w 75

...to /etc/check_mk/mrpe.cfg on your remote host, you should be able to check its output by configuring a service using the check_mrpe script.

  • Add check_mrpe to the Nagios plugins directory on your LibreNMS server and make it executable.
  • In LibreNMS, add a new service to the desired device with the type mrpe.
  • Enter the IP address of the remote host and in parameters enter -a cpu_check (this should match the name used at the beginning of the line in the mrpe.cfg file).
"},{"location":"Extensions/Smokeping/","title":"Smokeping integration","text":"

SmokePing is a tool which lets us keep track of network latency, and visualise this through RRD graphs.

LibreNMS has support for both new and pre-existing SmokePing installations.

For new installations, we can use the lnms cli to generate a Smokeping configuration file.

"},{"location":"Extensions/Smokeping/#pre-existing-smokeping-installation","title":"Pre-Existing Smokeping Installation","text":"

If you have an existing smokeping server, follow the instructions, you only need to look at Configure LibreNMS - All Operating Systems.

"},{"location":"Extensions/Smokeping/#new-installation","title":"New Installation","text":"

All installation steps assume a clean configuration - if you have an existing smokeping setup, you'll need to adapt these steps somewhat.

"},{"location":"Extensions/Smokeping/#install-and-integrate-smokeping-backend-rhel-centos-and-alike","title":"Install and integrate Smokeping Backend - RHEL, CentOS and alike","text":"

Smokeping is available via EPEL, which if you're running LibreNMS, you probably already have. If you want to do something like run Smokeping on a seperate host and ship data via RRCached though, here's the install command:

sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm\nsudo yum install smokeping\n

Once installed, you should need a cron script installed to make sure that the configuration file is updated. You can find an example in misc/librenms-smokeping-rhel.example. Put this into /etc/cron.d/hourly, and mark it executable:

sudo cp /opt/librenms/misc/smokeping-rhel.example /etc/cron.hourly/librenms-smokeping\nsudo chmod +x /etc/cron.hourly/librenms-smokeping\n

Finally, update the default configuration. Strip everything from the *** Probes *** and *** Targets *** stanza's, and replace with:

*** Probes ***\n\n@include /etc/smokeping/librenms-probes.conf\n
*** Targets ***\n\nprobe = FPing\n\nmenu = Top\ntitle = Network Latency Grapher\nremark = Welcome to the SmokePing website of <b>Insert Company Name Here</b>. \\\n         Here you will learn all about the latency of our network.\n\n@include /etc/smokeping/librenms-targets.conf\n

Note there may be other stanza's (possibly *** Slaves ***) between the *** Probes *** and *** Targets *** stanza's - leave these intact.

Leave everything else untouched. If you need to add other configuration, make sure it comes after the LibreNMS configuration, and keep in mind that Smokeping does not allow duplicate modules, and cares about the configuration file sequence.

Once you're happy, manually kick off the cron once, then enable and start smokeping:

sudo /etc/cron.hourly/librenms-smokeping\nsudo systemctl enable --now smokeping\n
"},{"location":"Extensions/Smokeping/#install-and-integrate-smokeping-backend-ubuntu-debian-and-alike","title":"Install and integrate Smokeping Backend - Ubuntu, Debian and alike","text":"

Smokeping is available via the default repositories.

sudo apt-get install smokeping\n

Once installed, you should need a cron script installed to make sure that the configuration file is updated. You can find an example in misc/librenms-smokeping-debian.example. Put this into /etc/cron.d/hourly, and mark it executable:

sudo cp /opt/librenms/misc/smokeping-debian.example /etc/cron.hourly/librenms-smokeping\nsudo chmod +x /etc/cron.hourly/librenms-smokeping\n

Finally, update the default configuration. Strip everything from /etc/smokeping/config.d/Probes and replace with:

*** Probes ***\n\n@include /etc/smokeping/config.d/librenms-probes.conf\n

Strip everything from /etc/smokeping/config.d/Targets and replace with:

*** Targets ***\n\nprobe = FPing\n\nmenu = Top\ntitle = Network Latency Grapher\nremark = Welcome to the SmokePing website of <b>Insert Company Name Here</b>. \\\n         Here you will learn all about the latency of our network.\n\n@include /etc/smokeping/config.d/librenms-targets.conf\n

Leave everything else untouched. If you need to add other configuration, make sure it comes after the LibreNMS configuration, and keep in mind that Smokeping does not allow duplicate modules, and cares about the configuration file sequence.

"},{"location":"Extensions/Smokeping/#configure-librenms-all-operating-systems","title":"Configure LibreNMS - All Operating Systems","text":"

external/smokeping

lnms config:set smokeping.dir '/var/lib/smokeping'\nlnms config:set smokeping.pings 20\nlnms config:set smokeping.probes 2\nlnms config:set smokeping.integration true\nlnms config:set smokeping.url 'smokeping/'\n

dir should match the location that smokeping writes RRD's to pings should match the default smokeping value, default 20 probes should be the number of processes to spread pings over, default 2

These settings can also be set in the Web UI.

"},{"location":"Extensions/Smokeping/#configure-smokepings-web-ui-optional","title":"Configure Smokeping's Web UI - Optional","text":"

This section covers the required configuration for your web server of choice. This covers the required configuration for either Apache or Nginx.

LibreNMS does not need the Web UI - you can find the graphs in LibreNMS on the latency tab.

"},{"location":"Extensions/Smokeping/#apache-configuration-ubuntu-debian-and-alike","title":"Apache Configuration - Ubuntu, Debian and alike","text":"

Edit the General configuration file's Owner and contact, and cgiurl hostname details:

nano /etc/smokeping/config.d/General\nowner    = LibreNMS-Admin\ncontact  = admin@ACME.xxx\ncgiurl   = http://yourlibrenms/cgi-bin/smokeping.cgi\n

Smokeping should automatically install an Apache configuration file in /etc/apache2/conf-available/. Verify this using :

librenms@librenms:~/scripts$ ls /etc/apache2/conf-available/ | grep smokeping\nsmokeping.conf\n

If you don't see smokeping.conf listed, you'll need to create a symlink for it:

ln -s /etc/smokeping/apache2.conf /etc/apache2/conf-available/smokeping.conf\n

After creating the symlink, restart Apache with sudo systemctl apache2 restart

You should be able to load the Smokeping web interface at http://yourhost/cgi-bin/smokeping.cgi

"},{"location":"Extensions/Smokeping/#nginx-configuration-rhel-centos-and-alike","title":"Nginx Configuration - RHEL, CentOS and alike","text":"

This section assumes you have configured LibreNMS with Nginx as specified in Configure Nginx.

Note, you need to install fcgiwrap for CGI wrapper interact with Nginx

yum install fcgiwrap\n
Then create a new configuration file for fcgiwrap in /etc/nginx/fcgiwrap.conf
# Include this file on your nginx.conf to support debian cgi-bin scripts using\n# fcgiwrap\nlocation /cgi-bin/ {\n  # Disable gzip (it makes scripts feel slower since they have to complete\n  # before getting gzipped)\n  gzip off;\n\n  # Set the root to /usr/lib (inside this location this means that we are\n  # giving access to the files under /usr/lib/cgi-bin)\n  #root /usr/lib;\n  root /usr/share/nginx;\n\n  # Fastcgi socket\n  fastcgi_pass  unix:/var/run/fcgiwrap.socket;\n\n  # Fastcgi parameters, include the standard ones\n  include /etc/nginx/fastcgi_params;\n\n  # Adjust non standard parameters (SCRIPT_FILENAME)\n  fastcgi_param SCRIPT_FILENAME  /usr/lib$fastcgi_script_name;\n} \n
Be sure to create the folder cgi-bin folder with required permissions (755)
mkdir /usr/share/nginx/cgi-bin\n
Create fcgiwrap systemd service in /usr/lib/systemd/system/fcgiwrap.service
# create new\n[Unit]\nDescription=Simple CGI Server\nAfter=nss-user-lookup.target\nRequires=fcgiwrap.socket\n\n[Service]\nEnvironmentFile=/etc/sysconfig/fcgiwrap\nExecStart=/usr/sbin/fcgiwrap ${DAEMON_OPTS} -c ${DAEMON_PROCS}\nUser=librenms\nGroup=librenms\n\n[Install]\nAlso=fcgiwrap.socket\n
The socket file in /usr/lib/systemd/system/fcgiwrap.socket
# create new\n[Unit]\nDescription=fcgiwrap Socket\n\n[Socket]\nListenStream=/var/run/fcgiwrap.socket\n\n[Install]\nWantedBy=sockets.target\n
Enable fcgiwrap
systemctl enable --now fcgiwrap\n

Add the following configuration to your /etc/nginx/conf.d/librenms.conf file within server section.

The following will configure Nginx to respond to http://yourlibrenms/smokeping:

location = /smokeping/ {\n        fastcgi_intercept_errors on;\n        fastcgi_param   SCRIPT_FILENAME         /usr/share/smokeping/cgi/smokeping.fcgi;\n        fastcgi_param   QUERY_STRING            $query_string;\n        fastcgi_param   REQUEST_METHOD          $request_method;\n        fastcgi_param   CONTENT_TYPE            $content_type;\n        fastcgi_param   CONTENT_LENGTH          $content_length;\n        fastcgi_param   REQUEST_URI             $request_uri;\n        fastcgi_param   DOCUMENT_URI            $document_uri;\n        fastcgi_param   DOCUMENT_ROOT           $document_root;\n        fastcgi_param   SERVER_PROTOCOL         $server_protocol;\n        fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;\n        fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;\n        fastcgi_param   REMOTE_ADDR             $remote_addr;\n        fastcgi_param   REMOTE_PORT             $remote_port;\n        fastcgi_param   SERVER_ADDR             $server_addr;\n        fastcgi_param   SERVER_PORT             $server_port;\n        fastcgi_param   SERVER_NAME             $server_name;\n        fastcgi_param   HTTPS                   $https if_not_empty;\n        fastcgi_pass unix:/var/run/fcgiwrap.socket;\n}\n\nlocation ^~ /smokeping/ {\n        alias /usr/share/smokeping/cgi/;\n        index smokeping.fcgi;\n        gzip off;\n}\n
If images/js/css don't load, you might have to add
location ^~ /smokeping/css {\n        alias /usr/share/smokeping/htdocs/css/;\n        gzip off;\n}\nlocation ^~ /smokeping/js {\n        alias /usr/share/smokeping/htdocs/js/;\n        gzip off;\n}\nlocation ^~ /smokeping/images {\n        alias /opt/librenms/rrd/smokeping/images;\n        gzip off;\n}\n
After saving the configuration file, verify your Nginx configuration file syntax is OK with sudo nginx -t, then restart Nginx with sudo systemctl restart nginx

You should be able to load the Smokeping web interface at http://yourlibrenms/smokeping

"},{"location":"Extensions/Smokeping/#nginx-configuration-ubuntu-debian-and-alike","title":"Nginx Configuration - Ubuntu, Debian and alike","text":"

This section assumes you have configured LibreNMS with Nginx as specified in Configure Nginx.

Note, you need to install fcgiwrap for CGI wrapper interact with Nginx

apt install fcgiwrap\n
Then configure Nginx with the default configuration

cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf\n

Add the following configuration to your /etc/nginx/conf.d/librenms.conf file within server section.

The following will configure Nginx to respond to http://yourlibrenms/smokeping:

# Browsing to `http://yourlibrenms/smokeping/` should bring up the smokeping web interface\n\nlocation = /smokeping/ {\n        fastcgi_intercept_errors on;\n\n        fastcgi_param   SCRIPT_FILENAME         /usr/lib/cgi-bin/smokeping.cgi;\n        fastcgi_param   QUERY_STRING            $query_string;\n        fastcgi_param   REQUEST_METHOD          $request_method;\n        fastcgi_param   CONTENT_TYPE            $content_type;\n        fastcgi_param   CONTENT_LENGTH          $content_length;\n        fastcgi_param   REQUEST_URI             $request_uri;\n        fastcgi_param   DOCUMENT_URI            $document_uri;\n        fastcgi_param   DOCUMENT_ROOT           $document_root;\n        fastcgi_param   SERVER_PROTOCOL         $server_protocol;\n        fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;\n        fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;\n        fastcgi_param   REMOTE_ADDR             $remote_addr;\n        fastcgi_param   REMOTE_PORT             $remote_port;\n        fastcgi_param   SERVER_ADDR             $server_addr;\n        fastcgi_param   SERVER_PORT             $server_port;\n        fastcgi_param   SERVER_NAME             $server_name;\n        fastcgi_param   HTTPS                   $https if_not_empty;\n\n        fastcgi_pass unix:/var/run/fcgiwrap.socket;\n}\n\nlocation ^~ /smokeping/ {\n        alias /usr/share/smokeping/www/;\n        index smokeping.cgi;\n        gzip off;\n}\n

After saving the configuration file, verify your Nginx configuration file syntax is OK with sudo nginx -t, then restart Nginx with sudo systemctl restart nginx

You should be able to load the Smokeping web interface at http://yourlibrenms/smokeping

"},{"location":"Extensions/Smokeping/#nginx-password-authentication","title":"Nginx Password Authentication","text":"

You can use the purpose-made htpasswd utility included in the apache2-utils package (Nginx password files use the same format as Apache). You can install it on Ubuntu with

apt install apache2-utils\n

After that you need to create password for your user

htpasswd -c /etc/nginx/.htpasswd USER\n

You can verify your user and password with

cat /etc/nginx/.htpasswd\n

Then you just need to add to your config auth_basic parameters

        location ^~ /smokeping/ {\n                alias /usr/share/smokeping/www/;\n                index smokeping.cgi;\n                gzip off;\n                auth_basic \"Private Property\";\n                auth_basic_user_file /etc/nginx/.htpasswd;\n        }\n
"},{"location":"Extensions/Smokeping/#common-problems","title":"Common Problems","text":""},{"location":"Extensions/Smokeping/#rrdsupdate-error-opening-permission-denied","title":"RRDs::update ERROR: opening ... Permission denied","text":"

There is a problem writing to the RRD directory. This is somewhat out of scope of LibreNMS, but make sure that file permissions and SELinux labels allow the smokeping user to write to the directory.

If you're using RRDCacheD, make sure that the permissions are correct there too, and that if you're using -B that the smokeping RRD's are inside the base directory; update the smokeping rrd directory if required.

It's not recommended to run RRDCachedD without the -B switch.

"},{"location":"Extensions/Smokeping/#share-rrdcached-with-librenms","title":"Share RRDCached with LibreNMS","text":"

Move the RRD's and give smokeping access rights to the LibreNMS RRD directory:

sudo systemctl stop smokeping\nsudo mv /var/lib/smokeping /opt/librenms/rrd/\nsudo usermod -a -G librenms smokeping\n

Update data directory in /etc/smokeping:

datadir = /opt/librenms/rrd/smokeping\ndyndir = /opt/librenms/rrd/smokeping/__cgi\n

If you have SELinux on, see next section before starting smokeping. Finally restart the smokeping service:

sudo systemctl start smokeping\n

Remember to update your config with the new locations.

"},{"location":"Extensions/Smokeping/#configure-selinux-to-allow-smokeping-to-write-in-librenms-directory-on-centos-rhel","title":"Configure SELinux to allow smokeping to write in LibreNMS directory on Centos / RHEL","text":"

If you are using RRDCached with the -B switch and smokeping RRD's inside the LibreNMS RRD base directory, you can install this SELinux profile:

cat > smokeping_librenms.te << EOF\nmodule smokeping_librenms 1.0;\n\nrequire {\ntype httpd_t;\ntype smokeping_t;\ntype smokeping_var_lib_t;\ntype var_run_t;\ntype httpd_sys_rw_content_t;\nclass dir { add_name create getattr read remove_name search write };\nclass file { create getattr ioctl lock open read rename setattr unlink write };\n}\n\n#============= httpd_t ==============\n\nallow httpd_t smokeping_var_lib_t:dir read;\nallow httpd_t var_run_t:file { read write };\n\n#============= smokeping_t ==============\n\nallow smokeping_t httpd_sys_rw_content_t:dir { add_name create getattr remove_name search write };\nallow smokeping_t httpd_sys_rw_content_t:file { create getattr ioctl lock open read rename setattr unlink write };\nEOF\ncheckmodule -M -m -o smokeping_librenms.mod smokeping_librenms.te\nsemodule_package -o smokeping_librenms.pp -m smokeping_librenms.mod\nsemodule -i smokeping_librenms.pp\n
"},{"location":"Extensions/Smokeping/#probe-fping-missing-missing-from-the-probes-section","title":"Probe FPing missing missing from the probes section","text":"

Take a look at the instructions again - something isn't correct in your configuration.

"},{"location":"Extensions/Smokeping/#section-or-variable-already-exists","title":"Section or variable already exists","text":"

Most likely, content wasn't fully removed from the *** Probes *** *** Targets*** stanza's as instructed. If you're trying to integrate LibreNMS, smokeping and another source of configuration, you're probably trying to redefine a module (e.g. '+ FPing' more than once) or stanza. Otherwise, look again at the instructions.

"},{"location":"Extensions/Smokeping/#mandatory-variable-probe-not-defined","title":"Mandatory variable 'probe' not defined","text":"

The target block must have a default probe. If you follow the instructions you will have one. If you're trying to integrate LibreNMS, smokeping and another source of configuration, you need to make sure there are no duplicate or missing definitions.

"},{"location":"Extensions/Smokeping/#file-usrsbinsendmail-does-not-exist","title":"File '/usr/sbin/sendmail' does not exist`","text":"

If you got this error at the end of the installation, simply edit or comment out the sendmail entry in the configuration:

-sendmail = /usr/sbin/sendmail\n+#sendmail = /usr/sbin/sendmail\n
"},{"location":"Extensions/Sub-Directory/","title":"Sub-directory Support","text":"

To run LibreNMS under a subdirectory on your Apache server, the directives for the LibreNMS directory are placed in the base server configuration, or in a virtual host container of your choosing. If using a virtual host, place the directives in the file where the virtual host is configured. If using the base server on RHEL distributions (CentOS, Scientific Linux, etc.) the directives can be placed in /etc/httpd/conf.d/librenms.conf. For Debian distributions (Ubuntu, etc.) place the directives in /etc/apache2/sites-available/default.

#These directives can be inside a virtual host or in the base server configuration\nAllowEncodedSlashes On\nAlias /librenms /opt/librenms/html\n\n<Directory \"/opt/librenms/html\">\n    AllowOverride All\n    Options FollowSymLinks MultiViews\n</Directory>\n

The RewriteBase directive in html/.htaccess must be rewritten to reference the subdirectory name. Assuming LibreNMS is running at http://example.com/librenms/, you will need to change RewriteBase / to RewriteBase /librenms.

Finally, set APP_URL=/librenms/ in .env and lnms config:set base_url '/librenms/'.

"},{"location":"Extensions/Supermicro/","title":"Supermicro","text":"

For some Supermicro information to show up in LibreNMS, you will need to install an agent.

"},{"location":"Extensions/Supermicro/#supermicro-superdoctor","title":"Supermicro SuperDoctor","text":"

Install Supermicro SuperDoctor onto the device you want to monitor.

Then add the following to /etc/snmp/snmpd.conf:

pass .1.3.6.1.4.1.10876 /usr/bin/sudo /opt/Supermicro/SuperDoctor5/libs/native/snmpagent\n

Restart net-snmp:

service snmpd restart\n
"},{"location":"Extensions/Syslog/","title":"Syslog support","text":""},{"location":"Extensions/Syslog/#syslog-integration-variants","title":"Syslog integration variants","text":"

This section explain different ways to recieve and process syslog with LibreNMS. Except of graylog, all Syslogs variants store their logs in the LibreNMS database. You need to enable the Syslog extension in config.php:

$config['enable_syslog'] = 1;\n
A Syslog integration gives you a centralized view of information within the LibreNMS (device view, traps, event). Further more you can trigger alerts based on syslog messages (see rule collections).

"},{"location":"Extensions/Syslog/#traditional-syslog-server","title":"Traditional Syslog server","text":""},{"location":"Extensions/Syslog/#syslog-ng","title":"syslog-ng","text":"Debian / UbuntuCentOS / RedHat
apt-get install syslog-ng-core\n
yum install syslog-ng\n

Once syslog-ng is installed, create the config file (/etc/syslog-ng/conf.d/librenms.conf) and paste the following:

source s_net {\n        tcp(port(514) flags(syslog-protocol));\n        udp(port(514) flags(syslog-protocol));\n};\n\ndestination d_librenms {\n        program(\"/opt/librenms/syslog.php\" template (\"$HOST||$FACILITY||$PRIORITY||$LEVEL||$TAG||$R_YEAR-$R_MONTH-$R_DAY $R_HOUR:$R_MIN:$R_SEC||$MSG||$PROGRAM\\n\") template-escape(yes));\n};\n\nlog {\n        source(s_net);\n        source(s_src);\n        destination(d_librenms);\n};\n

Next start syslog-ng:

service syslog-ng restart\n

If no messages make it to the syslog tab in LibreNMS, chances are you experience an issue with SELinux. If so, create a file mycustom-librenms-rsyslog.te , with the following content:

module mycustom-librenms-rsyslog 1.0;\n\nrequire {\n        type syslogd_t;\n        type httpd_sys_rw_content_t;\n        type ping_exec_t;\n        class process execmem;\n        class dir { getattr search write };\n        class file { append getattr execute open read };\n}\n\n#============= syslogd_t ==============\nallow syslogd_t httpd_sys_rw_content_t:dir { getattr search write };\nallow syslogd_t httpd_sys_rw_content_t:file { open read append getattr };\nallow syslogd_t self:process execmem;\nallow syslogd_t ping_exec_t:file execute;\n

Then, as root, execute the following commands:

checkmodule -M -m -o mycustom-librenms-rsyslog.mod mycustom-librenms-rsyslog.te\nsemodule_package -o mycustom-librenms-rsyslog.pp -m mycustom-librenms-rsyslog.mod\nsemodule -i mycustom-librenms-rsyslog.pp\n
"},{"location":"Extensions/Syslog/#rsyslog","title":"rsyslog","text":"

If you prefer rsyslog, here are some hints on how to get it working.

Add the following to your rsyslog config somewhere (could be at the top of the file in the step below, could be in rsyslog.conf if you are using remote logs for something else on this host)

# Listen for syslog messages on UDP:514\n$ModLoad imudp\n$UDPServerRun 514\n

Create a file called /etc/rsyslog.d/30-librenms.confand add the following depending on your version of rsyslog.

Version 8Version 7Legacy
# Feed syslog messages to librenms\nmodule(load=\"omprog\")\n\ntemplate(name=\"librenms\"\n        type=\"string\"\n        string= \"%fromhost%||%syslogfacility%||%syslogpriority%||%syslogseverity%||%syslogtag%||%$year%-%$month%-%$day% %timegenerated:8:25%||%msg%||%programname%\\n\")\n        action(type=\"omprog\"\n        binary=\"/opt/librenms/syslog.php\"\n        template=\"librenms\")\n\n& stop\n
#Feed syslog messages to librenms\n$ModLoad omprog\n\n$template librenms,\"%fromhost%||%syslogfacility%||%syslogpriority%||%syslogseverity%||%syslogtag%||%$year%-%$month%-%$day% %timegenerated:8:25%||%msg%||%programname%\\n\"\n\n*.* action(type=\"omprog\" binary=\"/opt/librenms/syslog.php\" template=\"librenms\")\n\n& stop\n
# Feed syslog messages to librenms\n$ModLoad omprog\n$template librenms,\"%FROMHOST%||%syslogfacility-text%||%syslogpriority-text%||%syslogseverity%||%syslogtag%||%$YEAR%-%$MONTH%-%$DAY%    %timegenerated:8:25%||%msg%||%programname%\\n\"\n\n$ActionOMProgBinary /opt/librenms/syslog.php\n*.* :omprog:;librenms\n

If your rsyslog server is receiving messages relayed by another syslog server, you may try replacing %fromhost% with %hostname%, since fromhost is the host the message was received from, not the host that generated the message. The fromhost property is preferred as it avoids problems caused by devices sending incorrect hostnames in syslog messages.

"},{"location":"Extensions/Syslog/#local-logstash","title":"Local Logstash","text":"

If you prefer logstash, and it is installed on the same server as LibreNMS, here are some hints on how to get it working.

First, install the output-exec plugin for logstash:

/usr/share/logstash/bin/logstash-plugin install logstash-output-exec\n

Next, create a logstash configuration file (ex. /etc/logstash/conf.d/logstash-simple.conf), and add the following:

input {\nsyslog {\n    port => 514\n  }\n}\n\n\noutput {\n        exec {\n        command => \"echo `echo %{host},,,,%{facility},,,,%{priority},,,,%{severity},,,,%{facility_label},,,,``date --date='%{timestamp}' '+%Y-%m-%d %H:%M:%S'``echo ',,,,%{message}'``echo ,,,,%{program} | sed 's/\\x25\\x7b\\x70\\x72\\x6f\\x67\\x72\\x61\\x6d\\x7d/%{facility_label}/'` | sed 's/,,,,/||/g' | /opt/librenms/syslog.php &\"\n        }\n        elasticsearch {\n        hosts => [\"10.10.10.10:9200\"]\n        index => \"syslog-%{+YYYY.MM.dd}\"\n        }\n}\n

Replace 10.10.10.10 with your primary elasticsearch server IP, and set the incoming syslog port. Alternatively, if you already have a logstash config file that works except for the LibreNMS export, take only the \"exec\" section from output and add it.

"},{"location":"Extensions/Syslog/#remote-logstash-or-any-json-source","title":"Remote Logstash (or any json source)","text":"

If you have a large logstash / elastic installation for collecting and filtering syslogs, you can simply pass the relevant logs as json to the LibreNMS API \"syslog sink\". This variant may be more flexible and secure in transport. It does not require any major changes to existing ELK setup. You can also pass simple json kv messages from any kind of application or script (example below) to this sink.

For long term or advanced aggregation searches you might still use Kibana/Grafana/Graylog etc. It is recommended to keep config['syslog_purge'] short.

A schematic setup can look like this:

  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2502Device\u251c\u2500\u25ba\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502Logstash Cluster   \u251c\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba\u2502ElasticSearch \u251c\u2510\n            \u2502  RabbitMQ         \u2502\u2502               \u2502 Cluster      \u2502\u2502\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u25ba\u2502    Filtering etc  \u2502\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u2514\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2502\n \u2502Device\u2502   \u2514\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2502        \u2502       \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518        \u25bc\n                                      ~~~WAN~~~\n                                          \u2502\n                                        \u250c\u2500\u253c\u2500\u2510\n                                        \u2502\u253c\u253c\u253c\u2502 LB / Firewall / etc\n                                        \u2514\u2500\u253c\u2500\u2518\n                                          \u2502\n                                          \u25bc\n                         \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                         \u2502LibreNMS Sink       \u251c\u252c\u2500\u2500\u25ba\u2502LibreNMS Master     \u2502\n                         \u2502/api/v0/syslogsink/ \u2502\u2502   \u2502 MariaDB            \u2502\n                         \u2514\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2502   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                          \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

A minimal Logstash http output configuration can look like this:

output {\n....\n        #feed it to LibreNMS\n        http {\n            http_method => \"post\"\n            url => \"https://sink.librenms.org/api/v0/syslogsink/    # replace with your librenms host\n            format => \"json_batch\"                                  # put multiple syslogs in on HTTP message\n                retry_failed => false                               # if true, logstash is blocking if the API is unavailable, be careful! \n                headers => [\"X-Auth-Token\",\"xxxxxxxLibreNMSApiToken]\n\n                # optional if your mapping is not already done before or does not match. \"msg\" and \"host\" is mandatory. \n                # you might also use out the clone {} function to duplicate your log stream and a dedicated log filtering/mapping etc.\n                # mapping => {\n                # \"host\"=> \"%{host}\"\n                # \"program\" => \"%{program}\"\n                # \"facility\" => \"%{facility_label}\"\n                # \"priority\" => \"%{syslog5424_pri}\"\n                # \"level\" => \"%{facility_label}\"                \n                # \"tag\" => \"%{topic}\"\n                # \"msg\" => \"%{message}\"\n                # \"timestamp\" => \"%{@timestamp}\"\n                # }\n        }\n}\n

Sample test data:

curl -L -X POST 'https://sink.librenms.org/api/v0/syslogsink/' -H 'X-Auth-Token: xxxxxxxLibreNMSApiToken' --data-raw '[   \n    {\n        \"msg\": \"kernel: minimum Message\",\n        \"host\": \"mydevice.fqdn.com\"\n    },\n    {\n        \"msg\": \"Line protocol on Interface GigabitEthernet1/0/41, changed state to up\",\n        \"facility\": 23,\n        \"priority\": \"189\",\n        \"program\": \"LINEPROTO-5-UPDOWN\",\n        \"host\": \"172.29.10.24\",\n        \"@timestamp\": \"2022-12-01T20:14:28.257Z\",\n        \"severity\": 5,\n        \"level\": \"ERROR\"\n    },\n    {\n        \"msg\": \"kernel: a unknown host\",\n        \"host\": \"unknown.fqdn.com\"\n    }\n]'\n
msg and host are the minimum keys.

"},{"location":"Extensions/Syslog/#graylog","title":"Graylog","text":"

This variant method use a external Graylog installation and its database. Please refer to the dedicated Graylog documentation.

"},{"location":"Extensions/Syslog/#client-configuration","title":"Client configuration","text":"

Below are sample configurations for a variety of clients. You should understand the config before using it as you may want to make some slight changes. Further configuration hints may be found in the file Graylog.md.

Replace librenms.ip with IP or hostname of your LibreNMS install.

Replace any variables in with the relevant information."},{"location":"Extensions/Syslog/#syslog","title":"syslog","text":"

*.*     @librenms.ip\n
"},{"location":"Extensions/Syslog/#rsyslog_1","title":"rsyslog","text":"
*.* @librenms.ip:514\n
"},{"location":"Extensions/Syslog/#cisco-asa","title":"Cisco ASA","text":"
logging enable\nlogging timestamp\nlogging buffer-size 200000\nlogging buffered debugging\nlogging trap notifications\nlogging host <outside interface name> librenms.ip\n
"},{"location":"Extensions/Syslog/#cisco-ios","title":"Cisco IOS","text":"
logging trap debugging\nlogging facility local6\nlogging librenms.ip\n
"},{"location":"Extensions/Syslog/#cisco-nxos","title":"Cisco NXOS","text":"
logging server librenms.ip 5 use-vrf default facility local6\n
"},{"location":"Extensions/Syslog/#juniper-junos","title":"Juniper Junos","text":"
set system syslog host librenms.ip authorization any\nset system syslog host librenms.ip daemon any\nset system syslog host librenms.ip kernel any\nset system syslog host librenms.ip user any\nset system syslog host librenms.ip change-log any\nset system syslog host librenms.ip source-address <management ip>\nset system syslog host librenms.ip exclude-hostname\nset system syslog time-format\n
"},{"location":"Extensions/Syslog/#huawei-vrp","title":"Huawei VRP","text":"
info-center loghost librenms.ip\ninfo-center timestamp debugging short-date without-timezone // Optional\ninfo-center timestamp log short-date // Optional\ninfo-center timestamp trap short-date // Optional\n//This is optional config, especially if the device is in public ip and you dont'want to get a lot of messages of ACL\ninfo-center filter-id bymodule-alias VTY ACL_DENY\ninfo-center filter-id bymodule-alias SSH SSH_FAIL\ninfo-center filter-id bymodule-alias SNMP SNMP_FAIL\ninfo-center filter-id bymodule-alias SNMP SNMP_IPLOCK\ninfo-center filter-id bymodule-alias SNMP SNMP_IPUNLOCK\ninfo-center filter-id bymodule-alias HTTP ACL_DENY\n
"},{"location":"Extensions/Syslog/#huawei-smartax-gpon-olt","title":"Huawei SmartAX (GPON OLT)","text":"
loghost add librenms.ip librenms\nloghost activate name librenms\n
"},{"location":"Extensions/Syslog/#allied-telesis-alliedware-plus","title":"Allied Telesis Alliedware Plus","text":"
log date-format iso // Required so syslog-ng/LibreNMS can correctly interpret the log message formatting.\nlog host x.x.x.x\nlog host x.x.x.x level <errors> // Required. A log-level must be specified for syslog messages to send.\nlog host x.x.x.x level notices program imish // Useful for seeing all commands executed by users.\nlog host x.x.x.x level notices program imi // Required for Oxidized Syslog hook log message.\nlog host source <eth0>\n
"},{"location":"Extensions/Syslog/#hpearuba-procurve","title":"HPE/Aruba Procurve","text":"
configure\nlogging severity warning\nlogging facility local6\nlogging librenms.ip control-descr \u201cLibreNMS\u201d\nlogging notify running-config-change\nwrite memory\n

If you have permitted udp and tcp 514 through any firewall then that should be all you need. Logs should start appearing and displayed within the LibreNMS web UI.

"},{"location":"Extensions/Syslog/#windows","title":"Windows","text":"

By Default windows has no native way to send logs to a remote syslog server.

Using this how to you can download Datagram-Syslog Agent to send logs to a remote syslog server (LibreNMS).

"},{"location":"Extensions/Syslog/#note","title":"Note","text":"

Keep in mind you can use any agent or program to send the logs. We are just using this Datagram-Syslog Agent for this example.

Link to How to

You will need to download and install \"Datagram-Syslog Agent\" for this how to Link to Download

"},{"location":"Extensions/Syslog/#external-hooks","title":"External hooks","text":"

Trigger external scripts based on specific syslog patterns being matched with syslog hooks. Add the following to your LibreNMS config.php to enable hooks:

$config['enable_syslog_hooks'] = 1;\n

The below are some example hooks to call an external script in the event of a configuration change on Cisco ASA, IOS, NX-OS and IOS-XR devices. Add to your config.php file to enable.

"},{"location":"Extensions/Syslog/#cisco-asa_1","title":"Cisco ASA","text":"
$config['os']['asa']['syslog_hook'][] = Array('regex' => '/%ASA-(config-)?5-111005/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#cisco-ios_1","title":"Cisco IOS","text":"
$config['os']['ios']['syslog_hook'][] = Array('regex' => '/%SYS-(SW[0-9]+-)?5-CONFIG_I/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#cisco-nxos_1","title":"Cisco NXOS","text":"
$config['os']['nxos']['syslog_hook'][] = Array('regex' => '/%VSHD-5-VSHD_SYSLOG_CONFIG_I/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#cisco-iosxr","title":"Cisco IOSXR","text":"
$config['os']['iosxr']['syslog_hook'][] = Array('regex' => '/%GBL-CONFIG-6-DB_COMMIT/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#juniper-junos_1","title":"Juniper Junos","text":"
$config['os']['junos']['syslog_hook'][] = Array('regex' => '/UI_COMMIT:/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#juniper-screenos","title":"Juniper ScreenOS","text":"
$config['os']['screenos']['syslog_hook'][] = Array('regex' => '/System configuration saved/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#allied-telesis-alliedware-plus_1","title":"Allied Telesis Alliedware Plus","text":"

Note: At least software version 5.4.8-2.1 is required. log host x.x.x.x level notices program imi may also be required depending on configuration. This is to ensure the syslog hook log message gets sent to the syslog server.

$config['os']['awplus']['syslog_hook'][] = Array('regex' => '/IMI.+.Startup-config saved on/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#hpearuba-procurve_1","title":"HPE/Aruba Procurve","text":"
$config['os']['procurve']['syslog_hook'][] = Array('regex' => '/Running Config Change/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
"},{"location":"Extensions/Syslog/#configuration-options","title":"Configuration Options","text":""},{"location":"Extensions/Syslog/#syslog-clean-up","title":"Syslog Clean Up","text":"

Can be set inside of config.php

$config['syslog_purge'] = 30;\n

The cleanup is run by daily.sh and any entries over X days old are automatically purged. Values are in days. See here for more Clean Up Options Link

"},{"location":"Extensions/Syslog/#matching-syslogs-to-hosts-with-different-names","title":"Matching syslogs to hosts with different names","text":"

In some cases, you may get logs that aren't being associated with the device in LibreNMS. For example, in LibreNMS the device is known as \"ne-core-01\", and that's how DNS resolves. However, the received syslogs are for \"loopback.core-nw\".

To fix this issue, you can configure LibreNMS to translate the incoming syslog hostname into another hostname, so that the logs get associated with the correct device.

Example:

$config['syslog_xlate'] = array(\n        'loopback0.core7k1.noc.net' => 'n7k1-core7k1',\n        'loopback0.core7k2.noc.net' => 'n7k2-core7k2'\n);\n
"},{"location":"Extensions/Two-Factor-Auth/","title":"Two-Factor Authentication","text":"

Over the last couple of years, the primary attack vector for internet accounts has been static passwords. Therefore static passwords are no longer sufficient to protect unauthorized access to accounts. Two Factor Authentication adds a variable part in authentication procedures. A user is now required to supply a changing 6-digit passcode in addition to their password to obtain access to the account.

LibreNMS has a RFC4226 conformant implementation of both Time and Counter based One-Time-Passwords. It also allows the administrator to configure a throttle time to enforce after 3 failures exceeded. Unlike RFC4226 suggestions, this throttle time will not stack on the amount of failures.

"},{"location":"Extensions/Two-Factor-Auth/#types","title":"Types","text":"

In general, these two types do not differ in algorithmic terms. The types only differ in the variable being used to derive the passcodes from. The underlying HMAC-SHA1 remains the same for both types, security advantages or disadvantages of each are discussed further down.

"},{"location":"Extensions/Two-Factor-Auth/#timebased-one-time-password-totp","title":"Timebased One-Time-Password (TOTP)","text":"

Like the name suggests, this type uses the current Time or a subset of it to generate the passcodes. These passcodes solely rely on the secrecy of their Secretkey in order to provide passcodes. An attacker only needs to guess that Secretkey and the other variable part is any given time, presumably the time upon login. RFC4226 suggests a resynchronization attempt in case the passcode mismatches, providing the attacker a range of up to +/- 3 Minutes to create passcodes.

"},{"location":"Extensions/Two-Factor-Auth/#counterbased-one-time-password-hotp","title":"Counterbased One-Time-Password (HOTP)","text":"

This type uses an internal counter that needs to be in sync with the server's counter to successfully authenticate the passcodes. The main advantage over timebased OTP is the attacker doesn't only need to know the Secretkey but also the server's Counter in order to create valid passcodes. RFC4226 suggests a resynchronization attempt in case the passcode mismatches, providing the attacker a range of up to +4 increments from the actual counter to create passcodes.

"},{"location":"Extensions/Two-Factor-Auth/#configuration","title":"Configuration","text":""},{"location":"Extensions/Two-Factor-Auth/#webui","title":"WebUI","text":"

Enable 'Two-Factor' Via Global Settings in the Web UI under Authentication -> General Authentication Settings.

Optionally enter a throttle timer in seconds. This will unlock an account after this time once it has failed 3 attempt to authenticate. Set to 0 (default) to disable this feature, meaning accounts will remain locked after 3 attempts and will need an administrator to clear.

"},{"location":"Extensions/Two-Factor-Auth/#cli","title":"CLI","text":"

Enable Two-Factor:

./lnms config:set twofactor true

Set throttle-time (in seconds):

./lnms config:set twofactor_lock 300

"},{"location":"Extensions/Two-Factor-Auth/#user-administation","title":"User Administation","text":"

If Two-Factor is enabled, the Settings -> Manage Users grid will show a '2FA' column containing a green tick for users with active 2FA.

There is no functionality to mandate 2FA for users.

If a user has failed 3 attempts, their account can be unlocked or 2FA disabled by editing the user from the Manage Users table.

If a throttle timer is set, it will unlock accounts after this time. If set to the default of 0, accounts will need to be manually unlocked by an administrator after 3 failed attempts.

Locked accounts will report to the user stating to wait for the throttle time period, or to contact the administrator if no timer set.

"},{"location":"Extensions/Two-Factor-Auth/#end-user-enrolment","title":"End-User Enrolment","text":"

These steps imply that Two-Factor has been enabled system wide as above under Configuration.

2FA is enabled by each user once they are logged in normally:

  • Go to 'My Settings' (/preferences/)
  • Choose TwoFactor type
  • Click on 'Generate TwoFactor Secret Key'
  • If your browser didn't reload, reload manually
  • Scan provided QR or click on 'Manual' to see the Key
"},{"location":"Extensions/Two-Factor-Auth/#google-authenticator","title":"Google Authenticator","text":"

Installation guides for Google Authenticator can be found here.

Usage:

  • Create a key as described above
  • Scan provided QR or click on 'Manual' and enter the Secret
  • On next login, enter the passcode that the App provides
"},{"location":"Extensions/Two-Factor-Auth/#lastpass-authenticator","title":"LastPass Authenticator","text":"

LastPass Authenticator is confirmed to work with Timebased One-Time Passwords (TOTP).

Installation guide for LastPass Authenticator can be found here.

Usage:

  • Create a Timerbased key as described above
  • Click Add (+) and scan provided QR or click on 'NO QR CODE?' and enter naming details and the Secret
  • On next login, enter the passcode that the App provides
"},{"location":"Extensions/Varnish/","title":"Varnish Installation Guide","text":"

This document explains how to install Varnish Reverse Proxy for LibreNMS.

Varnish is caching software that sits logically between an HTTP client and an HTTP server. Varnish caches HTTP responses from the HTTP server. If an HTTP request can not be responded to by the Varnish cache it directs the request to the HTTP Server. This type of HTTP caching is called a reverse proxy server. Caching your HTTP server can decrease page load times significantly.

"},{"location":"Extensions/Varnish/#architecture","title":"Architecture","text":"

Simplified block diagram of an Apache HTTP server with Varnish 4.0 Reverse Proxy

"},{"location":"Extensions/Varnish/#centos-7-varnish-installation","title":"CentOS 7 Varnish Installation","text":"

In this example we will assume your Apache 2.4.X HTTP server is working and configured to process HTTP requests on port 80. If not, please see Installing LibreNMS

"},{"location":"Extensions/Varnish/#install-varnish-40-rpm","title":"Install Varnish 4.0 RPM","text":"
  • Enable the Varnish CentOS 7 repo and install
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el7.rpm\nyum install varnish\n

By default Varnish listens for HTTP requests on port 6081.

  • Temporarily add a firewalld rule for testing Varnish.
firewall-cmd --zone=public --add-port=6081/tcp\n
"},{"location":"Extensions/Varnish/#test-varnish","title":"Test Varnish","text":"
  • Start Varnish
systemctl start varnish\n

Using a web browser navigate to :6081 or 127.0.0.1:6081. You should see a Varnish error message, this shows that Varnish is working. Example error message:

Error 503 Backend fetch failed\n\nBackend fetch failed\n\nGuru Meditation:\n\nXID: 3\n\nVarnish cache server\n
"},{"location":"Extensions/Varnish/#edit-varnish-parameters","title":"Edit Varnish Parameters","text":"

Now we need to configure Varnish to listen to HTTP requests on port 80 and relay those requests to the Apache HTTP server on port 8080 (see block diagram).

  • Stop Varnish.
systemctl stop varnish\n
  • Create a back-up of varnish.params just in case you make a mistake.
cp /etc/varnish/varnish.params /etc/varnish/varnish.params.bak\n
  • Edit the varnish.params config.
vim /etc/varnish/varnish.params\n

Set the VCL location, IP address, port, and cache location and size. malloc sets the cache location to RAM, and 512M sets the cache size to 512MB.

VARNISH_LISTEN_ADDRESS=192.168.1.10\nVARNISH_LISTEN_PORT=80\nVARNISH_VCL_CONF=/etc/varnish/librenms.vcl\nVARNISH_STORAGE=\"malloc,512M\"\n

Example varnish.params:

# Set this to 1 to make systemd reload try to switch vcl without restart.\nRELOAD_VCL=1\n\n# Main configuration file. You probably want to change it.\nVARNISH_VCL_CONF=/etc/varnish/librenms.vcl\n\n# Default address and port to bind to. Blank address means all IPv4\n# and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted\n# quad, or an IPv6 address in brackets.\nVARNISH_LISTEN_ADDRESS=192.168.1.10\nVARNISH_LISTEN_PORT=80\n\n# Admin interface listen address and port\nVARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1\nVARNISH_ADMIN_LISTEN_PORT=6082\n\n# Shared secret file for admin interface\nVARNISH_SECRET_FILE=/etc/varnish/secret\n\n# Backend storage specification, see Storage Types in the varnishd(5)\n# man page for details.\nVARNISH_STORAGE=\"malloc,512M\"\n\n# Default TTL used when the backend does not specify one\nVARNISH_TTL=120\n\n# User and group for the varnishd worker processes\nVARNISH_USER=varnish\nVARNISH_GROUP=varnish\n\n# Other options, see the man page varnishd(1)\nDAEMON_OPTS=\"-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300\"\n
"},{"location":"Extensions/Varnish/#configure-apache-for-varnish","title":"Configure Apache for Varnish","text":"

Edit librenms.conf and modify the Apache Virtual Host listening port.

  • Modify: <VirtualHost *:80> to <VirtualHost *:8080>
vim /etc/httpd/conf.d/librenms.conf\n

Varnish can not share a port with Apache. Change the Apache listening port to 8080.

  • Modify: Listen 80 to Listen 8080
vim /etc/httpd/conf/httpd.conf\n
  • Create the librenms.vcl
cd /etc/varnish\ntouch librenms.vcl\n
  • Set ownership and permissions for Varnish files.
chown varnish:varnish default.vcl varnish.params secret\nchmod 644 default.vcl varnish.params secret\n

Edit the librenms.vcl.

vim librenms.vcl\n

Paste example VCL config, read config comments for more information.

#\n# This is an example VCL file for Varnish.\n#\n# It does not do anything by default, delegating control to the\n# builtin VCL. The builtin VCL is called when there is no explicit\n# return statement.\n#\n# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/\n# and http://varnish-cache.org/trac/wiki/VCLExamples for more examples.\n\n# Marker to tell the VCL compiler that this VCL has been adapted to the\n# new 4.0 format.\nvcl 4.0;\n\n# Default backend definition. Set this to point to your Apache server.\nbackend librenms {\n    .host = \"127.0.0.1\";\n    .port = \"8080\";\n}\n\n# In this example our objective is to cache static content with Varnish and temporarily\n# cache dynamic content in the client web browser.\n\nsub vcl_recv {\n    # HTTP requests from client web browser.\n    # Here we remove any cookie HTTP requests for the 'librenms.domain.net' host\n    # containing the matching file extensions. We don't have to match by host if you\n    # only have LibreNMS running on Apache.\n    # If the cookies are not removed from the HTTP request then Varnish will not cache\n    # the files. 'else' function is set to 'pass', or don't cache anything that doesn't\n    # match.\n\n    if (req.http.host ~ \"^librenms.domain.net\") {\n        set req.backend_hint = librenms;\n        if (req.url ~ \"\\.(png|gif|jpg|jpeg|ico|pdf|js|css|svg|eot|otf|woff|woff2|ttf)$\") {\n            unset req.http.Cookie;\n        }\n\n        else{\n            return(pass);\n        }\n    }\n}\n\nsub vcl_backend_response {\n    # 'sub vcl_backend_response' is the same function as 'sub vcl_fetch' in Varnish 3, however,\n    # the syntax is slightly different\n    # This function happens after we read the response headers from the backend (Apache).\n    # First function 'if (bereq.url ~ \"\\' removes cookies from the Apache HTTP responses\n    # that match the file extensions that are between the quotes, and cache the files for 24 hours.\n    # This assumes you update LibreNMS once a day, otherwise restart Varnish to clear cache.\n    # Second function 'if (bereq.url ~ \"^/' removes the Pragma no-cache statements and sets the age\n    # of how long the client browser will cache the matching urls.\n    # LibreNMS graphs are updated every 300 seconds, 'max-age=300' is set to match this behavior.\n    # We could cache these URLs in Varnish but it would add to the complexity of the config.\n\n    if (bereq.http.host ~ \"^librenms.domain.net\") {\n        if (bereq.url ~ \"\\.(png|gif|jpg|jpeg|ico|pdf|js|css|svg|eot|otf|woff|woff2|ttf)$\") {\n            unset beresp.http.Set-cookie;\n            set beresp.ttl = 24h;\n        }\n\n        if (bereq.url ~ \"^/graph.php\" || \"^/device/\" || \"^/iftype/\" || \"^/customers/\" || \"^/health/\" || \"^/apps/\" || \"^/(plugin)$\" || \"^/(alert)$\" || \"^/eventlog/\" || \"^/graphs/\" || \"^/ports/\" ) {\n            unset beresp.http.Pragma;\n            set beresp.http.Cache-Control = \"max-age=300\";\n        }\n    }\n}\n\nsub vcl_deliver {\n    # Happens when we have all the pieces we need, and are about to send the\n    # response to the client.\n    # You can do accounting or modifying the final object here.\n\n    return (deliver);\n}\n
  • Reload rules to remove the temporary port rule we added earlier.
firewall-cmd --reload\n

Varnish caching does not take effect immediately. You will need to browse the LibreNMS website to build up the cache.

Use the command varnishstat to monitor Varnish caching. Over time you should see 'MAIN.cache_hit' and 'MAIN.client_req' increase. With the above VCL the hit to request ratio is approximately 84%.

  • Session based VCL (coming soon)

  • Testing and debugging VCL (coming soon)

"},{"location":"Extensions/VisJS-Config/","title":"Vis JS Configuration","text":"

The Network Maps and Dependency Maps all use a common configuration for the vis.js library, which affects the way the maps are rendered, as well as the way that users can interact with the maps. This configuration can be adjusted by following the instructions below.

This link will show you all the options and explain what they do.

You may also access the dynamic configuration interface example here from within LibreNMS by adding the following to config.php

$config['network_map_vis_options'] = '{\n  \"configure\": { \"enabled\": true},\n}';\n
"},{"location":"Extensions/VisJS-Config/#note","title":"Note","text":"

You may want to disable the automatic page refresh while you're tweaking your configuration, as the refresh will reset the dynamic configuration UI to the values currently saved in config.php This can be done by clicking on the Settings Icon then Refresh Pause.

"},{"location":"Extensions/VisJS-Config/#configurator-output","title":"Configurator Output","text":"

Once you've achieved your desired map appearance, click the generate options button at the bottom to be given the necessary parameters to add to your config.php file. You will need to paste the generated config into config.php the format will need to look something like this. Note that the configurator will output the config with var options you will need to strip them out and at the end of the config you need to add an }'; see the example below.

$config['network_map_vis_options'] = '{\n  \"nodes\": {\n    \"color\": {\n      \"background\": \"rgba(20,252,18,1)\"\n    },\n    \"font\": {\n      \"face\": \"tahoma\"\n    },\n    \"physics\": false\n  },\n  \"edges\": {\n    \"smooth\": {\n      \"forceDirection\": \"none\"\n    }\n  },\n  \"interaction\": {\n    \"hover\": true,\n    \"multiselect\": true,\n    \"navigationButtons\": true\n  },\n  \"manipulation\": {\n    \"enabled\": true\n  },\n  \"physics\": {\n    \"barnesHut\": {\n      \"avoidOverlap\": 0.11\n    },\n    \"minVelocity\": 0.75\n  }\n}';\n

"},{"location":"Extensions/Weathermap/","title":"Network-WeatherMap with LibreNMS","text":"

Integrating LibreNMS with Network-Weathermap, allows you to build network maps to help visulaize network traffic flow rates.

"},{"location":"Extensions/Weathermap/#prerequisites","title":"Prerequisites","text":"

Network-WeatherMap requires php pear to work.

"},{"location":"Extensions/Weathermap/#installing-network-weathermap","title":"Installing Network-WeatherMap","text":""},{"location":"Extensions/Weathermap/#step-1","title":"Step 1","text":"

Extract to your LibreNMS plugins directory /opt/librenms/html/plugins so you should see something like /opt/librenms/html/plugins/Weathermap/ The best way to do this is via git. Go to your install directory and then /opt/librenms/html/plugins enter:

git clone https://github.com/librenms-plugins/Weathermap.git\n

"},{"location":"Extensions/Weathermap/#step-2","title":"Step 2","text":"

Inside the html/plugins directory, change the ownership of the Weathermap directory by typing

chown -R librenms:librenms Weathermap/\n

Make the configs directory writeable.

chmod 775 /opt/librenms/html/plugins/Weathermap/configs\n

Note if you are using SELinux you need to input the following command

chcon -R -t httpd_cache_t Weathermap/\n
"},{"location":"Extensions/Weathermap/#step-3","title":"Step 3","text":"

Enable the cron process by editing your current LibreNMS cron file (typically /etc/cron.d/librenms) and add the following:

*/5 * * * * librenms /opt/librenms/html/plugins/Weathermap/map-poller.php >> /dev/null 2>&1\n
"},{"location":"Extensions/Weathermap/#step-4","title":"Step 4","text":"

Enable the plugin from LibreNMS Web UI in OverView -> Plugins -> Plugin Admin menu.

"},{"location":"Extensions/Weathermap/#step-5","title":"Step 5","text":"

Now you should see Weathermap Overview -> Plugins -> Weathermap Create your maps, please note when you create a MAP, please click Map Style, ensure Overlib is selected for HTML Style and click submit. Also, ensure you set an output image filename and output HTML filename in Map Properties. I'd recommend you use the output folder as this is excluded from git updates (i.e. use output/mymap.png and output/mymap.html).

Optional: If your install is in another directory than standard, set $basehref within map-poller.php.

"},{"location":"Extensions/Weathermap/#weathermapper","title":"WeatherMapper","text":"

Automatically generate weathermaps from a LibreNMS database using WeatherMapper.

"},{"location":"Extensions/Weathermap/#adding-your-network-weathermaps-to-the-dashboards","title":"Adding your Network Weathermaps to the Dashboards","text":"

Once you have created your Network Weather Map you can add it to a dashboard page by doing the following.

"},{"location":"Extensions/Weathermap/#step-1_1","title":"Step 1","text":"

When you create the Weathermap make sure to export as HTML and PNG you will need this for the out to the dashboard.

In the Weathermap Plugin page, you will see the output maps. Right click on one of the maps and click on copy image address.

Example URL: http://yourlibrenms.org/plugins/Weathermap/output/yourmap.html

"},{"location":"Extensions/Weathermap/#step-2_1","title":"Step 2","text":"

Then go back to your Dashboard, create a new dashboard and give it a name. select the widget as External Images.

Give the Widget a Title.

The Image URL will need to be the address you copied but at the end remove the .html and replace it with .png

Example Image URL http://yourlibrenms.org/plugins/Weathermap/output/yourmap.png

The Target URL will be the URL you copied but with the .html at the end of the URL.

Example Target URL http://yourlibrenms.org/plugins/Weathermap/output/yourmap.html

Then Click on Set

You should now be able to see the Weathermap you have created in your list of dashboards. You could also add this to existing dashboards.

"},{"location":"Extensions/World-Map/","title":"World Map Configuration","text":"

LibreNMS comes with a configurable Geo Map based on World Map Widget to visualize where your equipment is located geographically.

"},{"location":"Extensions/World-Map/#world-map-widget","title":"World Map Widget","text":"

World Map Widget, requires you to have properly formatted addresses in sysLocation or sysLocation override. As part of the standard poller these addresses will be Geocoded by Google and stored in the database.

Location resolution happens as follows

  1. If device['location'] contains [lat, lng] (note the square brackets), that is used
  2. If there is a location overide for the device in the WebUI and it contains [lat, lng] (note the square brackets), that is used.
  3. Attempt to resolve lat, lng using lnms config:set geoloc.engine
  4. Properly formatted addresses in sysLocation or sysLocation override, under device settings.

Example:

[40.424521, -86.912755]\n

or

1100 Congress Ave, Austin, TX 78701 (3rd floor cabinet)\n
Information inside parentheses is ignored during GEO lookup

We have two current mapping engines available:

  • Leaflet (default)
  • Jquery-Mapael
"},{"location":"Extensions/World-Map/#world-map-widget-settings","title":"World Map Widget Settings","text":"
  • Initial Latitude / Longitude: The map will be centered on those coordinates.
  • Initial Zoom: Initial zoom of the map. More information about zoom levels.
  • Grouping radius: Markers are grouped by area. This value define the maximum size of grouping areas.
  • Show devices: Show devices based on status.

Example Settings:

"},{"location":"Extensions/World-Map/#device-overview-world-map-settings","title":"Device Overview World Map Settings","text":"

If a device has a location with a valid latitude and logitude, the device overview page will have a panel showing the device on a world map. The following settings affect this map:

# Does the world map start opened, or does the user need to clivk to view\nlnms config:set device_location_map_open false\n# Do we show all other devices on the map as well\nlnms config:set device_location_map_show_devices false\n# Do we show a network map based on device dependencies\nlnms config:set device_location_map_show_device_dependencies false\n
"},{"location":"Extensions/World-Map/#offline-openstreet-map","title":"Offline OpenStreet Map","text":"

If you can't access OpenStreet map directly you can run a local tile server. To specify a different url you can set:

lnms config:set leaflet.tile_url 'localhost.com'\n
"},{"location":"Extensions/World-Map/#additional-leaflet-config","title":"Additional Leaflet config","text":"
lnms config:set map.engine leaflet\nlnms config:set leaflet.default_lat \"51.981074\"\nlnms config:set leaflet.default_lng \"5.350342\"\nlnms config:set leaflet.default_zoom 8\n# Device grouping radius in KM default 80KM\nlnms config:set leaflet.group_radius 1\n# Enable network map on world map\nlnms config:set network_map_show_on_worldmap true\n# Use CDP/LLDP for network map, or device dependencies\nlnms config:set network_map_worldmap_link_type xdp/depends\n# Do not show devices that have notifications disabled\nlnms config:set network_map_worldmap_show_disabled_alerts false\n
"},{"location":"Extensions/World-Map/#geocode-engine-config","title":"Geocode engine config","text":"

external/location

lnms config:set geoloc.engine google\nlnms config:set geoloc.api_key 'abcdefghijklmnopqrstuvwxyz'\n

Google: Pros: fast, accurate Cons: requires a credit card even for a free account

MapQuest: Pros: free, no credit card required Cons: inaccurate: most addresses are returned as locations at the center of the US

Bing: Pros: free, no credit card required, accurate Cons: Microsoft (debatable)

"},{"location":"Extensions/World-Map/#jquery-mapael-config","title":"Jquery-Mapael config","text":"

Further custom options are available to load different maps of the world, set default coordinates of where the map will zoom and the zoom level by default. An example of this is:

lnms config:set map.engine jquery-mapael\nlnms config:set mapael.default_map 'mapael-maps/united_kingdom/united_kingdom.js'\nlnms config:set mapael.map_width 400\nlnms config:set mapael.default_lat '50.898482'\nlnms config:set mapael.default_lng '-3.401402'\nlnms config:set mapael.default_zoom 20\n

A list of maps can be found in html/js/maps/ or html/js/mapael-maps/.

"},{"location":"Extensions/metrics/Graphite/","title":"Enabling support for Graphite","text":"

This module sends all metrics to a remote graphite service. You need something like Grafana for graphing.

"},{"location":"Extensions/metrics/Graphite/#what-you-dont-get","title":"What you don't get","text":"
  • Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.

RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

"},{"location":"Extensions/metrics/Graphite/#configuration","title":"Configuration","text":"

poller/graphite

lnms config:set graphite.enable true\nlnms config:set graphite.host 'your.graphite.server'\nlnms config:set graphite.port 2003\nlnms config:set graphite.prefix 'your.metric.prefix'\n

Your metric path can be prefixed if required, otherwise the metric path for Graphite will be in the form of hostname.measurement.fieldname, interfaces will be stored as hostname.ports.ifName.fieldname.

The same data then stored within rrd will be sent to Graphite and recorded. You can then create graphs within Grafana to display the information you need.

"},{"location":"Extensions/metrics/Graphite/#graphite-configuration","title":"Graphite Configuration","text":"

As LibreNMS updates its metrics every 5 minutes, the following addition to your storage-schemas.conf is suggested.

[network]\npattern = your\\.metric\\.prefix\\..*\nretentions = 5m:30d,15m:90d,1h:1y\n
"},{"location":"Extensions/metrics/InfluxDB/","title":"Enabling support for InfluxDB","text":"

Before we get started it is important that you know and understand that InfluxDB support is currently alpha at best. All it provides is the sending of data to a InfluxDB install. Due to the current changes that are constantly being made to InfluxDB itself then we cannot guarantee that your data will be ok so enabling this support is at your own risk!

"},{"location":"Extensions/metrics/InfluxDB/#requirements","title":"Requirements","text":"
  • InfluxDB >= 0.94 < 2.0
  • Grafana

The setup of the above is completely out of scope here and we aren't really able to provide any help with this side of things.

"},{"location":"Extensions/metrics/InfluxDB/#what-you-dont-get","title":"What you don't get","text":"
  • Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.
  • Support for InfluxDB or Grafana, we would highly recommend that you have some level of experience with these.

RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

"},{"location":"Extensions/metrics/InfluxDB/#configuration","title":"Configuration","text":"

poller/influxdb

lnms config:set influxdb.enable true\nlnms config:set influxdb.transport http\nlnms config:set influxdb.host '127.0.0.1'\nlnms config:set influxdb.port 8086\nlnms config:set influxdb.db 'librenms'\nlnms config:set influxdb.username 'admin'\nlnms config:set influxdb.password 'admin'\nlnms config:set influxdb.timeout 0\nlnms config:set influxdb.verifySSL false\n

No credentials are needed if you don't use InfluxDB authentication.

The same data then stored within rrd will be sent to InfluxDB and recorded. You can then create graphs within Grafana to display the information you need.

"},{"location":"Extensions/metrics/InfluxDBv2/","title":"Enabling support for InfluxDBv2","text":"

Before we get started it is important that you know and understand that InfluxDBv2 support is currently alpha at best. All it provides is the sending of data to a InfluxDBv2 bucket. Due to the current changes that are constantly being made to InfluxDB itself then we cannot guarantee that your data will be ok so enabling this support is at your own risk!

It is also important to understand that InfluxDBv2 only supports the InfluxDBv2 API used in InfluxDB version 2.0 or higher. If you are looking to send data to any other version of InfluxDB than you should use the InfluxDB datastore instead.

"},{"location":"Extensions/metrics/InfluxDBv2/#requirements","title":"Requirements","text":"
  • InfluxDB >= 2.0

The setup of the above is completely out of scope here and we aren't really able to provide any help with this side of things.

"},{"location":"Extensions/metrics/InfluxDBv2/#what-you-dont-get","title":"What you don't get","text":"
  • Support for InfluxDB, we would highly recommend that you have some level of experience with these.

RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

"},{"location":"Extensions/metrics/InfluxDBv2/#configuration","title":"Configuration","text":"

poller/influxdbv2

lnms config:set influxdbv2.enable true\nlnms config:set influxdbv2.transport http\nlnms config:set influxdbv2.host '127.0.0.1'\nlnms config:set influxdbv2.port 8086\nlnms config:set influxdbv2.bucket 'librenms'\nlnms config:set influxdbv2.token 'admin'\nlnms config:set influxdbv2.allow_redirect true\nlmns config:set influxdbv2.organization 'librenms'\nlmns config:set influxdbv2.debug false\nlmns config:set influxdbv2.groups-exclude [\"group_name_1\",\"group_name_2\"]\n

The same data stored within rrd will be sent to InfluxDB and recorded. You can then create graphs within Grafana or InfluxDB to display the information you need.

Please note that polling will slow down when the poller isn't able to reach or write data to InfluxDBv2.

"},{"location":"Extensions/metrics/OpenTSDB/","title":"Enabling support for OpenTSDB","text":"

This module sends all metrics to OpenTSDB server. You need something like Grafana for graphing.

"},{"location":"Extensions/metrics/OpenTSDB/#requirements","title":"Requirements","text":"
  • OpenTSDB
  • Grafana
"},{"location":"Extensions/metrics/OpenTSDB/#what-you-dont-get","title":"What you don't get","text":"

Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.

RRD will continue to function normally so LibreNMS itself should continue to function normally.

You can add the following to your config:

"},{"location":"Extensions/metrics/OpenTSDB/#configuration","title":"Configuration","text":"

poller/opentsdb

lnms config:set opentsdb.enable true\nlnms config:set opentsdb.host '127.0.0.1'\nlnms config:set opentsdb.port 4242\n

The same data than the one stored within rrd will be sent to OpenTSDB and recorded. You can then create graphs within Grafana to display the information you need.

"},{"location":"Extensions/metrics/Prometheus/","title":"Enabling support for Prometheus","text":"

Please be aware Prometheus support is alpha at best, It hasn't been extensively tested and is still in development All it provides is the sending of data to a a Prometheus PushGateway. Please be careful when enabling this support you use it at your own risk!

"},{"location":"Extensions/metrics/Prometheus/#requirements-older-versions-may-work-but-havent-been-tested","title":"Requirements (Older versions may work but haven't been tested","text":"
  • Prometheus >= 2.0
  • PushGateway >= 0.4.0
  • Grafana
  • PHP-CURL

The setup of the above is completely out of scope here and we aren't really able to provide any help with this side of things.

"},{"location":"Extensions/metrics/Prometheus/#what-you-dont-get","title":"What you don't get","text":"
  • Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.
  • Support for Prometheus or Grafana, we would highly recommend that you have some level of experience with these.

RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

"},{"location":"Extensions/metrics/Prometheus/#configuration","title":"Configuration","text":"

poller/prometheus

lnms config:set prometheus.enable true\nlnms config:set prometheus.url 'http://127.0.0.1:9091'\nlnms config:set prometheus.job 'librenms'\nlnms config:set prometheus.prefix 'librenms'\n

If your pushgateway uses basic authentication, configure the following:

poller/prometheus

lnms config:set prometheus.user username\nlnms config:set prometheus.password password\n
"},{"location":"Extensions/metrics/Prometheus/#prefix","title":"Prefix","text":"

Setting the 'prefix' option will cause all metric names to begin with the configured value.

For instance without setting this option metric names will be something like this:

OUTUCASTPKTS\nifOutUcastPkts_rate\nINOCTETS\nifInErrors_rate\n

Configuring a prefix name, for example 'librenms', instead caused those metrics to be exposed with the following names:

librenms_OUTUCASTPKTS\nlibrenms_ifOutUcastPkts_rate\nlibrenms_INOCTETS\nlibrenms_ifInErrors_rate\n
"},{"location":"Extensions/metrics/Prometheus/#sample-prometheus-scrape-config-for-scraping-the-push-gateway","title":"Sample Prometheus Scrape Config (for scraping the Push Gateway)","text":"
- job_name: pushgateway\n  scrape_interval: 300s\n  honor_labels: true\n  static_configs:\n    - targets: ['127.0.0.1:9091']\n

The same data then stored within rrd will be sent to Prometheus and recorded. You can then create graphs within Grafana to display the information you need.

"},{"location":"General/Acknowledgement/","title":"Acknowledgements","text":"

LibreNMS wouldn't be what it is today without the use of some other amazing projects. We list below what we make use of including the license compliance.

"},{"location":"General/Acknowledgement/#3rd-party-gplv3-compliant","title":"3rd Party GPLv3 Compliant","text":"
  • Bootstrap: MIT
  • Font Awesome: MIT License
  • Jquery Bootgrid: MIT License
  • Pace: Open License
  • Twitter typeahead: Open License
  • Vis: MIT / Apache 2.0
  • TCPDF: LGPLv3
  • Bootstrap 3 Datepicker:MIT
  • Bootstrap Dropdown Hover Plugin: MIT
  • Bootstrap Switch: Apache 2.0
  • Handlebars: Open License
  • Cycle2: MIT/GPL
  • Jquery: MIT
  • Jquery UI: MIT
  • Jquery QRCode: MIT
  • Mktree: Open License
  • Moment: MIT
  • Tag Manager: MIT
  • TW Sack: GPLv3
  • Gridster: MIT
  • Pure PHP radius class: GPLv3
  • GeSHi - Generic Syntax Highlighter: GPLv2+
  • MalaysiaMap.svg - By Exiang CC BY 3.0, via Wikimedia Commons
  • Code for UBNT Devices Mark Gibbons mgibbons@oemcomp.com Initial code base submitted via PR721
  • Jquery LazyLoad: MIT License
  • influxdb-php: MIT License
  • influxdb-client-php: MIT License
  • HTML Purifier: LGPL v2.1
  • Symfony Yaml: MIT
  • PHPMailer: LGPL v2.1
  • pbin: GPLv2 (or later - see script header)
  • CorsSlim: MIT
  • Confluence HTTP Authenticator
  • Graylog SSO Authentication Plugin
  • Select2: MIT License
  • JustGage: MIT
  • jQuery.extendext: MIT
  • doT: MIT
  • jQuery-queryBuilder: MIT
  • sql-parser: MIT (Currently a custom build is used)
"},{"location":"General/Acknowledgement/#3rd-party-gplv3-non-compliant","title":"3rd Party GPLv3 Non-compliant","text":"
  • JpGraph (html/includes/jpgraph): QPL 1.0 license
  • MIBS (mibs): unknown/various
  • html/graph-realtime.php: BSD (original?)
  • html/includes/collectd/: GPLv2 only
  • overLIB (html/js/overlib_mini.js): modified Artistic 1.0?
"},{"location":"General/Callback-Stats-and-Privacy/","title":"Submitting Stats","text":""},{"location":"General/Callback-Stats-and-Privacy/#stats-data-and-your-privacy","title":"Stats data and your privacy","text":"

This document has been put together to explain what LibreNMS does when it calls back home to report some anonymous statistics.

Let's start off by saying, all of the code that processes the data and submits it is included in the standard LibreNMS branch you've installed, the code that accepts this data and in turn generates some pretty graphs is all open source and available on GitHub. Please feel free to review the code, comment on it and suggest changes / improvements. Also, don't forget - by default installations DO NOT call back home, you need to opt into this.

Above all we respect users privacy which is why this system has been designed like it has.

Now onto the bit you're interested in, what is submitted and what we do with that data.

"},{"location":"General/Callback-Stats-and-Privacy/#what-is-submitted","title":"What is submitted","text":"
  • All data is anonymous.
  • Generic statistics are taken from the database, these include things like device count, device type, device OS, port types, port speeds, port count and BGP peer count. Take a look at the code for full details.
  • Pairs of sysDescr and sysObjectID from devices with a small amount of sanitation to prevent things like hostnames from being submitted.
  • We record version numbers of php, mysql, net-snmp and rrdtool
  • A random UUID is generated on your own install.
  • That's it!
  • Your IP isn't logged, even via our web service accepting the data. We don't need to know who you are so we don't ask.
"},{"location":"General/Callback-Stats-and-Privacy/#what-we-do-with-the-data","title":"What we do with the data","text":"
  • We store it, not for long - 3 months at the moment although this could change.
  • We use it to generate pretty graphs for people to see.
  • We use it to help prioritise issues and features that need to be worked on.
  • We use sysDescr and sysObjectID to create unit tests and improve OS discovery
"},{"location":"General/Callback-Stats-and-Privacy/#how-do-i-enable-stats-submission","title":"How do I enable stats submission?","text":"

If you're happy with all of this - please consider switching the call back system on, you can do this within the About LibreNMS page within your control panel. In the Statistics section you will find a toggle switch to enable / disable the feature. If you've previously had it switched on and want to opt out and remove your data, click the 'Clear remote stats' button and on the next submission all the data you've sent us will be removed!

"},{"location":"General/Callback-Stats-and-Privacy/#questions","title":"Questions?","text":""},{"location":"General/Callback-Stats-and-Privacy/#how-often-is-data-submitted","title":"How often is data submitted?","text":"

We submit the data once a day according to running daily.sh via cron. If you disable this then opting in will not have any affect.

"},{"location":"General/Callback-Stats-and-Privacy/#where-can-i-see-the-data-i-submitted","title":"Where can I see the data I submitted?","text":"

You can't see the data raw, but we collate all of the data together and provide a dynamic site so you can see the results of all contributed stats here

"},{"location":"General/Callback-Stats-and-Privacy/#i-want-my-data-removed","title":"I want my data removed.","text":"

That's easy, simply press 'Clear remote stats' in the About LibreNMS page of your control panel, the next time the call back script is run it will remove all the data we have.

"},{"location":"General/Callback-Stats-and-Privacy/#i-clicked-the-clear-remote-stats-button-by-accident","title":"I clicked the 'Clear remote stats' button by accident.","text":"

No problem, before daily.sh runs again - just opt back in, all of your existing data will stay.

Hopefully this answers the questions you might have on why and what we are doing here, if not, please pop into our discord server or community forum and ask any questions you like.

"},{"location":"General/Changelog/","title":"Changelog","text":""},{"location":"General/Changelog/#2480","title":"24.8.0","text":"

(2024-08-15)

A big thank you to the following 19 contributors this last month:

  • murrant (18)
  • PipoCanaja (5)
  • Npeca75 (2)
  • Jellyfrog (2)
  • nicolasberens (2)
  • electrocret (2)
  • dethmetaljeff (2)
  • xorrkaz (2)
  • rudybroersma (2)
  • TheMysteriousX (1)
  • dependabot (1)
  • ethan-bmn (1)
  • suom1 (1)
  • hatboxen (1)
  • freddy36 (1)
  • Ferris-0815 (1)
  • mib1185 (1)
  • ervin09 (1)
  • x0ul (1)

Thanks to maintainers and others that helped with pull requests this month:

  • murrant (11)
  • Jellyfrog (10)
  • PipoCanaja (7)
  • electrocret (4)
  • f0o (1)
  • VVelox (1)
"},{"location":"General/Changelog/#breaking-change","title":"Breaking Change","text":"
  • Fix Port Channel (#16227) - murrant
"},{"location":"General/Changelog/#device","title":"Device","text":"
  • Bug - Fix CISCO-BGP4-MIB logic (#16260) - PipoCanaja
  • Add support for GUDE Expert Sensor Box (#16257) - Jellyfrog
  • Add skip_values to iosxr hsrp (#16251) - electrocret
  • Improve Fiberstore S3900 series support (#16225) - freddy36
  • Add support for FortiNet FortiExtender (#16219) - rudybroersma
  • F5-Loadbalancer module to support an expiration check of the installed certificates (#16217) - Ferris-0815
  • Add value 0 to HP Physical Drive Status (meaning no disk is inserted) (#16211) - rudybroersma
  • Tripplite console server (#16156) - nicolasberens
  • Device - Adding support to Infortrend DS3016 (#16070) - ervin09
  • Device - Added Baicells Atom OD04 CPE support (#14838) - x0ul
"},{"location":"General/Changelog/#webui","title":"Webui","text":"
  • [webui] sort vlan tooltip by vlanid (#16266) - Npeca75
  • Add Servicename to Alert Detail (#16249) - electrocret
  • Update graph timezone data (#16244) - murrant
  • Fix custom map default settings error (#16236) - murrant
  • Add link on alert-rules page to display active alerts for rule (#16232) - dethmetaljeff
  • Custom map defaults (#16212) - murrant
  • Make also the total in and out interface errors selectable on the ports list (#16073) - mib1185
"},{"location":"General/Changelog/#alerting","title":"Alerting","text":"
  • Add bgp peer description to alert_detail (#16233) - dethmetaljeff
"},{"location":"General/Changelog/#api","title":"Api","text":"
  • Fix list_arp API (#16243) - murrant
"},{"location":"General/Changelog/#discovery","title":"Discovery","text":"
  • Discovery, make sure where is set (#16237) - murrant
  • Discovery - LLDPv2 support extension, and discovery-protocols tests (#16113) - PipoCanaja
"},{"location":"General/Changelog/#polling","title":"Polling","text":"
  • Nac polling improvement (#16265) - murrant
  • Fix poller wrapper debug option (#16214) - murrant
"},{"location":"General/Changelog/#authentication","title":"Authentication","text":"
  • Set default_role when registering instead of at every login (#16235) - suom1
"},{"location":"General/Changelog/#bug","title":"Bug","text":"
  • Fix alert bug when key missing (#16281) - murrant
  • Remove file differing by case only (#16280) - TheMysteriousX
  • Fix runtime cache (#16272) - murrant
  • Bug - Fixing 'cisco-pw' cpwVcMplsPeerLdpID (#16268) - PipoCanaja
  • [webui] fix port_row.blade generate vlan link (#16256) - Npeca75
  • Bug - services - fix splitting of perfdata (#16255) - nicolasberens
  • Cleanup - Ensure percentage is calculated out of positive values only (#16250) - PipoCanaja
  • Fix error from MikroTik routers when updating BGP peer info (#16224) - xorrkaz
  • Fix snmpsim in CI (#16213) - murrant
"},{"location":"General/Changelog/#refactor","title":"Refactor","text":"
  • Refactor SnmpResponse mapTable (#16238) - murrant
"},{"location":"General/Changelog/#cleanup","title":"Cleanup","text":"
  • Mark addhost.php as deprecated (#16283) - murrant
  • Validate.php proper exit code (#16274) - murrant
  • Remove FILTER_SANITIZE_STRING (#16264) - murrant
"},{"location":"General/Changelog/#documentation","title":"Documentation","text":"
  • Update Devices.md (#16252) - ethan-bmn
  • Docs Update: Large Scale LibreNMS Deployment Example (#16226) - hatboxen
"},{"location":"General/Changelog/#misc","title":"Misc","text":"
  • Add support for Prometheus pushgateway basic auth (#16230) - xorrkaz
"},{"location":"General/Changelog/#internal-features","title":"Internal Features","text":"
  • Improve Snmpsim usage to ease testing (#15471) - murrant
"},{"location":"General/Changelog/#dependencies","title":"Dependencies","text":"
  • Update PHP dependencies (#16263) - murrant
  • Bump postcss from 7.0.39 to 8.4.40 (#16262) - dependabot
"},{"location":"General/Changelog/#2470","title":"24.7.0","text":"

(2024-07-17)

A big thank you to the following 25 contributors this last month:

  • murrant (28)
  • freddy36 (6)
  • VVelox (5)
  • rudybroersma (2)
  • nicolasberens (2)
  • electrocret (2)
  • slashdoom (2)
  • dependabot (2)
  • fabriciotm (1)
  • TridTech (1)
  • PipoCanaja (1)
  • Walkablenormal (1)
  • jediblair (1)
  • westerterp (1)
  • Npeca75 (1)
  • kanokc (1)
  • dennypage (1)
  • normand-hue (1)
  • peejaychilds (1)
  • bonzo81 (1)
  • schnobbc (1)
  • dasdromedar (1)
  • VoipTelCH (1)
  • f7naz (1)
  • jepke (1)

Thanks to maintainers and others that helped with pull requests this month:

  • murrant (26)
  • PipoCanaja (10)
  • Jellyfrog (5)
  • electrocret (3)
  • ottorei (2)
  • SourceDoctor (1)
"},{"location":"General/Changelog/#feature","title":"Feature","text":"
  • Lnms snmp:translate always show textual and numeric translations (#16187) - murrant
  • InfluxDBv2 allow filter by group and disable debug by default (#16186) - Walkablenormal
"},{"location":"General/Changelog/#device_1","title":"Device","text":"
  • Fix FortiGate Cluster Sync status (#16206) - rudybroersma
  • Add transceiver threshold support (#16203) - freddy36
  • Add NAC to Arubaos-CX (#16194) - TridTech
  • Add Hardware and frmware detection for moxa P510 (#16185) - nicolasberens
  • Fix up the Siteboss571 discovery yaml to split pdnOutputCurrentValue and pdnMainCurrentValue indexes (#16181) - jediblair
  • Adjust Line Nominal default limits (#16180) - freddy36
  • Add more Synology disk health info (#16178) - westerterp
  • Add support for Fiberstore branded Centec switches (#16175) - freddy36
  • Fix php issue in cisco ntp code (#16172) - murrant
  • Allow for AXIS Panoramic cameras such as the P4707 (#16166) - dennypage
  • Add support for Fiberstore branded BDCOM switches (#16162) - freddy36
  • Add transceiver monitoring (#16160) - freddy36
  • Add support for more Cisco FTD devices (#16150) - normand-hue
  • ArubaOS - Addtional support to poll Active VPN sessions (#16137) - schnobbc
  • Update eaton-sc200.yaml (#16133) - dasdromedar
  • Update axis detection (#16130) - nicolasberens
  • New OS broadworks / broadsoft (#16078) - jepke
"},{"location":"General/Changelog/#webui_1","title":"Webui","text":"
  • Maps - Keep edge black when link is 0 bps (#16192) - PipoCanaja
  • [webui] Ports: correct sorting order when using ifName (#16170) - Npeca75
  • Handle missing device when linking (#16164) - murrant
  • WebUI - Dark mode menu fix (#16152) - slashdoom
  • Fix port link device missing (#16151) - murrant
  • Port link component easier graphs (#16147) - murrant
  • Fix graph row lazy loading (#16145) - murrant
  • Left align text for dashboard widgets (#16138) - bonzo81
  • Device Ports settings (#16132) - murrant
  • Change port pagination default to 32 (#16131) - murrant
  • Ports UI update (#16115) - murrant
"},{"location":"General/Changelog/#alerting_1","title":"Alerting","text":"
  • Alertmanager, Striptag Dynamic Variables! (#16141) - electrocret
"},{"location":"General/Changelog/#snmp-traps","title":"Snmp Traps","text":"
  • SnmpTrap Handler for Cisco IOS LDP Session UP and DOWN (#16107) - f7naz
"},{"location":"General/Changelog/#applications","title":"Applications","text":"
  • Add missing graphs for NFS app page (#16197) - VVelox
  • Extend update for wireguard, correct is_int to is_numeric for polling purposes, and clean up the app page (#16182) - VVelox
  • PHP-FPM app update to handle multiple pools (#16122) - VVelox
  • Add some alert template items for CAPEv2 (#16077) - VVelox
  • Add generic and improved NFS support with initial support for both FreeBSD and Linux (#15906) - VVelox
"},{"location":"General/Changelog/#api_1","title":"Api","text":"
  • Convert list_arp API to Eloquent (#16111) - murrant
  • Fixed wrong column and parameter used when deleting a location via API (#16109) - VoipTelCH
"},{"location":"General/Changelog/#authentication_1","title":"Authentication","text":"
  • Handle ad/ldap authorizer search error (#16139) - murrant
"},{"location":"General/Changelog/#bug_1","title":"Bug","text":"
  • Fix null in sensors discovery (#16201) - murrant
  • Fix incorrect get_class call (#16179) - murrant
  • Fix some testing issues (#16174) - murrant
  • BGP integer fields fix (#16173) - murrant
  • Fix for lnms snmp:translate (#16159) - murrant
"},{"location":"General/Changelog/#documentation_1","title":"Documentation","text":"
  • Changelog cleanup (#16154) - murrant
  • Fortigate append-index doc (#16153) - electrocret
  • Clarify okta claim configuration requirement (#16142) - peejaychilds
  • [DOC] - Update doc/API/DeviceGroups.md (#16140) - slashdoom
"},{"location":"General/Changelog/#translation","title":"Translation","text":"
  • Support to Brazilian Portuguese (#16209) - fabriciotm
"},{"location":"General/Changelog/#tests","title":"Tests","text":"
  • Add entity physical test data (#16183) - murrant
  • Add support for snmpsim-lextudio (#16161) - freddy36
"},{"location":"General/Changelog/#misc_1","title":"Misc","text":"
  • Change entPhysical table column defaults (#16199) - murrant
"},{"location":"General/Changelog/#internal-features_1","title":"Internal Features","text":"
  • SnmpQuery default improvements (#16204) - murrant
"},{"location":"General/Changelog/#mibs","title":"Mibs","text":"
  • Radwin MIB update (#16200) - murrant
  • Misc Junos MIB updates (#16171) - murrant
"},{"location":"General/Changelog/#dependencies_1","title":"Dependencies","text":"
  • Bump tecnickcom/tcpdf from 6.7.4 to 6.7.5 (#16148) - dependabot
  • Bump ws from 8.17.0 to 8.17.1 (#16143) - dependabot
"},{"location":"General/Changelog/#2460","title":"24.6.0","text":"

(2024-06-16)

A big thank you to the following 20 contributors this last month:

  • murrant (13)
  • VVelox (7)
  • PipoCanaja (3)
  • dependabot (2)
  • Npeca75 (2)
  • ashwath129 (2)
  • electrocret (2)
  • scamp (1)
  • nicolasberens (1)
  • sorano (1)
  • GonBlank (1)
  • jepke (1)
  • EinGlasVollKakao (1)
  • Cougar (1)
  • whitej46 (1)
  • cadirol (1)
  • santiag0z (1)
  • rons4 (1)
  • freddy36 (1)
  • cjsoftuk (1)

Thanks to maintainers and others that helped with pull requests this month:

  • murrant (18)
  • Jellyfrog (12)
  • electrocret (9)
  • PipoCanaja (1)
"},{"location":"General/Changelog/#feature_1","title":"Feature","text":"
  • ESRI ArcGIS geo map support (#16059) - murrant
"},{"location":"General/Changelog/#device_2","title":"Device","text":"
  • Update Dell MIBs (#16120) - murrant
  • Add TI-G102i (.46) and TI-PG1284i (.34) (#16099) - nicolasberens
  • Add \"Bullet Camera\" in Axis discovery. (#16098) - sorano
  • [vlans] Add VLANs information to Huawei VRP os (#16089) - Npeca75
  • Cisco Catalyst 1300 recognition (#16080) - jepke
  • Fix Ruckus Unleashed product ID for OS detection (#16067) - Cougar
  • Fix error in riverbed (#16066) - murrant
  • Update Hatteras DSLAM name (#16054) - cadirol
  • Add initial support for socomec-ups (#16018) - Npeca75
  • Fix bdcom/pbn neighbour discovery (#15935) - freddy36
  • Add support for new sensors on Firebrick 9000 models. (#15842) - cjsoftuk
"},{"location":"General/Changelog/#webui_2","title":"Webui","text":"
  • Fix popup toast messages (Remove Flasher) (#16090) - murrant
  • Handle $app_data['disks'] not being set for SMART app page display (#16087) - VVelox
  • Edit Current Map menu entry (#16084) - murrant
  • Fix device summary widget alignment and dropdown color on dark theme (#16083) - GonBlank
  • Fix duplicate maps in relationship (#16081) - murrant
  • Manage Maps limit width (#16055) - murrant
  • Widget hot refresh & worldmap cleanup (#16053) - murrant
  • Align the buttons (Edit and Delete) to the right in Map Management (#16052) - santiag0z
"},{"location":"General/Changelog/#alerting_2","title":"Alerting","text":"
  • AlertOps alert transport (#16050) - ashwath129
  • SIGNL4 Alert Transport (#16037) - rons4
"},{"location":"General/Changelog/#applications_1","title":"Applications","text":"
  • Fix display of graphs on the multi-server app page for Mojo CAPE Submit (#16094) - VVelox
  • Two minor fixes for sagan (#16082) - VVelox
  • Fix path related issues for ss and systemd applications (#16045) - VVelox
  • Add Suricata 7 support to Suricata (#16044) - VVelox
"},{"location":"General/Changelog/#api_2","title":"Api","text":"
  • Return error when no device ports found (#16043) - murrant
"},{"location":"General/Changelog/#settings","title":"Settings","text":"
  • Add nfsen_base to config_definitions.json (#16065) - whitej46
  • Remove device_perf_purge (#16057) - electrocret
  • Remove enable_ports_poe (#16056) - electrocret
"},{"location":"General/Changelog/#bug_2","title":"Bug","text":"
  • Bug - Sorting FDB table by devices (#16116) - PipoCanaja
  • Fix typo in device edit page (#16096) - murrant
  • Fix fping bulk (#16085) - murrant
  • Fix duplication of processor entries & limit length of type (#16075) - EinGlasVollKakao
"},{"location":"General/Changelog/#refactor_1","title":"Refactor","text":"
  • Rename index_string to str_index_as_numeric (#15916) - PipoCanaja
"},{"location":"General/Changelog/#documentation_2","title":"Documentation","text":"
  • Note the suffix/prefix stuff for LDAP auth (#16091) - VVelox
  • Clean up SMART docs a bit (#16086) - VVelox
  • Update Transports.md to add documentation for AlertOps (#16058) - ashwath129
"},{"location":"General/Changelog/#misc_2","title":"Misc","text":"
  • Don't run poller validations when there are no devices (#16088) - murrant
"},{"location":"General/Changelog/#mibs_1","title":"Mibs","text":"
  • Fix ECS4120 MIB, resolves #16093 (#16101) - scamp
"},{"location":"General/Changelog/#dependencies_2","title":"Dependencies","text":"
  • Bump braces from 3.0.2 to 3.0.3 (#16105) - dependabot
  • Bump composer/composer from 2.7.1 to 2.7.7 (#16104) - dependabot
"},{"location":"General/Changelog/#2450","title":"24.5.0","text":"

(2024-05-19)

A big thank you to the following 23 contributors this last month:

  • murrant (24)
  • santiag0z (5)
  • eskyuu (3)
  • sogadm (2)
  • Jarod2801 (2)
  • Pikamander2 (1)
  • scamp (1)
  • ottorei (1)
  • whitej46 (1)
  • sonic45132 (1)
  • fbouynot (1)
  • EinGlasVollKakao (1)
  • h-barnhart (1)
  • sarabveer (1)
  • netravnen (1)
  • jthiltges (1)
  • hatboxen (1)
  • electrocret (1)
  • washcroft (1)
  • Npeca75 (1)
  • paulierco (1)
  • drshawnkwang (1)
  • systeembeheerder (1)

Thanks to maintainers and others that helped with pull requests this month:

  • murrant (22)
  • Jellyfrog (13)
  • electrocret (3)
  • ottorei (1)
  • PipoCanaja (1)
"},{"location":"General/Changelog/#feature_2","title":"Feature","text":"
  • Custom Maps: geo map and color backgrounds (#16020) - murrant
  • Show custom maps in device overview (#15985) - murrant
  • New Map Menu (#15969) - murrant
  • Mysql PDO options to support SSL/TLS client communication (#15832) - drshawnkwang
  • Snmpscan.py output errors and nodns (#15673) - murrant
"},{"location":"General/Changelog/#breaking-change_1","title":"Breaking Change","text":"
  • Linux MegaRAID SAS fixes (#15566) - eskyuu
"},{"location":"General/Changelog/#device_3","title":"Device","text":"
  • Use null coalescing on Panos.php (#16019) - ottorei
  • Improved powerwalker sensors (#15999) - EinGlasVollKakao
  • Added initial support for ULAF+ devices (#15997) - Jarod2801
  • Correct swapped SET and WHERE parameters in bgp-peers/dell-os10.inc.php (#15983) - jthiltges
  • Added FibroLAN devices (#15967) - Jarod2801
  • New velocloud devices (#15958) - paulierco
"},{"location":"General/Changelog/#webui_3","title":"Webui","text":"
  • Fix issue loading session preferences (#16041) - murrant
  • Device location map zoom out when location N/A (#16034) - murrant
  • Added read permission test to the custom map model (#16030) - eskyuu
  • Do not allow the legend nodes to trigger the node edit modal (#16026) - eskyuu
  • Mobile menu full height (#16011) - murrant
  • Map Management: Show Groups (#16005) - murrant
  • Change custom map editor icon (#16004) - murrant
  • Custom Map: Show crosshairs when adding (#15978) - murrant
  • On-demand map menu items (#15971) - murrant
  • Custom Maps: make edit title clickable (#15965) - murrant
  • [webui] sort ports in VLANs blade (#15960) - Npeca75
"},{"location":"General/Changelog/#graphs","title":"Graphs","text":"
  • Fix icmp ping y-axis over 1000ms (#16039) - murrant
  • Fix graph_type variable (svg / png) (#15972) - washcroft
"},{"location":"General/Changelog/#snmp-traps_1","title":"Snmp Traps","text":"
  • SNMP Traps - Ciena AAA (#15998) - h-barnhart
"},{"location":"General/Changelog/#bug_3","title":"Bug","text":"
  • Fix downtime in corner cases (#16040) - murrant
  • Fix WirelessSensor incorrect model (#16016) - whitej46
  • Merge duplicate toBytes functions (#15994) - murrant
  • Fix systemd graphs using wrong rrd filename variable (#15988) - sarabveer
  • Rrd source does not work with rrdcached (#15974) - murrant
  • Git ignore custom map images (#15966) - murrant
  • Packet_loss macros quick fix (#15961) - murrant
"},{"location":"General/Changelog/#cleanup_1","title":"Cleanup","text":"
  • Fix incorrect number of seconds in a day (#16042) - Pikamander2
"},{"location":"General/Changelog/#documentation_3","title":"Documentation","text":"
  • [DOC] Update Customizing-the-Web-UI.md (#16025) - santiag0z
  • [DOC] Install LibreNMS: add Icons (#16017) - santiag0z
  • Set httpd_cache_t type to /opt/librenms/cache (#16000) - fbouynot
  • Update to Material for MkDocs 8.3.9 -> 9.5.20 (#15996) - santiag0z
  • Update link to LibreNMS origin blog post (#15981) - hatboxen
  • Remove poller_name from docs (#15979) - electrocret
  • Update packet_loss docs (#15962) - murrant
  • Update Dispatcher-Service.md (#15705) - systeembeheerder
"},{"location":"General/Changelog/#translation_1","title":"Translation","text":"
  • Massive changes to the Chinese interface translation. (#16009) - sogadm
  • Chinese translation fixesChinese translation fixes (#15991) - sogadm
"},{"location":"General/Changelog/#tests_1","title":"Tests","text":"
  • Always run tests (#16024) - murrant
"},{"location":"General/Changelog/#mibs_2","title":"Mibs","text":"
  • Update MIB for Edge-Core ECS4120-Series (#16023) - scamp
  • Update to latest revision (#15984) - netravnen
"},{"location":"General/Changelog/#2440","title":"24.4.0","text":"

(2024-04-19)

A big thank you to the following 18 contributors this last month:

  • murrant (8)
  • PipoCanaja (4)
  • xorrkaz (2)
  • moisseev (1)
  • VVelox (1)
  • Taarek (1)
  • Melhuig (1)
  • dependabot (1)
  • Lollbrant (1)
  • HolgerHees (1)
  • voileux (1)
  • hvanderheide (1)
  • jasoncheng7115 (1)
  • h-barnhart (1)
  • Jellyfrog (1)
  • CTV-2023 (1)
  • fbouynot (1)
  • OSIRIS-REx (1)

Thanks to maintainers and others that helped with pull requests this month:

  • Jellyfrog (13)
  • murrant (9)
  • PipoCanaja (8)
  • electrocret (1)
"},{"location":"General/Changelog/#feature_3","title":"Feature","text":"
  • Improved Latency graph (#15940) - murrant
"},{"location":"General/Changelog/#security","title":"Security","text":"
  • Fix Graph date selector (#15956) - murrant
  • Fix JS injection in Service Templates (#15954) - murrant
  • Fix SQL injection issues in packages search (#15950) - murrant
  • Improve order validation in list_devices (#15885) - Jellyfrog
"},{"location":"General/Changelog/#device_4","title":"Device","text":"
  • ILO storage: fix malformed snmp data parsing (#15931) - HolgerHees
  • Add Fortigate HA state sensor definition (#15924) - hvanderheide
  • Devices - Ciena RLS 6500 (#15909) - h-barnhart
  • Cumulus mellanox discovery (#15732) - fbouynot
  • Added support for new device OS Westermo WeOS (#15674) - OSIRIS-REx
"},{"location":"General/Changelog/#webui_4","title":"Webui","text":"
  • Fix null in services (#15945) - murrant
"},{"location":"General/Changelog/#alerting_3","title":"Alerting","text":"
  • Pretty up Slack formatting. (#15898) - xorrkaz
"},{"location":"General/Changelog/#graphs_1","title":"Graphs","text":"
  • Fix typo (#15952) - Taarek
  • Fix graph selection when to/from missing from url (#15946) - murrant
"},{"location":"General/Changelog/#applications_2","title":"Applications","text":"
  • For gzip+base64 compressed json, don't call stripslashes (#15953) - VVelox
  • Fix PDNS recursor error (#15942) - murrant
"},{"location":"General/Changelog/#api_3","title":"Api","text":"
  • Add type property to Device class to update it by API (#15930) - voileux
  • Add support for a maintenance boolean in API results. (#15904) - xorrkaz
"},{"location":"General/Changelog/#bug_4","title":"Bug","text":"
  • Skip rrd sources that do not exist (#15959) - murrant
  • Bug - Cisco NAC key error (#15934) - PipoCanaja
  • Bug - typo for request rate + sanity on numerical not_null values (#15919) - PipoCanaja
  • Bug - vrp - fix signed-tinyint overloaded with disabled radios (#15917) - PipoCanaja
"},{"location":"General/Changelog/#documentation_4","title":"Documentation","text":"
  • Add missing p5-File-Slurp dependency (#15955) - moisseev
  • Fix \"lnms config:set\" command syntax (#15949) - Melhuig
  • Graylog how to set up non-admin user (#15938) - Lollbrant
  • Documentation - opcache issue on Debian 12 (#15870) - CTV-2023
"},{"location":"General/Changelog/#translation_2","title":"Translation","text":"
  • Fix wrong terminology (#15920) - jasoncheng7115
"},{"location":"General/Changelog/#dependencies_3","title":"Dependencies","text":"
  • Bump tecnickcom/tcpdf from 6.6.5 to 6.7.4 (#15948) - dependabot
"},{"location":"General/Changelog/#2430","title":"24.3.0","text":"

(2024-04-01)

A big thank you to the following 24 contributors this last month:

  • rpardim (4)
  • dependabot (3)
  • electrocret (3)
  • bionicman (2)
  • PipoCanaja (2)
  • eskyuu (2)
  • Walkablenormal (2)
  • bnerickson (2)
  • rudybroersma (2)
  • d-k-7 (1)
  • murrant (1)
  • czarnian (1)
  • dmbokhan (1)
  • TheMysteriousX (1)
  • msaringer (1)
  • Didr (1)
  • vhuk (1)
  • Jellyfrog (1)
  • KingDaveRa (1)
  • Npeca75 (1)
  • dethmetaljeff (1)
  • blknight88 (1)
  • gunkaaa (1)
  • pjordanovic (1)

Thanks to maintainers and others that helped with pull requests this month:

  • Jellyfrog (25)
  • electrocret (7)
  • PipoCanaja (5)
  • murrant (2)
  • laf (2)
  • mpikzink (1)
  • VVelox (1)
"},{"location":"General/Changelog/#feature_4","title":"Feature","text":"
  • Support for InfluxDB V2 API (#15861) - Walkablenormal
"},{"location":"General/Changelog/#breaking-change_2","title":"Breaking Change","text":"
  • Wireguard application graph cleanup and new wireguard interface/global metrics. (#15847) - bnerickson
"},{"location":"General/Changelog/#device_5","title":"Device","text":"
  • Fix catos discovery (#15915) - d-k-7
  • Add health sensors (#15910) - murrant
  • Add support for Huawei YunShan OS (#15903) - czarnian
  • Add support for Ubiquiti Unifi USP-RPS device (#15900) - bionicman
  • Add support for Ubiquiti Unifi LTE devices. (#15899) - bionicman
  • Checkpoint Gaia PowerSupply state sensor (#15882) - rpardim
  • Add support for Cisco FTD 3105 (#15881) - msaringer
  • Fix for Checkpoint Gaia VPN state sensor (#15878) - rpardim
  • Support for Forcepoint NGFW 6.11 and later (#15872) - vhuk
  • A10 ACOS version, state and count sensors (#15871) - rpardim
  • F5 BIG-IP state and count sensors (#15865) - rpardim
  • Supermicro bmc updates (#15862) - dethmetaljeff
  • YAMLized version of previous PR for Ericsson SSR 80xx routers (#15834) - rudybroersma
  • Fix for FortiSwitch RPM/percentage fans (#15829) - rudybroersma
  • Move sentry3 current/voltage/power sensors to YAML (#15715) - gunkaaa
  • Device - EPSON DS-860 + Network Interface Unit DSBXNW1 (#15420) - pjordanovic
"},{"location":"General/Changelog/#applications_3","title":"Applications","text":"
  • Systemd Application Code Cleanup and new Systemd Unit State Metrics. (#15848) - bnerickson
"},{"location":"General/Changelog/#discovery_1","title":"Discovery","text":"
  • Bug - Fix OSes 'Junos' and 'Hirschmann' misuse of entPhysicalIndex (#15886) - TheMysteriousX
"},{"location":"General/Changelog/#bug_5","title":"Bug","text":"
  • Fix Vrf Table (#15912) - electrocret
  • Fix for explicit timezone selection (#15890) - eskyuu
  • Bug - fix extra fields in DB entry create/update (#15883) - PipoCanaja
  • Remove config_bgp config check in bird2 app (#15877) - Didr
  • Custommap label fixes (#15875) - eskyuu
  • [ipv4] fix /32 addresses discovery (#15863) - Npeca75
"},{"location":"General/Changelog/#refactor_2","title":"Refactor","text":"
  • Refactor - remove unused entPhysicalIndex_measured (#15892) - PipoCanaja
"},{"location":"General/Changelog/#documentation_5","title":"Documentation","text":"
  • Added additional lines for selinux config to work with RHEL8 (#15864) - KingDaveRa
  • Fix @signedGraphTag documention (#15853) - blknight88
"},{"location":"General/Changelog/#tests_2","title":"Tests","text":"
  • Bump Github Actions to Node.JS 20. (#15873) - Walkablenormal
"},{"location":"General/Changelog/#dependencies_4","title":"Dependencies","text":"
  • Bump express from 4.18.2 to 4.19.2 (#15913) - dependabot
  • Bump webpack-dev-middleware from 5.3.3 to 5.3.4 (#15907) - dependabot
  • Bump follow-redirects from 1.15.4 to 1.15.6 (#15897) - dependabot
  • Update dependencies (#15869) - Jellyfrog
"},{"location":"General/Changelog/#2420","title":"24.2.0","text":"

(2024-02-27)

A big thank you to the following 46 contributors this last month:

  • rudybroersma (14)
  • Npeca75 (10)
  • eskyuu (6)
  • electrocret (5)
  • PipoCanaja (5)
  • Jellyfrog (5)
  • vhuk (5)
  • murrant (5)
  • bnerickson (3)
  • fbouynot (3)
  • FlyveHest (2)
  • nickhilliard (2)
  • dependabot (2)
  • richard-ririe (2)
  • laf (2)
  • SourceDoctor (2)
  • VVelox (2)
  • VoipTelCH (1)
  • fabriciotm (1)
  • dirkx (1)
  • swerveshot (1)
  • jmesserli (1)
  • lrizzi (1)
  • Personwho (1)
  • OSIRIS-REx (1)
  • xorrkaz (1)
  • jcostom (1)
  • tevkar (1)
  • descilla (1)
  • arjitc (1)
  • My-Random-Thoughts (1)
  • dlangille (1)
  • blknight88 (1)
  • z0d1ac-RU (1)
  • lferrerfmv (1)
  • gil-obradors (1)
  • gunkaaa (1)
  • TvL2386 (1)
  • santiag0z (1)
  • EinGlasVollKakao (1)
  • kakohegyi (1)
  • i4networks (1)
  • Bierchermuesli (1)
  • mhamzak008 (1)
  • nicklockhart-fullfibre (1)
  • LoveSkylark (1)

Thanks to maintainers and others that helped with pull requests this month:

  • PipoCanaja (35)
  • Jellyfrog (30)
  • electrocret (26)
  • laf (21)
  • murrant (11)
  • mpikzink (1)
  • rudybroersma (1)
  • ottorei (1)
  • vhuk (1)
"},{"location":"General/Changelog/#feature_5","title":"Feature","text":"
  • Additional custom map features (#15806) - eskyuu
  • Add/Remove devices from static devicegroups (#15775) - richard-ririe
  • Option to ignore device status (#15697) - SourceDoctor
  • Add functionality for custom maps (weathermaps) (#15633) - eskyuu
  • Alert Rule Editor: new notes field & SQL field improove (#15631) - Bierchermuesli
  • NAC - Improve search in WebUI - Keep Historical data (#15629) - PipoCanaja
"},{"location":"General/Changelog/#security_1","title":"Security","text":"
  • Fix XSS in default example plugin (#15711) - murrant
"},{"location":"General/Changelog/#device_6","title":"Device","text":"
  • Updated SLA poller for Cisco Nexus 9000 (#15855) - FlyveHest
  • Update geist-watchdog.yaml (#15851) - fabriciotm
  • Correctly identify FS Datacenter Switch N8560-48BC (#15837) - rudybroersma
  • Konica printers additional counters (#15826) - Npeca75
  • Add HSRP state sensors for Cisco IOSXE on L3 switches (#15823) - rudybroersma
  • Add HSRP Sensor support for IOSXR (#15821) - electrocret
  • Add support for Cisco IE1000 (#15820) - rudybroersma
  • Initial support for Eltex mes24xx (#15816) - Npeca75
  • Add support for Cadant E6000 (#15813) - nickhilliard
  • Add LRT-C / LCM-B / LRS-D / LCM-B modules to Luminato model (#15812) - nickhilliard
  • Add HSRP state sensors for Cisco IOS on L3 switches (#15809) - rudybroersma
  • [rfc1628] Add UPS Test (battery test) status sensor (#15802) - Npeca75
  • Add build 22631 as Windows 11 23H2 (#15800) - vhuk
  • Zyxel ZynOS PoE Budget sensor support (#15798) - rudybroersma
  • Add Procurve NAC support (#15794) - vhuk
  • Add ArubaOS-CX VSF state sensor support (#15793) - rudybroersma
  • Support for new os/devices, CTS (#15790) - OSIRIS-REx
  • Support for new Lancom devices (#15779) - rudybroersma
  • Add NAC support for Powerconnect (#15778) - vhuk
  • Detect UniFi U7 APs as UniFi AP type (#15776) - jcostom
  • FS.com S5810 Discovery fix (#15765) - rudybroersma
  • Device - webpower smart II snmp UPS card (#15764) - Npeca75
  • Support for temp sensors - WUT Thermometers - W57605 and W57614 (#15757) - rudybroersma
  • Initial support for Supermicro BMC (#15750) - Npeca75
  • ArubaOS-CX PSU state sensor support & OS and serial detection (#15738) - rudybroersma
  • Add FortiSwitch PSU state sensor support (#15735) - rudybroersma
  • Added support for Dlink dgs-1250-28x (#15734) - Npeca75
  • Add FortiGate DHCP Scope usage percentage sensors (#15727) - rudybroersma
  • Added MES 2348B (#15725) - z0d1ac-RU
  • Add FortiGate license status sensors (#15722) - rudybroersma
  • Handle icmpjitter SLA parsing for iosxe (#15707) - FlyveHest
  • Zyxel Wireless Controller OS ( Zyxel NXC series ) (#15694) - kakohegyi
  • Device - fix Counter64 octets value in 32bit column bgpPeerInTotalMessages (#15621) - PipoCanaja
  • Fix tp-link jetstream FDB discovery (#14321) - Npeca75
"},{"location":"General/Changelog/#webui_5","title":"Webui","text":"
  • Disable Page Refresh on Oxidized Tools Page (#15831) - electrocret
  • Modify the date selector to use the session timezone (#15783) - eskyuu
  • Switch bill_notes input to textarea (#15749) - arjitc
  • Sort smart app disks by label (#15686) - SourceDoctor
"},{"location":"General/Changelog/#alerting_4","title":"Alerting","text":"
  • Add support for Webex max message length. (#15789) - xorrkaz
  • Rename JiraServiceManagement.php to Jiraservicemanagement.php (#15717) - gil-obradors
  • Add JiraServiceManagement Transport (#15593) - mhamzak008
  • Transport - Jira transport rewrite (#15561) - LoveSkylark
"},{"location":"General/Changelog/#graphs_2","title":"Graphs","text":"
  • Fixed graphs for icmp service showing PL 4 times (#15856) - VoipTelCH
  • Socket Statistic Application cleanup and application page graph fixes. (#15845) - bnerickson
"},{"location":"General/Changelog/#applications_4","title":"Applications","text":"
  • Deliver output for a specific memcached instance (#15759) - tevkar
  • Update nvidia.inc.php (#15756) - descilla
  • Add BorgBackup monitoring support (#15591) - VVelox
  • Add dhcp-stats tests and update for v3 of the extend (#15378) - VVelox
"},{"location":"General/Changelog/#billing","title":"Billing","text":"
  • Updated bill_data table, alter indexes and add new column (#15751) - laf
"},{"location":"General/Changelog/#api_4","title":"Api","text":"
  • Add API endpoints to update and delete Device Groups (#15774) - richard-ririe
  • Add port description API endpoints and documentation (#15578) - nicklockhart-fullfibre
"},{"location":"General/Changelog/#settings_1","title":"Settings","text":"
  • Fix twofactor default value (#15772) - murrant
  • Add isis module to os schema (#15710) - murrant
"},{"location":"General/Changelog/#discovery_2","title":"Discovery","text":"
  • Fall back to IPV6-MIB IPv6 address discovery if IP-MIB IPv6 address discovery doesn't return any valid addresses (#15714) - gunkaaa
"},{"location":"General/Changelog/#oxidized","title":"Oxidized","text":"
  • Add PollerGroup as an option for OxidizedMap (#15696) - electrocret
"},{"location":"General/Changelog/#bug_6","title":"Bug","text":"
  • Update Port Real Time Graph error (#15846) - electrocret
  • [bugfix] Fix json-app-tool.php to work with Oid class. (#15844) - bnerickson
  • Fix for linkDown/linkUp ifOperStatus (#15835) - PipoCanaja
  • Fix \"Tempurature\" Typo (#15811) - lrizzi
  • Bug fixes for the custom maps (#15810) - eskyuu
  • Remove dumpRawSql() function in AlertUtil.php (#15803) - Personwho
  • Make all image URLs absolute and fix path for viewer (#15788) - eskyuu
  • Prevent ansi colors in key:generate output (#15773) - Jellyfrog
  • VRP - avoid emptying bgpPeers description at discovery when manually set (#15713) - PipoCanaja
  • OSPF instances and missing mandatory fields fix attempt (#15712) - PipoCanaja
  • Fixed typo in misc/alert_rules.json with regards to \"Space on ...\" alerts (#15708) - TvL2386
  • Don't escape leaflet tile url in location edit map (#15695) - EinGlasVollKakao
  • Show error if \"Check Type\" field is empty when creating new service template (#15685) - vhuk
"},{"location":"General/Changelog/#refactor_3","title":"Refactor","text":"
  • Rewrite ups-nut discovery to SnmpQuery:: (#15850) - Npeca75
  • Rewrite lmsensors discovery to SnmpQuery:: (#15833) - Npeca75
  • Rewrite ipv4 address discovery to Eloquent (#15830) - Npeca75
"},{"location":"General/Changelog/#documentation_6","title":"Documentation","text":"
  • Applications.md formatting update for better readability. (#15849) - bnerickson
  • Update Images.md (#15824) - swerveshot
  • More precise OAuth group/role claim information (#15817) - jmesserli
  • Add selinux open directory permission for rrdcached in RRDCached.md (#15755) - fbouynot
  • Missing dir read permission in sepolicy in RRDCached.md (#15754) - fbouynot
  • Update SQL override section after switch to SQL strict mode (#15736) - blknight88
  • Add CentOS option to SMART dependency install (#15704) - fbouynot
"},{"location":"General/Changelog/#misc_3","title":"Misc","text":"
  • Add kelvin to celcius conversion (#15836) - dirkx
"},{"location":"General/Changelog/#mibs_3","title":"Mibs","text":"
  • Update watchguard MIBs (#15719) - lferrerfmv
"},{"location":"General/Changelog/#dependencies_5","title":"Dependencies","text":"
  • Bump composer/composer from 2.6.6 to 2.7.0 (#15808) - dependabot
  • Update PHP dependencies (#15737) - murrant
  • Bump follow-redirects from 1.15.3 to 1.15.4 (#15724) - dependabot
"},{"location":"General/Changelog/#2410","title":"24.1.0","text":"

(2024-01-07)

A big thank you to the following 37 contributors this last month:

  • PipoCanaja (12)
  • murrant (7)
  • laf (5)
  • electrocret (3)
  • peejaychilds (3)
  • Jellyfrog (2)
  • vhuk (2)
  • MittWillson (2)
  • Bierchermuesli (2)
  • netravnen (1)
  • iliessens (1)
  • sarcastic6 (1)
  • SourceDoctor (1)
  • altf4arnold (1)
  • robje (1)
  • rudybroersma (1)
  • mtentilucci (1)
  • tuxgasy (1)
  • craig-nokia (1)
  • brianegge (1)
  • amyjohn000 (1)
  • VirTechSystems (1)
  • atj (1)
  • lhwolfarth (1)
  • bonzo81 (1)
  • Sweeny42 (1)
  • jduke-halls (1)
  • pjordanovic (1)
  • dependabot (1)
  • TheMysteriousX (1)
  • swiftnode-linden (1)
  • cguillaumie (1)
  • luc-ass (1)
  • VVelox (1)
  • Leo-FJ (1)
  • MaxPecc (1)
  • jerji (1)

Thanks to maintainers and others that helped with pull requests this month:

  • Jellyfrog (20)
  • murrant (16)
  • PipoCanaja (15)
  • electrocret (12)
  • craig-nokia (1)
  • ottorei (1)
"},{"location":"General/Changelog/#device_7","title":"Device","text":"
  • Ignore nameless health sensors for Fortigate (#15678) - iliessens
  • Add support for RoomAlert 32S device (#15676) - sarcastic6
  • Device - Add Cisco REP Segment state sensor (#15666) - rudybroersma
  • Added better support for some HiveOS Wireless devices (#15661) - laf
  • Fix HPE iLO CPU Status Sensor Description (#15660) - mtentilucci
  • Fix OcNOS detection for recent firmware versions (#15642) - murrant
  • Add support for Fortinet FortiAPs (#15641) - atj
  • Fixing memory scale for datacom-dmos devices (#15640) - lhwolfarth
  • Bug - Fix Cisco NTP values (#15639) - PipoCanaja
  • Add support for Forcepoint NGFW 6.10 and older (#15632) - vhuk
  • Bug - timos MPLS - more poller fixes (#15624) - PipoCanaja
  • Add memory readings for Draytek OS (#15618) - Sweeny42
  • Updated support for HiveOS Wireless newer models (#15610) - laf
  • Add HPE iLO 6 to discovery (#15607) - jduke-halls
  • Incorrect discovery APC Smart-UPS RT 3000 XL 4.1 ( APC Web/SNMP Management Card (AP9619 MB:v4.1.1 PF:v3.9.4) as multi-phase ups (#15602) - pjordanovic
  • Device - McAfee Web Gateway -> SkyHigh Web Gateway (#15596) - PipoCanaja
  • Add and extend support for Hirshmann devices (#15588) - cguillaumie
  • Updated regex for HWG STE2 r2 to better detect hardware and software version (#15573) - luc-ass
  • Update entity-sensor.inc.php for xos' os (#15552) - Leo-FJ
  • Added support of new OS for NTP/PTP systems: Meinberg OS, Safran (Orolia), Oscilloquartz (Adva) (#15453) - MaxPecc
  • Zhone health (#15276) - jerji
  • Fix wrong ASN discovery on non-BGP Devices (#14948) - Bierchermuesli
"},{"location":"General/Changelog/#webui_6","title":"Webui","text":"
  • Clarify In/Out on Ports table. (#15680) - electrocret
  • WebUI - Filter FDB and ARP tabs in port page if empty (#15653) - PipoCanaja
  • Update Pushover.php (#15652) - brianegge
  • Mark old alert email settings as deprecated (#15650) - murrant
  • Add bad port settings to webui (#15649) - murrant
  • Bug - FDB Table - allow empty searchby as well (#15626) - PipoCanaja
  • Update alertlog query to be more efficient (#15622) - laf
  • Add vendor to searchby rules function (#15619) - bonzo81
  • Fix grabled characters when oid already UTF-8 (#15615) - MittWillson
"},{"location":"General/Changelog/#graphs_3","title":"Graphs","text":"
  • Change default graph image to SVG (#15586) - electrocret
"},{"location":"General/Changelog/#api_5","title":"Api","text":"
  • API add_device: Add ping_ping fallback option (#15637) - murrant
  • More filter options for the BGP peer API endpoint (#15599) - Bierchermuesli
"},{"location":"General/Changelog/#discovery_3","title":"Discovery","text":"
  • Set array before use to stop discovery erroring (#15604) - laf
"},{"location":"General/Changelog/#authentication_2","title":"Authentication","text":"
  • Add support for Okta Group claims to set Roles (#15592) - peejaychilds
  • Output Roles in auth_test script (#15587) - peejaychilds
"},{"location":"General/Changelog/#bug_7","title":"Bug","text":"
  • Fix Rancid error messages (#15683) - vhuk
  • Fix smart application parsing (#15672) - SourceDoctor
  • Fix pagination in alert rules page (#15659) - tuxgasy
  • Bug - \"null\" checks for SAR 7705 release 8.X (#15657) - craig-nokia
  • Bug - missing \"use\" statement in NTP Cisco (#15656) - PipoCanaja
  • Bug - TPLink - fix null exception for LLDP discovery WIP (#15628) - PipoCanaja
  • Bug - bgp-peers error in Timos -> dbFacile cleanup (#15620) - PipoCanaja
  • Bug - ADSL ifIndex to port error not handled (#15617) - PipoCanaja
  • Bug - XDSL adslAtucCurrOutputPwr exception (Cisco CSCvj53634) (#15614) - PipoCanaja
  • Bug - null checks in Nokia MPLS polling (#15613) - PipoCanaja
  • Bug - Nokia discovery protocols (#15606) - PipoCanaja
  • Make vminfo.vmwVmGuestOS wider (#15595) - TheMysteriousX
  • Fixed state flag causing sql issues in test-template.php (#15589) - laf
"},{"location":"General/Changelog/#documentation_7","title":"Documentation","text":"
  • Add traceroute to the installed packages doc (#15645) - VirTechSystems
  • Fix documentation formatting (#15635) - Jellyfrog
  • Fix formatting in OAuth-SAML.md (#15616) - peejaychilds
  • Update Debian 12 Installation Instructions. (#15590) - swiftnode-linden
  • Add Debian 12 to install docs (#15559) - VVelox
"},{"location":"General/Changelog/#misc_4","title":"Misc","text":"
  • Updating the logo to higher resolution one (#15669) - altf4arnold
  • Update the type of nummonbssid column in the access_points table (#15647) - amyjohn000
  • Fix device format missing display field (#15623) - MittWillson
  • Link Model (#15611) - murrant
  • Add space to Oxidized error msg (#15603) - electrocret
"},{"location":"General/Changelog/#internal-features_2","title":"Internal Features","text":"
  • New utility Number::constrainInteger() (#15663) - murrant
"},{"location":"General/Changelog/#mibs_4","title":"Mibs","text":"
  • Update MIKROTIK-MIB (#15690) - netravnen
"},{"location":"General/Changelog/#dependencies_6","title":"Dependencies","text":"
  • Update javascript dependencies (#15651) - murrant
  • Bump phpseclib/phpseclib from 3.0.21 to 3.0.34 (#15600) - dependabot
"},{"location":"General/Changelog/#old-changelogs","title":"Old Changelogs","text":""},{"location":"General/Releases/","title":"Choosing a release","text":"

We try to ensure that breaking changes aren't introduced by utilising various automated code testing, syntax testing and unit testing along with manual code review. However bugs can and do get introduced as well as major refactoring to improve the quality of the code base.

We have two branches available for you to use. The default is the master branch.

"},{"location":"General/Releases/#development-branch","title":"Development branch","text":"

Our master branch is our dev branch, this is actively commited to and it's not uncommon for multiple commits to be merged in daily. As such sometimes changes will be introduced which will cause unintended issues. If this happens we are usually quick to fix or revert those changes.

We appreciate everyone that runs this branch as you are in essence secondary testers to the automation and manually testing that is done during the merge stages.

You can configure your install (this is the default) to use this branch by setting lnms config:set update_channel master and ensuring you switch to the master branch with:

cd /opt/librenms && git checkout master

"},{"location":"General/Releases/#stable-branch","title":"Stable branch","text":"

With this in mind, we provide a monthly stable release which is released on or around the last Sunday of the month. Code pull requests (aside from Bug fixes) are stopped days leading up to the release to ensure that we have a clean working branch at that point.

The changelog is also updated and will reference the release number and date so you can see what changes have been made since the last release.

To switch to using stable branches you can set lnms config:set update_channel release

This will pause updates until the next stable release, at that time LibreNMS will update to the stable release and continue to only update to stable releases. Downgrading is not supported on LibreNMS and will likely cause bugs.

"},{"location":"General/Security/","title":"General","text":"

Like any good software we take security seriously. However, bugs do make it into the software along with the history of the code base we inherited. It's how we deal with identified vulnerabilities that should show that we take things seriously.

"},{"location":"General/Security/#securing-your-install","title":"Securing your install","text":"

As with any system of this nature, we highly recommend that you restrict access to the install via a firewall or VPN.

Please ensure you keep your install up to date.

"},{"location":"General/Security/#enable-https","title":"Enable HTTPS","text":"

It is also highly recommended that the Web interface is protected with an SSL certificate such as ones provided by LetsEncrypt.

"},{"location":"General/Security/#secure-session-cookies","title":"Secure Session Cookies","text":"

Once you have enabled HTTPS for your install, you should set SESSION_SECURE_COOKIE=true in your .env file. This will require cookies to be transferred by secure protocol and prevent any MiM attacks against it.

"},{"location":"General/Security/#trusted-proxies","title":"Trusted Proxies","text":"

When using a reverse proxy, you may restrict the hosts allowed to forward headers to LibreNMS. By default this allows all proxies, due to legacy reasons.

Set APP_TRUSTED_PROXIES in your .env to an empty string or the urls to the proxies allowed to forward.

"},{"location":"General/Security/#reporting-vulnerabilities","title":"Reporting vulnerabilities","text":"

Like anyone, we appreciate the work people put in to find flaws in software and welcome anyone to do so with LibreNMS, this will lead to better quality and more secure software for everyone.

If you think you've found a vulnerability and want to discuss it with some of the core team then you can contact us on Discord and we will endeavour to get back to as quick as we can, this is usually within 24 hours.

We are happy to attribute credit to the findings, but we ask that we're given a chance to patch any vulnerability before public disclosure so that our users can update as soon as a fix is available.

"},{"location":"General/Updating/","title":"Updating an Install","text":"

By default, LibreNMS is set to automatically update. If you have disabled this feature then you can perform a manual update.

"},{"location":"General/Updating/#manual-update","title":"Manual update","text":"

If you would like to perform a manual update then you can do this by running the following command as the librenms user:

./daily.sh

This will update both the core LibreNMS files but also update the database structure if updates are available.

"},{"location":"General/Updating/#advanced-users","title":"Advanced users","text":"

If you absolutely must update manually without using ./daily.sh then you can do so by running the following commands:

cd /opt/librenms\ngit pull\n./scripts/composer_wrapper.php install --no-dev\n./lnms migrate\n./validate.php\n
"},{"location":"General/Updating/#disabling-automatic-updates","title":"Disabling automatic updates","text":"

LibreNMS by default performs updates on a daily basis. This can be disabled in the WebUI Global Settings under System -> Updates, or using lnms

Warning

You should never remove daily.sh from the cronjob! This does database cleanup and other processes in addition to updating.

settings/system/updates

lnms config:set update false\n
"},{"location":"General/Welcome-to-Observium-users/","title":"Welcome to Observium users","text":"

LibreNMS is a fork of Observium. The reason for the fork has nothing to do with Observium's move to community vs. paid versions. It is simply that we have different priorities and values to the Observium development team. We decided to fork (reluctantly) because we like using Observium, but we want to collaborate on a community-based project with like-minded IT professionals. See README.md and the references there for more information about the kind of community we're trying to promote.

LibreNMS was forked from the last GPL-licensed version of Observium.

Thanks to one of our users, Dan Brown, who has written a migration script, you can easily move your Observium install over to LibreNMS. This also takes care of moving from one CPU architecture to another. Give it a try :)

How LibreNMS will be different from Observium:

  • We will have an inclusive community, where it's OK to ask stupid questions, and OK to ask for things that aren't on the roadmap. If you'd like to see something added, add or comment on the relevant issue in our Community forum.
  • Development decisions will be community-driven. We want to make software that fulfills its users' needs.
  • There are no plans for a paid version, and we don't anticipate this ever changing.
  • There are no current plans for paid support, but this may be added later if there is sufficient demand.
  • We use git for version control and GitHub for hosting to make it as easy and painless as possible to create forked or private versions.

Reasons why you might want to use Observium instead of LibreNMS:

  • You have a financial investment in Observium and aren't concerned about community contributions.
  • You don't like the GNU General Public License, version 3 or the philosophy of Free Software/copyleft in general.

Reasons why you might want to use LibreNMS instead of Observium:

  • You want to work with others on the project, knowing that your investment of time and effort will not be wasted.
  • You want to add and experiment with features that are not a priority for the Observium developers. See CONTRIBUTING for more details.
  • You want to make use of the additional features LibreNMS can offer.
"},{"location":"Installation/Docker/","title":"Docker","text":"

An official LibreNMS docker image based on Alpine Linux and Nginx is available on DockerHub.

"},{"location":"Installation/Docker/#documentation","title":"Documentation","text":"

Full install and configuration documentation can be found on the GitHub repository.

"},{"location":"Installation/Docker/#quick-install","title":"Quick install","text":"
  1. Install docker: https://docs.docker.com/engine/install/
  2. Download and unzip composer files:
    mkdir librenms\ncd librenms\nwget https://github.com/librenms/docker/archive/refs/heads/master.zip\nunzip master.zip\ncd docker-master/examples/compose\n
  3. Set a new mysql password in .env and inspect compose.yml
  4. Bring up the docker containers
    sudo docker compose -f compose.yml up -d\n
  5. Open webui to finish configuration. http://localhost:8000 (use the correct ip or name instead of localhost)
"},{"location":"Installation/Images/","title":"LibreNMS VMs","text":"

NOTE: We highly advise that you change all passwords on this image when you deploy it!!

NOTE: These images ship with a vagrant user, please remove this user account when you deploy it!!

NOTE: Read the above note again!

We have available for download a pre-built image based on Ubuntu 22.04. These images are built using packer.io.

Details of the image and it's setup are:

At present we provide the following builds:

  • OVA Built with VirtualBox.
  • OVA Built for VMWare ESXi.
  • Vagrant Box file.

  • Any issues and or help with these images should be reported via Community Forum or our Discord server

"},{"location":"Installation/Images/#setup","title":"Setup","text":"
  • US Keyboard
  • Etc/UTC Timezone
  • 4 Poller Wrapper threads
"},{"location":"Installation/Images/#software","title":"Software","text":"
  • PHP 8.1
  • MariaDB
  • Syslog-ng
"},{"location":"Installation/Images/#features","title":"Features","text":"
  • Oxidized installed but not configured
  • Weathermap plugin enabled
  • Billing enabled
  • RRDCached enabled
  • Service checks enabled
  • Syslog enabled
"},{"location":"Installation/Images/#download","title":"Download","text":"

All images can be downloaded from GitHub. The tags follow the main LibreNMS repo. When a new LibreNMS release is available we will push new images out running that version. Please do note that if you download an older release with a view to running that specific version, you will need to disable updates lnms config:set update false.

"},{"location":"Installation/Images/#accesscredentials","title":"Access/Credentials","text":"

If you are using the VirtualBox image then to access your newly imported VM, these ports are forwarded from your machine to the VM: 8080 for WebUI and 2023 for SSH. Remember to edit/remove them if you change (and you should) the VM network configuration.

  • WebUI (http://localhost)
  • username: librenms
  • password: D32fwefwef

  • SSH (change the password ssh://localhost:2023)

  • username: librenms
  • password: CDne3fwdfds

  • SSH (remove this account)

  • username: vagrant
  • password; vagrant

  • MySQL/MariaDB

  • username: librenms
  • password: D42nf23rewD
"},{"location":"Installation/Images/#contributing","title":"Contributing","text":"

If you would like to help with these images whether it's add additional features or default software / settings then you can do so on GitHub.

"},{"location":"Installation/Install-LibreNMS/","title":"Install LibreNMS","text":""},{"location":"Installation/Install-LibreNMS/#prepare-linux-server","title":"Prepare Linux Server","text":"

You should have an installed Linux server running one of the supported OS. Make sure you select your server's OS in the tabbed options below. Choice of web server is your preference, NGINX is recommended.

Connect to the server command line and follow the instructions below.

Note

These instructions assume you are the root user. If you are not, prepend sudo to the shell commands (the ones that aren't at mysql> prompts) or temporarily become a user with root privileges with sudo -s or sudo -i.

Please note the minimum supported PHP version is 8.1

"},{"location":"Installation/Install-LibreNMS/#install-required-packages","title":"Install Required Packages","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12 NGINX
apt install acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd unzip python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip whois traceroute\n
NGINX
apt install acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd unzip python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip whois traceroute\n
NGINXApache
apt install software-properties-common\nadd-apt-repository universe\nadd-apt-repository ppa:ondrej/php\napt update\napt install acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd unzip python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip whois traceroute\n
apt install software-properties-common\nadd-apt-repository universe\nadd-apt-repository ppa:ondrej/php\napt update\napt install acl curl apache2 fping git graphviz imagemagick libapache2-mod-fcgid mariadb-client mariadb-server mtr-tiny nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd whois python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip unzip traceroute\n
NGINXApache
dnf -y install epel-release\ndnf -y install dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm\ndnf module reset php\ndnf module enable php:8.1\ndnf install bash-completion cronie fping git ImageMagick mariadb-server mtr net-snmp net-snmp-utils nginx nmap php-fpm php-cli php-common php-curl php-gd php-gmp php-json php-mbstring php-process php-snmp php-xml php-zip php-mysqlnd python3 python3-PyMySQL python3-redis python3-memcached python3-pip python3-systemd rrdtool unzip\n
dnf -y install epel-release\ndnf -y install dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm\ndnf module reset php\ndnf module enable php:remi-8.1\ndnf install bash-completion cronie fping gcc git httpd ImageMagick mariadb-server mtr net-snmp net-snmp-utils nmap php-fpm php-cli php-common php-curl php-gd php-gmp php-json php-mbstring php-process php-snmp php-xml php-zip php-mysqlnd python3 python3-devel python3-PyMySQL python3-redis python3-memcached python3-pip python3-systemd rrdtool unzip \n
NGINX
apt install apt-transport-https lsb-release ca-certificates wget acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php8.2-cli php8.2-curl php8.2-fpm php8.2-gd php8.2-gmp php8.2-mbstring php8.2-mysql php8.2-snmp php8.2-xml php8.2-zip python3-dotenv python3-pymysql python3-redis python3-setuptools python3-systemd python3-pip rrdtool snmp snmpd unzip whois\n
"},{"location":"Installation/Install-LibreNMS/#add-librenms-user","title":"Add librenms user","text":"
useradd librenms -d /opt/librenms -M -r -s \"$(which bash)\"\n
"},{"location":"Installation/Install-LibreNMS/#download-librenms","title":"Download LibreNMS","text":"
cd /opt\ngit clone https://github.com/librenms/librenms.git\n
"},{"location":"Installation/Install-LibreNMS/#set-permissions","title":"Set permissions","text":"
chown -R librenms:librenms /opt/librenms\nchmod 771 /opt/librenms\nsetfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/\nsetfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/\n
"},{"location":"Installation/Install-LibreNMS/#install-php-dependencies","title":"Install PHP dependencies","text":"

su - librenms\n./scripts/composer_wrapper.php install --no-dev\nexit\n
Sometimes when there is a proxy used to gain internet access, the above script may fail. The workaround is to install the composer package manually. For a global installation:
wget https://getcomposer.org/composer-stable.phar\nmv composer-stable.phar /usr/bin/composer\nchmod +x /usr/bin/composer\n

"},{"location":"Installation/Install-LibreNMS/#set-timezone","title":"Set timezone","text":"

See https://php.net/manual/en/timezones.php for a list of supported timezones. Valid examples are: \"America/New_York\", \"Australia/Brisbane\", \"Etc/UTC\". Ensure date.timezone is set in php.ini to your preferred time zone.

Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12
vi /etc/php/8.3/fpm/php.ini\nvi /etc/php/8.3/cli/php.ini\n
vi /etc/php/8.1/fpm/php.ini\nvi /etc/php/8.1/cli/php.ini\n
vi /etc/php/8.1/fpm/php.ini\nvi /etc/php/8.1/cli/php.ini\n
vi /etc/php.ini\n
vi /etc/php/8.2/fpm/php.ini\nvi /etc/php/8.2/cli/php.ini\n

Remember to set the system timezone as well.

timedatectl set-timezone Etc/UTC\n
"},{"location":"Installation/Install-LibreNMS/#configure-mariadb","title":"Configure MariaDB","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12
vi /etc/mysql/mariadb.conf.d/50-server.cnf\n
vi /etc/mysql/mariadb.conf.d/50-server.cnf\n
vi /etc/mysql/mariadb.conf.d/50-server.cnf\n
vi /etc/my.cnf.d/mariadb-server.cnf\n
vi /etc/mysql/mariadb.conf.d/50-server.cnf\n

Within the [mysqld] section add:

innodb_file_per_table=1\nlower_case_table_names=0\n

Then restart MariaDB

systemctl enable mariadb\nsystemctl restart mariadb\n
Start MariaDB client

mysql -u root\n

NOTE: Change the 'password' below to something secure.

CREATE DATABASE librenms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\nCREATE USER 'librenms'@'localhost' IDENTIFIED BY 'password';\nGRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'localhost';\nexit\n
"},{"location":"Installation/Install-LibreNMS/#configure-php-fpm","title":"Configure PHP-FPM","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12
cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/librenms.conf\nvi /etc/php/8.3/fpm/pool.d/librenms.conf\n
cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/librenms.conf\nvi /etc/php/8.1/fpm/pool.d/librenms.conf\n
cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/librenms.conf\nvi /etc/php/8.1/fpm/pool.d/librenms.conf\n
cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/librenms.conf\nvi /etc/php-fpm.d/librenms.conf\n
cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/librenms.conf\nvi /etc/php/8.2/fpm/pool.d/librenms.conf\n

Change [www] to [librenms]:

[librenms]\n

Change user and group to \"librenms\":

user = librenms\ngroup = librenms\n

Change listen to a unique path that must match your webserver's config (fastcgi_pass for NGINX and SetHandler for Apache) :

listen = /run/php-fpm-librenms.sock\n

If there are no other PHP web applications on this server, you may remove www.conf to save some resources. Feel free to tune the performance settings in librenms.conf to meet your needs.

"},{"location":"Installation/Install-LibreNMS/#configure-web-server","title":"Configure Web Server","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12 NGINX
vi /etc/nginx/conf.d/librenms.conf\n

Add the following config, edit server_name as required:

server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default\nsystemctl restart nginx\nsystemctl restart php8.3-fpm\n
NGINX
vi /etc/nginx/conf.d/librenms.conf\n

Add the following config, edit server_name as required:

server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
rm /etc/nginx/sites-enabled/default\nsystemctl restart nginx\nsystemctl restart php8.1-fpm\n
NGINXApache
vi /etc/nginx/conf.d/librenms.conf\n

Add the following config, edit server_name as required:

server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
rm /etc/nginx/sites-enabled/default\nsystemctl restart nginx\nsystemctl restart php8.1-fpm\n
vi /etc/apache2/sites-available/librenms.conf\n

Add the following config, edit ServerName as required:

<VirtualHost *:80>\n  DocumentRoot /opt/librenms/html/\n  ServerName  librenms.example.com\n\n  AllowEncodedSlashes NoDecode\n  <Directory \"/opt/librenms/html/\">\n    Require all granted\n    AllowOverride All\n    Options FollowSymLinks MultiViews\n  </Directory>\n\n  # Enable http authorization headers\n  <IfModule setenvif_module>\n    SetEnvIfNoCase ^Authorization$ \"(.+)\" HTTP_AUTHORIZATION=$1\n  </IfModule>\n\n  <FilesMatch \".+\\.php$\">\n    SetHandler \"proxy:unix:/run/php-fpm-librenms.sock|fcgi://localhost\"\n  </FilesMatch>\n</VirtualHost>\n
a2dissite 000-default\na2enmod proxy_fcgi setenvif rewrite\na2ensite librenms.conf\nsystemctl restart apache2\nsystemctl restart php8.1-fpm\n
NGINXApache
vi /etc/nginx/conf.d/librenms.conf\n

Add the following config, edit server_name as required:

server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n

NOTE: If this is the only site you are hosting on this server (it should be :)) then you will need to disable the default site.

Delete the server section from /etc/nginx/nginx.conf

systemctl enable --now nginx\nsystemctl enable --now php-fpm\n

Create the librenms.conf:

vi /etc/httpd/conf.d/librenms.conf\n

Add the following config, edit ServerName as required:

<VirtualHost *:80>\n  DocumentRoot /opt/librenms/html/\n  ServerName  librenms.example.com\n\n  AllowEncodedSlashes NoDecode\n  <Directory \"/opt/librenms/html/\">\n    Require all granted\n    AllowOverride All\n    Options FollowSymLinks MultiViews\n  </Directory>\n\n  # Enable http authorization headers\n  <IfModule setenvif_module>\n    SetEnvIfNoCase ^Authorization$ \"(.+)\" HTTP_AUTHORIZATION=$1\n  </IfModule>\n\n  <FilesMatch \".+\\.php$\">\n    SetHandler \"proxy:unix:/run/php-fpm-librenms.sock|fcgi://localhost\"\n  </FilesMatch>\n</VirtualHost>\n

NOTE: If this is the only site you are hosting on this server (it should be :)) then you will need to disable the default site. rm -f /etc/httpd/conf.d/welcome.conf

systemctl enable --now httpd\nsystemctl enable --now php-fpm\n
NGINX
vi /etc/nginx/sites-enabled/librenms.vhost\n

Add the following config, edit server_name as required:

server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
rm /etc/nginx/sites-enabled/default\nsystemctl reload nginx\nsystemctl restart php8.2-fpm\n
"},{"location":"Installation/Install-LibreNMS/#selinux","title":"SELinux","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12

SELinux not enabled by default

SELinux not enabled by default

SELinux not enabled by default

Install the policy tool for SELinux:

dnf install policycoreutils-python-utils\n

Configure the contexts needed by LibreNMS

semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/html(/.*)?'\nsemanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/(rrd|storage)(/.*)?'\nsemanage fcontext -a -t httpd_log_t \"/opt/librenms/logs(/.*)?\"\nsemanage fcontext -a -t httpd_cache_t '/opt/librenms/cache(/.*)?'\nsemanage fcontext -a -t bin_t '/opt/librenms/librenms-service.py'\nrestorecon -RFvv /opt/librenms\nsetsebool -P httpd_can_sendmail=1\nsetsebool -P httpd_execmem 1\nchcon -t httpd_sys_rw_content_t /opt/librenms/.env\n

Allow fping

Create the file http_fping.tt with the following contents. You can create this file anywhere, as it is a throw-away file. The last step in this install procedure will install the module in the proper location.

module http_fping 1.0;\n\nrequire {\ntype httpd_t;\nclass capability net_raw;\nclass rawip_socket { getopt create setopt write read };\n}\n\n#============= httpd_t ==============\nallow httpd_t self:capability net_raw;\nallow httpd_t self:rawip_socket { getopt create setopt write read };\n

Then run these commands

checkmodule -M -m -o http_fping.mod http_fping.tt\nsemodule_package -o http_fping.pp -m http_fping.mod\nsemodule -i http_fping.pp\n

Additional SELinux problems may be found by executing the following command

audit2why < /var/log/audit/audit.log\n

SELinux not enabled by default

"},{"location":"Installation/Install-LibreNMS/#allow-access-through-firewall","title":"Allow access through firewall","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12

Firewall not enabled by default

Firewall not enabled by default

Firewall not enabled by default

firewall-cmd --zone public --add-service http --add-service https\nfirewall-cmd --permanent --zone public --add-service http --add-service https\n

Firewall not enabled by default

"},{"location":"Installation/Install-LibreNMS/#enable-lnms-command-completion","title":"Enable lnms command completion","text":"

This feature grants you the opportunity to use tab for completion on lnms commands as you would for normal linux commands.

ln -s /opt/librenms/lnms /usr/bin/lnms\ncp /opt/librenms/misc/lnms-completion.bash /etc/bash_completion.d/\n
"},{"location":"Installation/Install-LibreNMS/#configure-snmpd","title":"Configure snmpd","text":"
cp /opt/librenms/snmpd.conf.example /etc/snmp/snmpd.conf\n
vi /etc/snmp/snmpd.conf\n

Edit the text which says RANDOMSTRINGGOESHERE and set your own community string.

curl -o /usr/bin/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro\nchmod +x /usr/bin/distro\nsystemctl enable snmpd\nsystemctl restart snmpd\n
"},{"location":"Installation/Install-LibreNMS/#cron-job","title":"Cron job","text":"
cp /opt/librenms/dist/librenms.cron /etc/cron.d/librenms\n

NOTE: Keep in mind that cron, by default, only uses a very limited set of environment variables. You may need to configure proxy variables for the cron invocation. Alternatively adding the proxy settings in config.php is possible too. The config.php file will be created in the upcoming steps. Review the following URL after you finished librenms install steps: https://docs.librenms.org//Support/Configuration/#proxy-support

"},{"location":"Installation/Install-LibreNMS/#enable-the-scheduler","title":"Enable the scheduler","text":"
cp /opt/librenms/dist/librenms-scheduler.service /opt/librenms/dist/librenms-scheduler.timer /etc/systemd/system/\n\nsystemctl enable librenms-scheduler.timer\nsystemctl start librenms-scheduler.timer\n
"},{"location":"Installation/Install-LibreNMS/#copy-logrotate-config","title":"Copy logrotate config","text":"

LibreNMS keeps logs in /opt/librenms/logs. Over time these can become large and be rotated out. To rotate out the old logs you can use the provided logrotate config file:

cp /opt/librenms/misc/librenms.logrotate /etc/logrotate.d/librenms\n
"},{"location":"Installation/Install-LibreNMS/#web-installer","title":"Web installer","text":"

Now head to the web installer and follow the on-screen instructions.

http://librenms.example.com/install

The web installer might prompt you to create a config.php file in your librenms install location manually, copying the content displayed on-screen to the file. If you have to do this, please remember to set the permissions on config.php after you copied the on-screen contents to the file. Run:

chown librenms:librenms /opt/librenms/config.php\n
"},{"location":"Installation/Install-LibreNMS/#final-steps","title":"Final steps","text":"

That's it! You now should be able to log in to http://librenms.example.com/. Please note that we have not covered HTTPS setup in this example, so your LibreNMS install is not secure by default. Please do not expose it to the public Internet unless you have configured HTTPS and taken appropriate web server hardening steps.

"},{"location":"Installation/Install-LibreNMS/#add-the-first-device","title":"Add the first device","text":"

We now suggest that you add localhost as your first device from within the WebUI.

"},{"location":"Installation/Install-LibreNMS/#troubleshooting","title":"Troubleshooting","text":"

If you ever have issues with your install, run validate.php:

sudo su - librenms\n./validate.php\n

There are various options for getting help listed on the LibreNMS web site: https://www.librenms.org/#support

"},{"location":"Installation/Install-LibreNMS/#what-next","title":"What next?","text":"

Now that you've installed LibreNMS, we'd suggest that you have a read of a few other docs to get you going:

  • Performance tuning
  • Alerting
  • Device Groups
  • Auto discovery
"},{"location":"Installation/Install-LibreNMS/#closing","title":"Closing","text":"

We hope you enjoy using LibreNMS. If you do, it would be great if you would consider opting into the stats system we have, please see this page on what it is and how to enable it.

If you would like to help make LibreNMS better there are many ways to help. You can also back LibreNMS on Open Collective.

"},{"location":"Installation/Migrating-from-Observium/","title":"Migrating from Observium","text":"

A LibreNMS user, Dan, has kindly provided full details and scripts to be able to migrate from Observium to LibreNMS.

We have mirrored the scripts he's provided with consent, these are available in the scripts\\Migration folder of your installation..

"},{"location":"Installation/Migrating-from-Observium/#setup","title":"Setup:","text":"

First I had to lay out my script requirements:

  • Build the RRD directories on LibreNMS
  • Convert the RRD files on Observium to XML (x86 to x64 move)
  • Copy the RRD/XML files to LibreNMS
  • Convert the XML files back to RRD files
  • Add the device to LibreNMS
"},{"location":"Installation/Migrating-from-Observium/#script","title":"Script:","text":"

There are two versions of the scripts available for you to download: - One converts the RRDs to XML and then back to RRD files when they hit the destination. This is a requirement if you are moving from x86 to x64. - Assuming you\u2019re moving servers that are on the same architecture, we can skip that step and just SCP the original RRD files.

For everything to work as originally intended, you\u2019ll need four files.\u00a0Put all four files on both servers, the scripts default to /tmp/:

  • nodelist.txt \u2013 this file contains the list of hosts you would like to move. This must match exactly to the hostname Observium uses
  • mkdir.sh \u2013 this script creates the necessary directories on your LibreNMS server
  • destwork.sh \u2013 depending on the version you choose, this script will add the device to LibreNMS and possibly convert from XML to RRD
  • convert.sh \u2013 convert is the main script we\u2019ll be calling. All of the magic happens here.

Feel free to crack open the scripts and modify them to suit you. Each file has a handful of variables you\u2019ll need to set for your conversion. They should be self-explanatory, but please leave a comment if you have trouble.

"},{"location":"Installation/Migrating-from-Observium/#conversion","title":"Conversion:","text":"

This section assumes the following:

  • Root access is available on both servers
  • You have SSH access to both servers
  • All four files have been placed in the tmp directory of both servers

I would strongly suggest you start with just one or two hosts and see how things work. For me, 10 standard sized devices took about 20 minutes with the RRD to XML conversion. Every environment will be different, so start slow and work your way up to full automation.

"},{"location":"Installation/Migrating-from-Observium/#ssh-keys","title":"SSH Keys","text":"

First thing we will want to do is exchange SSH keys so that we can automate the login process used by the scripts. Perform these steps on your Observium server:

ssh-keygen -t rsa

Accept the defaults and enter a passphrase if you wish. Then:

ssh-copy-id librenms

Where librenms is the hostname or IP of your destination server.

"},{"location":"Installation/Migrating-from-Observium/#nodelisttxt","title":"Nodelist.txt","text":"

The nodelist.txt file contains a list of hosts we want to migrate from Observium. These names must match the name of the RRD folder on Observium. You can get those names by running the following \u2013

ls /opt/observium/rrd/

Also important, the nodelist.txt file must be on\u00a0both your Observium and LibreNMS server. Once you have your list, edit nodelist.txt with\u00a0nano:

nano /tmp/nodelist.txt

And replace the dummy data with the hosts you are converting. CTRL+X and then Y to save your modifications. Make the same changes on the LibreNMS server.

"},{"location":"Installation/Migrating-from-Observium/#script-variables","title":"Script Variables","text":"

Now that we have nodelist.txt setup correctly, it is time to set the variables in all three shell scripts. We are going to start with convert.sh. Edit it with nano:

nano /tmp/convert.sh

and change the variables to suit your environment. Here is a quick list of them:

  • DEST \u2013 This should be the IP or hostname of your LibreNMS server
  • L_RRDPATH \u2013 This signifies the location of the LibreNMS RRD directory. The default value is the default install location
  • O_RRDPATH \u2013 Location of the Observium RRD directory. The default value is the default install location
  • MKDIR \u2013 Location of the mkdir.sh script
  • DESTSCRIPT \u2013 Location of the destwork.sh script
  • NODELIST \u2013 Location of the nodelist.txt file

Next, edit the destwork.sh script:

nano /tmp/destwork.sh

"},{"location":"Support/","title":"How to get Help","text":"
  • Browse through the navigation on the left
  • Search in the upper right
  • Check the frequently asked questions
"},{"location":"Support/#additional-support","title":"Additional Support","text":"

We have a few methods for you to get in touch to ask for help.

  • Community Forum
  • Ask for Help
  • Feature Requests

  • Discord Active chat and discussion

  • Bug Reports

"},{"location":"Support/1-Minute-Polling/","title":"1-Minute Polling","text":"

We now have support for polling data at intervals to fit your needs.

Please be aware of the following:

  • If you just want faster up/down alerts, Fast Ping is a much easier path to that goal.
  • You must also change your cron entry for poller-wrapper.py for this to work (if you change from the default 300 seconds).
  • Your polling MUST complete in the time you configure for the heartbeat step value. See /poller in your WebUI for your current value.
  • This will only affect RRD files created from the moment you change your settings.
  • This change will affect all data storage mechanisms such as MySQL, RRD and InfluxDB. If you decrease the values then please be aware of the increase in space use for MySQL and InfluxDB.
  • It's highly recommended to configure some performance optimizations. Keep in mind that all your devices will write all graphs every minute to the disk and that every device has many graphs. The most important thing is probably the RRDCached configuration that can save a lot of write IOPS.

To make the changes, please navigate to /settings/poller/rrdtool/ within your WebUI. Select RRDTool Setup and then update the two values for step and heartbeat intervals:

  • Step is how often you want to insert data, so if you change to 1 minute polling then this should be 60.
  • Heartbeat is how long to wait for data before registering a null value, i.e 120 seconds.
"},{"location":"Support/1-Minute-Polling/#converting-existing-rrd-files","title":"Converting existing RRD files","text":"

We provide a basic script to convert the default rrd files we generate to utilise your configured step and heartbeat values. Please do ensure that you backup your RRD files before running this just in case. The script runs on a per device basis or all devices at once.

The rrd files must be accessible from the server you run this script from.

./scripts/rrdstep.php

This will provide the help information. To run it for localhost just run:

./scripts/rrdstep.php -h localhost

"},{"location":"Support/Adding-a-Device/","title":"Adding Device","text":"

You have two options for adding a new device into LibreNMS. You can add a device via the cli or by using the WebUI.

"},{"location":"Support/Adding-a-Device/#via-webui","title":"Via WebUI","text":"

Using the web interface, go to Devices and click Add Device. Enter the details required for the device that you want to add and then click 'Add Host'. As an example, if your device is configured to use the community my_company using snmp v2c then you would enter: SNMP Port defaults to 161.

By default Hostname will be used for polling data. If you want to get polling Device data via a specific IP-Address (e.g. Management IP) fill out the optional field Overwrite IP with it's IP-Address.

"},{"location":"Support/Adding-a-Device/#via-cli","title":"Via CLI","text":"

Using the command line via ssh you can add a new device by changing to the directory of your LibreNMS install and typing (be sure to put the correct details).

./lnms device:add yourhostname [--v1|--v2c] [-c yourSNMPcommunity]\n

You can use ./lnms device:add --help for a list of available options and defaults.

As an example, if your device with the name mydevice.example.com is configured to use the community my_company using snmp v2c then you would enter:

./lnms device:add --v2c -c my_company mydevice.example.com\n

Please note that if the community contains special characters such as $ then you will need to wrap it in '. I.e: 'Pa$$w0rd'.

"},{"location":"Support/Adding-a-Device/#ping-only-device","title":"Ping Only Device","text":"

You can add ping only devices into LibreNMS through the WebUI or CLI. When adding the device switch the SNMP button to \"off\". Device will be added into LibreNMS as Ping Only Device and will show ICMP Response Graph.

  • Hostname: IP address or DNS name.
  • Hardware: Optional you can type in whatever you like.
  • OS: Optional this will add the Device's OS Icon.

Via CLI this is done with ./lnms device:add [-P|--ping-only] yourhostname

A How-to video can be found here: How to add ping only devices

"},{"location":"Support/Adding-a-Device/#automatic-discovery-and-api","title":"Automatic Discovery and API","text":"

If you would like to add devices automatically then you will probably want to read the Auto-discovery Setup guide.

You may also want to add devices programmatically, if so, take a look at our API documentation

"},{"location":"Support/Bare-Dashboard/","title":"Bare Dashboard","text":"

Settings to assist with wall/monitor displays.

"},{"location":"Support/Bare-Dashboard/#hide-menubar","title":"Hide Menubar","text":"

To hide Menubar e.g. for Monitoring TV Screens attach ?bare=yes on URL

"},{"location":"Support/Bare-Dashboard/#no-search-fields-in-dashboard-widgets","title":"No Search Fields in Dashboard Widgets","text":"

To hide Search Field in Dashboard Widgets take a look into Widget Settings.

"},{"location":"Support/CLI-Tools/","title":"Command line tools","text":"

Here's a brief list of command line tools, some might be missing. If you think something is missing, feel free to ask us or send a pull request :-)

"},{"location":"Support/CLI-Tools/#purge-portsphp","title":"purge-ports.php","text":"

This script provides CLI access to the \"delete port\" function of the WebUI. This might come in handy when trying to clean up old ports after large changes within the network or when hacking on the poller/discovery functions.

LibreNMS Port purge tool\n-p port_id  Purge single port by it's port-id\n-f file     Purge a list of ports, read port-ids from _file_, one on each line\n            A filename of - means reading from STDIN.\n
"},{"location":"Support/CLI-Tools/#querying-port-ids-from-the-database","title":"Querying port IDs from the database","text":"

One simple way to obtain port IDs is by querying the SQL database.

If you wanted to query all deleted ports from the database, you could to this with the following query:

echo 'SELECT port_id, hostname, ifDescr FROM ports, devices WHERE devices.device_id = ports.device_id AND deleted = 1' | mysql -h your_DB_server -u your_DB_user -p --skip-column-names your_DB_name\n

When you are sure that the list of ports is correct and you want to delete all of them, you can write the list into a file and call purge-ports.php with that file as input:

echo 'SELECT port_id FROM ports, devices WHERE devices.device_id = ports.device_id AND deleted = 1' | mysql -h your_DB_server -u your_DB_user -p --skip-column-names your_DB_name > ports_to_delete\n./purge-port.php -f ports_to_delete\n
"},{"location":"Support/Cleanup-options/","title":"Cleanup Options","text":"

As the number of devices starts to grow in your LibreNMS install, so will things such as the RRD files, MySQL database containing eventlogs, Syslogs and performance data etc. Your LibreNMS install could become quite large so it becomes necessary to clean up those entries. With Cleanup Options, you can stay in control.

These options rely on daily.sh running from cron as per the installation instructions.

system/cleanup

lnms config:set eventlog_purge 30\nlnms config:set syslog_purge 30\nlnms config:set route_purge 10\nlnms config:set alert_log_purge 365\nlnms config:set authlog_purge 30\nlnms config:set ports_fdb_purge 10\nlnms config:set ports_nac_purge 10\nlnms config:set rrd_purge 0\nlnms config:set ports_purge true\n

These options will ensure data within LibreNMS over X days old is automatically purged. You can alter these individually, values are in days.

NOTE: Please be aware that rrd_purge is NOT set by default. This option will remove any RRD files that have not been updated for the set amount of days automatically - only enable this if you are comfortable with that happening. (All active RRD files are updated every polling period.)

"},{"location":"Support/Cleanup-options/#ports-purge","title":"Ports Purge","text":"

Over time as you add devices some interfaces will need to be purged as they are set to be ignored or bad interfaces or marked as deleted.

You can purge all deleted ports from the WebUI (see below) or by setting lnms config:set ports_purge true.

In the Web UI Under the Ports Tab in the Nav Bar, Click on \"Deleted\" then click on \"Purge all deleted\". This will purge all the ports.

"},{"location":"Support/Configuration/","title":"Configuration Docs","text":"

LibreNMS configuration is a set of key values.

The config is stored in two places: Database: This applies to all pollers and can be set with either lnms config:set or in the Web UI. Database config takes precedence over config.php. config.php: This applies to the local poller only. Configs set here will be disabled in the Web UI to prevent unexpected behaviour.

The LibreNMS uses dot notation for config items:

Database config.php snmp.community $config['snmp']['community'] snmp.community.+ $config['snmp']['community'][] snmp.v3.0.authalgo $config['snmp']['v3'][0]['authalgo']

The documentation has not been updated to reflect using lnms config:set to set config items, but it will work for all settings. Not all settings have been defined in LibreNMS, but they can still be set with the --ignore-checks option. Without that option input is checked for correctness, that does not mean it is not possible to set bad values. Please report missing settings.

"},{"location":"Support/Configuration/#cli","title":"CLI","text":"

lnms config:get will fetch the current config settings (composite of database, config.php, and defaults). lnms config:set will set the config setting in the database. Calling lnms config:set on a setting with no value will reset it to the default value.

If you set up bash completion, you can use tab completion to find config settings.

"},{"location":"Support/Configuration/#getting-a-list-of-all-current-values","title":"Getting a list of all current values","text":"

To get a complete list of all the current values, you can use the command lnms config:get --dump. The output may not be desirable, so you can use the jq package to pretty print it. Then it would be lnms config:get --dump | jq.

Example output:

librenms@librenms:~$ lnms config:get --dump | jq \n{\n  \"install_dir\": \"/opt/librenms\",\n  \"active_directory\": {\n    \"users_purge\": 0\n  },\n  \"addhost_alwayscheckip\": false,\n  \"alert\": {\n    \"ack_until_clear\": false,\n    \"admins\": true,\n    \"default_copy\": true,\n    \"default_if_none\": false,\n    \"default_mail\": false,\n    \"default_only\": true,\n    \"disable\": false,\n    \"fixed-contacts\": true,\n    \"globals\": true,\n    \"syscontact\": true,\n    \"transports\": {\n      \"mail\": 5\n    },\n    \"tolerance_window\": 5,\n    \"users\": false,\n    ...\n

"},{"location":"Support/Configuration/#examples","title":"Examples","text":"
lnms config:get snmp.community\n  [\n      \"public\"\n  ]\n\n\nlnms config:set snmp.community.+ testing\n\nlnms config:get snmp.community\n  [\n      \"public\",\n      \"testing\"\n  ]\n\n\nlnms config:set snmp.community.0 private\n\nlnms config:get snmp.community\n  [\n      \"private\",\n      \"testing\"\n  ]\n\nlnms config:set snmp.community test\n  Invalid format\n\nlnms config:set snmp.community '[\"test\", \"othercommunity\"]'\n\nlnms config:get snmp.community\n  [\n      \"test\",\n      \"othercommunity\"\n  ]\n\nlnms config:set snmp.community\n\n  Reset snmp.community to the default? (yes/no) [no]:\n  > yes\n\n\nlnms config:get snmp.community\n  [\n      \"public\"\n  ]\n
"},{"location":"Support/Configuration/#pre-load-configuration","title":"Pre-load configuration","text":"

This feature is primarily for docker images and other automation. When installing LibreNMS for the first time with a new database you can place yaml key value files in database/seeders/config to pre-populate the config database.

Example snmp.yaml

snmp.community:\n    - public\n    - private\nsnmp.max_repeaters: 30\n

"},{"location":"Support/Configuration/#directories","title":"Directories","text":"
lnms config:set temp_dir /tmp\n

The temporary directory is where images and other temporary files are created on your filesystem.

lnms config:set log_dir /opt/librenms/logs\n

Log files created by LibreNMS will be stored within this directory.

"},{"location":"Support/Configuration/#database-config","title":"Database config","text":"

Set these variables either in .env (/opt/librenms/.env by default) or in the environment.

DB_HOST=127.0.0.1\nDB_DATABASE=librenms\nDB_USERNAME=DBUSER\nDB_PASSWORD=\"DBPASS\"\n

Use non-standard port:

DB_PORT=3306\n

Use a unix socket:

DB_SOCKET=/run/mysqld/mysqld.sock\n
"},{"location":"Support/Configuration/#core","title":"Core","text":""},{"location":"Support/Configuration/#php-settings","title":"PHP Settings","text":"

You can change the memory limits for php within config.php. The value is in Megabytes and should just be an int value:

lnms config:set php_memory_limit 128

"},{"location":"Support/Configuration/#programs","title":"Programs","text":"

A lot of these are self explanatory so no further information may be provided. Any extensions that have dedicated documentation page will be linked to rather than having the config provided.

"},{"location":"Support/Configuration/#rrdtool","title":"RRDTool","text":"

You can configure these options within the WebUI now, please avoid setting these options within config.php

Settings -> External Settings -> RRDTool Setup

external/binaries

lnms config:set rrdtool /usr/bin/rrdtool\n

Please see 1 Minute polling for information on configuring your install to record data more frequently.

"},{"location":"Support/Configuration/#fping","title":"fping","text":"

external/binaries

lnms config:set fping /usr/bin/fping\nlnms config:set fping6 fping6\n

poller/ping

lnms config:set fping_options.timeout 500\nlnms config:set fping_options.count 3\nlnms config:set fping_options.interval 500\nlnms config:set fping_options.tos 184\n

fping configuration options:

  • timeout (fping parameter -t): Amount of time that fping waits for a response to its first request (in milliseconds). See note below
  • count (fping parameter -c): Number of request packets to send to each target.
  • interval (fping parameter -p): Time in milliseconds that fping waits between successive packets to an individual target.
  • tos (fpingparameter -O): Set the type of service flag (TOS). Value can be either decimal or hexadecimal (0xh) format. Can be used to ensure that ping packets are queued in following QOS mecanisms in the network. Table is accessible in the TOS Wikipedia page.

NOTE: Setting a higher timeout value than the interval value can lead to slowing down poller. Example:

timeout: 3000

count: 3

interval: 500

In this example, interval will be overwritten by the timeout value of 3000 which is 3 seconds. As we send three icmp packets (count: 3), each one is delayed by 3 seconds which will result in fping taking > 6 seconds to return results.

You can disable the fping / icmp check that is done for a device to be determined to be up on a global or per device basis. We don't advise disabling the fping / icmp check unless you know the impact, at worst if you have a large number of devices down then it's possible that the poller would no longer complete in 5 minutes due to waiting for snmp to timeout.

Globally disable fping / icmp check:

lnms config:set icmp_check false\n

If you would like to do this on a per device basis then you can do so under Device -> Edit -> Misc -> Disable ICMP Test? On

"},{"location":"Support/Configuration/#snmp","title":"SNMP","text":"

SNMP program locations.

external/binaries

lnms config:set snmpwalk /usr/bin/snmpwalk\nlnms config:set snmpget /usr/bin/snmpget\nlnms config:set snmpbulkwalk /usr/bin/snmpbulkwalk\nlnms config:set snmpgetnext /usr/bin/snmpgetnext\nlnms config:set snmptranslate /usr/bin/snmptranslate\n
"},{"location":"Support/Configuration/#misc-binaries","title":"Misc binaries","text":"

external/binaries

lnms config:set whois /usr/bin/whois\nlnms config:set ping /bin/ping\nlnms config:set mtr /usr/bin/mtr\nlnms config:set nmap /usr/bin/nmap\nlnms config:set nagios_plugins /usr/lib/nagios/plugins\nlnms config:set ipmitool /usr/bin/ipmitool\nlnms config:set virsh /usr/bin/virsh\nlnms config:set dot /usr/bin/dot\nlnms config:set sfdp /usr/bin/sfdp\n
"},{"location":"Support/Configuration/#authentication","title":"Authentication","text":"

Generic Authentication settings.

Password minimum length for auth that allows user creation

lnms config:set password.min_length 8\n
"},{"location":"Support/Configuration/#proxy-support","title":"Proxy support","text":"

For alerting and the callback functionality, we support the use of a http proxy setting. These can be any one of the following:

system/proxy

lnms config:set callback_proxy proxy.domain.com\nlnms config:set http_proxy proxy.domain.com\n

We can also make use of one of these environment variables which can be set in /etc/environment:

http_proxy=proxy.domain.com\nhttps_proxy=proxy.domain.com\n
"},{"location":"Support/Configuration/#rrdcached","title":"RRDCached","text":"

Please refer to RRDCached

"},{"location":"Support/Configuration/#webui-settings","title":"WebUI Settings","text":"
lnms config:set base_url http://demo.librenms.org\n

LibreNMS will attempt to detect the URL you are using but you can override that here.

webui/style

lnms config:set site_style light\n

Currently we have a number of styles which can be set which will alter the navigation bar look. dark, light and mono with light being the default.

lnms config:set webui.custom_css.+ css/custom/styles.css\n

You can override a large number of visual elements by creating your own css stylesheet and referencing it here, place any custom css files into html/css/custom so they will be ignored by auto updates. You can specify as many css files as you like, the order they are within your config will be the order they are loaded in the browser.

webui/style

lnms config:set title_image images/custom/yourlogo.png\n

You can override the default logo with yours, place any custom images files into html/images/custom so they will be ignored by auto updates.

lnms config:set page_refresh 300\n

Set how often pages are refreshed in seconds. The default is every 5 minutes. Some pages don't refresh at all by design.

lnms config:set front_page default\n

You can create your own front page by adding a blade file in resources/views/overview/custom/ and setting front_page to it's name. For example, if you create resources/views/overview/custom/foobar.blade.php, set front_page to foobar.

webui/dashboard

lnms config:set webui.default_dashboard_id 0\n

Allows the specification of a global default dashboard page for any user who has not set one in their user preferences. Should be set to dashboard_id of an existing dashboard that is shared or shared(read). Otherwise, the system will automatically create each user an empty dashboard called Default on their first login.

lnms config:set login_message \"Unauthorised access or use shall render the user liable to criminal and/or civil prosecution.\"\n

This is the default message on the login page displayed to users.

lnms config:set public_status true\n

If this is set to true then an overview will be shown on the login page of devices and the status.

lnms config:set show_locations true  # Enable Locations on menu\nlnms config:set show_locations_dropdown true  # Enable Locations dropdown on menu\nlnms config:set show_services false  # Disable Services on menu\nlnms config:set int_customers true  # Enable Customer Port Parsing\nlnms config:set summary_errors false  # Show Errored ports in summary boxes on the dashboard\nlnms config:set customers_descr '[\"cust\"]'  # The description to look for in ifDescr. Can have multiple '[\"cust\",\"cid\"]'\nlnms config:set transit_descr '[\"transit\"]'  # Add custom transit descriptions (array)\nlnms config:set peering_descr '[\"peering\"]'  # Add custom peering descriptions (array)\nlnms config:set core_descr '[\"core\"]'  # Add custom core descriptions  (array)\nlnms config:set custom_descr '[\"This is Custom\"]'  # Add custom interface descriptions (array)\nlnms config:set int_transit true  # Enable Transit Types\nlnms config:set int_peering true  # Enable Peering Types\nlnms config:set int_core true  # Enable Core Port Types\nlnms config:set int_l2tp false  # Disable L2TP Port Types\n

Enable / disable certain menus from being shown in the WebUI.

You are able to adjust the number and time frames of the quick select time options for graphs and the mini graphs shown per row.

Quick select:

lnms config:set graphs.mini.normal '{\n    \"day\": \"24 Hours\",\n    \"week\": \"One Week\",\n    \"month\": \"One Month\",\n    \"year\": \"One Year\"\n}'\n\nlnms config:set graphs.mini.widescreen '{\n    \"sixhour\": \"6 Hours\",\n    \"day\": \"24 Hours\",\n    \"twoday\": \"48 Hours\",\n    \"week\": \"One Week\",\n    \"twoweek\": \"Two Weeks\",\n    \"month\": \"One Month\",\n    \"twomonth\": \"Two Months\",\n    \"year\": \"One Year\",\n    \"twoyear\": \"Two Years\"\n}'\n

Mini graphs:

lnms config:set graphs.row.normal '{\n    \"sixhour\": \"6 Hours\",\n    \"day\": \"24 Hours\",\n    \"twoday\": \"48 Hours\",\n    \"week\": \"One Week\",\n    \"twoweek\": \"Two Weeks\",\n    \"month\": \"One Month\",\n    \"twomonth\": \"Two Months\",\n    \"year\": \"One Year\",\n    \"twoyear\": \"Two Years\"\n}'\n
lnms config:set web_mouseover true\n

You can disable the mouseover popover for mini graphs by setting this to false.

lnms config:set enable_lazy_load true\n

You can disable image lazy loading by setting this to false.

lnms config:set overview_show_sysDescr true\n

Enable or disable the sysDescr output for a device.

webui/device

lnms config:set device_display_default '{{ $hostname }}'\n

This is a simple template to control the display of device names by default. You can override this setting per-device.

You may enter any free-form text including one or more of the following template replacements:

Template Replacement {{ $hostname }} The hostname or IP of the device that was set when added *default {{ $sysName_fallback }} The hostname or sysName if hostname is an IP {{ $sysName }} The SNMP sysName of the device, falls back to hostname/IP if missing {{ $ip }} The actual polled IP of the device, will not display a hostname

For example, {{ $sysName_fallback }} ({{ $ip }}) will display something like server (192.168.1.1)

lnms config:set device_traffic_iftype.+ '/loopback/'\n

Interface types that aren't graphed in the WebUI. The default array contains more items, please see misc/config_definitions.json for the full list.

lnms config:set enable_clear_discovery true\n

Administrators are able to clear the last discovered time of a device which will force a full discovery run within the configured 5 minute cron window.

lnms config:set enable_footer true\n

Disable the footer of the WebUI by setting enable_footer to 0.

You can enable the old style network map (only available for individual devices with links discovered via xDP) by setting:

lnms config:set gui.network-map.style old\n
lnms config:set percentile_value 90\n

Show the Xth percentile in the graph instead of the default 95th percentile.

webui/graph

lnms config:set shorthost_target_length 15\n

The target maximum hostname length when applying the shorthost() function. You can increase this if you want to try and fit more of the hostname in graph titles. The default value is 12 However, this can possibly break graph generation if this is very long.

You can enable dynamic graphs within the WebUI under Global Settings -> Webui Settings -> Graph Settings.

Graphs will be movable/scalable without reloading the page:

"},{"location":"Support/Configuration/#stacked-graphs","title":"Stacked Graphs","text":"

You can enable stacked graphs instead of the default inverted graphs. Enabling them is possible via webui Global Settings -> Webui Settings -> Graph settings -> Use stacked graphs

"},{"location":"Support/Configuration/#add-host-settings","title":"Add host settings","text":"

The following setting controls how hosts are added. If a host is added as an ip address it is checked to ensure the ip is not already present. If the ip is present the host is not added. If host is added by hostname this check is not performed. If the setting is true hostnames are resolved and the check is also performed. This helps prevents accidental duplicate hosts.

lnms config:set addhost_alwayscheckip false # true - check for duplicate ips even when adding host by name.\n                                            # false- only check when adding host by ip.\n

By default we allow hosts to be added with duplicate sysName's, you can disable this with the following config:

discovery/general

lnms config:set allow_duplicate_sysName false\n
"},{"location":"Support/Configuration/#global-poller-and-discovery-modules","title":"Global poller and discovery modules","text":"

Enable or disable discovery or poller modules.

This setting has an order of precedence Device > OS > Global. So if the module is set at a more specific level, it will override the less specific settings.

Global:

lnms config:set discovery_modules.arp-table false\n\nlnms config:set discovery_modules.entity-state true\nlnms config:set poller_modules.entity-state true\n

Per OS:

lnms config:set os.ios.discovery_modules.arp-table false\n\nlnms config:set os.ios.discovery_modules.entity-state true\nlnms config:set os.ios.poller_modules.entity-state true\n
"},{"location":"Support/Configuration/#snmp-settings","title":"SNMP Settings","text":"

Default SNMP options including retry and timeout settings and also default version and port.

poller/snmp

lnms config:set snmp.timeout 1                         # timeout in seconds\nlnms config:set snmp.retries 5                         # how many times to retry the query\nlnms config:set snmp.transports '[\"udp\", \"udp6\", \"tcp\", \"tcp6\"]'    # Transports to use\nlnms config:set snmp.version '[\"v2c\", \"v3\", \"v1\"]'       # Default versions to use\nlnms config:set snmp.port 161                          # Default port\nlnms config:set snmp.exec_timeout 1200                 # execution time limit in seconds\n

NOTE: timeout is the time to wait for an answer and exec_timeout is the max time to run a query.

The default v1/v2c snmp community to use, you can expand this array with [1], [2], [3], etc.

poller/snmp

lnms config:set snmp.community.0 public\n

NOTE: This list of SNMP communities is used for auto discovery, and as a default set for any manually added device.

The default v3 snmp details to use, you can expand this array with [1], [2], [3], etc.

poller/snmp

lnms config:set snmp.v3.0 '{\n    authlevel: \"noAuthNoPriv\",\n    authname: \"root\",\n    authpass: \"\",\n    authalgo: \"MD5\",\n    cryptopass: \"\",\n    cryptoalgo: \"AES\"\n}'\n
authlevel   noAuthNoPriv | authNoPriv | authPriv\nauthname    User Name (required even for noAuthNoPriv)\nauthpass    Auth Passphrase\nauthalgo    MD5 | SHA | SHA-224 | SHA-256 | SHA-384 | SHA-512\ncryptopass  Privacy (Encryption) Passphrase\ncryptoalgo  AES | AES-192 | AES-256 | AES-256-C | DES\n
"},{"location":"Support/Configuration/#auto-discovery-settings","title":"Auto discovery settings","text":"

Please refer to Auto-Discovery

"},{"location":"Support/Configuration/#email-configuration","title":"Email configuration","text":"

You can configure these options within the WebUI now, please avoid setting these options within config.php

alerting/email

lnms config:set email_backend mail\nlnms config:set email_from librenms@yourdomain.local\nlnms config:set email_user `lnms config:get project_id`\nlnms config:set email_sendmail_path /usr/sbin/sendmail\nlnms config:set email_smtp_host localhost\nlnms config:set email_smtp_port 25\nlnms config:set email_smtp_timeout 10\nlnms config:set email_smtp_secure tls\nlnms config:set email_smtp_auth false\nlnms config:set email_smtp_username NULL\nlnms config:set email_smtp_password NULL\n

What type of mail transport to use for delivering emails. Valid options for email_backend are mail, sendmail or smtp. The varying options after that are to support the different transports.

"},{"location":"Support/Configuration/#alerting","title":"Alerting","text":"

Please refer to Alerting

"},{"location":"Support/Configuration/#billing","title":"Billing","text":"

Please refer to Billing

"},{"location":"Support/Configuration/#global-module-support","title":"Global module support","text":"
lnms config:set enable_syslog false # Enable Syslog\nlnms config:set enable_inventory true # Enable Inventory\nlnms config:set enable_pseudowires true # Enable Pseudowires\nlnms config:set enable_vrfs true # Enable VRFs\n
"},{"location":"Support/Configuration/#port-extensions","title":"Port extensions","text":"

Please refer to Port-Description-Parser

lnms config:set enable_ports_etherlike false\nlnms config:set enable_ports_junoseatmvp false\nlnms config:set enable_ports_poe false\n

Enable / disable additional port statistics.

"},{"location":"Support/Configuration/#port-group","title":"Port Group","text":"

Assign a new discovered Port automatically to Port Group with this Port Group ID (0 means no Port Group assignment)

discovery/networks

lnms config:set default_port_group 0\n
"},{"location":"Support/Configuration/#external-integration","title":"External integration","text":""},{"location":"Support/Configuration/#rancid","title":"Rancid","text":"
lnms config:set rancid_configs.+ /var/lib/rancid/network/configs/\nlnms config:set rancid_repo_type svn\nlnms config:set rancid_ignorecomments false\n

Rancid configuration, rancid_configs is an array containing all of the locations of your rancid files. Setting rancid_ignorecomments will disable showing lines that start with #

"},{"location":"Support/Configuration/#oxidized","title":"Oxidized","text":"

Please refer to Oxidized

"},{"location":"Support/Configuration/#collectd","title":"CollectD","text":"
lnms config:set collectd_dir /var/lib/collectd/rrd\n

Specify the location of the collectd rrd files. Note that the location in config.php should be consistent with the location set in /etc/collectd.conf and etc/collectd.d/rrdtool.conf

<Plugin rrdtool>\n        DataDir \"/var/lib/collectd/rrd\"\n        CreateFilesAsync false\n        CacheTimeout 120\n        CacheFlush   900\n        WritesPerSecond 50\n</Plugin>\n

/etc/collectd.conf

LoadPlugin rrdtool\n<Plugin rrdtool>\n       DataDir \"/var/lib/collectd/rrd\"\n       CacheTimeout 120\n       CacheFlush   900\n</Plugin>\n

/etc/collectd.d/rrdtool.conf

lnms config:set collectd_sock unix:///var/run/collectd.sock\n

Specify the location of the collectd unix socket. Using a socket allows the collectd graphs to be flushed to disk before being drawn. Be sure that your web server has permissions to write to this socket.

"},{"location":"Support/Configuration/#smokeping","title":"Smokeping","text":"

Please refer to Smokeping

"},{"location":"Support/Configuration/#nfsen","title":"NFSen","text":"

Please refer to NFSen

"},{"location":"Support/Configuration/#location-parsing","title":"Location parsing","text":"

LibreNMS can interpret sysLocation information and map the device loction based on GeoCoordinates or GeoCoding information.

  • Info-keywords
  • [] contains optional Latitude and Longitude information if manual GeoCoordinate positioning is desired.
  • () contains optional information that is ignored during GeoCoding lookups.
"},{"location":"Support/Configuration/#geocoordinates","title":"GeoCoordinates","text":"

If device sysLocation information contains [lat, lng] (note the comma and square brackets), that is used to determin the GeoCoordinates.

Example:

name_that_can_not_be_looked_up [40.424521, -86.912755]\n

"},{"location":"Support/Configuration/#geocoding","title":"GeoCoding","text":"

Next it will attempt to look up the sysLocation with a map engine provided you have configured one under $config['geoloc']['engine']. The information has to be accurate or no result is returned, when it does it will ignore any information inside parentheses, allowing you to add details that would otherwise interfeeer with the lookup.

Example:

1100 Congress Ave, Austin, TX 78701 (3rd floor)\nGeocoding lookup is:\n1100 Congress Ave, Austin, TX 78701\n

"},{"location":"Support/Configuration/#overrides","title":"Overrides","text":"
  1. You can overwrite each device sysLocation information in the webGUI under \"Device settings\".
  2. You can overwrite the location coordinates n in the webGUI under Device>GEO Locations
"},{"location":"Support/Configuration/#location-mapping","title":"Location mapping","text":"

If you just want to set GPS coordinates on a location, you should visit Devices > Geo Locations > All Locations and edit the coordinates there.

Exact Matching:

lnms config:set location_map '{\"Under the Sink\": \"Under The Sink, The Office, London, UK\"}'\n

Regex Matching:

lnms config:set location_map_regex '{\"/Sink/\": \"Under The Sink, The Office, London, UK\"}'\n

Regex Match Substitution:

lnms config:set location_map_regex_sub '{\"/Sink/\": \"Under The Sink, The Office, London, UK [lat, long]\"}'\n

If you have an SNMP SysLocation of \"Rack10,Rm-314,Sink\", Regex Match Substition yields \"Rack10,Rm-314,Under The Sink, The Office, London, UK [lat, long]\". This allows you to keep the SysLocation string short and keeps Rack/Room/Building information intact after the substitution.

The above are examples, these will rewrite device snmp locations so you don't need to configure full location within snmp.

"},{"location":"Support/Configuration/#interfaces-to-be-ignored","title":"Interfaces to be ignored","text":"

Interfaces can be automatically ignored during discovery by modifying bad_if* entries in a default array, unsetting a default array and customizing it, or creating an OS specific array. The preferred method for ignoring interfaces is to use an OS specific array. The default arrays can be found in misc/config_definitions.json. OS specific definitions (includes/definitions/_specific_os_.yaml) can contain bad_if* arrays, but should only be modified via pull-request as manipulation of the definition files will block updating:

Examples:

Add entries to default arrays

lnms config:set bad_if.+ voip-null\nlnms config:set bad_iftype.+ voiceEncap\nlnms config:set bad_if_regexp.+ '/^lo[0-9].*/'    # loopback\n

Override default bad_if values

lnms config:set bad_if '[\"voip-null\", \"voiceEncap\", \"voiceFXO\"]'\n

Create an OS specific array

lnms config:set os.iosxe.bad_iftype.+ macSecControlledIF\nlnms config:set os.iosxe.bad_iftype.+ macSecUncontrolledIF\n

Various bad_if* selection options available

bad_if is matched against the ifDescr value.

bad_iftype is matched against the ifType value.

bad_if_regexp is matched against the ifDescr value as a regular expression.

bad_ifname_regexp is matched against the ifName value as a regular expression.

bad_ifalias_regexp is matched against the ifAlias value as a regular expression.

"},{"location":"Support/Configuration/#interfaces-that-shouldnt-be-ignored","title":"Interfaces that shouldn't be ignored","text":"

Examples:

lnms config:set good_if.+ FastEthernet\nlnms config:set os.ios.good_if.+ FastEthernet\n

good_if is matched against ifDescr value. This can be a bad_if value as well which would stop that port from being ignored. i.e. if bad_if and good_if both contained FastEthernet then ports with this value in the ifDescr will be valid.

"},{"location":"Support/Configuration/#interfaces-to-be-rewritten","title":"Interfaces to be rewritten","text":"
lnms config:set rewrite_if '{\"cpu\": \"Management Interface\"}'\nlnms config:set rewrite_if_regexp '{\"/cpu /\": \"Management \"}'\n

Entries defined in rewrite_if are being replaced completely. Entries defined in rewrite_if_regexp only replace the match. Matches are compared case-insensitive.

"},{"location":"Support/Configuration/#entity-sensors-to-be-ignored","title":"Entity sensors to be ignored","text":"

Some devices register bogus sensors as they are returned via SNMP but either don't exist or just don't return data. This allows you to ignore those based on the descr field in the database. You can either ignore globally or on a per os basis.

lnms config:set bad_entity_sensor_regex.+ '/Physical id [0-9]+/'\nlnms config:set os.ios.bad_entity_sensor_regex '[\"/Physical id [0-9]+/\"]'\n
"},{"location":"Support/Configuration/#entity-sensors-limit-values","title":"Entity sensors limit values","text":"

Vendors may give some limit values (or thresholds) for the discovered sensors. By default, when no such value is given, both high and low limit values are guessed, based on the value measured during the initial discovery.

When it is preferred to have no high and/or low limit values at all if these are not provided by the vendor, the guess method can be disabled:

lnms config:set sensors.guess_limits false\n
"},{"location":"Support/Configuration/#ignoring-health-sensors","title":"Ignoring Health Sensors","text":"

It is possible to filter some sensors from the configuration:

  • Ignore all temperature sensors
lnms config:set disabled_sensors.current true\n
  • Filter all sensors matching regexp '/PEM Iout/'.
lnms config:set disabled_sensors_regex.+ '/PEM Iout/'\n
  • Filter all 'current' sensors for Operating System 'vrp'.
lnms config:set os.vrp.disabled_sensors.current true\n
  • Filter all sensors matching regexp '/PEM Iout/' for Operating System iosxe.
lnms config:set os.iosxe.disabled_sensors_regex '/PEM Iout/'\n
"},{"location":"Support/Configuration/#storage-configuration","title":"Storage configuration","text":"

Mounted storage / mount points to ignore in discovery and polling.

discovery/storage

lnms config:set ignore_mount_removable true\nlnms config:set ignore_mount_network true\nlnms config:set ignore_mount_optical true\n\nlnms config:set ignore_mount.+ /kern\nlnms config:set ignore_mount.+ /mnt/cdrom\nlnms config:set ignore_mount.+ /proc\nlnms config:set ignore_mount.+ /dev\n\nlnms config:set ignore_mount_string.+ packages\nlnms config:set ignore_mount_string.+ devfs\nlnms config:set ignore_mount_string.+ procfs\nlnms config:set ignore_mount_string.+ UMA\nlnms config:set ignore_mount_string.+ MALLOC\n\nlnms config:set ignore_mount_regexp.+ '/on: \\/packages/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/dev/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/proc/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/junos^/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/junos\\/dev/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/jail\\/dev/'\nlnms config:set ignore_mount_regexp.+ '/^(dev|proc)fs/'\nlnms config:set ignore_mount_regexp.+ '/^\\/dev\\/md0/'\nlnms config:set ignore_mount_regexp.+ '/^\\/var\\/dhcpd\\/dev,/'\nlnms config:set ignore_mount_regexp.+ '/UMA/'\n

Custom storage warning percentage

lnms config:set storage_perc_warn 60\n
"},{"location":"Support/Configuration/#irc-bot","title":"IRC Bot","text":"

Please refer to IRC Bot

"},{"location":"Support/Configuration/#authentication_1","title":"Authentication","text":"

Please refer to Authentication

"},{"location":"Support/Configuration/#cleanup-options","title":"Cleanup options","text":"

Please refer to Cleanup Options

"},{"location":"Support/Configuration/#syslog-options","title":"Syslog options","text":"

Please refer to Syslog

"},{"location":"Support/Configuration/#virtualization","title":"Virtualization","text":"
lnms config:set enable_libvirt true\nlnms config:set libvirt_protocols '[\"qemu+ssh\",\"xen+ssh\"]'\nlnms config:set libvirt_username root\n

Enable this to switch on support for libvirt along with libvirt_protocols to indicate how you connect to libvirt. You also need to:

  1. Generate a non-password-protected ssh key for use by LibreNMS, as the user which runs polling & discovery (usually librenms).
  2. On each VM host you wish to monitor:
  3. Configure public key authentication from your LibreNMS server/poller by adding the librenms public key to ~root/.ssh/authorized_keys.
  4. (xen+ssh only) Enable libvirtd to gather data from xend by setting (xend-unix-server yes) in /etc/xen/xend-config.sxp and restarting xend and libvirtd.

To test your setup, run virsh -c qemu+ssh://vmhost/system list or virsh -c xen+ssh://vmhost list as your librenms polling user.

"},{"location":"Support/Configuration/#bgp-support","title":"BGP Support","text":"
lnms config:set astext.65332 \"Cymru FullBogon Feed\"\n

You can use this array to rewrite the description of ASes that you have discovered.

"},{"location":"Support/Configuration/#auto-updates","title":"Auto updates","text":"

Please refer to Updating

"},{"location":"Support/Configuration/#ipmi","title":"IPMI","text":"

Setup the types of IPMI protocols to test a host for and in what order. Don't forget to install ipmitool on the monitoring host.

lnms config:set ipmi.type '[\"lanplus\", \"lan\", \"imb\", \"open\"]'\n
"},{"location":"Support/Configuration/#distributed-poller-settings","title":"Distributed poller settings","text":"

Please refer to Distributed Poller

"},{"location":"Support/Configuration/#api-settings","title":"API Settings","text":""},{"location":"Support/Configuration/#cors-support","title":"CORS Support","text":"

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

CORS support for the API is disabled by default. Below you will find the standard options, all of which you can configure.

lnms config:set api.cors.enabled false\nlnms config:set api.cors.origin '[\"*\"]'\nlnms config:set api.cors.maxage '86400'\nlnms config:set api.cors.allowmethods '[\"POST\", \"GET\", \"PUT\", \"DELETE\", \"PATCH\"]'\nlnms config:set api.cors.allowheaders '[\"Origin\", \"X-Requested-With\", \"Content-Type\", \"Accept\", \"X-Auth-Token\"]'\nlnms config:set api.cors.exposeheaders '[\"Cache-Control\", \"Content-Language\", \"Content-Type\", \"Expires\", \"Last-Modified\", \"Pragma\"]'\nlnms config:set api.cors.allowmethods '[\"POST\", \"GET\", \"PUT\", \"DELETE\", \"PATCH\"]'\nlnms config:set api.cors.allowheaders '[\"Origin\", \"X-Requested-With\", \"Content-Type\", \"Accept\", \"X-Auth-Token\"]'\nlnms config:set api.cors.exposeheaders '[\"Cache-Control\", \"Content-Language\", \"Content-Type\", \"Expires\", \"Last-Modified\", \"Pragma\"]'\nlnms config:set api.cors.allowcredentials false\n
"},{"location":"Support/Device-Sensors/","title":"Device Sensors","text":"

LibreNMS has a standard for device sensors they are split into categories. This doc is to help users understand device sensors in general, if you need help with developing sensors for a device please see the Contributing + Developing section.

"},{"location":"Support/Device-Sensors/#health-sensors","title":"Health Sensors","text":"

The High and Low values of these sensors can be edited in Web UI by going to the device settings -> Health. There you can set your own custom High and Low values. List of these sensors can be found here Link

Note Some values are defined by the manufactures and others are auto calculated when you add the device into librenms. Keep in mind every environment is different and may require user input.

"},{"location":"Support/Device-Sensors/#wireless-sensors","title":"Wireless Sensors","text":"

Some Wireless have High and Low values of these sensors can be edited in Web UI by going to the device settings -> Wireless Sensors There you can set your own custom High and Low values. List of these sensors can be found here Link

Note Some values are defined by the manufactures and others are auto calculated when you add the device into librenms. Keep in mind every environment is different and may require user input.

"},{"location":"Support/Device-Sensors/#state-sensors","title":"State Sensors","text":"

Return states of device entries sensors states. For example.

Drive Status, Memory Status, Power Supply Status.

0 = OK\n1 = Warning\n2 = Critical\n3 = Unknown\n
"},{"location":"Support/Device-Sensors/#alerting-sensors","title":"Alerting Sensors","text":"

These alert rules can be found inside the Alert Rules Collection. The alert rules below are the default alert rules, there are more device-specific alert rules in the alerts collection.

Sensor Over Limit Alert Rule: Will alert on any sensor value that is over the limit.

Sensor Under Limit Alert Rule: Will alert on any sensor value that is under the limit.

Remember you can set these limits inside device settings in the Web UI.

State Sensor Critical: Will alert on any state that returns critical = 2

State Sensor Warning: Will alert on any state that returns warning = 1

Wireless Sensor Over Limit Alert Rule: Will Alert on sensors that listed in device settings under Wireless.

Wireless Sensor Under Limit Alert Rule: Will Alert on sensors that listed in device settings under Wireless.

"},{"location":"Support/Device-Troubleshooting/","title":"Capture Debug Information","text":"

You can use this feature to run Debug on Discovery, Poller, SNMP, Alerts. This output information could be helpful for you in troubleshooting a device or when requesting help.

This feature can be found by going to the device that you are troubleshooting in the webui, clicking on the settings icon menu on far right and selecting Capture.

"},{"location":"Support/Device-Troubleshooting/#discovery","title":"Discovery","text":"

Discovery will run and output debug information.

"},{"location":"Support/Device-Troubleshooting/#poller","title":"Poller","text":"

Poller will run and output debug information.

"},{"location":"Support/Device-Troubleshooting/#snmp","title":"SNMP","text":"

SNMP will run SNMP Bulk Walk on the device and output the information.

"},{"location":"Support/Device-Troubleshooting/#alerts","title":"Alerts","text":"

Alerts Capture is handy when you are creating alerts and need to see if your alert rule matches.

"},{"location":"Support/Discovery%20Support/","title":"discovery.php","text":"

This document will explain how to use discovery.php to debug issues or manually running to process data.

"},{"location":"Support/Discovery%20Support/#command-options","title":"Command options","text":"
-h <device id> | <device hostname wildcard>  Poll single device\n-h odd                                       Poll odd numbered devices  (same as -i 2 -n 0)\n-h even                                      Poll even numbered devices (same as -i 2 -n 1)\n-h all                                       Poll all devices\n-h new                                       Poll all devices that have not had a discovery run before\n--os <os_name>                               Poll devices only with specified operating system\n--type <type>                                Poll devices only with specified type\n-i <instances> -n <number>                   Poll as instance <number> of <instances>\n                                             Instances start at 0. 0-3 for -n 4\n\nDebugging and testing options:\n-d                                           Enable debugging output\n-v                                           Enable verbose debugging output\n-m                                           Specify module(s) to be run. Comma separate modules, submodules may be added with /\n

-h Use this to specify a device via either id or hostname (including wildcard using *). You can also specify odd and even. all will run discovery against all devices whilst new will poll only those devices that have recently been added or have been selected for rediscovery.

-i This can be used to stagger the discovery process.

-d Enables debugging output (verbose output but with most sensitive data masked) so that you can see what is happening during a discovery run. This includes things like rrd updates, SQL queries and response from snmp.

-v Enables verbose debugging output with all data in tact.

-m This enables you to specify the module you want to run for discovery.

"},{"location":"Support/Discovery%20Support/#discovery-wrapper","title":"Discovery wrapper","text":"

We have a discovery-wrapper.py script which is based on poller-wrapper.py by Job Snijders. This script is currently the default.

If you need to debug the output of discovery-wrapper.py then you can add -d to the end of the command - it is NOT recommended to do this in cron.

You also may use -m to pass a list of comma-separated modules. Please refer to Command options of discovery.php. Example: /opt/librenms/discovery-wrapper.py 1 -m bgp-peers

If you want to switch back to discovery.php then you can replace:

33 */6 * * * librenms /opt/librenms/discovery-wrapper.py 1 >> /dev/null 2>&1

With:

33 */6 * * * librenms /opt/librenms/discovery.php -h all >> /dev/null 2>&1

"},{"location":"Support/Discovery%20Support/#discovery-config","title":"Discovery config","text":"

These are the default discovery config items. You can globally disable a module by setting it to 0. If you just want to disable it for one device then you can do this within the WebUI -> Device -> Settings -> Modules.

discovery/discovery_modules

lnms config:set discovery_modules.os true\nlnms config:set discovery_modules.ports true\nlnms config:set discovery_modules.ports-stack true\nlnms config:set discovery_modules.entity-physical true\nlnms config:set discovery_modules.entity-state false\nlnms config:set discovery_modules.processors true\nlnms config:set discovery_modules.mempools true\nlnms config:set discovery_modules.cisco-vrf-lite true\nlnms config:set discovery_modules.cisco-mac-accounting false\nlnms config:set discovery_modules.cisco-pw false\nlnms config:set discovery_modules.vrf false\nlnms config:set discovery_modules.cisco-cef false\nlnms config:set discovery_modules.slas false\nlnms config:set discovery_modules.cisco-cbqos false\nlnms config:set discovery_modules.cisco-otv false\nlnms config:set discovery_modules.ipv4-addresses true\nlnms config:set discovery_modules.ipv6-addresses true\nlnms config:set discovery_modules.route false\nlnms config:set discovery_modules.sensors true\nlnms config:set discovery_modules.storage true\nlnms config:set discovery_modules.hr-device true\nlnms config:set discovery_modules.discovery-protocols true\nlnms config:set discovery_modules.arp-table true\nlnms config:set discovery_modules.discovery-arp false\nlnms config:set discovery_modules.junose-atm-vp false\nlnms config:set discovery_modules.bgp-peers true\nlnms config:set discovery_modules.vlans true\nlnms config:set discovery_modules.vminfo false\nlnms config:set discovery_modules.printer-supplies false\nlnms config:set discovery_modules.ucd-diskio true\nlnms config:set discovery_modules.applications false\nlnms config:set discovery_modules.services true\nlnms config:set discovery_modules.stp true\nlnms config:set discovery_modules.ntp true\nlnms config:set discovery_modules.loadbalancers false\nlnms config:set discovery_modules.mef false\nlnms config:set discovery_modules.wireless true\nlnms config:set discovery_modules.fdb-table true\nlnms config:set discovery_modules.xdsl false\n
"},{"location":"Support/Discovery%20Support/#os-based-discovery-config","title":"OS based Discovery config","text":"

You can enable or disable modules for a specific OS by using lnms config:set OS based settings have preference over global. Device based settings have preference over all others

Discover performance improvement can be achieved by deactivating all modules that are not supported by specific OS.

E.g. to deactivate spanning tree but activate discovery-arp module for linux OS

discovery/discovery_modules

lnms config:set os.linux.discovery_modules.stp false\nlnms config:set os.linux.discovery_modules.discovery-arp true\n
"},{"location":"Support/Discovery%20Support/#discovery-modules","title":"Discovery modules","text":"

os: Os detection. This module will pick up the OS of the device.

ports: This module will detect all ports on a device excluding ones configured to be ignored by config options.

ports-stack: Same as ports except for stacks.

xdsl: Module to collect more metrics for xDSL interfaces.

entity-physical: Module to pick up the devices hardware support.

processors: Processor support for devices.

mempools: Memory detection support for devices.

cisco-vrf-lite: VRF-Lite detection and support.

ipv4-addresses: IPv4 Address detection

ipv6-addresses: IPv6 Address detection

route: This module will load the routing table of the device. The default route limit is 1000 (configurable with lnms config:set routes.max_number 1000), with history data.

sensors: Sensor detection such as Temperature, Humidity, Voltages + More

storage: Storage detection for hard disks

hr-device: Processor and Memory support via HOST-RESOURCES-MIB.

discovery-protocols: Auto discovery module for xDP, OSPF and BGP.

arp-table: Detection of the ARP table for the device.

fdb-table: Detection of the Forwarding DataBase table for the device, with history data.

discovery-arp: Auto discovery via ARP.

junose-atm-vp: Juniper ATM support.

bgp-peers: BGP detection and support.

vlans: VLAN detection and support.

cisco-mac-accounting: MAC Address account support.

cisco-pw: Pseudowires wires detection and support.

vrf: VRF detection and support.

cisco-cef: CEF detection and support.

slas: SLA detection and support.

vminfo: Detection of vm guests for VMware ESXi and libvert

printer-supplies: Toner levels support.

ucd-diskio: Disk I/O support.

services: *Nix services support.

charge: APC Charge detection and support.

"},{"location":"Support/Discovery%20Support/#running","title":"Running","text":"

Here are some examples of running discovery from within your install directory.

./discovery.php -h localhost\n\n./discovery.php -h localhost -m ports\n
"},{"location":"Support/Discovery%20Support/#debugging","title":"Debugging","text":"

To provide debugging output you will need to run the discovery process with the -d flag. You can do this either against all modules, single or multiple modules:

All Modules

./discovery.php -h localhost -d\n

Single Module

./discovery.php -h localhost -m ports -d\n

Multiple Modules

./discovery.php -h localhost -m ports,entity-physical -d\n

Using -d shouldn't output much sensitive information, -v will so it is then advisable to sanitise the output before pasting it somewhere as the debug output will contain snmp details amongst other items including port descriptions.

The output will contain:

DB Updates

SNMP Response

"},{"location":"Support/Environment-Variables/","title":"Environment Variables","text":"

LibreNMS allows certain settings to be set via the environment or through the .env file.

"},{"location":"Support/Environment-Variables/#database","title":"Database","text":"

Set the variables to connect to the database. The default values are shown below.

DB_HOST=localhost\nDB_PORT=3306\nDB_DATABASE=librenms\nDB_USERNAME=librenms\nDB_PASSWORD=\nDB_SOCKET=\n
"},{"location":"Support/Environment-Variables/#trusted-reverse-proxies","title":"Trusted Reverse Proxies","text":"

A comma separated list of trusted reverse proxy IPs or CIDR.

For legacy reasons the default is '*', which means any proxy is allowed. '**' means trust any proxy up the chain.

APP_TRUSTED_PROXIES=192.168.1.0/24,192.167.8.20\n
"},{"location":"Support/Environment-Variables/#base-url","title":"Base url","text":"

Set the base url for generated urls.

This will be needed when using signed graph urls for alerting. It may be needed when using reverse proxies combined with a subdirectory.

Generally, LibreNMS will make correct URLs (especially if you have set up your proxy variables correctly)

APP_URL=http://librenms/\n
"},{"location":"Support/Environment-Variables/#user-group","title":"User / Group","text":"

The user and group that LibreNMS should operate as. Group will default to the same as the user if unset.

LIBRENMS_USER=librenms\nLIBRENMS_GROUP=librenms\n
"},{"location":"Support/Environment-Variables/#debug","title":"Debug","text":"

Increases the amount of information shown when an error occurs.

WARNING: This may leak information, do not leave enabled.

APP_DEBUG=true\n
"},{"location":"Support/Example-Hardware-Setup/","title":"Example hardware setups","text":"

The information in this document is direct from users, it's a place for people to share their setups so you have an idea of what may be required for your install.

To obtain the device, port and sensor counts you can run:

select count(*) from devices;\nselect count(*) from ports where `deleted` = 0;\nselect count(*) from sensors where `sensor_deleted` = 0;\n
"},{"location":"Support/Example-Hardware-Setup/#laf","title":"laf","text":"

Home

Running in Proxmox.

LibreNMS MySQL Type Virtual Virtual OS CentOS 7 CentOS 7 CPU 2 Sockets, 4 Cores 1 Socket, 2 Cores Memory 2GB 2GB Disk Type Raid 1, SSD Raid 1, SSD Disk Space 18GB 30GB Devices 20 - Ports 133 - Health sensors 47 - Load < 0.1 < 0.1"},{"location":"Support/Example-Hardware-Setup/#vente-privee","title":"Vente-Priv\u00e9e","text":"

NOC

LibreNMS MariaDB Type Dell R430 Dell R430 OS Debian 7 (dotdeb) Debian 7 (dotdeb) CPU 2 Sockets, 14 Cores 1 Socket, 2 Cores Memory 256GB 256GB Disk Type Raid 10, SSD Raid 10, SSD Disk Space 1TB 1TB Devices 1028 - Ports 26745 - Health sensors 6238 - Load < 0.5 < 0.5"},{"location":"Support/Example-Hardware-Setup/#kkrumm","title":"KKrumm","text":"

Home

LibreNMS MySQL Type VM Same Server OS CentOS 7 CPU 2 Sockets, 4 Cores Memory 4GB Disk Type Raid 10, SAS Drives Disk Space 40 GB Devices 12 Ports 130 Health sensors 44 Load < 2.5"},{"location":"Support/Example-Hardware-Setup/#kkrumm_1","title":"KKrumm","text":"

Work

LibreNMS MySQL Type HP Proliantdl380gen8 Same Server OS CentOS 7 CPU 2 Sockets, 24 Cores Memory 32GB Disk Type Raid 10, SAS Drives Disk Space 250 GB Devices 390 Ports 16167 Health sensors 3223 Load < 14.5"},{"location":"Support/Example-Hardware-Setup/#cppmonkeykodapa85","title":"CppMonkey(KodApa85)","text":"

Home

LibreNMS MariaDB Type i5-4690K Same Workstation OS Ubuntu 18.04.2 CPU 4 Cores Memory 16GB Disk Type Hybrid SATA Disk Space 2 TB Devices 14 Ports 0 Health sensors 70 Load < 0.5"},{"location":"Support/Example-Hardware-Setup/#cppmonkeykodapa85_1","title":"CppMonkey(KodApa85)","text":"

Dev

Running in Ganeti

LibreNMS MariaDB Type VM Same VM OS CentOS 7.5 CPU 2 Cores Memory 4GB Disk Type M.2 Disk Space 40 GB Devices 38 Ports 1583 Health sensors 884 Load < 1.0"},{"location":"Support/Example-Hardware-Setup/#cppmonkeykodapa85_2","title":"CppMonkey(KodApa85)","text":"

Work NOC

Running in Ganeti Cluster with 2x Dell PER730xd - 64GB, Dual E5-2660 v3

LibreNMS MariaDB Type VM VM OS Debian Stretch Debian Stretch CPU 4 Cores 2 Cores Memory 8GB 4GB Disk Type Raid 6, SAS Drives Disk Space 100 GB 40GB Devices 179 Ports 14495 Health sensors 2329 Load < 2.5 < 1.5"},{"location":"Support/Example-Hardware-Setup/#lazydk","title":"LaZyDK","text":"

Home

LibreNMS MariaDB Type VM - QNAP TS-453 Pro Same Server OS Ubuntu 16.04 CPU 1 vCore Memory 2GB Disk Type Raid 1, SATA Drives Disk Space 10 GB Devices 26 Ports 228 Health sensors 117 Load < 0.92"},{"location":"Support/Example-Hardware-Setup/#sirmaple","title":"SirMaple","text":"

Home

LibreNMS MariaDB Type VM Same Server OS Debian 11 CPU 4 vCore Memory 4GB Disk Type Raid 1, SSD Disk Space 50 GB Devices 41 Ports 317 Health sensors 243 Load < 3.15"},{"location":"Support/Example-Hardware-Setup/#vvelox","title":"VVelox","text":"

Home / Dev

LibreNMS MariaDB Type Supermicro X7SPA-HF Same Server OS FreeBSD 12-STABLE CPU Intel Atom D525 Memory 4GB Disk Type Raid 1, SATA Disk Space 1TB Devices 17 Ports 174 Health sensors 76 Load < 3"},{"location":"Support/Example-Hardware-Setup/#sourcedoctor","title":"SourceDoctor","text":"

Home / Dev

Running in VMWare Workstation Pro

LibreNMS MariaDB Type VM Same Server OS Debian Buster CPU 2 vCore Memory 2GB Disk Type Raid 5, SSD Disk Space 20GB Devices 35 Ports 245 Health sensors 101 Load < 1"},{"location":"Support/Example-Hardware-Setup/#lazyb0nes","title":"lazyb0nes","text":"

Lab

LibreNMS MariaDB Type VM Same Server OS RHEL 7.7 CPU 32 cores Memory 64GB Disk Type Flash San Array Disk Space 400GB Devices 670 Ports 25678 Health sensors 2457 Load 10.92"},{"location":"Support/Example-Hardware-Setup/#dagb","title":"dagb","text":"

Work

Running in VMware.

LibreNMS MariaDB Type Virtual Same Server OS CentOS 7 CPU 12 Cores Xeon 6130 Memory 8GB Disk Type SAN (SSD) Disk Space 26GB/72GB/7GB (logs/RRDs/db) Devices 650 Ports 34300 Health sensors 10500 Load 5.5 (45%)"},{"location":"Support/FAQ/","title":"FAQ","text":""},{"location":"Support/FAQ/#getting-started","title":"Getting started","text":""},{"location":"Support/FAQ/#how-do-i-install-librenms","title":"How do I install LibreNMS?","text":"

This is currently well documented within the doc folder of the installation files.

Please see the following doc

"},{"location":"Support/FAQ/#how-do-i-add-a-device","title":"How do I add a device?","text":"

You have two options for adding a new device into LibreNMS.

1: Using the command line via ssh you can add a new device by changing to the directory of your LibreNMS install and typing:

lnms device:add [hostname or ip]\n

To see all options run: lnms device:add -h

Please note that if the community contains special characters such as $ then you will need to wrap it in '. I.e: 'Pa$$w0rd'.

2: Using the web interface, go to Devices and then Add Device. Enter the details required for the device that you want to add and then click 'Add Host'.

"},{"location":"Support/FAQ/#how-do-i-get-help","title":"How do I get help?","text":"

Getting Help

"},{"location":"Support/FAQ/#what-are-the-supported-oses-for-installing-librenms-on","title":"What are the supported OSes for installing LibreNMS on?","text":"

Supported is quite a strong word :) The 'officially' supported distros are:

  • Ubuntu / Debian
  • Red Hat / CentOS
  • Gentoo

However we will always aim to help wherever possible so if you are running a distro that isn't one of the above then give it a try anyway and if you need help then jump on the discord server.

"},{"location":"Support/FAQ/#do-you-have-a-demo-available","title":"Do you have a demo available?","text":"

We do indeed, you can find access to the demo here

"},{"location":"Support/FAQ/#support","title":"Support","text":""},{"location":"Support/FAQ/#how-does-librenms-use-mibs","title":"How does LibreNMS use MIBs?","text":"

LibreNMS does not parse MIBs to discover sensors for devices. LibreNMS uses static discovery definitions written in YAML or PHP. Therefore, updating a MIB alone will not improve OS support, the definitions must be updated. LibreNMS only uses MIBs to make OIDs easier to read.

"},{"location":"Support/FAQ/#why-do-i-get-blank-pages-sometimes-in-the-webui","title":"Why do I get blank pages sometimes in the WebUI?","text":"

You can enable debug information by setting APP_DEBUG=true in your .env. (Do not leave this enabled, it could leak private data)

If the page you are trying to load has a substantial amount of data in it then it could be that the php memory limit needs to be increased in config.php.

"},{"location":"Support/FAQ/#why-do-i-not-see-any-graphs","title":"Why do I not see any graphs?","text":"

The easiest way to check if all is well is to run ./validate.php as librenms from within your install directory. This should give you info on why things aren't working.

One other reason could be a restricted snmpd.conf file or snmp view which limits the data sent back. If you use net-snmp then we suggest using the included snmpd.conf file.

"},{"location":"Support/FAQ/#how-do-i-debug-pages-not-loading-correctly","title":"How do I debug pages not loading correctly?","text":"

A debug system is in place which enables you to see the output from php errors, warnings and notices along with the MySQL queries that have been run for that page.

You can enable debug information by setting APP_DEBUG=true in your .env. (Do not leave this enabled, it could leak private data) To see additional information, run ./scripts/composer_wrapper.php install, to install additional debug tools. This will add a debug bar at the bottom of every page that will show you detailed debug information.

"},{"location":"Support/FAQ/#how-do-i-debug-the-discovery-process","title":"How do I debug the discovery process?","text":"

Please see the Discovery Support document for further details.

"},{"location":"Support/FAQ/#how-do-i-debug-the-poller-process","title":"How do I debug the poller process?","text":"

Please see the Poller Support document for further details.

"},{"location":"Support/FAQ/#why-do-i-get-a-lot-apache-or-rrdtool-zombies-in-my-process-list","title":"Why do I get a lot apache or rrdtool zombies in my process list?","text":"

If this is related to your web service for LibreNMS then this has been tracked down to an issue within php which the developers aren't fixing. We have implemented a work around which means you shouldn't be seeing this. If you are, please report this in issue 443.

"},{"location":"Support/FAQ/#why-do-i-see-traffic-spikes-in-my-graphs","title":"Why do I see traffic spikes in my graphs?","text":"

This occurs either when a counter resets or the device sends back bogus data making it look like a counter reset. We have enabled support for setting a maximum value for rrd files for ports.

Before this all rrd files were set to 100G max values, now you can enable support to limit this to the actual port speed.

rrdtool tune will change the max value when the interface speed is detected as being changed (min value will be set for anything 10M or over) or when you run the included script (./scripts/tune_port.php) - see RRDTune doc

SNMP ifInOctets and ifOutOctets are counters, which means they start at 0 (at device boot) and count up from there. LibreNMS records the value every 5 minutes and uses the difference between the previous value and the current value to calculate rate. (Also, this value resets to 0 when it hits the max value)

Now, when the value is not recorded for awhile RRD (our time series storage) does not record a 0, it records the last value, otherwise, there would be even worse problems. Then finally we get the current ifIn/OutOctets value and record that. Now, it appears as though all of the traffic since it stopped getting values have occurred in the last 5 minute interval.

So whenever you see spikes like this, it means we have not received data from the device for several polling intervals. The cause can vary quite a bit: bad snmp implementations, intermittent network connectivity, broken poller, and more.

"},{"location":"Support/FAQ/#why-do-i-see-gaps-in-my-graphs","title":"Why do I see gaps in my graphs?","text":"

This is most commonly due to the poller not being able to complete it's run within 300 seconds. Check which devices are causing this by going to /poll-log/ within the Web interface.

When you find the device(s) which are taking the longest you can then look at the Polling module graph under Graphs -> Poller -> Poller Modules Performance. Take a look at what modules are taking the longest and disabled un used modules.

If you poll a large number of devices / ports then it's recommended to run a local recursive dns server such as pdns-recursor.

Running RRDCached is also highly advised in larger installs but has benefits no matter the size.

"},{"location":"Support/FAQ/#how-do-i-change-the-ip-hostname-of-a-device","title":"How do I change the IP / hostname of a device?","text":"

There is a host rename tool called renamehost.php in your librenms root directory. When renaming you are also changing the device's IP / hostname address for monitoring.

Usage:

./renamehost.php <old hostname> <new hostname>\n

You can also rename a device in the Web UI by going to the device, then clicking settings Icon -> Edit.

"},{"location":"Support/FAQ/#my-device-doesnt-finish-polling-within-300-seconds","title":"My device doesn't finish polling within 300 seconds","text":"

We have a few things you can try:

  • Disable unnecessary polling modules under edit device.
  • Set a max repeater value within the snmp settings for a device. What to set this to is tricky, you really should run an snmpbulkwalk with -Cr10 through -Cr50 to see what works best. 50 is usually a good choice if the device can cope.
"},{"location":"Support/FAQ/#things-arent-working-correctly","title":"Things aren't working correctly?","text":"

Run ./validate.php as librenms from within your install.

Re-run ./validate.php once you've resolved any issues raised.

You have an odd issue - we'd suggest you join our discord server to discuss.

"},{"location":"Support/FAQ/#what-do-the-values-mean-in-my-graphs","title":"What do the values mean in my graphs?","text":"

The values you see are reported as metric values. Thanks to a post on Reddit here are those values:

10^-18  a - atto\n10^-15  f - femto\n10^-12  p - pico\n10^-9   n - nano\n10^-6   u - micro\n10^-3   m - milli\n0    (no unit)\n10^3    k - kilo\n10^6    M - mega\n10^9    G - giga\n10^12   T - tera\n10^15   P - peta\n
"},{"location":"Support/FAQ/#why-does-a-device-show-as-a-warning","title":"Why does a device show as a warning?","text":"

This is indicating that the device has rebooted within the last 24 hours (by default). If you want to adjust this threshold then you can do so by setting $config['uptime_warning'] = '86400'; in config.php. The value must be in seconds.

"},{"location":"Support/FAQ/#why-do-i-not-see-all-interfaces-in-the-overall-traffic-graph-for-a-device","title":"Why do I not see all interfaces in the Overall traffic graph for a device?","text":"

By default numerous interface types and interface descriptions are excluded from this graph. The excluded defaults are:

$config['device_traffic_iftype'][] = '/loopback/';\n$config['device_traffic_iftype'][] = '/tunnel/';\n$config['device_traffic_iftype'][] = '/virtual/';\n$config['device_traffic_iftype'][] = '/mpls/';\n$config['device_traffic_iftype'][] = '/ieee8023adLag/';\n$config['device_traffic_iftype'][] = '/l2vlan/';\n$config['device_traffic_iftype'][] = '/ppp/';\n\n$config['device_traffic_descr'][] = '/loopback/';\n$config['device_traffic_descr'][] = '/vlan/';\n$config['device_traffic_descr'][] = '/tunnel/';\n$config['device_traffic_descr'][] = '/bond/';\n$config['device_traffic_descr'][] = '/null/';\n$config['device_traffic_descr'][] = '/dummy/';\n

If you would like to re-include l2vlan interfaces for instance, you first need to unset the config array and set your options:

unset($config['device_traffic_iftype']);\n$config['device_traffic_iftype'][] = '/loopback/';\n$config['device_traffic_iftype'][] = '/tunnel/';\n$config['device_traffic_iftype'][] = '/virtual/';\n$config['device_traffic_iftype'][] = '/mpls/';\n$config['device_traffic_iftype'][] = '/ieee8023adLag/';\n$config['device_traffic_iftype'][] = '/ppp/';\n
"},{"location":"Support/FAQ/#how-do-i-migrate-my-librenms-install-to-another-server","title":"How do I migrate my LibreNMS install to another server?","text":"

If you are moving from one CPU architecture to another then you will need to dump the rrd files and re-create them. If you are in this scenario then you can use Dan Brown's migration scripts.

If you are just moving to another server with the same CPU architecture then the following steps should be all that's needed:

  • Install LibreNMS as per our normal documentation; you don't need to run through the web installer or building the sql schema.
  • Stop cron by commenting out all lines in /etc/cron.d/librenms
  • Dump the MySQL database librenms from your old server (mysqldump librenms -u root -p > librenms.sql)...
  • and import it into your new server (mysql -u root -p librenms < librenms.sql).
  • Copy the rrd/ folder to the new server.
  • Copy the .env and config.php files to the new server.
  • Check for modified files (eg specific os, ...) with git status and migrate them.
  • Ensure ownership of the copied files and folders (substitute your user if necessary) - chown -R librenms:librenms /opt/librenms
  • Delete old pollers on the GUI (gear icon --> Pollers --> Pollers)
  • Validate your installation (/opt/librenms/validate.php)
  • Re-enable cron by uncommenting all lines in /etc/cron.d/librenms
"},{"location":"Support/FAQ/#why-is-my-edgerouter-device-not-detected","title":"Why is my EdgeRouter device not detected?","text":"

If you have service snmp description set in your config then this will be why, please remove this. For some reason Ubnt have decided setting this value should override the sysDescr value returned which breaks our detection.

If you don't have that set then this may be then due to an update of EdgeOS or a new device type, please create an issue.

"},{"location":"Support/FAQ/#why-are-some-of-my-disks-not-showing","title":"Why are some of my disks not showing?","text":"

If you are monitoring a linux server then net-snmp doesn't always expose all disks via hrStorage (HOST-RESOURCES-MIB). We have additional support which will retrieve disks via dskTable (UCD-SNMP-MIB). To expose these disks you need to add additional config to your snmpd.conf file. For example, to expose /dev/sda1 which may be mounted as /storage you can specify:

disk /dev/sda1

Or

disk /storage

Restart snmpd and LibreNMS should populate the additional disk after a fresh discovery.

"},{"location":"Support/FAQ/#why-are-my-disks-reporting-an-incorrect-size","title":"Why are my disks reporting an incorrect size?","text":"

There is a known issue for net-snmp, which causes it to report incorrect disk size and disk usage when the size of the disk (or raid) are larger then 16TB, a workaround has been implemented but is not active on Centos 6.8 by default due to the fact that this workaround breaks official SNMP specs, and as such could cause unexpected behaviour in other SNMP tools. You can activate the workaround by adding to /etc/snmp/snmpd.conf :

realStorageUnits 0

"},{"location":"Support/FAQ/#what-does-mean-ignore-alert-tag-on-device-component-service-and-port","title":"What does mean \\\"ignore alert tag\\\" on device, component, service and port?","text":"

Tag device, component, service and port to ignore alerts. Alert checks will still run. However, ignore tag can be read in alert rules. For example on device, if devices.ignore = 0 or macros.device = 1 condition is is set and ignore alert tag is on, the alert rule won't match. The alert rule is ignored.

"},{"location":"Support/FAQ/#how-do-i-clean-up-alerts-from-my-switches-and-routers-about-ports-being-down-or-changing-speed","title":"How do I clean up alerts from my switches and routers about ports being down or changing speed","text":"

Some properties used for alerting (ending in _prev) are only updated when a change is detected, and not every time the poller runs. This means that if you make a permanant change to your network such as removing a device, performing a major firmware upgrade, or downgrading a WAN connection, you may be stuck with some unresolvable alerts.

If a port will be permantly down, it's best practice to configure it to be administratively down on the device to prevent malicious access. You can then only run alerts on ports with ifAdminStatus = up. Otherwise, you'll need to reset the device port state history.

On the device generating alerts, use the cog button to go to the edit device page. At the top of the device settings pane is a button labelled Reset Port State - this will clear the historic state for all ports on that device, allowing any active alerts to clear.

"},{"location":"Support/FAQ/#why-cant-normal-and-global-view-users-see-oxidized","title":"Why can't Normal and Global View users see Oxidized?","text":"

Configs can often contain sensitive data. Because of that only global admins can see configs.

"},{"location":"Support/FAQ/#what-is-the-demo-user-for","title":"What is the Demo User for?","text":"

Demo users allow full access except adding/editing users and deleting devices and can't change passwords.

"},{"location":"Support/FAQ/#why-does-modifying-default-alert-template-fail","title":"Why does modifying 'Default Alert Template' fail?","text":"

This template's entry could be missing in the database. Please run this from the LibreNMS directory:

php artisan db:seed --class=DefaultAlertTemplateSeeder\n
"},{"location":"Support/FAQ/#why-would-alert-un-mute-itself","title":"Why would alert un-mute itself?","text":"

If alert un-mutes itself then it most likely means that the alert cleared and is then triggered again. Please review eventlog as it will tell you in there.

"},{"location":"Support/FAQ/#how-do-i-change-the-device-type","title":"How do I change the Device Type?","text":"

You can change the Device Type by going to the device you would like to change, then click on the Gear Icon -> Edit. If you would like to define custom types, we suggest using Device Groups. They will be listed in the menu similarly to device types.

"},{"location":"Support/FAQ/#editing-large-device-groups-gives-error-messages","title":"Editing large device groups gives error messages","text":"

If the device group contains large amount of devices, editing it from the UI might cause errors on the form even when all the data seems correct. This is caused by PHP's max_input_vars-variable. You should be able to confirm that this is the case by inspecting the PHP's error logs.

With the basic installation on Ubuntu 22.04 LTS with Nginx and PHP 8.1 FPM this value can be tuned by editing the file /etc/php/8.1/fpm/php.ini and adjusting the value of max_input_vars to be at least the size of the large group. In larger installations a value such as 10000 should suffice.

"},{"location":"Support/FAQ/#where-do-i-update-my-database-credentials","title":"Where do I update my database credentials?","text":"

If you've changed your database credentials then you will need to update LibreNMS with those new details. Please edit .env

.env:

DB_HOST=\nDB_DATABASE=\nDB_USERNAME=\nDB_PASSWORD=\nDB_PORT=\n
"},{"location":"Support/FAQ/#my-reverse-proxy-is-not-working","title":"My reverse proxy is not working","text":"

Make sure your proxy is passing the proper variables. At a minimum: X-Forwarded-For and X-Forwarded-Proto (X-Forwarded-Port if needed)

You also need to Set the proxy or proxies as trusted

If you are using a subdirectory on the reverse proxy and not on the actual web server, you may need to set APP_URL and $config['base_url'].

"},{"location":"Support/FAQ/#my-alerts-arent-being-delivered-on-time","title":"My alerts aren't being delivered on time","text":"

If you're running MySQL/MariaDB on a separate machine or container make sure the timezone is set properly on both the LibreNMS and MySQL/MariaDB instance. Alerts will be delivered according to MySQL/MariaDB's time, so a mismatch between the two can cause alerts to be delivered late if LibreNMS is on a timezone later than MySQL/MariaDB.

"},{"location":"Support/FAQ/#my-alert-templates-stopped-working","title":"My alert templates stopped working","text":"

You should probably have a look in the documentation concerning the new template syntax. Since version 1.42, syntax changed, and you basically need to convert your templates to this new syntax (including the titles).

"},{"location":"Support/FAQ/#how-do-i-use-trend-prediction-in-graphs","title":"How do I use trend prediction in graphs","text":"

As of Ver. 1.55 a new feature has been added where you can view a simple linear prediction in port graphs.

It doesn't work on non-port graphs or consolidated graphs at the time this FAQ entry was written.

To view a prediction:

  • Click on any port graph of any network device
  • Select a From date to your liking (not earlier than the device was actually added to LNMS), and then select a future date in the To field.
  • Click update

You should now see a linear prediction line on the graph.

"},{"location":"Support/FAQ/#how-do-i-move-only-the-db-to-another-server","title":"How do I move only the DB to another server?","text":"

There is already a reference how to move your whole LNMS installation to another server. But the following steps will help you to split up an \"All-in-one\" installation to one LibreNMS installation with a separate database install. *Note: This section assumes you have a MySQL/MariaDB instance

  • Stop the apache and mysql service in you LibreNMS installation.
  • Edit out all the cron entries in /etc/cron.d/librenms.
  • Dump your librenmsdatabase on your current install by issuing mysqldump librenms -u root -p > librenms.sql.
  • Stop and disable the MySQL server on your current install.
  • On your new server make sure you create a new database with the standard install command, no need to add a user for localhost though.
  • Copy this over to your new database server and import it with mysql -u root -p librenms < librenms.sql.
  • Enter to mysql and add permissions with the following two commands:
    GRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'IP_OF_YOUR_LNMS_SERVER' IDENTIFIED BY 'PASSWORD' WITH GRANT OPTION;\nGRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'FQDN_OF_YOUR_LNMS_SERVER' IDENTIFIED BY 'PASSWORD' WITH GRANT OPTION;\nFLUSH PRIVILEGES;\nexit;\n
  • Enable and restart MySQL server.
  • Edit your config.php file to point the install to the new database server location.
  • Very important: On your LibreNMS server, inside your install directory is a .env file, in it you need to edit the DBHOST paramater to point to your new server location.
  • After all this is done, enable all the cron entries again and start apache.
"},{"location":"Support/FAQ/#what-are-the-optional-requirements-message-when-i-add-snmpv3-devices","title":"What are the \"optional requirements message\" when I add SNMPv3 devices?","text":"

When you add a device via the WebUI you may see a little message stating \"Optional requirements are not met so some options are disabled\". Do not panic. This simply means your system does not contain openssl >= 1.1 and net-snmp >= 5.8, which are the minimum specifications needed to be able to use SHA-224|256|384|512 as auth algorithms. For crypto algorithms AES-192, AES-256 you need net-snmp compiled with --enable-blumenthal-aes.

"},{"location":"Support/FAQ/#developing","title":"Developing","text":""},{"location":"Support/FAQ/#how-do-i-add-support-for-a-new-os","title":"How do I add support for a new OS?","text":"

Please see Supporting a new OS if you are adding all the support yourself, i.e. writing all of the supporting code. If you are only able to supply supporting info, and would like the help of others to write up the code, please follow the below steps.

"},{"location":"Support/FAQ/#what-information-do-you-need-to-add-a-new-os","title":"What information do you need to add a new OS?","text":"

Please open a feature request in the community forum and provide the output of Discovery, Poller, and Snmpwalk as separate non-expiring https://p.libren.ms/ links :

Please use preferably the command line to obtain the information. Especially, if snmpwalk results in a large amount of data. Replace the relevant information in these commands such as HOSTNAME and COMMUNITY. Use snmpwalk instead of snmpbulkwalk for v1 devices.

These commands will automatically upload the data to LibreNMS servers.

./discovery.php -h HOSTNAME -d | ./pbin.sh\nlnms device:poll HOSTNAME -vv | ./pbin.sh\nsnmpbulkwalk -OUneb -v2c -c COMMUNITY HOSTNAME .  | ./pbin.sh\n

You can use the links provided by these commands within the community post.

If possible please also provide what the OS name should be if it doesn't exist already, as well as any useful link (MIBs from vendor, logo, etc etc)

"},{"location":"Support/FAQ/#what-can-i-do-to-help","title":"What can I do to help?","text":"

Thanks for asking, sometimes it's not quite so obvious and everyone can contribute something different. So here are some ways you can help LibreNMS improve.

  • Code. This is a big thing. We want this community to grow by the software developing and evolving to cater for users needs. The biggest area that people can help make this happen is by providing code support. This doesn't necessarily mean contributing code for discovering a new device:
  • Web UI, a new look and feel has been adopted but we are not finished by any stretch of the imagination. Make suggestions, find and fix bugs, update the design / layout.
  • Poller / Discovery code. Improving it (we think a lot can be done to speed things up), adding new device support and updating old ones.
  • The LibreNMS main website, this is hosted on GitHub like the main repo and we accept use contributions here as well :)
  • Hardware. We don't physically need it but if we are to add device support, it's made a whole lot easier with access to the kit via SNMP.
  • If you've got MIBs, they are handy as well :)
  • If you know the vendor and can get permission to use logos that's also great.
  • Bugs. Found one? We want to know about it. Most bugs are fixed after being spotted and reported by someone, I'd love to say we are amazing developers and will fix all bugs before you spot them but that's just not true.
  • Feature requests. Can't code / won't code. No worries, chuck a feature request into our community forum with enough detail and someone will take a look. A lot of the time this might be what interests someone, they need the same feature or they just have time. Please be patient, everyone who contributes does so in their own time.
  • Documentation. Documentation can always be improved and every little bit helps. Not all features are currently documented or documented well, there's spelling mistakes etc. It's very easy to submit updates through the GitHub website, no git experience needed.
  • Be nice, this is the foundation of this project. We expect everyone to be nice. People will fall out, people will disagree but please do it so in a respectable way.
  • Ask questions. Sometimes just by asking questions you prompt deeper conversations that can lead us to somewhere amazing so please never be afraid to ask a question.
"},{"location":"Support/FAQ/#how-can-i-test-another-users-branch","title":"How can I test another users branch?","text":"

LibreNMS can and is developed by anyone, this means someone may be working on a new feature or support for a device that you want. It can be helpful for others to test these new features, using Git, this is made easy.

cd /opt/librenms\n

Firstly ensure that your current branch is in good state:

git status\n

If you see nothing to commit, working directory clean then let's go for it :)

Let's say that you want to test a users (f0o) new development branch (issue-1337) then you can do the following:

git remote add f0o https://github.com/f0o/librenms.git\ngit remote update f0o\ngit checkout issue-1337\n

Once you are done testing, you can easily switch back to the master branch:

git checkout master\n

If you want to pull any new updates provided by f0o's branch then whilst you are still in it, do the following:

git pull f0o issue-1337\n
"},{"location":"Support/Features/","title":"Features","text":"

Here's a brief list of supported features, some might be missing. If you think something is missing, feel free to ask us.

  • Auto discovery
  • Alerting
  • Multiple environment sensors support
  • Multiple protocols data collection (STP, OSPF, BGP etc)
  • VLAN, ARP and FDB table collection
  • Customizable Dashboards
  • Device Backup integration (Oxidized, RANCID)
  • Distributed Polling
  • Multiple Authentication Methods (MySQL, LDAP, Active Directory, HTTP)
  • NetFlow, sFlow, IPFIX (NfSen)
  • Service monitoring (Nagios Plugins)
  • Syslog (Integrated, Graylog)
  • Traffic Billing (Quota, 95th Percentile)
  • Two Factor Authentication
  • API
  • Auto Updating
"},{"location":"Support/Features/#supported-vendors","title":"Supported Vendors","text":"

Here's a list of supported vendors, some might be missing. If you are unsure of whether your device is supported or not, feel free to ask us.

"},{"location":"Support/Features/#3","title":"3","text":"
  • 3Com
"},{"location":"Support/Features/#a","title":"A","text":"
  • A10 Networks
  • Acano OS
  • Accedian AEN
  • Adtran AOS
  • ADVA FSP150CC
  • ADVA FSP3000 R7
  • ADVA OptiSwitch
  • Advantech
  • Aerohive HiveOS
  • Airconsole Server
  • AIX
  • AKCP SensorProbe
  • Alcatel OmniPCX
  • Alcatel-Lucent Enterprise Stellar Wireless OS (AWOS)
  • Alcatel-Lucent OS
  • Alcoma
  • ALGCOM DC UPS
  • Allied Telesis Wireless (TQ)
  • Alliedware
  • Alliedware Plus
  • Allworx VoIP
  • Alpha Comp@s
  • Alpha CXC HP Controller
  • Alpha FXM
  • Alpine OptoElectronics TDCM-EDFA platform
  • AlteonOS
  • Alvarion Breeze
  • Anue
  • AnyOS
  • APC Environmental Monitoring Unit
  • APC ePDU
  • APC Management Module
  • APC MGE UPS
  • Apex Lynx
  • Apex Plus
  • Apple AirPort
  • Apple OS X
  • Aprisa
  • ApsoluteOS
  • ArbOS
  • Areca RAID Subsystem
  • Arista EOS
  • Arista MOS
  • Array Networks
  • Arris Apex
  • Arris CMTS
  • Arris D5 Universal EdgeQAM
  • ARRIS DOCSIS
  • Arris Satellite Receiver
  • Aruba Clearpass
  • Aruba Instant
  • ArubaOS
  • ArubaOS-CX
  • Ascom
  • Asentria SiteBoss
  • AsusWRT Merlin
  • Aten PDU
  • Audiocodes
  • Automatic Transfer Switch
  • Avaya Scopia
  • AvediaPlayer Receivers
  • AvediaStream Encoder
  • Aviat WTM
  • Avocent
  • Avtech Environment Sensor
  • AXIS Audio Appliances
  • AXIS Network Camera
  • AXIS Network Document Server
"},{"location":"Support/Features/#b","title":"B","text":"
  • Barco Clickshare
  • Barracuda Email Security Gateway
  • Barracuda Load Balancer
  • Barracuda NG Firewall
  • Barracuda Web Application Firewall
  • BATS AATS
  • BDCOM(tm) Software
  • BeagleBoard
  • Benu
  • Bintec Be.IP Plus
  • Bintec Smart Router
  • BKE
  • BKtel
  • Blade Network Technologies
  • BladeShelter PDU by PowerTek
  • Blue Coat PacketShaper
  • Blue Coat SSL Visibility
  • Bluecat Networks
  • BlueCoat ProxySG
  • Broadcom BCM963xx
  • Brocade FabricOS
  • Brocade IronWare
  • Brocade NOS
  • Brocade ServerIron
  • Brother Printer
  • BTI SA-800
  • Buffalo
"},{"location":"Support/Features/#c","title":"C","text":"
  • C&C Power Commander plus
  • Calix AXOS
  • Calix B6 System
  • Calix EXA
  • Calix Legacy
  • Cambium
  • Cambium CMM
  • Cambium CMM4
  • Cambium cnMatrix
  • Cambium cnPilot
  • Cambium cnPilot Router
  • Cambium cnWave60
  • Cambium epmp
  • Cambium PTP 250
  • Cambium PTP 300/500
  • Cambium PTP 600
  • Cambium PTP 650
  • Cambium PTP 670
  • Cambium PTP 800
  • Canon Printer
  • Carel pCOWeb
  • cdata
  • Ceragon CeraOS
  • CET TSI Controller
  • Chatsworth PDU
  • Check Point GAiA
  • CheckPoint SecurePlatform
  • Christie Projector
  • Ciena SAOS
  • Ciena Service Delivery Switch
  • Ciena Waveserver
  • Ciena Z-Series
  • cirpack
  • Cisco ACE
  • Cisco ACS
  • Cisco APIC
  • Cisco ASA
  • Cisco AsyncOS
  • Cisco Catalyst 1900
  • Cisco CatOS
  • Cisco EPC
  • Cisco FTD
  • Cisco FX-OS
  • Cisco Identity Services Engine
  • Cisco Integrated Management Controller
  • Cisco Intrusion Prevention System
  • Cisco IOS
  • Cisco IOS-XE
  • Cisco IOS-XR
  • Cisco ME1200
  • Cisco Nexus 3550 Series
  • Cisco NX-OS
  • Cisco ONS
  • Cisco PIX-OS
  • Cisco SAN-OS
  • Cisco Satellite Receiver
  • Cisco SCE
  • Cisco Services Ready Platform
  • Cisco Small Business
  • Cisco Unified Communications Manager
  • Cisco Voice Gateway
  • Cisco WAAS
  • Cisco Wireless Access Point
  • Cisco WLC
  • Citrix Netscaler
  • Comet System Web Sensor
  • Comtrol Industrial Switch
  • Controlbox TH-332B
  • CoreOS
  • Corero CMS
  • Coriant TNMS
  • CradlePoint WiPipe
  • CTC Union
  • Cumulus Linux
  • CXR Networks TS
  • Cyberoam UTM
  • Cyberpower
"},{"location":"Support/Features/#d","title":"D","text":"
  • D-Link Access Point
  • D-Link Switch
  • Dahua NVR
  • Dantel Webmon
  • Dantherm
  • Dasan NOS
  • Datacom
  • dd-wrt
  • DDN Storage
  • Deliberant OS
  • Dell DRAC
  • Dell EMC Networking OS10 Enterprise
  • Dell EqualLogic
  • Dell Laser
  • Dell Networking OS
  • Dell OpenManage Enterprise Modular
  • Dell PowerConnect
  • Dell PowerVault
  • Dell PowerVault MD
  • Dell Rack PDU
  • Dell Remote Console
  • Dell Storage
  • Dell UPS
  • Delta Orion Controller
  • Delta UPS
  • Develop Printer
  • DHCPatriot
  • Digipower
  • Digital China Networks
  • DKT Comega
  • DPS Telecom NetGuardian
  • DragonflyBSD
  • Dragonwave Harmony Enhanced
  • Dragonwave Horizon Compact
  • Dragonwave Horizon Compact Plus
  • Dragonwave Horizon Duo
  • DrayTek
  • DVB Modulator & Ampiflier
  • DVB-T Transmitter
"},{"location":"Support/Features/#e","title":"E","text":"
  • E3 Meter
  • E3 Meter DataConcentrator
  • Eagle-I
  • East
  • Eaton ATS
  • Eaton Matrix
  • Eaton MGE PDU
  • Eaton PDU
  • Eaton SC200 Controller
  • Eaton UPS
  • EDFA
  • Edgecore
  • EdgeOS
  • EdgeSwitch
  • EDS
  • EfficientIP SOLIDserver
  • Ekinops Optical
  • Eltek Valere
  • Eltek Valere eNexus
  • Eltek WebPower
  • Eltex OLT
  • Eltex-MES21xx
  • Eltex-MES23xx
  • EMC Data Domain
  • EMC Flare OS
  • EMC Isilon OneFS
  • Emerson Energy System
  • Emerson Netsure
  • Endian
  • EndRun
  • EnGenius Access Point
  • enLogic PDU
  • Enterasys
  • Epson Printer
  • Epson Projector
  • Ericsson 6600 series
  • Ericsson IPOS
  • Ericsson LG iPECS UCP
  • Ericsson MINI-LINK
  • Ericsson Traffic Node
  • EricssonLG IPECS ES
  • Etherwan Managed Switch
  • EUROstor RAID Subsystem
  • Exagrid
  • Exalt ExtendAir
  • Exinda
  • Extrahop Appliance
  • Extreme BOSS
  • Extreme SLX-OS
  • Extreme VOSS
  • Extreme Wireless Convergence
  • Extreme XOS
  • Extremeware
"},{"location":"Support/Features/#f","title":"F","text":"
  • F5 Big IP
  • F5OS
  • Fiberhome
  • FiberHome Switch
  • Fibernet XMUX 4+
  • Fiberstore GBN
  • Fiberstore Switch
  • Firebrick
  • FireEye OS
  • Force10 FTOS
  • Fortinet Application Deliver Controller
  • Fortinet FortiAuthenticator
  • Fortinet Fortigate
  • Fortinet FortiMail
  • Fortinet FortiSandbox
  • Fortinet FortiSwitch
  • Fortinet FortiVoice
  • Fortinet FortiWeb
  • Fortinet FortiWLC
  • FortiOS
  • Foundry Networking
  • FreeBSD
  • FreshTomato
  • FS.COM monitored pdu
  • Fujitsu
  • Fujitsu ETERNUS
  • FUJITSU iRMC
  • Fujitsu NAS
  • FusionHub
"},{"location":"Support/Features/#g","title":"G","text":"
  • Gamatronic UPS Stack
  • Gandi Packet Journey
  • GE Digital Energy UPS
  • GE MDS Orbit network Operating System
  • GE Pulsar
  • Geist PDU
  • Geist Watchdog
  • Generex UPS SNMP adapter
  • Generic
  • Generic Device
  • Gestetner Printer
  • GigaVUE
  • Glass Way WDM EYDFA
  • Grandstream HT
  • Greenbone OS
  • Gude Expert Transfer Switch
  • gwd
"},{"location":"Support/Features/#h","title":"H","text":"
  • Halon
  • Hanwha Techwin
  • HAProxy ALOHA
  • Hardware Appliance
  • Hatteras Overdue DSLAM
  • Helios IP
  • Hikvision Camera
  • Hikvision NVR
  • Hillstone StoneOs
  • Himoinsa Generator Sets
  • Hirschmann Railswitch
  • Hitachi Storage Virtualization Operating System (SVOS)
  • HP Blade Management
  • HP MSM
  • HP PDU Management Module
  • HP Print server
  • HP ProCurve
  • HP UPS
  • HP Virtual Connect
  • HPE 3PAR
  • HPE Comware
  • HPE Integrated Lights Out
  • HPE iPDU
  • HPE Managed Power Distribution Unit
  • HPE MSA
  • HPE OpenVMS
  • HPE StoreEver MSL
  • Huawei iBMC Management Console
  • Huawei OceanStor
  • Huawei SmartAX
  • Huawei SmartAX MDU
  • Huawei SMU
  • Huawei UPS
  • Huawei VRP
  • HWg Poseidon
  • HWg STE
  • HWg STE2
  • HWg WLD
  • Hytera Repeater
"},{"location":"Support/Features/#i","title":"I","text":"
  • IBM AMM
  • IBM DPI
  • IBM i
  • IBM IMM
  • IBM Networking Operating System
  • IBM Tape Library
  • iBoot PDU
  • Icotera OS
  • ICR-OS
  • ICT Digital Series Power Supply
  • ICT Distribution Series
  • ICT Modular Power System
  • ICT Sine Wave Inverter
  • Ifotec
  • IgniteNet FusionSwitch
  • IgniteNet HeliOS
  • Illustra Network Camera
  • Imco Power
  • Imco Power LS110
  • Infinera Groove
  • Infinera PON
  • Infinera XTM
  • Infoblox
  • Ingrasys iPoMan
  • Innovaphone ISDN
  • Inteno GW
  • IONODES
  • IP Infusion OcNOS
  • IP Office Firmware
  • ITWatchDogs Goose
"},{"location":"Support/Features/#j","title":"J","text":"
  • Jacarta InterSeptor
  • Janitza
  • Janitza UMG96
  • Juniper EX2500
  • Juniper JunOS
  • Juniper JunOSe
  • Juniper JWOS
  • Juniper MSS
  • Juniper ScreenOS
"},{"location":"Support/Features/#k","title":"K","text":"
  • Kemp Loadbalancer
  • Konica-Minolta Printer
  • KTI
  • Kyocera Mita Printer
"},{"location":"Support/Features/#l","title":"L","text":"
  • Lambdatrail
  • Lancom OS
  • Lanier Printer
  • LANTIME v6
  • Lantronix SLC
  • Lantronix UDS
  • Last Mile Gear CTM
  • Lenovo Cloud Network Operating System
  • Lenovo XCC IMPI
  • LenovoEMC
  • Lexmark Printer
  • Liebert
  • LigoWave Infinity
  • LigoWave LigoOS
  • Linksys Smart Switch
  • Linux
  • Loadbalancer.org
  • LogMaster
  • Loop Telecom Operating System
"},{"location":"Support/Features/#m","title":"M","text":"
  • m0n0wall
  • Maipu MyPower
  • Marathon UPS
  • McAfee Linux OS - ATD
  • McAfee Linux OS - NSP
  • McAfee SIEM Nitro
  • Mcafee Web Gateway
  • MegaTec NetAgent II
  • Mellanox
  • Meraki AP
  • Meraki MX Appliance
  • Meraki Switch
  • Microsemi PowerDsine Midspan PoE
  • Microsemi Synchronization Supply Unit
  • Microsoft Windows
  • Mikrotik RouterOS
  • Mikrotik SwOS
  • Mimosa
  • Minkels RMS
  • Mirth Connect
  • Mitel Standard Linux
  • MNI Microwave Radio
  • MobileIron
  • Montclair EDFA
  • Motorola DOCSIS Cable Modem
  • Motorola Netopia
  • Moxa
  • Moxa AWK
  • MRV LambdaDriver
  • MRV OptiDriver
"},{"location":"Support/Features/#n","title":"N","text":"
  • NEC Univerge
  • NetApp
  • NetBotz Environment Sensor
  • NetBSD
  • Netgear ProSafe
  • NetMan Plus
  • NetModule
  • Netonix
  • NetScaler SD-WAN
  • Network Management Unit
  • Nexans
  • Nimble OS
  • NOKIA ISAM
  • Nokia SR OS (TiMOS)
  • Novell Netware
  • NRG Printer
  • NTI
  • Nutanix AOS
  • NVT Phybridge
"},{"location":"Support/Features/#o","title":"O","text":"
  • OKI Printer
  • Omnitron iConverter
  • OneAccess
  • Open Access Netspire
  • Open-E
  • OpenBSD
  • Opengear
  • OpenIndiana
  • OpenSystems
  • OpenWrt
  • OPNsense
  • Oracle ILOM
  • Orvaldi UPS
"},{"location":"Support/Features/#p","title":"P","text":"
  • Packetflux SiteMonitor
  • Packetlight
  • Panasonic KX-NS Series
  • Panduit PDU
  • PanOS
  • Papouch QUIDO
  • Papouch TME
  • Paradyne (by Zhone)
  • Patton SmartNode
  • PBI Digital Decoder
  • PBN
  • PBN P2P CP100 Series Platform
  • Pegasus
  • Pepwave
  • Perle
  • pfSense
  • Pica8 OS
  • Ping only
  • PLANET
  • Polycom Videoconferencing System
  • Powercode BMU
  • PowerWalker UPS
  • PowerWalker VFI
  • Prime Infrastructure
  • Procera Networks
  • Proxim
  • proxmox pve
  • Pulse Secure
"},{"location":"Support/Features/#q","title":"Q","text":"
  • QNAP TurboNAS
  • QTECH
  • Quanta
  • QuantaStor
"},{"location":"Support/Features/#r","title":"R","text":"
  • Radlan
  • RADWIN
  • Raisecom ROAP
  • Raisecom ROS
  • Raritan EMX
  • Raritan KVM
  • Raritan PDU
  • RAy
  • RAy3
  • RecoveryOS
  • Red Lion Sixnet
  • Redback Networks SmartEdge
  • Redlion N-Tron
  • Ribbon GSX
  • Ribbon SBC
  • Ricoh Printer
  • Rittal CMC
  • Rittal CMC III PU
  • Rittal IT Chiller
  • Rittal LCP
  • Rittal LCP DX Chiller
  • Riverbed
  • RNX UPDU
  • Rohde & Schwarz
  • Rubrik
  • Ruckus Wireless HotZone
  • Ruckus Wireless SmartZone
  • Ruckus Wireless Unleashed
  • Ruckus Wireless ZoneDirector
  • Ruijie Networks
"},{"location":"Support/Features/#s","title":"S","text":"
  • SAF CFM
  • SAF Integra B
  • SAF Integra E
  • SAF Integra W
  • SAF Integra X
  • SAF Tehnika
  • Sagem ADR IONOS
  • Samsung Printer
  • Savin Printer
  • Schleifenbauer SPDM
  • Schneider PowerLogic
  • SCS KS
  • Sensatronics EM1
  • Sensatronics ITTM
  • ServersCheck
  • ServerTech Sentry3
  • ServerTech Sentry4
  • Sharp Printer
  • SIAE Alfoplus 80HD
  • Siemens Ruggedcom Switches (ROS)
  • Siemens SCALANCE
  • Siklu Wireless
  • Silver Peak VXOA
  • Sinetica UPS
  • SM-OS
  • SmartOptics DCP-M Series
  • SmartOptics M-Series
  • SmartOptics T-Series
  • snr
  • snr-erd
  • Socomec Net Vision
  • Socomec PDU
  • Software Appliance
  • Solid Optics EDFAMUX
  • SonicWALL
  • Sophos UTM Firewall
  • Sophos XG
  • Stormshield NS-BSD
  • Stulz GMBH Klimatechnik
  • Sub10 Systems
  • Sun OpenSolaris
  • Sun Solaris
  • Supermicro Switch
  • Symbol AP
  • SyncServer
  • Synology DSM
"},{"location":"Support/Features/#t","title":"T","text":"
  • Tait Infra93 Series
  • Tait TN Admin OS
  • Tandberg Magnum
  • technicolor TG MediaAcces
  • Tegile IntelliFlash
  • Telco Systems BiNOS
  • Telco Systems BiNOX
  • Teldat
  • TelePresence Codec
  • TelePresence Conductor
  • Teleste Luminato
  • teltonika rutos
  • Teltonika RutOS RUTX Series
  • Teradici PCoIP
  • Terra
  • Thomson DOCSIS Cable Modem
  • Thomson Speedtouch
  • Tomato
  • TopVision
  • Toshiba Printer
  • Toshiba RemotEye4
  • TP-Link JetStream
  • TP-Link Switch
  • Transition
  • Tranzeo
  • TRENDnet Switch
  • Tripp Lite PowerAlert
  • TrueNAS
  • TSC Printer
  • Tycon Systems TPDIN
"},{"location":"Support/Features/#u","title":"U","text":"
  • Ubiquiti AirFiber
  • Ubiquiti AirFiber 60
  • Ubiquiti AirFiber LTU
  • Ubiquiti AirOS
  • Ubiquiti Edgepower
  • Ubiquiti UniFi
  • Ubiquoss PON
  • Ucopia
  • UFiber
  • UHP Networks VSAT Terminal
  • UniPing
"},{"location":"Support/Features/#v","title":"V","text":"
  • V-Solution
  • Vanguard ApplicationsWare
  • Vertiv Avocent MergePoint Unity
  • Vertiv PDU
  • Video Communication Server
  • Viprinux
  • Viptela
  • Vivotek Camera
  • VMware ESXi
  • VMware SD-WAN
  • VMware vCenter
  • Volius
  • Voswall
  • Vubiq Networks
  • Vutlan
  • Vyatta
  • VyOS
"},{"location":"Support/Features/#w","title":"W","text":"
  • Watchguard Fireware
  • Waystream iBOS
  • Web-Thermo-Hygrometer
  • WebPower
  • West Mountain RMCU
  • WISI Tangram
  • WTI CONSOLE
  • WTI MPC
  • WTI POWER
"},{"location":"Support/Features/#x","title":"X","text":"
  • Xerox Printer
  • Xirrus ArrayOS
"},{"location":"Support/Features/#z","title":"Z","text":"
  • ZebraNet
  • Zhone MXK
  • Zmtel Greenpacket
  • ZTE ZXA10
  • ZTE ZXR10
  • ZXDSL
  • ZyXEL AC
  • ZyXEL DSLAM
  • ZyXEL Ethernet Switch
  • ZyXEL IES MSAN
  • ZyXEL IES-5000 DSLAM
  • ZyXEL NWA
  • ZyXEL Prestige
  • ZyXEL ZyWALL
"},{"location":"Support/Install%20Validation/","title":"Install validation","text":"

With a lot of configuration possibilities, manually editing config.php means it's not uncommon that mistakes get made. It's also impossible to validate user input in config.php when you're just using a text editor :)

So, to try and help with some of the general issues people come across we've put together a simple validation tool which at present will:

  • Validate config.php from a php perspective including whitespace where it shouldn't be.
  • Connection to your MySQL server to verify credentials.
  • Checks if you are running the older alerting system.
  • Checks your rrd directory setup if not running rrdcached.
  • Checks disk space for where /opt/librenms is installed.
  • Checks location to fping
  • Tests MySQL strict mode being enabled
  • Tests for files not owned by librenms user (if configured)

Optionally you can also pass -m and a module name for that to be tested. Current modules are:

  • mail - This will validate your mail transport configuration.
  • dist-poller - This will test your distributed poller configuration.
  • rrdcheck - This will test your rrd files to see if they are unreadable or corrupted (source of broken graphs).

You can run validate.php as root by executing ./validate.php within your install directory.

The output will provide you either a clean bill of health or a list of things you need to fix:

OK - This is a good thing, you can skip over these :)

WARN - You probably want to check this out.

FAIL - This is going to need your attention!

"},{"location":"Support/Install%20Validation/#validate-from-the-webui","title":"Validate from the WebUI","text":"

You can validate your LibreNMS install from the WebUI, using the nav bar and clicking on the little Gear Icon -> Validate Config.

Then You should see the results of validate.

Below is just example of the results.

"},{"location":"Support/Performance/","title":"Performance optimisations","text":"

This document will give you some guidance on optimising your setup.

The suggestions are in a rough order of how much impact they will have.

"},{"location":"Support/Performance/#rrdcached","title":"RRDCached","text":"

We absolutely recommend running this, it will save on IO load. RRDCached

"},{"location":"Support/Performance/#mysql-optimisation","title":"MySQL Optimisation","text":"

It's advisable after 24 hours of running MySQL that you run MySQL Tuner which will make suggestions on things you can change specific to your setup.

One recommendation we can make is that you set the following in my.cnf under a [mysqld] group:

innodb_flush_log_at_trx_commit = 0\n

You can also set this to 2. This will have the possibility that you could lose up to 1 second on mysql data in the event MySQL crashes or your server does but it provides an amazing difference in IO use.

"},{"location":"Support/Performance/#polling-modules","title":"Polling modules","text":"

Review the graph of poller module time take under gear > pollers > performance to see what modules are consuming poller time. This data is shown per device under device > graphs > poller.

Disable polling (and discovery) modules that you do not need. You can do this globally in config.php like:

Disable OSPF polling

poller/poller_modules

lnms config:set poller_modules.ospf false\n

You can disable modules globally then re-enable the module per device or the opposite way. For a list of modules please see Poller modules

"},{"location":"Support/Performance/#snmp-max-repeaters","title":"SNMP Max Repeaters","text":"

We have support for SNMP Max repeaters which can be handy on devices where we poll a lot of ports or bgp sessions for instance and where snmpwalk or snmpbulkwalk is used. This needs to be enabled on a per device basis under edit device -> snmp -> Max repeaters.

You can also set this globally with the config option $config['snmp']['max_repeaters'] = X;.

It's advisable to test the time taken to snmpwalk IF-MIB or something similar to work out what the best value is. To do this run the following but replace -REPEATERS- with varying numbers from 10 upto around 50. You will also need to set the correct snmp version, hostname and community string:

time snmpbulkwalk -v2c -cpublic HOSTNAME -Cr-REPEATERS- -M /opt/librenms/mibs -m IF-MIB IfEntry

NOTE: Do not go blindly setting this value as you can impact polling negatively.

"},{"location":"Support/Performance/#snmp-max-oids","title":"SNMP Max OIDs","text":"

For sensors polling we now do bulk snmp gets to speed things up. By default this is ten but you can overwrite this per device under edit device -> snmp -> Max OIDs.

You can also set this globally with the config option $config['snmp']['max_oid'] = X;.

NOTE: It is advisable to monitor sensor polling when you change this to ensure you don't set the value too high.

"},{"location":"Support/Performance/#fping-tuning","title":"fping tuning","text":"

You can change some of the default fping options used globally or per device. The defaults are:

poller/ping

lnms config:set fping_options.timeout 500\nlnms config:set fping_options.count 3\nlnms config:set fping_options.interval 500\n

If your devices are slow to respond then you will need to increase the timeout value and potentially the interval value. However if your network is stable, you can increase poller performance by dropping the count value to 1 and/or the timeout+millsec value to 200 or 300:

poller/ping

lnms config:set fping_options.timeout 300\nlnms config:set fping_options.count 1\nlnms config:set fping_options.interval 300\n

This will mean that we no longer delay each icmp packet sent (we send 3 in total by default) by 0.5 seconds. With only 1 icmp packet being sent then we will receive a response quicker. The defaults mean it will take at least 1 second for a response no matter how quick the icmp packet is returned.

"},{"location":"Support/Performance/#optimise-poller-wrapper","title":"Optimise poller-wrapper","text":"

poller-wrapper.py defaults to using 16 threads, this isn't necessarily optimal. A general rule of thumb is 2 threads per core but we suggest that you play around with lowering / increasing the number until you get the optimal value. Note KEEP in MIND that this doesn't always help, it depends on your system and CPU. So be careful. This can be changed by going to the cron job for librenms. Usually in /etc/cron.d/librenms and changing the \"16\"

*/5  *    * * *   librenms    /opt/librenms/cronic /opt/librenms/poller-wrapper.py 16\n
Please also see Dispatcher Service

"},{"location":"Support/Performance/#recursive-dns","title":"Recursive DNS","text":"

If your install uses hostnames for devices and you have quite a lot then it's advisable to setup a local recursive dns instance on the LibreNMS server. Something like pdns-recursor can be used and then configure /etc/resolv.conf to use 127.0.0.1 for queries.

"},{"location":"Support/Performance/#per-port-polling-experimental","title":"Per port polling - experimental","text":"

By default the polling ports module will walk ifXEntry + some items from ifEntry regardless of the port. So if a port is marked as deleted because you don't want to see them or it's disabled then we still collect data. For the most part this is fine as the walks are quite quick. However for devices with a lot of ports and good % of those are either deleted or disabled then this approach isn't optimal. So to counter this you can enable 'selected port polling' per device within the edit device -> misc section or by globally enabling it (not recommended): $config['polling']['selected_ports'] = true;. This is truly not recommended, as it has been proven to affect cpu usage of your poller negatively. You can also set it for a specific OS: $config['os']['ios']['polling']['selected_ports'] = true;.

Running ./scripts/collect-port-polling.php will poll your devices with both full and selective polling, display a table with the difference and optionally enable or disable selected ports polling for devices which would benefit from a change. Note that it doesn't continuously re-evaluate this, it will only be updated when the script is run. There are a number of options:

-h <device id> | <device hostname wildcard>  Poll single device or wildcard hostname\n-e <percentage>                              Enable/disable selected ports polling for devices which would benefit <percentage> from a change\n
If you want to run this script to have it set selected port polling on devices where a change of 10% or more is evaluated, run it with ./scripts/collect-port-polling.php -e 10. But note: it will not blindly use only the 10%. There is a second condition that the change has to be more than one second in polling time.

"},{"location":"Support/Performance/#web-interface","title":"Web interface","text":""},{"location":"Support/Performance/#http2","title":"HTTP/2","text":"

If you are running https then you should enable http/2 support in whatever web server you use:

For Nginx (1.9.5 and above) change listen 443 ssl; to listen 443 ssl http2; in the Virtualhost config.

For Apache (2.4.17 and above) set Protocols h2 http/1.1 in the Virtualhost config.

"},{"location":"Support/Performance/#php-opcache","title":"PHP-opcache","text":"

A lot of performance can be gained from setting up php-opcache correctly.

Note: Memory based caching with PHP cli will increase memory usage and slow things down. File based caching is not as fast as memory based and is more likely to have stale cache issues.

Some distributions allow separate cli, mod_php and php-fpm configurations, we can use this to set the optimal config.

"},{"location":"Support/Performance/#for-web-servers-using-mod_php-and-php-fpm","title":"For web servers using mod_php and php-fpm","text":"

Update your web PHP opcache.ini. Possible locations: /etc/php/8.1/fpm/conf.d/opcache.ini, /etc/php.d/opcache.ini, or /etc/php/conf.d/opcache.ini.

zend_extension=opcache\nopcache.enable=1\nopcache.memory_consumption=256\n

If you are having caching issues, you can clear the opcache by simply restarting httpd or php-fpm.

"},{"location":"Support/Performance/#for-pollers","title":"For pollers","text":"

Create a cache directory that is writable by the librenms user first: sudo mkdir -p /tmp/cache && sudo chmod 775 /tmp/cache && sudo chown -R librenms /tmp/cache

Update your PHP opcache.ini. Possible locations: /etc/php/8.1/cli/conf.d/opcache.ini, /etc/php.d/opcache.ini, or /etc/php/conf.d/opcache.ini.

zend_extension=opcache.so\nopcache.enable=1\nopcache.enable_cli=1\nopcache.file_cache=\"/tmp/cache/\"\nopcache.file_cache_only=0\nopcache.file_cache_consistency_checks=1\nopcache.memory_consumption=256\n

If you are having caching issues, you can clear the file based opcache with rm -rf /tmp/cache.

Debian 12 users, be aware php 8.2 current stable version (8.2.7) creates segmentation faults when opcache uses file cache. Issue should be this one https://github.com/php/php-src/issues/10914 Using sury packages or disabling file cache solves the issue

"},{"location":"Support/Poller%20Support/","title":"lnms device:poll","text":"

This document will explain how to use lnms device:poll to debug issues or manually running to process data.

"},{"location":"Support/Poller%20Support/#command-options","title":"Command options","text":"
Description:\n  Poll data from device(s) as defined by discovery\n\nUsage:\n  device:poll [options] [--] <device spec>\n\nArguments:\n  device spec            Device spec to poll: device_id, hostname, wildcard (*), odd, even, all\n\nOptions:\n  -m, --modules=MODULES  Specify single module to be run. Comma separate modules, submodules may be added with /\n  -x, --no-data          Do not update datastores (RRD, InfluxDB, etc)\n  -h, --help             Display help for the given command. When no command is given display help for the list command\n  -q, --quiet            Do not output any message\n  -V, --version          Display this application version\n      --ansi|--no-ansi   Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction   Do not ask any interactive question\n      --env[=ENV]        The environment the command should run under\n  -v|vv|vvv, --verbose   Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n
"},{"location":"Support/Poller%20Support/#poller-wrapper","title":"Poller Wrapper","text":"

We have a poller-wrapper.py script by Job Snijders. This script is currently the default.

If you need to debug the output of poller-wrapper.py then you can add -d to the end of the command - it is NOT recommended to do this in cron.

"},{"location":"Support/Poller%20Support/#poller-config","title":"Poller config","text":"

These are the default poller config items. You can globally disable a module by setting it to 0. If you just want to disable it for one device then you can do this within the WebUI Device -> Edit -> Modules.

poller/poller_modules

lnms config:set poller_modules.unix-agent false\nlnms config:set poller_modules.os true\nlnms config:set poller_modules.ipmi true\nlnms config:set poller_modules.sensors true\nlnms config:set poller_modules.processors true\nlnms config:set poller_modules.mempools true\nlnms config:set poller_modules.storage true\nlnms config:set poller_modules.netstats true\nlnms config:set poller_modules.hr-mib true\nlnms config:set poller_modules.ucd-mib true\nlnms config:set poller_modules.ipSystemStats true\nlnms config:set poller_modules.ports true\nlnms config:set poller_modules.nac false\nlnms config:set poller_modules.bgp-peers true\nlnms config:set poller_modules.junose-atm-vp false\nlnms config:set poller_modules.printer-supplies false\nlnms config:set poller_modules.ucd-diskio true\nlnms config:set poller_modules.wireless true\nlnms config:set poller_modules.ospf true\nlnms config:set poller_modules.cisco-ipsec-flow-monitor false\nlnms config:set poller_modules.cisco-remote-access-monitor false\nlnms config:set poller_modules.cisco-cef false\nlnms config:set poller_modules.slas false\nlnms config:set poller_modules.cisco-mac-accounting false\nlnms config:set poller_modules.cipsec-tunnels false\nlnms config:set poller_modules.cisco-ace-loadbalancer false\nlnms config:set poller_modules.cisco-ace-serverfarms false\nlnms config:set poller_modules.cisco-asa-firewall false\nlnms config:set poller_modules.cisco-voice false\nlnms config:set poller_modules.cisco-cbqos false\nlnms config:set poller_modules.cisco-otv false\nlnms config:set poller_modules.cisco-vpdn false\nlnms config:set poller_modules.netscaler-vsvr false\nlnms config:set poller_modules.aruba-controller false\nlnms config:set poller_modules.entity-physical true\nlnms config:set poller_modules.entity-state false\nlnms config:set poller_modules.applications true\nlnms config:set poller_modules.availability true\nlnms config:set poller_modules.stp true\nlnms config:set poller_modules.vminfo false\nlnms config:set poller_modules.ntp true\nlnms config:set poller_modules.services true\nlnms config:set poller_modules.loadbalancers false\nlnms config:set poller_modules.mef false\nlnms config:set poller_modules.mef false\n
"},{"location":"Support/Poller%20Support/#os-based-poller-config","title":"OS based Poller config","text":"

You can enable or disable modules for a specific OS by add corresponding line in config.php OS based settings have preference over global. Device based settings have preference over all others

Poller performance improvement can be achieved by deactivating all modules that are not supported by specific OS.

E.g. to deactivate spanning tree but activate unix-agent module for linux OS

poller/poller_modules

lnms config:set os.linux.poller_modules.stp false\nlnms config:set os.linux.poller_modules.unix-agent true\n
"},{"location":"Support/Poller%20Support/#poller-modules","title":"Poller modules","text":"

unix-agent: Enable the check_mk agent for external support for applications.

system: Provides information on some common items like uptime, sysDescr and sysContact.

os: Os detection. This module will pick up the OS of the device.

ipmi: Enables support for IPMI if login details have been provided for IPMI.

sensors: Sensor detection such as Temperature, Humidity, Voltages + More.

processors: Processor support for devices.

mempools: Memory detection support for devices.

storage: Storage detection for hard disks

netstats: Statistics for IP, TCP, UDP, ICMP and SNMP.

hr-mib: Host resource support.

ucd-mib: Support for CPU, Memory and Load.

ipSystemStats: IP statistics for device.

ports: This module will detect all ports on a device excluding ones configured to be ignored by config options.

xdsl: This module will collect more metrics for xdsl interfaces.

nac: Network Access Control (NAC) or 802.1X support.

bgp-peers: BGP detection and support.

junose-atm-vp: Juniper ATM support.

printer-supplies: Toner levels support.

ucd-diskio: Disk I/O support.

wifi: WiFi Support for those devices with support.

ospf: OSPF Support.

cisco-ipsec-flow-monitor: IPSec statistics support.

cisco-remote-access-monitor: Cisco remote access support.

cisco-cef: CEF detection and support.

slas: SLA detection and support.

cisco-mac-accounting: MAC Address account support.

cipsec-tunnels: IPSec tunnel support.

cisco-ace-loadbalancer: Cisco ACE Support.

cisco-ace-serverfarms: Cisco ACE Support.

netscaler-vsvr: Netscaler support.

aruba-controller: Aruba wireless controller support.

entity-physical: Module to pick up the devices hardware support.

applications: Device application support.

availability: Device Availability Calculation.

cisco-asa-firewall: Cisco ASA firewall support.

"},{"location":"Support/Poller%20Support/#running","title":"Running","text":"

Here are some examples of running poller from within your install directory.

lnms device:poll localhost\n\nlnms device:poll localhost -m ports\n
"},{"location":"Support/Poller%20Support/#debugging","title":"Debugging","text":"

To provide debugging output you will need to run the poller process with the -vv flag. You can do this either against all modules, single or multiple modules:

All Modules

lnms device:poll localhost -vv\n

Single Module

lnms device:poll localhost -m ports -vv\n

Multiple Modules

lnms device:poll localhost -m ports,entity-physical -vv\n

Using -vv shouldn't output much sensitive information, -vvv will so it is then advisable to sanitise the output before pasting it somewhere as the debug output will contain snmp details amongst other items including port descriptions.

The output will contain:

DB Updates

RRD Updates

SNMP Response

"},{"location":"Support/Remote-Monitoring-VPN/","title":"Remote monitoring using tinc VPN","text":"

This article describes how to use tinc to connect several remote sites and their subnets to your central monitoring server. This will let you connect to devices on remote private IP ranges through one gateway on each site, routing them securely back to your LibreNMS installation.

"},{"location":"Support/Remote-Monitoring-VPN/#configuring-the-monitoring-server","title":"Configuring the monitoring server","text":"

tinc should be available on nearly all Linux distributions via package management. If you are running something different, just take a look at tinc's homepage to find an appropriate version for your operating system: https://www.tinc-vpn.org/download/

I am going to describe the setup for Debian-based systems, but there are virtually no differences for e.g. CentOS or similar.

  • First make sure your firewall accepts connections on port 655 UDP and TCP.
  • Then install tinc via apt-get install tinc.
  • Create the following directory structure to hold all your configuration files: mkdir -p /etc/tinc/myvpn/hosts \"myvpn\" is your VPN network's name and can be chosen freely.
  • Create your main configuration file: vim /etc/tinc/myvpn/tinc.conf
Name = monitoring\nAddressFamily = ipv4\nDevice = /dev/net/tun\n
  • Next we need network up- and down scripts to define a few network settings for inside our VPN: vim /etc/tinc/myvpn/tinc-up
#!/bin/sh\nifconfig $INTERFACE 10.6.1.1 netmask 255.255.255.0\nip route add 10.6.1.1/24 dev $INTERFACE\nip route add 10.0.0.0/22 dev $INTERFACE\nip route add 10.100.0.0/22 dev $INTERFACE\nip route add 10.200.0.0/22 dev $INTERFACE\n
  • In this example we have 10.6.1.1 as the VPN IP address for the monitoring server on a /24 subnet. $INTERFACE will be automatically substituted with the name of the VPN, \"myvpn\" in this case. Then we have a route for the VPN subnet, so we can reach other sites via their VPN address. The last 3 lines designate the remote subnets. In the example I want to reach devices on three different remote private /22 subnets and be able to monitor devices on them from this server, so I set up routes for each of those remote sites in my tinc-up script.

  • The tinc-down script is relatively simple as it just removes the custom interface, which should get rid of the routes as well: vim /etc/tinc/myvpn/tinc-down

#!/bin/sh\nifconfig $INTERFACE down\n
  • Make sure your scripts scan be executed: chmod +x /etc/tinc/myvpn/tinc-*
  • As a last step we need a host configuration file. This should be named the same as the \"Name\" you defined in tinc.conf: vim /etc/tinc/myvpn/hosts/monitoring
Subnet = 10.6.1.1/32\n

On the monitoring server we will just fill in the subnet and not define its external IP address to make sure it listens on all available external interfaces.

  • It's time to use tinc to create our key-pair: tincd -n myvpn -K
  • Now the file /etc/tinc/myvpn/hosts/monitoring should have an RSA public key appended to it and your private key should reside in /etc/tinc/myvpn/rsa_key.priv.
  • To make sure that the connection will be restored after each reboot, you can add your VPN name to /etc/tinc/nets.boot.
  • Now you can start tinc with tincd -n myvpn and it will listen for your remote sites to connect to it.
"},{"location":"Support/Remote-Monitoring-VPN/#remote-site-configuration","title":"Remote site configuration","text":"

Essentially the same steps as for your central monitoring server apply for all remote gateway devices. These can be routers, or just any computer or VM running on the remote subnet, able to reach the internet with the ability to forward IP packets externally.

  • Install tinc
  • Create directory structure: mkdir -p /etc/tinc/myvpn/hosts
  • Create main configuration: vim /etc/tinc/myvpn/tinc.conf
Name = remote1\nAddressFamily = ipv4\nDevice = /dev/net/tun\nConnectTo = monitoring\n
  • Create up script: vim /etc/tinc/myvpn/tinc-up
#!/bin/sh\nifconfig $INTERFACE 10.6.1.2 netmask 255.255.255.0\nip route add 10.6.1.2/32 dev $INTERFACE\n
  • Create down script: vim /etc/tinc/myvpn/tinc-down
#!/bin/sh\nifconfig $INTERFACE down\n
  • Make executable: chmod +x /etc/tinc/myvpn/tinc*
  • Create device configuration: vim /etc/tinc/myvpn/hosts/remote1
Address = 198.51.100.2\nSubnet = 10.0.0.0/22\n

This defines the device IP address outside of the VPN and the subnet it will expose.

  • Copy over the monitoring server's host configuration (including the embedded public key) and add it's external IP address: vim /etc/tinc/myvpn/hosts/monitoring
Address = 203.0.113.6\nSubnet = 10.6.1.1/32\n\n-----BEGIN RSA PUBLIC KEY-----\nVeDyaqhKd4o2Fz...\n
  • Generate this device's keys: tincd -n myvpn -K
  • Copy over this devices host file including the embedded public key to your monitoring server.
  • Add the name for the VPN to/etc/tinc/nets.boot if you want to autostart the connection upon reboot.
  • Start tinc: tincd -n myvpn

These steps can basically be repeated for every remote site just choosing different names and other internal IP addresses. In my case I connected 3 remote sites running behind Ubiquiti EdgeRouters. Since those devices let me install software through Debian's package management it was very easy to set up. Just create the necessary configuration files and network scripts on each device and distribute the host configurations including the public keys to each device that will actively connect back.

Now you can add all devices you want to monitor in LibreNMS using their internal IP address on the remote subnets or using some form of name resolution. I opted to declare the most important devices in my /etc/hosts file on the monitoring server.

As an added bonus tinc is a mesh VPN, so in theory you could specify several \"ConnectTo\" on each device and they should hold connections even if one network path goes down.

"},{"location":"Support/SNMP-Configuration-Examples/","title":"SNMP configuration examples","text":""},{"location":"Support/SNMP-Configuration-Examples/#devices","title":"Devices","text":""},{"location":"Support/SNMP-Configuration-Examples/#cisco","title":"Cisco","text":""},{"location":"Support/SNMP-Configuration-Examples/#adaptive-security-appliance-asa","title":"Adaptive Security Appliance (ASA)","text":"

ASDM

  1. Launch ASDM and connect to your device
  2. Go to Configuration > Management Access > SNMP
  3. Add your community string
  4. Add in the \"SNMP Host Access List\" section your LibreNMS server IP address
  5. Click Apply and Save

CLI

# SNMPv2c\n\nsnmp-server community <YOUR-COMMUNITY>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\nsnmp-server host <INTERFACE> <LIBRENMS-IP> poll community <YOUR-COMMUNITY> version 2c\n\n# SNMPv3\n\nsnmp-server group <GROUP-NAME> v3 priv\nsnmp-server user <USER-NAME> <GROUP-NAME> v3 auth sha <AUTH-PASSWORD> priv aes 128 <PRIV-PASSWORD>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\nsnmp-server host <INTERFACE> <LIBRENMS-IP> poll version 3 <USER-NAME>\n

Note: If the device is unable to find the SNMP user, reboot the ASA. Once rebooted, continue the steps as normal.

"},{"location":"Support/SNMP-Configuration-Examples/#ios-ios-xe","title":"IOS / IOS XE","text":"
# SNMPv2c\n\nsnmp-server community <YOUR-COMMUNITY> RO\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n\n# SNMPv3\n\nsnmp-server group <GROUP-NAME> v3 priv\nsnmp-server user <USER-NAME> <GROUP-NAME> v3 auth sha <AUTH-PASSWORD> priv aes 128 <PRIV-PASSWORD>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n\n# Note: The following is also required if using SNMPv3 and you want to populate the FDB table, STP info and others.\n\nsnmp-server group <GROUP-NAME> v3 priv context vlan- match prefix\n

Note: If the device is unable to find the SNMP user, reboot the ASA. Once rebooted, continue the steps as normal.

"},{"location":"Support/SNMP-Configuration-Examples/#nx-os","title":"NX-OS","text":"
# SNMPv2c\n\nsnmp-server community <YOUR-COMMUNITY> RO\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n\n# SNMPv3\n\nsnmp-server user <USER-NAME> <GROUP-NAME> v3 auth sha <AUTH-PASSWORD> priv aes 128 <PRIV-PASSWORD>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n
"},{"location":"Support/SNMP-Configuration-Examples/#wireless-lan-controller-wlc","title":"Wireless LAN Controller (WLC)","text":"
  1. Access the web admin page and log in
  2. If you are running version 8.1 and later, on the new dashboard click \"Advanced\"
  3. Go to management Tab
  4. On SNMP sub-menu, select \"Communities\"
  5. Click \"New...\"
  6. Add your community name and leave IP addresses empty
  7. Click Apply and Save
"},{"location":"Support/SNMP-Configuration-Examples/#eaton","title":"Eaton","text":""},{"location":"Support/SNMP-Configuration-Examples/#network-card-ms","title":"Network Card-MS","text":"
  1. Connect to the Web UI of the device
  2. Upgrade to the latest available manufacturer firmware which applies to your hardware revision. Refer to the release notes. For devices which can use the Lx releases, do install LD.
  3. After rebooting the card (safe for connected load), configure Network, System and Access Control. Save config for each step.
  4. Configure SNMP. The device defaults to both SNMP v1 and v3 enabled, with default credentials. Disable what you do not need. SNMP v3 works, but uses MD5/DES. You may have to add another section to your SNMP credentials table in LibreNMS. Save.
"},{"location":"Support/SNMP-Configuration-Examples/#hpe-3par","title":"HPE / 3PAR","text":""},{"location":"Support/SNMP-Configuration-Examples/#comware","title":"Comware","text":"

SNMPv2c

snmp-agent community read <YOUR-COMMUNITY>\nsnmp-agent sys-info contact <YOUR-CONTACT>\nsnmp-agent sys-info location <YOUR-LOCATION>\nsnmp-agent sys-info version all\nsnmp-agent packet max-size 6000\n

packet max-size is required for some walks to complete, but the path must support fragmentation.

SNMPv3

snmp-agent mib-view excluded ExcludeAll snmp\nsnmp-agent group v3 V3ROGroup privacy read-view ViewDefault write-view ExcludeAll\nsnmp-agent usm-user v3 <USER> V3ROGroup simple authentication-mode sha <AuthKey> privacy-mode aes128 <PrivacyKey>\nsnmp-agent sys-info contact <YOUR-CONTACT>\nsnmp-agent sys-info location <YOUR-LOCATION>\nsnmp-agent sys-info version v3\nundo snmp-agent sys-info version v1 v2c\nsnmp-agent packet max-size 6000\n

packet max-size is required for some walks to complete, but the path must support fragmentation.

"},{"location":"Support/SNMP-Configuration-Examples/#inform-os-32x","title":"Inform OS 3.2.x","text":"
  • Access the CLI
  • Add an SNMP Manager with your LibreNMS IP address:
addsnmpmgr <librenms ip>\n
  • Add your SNMP community:
setsnmppw <community>\n
"},{"location":"Support/SNMP-Configuration-Examples/#infoblox","title":"Infoblox","text":""},{"location":"Support/SNMP-Configuration-Examples/#nios-7x","title":"NIOS 7.x+","text":"
  1. Access the web admin page and log in
  2. Go to Grid tab > Grid Manager
  3. In the right menu select \"Grid properties\"
  4. Select \"SNMP\" menu
  5. Click \"Enable SNMPv1/SNMPv2 Queries\"
  6. Add your community
  7. Click Save & Close
"},{"location":"Support/SNMP-Configuration-Examples/#juniper","title":"Juniper","text":""},{"location":"Support/SNMP-Configuration-Examples/#junos-os","title":"Junos OS","text":"

for SNMPv1/v2c

set snmp description description\nset snmp location location\nset snmp contact contact\nset snmp community YOUR-COMMUNITY authorization read-only\n

for SNMPv3 (authPriv):

set snmp v3 usm local-engine user authpriv authentication-sha authentication-password YOUR_AUTH_SECRET\nset snmp v3 usm local-engine user authpriv privacy-aes128 privacy-password YOUR_PRIV_SECRET\nset snmp v3 vacm security-to-group security-model usm security-name authpriv group mysnmpv3\nset snmp v3 vacm access group mysnmpv3 default-context-prefix security-model any security-level authentication read-view mysnmpv3view\nset snmp v3 vacm access group mysnmpv3 default-context-prefix security-model any security-level privacy read-view mysnmpv3view\nset snmp view mysnmpv3view oid iso include\n
"},{"location":"Support/SNMP-Configuration-Examples/#mikrotik","title":"Mikrotik","text":""},{"location":"Support/SNMP-Configuration-Examples/#routeros-6x","title":"RouterOS 6.x","text":"

CLI SNMP v2 Configuration

/snmp community\nset [ find default=yes ] read-access=no\nadd addresses=<ALLOWED-SRC-IPs/NETMASK> name=<COMMUNITY>\n/snmp\nset contact=\"<NAME>\" enabled=yes engine-id=<ENGINE ID> location=\"<LOCALTION>\"\n
Notes:

  • About the snmp community commands:
    • The commands change the default snmp community. It is probably possible to create a new one instead.
    • specify the address and host (not network) netmask of the LibreNMS server. Example: 192.168.8.71/32
    • trap-version=2 must also be specified if some other trap-version has been set
    • trap-interfaces may also be used to limit the interfaces the router listens on
    • About the snmp command:
      • contact, engine-id and location are optional
      • trap-community is probably required if a new snmp community has been created.
    • CLI SNMP v3 Configuration for authPriv

      /snmp community\nadd name=\"<COMMUNITY>\" addresses=\"<ALLOWED-SRC-IPs/NETMASK>\"\nset \"<COMMUNITY>\" authentication-password=\"<AUTH_PASS>\" authentication-protocol=MD5\nset \"<COMMUNITY>\" encryption-password=\"<ENCRYP_PASS>\" encryption-protocol=AES\nset \"<COMMUNITY>\" read-access=yes write-access=no security=private\n#Disable public SNMP\nset public read-access=no write-access=no security=private\n/snmp\nset contact=\"<NAME>\" enabled=yes engine-id=\"<ENGINE ID>\" location=\"<LOCALTION>\"\n
      Notes:

      • Use password with length of min 8 chars

      Notes for both SNMP v2 and v3

      • In some cases of advanced routing one may need to set explicitly the source IP address from which the SNMP daemon will reply - /snmp set src-address=<SELF_IP_ADDRESS>
      "},{"location":"Support/SNMP-Configuration-Examples/#palo-alto","title":"Palo Alto","text":""},{"location":"Support/SNMP-Configuration-Examples/#panos-6x7x","title":"PANOS 6.x/7.x","text":"
      1. Access the web admin page and log in
      2. Go to Device tab > Setup
      3. Go to the sub-tab \"Operations\"
      4. Click \"SNMP Setup\"
      5. Enter your SNMP community and then click \"OK\"
      6. Click Apply

      Note that you need to allow SNMP on the needed interfaces. To do that you need to create a network \"Interface Mgmt\" profile for standard interface and allow SNMP under \"Device > Management > Management Interface Settings\" for out of band management interface.

      One may also configure SNMP from the command line, which is useful when you need to configure more than one firewall for SNMP monitoring. Log into the firewall(s) via ssh, and perform these commands for basic SNMPv3 configuration:

      username@devicename> configure\nusername@devicename# set deviceconfig system service disable-snmp no\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 views pa view iso oid 1.3.6.1\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 views pa view iso option include\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 views pa view iso mask 0xf0\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 users authpriv authpwd YOUR_AUTH_SECRET\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 users authpriv privpwd YOUR_PRIV_SECRET\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 users authpriv view pa\nusername@devicename# set deviceconfig system snmp-setting snmp-system location \"Yourcity, Yourcountry [60.4,5.31]\"\nusername@devicename# set deviceconfig system snmp-setting snmp-system contact noc@your.org\nusername@devicename# commit\nusername@devicename# exit\n
      "},{"location":"Support/SNMP-Configuration-Examples/#ubiquiti","title":"Ubiquiti","text":""},{"location":"Support/SNMP-Configuration-Examples/#edgeos","title":"EdgeOs","text":"

      If you use the HTTP interface: 1. Access the legacy web admin page and log in 1. Go to System > Advanced Configuration 1. Go to the sub-tab \"SNMP\" > \"Community\" 1. Click \"Add Community Group\" 1. Enter your SNMP community, ip address and click submit 1. Go to System > Summary 1. Go to the sub-tab \"Description\" 1. Enter your System Name, System Location and System Contact. 1. Click submit 1. Click \"Save Configuration\"

      If you use CLI:

      username@devicename> enable\nusername@devicename# configure\nusername@devicename (Config)# snmp-server community \"public\" ro\nusername@devicename (Config)# snmp-server sysname \"devicename\"\nusername@devicename (Config)# snmp-server contact \"noc@example.com\"\nusername@devicename (Config)# exit\nusername@devicename# write memory\n

      "},{"location":"Support/SNMP-Configuration-Examples/#vmware","title":"VMware","text":""},{"location":"Support/SNMP-Configuration-Examples/#esxesxi-5x6x","title":"ESX/ESXi 5.x/6.x","text":"

      Log on to your ESX server by means of ssh. You may have to enable the ssh service in the GUI first. From the CLI, execute the following commands:

      esxcli system snmp set --authentication SHA1\nesxcli system snmp set --privacy AES128\nesxcli system snmp hash --auth-hash YOUR_AUTH_SECRET --priv-hash YOUR_PRIV_SECRET --raw-secret\n

      This command produces output like this

         Authhash: f3d8982fc28e8d1346c26eee49eb2c4a5950c934\n   Privhash: 0596ab30b315576a4e9f7d7bde65bf49b749e335\n

      Now define a SNMPv3 user:

      esxcli system snmp set --users <username>/f3d8982fc28e8d1346c26eee49eb2c4a5950c934/0596ab30b315576a4e9f7d7bde65bf49b749e335/priv\nesxcli system snmp set -L \"Yourcity, Yourcountry [60.4,5.3]\"\nesxcli system snmp set -C noc@your.org\nesxcli system snmp set --enable true\n

      Note: In case of snmp timeouts, disable the firewall with esxcli network firewall set --enabled false If snmp timeouts still occur with firewall disabled, migrate VMs if needed and reboot ESXi host.

      "},{"location":"Support/SNMP-Configuration-Examples/#vcenter-6x","title":"VCenter 6.x","text":"

      Log on to your ESX server by means of ssh. You may have to enable the ssh service in the GUI first. From the CLI, execute the following commands:

      snmp.set --authentication SHA1\nsnmp.set --privacy AES128\nsnmp.hash --auth_hash YOUR_AUTH_SECRET --priv_hash YOUR_PRIV_SECRET --raw_secret true\n

      This command produces output like this

         Privhash: 0596ab30b315576a4e9f7d7bde65bf49b749e335\n   Authhash: f3d8982fc28e8d1346c26eee49eb2c4a5950c934\n

      Now define a SNMPv3 user:

      snmp.set --users authpriv/f3d8982fc28e8d1346c26eee49eb2c4a5950c934/0596ab30b315576a4e9f7d7bde65bf49b749e335/priv\nsnmp.enable\n
      "},{"location":"Support/SNMP-Configuration-Examples/#operating-systems","title":"Operating systems","text":""},{"location":"Support/SNMP-Configuration-Examples/#linux-snmpd-v2","title":"Linux (snmpd v2)","text":"

      Replace your snmpd.conf file by the example below and edit it with appropriate community in \"RANDOMSTRINGGOESHERE\".

      vi /etc/snmp/snmpd.conf\n
      # Change RANDOMSTRINGGOESHERE to your preferred SNMP community string\ncom2sec readonly  default         RANDOMSTRINGGOESHERE\n\ngroup MyROGroup v2c        readonly\nview all    included  .1                               80\naccess MyROGroup \"\"      any       noauth    exact  all    none   none\n\nsyslocation Rack, Room, Building, City, Country [GPSX,Y]\nsyscontact Your Name <your@email.address>\n\n#Distro Detection\nextend distro /usr/bin/distro\n#Hardware Detection (uncomment to enable)\n#extend hardware '/bin/cat /sys/devices/virtual/dmi/id/product_name'\n#extend manufacturer '/bin/cat /sys/devices/virtual/dmi/id/sys_vendor'\n#extend serial '/bin/cat /sys/devices/virtual/dmi/id/product_serial'\n

      NOTE: On some systems the snmpd is running as its own user, which means it can't read /sys/devices/virtual/dmi/id/product_serial which is mode 0400. One solution is to include @reboot chmod 444 /sys/devices/virtual/dmi/id/product_serial in the crontab for root or equivalent.

      Non-x86 or SMBIOS-based systems, such as ARM-based Raspberry Pi units should query device tree locations for this metadata, for example:

      extend hardware '/bin/cat /sys/firmware/devicetree/base/model'\nextend serial '/bin/cat /sys/firmware/devicetree/base/serial-number'\n

      The LibreNMS server include a copy of this example here:

      /opt/librenms/snmpd.conf.example\n

      The binary /usr/bin/distro must be copied from the original source repository:

      curl -o /usr/bin/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro\nchmod +x /usr/bin/distro\n
      "},{"location":"Support/SNMP-Configuration-Examples/#linux-snmpd-v3","title":"Linux (snmpd v3)","text":"

      Go to /etc/snmp/snmpd.conf

      Open the file in vi or nano /etc/snmp/snmpd.conf and add the following line to create SNMPV3 User (replace username and passwords with your own):

      createUser authPrivUser SHA \"authPassword\" AES \"privPassword\"\n

      Make sure the agent listens to all interfaces by adding the following line inside snmpd.conf:

      agentAddress udp:161,udp6:161\n

      This line simply means listen to connections across all interfaces IPv4 and IPv6 respectively

      Uncomment and change the following line to give read access to the username created above (rouser is what LibreNMS uses) :

      #rouser authPrivUser priv\n

      Change the following details inside snmpd.conf

      syslocation Rack, Room, Building, City, Country [GPSX,Y]\nsyscontact Your Name <your@email.address>\n

      Save and exit the file

      "},{"location":"Support/SNMP-Configuration-Examples/#restart-the-snmpd-service","title":"Restart the snmpd service","text":""},{"location":"Support/SNMP-Configuration-Examples/#centos-6-red-hat-6","title":"CentOS 6 / Red hat 6","text":"
      service snmpd restart\n
      "},{"location":"Support/SNMP-Configuration-Examples/#centos-7-red-hat-7","title":"CentOS 7 / Red hat 7","text":"
      systemctl restart snmpd\n

      Add SNMP to Firewalld

      firewall-cmd --zone=public --permanent --add-service=snmp\nfirewall-cmd --reload\n
      "},{"location":"Support/SNMP-Configuration-Examples/#ubuntu","title":"Ubuntu","text":"
      service snmpd restart\n
      "},{"location":"Support/SNMP-Configuration-Examples/#arch-linux-snmpd-v2","title":"Arch Linux (snmpd v2)","text":"
      1. Install SNMP Package pacman -S net-snmp
      2. create SNMP folder mkdir /etc/snmp/
      3. set community echo rocommunity read_only_community_string >> /etc/snmp/snmpd.conf
      4. set contact echo syscontact Firstname Lastname >> /etc/snmp/snmpd.conf
      5. set location echo syslocation L69 4RX >> /etc/snmp/snmpd.conf
      6. enable startup systemctl enable snmpd.service
      7. start snmp systemctl restart snmpd.service
      "},{"location":"Support/SNMP-Configuration-Examples/#windows-server-2008-r2","title":"Windows Server 2008 R2","text":"
      1. Log in to your Windows Server 2008 R2
      2. Start \"Server Manager\" under \"Administrative Tools\"
      3. Click \"Features\" and then click \"Add Feature\"
      4. Check (if not checked) \"SNMP Service\", click \"Next\" until \"Install\"
      5. Start \"Services\" under \"Administrative Tools\"
      6. Edit \"SNMP Service\" properties
      7. Go to the security tab
      8. In \"Accepted community name\" click \"Add\" to add your community string and permission
      9. In \"Accept SNMP packets from these hosts\" click \"Add\" and add your LibreNMS server IP address
      10. Validate change by clicking \"Apply\"
      "},{"location":"Support/SNMP-Configuration-Examples/#windows-server-2012-r2-and-newer","title":"Windows Server 2012 R2 and newer","text":""},{"location":"Support/SNMP-Configuration-Examples/#gui","title":"GUI","text":"
      1. Log in to your Windows Server 2012 R2 or newer
      2. Start \"Server Manager\" under \"Administrative Tools\"
      3. Click \"Manage\" and then \"Add Roles and Features\"
      4. Continue by pressing \"Next\" to the \"Features\" menu
      5. Install (if not installed) \"SNMP Service\"
      6. Start \"Services\" under \"Administrative Tools\"
      7. Edit \"SNMP Service\" properties
      8. Go to the security tab
      9. In \"Accepted community name\" click \"Add\" to add your community string and permission
      10. In \"Accept SNMP packets from these hosts\" click \"Add\" and add your LibreNMS server IP address
      11. Validate change by clicking \"Apply\"
      "},{"location":"Support/SNMP-Configuration-Examples/#powershell","title":"PowerShell","text":"

      The following example will install SNMP, set the Librenms IP and set a read only community string. Replace $IP and $communitystring with your values.

      Install-WindowsFeature -Name 'SNMP-Service','RSAT-SNMP'\nNew-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\services\\SNMP\\Parameters\\PermittedManagers\"  -Name 2 -Value $IP\nNew-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\services\\SNMP\\Parameters\\ValidCommunities\"  -Name $communitystring -Value 4\n

      Note: SNMPv3 can be supported on Windows platforms with the use of Net-SNMP.

      "},{"location":"Support/SNMP-Configuration-Examples/#mac-osx","title":"Mac OSX","text":"

      Step 1: sudo nano /etc/snmp/snmpd.conf

      #Allow read-access with the following SNMP Community String:\nrocommunity public\n\n# all other settings are optional but recommended.\n\n# Location of the device\nsyslocation data centre A\n\n# Human Contact for the device\nsyscontact SysAdmin\n\n# System Name of the device\nsysName SystemName\n\n# the system OID for this device. This is optional but recommended,\n# to identify this as a MAC OS system.\nsysobjectid 1.3.6.1.4.1.8072.3.2.16\n

      Step 2:

      sudo launchctl load -w /System/Library/LaunchDaemons/org.net-snmp.snmpd.plist\n
      "},{"location":"Support/Device-Notes/AsuswrtMerlin/","title":"Asuswrt-Merlin","text":"

      To use Wireless Sensors on AsuswrtMerlin, an agent of sorts is required. The purpose of the agent is to execute on the client (AsuswrtMerlin) side, to ensure that the needed Wireless Sensor information is returned for SNMP queries (from LibreNMS).

      "},{"location":"Support/Device-Notes/AsuswrtMerlin/#installation","title":"Installation","text":""},{"location":"Support/Device-Notes/AsuswrtMerlin/#asuswrtmerlin","title":"AsuswrtMerlin","text":"

      Two items are required on the AsuswrtMerlin side - scripts to generate the necessary information (for SNMP replies), and an SNMP extend configuration update (to return the information vs. the expected query).

      1: Install the scripts:

      Copy the scripts from librenms-agent/snmp/Openwrt - preferably inside /etc/librenms on AsuswrtMerlin (and add this directory to /etc/sysupgrade.conf, to survive firmware updates).

      The only file that needs to be edited is wlInterfaces.txt, which is a mapping from the wireless interfaces, to the desired display name in LibreNMS. For example,

      wlan0,wl-2.4G\nwlan1,wl-5.0G\n

      2: Update the AsuswrtMerlin SNMP configuration, adding extend support for the Wireless Sensor queries:

      vi /etc/config/snmpd, adding the following entries (assuming the scripts are installed in /etc/librenms, and are executable), and update the network interfaces as needed to match the hardware,

      config extend\n        option name     interfaces\n        option prog     \"/bin/cat /etc/librenms/wlInterfaces.txt\"\nconfig extend\n        option name     clients-wlan0\n        option prog     \"/etc/librenms/wlClients.sh wlan0\"\nconfig extend\n        option name     clients-wlan1\n        option prog     \"/etc/librenms/wlClients.sh wlan1\"\nconfig extend\n        option name     clients-wlan\n        option prog     \"/etc/librenms/wlClients.sh\"\nconfig extend\n        option name     frequency-wlan0\n        option prog     \"/etc/librenms/wlFrequency.sh wlan0\"\nconfig extend\n        option name     frequency-wlan1\n        option prog     \"/etc/librenms/wlFrequency.sh wlan1\"\nconfig extend\n        option name     rate-tx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx min\"\nconfig extend\n        option name     rate-tx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx avg\"\nconfig extend\n        option name     rate-tx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx max\"\nconfig extend\n        option name     rate-tx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx min\"\nconfig extend\n        option name     rate-tx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx avg\"\nconfig extend\n        option name     rate-tx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx max\"\nconfig extend\n        option name     rate-rx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx min\"\nconfig extend\n        option name     rate-rx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx avg\"\nconfig extend\n        option name     rate-rx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx max\"\nconfig extend\n        option name     rate-rx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx min\"\nconfig extend\n        option name     rate-rx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx avg\"\nconfig extend\n        option name     rate-rx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx max\"\nconfig extend\n        option name     noise-floor-wlan0\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan0\"\nconfig extend\n        option name     noise-floor-wlan1\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan1\"\nconfig extend\n        option name     snr-wlan0-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 min\"\nconfig extend\n        option name     snr-wlan0-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 avg\"\nconfig extend\n        option name     snr-wlan0-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 max\"\nconfig extend\n        option name     snr-wlan1-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 min\"\nconfig extend\n        option name     snr-wlan1-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 avg\"\nconfig extend\n        option name     snr-wlan1-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 max\"\n

      NOTE, any of the scripts above can be tested simply by running the corresponding command.

      NOTE, to check the output data from any of these extensions, on the LibreNMS machine, run (for example),

      snmpwalk -v 2c -c public -Osqnv <openwrt-host> 'NET-SNMP-EXTEND-MIB::nsExtendOutputFull.\"frequency-wlan0\"'

      NOTE, on the LibreNMS machine, ensure that snmp-mibs-downloader is installed.

      NOTE, on the AsuswrtMerlin machine, ensure that distro is installed (i.e. that the OS is correctly detected!).

      3: Restart the snmp service on AsuswrtMerlin:

      service snmpd restart

      And then wait for discovery and polling on LibreNMS!

      "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/","title":"Carel pCOweb Devices","text":"

      The pCOWeb card is used to interface the pCO system to networks that use the HVAC protocols based on the Ethernet physical standard such as SNMP. The problem with this card is that the implementation is based on the final manufacturer of the HVAC (Heating, Ventilation and Air Conditioning) and not based on a standard given by Carel. So each pCOweb card has a different configuration that needs a different MIB depending on the manufacturers implementation.

      The main problem is that LibreNMS will by default discover this card as pCOweb and not as your real manufacturer like it should. A solution was found to bypass this issue, but it's LibreNMS independent and you need to first configure your pCOWeb through the admin interface.

      "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#accessing-the-pcoweb-card","title":"Accessing the pCOWeb card","text":"

      Log on to the configuration page of the pCOWeb card. The pCOWeb interface is not always found when accessing the ip directly but rather a subdirectory. If you cant directly reach the configuration page try <ip address>/config. The default username and password is admin/fadmin. Modern browsers require you to enter this 2 or 3 times.

      "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#configuring-the-pcoweb-card-snmp-for-librenms","title":"Configuring the pCOweb card SNMP for LibreNMS","text":"

      First you need to configure your SNMP card using the admin interface. An SNMP tab in the configuration menu leaves you the choice to choose a System OID and a Enterprise OID. This is a little tricky but based on this information we defined a \"standard\" for all implementation of Carel products with LibreNMS.

      The base Carel OID is 1.3.6.1.4.1.9839. To this OID we will add the final manufacturer Enterprise OID. You can find all enterprise OID following this link. This will allow us to create a specific support for this device. Librenms uses this value to detect which HVAC device is connected to the pCOWeb card.

      Example for the Rittal IT Chiller that uses a pCOweb card:

      1. Base Carel OID : 1.3.6.1.4.1.9839
      2. Rittal (the manufacturer) base enterprise OID : 2606
      3. Adding value to identify this device in LibreNMS : 1
      4. Complete System OID for a Rittal Chiller using a Carel pCOweb card: 1.3.6.1.4.1.9839.2606.1
      5. Use 9839 as Enterprise OID

      The way this works is that the pCOWeb card pretends to be another device. In reality the pCOWeb card just inserts the \"enterprise OID\" in place of the vendor id in the OID.

      In the table below you can find the values needed for devices which are already supported.

      "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#supported-devices","title":"Supported devices","text":"

      LibreNMS is ready for the devices listed in this table. You only need to configure your pCOweb card with the accorded System OID and Enterprise OID:

      Manufacturer Description System OID Enterprise OID Rittal IT Chiller 1.3.6.1.4.1.9839.2606.1 9839 Rittal LCP DX 3311 1.3.6.1.4.1.9839.2606.3311 9839.2606"},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#unsupported-devices","title":"Unsupported devices","text":"

      After constructing the correct System OID for your SNMP card, you can start the LibreNMS new OS implementation and use this new OID as sysObjectID for the YAML definition file.

      "},{"location":"Support/Device-Notes/Fortigate/","title":"Fortigate","text":"

      To gather Port IP info & routing info for Fortigates, disable the append-index feature. This feature appends VDOM to the index, breaking standard MIBs.

      config system snmp sysinfo\n    set append-index disable\nend\n
      https://docs.fortinet.com/document/fortigate/7.2.0/new-features/742119/enabling-the-index-extension-7-2-8

      "},{"location":"Support/Device-Notes/Openwrt/","title":"OpenWRT","text":"

      To use Wireless Sensors on Openwrt, an agent of sorts is required. The purpose of the agent is to execute on the client (Openwrt) side, to ensure that the needed Wireless Sensor information is returned for SNMP queries (from LibreNMS).

      "},{"location":"Support/Device-Notes/Openwrt/#installation","title":"Installation","text":""},{"location":"Support/Device-Notes/Openwrt/#openwrt","title":"Openwrt","text":"

      Two items are required on the Openwrt side - scripts to generate the necessary information (for SNMP replies), and an SNMP extend configuration update (to return the information vs. the expected query).

      1: Install the scripts:

      Copy the scripts from librenms-agent repository - preferably inside /etc/librenms on Openwrt (and add this directory to /etc/sysupgrade.conf, to survive firmware updates):

      wget -O /etc/librenms/wlClients.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlClients.sh\nwget -O /etc/librenms/wlFrequency.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlFrequency.sh\nwget -O /etc/librenms/wlInterfaces.txt https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlInterfaces.txt\nwget -O /etc/librenms/wlNoiseFloor.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlNoiseFloor.sh\nwget -O /etc/librenms/wlRate.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlRate.sh\nwget -O /etc/librenms/wlSNR.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlSNR.sh\nwget -O /etc/librenms/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro\nchmod +x /etc/librenms/*.sh\nchmod +x /etc/librenms/distro\n

      The only file that needs to be edited is wlInterfaces.txt, which is a mapping from the wireless interfaces, to the desired display name in LibreNMS. For example,

      wlan0,wl-2.4G\nwlan1,wl-5.0G\n

      2: Update the Openwrt SNMP configuration, adding extend support for the OS detection and the Wireless Sensor queries:

      vi /etc/config/snmpd, adding the following entries (assuming the scripts are installed in /etc/librenms, and are executable), and update the network interfaces as needed to match the hardware,

      config extend\n        option name distro\n        option prog '/etc/librenms/distro'\nconfig extend\n        option name hardware\n        option prog '/bin/cat'\n        option args '/sys/firmware/devicetree/base/model'\nconfig extend\n        option name     interfaces\n        option prog     \"/bin/cat /etc/librenms/wlInterfaces.txt\"\nconfig extend\n        option name     clients-wlan0\n        option prog     \"/etc/librenms/wlClients.sh wlan0\"\nconfig extend\n        option name     clients-wlan1\n        option prog     \"/etc/librenms/wlClients.sh wlan1\"\nconfig extend\n        option name     clients-wlan\n        option prog     \"/etc/librenms/wlClients.sh\"\nconfig extend\n        option name     frequency-wlan0\n        option prog     \"/etc/librenms/wlFrequency.sh wlan0\"\nconfig extend\n        option name     frequency-wlan1\n        option prog     \"/etc/librenms/wlFrequency.sh wlan1\"\nconfig extend\n        option name     rate-tx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx min\"\nconfig extend\n        option name     rate-tx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx avg\"\nconfig extend\n        option name     rate-tx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx max\"\nconfig extend\n        option name     rate-tx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx min\"\nconfig extend\n        option name     rate-tx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx avg\"\nconfig extend\n        option name     rate-tx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx max\"\nconfig extend\n        option name     rate-rx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx min\"\nconfig extend\n        option name     rate-rx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx avg\"\nconfig extend\n        option name     rate-rx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx max\"\nconfig extend\n        option name     rate-rx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx min\"\nconfig extend\n        option name     rate-rx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx avg\"\nconfig extend\n        option name     rate-rx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx max\"\nconfig extend\n        option name     noise-floor-wlan0\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan0\"\nconfig extend\n        option name     noise-floor-wlan1\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan1\"\nconfig extend\n        option name     snr-wlan0-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 min\"\nconfig extend\n        option name     snr-wlan0-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 avg\"\nconfig extend\n        option name     snr-wlan0-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 max\"\nconfig extend\n        option name     snr-wlan1-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 min\"\nconfig extend\n        option name     snr-wlan1-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 avg\"\nconfig extend\n        option name     snr-wlan1-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 max\"\n

      NOTE, any of the scripts above can be tested simply by running the corresponding command.

      NOTE, to check the output data from any of these extensions, on the LibreNMS machine, run (for example),

      snmpwalk -v 2c -c public -Osqnv <openwrt-host> 'NET-SNMP-EXTEND-MIB::nsExtendOutputFull.\"frequency-wlan0\"'

      NOTE, on the LibreNMS machine, ensure that snmp-mibs-downloader is installed.

      NOTE, on the AsuswrtMerlin machine, ensure that distro is installed (i.e. that the OS is correctly detected!).

      3: Restart the snmp service on Openwrt:

      service snmpd restart

      And then wait for discovery and polling on LibreNMS!

      "},{"location":"Support/Device-Notes/Routeros/","title":"RouterOS","text":"

      This agent script will allow LibreNMS to run a script on a Mikrotik / RouterOS device to gather the vlan information from both /interface/vlan/ and /interface/bridge/vlan/

      "},{"location":"Support/Device-Notes/Routeros/#installation","title":"Installation","text":"
      • Go to https://github.com/librenms/librenms-agent/tree/master/snmp/Routeros
      • Copy and paste the contents of LNMS_vlans.scr file into a script within a RouterOS device. Name this script LNMS_vlans. (This is NOT the same thing as creating a txt file and importing it into the Files section of the device)
      • If you're unsure how to create the script. Download the LNMS_vlans.scr file. Rename to remove the .scr extension. Copy this file onto all the Mikrotik devices you want to monitor.
      • Open a Terminal / CLI on each tik and run this. { :global txtContent [/file get LNMS_vlans contents]; /system/script/add name=LNMS_vlans owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=$txtContent ;} This will import the contents of that txt file into a script named LNMS_vlans
      • Enable an SNMP community that has both READ and WRITE capabilities. This is important, otherwise, LibreNMS will not be able to run the above script. It is recommended to use SNMP v3 for this.
      • Discover / Force rediscover your Mikrotik devices. After discovery has been completed the vlans menu should appear within LibreNMS for the device.
      "},{"location":"Support/Device-Notes/Routeros/#important-note","title":"*** IMPORTANT NOTE ***","text":"

      It is strongly recommended that SNMP service only be allowed to be communicated on a very limited set of IP addresses that LibreNMS and related systems will be coming from. (usually /32 address for each) because the write permission could allow an attack on a device. (such as dropping all firewall filters or changing the admin credentials)

      "},{"location":"Support/Device-Notes/Routeros/#theory-of-operation","title":"Theory of operation:","text":"

      Mikrotik vlan discovery plugin using the ability of ROS to \"fire up\" a script through SNMP.

      At first, LibreNMS check for the existence of the script, and if it is present, it will start the LNMS_vlans script.

      The script will gather information from: - /interface/bridge/vlan for tagged ports inside bridge - /interface/bridge/vlan for currently untagged ports inside bridge - /interface/bridge/port for ports PVID (untagged) inside bridge - /interface/vlan for vlan interfaces

      after the information is gathered, it is transmitted to LibreNMS over SNMP

      protocol is: type,vlanId,ifName

      i.e: T,254,ether1 is translated to Tagged vlan 254 on port ether1

      U,100,wlan2 is translated to Untagged vlan 100 on port wlan2

      "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":"Installing Install LibreNMS Now Install Using Docker Setup Applications Auto Discovery Oxidized RRDCached Alerting Rules Templates Transports More... API Using the API API Endpoints Support FAQ Install validation Performance tweaks More... Developing Getting Started Support for a new OS"},{"location":"API/","title":"Using the API","text":""},{"location":"API/#versioning","title":"Versioning","text":"

      Versioning an API is a minefield which saw us looking at numerous options on how to do this.

      We have currently settled on using versioning within the API end point itself /api/v0. As the API itself is new and still in active development we also decided that v0 would be the best starting point to indicate it's in development.

      "},{"location":"API/#tokens","title":"Tokens","text":"

      To access any of the token end points you will be required to authenticate using a token. Tokens can be created directly from within the LibreNMS web interface by going to /api-access/.

      • Click on 'Create API access token'.
      • Select the user you would like to generate the token for.
      • Enter an optional description.
      • Click Create API Token.
      "},{"location":"API/#endpoints","title":"Endpoints","text":"

      Whilst this documentation will describe and show examples of the end points, we've designed the API so you should be able to traverse through it without knowing any of the available API routes.

      You can do this by first calling /api/v0:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0\n

      Output:

      {\n \"list_bgp\": \"https://librenms.org/api/v0/bgp\",\n  ...\n \"edit_rule\": \"https://librenms.org/api/v0/rules\"\n}\n
      "},{"location":"API/#input","title":"Input","text":"

      Input to the API is done in three different ways, sometimes a combination of two or three of these.

      • Passing parameters via the api route. For example when obtaining a devices details you will pass the hostname of the device in the route: /api/v0/devices/:hostname.
      • Passing parameters via the query string. For example you can list all devices on your install but limit the output to devices that are currently down: /api/v0/devices?type=down
      • Passing data in via JSON, this will mainly be used when adding or updating information via the API, for instance adding a new device:
      curl -X POST -d '{\"hostname\":\"localhost.localdomain\",\"version\":\"v1\",\"community\":\"public\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices\n
      "},{"location":"API/#output","title":"Output","text":"

      Output from the API currently is via two output types:

      • JSON: Most API responses will output json. As shown in the example for calling the API endpoint.
      • PNG: This is for when the request is for an image such as a graph for a switch port.
      "},{"location":"API/#endpoint-categories","title":"Endpoint Categories","text":"
      • Devices
      • DeviceGroups
      • Ports
      • Port_Groups
      • PortGroups
      • Alerts
      • Routing
      • Switching
      • Inventory
      • Bills
      • ARP
      • Services
      • Logs
      • System
      • Locations
      "},{"location":"API/ARP/","title":"ARP","text":""},{"location":"API/ARP/#list_arp","title":"list_arp","text":"

      Retrieve a specific ARP entry or all ARP entries for a device

      Route: /api/v0/resources/ip/arp/:query

      Query can be: - An IP address - A MAC address - A CIDR network (192.168.1.0/24) - all and set ?device=hostname (or device id)

      Input:

      • device if you specify all for the query then you need to populate this with the hostname or id of the device.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/1.1.1.1\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/192.168.1.0/24\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/arp/all?device=localhost\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"arp\": [\n        {\n            \"port_id\": \"229\",\n            \"mac_address\": \"da160e5c2002\",\n            \"ipv4_address\": \"1.1.1.1\",\n            \"context_name\": \"\"\n        }\n    ]\n}\n
      "},{"location":"API/Alerts/","title":"Alerts","text":""},{"location":"API/Alerts/#get_alert","title":"get_alert","text":"

      Get details of an alert

      Route: /api/v0/alerts/:id

      • id is the alert id, you can obtain a list of alert ids from list_alerts.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts/1\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 7,\n \"alerts\": [\n  {\n   \"hostname\": \"localhost\",\n   \"id\": \"1\",\n   \"device_id\": \"1\",\n   \"rule_id\": \"1\",\n   \"state\": \"1\",\n   \"alerted\": \"1\",\n   \"open\": \"1\",\n   \"timestamp\": \"2014-12-11 14:40:02\"\n  }]\n}\n
      "},{"location":"API/Alerts/#ack_alert","title":"ack_alert","text":"

      Acknowledge an alert

      Route: /api/v0/alerts/:id

      • id is the alert id, you can obtain a list of alert ids from list_alerts.
      • note is the note to add to the alert
      • until_clear is a boolean and if set to false, the alert will re-alert if it worsens/betters.

      Input:

      -

      Example:

      curl -X PUT -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts/1\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"message\": \"Alert has been acknowledged\"\n}\n
      "},{"location":"API/Alerts/#unmute_alert","title":"unmute_alert","text":"

      Unmute an alert

      Route: /api/v0/alerts/unmute/:id

      • id is the alert id, you can obtain a list of alert ids from list_alerts.

      Input:

      -

      Example:

      curl -X PUT -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts/unmute/1\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"Alert has been unmuted\"\n}\n
      "},{"location":"API/Alerts/#list_alerts","title":"list_alerts","text":"

      List all alerts

      Route: /api/v0/alerts

      Input:

      • state: Filter the alerts by state, 0 = ok, 1 = alert, 2 = ack
      • severity: Filter the alerts by severity. Valid values are ok, warning, critical.
      • alert_rule: Filter alerts by alert rule ID.
      • order: How to order the output, default is by timestamp (descending). Can be appended by DESC or ASC to change the order.

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?state=1\n
      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?severity=critical\n
      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?order=timestamp%20ASC\n
      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/alerts?alert_rule=49\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"alerts\": [\n  {\n   \"id\": \"1\",\n   \"device_id\": \"1\",\n   \"rule_id\": \"1\",\n   \"state\": \"1\",\n   \"alerted\": \"1\",\n   \"open\": \"1\",\n   \"timestamp\": \"2014-12-11 14:40:02\"\n  }]\n}\n
      "},{"location":"API/Alerts/#rules","title":"Rules","text":""},{"location":"API/Alerts/#get_alert_rule","title":"get_alert_rule","text":"

      Get the alert rule details.

      Route: /api/v0/rules/:id

      • id is the rule id.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules/1\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"rules\": [\n  {\n   \"id\": \"1\",\n   \"device_id\": \"1\",\n   \"rule\": \"%devices.os != \\\"Juniper\\\"\",\n   \"severity\": \"warning\",\n   \"extra\": \"{\\\"mute\\\":true,\\\"count\\\":\\\"15\\\",\\\"delay\\\":null,\\\"invert\\\":false}\",\n   \"disabled\": \"0\",\n   \"name\": \"A test rule\"\n  }\n ]\n}\n
      "},{"location":"API/Alerts/#delete_rule","title":"delete_rule","text":"

      Delete an alert rule by id

      Route: /api/v0/rules/:id

      • id is the rule id.

      Input:

      -

      Example:

      curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules/1\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"message\": \"Alert rule has been removed\"\n}\n
      "},{"location":"API/Alerts/#list_alert_rules","title":"list_alert_rules","text":"

      List the alert rules.

      Route: /api/v0/rules

      -

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"rules\": [\n  {\n   \"id\": \"1\",\n   \"device_id\": \"-1\",\n   \"rule\": \"%devices.os != \\\"Juniper\\\"\",\n   \"severity\": \"critical\",\n   \"extra\": \"{\\\"mute\\\":false,\\\"count\\\":\\\"15\\\",\\\"delay\\\":\\\"300\\\",\\\"invert\\\":false}\",\n   \"disabled\": \"0\",\n   \"name\": \"A test rule\"\n  }]\n}\n
      "},{"location":"API/Alerts/#add_rule","title":"add_rule","text":"

      Add a new alert rule.

      Route: /api/v0/rules

      -

      Input (JSON):

      • devices: This is either an array of device ids or -1 for a global rule
      • builder: The rule which should be in the format entity.condition value (i.e devices.status != 0 for devices marked as down). It must be json encoded in the format rules are currently stored.
      • severity: The severity level the alert will be raised against, Ok, Warning, Critical.
      • disabled: Whether the rule will be disabled or not, 0 = enabled, 1 = disabled
      • count: This is how many polling runs before an alert will trigger and the frequency.
      • delay: Delay is when to start alerting and how frequently. The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
      • interval: How often to re-issue notifications while this alert is active,0 means notify once.The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
      • mute: If mute is enabled then an alert will never be sent but will show up in the Web UI (true or false).
      • invert: This would invert the rules check.
      • name: This is the name of the rule and is mandatory.
      • notes: Some informal notes for this rule

      Example:

      curl -X POST -d '{\"devices\":[1,2,3], \"name\": \"testrule\", \"builder\":{\"condition\":\"AND\",\"rules\":[{\"id\":\"devices.hostname\",\"field\":\"devices.hostname\",\"type\":\"string\",\"input\":\"text\",\"operator\":\"equal\",\"value\":\"localhost\"}],\"valid\":true},\"severity\": \"critical\",\"count\":15,\"delay\":\"5 m\",\"interval\":\"5 m\",\"mute\":false,\"notes\":\"This a note from the API\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules\n

      Output:

      {\n \"status\": \"ok\"\n}\n
      "},{"location":"API/Alerts/#edit_rule","title":"edit_rule","text":"

      Edit an existing alert rule

      Route: /api/v0/rules

      -

      Input (JSON):

      • rule_id: You must specify the rule_id to edit an existing rule, if this is absent then a new rule will be created.
      • devices: This is either an array of device ids or -1 for a global rule
      • builder: The rule which should be in the format entity.condition value (i.e devices.status != 0 for devices marked as down). It must be json encoded in the format rules are currently stored.
      • severity: The severity level the alert will be raised against, Ok, Warning, Critical.
      • disabled: Whether the rule will be disabled or not, 0 = enabled, 1 = disabled
      • count: This is how many polling runs before an alert will trigger and the frequency.
      • delay: Delay is when to start alerting and how frequently. The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
      • interval: How often to re-issue notifications while this alert is active,0 means notify once.The value is stored in seconds but you can specify minutes, hours or days by doing 5 m, 5 h, 5 d for each one.
      • mute: If mute is enabled then an alert will never be sent but will show up in the Web UI (true or false).
      • invert: This would invert the rules check.
      • name: This is the name of the rule and is mandatory.
      • notes: Some informal notes for this rule

      Example:

      curl -X PUT -d '{\"rule_id\":1,\"device_id\":\"-1\", \"name\": \"testrule\", \"builder\":{\"condition\":\"AND\",\"rules\":[{\"id\":\"devices.hostname\",\"field\":\"devices.hostname\",\"type\":\"string\",\"input\":\"text\",\"operator\":\"equal\",\"value\":\"localhost\"}],\"valid\":true},\"severity\": \"critical\",\"count\":15,\"delay\":\"5 m\",\"interval\":\"5 m\",\"mute\":false,\"notes\":\"This a note from the API\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/rules\n

      Output:

      {\n \"status\": \"ok\"\n}\n
      "},{"location":"API/Bills/","title":"Bills","text":""},{"location":"API/Bills/#list_bills","title":"list_bills","text":"

      Retrieve the list of bills currently in the system.

      Route: /api/v0/bills /api/v0/bills?period=previous

      Input:

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills?period=previous\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"bills\": [\n  {\n   \"bill_id\": \"1\",\n   \"bill_name\": \"Router bills\",\n   \"bill_type\": \"cdr\",\n   \"bill_cdr\": \"10000000\",\n   \"bill_day\": \"1\",\n   \"bill_quota\": \"0\",\n   \"rate_95th_in\": \"0\",\n   \"rate_95th_out\": \"0\",\n   \"rate_95th\": \"0\",\n   \"dir_95th\": \"in\",\n   \"total_data\": \"0\",\n   \"total_data_in\": \"0\",\n   \"total_data_out\": \"0\",\n   \"rate_average_in\": \"0\",\n   \"rate_average_out\": \"0\",\n   \"rate_average\": \"0\",\n   \"bill_last_calc\": \"2015-07-02 17:01:26\",\n   \"bill_custid\": \"Router\",\n   \"bill_ref\": \"Router\",\n   \"bill_notes\": \"Bill me\",\n   \"bill_autoadded\": \"0\",\n   \"ports_total\": \"0\",\n   \"allowed\": \"10Mbps\",\n   \"used\": \"0bps\",\n   \"percent\": 0,\n   \"overuse\": \"-\",\n   \"ports\": [\n       {\n           \"device_id\": \"168\",\n           \"port_id\": \"35146\",\n           \"ifName\": \"eth0\"\n       }\n   ]\n  }\n ]\n}\n
      "},{"location":"API/Bills/#get_bill","title":"get_bill","text":"

      Retrieve a specific bill

      Route: /api/v0/bills/:id /api/v0/bills/:id?period=previous /api/v0/bills?ref=:ref /api/v0/bills?ref=:ref&period=previous /api/v0/bills?custid=:custid /api/v0/bills?custid=:custid&period=previous

      • id is the specific bill id
      • ref is the billing reference
      • custid is the customer reference
      • period=previous indicates you would like the data for the last complete period rather than the current period

      Input:

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills?ref=:customerref\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills?custid=:custid\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"count\": 1,\n \"bills\": [\n  {\n   \"bill_id\": \"1\",\n   \"bill_name\": \"Router bills\",\n   \"bill_type\": \"cdr\",\n   \"bill_cdr\": \"10000000\",\n   \"bill_day\": \"1\",\n   \"bill_quota\": \"0\",\n   \"rate_95th_in\": \"0\",\n   \"rate_95th_out\": \"0\",\n   \"rate_95th\": \"0\",\n   \"dir_95th\": \"in\",\n   \"total_data\": \"0\",\n   \"total_data_in\": \"0\",\n   \"total_data_out\": \"0\",\n   \"rate_average_in\": \"0\",\n   \"rate_average_out\": \"0\",\n   \"rate_average\": \"0\",\n   \"bill_last_calc\": \"2015-07-02 17:01:26\",\n   \"bill_custid\": \"Router\",\n   \"bill_ref\": \"Router\",\n   \"bill_notes\": \"Bill me\",\n   \"bill_autoadded\": \"0\",\n   \"ports_total\": \"0\",\n   \"allowed\": \"10Mbps\",\n   \"used\": \"0bps\",\n   \"percent\": 0,\n   \"overuse\": \"-\",\n   \"ports\": [\n       {\n           \"device_id\": \"168\",\n           \"port_id\": \"35146\",\n           \"ifName\": \"eth0\"\n       }\n   ]\n  }\n ]\n}\n
      "},{"location":"API/Bills/#get_bill_graph","title":"get_bill_graph","text":"

      Retrieve a graph image associated with a bill.

      NB: The graphs returned from this will always be png as they do not come from rrdtool, even if you have SVG set.

      Route: `/api/v0/bills/:id/graphs/:graph_type

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits?from=1517443200\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/bits?from=1517443200&to=1517788800\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphs/monthly\n

      Output:

      Graph Image

      "},{"location":"API/Bills/#get_bill_graphdata","title":"get_bill_graphdata","text":"

      Retrieve the data used to draw a graph so it can be rendered in an external system

      Route: /api/v0/bills/:id/graphdata/:graph_type

      Input:

      The reducefactor parameter is used to reduce the number of data points. Billing data has 5 minute granularity, so requesting a graph for a long time period will result in many data points. If not supplied, it will be automatically calculated. A reducefactor of 1 means return all items, 2 means half of the items etc.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200&to=1517788800\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/graphdata/bits?from=1517443200&to=1517788800&reducefactor=5\n

      Output:

      { \"status\": \"ok\", \"graph_data\": { \"from\": \"1517443200\", \"to\": 1518196161, \"last\": \"1518195901\", \"in_data\": [ 103190525.20999999, 104949255.81 ], \"out_data\": [ 1102059.1299999999, 1079216.46 ], \"tot_data\": [ 104292584.33999999, 106028472.27 ], \"ticks\": [ \"1517750401\", \"1517756101\" ], \"rate_95th\": \"251880417\", \"rate_average\": \"146575554\", \"bill_type\": \"cdr\", \"max_in\": 9888289942, \"max_out\": 75848756, \"ave_in\": 18029660.242105871, \"ave_out\": 196447.38060137472, \"last_in\": 3790227.9500000002, \"last_out\": 122731.63333333333 } }

      "},{"location":"API/Bills/#get_bill_history","title":"get_bill_history","text":"

      Retrieve the history of specific bill

      Route: /api/v0/bills/:id/history

      Input:

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history\n

      Output:

      {\n \"status\": \"ok\",\n \"bill_history\": [\n    {\n        \"bill_hist_id\": \"1\",\n        \"bill_id\": \"1\",\n        \"updated\": \"2018-02-06 17:01:01\",\n        \"bill_datefrom\": \"2018-02-01 00:00:00\",\n        \"bill_dateto\": \"2018-02-28 23:59:59\",\n        \"bill_type\": \"CDR\",\n        \"bill_allowed\": \"100000000\",\n        \"bill_used\": \"229963765\",\n        \"bill_overuse\": \"129963765\",\n        \"bill_percent\": \"229.96\",\n        \"rate_95th_in\": \"229963765\",\n        \"rate_95th_out\": \"1891344\",\n        \"rate_95th\": \"229963765\",\n        \"dir_95th\": \"in\",\n        \"rate_average\": \"136527101\",\n        \"rate_average_in\": \"135123359\",\n        \"rate_average_out\": \"1403743\",\n        \"traf_in\": \"3235123452544\",\n        \"traf_out\": \"33608406566\",\n        \"traf_total\": \"3268731859110\",\n        \"bill_peak_out\": \"2782349290\",\n        \"bill_peak_in\": \"10161119\",\n        \"pdf\": null\n    }\n ],\n \"count\": 1,\n}\n
      "},{"location":"API/Bills/#get_bill_history_graph","title":"get_bill_history_graph","text":"

      Retrieve a graph of a previous period of a bill

      NB: The graphs returned from this will always be png as they do not come from rrdtool, even if you have SVG set.

      Route: /api/v0/bills/:id/history/:bill_hist_id/graphs/:graph_type

      Input:

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/hour\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphs/day\n

      Output:

      (image)

      "},{"location":"API/Bills/#get_bill_history_graphdata","title":"get_bill_history_graphdata","text":"

      Retrieve the data for a graph of a previous period of a bill, to be rendered in an external system

      Route: /api/v0/bills/:id/history/:bill_hist_id/graphdata/:graph_type

      Input:

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/bits\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/hour\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1/history/1/graphdata/day\n

      Output:

      "},{"location":"API/Bills/#delete_bill","title":"delete_bill","text":"

      Delete a specific bill and all dependent data

      Route: /api/v0/bills/:id

      • id is the specific bill id

      Input:

      Example:

      curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills/1\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Bill has been removed\"\n}\n
      "},{"location":"API/Bills/#create_edit_bill","title":"create_edit_bill","text":"

      Creates a new bill or updates an existing one

      Route: /api/v0/bills

      Method: POST

      • If you send an existing bill_id the call replaces all values it receives. For example if you send 2 ports it will delete the existing ports and add the the 2 new ports. So to add ports you have to get the current ports first and add them to your update call.

      Input:

      Example (create):

      curl -X POST -d '{\"ports\":[ 1021 ],\"bill_name\":\"NEWBILL\",\"bill_day\":\"1\",\"bill_type\":\"quota\",\"bill_quota\":\"2000000000000\",\"bill_custid\":\"1337\",\"bill_ref\":\"reference1\",\"bill_notes\":\"mynote\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills\n

      Example (set):

      curl -X POST -d '{\"bill_id\":\"32\",\"ports\":[ 1021 ],\"bill_name\":\"NEWNAME\",\"bill_quota\":\"1000000000000\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bills\n

      Output:

      {\n    \"status\": \"ok\",\n    \"bill_id\": 32\n}\n
      "},{"location":"API/DeviceGroups/","title":"DeviceGroups","text":""},{"location":"API/DeviceGroups/#get_devicegroups","title":"get_devicegroups","text":"

      List all device groups.

      Route: /api/v0/devicegroups

      Input (JSON):

      -

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Found 1 device groups\",\n        \"count\": 1,\n        \"groups\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Testing\",\n            \"desc\": \"Testing\",\n            \"pattern\": \"%devices.status = \\\"1\\\" &&\"\n        }\n        ]\n    }\n]\n
      "},{"location":"API/DeviceGroups/#add_devicegroup","title":"add_devicegroup","text":"

      Add a new device group. Upon success, the ID of the new device group is returned and the HTTP response code is 201.

      Route: /api/v0/devicegroups

      Input (JSON):

      • name: required - The name of the device group
      • type: required - should be static or dynamic. Setting this to static requires that the devices input be provided
      • desc: optional - Description of the device group
      • rules: required if type == dynamic - A set of rules to determine which devices should be included in this device group
      • devices: required if type == static - A list of devices that should be included in this group. This is a static list of devices

      Examples:

      Dynamic Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups \\\n  --data-raw '\n{\n \"name\": \"New Device Group\", \n \"desc\": \"A very fancy dynamic group\",\n \"type\": \"dynamic\", \n \"rules\": \"{\\\"condition\\\":\\\"AND\\\",\\\"rules\\\":[{\\\"id\\\":\\\"access_points.name\\\",\\\"field\\\":\\\"access_points.name\\\",\\\"type\\\":\\\"string\\\",\\\"input\\\":\\\"text\\\",\\\"operator\\\":\\\"equal\\\",\\\"value\\\":\\\"accesspoint1\\\"}],\\\"valid\\\":true}\"\n}\n'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"id\": 86,\n    \"message\": \"Device group New Device Group created\"\n}\n

      Static Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups \\\n  -d '{\"name\":\"New Device Group\",\"type\":\"static\",\"devices\":[261,271]}'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"id\": 86,\n    \"message\": \"Device group New Device Group created\"\n}\n
      "},{"location":"API/DeviceGroups/#update_devicegroup","title":"update_devicegroup","text":"

      Updates a device group.

      Route: /api/v0/devicegroups/:name

      • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

      Input (JSON):

      • name: optional - The name of the device group
      • type: optional - should be static or dynamic. Setting this to static requires that the devices input be provided
      • desc: optional - Description of the device group
      • rules: required if type == dynamic - A set of rules to determine which devices should be included in this device group
      • devices: required if type == static - A list of devices that should be included in this group. This is a static list of devices

      Examples:

      curl -X PATCH -d '{\"name\": \"NewLinuxServers\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/LinuxServers\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device group LinuxServers updated\"\n}\n
      "},{"location":"API/DeviceGroups/#delete_devicegroup","title":"delete_devicegroup","text":"

      Deletes a device group.

      Route: /api/v0/devicegroups/:name

      • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

      Input:

      -

      Examples:

      curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/LinuxServers\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device group LinuxServers deleted\"\n}\n
      "},{"location":"API/DeviceGroups/#get_devices_by_group","title":"get_devices_by_group","text":"

      List all devices matching the group provided.

      Route: /api/v0/devicegroups/:name

      • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

      Input (JSON):

      • full: set to any value to return all data for the devices in a given group

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devicegroups/LinuxServers\n

      Output:

      [\n     {\n         \"status\": \"ok\",\n         \"message\": \"Found 3 in group LinuxServers\",\n         \"count\": 3,\n         \"devices\": [\n            {\n                \"device_id\": \"15\"\n            },\n            {\n                \"device_id\": \"18\"\n            },\n            {\n                \"device_id\": \"20\"\n            }\n         ]\n     }\n]\n
      "},{"location":"API/DeviceGroups/#maintenance_devicegroup","title":"maintenance_devicegroup","text":"

      Set a device group into maintenance mode.

      Route: /api/v0/devicegroups/:name/maintenance

      Input (JSON):

      • title: optional - Some title for the Maintenance Will be replaced with device group name if omitted
      • notes: optional - Some description for the Maintenance
      • start: optional - start time of Maintenance in full format Y-m-d H:i:00 eg: 2022-08-01 22:45:00 Current system time now() will be used if omitted
      • duration: required - Duration of Maintenance in format H:i / Hrs:Mins eg: 02:00

      Example with start time:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups/Cisco%20switches/maintenance/ \\\n  --data-raw '\n{\n \"title\":\"Device group Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with start time\",\n  \"start\":\"2022-08-01 08:00:00\",\n  \"duration\":\"2:00\"\n}\n'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device group Cisco switches (2) will begin maintenance mode at 2022-08-01 22:45:00 for 2:00h\"\n}\n

      Example with no start time:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups/Cisco%20switches/maintenance/ \\\n  --data-raw '\n{\n \"title\":\"Device group Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with no start time\",\n  \"duration\":\"2:00\"\n}\n'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device group Cisco switches (2) moved into maintenance mode for 2:00h\"\n}\n
      "},{"location":"API/DeviceGroups/#add-devices-to-group","title":"Add devices to group","text":"

      Add devices to a device group.

      Route: /api/v0/devicegroups/:name/devices

      • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

      Input (JSON):

      • devices: required - A list of devices to be added to the group.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devicegroups/devices \\\n  --data-raw '{\"devices\":[261,271]}'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Devices added\"\n}\n
      "},{"location":"API/DeviceGroups/#remove-devices-from-group","title":"Remove devices from group","text":"

      Removes devices from a device group.

      Route: /api/v0/devicegroups/:name/devices

      • name Is the name of the device group which can be obtained using get_devicegroups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

      Input (JSON):

      • devices: required - A list of devices to be removed from the group.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X DELETE https://librenms.org/api/v0/devicegroups/devices \\\n  --data-raw '{\"devices\":[261,271]}'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Devices removed\"\n}\n
      "},{"location":"API/Devices/","title":"Devices","text":""},{"location":"API/Devices/#del_device","title":"del_device","text":"

      Delete a given device.

      Route: /api/v0/devices/:hostname

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Removed device localhost\",\n    \"devices\": [\n        {\n            \"device_id\": \"1\",\n            \"hostname\": \"localhost\",\n            ...\n            \"serial\": null,\n            \"icon\": null\n        }\n    ]\n}\n
      "},{"location":"API/Devices/#get_device","title":"get_device","text":"

      Get details of a given device.

      Route: /api/v0/devices/:hostname

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

      Output:

      {\n    \"status\": \"ok\",\n    \"devices\": [\n        {\n            \"device_id\": \"1\",\n            \"hostname\": \"localhost\",\n            ...\n            \"serial\": null,\n            \"icon\": null\n        }\n    ]\n}\n
      "},{"location":"API/Devices/#discover_device","title":"discover_device","text":"

      Trigger a discovery of given device.

      Route: /api/v0/devices/:hostname/discover

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/discover\n

      Output:

      {\n    \"status\": \"ok\",\n    \"result\": {\n        \"status\": 0,\n        \"message\": \"Device will be rediscovered\"\n    },\n    \"count\": 2\n}\n
      "},{"location":"API/Devices/#availability","title":"availability","text":"

      Get calculated availabilities of given device.

      Route: /api/v0/devices/:hostname/availability

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/availability\n

      Output:

      {\n    \"status\": \"ok\",\n    \"availability\": [\n        {\n            \"duration\": 86400,\n            \"availability_perc\": \"100.000000\"\n        },\n        {\n            \"duration\": 604800,\n            \"availability_perc\": \"100.000000\"\n        },\n        {\n            \"duration\": 2592000,\n            \"availability_perc\": \"99.946000\"\n        },\n        {\n            \"duration\": 31536000,\n            \"availability_perc\": \"99.994000\"\n        }\n    ],\n    \"count\": 4\n}\n
      "},{"location":"API/Devices/#outages","title":"outages","text":"

      Get detected outages of given device.

      Route: /api/v0/devices/:hostname/outages

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/outages\n

      Output:

      {\n    \"status\": \"ok\",\n    \"outages\": [\n        {\n            \"going_down\": 1593194031,\n            \"up_again\": 1593194388\n        },\n        {\n            \"going_down\": 1593946507,\n            \"up_again\": 1593946863\n        },\n        {\n            \"going_down\": 1594628616,\n            \"up_again\": 1594628968\n        },\n        {\n            \"going_down\": 1594628974,\n            \"up_again\": 1594629339\n        },\n        {\n            \"going_down\": 1594638668,\n            \"up_again\": 1594638992\n        }\n    ],\n    \"count\": 5\n}\n
      "},{"location":"API/Devices/#get_graphs","title":"get_graphs","text":"

      Get a list of available graphs for a device, this does not include ports.

      Route: /api/v0/devices/:hostname/graphs

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 3,\n    \"graphs\": [\n        {\n            \"desc\": \"Poller Time\",\n            \"name\": \"device_poller_perf\"\n        },\n        {\n            \"desc\": \"Ping Response\",\n            \"name\": \"device_ping_perf\"\n        },\n        {\n            \"desc\": \"System Uptime\",\n            \"name\": \"uptime\"\n        }\n    ]\n}\n
      "},{"location":"API/Devices/#list_available_health_graphs","title":"list_available_health_graphs","text":"

      This function allows to do three things:

      • Get a list of overall health graphs available.
      • Get a list of health graphs based on provided class.
      • Get the health sensors information based on ID.

      Route: /api/v0/devices/:hostname/health(/:type)(/:sensor_id)

      • hostname can be either the device hostname or id
      • type (optional) is health type / sensor class
      • sensor_id (optional) is the sensor id to retrieve specific information.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 2,\n    \"graphs\": [\n        {\n            \"desc\": \"Airflow\",\n            \"name\": \"device_airflow\"\n        },\n        {\n            \"desc\": \"Voltage\",\n            \"name\": \"device_voltage\"\n        }\n    ]\n}\n

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_voltage\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 2,\n    \"graphs\": [\n        {\n            \"sensor_id\": \"1\",\n            \"desc\": \"Input Feed A\"\n        },\n        {\n            \"sensor_id\": \"2\",\n            \"desc\": \"Output Feed\"\n        }\n    ]\n}\n

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_voltage/1\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"graphs\": [\n        {\n            \"sensor_id\": \"1\",\n            \"sensor_deleted\": \"0\",\n            \"sensor_class\": \"voltage\",\n            \"device_id\": \"1\",\n            \"poller_type\": \"snmp\",\n            \"sensor_oid\": \".1.3.6.1.4.1.318.1.1.27.1.1.0\",\n            \"sensor_index\": \"1\",\n            \"sensor_type\": \"apc\",\n            \"sensor_descr\": \"Input\",\n            \"sensor_divisor\": \"1\",\n            \"sensor_multiplier\": \"1\",\n            \"sensor_current\": \"1\",\n            \"sensor_limit\": \"1.15\",\n            \"sensor_limit_warn\": null,\n            \"sensor_limit_low\": \"0.85\",\n            \"sensor_limit_low_warn\": null,\n            \"sensor_alert\": \"1\",\n            \"sensor_custom\": \"No\",\n            \"entPhysicalIndex\": null,\n            \"entPhysicalIndex_measured\": null,\n            \"lastupdate\": \"2017-01-13 13:50:26\",\n            \"sensor_prev\": \"1\"\n        }\n    ]\n}\n
      "},{"location":"API/Devices/#list_available_wireless_graphs","title":"list_available_wireless_graphs","text":"

      This function allows to do three things:

      • Get a list of overall wireless graphs available.
      • Get a list of wireless graphs based on provided class.
      • Get the wireless sensors information based on ID.

      Route: /api/v0/devices/:hostname/wireless(/:type)(/:sensor_id)

      • hostname can be either the device hostname or id
      • type (optional) is wireless type / wireless class
      • sensor_id (optional) is the sensor id to retrieve specific information.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/wireless\n

      Output:

      {\n    \"status\": \"ok\",\n    \"graphs\": [\n        {\n            \"desc\": \"Ccq\",\n            \"name\": \"device_wireless_ccq\"\n        },\n        {\n            \"desc\": \"Clients\",\n            \"name\": \"device_wireless_clients\"\n        }\n    ],\n    \"count\": 2\n}\n

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/wireless/device_wireless_ccq\n

      Output:

      {\n    \"status\": \"ok\",\n    \"graphs\": [\n        {\n            \"sensor_id\": \"791\",\n            \"desc\": \"SSID: bast (ng)\"\n        },\n        {\n            \"sensor_id\": \"792\",\n            \"desc\": \"SSID: bast (na)\"\n        }\n    ],\n    \"count\": 2\n}\n

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/health/device_wireless_ccq/1\n

      Output:

      {\n    \"status\": \"ok\",\n    \"graphs\": [\n        {\n            \"sensor_id\": \"791\",\n            \"sensor_deleted\": \"0\",\n            \"sensor_class\": \"ccq\",\n            \"device_id\": \"381\",\n            \"sensor_index\": \"0\",\n            \"sensor_type\": \"unifi\",\n            \"sensor_descr\": \"SSID: bast (ng)\",\n            \"sensor_divisor\": \"10\",\n            \"sensor_multiplier\": \"1\",\n            \"sensor_aggregator\": \"sum\",\n            \"sensor_current\": \"100\",\n            \"sensor_prev\": \"100\",\n            \"sensor_limit\": null,\n            \"sensor_limit_warn\": null,\n            \"sensor_limit_low\": null,\n            \"sensor_limit_low_warn\": null,\n            \"sensor_alert\": \"1\",\n            \"sensor_custom\": \"No\",\n            \"entPhysicalIndex\": null,\n            \"entPhysicalIndex_measured\": null,\n            \"lastupdate\": \"2017-12-06 21:26:29\",\n            \"sensor_oids\": \"[\\\".1.3.6.1.4.1.41112.1.6.1.2.1.3.0\\\"]\",\n            \"access_point_id\": null\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Devices/#get_health_graph","title":"get_health_graph","text":"

      Get a particular health class graph for a device, if you provide a sensor_id as well then a single sensor graph will be provided. If no sensor_id value is provided then you will be sent a stacked sensor graph.

      Route: /api/v0/devices/:hostname/graphs/health/:type(/:sensor_id)

      • hostname can be either the device hostname or id
      • type is the name of the health graph as returned by list_available_health_graphs
      • sensor_id (optional) restricts the graph to return a particular health sensor graph.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/health/device_voltage\n

      Output:

      Output is a stacked graph for the health type provided.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/health/device_voltage/1\n

      Output:

      Output is the graph of the particular health type sensor provided.

      "},{"location":"API/Devices/#get_wireless_graph","title":"get_wireless_graph","text":"

      Get a particular wireless class graph for a device, if you provide a sensor_id as well then a single sensor graph will be provided. If no sensor_id value is provided then you will be sent a stacked wireless graph.

      Route: /api/v0/devices/:hostname/graphs/wireless/:type(/:sensor_id)

      • hostname can be either the device hostname or id
      • type is the name of the wireless graph as returned by list_available_wireless_graphs
      • sensor_id (optional) restricts the graph to return a particular wireless sensor graph.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/wireless/device_wireless_ccq\n

      Output:

      Output is a stacked graph for the wireless type provided.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/graphs/wireless/device_wireless_ccq/1\n

      Output:

      Output is the graph of the particular wireless type sensor provided.

      "},{"location":"API/Devices/#get_graph_generic_by_hostname","title":"get_graph_generic_by_hostname","text":"

      Get a specific graph for a device, this does not include ports.

      Route: /api/v0/devices/:hostname/:type

      • hostname can be either the device hostname or id
      • type is the type of graph you want, use [get_graphs](#function-get_graphs to see the graphs available. Defaults to device uptime.

      Input:

      • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • width: The graph width, defaults to 1075.
      • height: The graph height, defaults to 300.
      • output: Set how the graph should be outputted (base64, display), defaults to display.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/device_poller_perf\n

      Output:

      Output is an image.

      "},{"location":"API/Devices/#get_graph_by_service","title":"get_graph_by_service","text":"

      Get the graph for a service

      Route: /api/v0/devices/:hostname/services/:service_id/graphs/:datasource

      • hostname can be either the device hostname or id
      • service id
      • datasource is the name of the service datasource

      Input:

      • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • width: The graph width, defaults to 1075.
      • height: The graph height, defaults to 300.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/localhost/35/graphs/loss\n

      Output:

      Output is an image.

      "},{"location":"API/Devices/#get_port_graphs","title":"get_port_graphs","text":"

      Get a list of ports for a particular device.

      Route: /api/v0/devices/:hostname/ports

      • hostname can be either the device hostname or id

      Input:

      • columns: Comma separated list of columns you want returned.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ports\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 3,\n    \"ports\": [\n        {\n            \"ifName\": \"lo\"\n        },\n        {\n            \"ifName\": \"eth0\"\n        },\n        {\n            \"ifName\": \"eth1\"\n        }\n    ]\n}\n
      "},{"location":"API/Devices/#get_device_fdb","title":"get_device_fdb","text":"

      Get a list of FDB entries associated with a device.

      Route: /api/v0/devices/:hostname/fdb

      • hostname can be either the device hostname or id

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/fdb\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ports_fdb\": {\n        \"ports_fdb_id\": 10,\n        \"port_id\": 10000,\n        \"mac_address\": \"1aaa2bbb3ccc\",\n        \"vlan_id\": 20000,\n        \"device_id\": 1,\n        \"created_at\": \"2019-01-1 01:01:01\",\n        \"updated_at\": \"2019-01-1 01:01:01\"\n    }\n}\n
      "},{"location":"API/Devices/#get_device_ip_addresses","title":"get_device_ip_addresses","text":"

      Get a list of IP addresses (v4 and v6) associated with a device.

      Route: /api/v0/devices/:hostname/ip

      • hostname can be either the device hostname or id

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ip\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"addresses\": [\n        {\n          \"ipv4_address_id\": \"290\",\n          \"ipv4_address\": \"192.168.99.292\",\n          \"ipv4_prefixlen\": \"30\",\n          \"ipv4_network_id\": \"247\",\n          \"port_id\": \"323\",\n          \"context_name\": \"\"\n        }\n    ]\n}\n
      "},{"location":"API/Devices/#get_port_stack","title":"get_port_stack","text":"

      Get a list of port mappings for a device. This is useful for showing physical ports that are in a virtual port-channel.

      Route: /api/v0/devices/:hostname/port_stack

      • hostname can be either the device hostname or id

      Input:

      • valid_mappings: Filter the result by only showing valid mappings (\"0\" values not shown).

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/port_stack?valid_mappings\n

      Output:

      {\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"count\": 2,\n  \"mappings\": [\n    {\n      \"device_id\": \"3742\",\n      \"port_id_high\": \"1001000\",\n      \"port_id_low\": \"51001\",\n      \"ifStackStatus\": \"active\"\n    },\n    {\n      \"device_id\": \"3742\",\n      \"port_id_high\": \"1001000\",\n      \"port_id_low\": \"52001\",\n      \"ifStackStatus\": \"active\"\n    }\n  ]\n}\n
      "},{"location":"API/Devices/#get_components","title":"get_components","text":"

      Get a list of components for a particular device.

      Route: /api/v0/devices/:hostname/components

      • hostname can be either the device hostname or id

      Input:

      • type: Filter the result by type (Equals).
      • id: Filter the result by id (Equals).
      • label: Filter the result by label (Contains).
      • status: Filter the result by status (Equals).
      • disabled: Filter the result by disabled (Equals).
      • ignore: Filter the result by ignore (Equals).

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 3,\n    \"components\": {\n        \"2\": {\n            \"TestAttribute-1\": \"Value1\",\n            \"TestAttribute-2\": \"Value2\",\n            \"TestAttribute-3\": \"Value3\",\n            \"type\": \"TestComponent-1\",\n            \"label\": \"This is a really cool blue component\",\n            \"status\": \"1\",\n            \"ignore\": \"0\",\n            \"disabled\": \"0\"\n        },\n        \"20\": {\n            \"TestAttribute-1\": \"Value4\",\n            \"TestAttribute-2\": \"Value5\",\n            \"TestAttribute-3\": \"Value6\",\n            \"type\": \"TestComponent-1\",\n            \"label\": \"This is a really cool red component\",\n            \"status\": \"1\",\n            \"ignore\": \"0\",\n            \"disabled\": \"0\"\n        },\n        \"27\": {\n            \"TestAttribute-1\": \"Value7\",\n            \"TestAttribute-2\": \"Value8\",\n            \"TestAttribute-3\": \"Value9\",\n            \"type\": \"TestComponent-2\",\n            \"label\": \"This is a really cool yellow widget\",\n            \"status\": \"1\",\n            \"ignore\": \"0\",\n            \"disabled\": \"0\"\n        }\n    }\n}\n
      "},{"location":"API/Devices/#add_components","title":"add_components","text":"

      Create a new component of a type on a particular device.

      Route: /api/v0/devices/:hostname/components/:type

      • hostname can be either the device hostname or id
      • type is the type of component to add

      Example:

      curl -X POST -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components/APITEST\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"components\": {\n        \"4459\": {\n            \"type\": \"APITEST\",\n            \"label\": \"\",\n            \"status\": 1,\n            \"ignore\": 0,\n            \"disabled\": 0,\n            \"error\": \"\"\n        }\n    }\n}\n
      "},{"location":"API/Devices/#edit_components","title":"edit_components","text":"

      Edit an existing component on a particular device.

      Route: /api/v0/devices/:hostname/components

      • hostname can be either the device hostname or id

      In this example we set the label and add a new field: TestField:

      curl -X PUT -d '{\"4459\": {\"type\": \"APITEST\",\"label\": \"This is a test label\",\"status\": 1,\"ignore\": 0,\"disabled\": 0,\"error\": \"\",\"TestField\": \"TestData\"}}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1\n}\n

      Just take the JSON array from add_components or edit_components, edit as you wish and submit it back to edit components.

      "},{"location":"API/Devices/#delete_components","title":"delete_components","text":"

      Delete an existing component on a particular device.

      Route: /api/v0/devices/:hostname/components/:component

      • hostname can be either the device hostname or id
      • component is the component ID to be deleted.

      Example:

      curl -X DELETE -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/components/4459\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\"\n}\n
      "},{"location":"API/Devices/#get_port_stats_by_port_hostname","title":"get_port_stats_by_port_hostname","text":"

      Get information about a particular port for a device.

      Route: /api/v0/devices/:hostname/ports/:ifname

      • hostname can be either the device hostname or id
      • ifname can be any of the interface names for the device which can be obtained using get_port_graphs. Please ensure that the ifname is urlencoded if it needs to be (i.e Gi0/1/0 would need to be urlencoded.

      Input:

      • columns: Comma separated list of columns you want returned.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ports/eth0\n

      Output:

      {\n \"status\": \"ok\",\n \"port\": {\n  \"port_id\": \"2\",\n  \"device_id\": \"1\",\n  ...\n  \"poll_prev\": \"1418412902\",\n  \"poll_period\": \"300\"\n }\n}\n
      "},{"location":"API/Devices/#get_graph_by_port_hostname","title":"get_graph_by_port_hostname","text":"

      Get a graph of a port for a particular device.

      Route: /api/v0/devices/:hostname/ports/:ifname/:type

      • hostname can be either the device hostname or id
      • ifname can be any of the interface names for the device which can be obtained using get_port_graphs. Please ensure that the ifname is urlencoded if it needs to be (i.e Gi0/1/0 would need to be urlencoded.
      • type is the port type you want the graph for, you can request a list of ports for a device with get_port_graphs.

      Input:

      • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • width: The graph width, defaults to 1075.
      • height: The graph height, defaults to 300.
      • ifDescr: If this is set to true then we will use ifDescr to lookup the port instead of ifName. Pass the ifDescr value you want to search as you would ifName.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/ports/eth0/port_bits\n

      Output:

      Output is an image.

      "},{"location":"API/Devices/#list_sensors","title":"list_sensors","text":"

      Get a list of all Sensors.

      Route: /api/v0/resources/sensors

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/sensors\n

      Output:

      {\n    \"status\": \"ok\",\n    \"sensors\": [\n        {\n            \"sensor_id\": 218810,\n            \"sensor_deleted\": 0,\n            \"sensor_class\": \"dbm\",\n            \"device_id\": 136,\n            \"poller_type\": \"snmp\",\n            \"sensor_oid\": \".1.3.6.1.4.1.2636.3.60.1.1.1.1.7.919\",\n            \"sensor_index\": \"tx-919\",\n            \"sensor_type\": \"junos\",\n            \"sensor_descr\": \"xe-2/1/4 Tx Power\",\n            \"group\": null,\n            \"sensor_divisor\": 100,\n            \"sensor_multiplier\": 1,\n            \"sensor_current\": -1.81,\n            \"sensor_limit\": 2,\n            \"sensor_limit_warn\": 0.5,\n            \"sensor_limit_low\": -9.7,\n            \"sensor_limit_low_warn\": -8.21,\n            \"sensor_alert\": 1,\n            \"sensor_custom\": \"No\",\n            \"entPhysicalIndex\": \"919\",\n            \"entPhysicalIndex_measured\": \"ports\",\n            \"lastupdate\": \"2019-02-18 02:47:09\",\n            \"sensor_prev\": -1.77,\n            \"user_func\": null\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Devices/#list_devices","title":"list_devices","text":"

      Return a list of devices.

      Route: /api/v0/devices

      Input:

      • order: How to order the output, default is by hostname. Can be prepended by DESC or ASC to change the order.
      • type: can be one of the following to filter or search by:
      • all: All devices
      • active: Only not ignored and not disabled devices
      • ignored: Only ignored devices
      • up: Only devices that are up
      • down: Only devices that are down
      • disabled: Disabled devices
      • os: search by os type
      • mac: search by mac address
      • ipv4: search by IPv4 address
      • ipv6: search by IPv6 address (compressed or uncompressed)
      • location: search by location
      • location_id: search by location_id
      • hostname: search by hostname
      • sysName: search by sysName
      • display: search by display name
      • device_id: exact match by device-id
      • type: search by device type
      • query: If searching by, then this will be used as the input.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices?order=hostname%20DESC&type=down\n

      Output:

      {\n \"status\": \"ok\",\n \"count\": 1,\n \"devices\": [\n  {\n   \"device_id\": \"1\",\n   \"hostname\": \"localhost\",\n   ...\n   \"serial\": null,\n   \"icon\": null\n  }\n ]\n}\n

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices?type=mac&query=00000c9ff013\n

      Output:

      {\n \"status\": \"ok\",\n \"count\": 1,\n \"devices\": [\n  {\n   \"device_id\": \"1\",\n   \"hostname\": \"localhost\",\n   ...\n   \"serial\": null,\n   \"icon\": null\n  }\n ]\n}\n
      "},{"location":"API/Devices/#device_under_maintenance","title":"device_under_maintenance","text":"

      Get the current maintenance status of a device.

      Route: /api/v0/devices/:hostname/maintenance

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/maintenance\n

      Output:

      {\n    \"status\": \"ok\",\n    \"is_under_maintenance\": true\n}\n
      "},{"location":"API/Devices/#maintenance_device","title":"maintenance_device","text":"

      Set a device into maintenance mode.

      Route: /api/v0/devices/:hostname/maintenance

      Input (JSON):

      • title: optional - Some title for the Maintenance Will be replaced with hostname if omitted
      • notes: optional - Some description for the Maintenance Will also be added to device notes if user prefs \"Add schedule notes to devices notes\" is set
      • start: optional - start time of Maintenance in full format Y-m-d H:i:00 eg: 2022-08-01 22:45:00 Current system time now() will be used if omitted
      • duration: required - Duration of Maintenance in format H:i / Hrs:Mins eg: 02:00

      Example with start time:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devices/localhost/maintenance/ \\\n  --data-raw '\n \"title\":\"Device Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with start time\",\n  \"start\":\"2022-08-01 08:00:00\",\n  \"duration\":\"2:00\"\n}\n'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device localhost (1) will begin maintenance mode at 2022-08-01 22:45:00 for 2:00h\"\n}\n

      Example with no start time:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST https://librenms.org/api/v0/devices/localhost/maintenance/ \\\n  --data-raw '\n \"title\":\"Device Maintenance\",\n  \"notes\":\"A 2 hour Maintenance triggered via API with no start time\",\n  \"duration\":\"2:00\"\n}\n'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device localhost (1) moved into maintenance mode for 2:00h\"\n}\n
      "},{"location":"API/Devices/#add_device","title":"add_device","text":"

      Add a new device. Most fields are optional. You may omit snmp credentials to attempt each system credential in order. See snmp.version, snmp.community, and snmp.v3

      To guarantee device is added, use force_add. This will skip checks for duplicate device and snmp reachability, but not duplicate hostname.

      Route: /api/v0/devices

      Input (JSON):

      Fields:

      • hostname (required): device hostname or IP
      • display: A string to display as the name of this device, defaults to hostname (or device_display_default setting). May be a simple template using replacements: {{ $hostname }}, {{ $sysName }}, {{ $sysName_fallback }}, {{ $ip }}
      • snmpver: SNMP version to use, v1, v2c or v3. During checks detection order is v2c,v3,v1
      • port: SNMP port (defaults to port defined in config).
      • transport: SNMP protocol (udp,tcp,udp6,tcp6) Defaults to transport defined in config.
      • port_association_mode: method to identify ports: ifIndex (default), ifName, ifDescr, ifAlias
      • poller_group: This is the poller_group id used for distributed poller setup. Defaults to 0.
      • location or location_id: set the location by text or location id

      Options:

      • force_add: Skip all checks and attempts to detect credentials. Add the device as given directly to the database.
      • ping_fallback: if snmp checks fail, add the device as ping only instead of failing

      SNMP v1 or v2c credentials:

      • community: Required for SNMP v1 or v2c.

      SNMP v3 credentials:

      • authlevel: SNMP authlevel (noAuthNoPriv, authNoPriv, authPriv).
      • authname: SNMP Auth username
      • authpass: SNMP Auth password
      • authalgo: SNMP Auth algorithm (MD5, SHA) (SHA-224, SHA-256, SHA-384, SHA-512 if supported by your server)
      • cryptopass: SNMP Crypto Password
      • cryptoalgo: SNMP Crypto algorithm (AES, DES)

      For ICMP only:

      • snmp_disable: set to true for ICMP only. Disables SNMP checks and polling.
      • os: OS short name for the device (defaults to ping).
      • sysName: sysName for the device.
      • hardware: Device hardware.

      Example:

      curl -X POST -d '{\"hostname\":\"localhost.localdomain\",\"version\":\"v1\",\"community\":\"public\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device localhost.localdomain (57) has been added successfully\",\n    \"devices\": [\n        {\n            \"device_id\": \"57\",\n            \"hostname\": \"localhost\",\n            ...\n            \"serial\": null,\n            \"icon\": null\n        }\n}\n
      "},{"location":"API/Devices/#list_oxidized","title":"list_oxidized","text":"

      List devices for use with Oxidized. If you have group support enabled then a group will also be returned based on your config.

      LibreNMS will automatically map the OS to the Oxidized model name if they don't match.

      Route: /api/v0/oxidized(/:hostname)

      Input (JSON):

      -

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized\n

      Output:

      [\n    {\n        \"hostname\": \"localhost\",\n        \"os\": \"linux\"\n    },\n    {\n        \"hostname\": \"otherserver\",\n        \"os\": \"linux\"\n    }\n]\n
      "},{"location":"API/Devices/#update_device_field","title":"update_device_field","text":"

      Update devices field in the database.

      Route: /api/v0/devices/:hostname

      • hostname can be either the device hostname or id

      Input (JSON):

      • field: The column name within the database (can be an array of fields)
      • data: The data to update the column with (can be an array of data))

      Examples:

      curl -X PATCH -d '{\"field\": \"notes\", \"data\": \"This server should be kept online\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Device notes has been updated\"\n    }\n]\n
      "},{"location":"API/Devices/#update_device_port_notes","title":"update_device_port_notes","text":"

      Update a device port notes field in the devices_attrs database.

      Route: /api/v0/devices/:hostname/port/:portid

      • hostname can be either the device hostname or id
      • portid needs to be the port unique id (int).

      Input (JSON): - notes: The string data to populate on the port notes field.

      Examples:

      curl -X PATCH -d '{\"notes\": \"This port is in a scheduled maintenance with the provider.\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/port/5\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Port notes field has been updated\"\n    }\n]\n
      curl -X PATCH -d '{\"field\": [\"notes\",\"purpose\"], \"data\": [\"This server should be kept online\", \"For serving web traffic\"]}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Device fields have been updated\"\n    }\n]\n
      "},{"location":"API/Devices/#rename_device","title":"rename_device","text":"

      Rename device.

      Route: /api/v0/devices/:hostname/rename/:new_hostname

      • hostname can be either the device hostname or id

      Input:

      -

      Examples:

      curl -X PATCH  -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/rename/localhost2\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Device has been renamed\"\n    }\n]\n
      "},{"location":"API/Devices/#get_device_groups","title":"get_device_groups","text":"

      List the device groups that a device is matched on.

      Route: /api/v0/devices/:hostname/groups

      • hostname can be either the device hostname or id

      Input (JSON):

      -

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/groups\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Found 1 device groups\",\n        \"count\": 1,\n        \"groups\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Testing\",\n            \"desc\": \"Testing\",\n            \"pattern\": \"%devices.status = \\\"1\\\" &&\"\n        }\n        ]\n    }\n]\n
      "},{"location":"API/Devices/#search_oxidized","title":"search_oxidized","text":"

      search all oxidized device configs for a string.

      Route: api/v0/oxidized/config/search/:searchstring

      • searchstring is the specific string you would like to search for.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized/config/search/vlan10\n

      Output:

      {\n    \"status\": \"ok\",\n    \"nodes\": [\n        {\n            \"node\": \"asr9k.librenms.org\",\n            \"full_name\": \"cisco\\/ASR9K.Librenms.org\"\n        },\n        {\n            \"node\": \"ios.Librenms.org\",\n            \"full_name\": \"cisco\\/ios.Librenms.org\"\n        }\n    ],\n    \"count\": 2\n}\n

      "},{"location":"API/Devices/#get_oxidized_config","title":"get_oxidized_config","text":"

      Returns a specific device's config from oxidized.

      Route: api/v0/oxidized/config/:hostname

      • hostname is the Hostname or IP of the device used when adding the device to librenms.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized/config/router.corp.com\n

      Output:

      {\n    \"status\": \"ok\",\n    \"config\": \"DEVICE CONFIG HERE\"\n}\n

      "},{"location":"API/Devices/#add_parents_to_host","title":"add_parents_to_host","text":"

      Add one or more parents to a host.

      Route: /api/v0/devices/:device/parents

      Input (JSON):

      • parent_ids: one or more parent ids or hostnames

      Example:

      curl -X POST -d '{\"parent_ids\":\"15,16,17\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/1/parents\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Device dependencies have been saved\"\n}\n

      "},{"location":"API/Devices/#delete_parents_from_host","title":"delete_parents_from_host","text":"

      Deletes some or all the parents from a host.

      Route: /api/v0/devices/:device/parents

      Input (JSON):

      • parent_ids: One or more parent ids or hostnames, if not specified deletes all parents from host.

      Example:

      curl -X DELETE -d '{\"parent_ids\":\"15,16,17\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/1/parents\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"All device dependencies have been removed\"\n}\n

      "},{"location":"API/Devices/#list_parents_of_host","title":"list_parents_of_host","text":"

      This is not a seperate API call. Instead, you obtain the list of parents from list_devices. See that entry point for more detailed information.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' 'http://librenms.org/api/v0/devices?type=device_id&query=34'\n

      Output:

      {\n    \"status\": \"ok\",\n    \"devices\": [\n        {\n            ...\n            \"dependency_parent_id\": \"98,99\",\n            \"dependency_parent_hostname\": \"HOSTNAME1,HOSTNAME2\",\n            ...\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Inventory/","title":"Inventory","text":""},{"location":"API/Inventory/#get_inventory","title":"get_inventory","text":"

      Retrieve the inventory for a device. If you call this without any parameters then you will only get part of the inventory. This is because a lot of devices nest each component, for instance you may initially have the chassis, within this the ports - 1 being an sfp cage, then the sfp itself. The way this API call is designed is to enable a recursive lookup. The first call will retrieve the root entry, included within this response will be entPhysicalIndex, you can then call for entPhysicalContainedIn which will then return the next layer of results. To retrieve all items together, see get_inventory_for_device.

      Route: /api/v0/inventory/:hostname

      • hostname can be either the device hostname or the device id

      Input:

      • entPhysicalClass: This is used to restrict the class of the inventory, for example you can specify chassis to only return items in the inventory that are labelled as chassis.
      • entPhysicalContainedIn: This is used to retrieve items within the inventory assigned to a previous component, for example specifying the chassis (entPhysicalIndex) will retrieve all items where the chassis is the parent.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/inventory/localhost?entPhysicalContainedIn=65536\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"inventory\": [\n        {\n            \"entPhysical_id\": \"2\",\n            \"device_id\": \"32\",\n            \"entPhysicalIndex\": \"262145\",\n            \"entPhysicalDescr\": \"Linux 3.3.5 ehci_hcd RB400 EHCI\",\n            \"entPhysicalClass\": \"unknown\",\n            \"entPhysicalName\": \"1:1\",\n            \"entPhysicalHardwareRev\": \"\",\n            \"entPhysicalFirmwareRev\": \"\",\n            \"entPhysicalSoftwareRev\": \"\",\n            \"entPhysicalAlias\": \"\",\n            \"entPhysicalAssetID\": \"\",\n            \"entPhysicalIsFRU\": \"false\",\n            \"entPhysicalModelName\": \"0x0002\",\n            \"entPhysicalVendorType\": \"zeroDotZero\",\n            \"entPhysicalSerialNum\": \"rb400_usb\",\n            \"entPhysicalContainedIn\": \"65536\",\n            \"entPhysicalParentRelPos\": \"-1\",\n            \"entPhysicalMfgName\": \"0x1d6b\",\n            \"ifIndex\": \"0\"\n        }\n    ]\n}\n
      "},{"location":"API/Inventory/#get_inventory_for_device","title":"get_inventory_for_device","text":"

      Retrieve the flattened inventory for a device. This retrieves all inventory items for a device regardless of their structure, and may be more useful for devices with with nested components.

      Route: /api/v0/inventory/:hostname/all

      • hostname can be either the device hostname or the device id

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/inventory/localhost?entPhysicalContainedIn=65536\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"inventory\": [\n        {\n            \"entPhysical_id\": \"2\",\n            \"device_id\": \"32\",\n            \"entPhysicalIndex\": \"262145\",\n            \"entPhysicalDescr\": \"Linux 3.3.5 ehci_hcd RB400 EHCI\",\n            \"entPhysicalClass\": \"unknown\",\n            \"entPhysicalName\": \"1:1\",\n            \"entPhysicalHardwareRev\": \"\",\n            \"entPhysicalFirmwareRev\": \"\",\n            \"entPhysicalSoftwareRev\": \"\",\n            \"entPhysicalAlias\": \"\",\n            \"entPhysicalAssetID\": \"\",\n            \"entPhysicalIsFRU\": \"false\",\n            \"entPhysicalModelName\": \"0x0002\",\n            \"entPhysicalVendorType\": \"zeroDotZero\",\n            \"entPhysicalSerialNum\": \"rb400_usb\",\n            \"entPhysicalContainedIn\": \"65536\",\n            \"entPhysicalParentRelPos\": \"-1\",\n            \"entPhysicalMfgName\": \"0x1d6b\",\n            \"ifIndex\": \"0\"\n        }\n    ]\n}\n
      "},{"location":"API/Locations/","title":"Locations","text":""},{"location":"API/Locations/#list_locations","title":"list_locations","text":"

      Return a list of locations.

      Route: /api/v0/resources/locations

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/locations\n

      Output:

      {\n    \"status\": \"ok\",\n    \"locations\": [\n        {\n            \"id\": \"1\",\n            \"location\": \"Example location, Example city, Example Country\",\n            \"lat\": \"-18.911436\",\n            \"lng\": \"47.517446\",\n            \"timestamp\": \"2017-04-01 02:40:05\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Locations/#add_location","title":"add_location","text":"

      Add a new location

      Route: /api/v0/locations/

      Input:

      • location: name of the new location
      • lat: latitude
      • lng: longitude
      • fixed_coordinates: 0 if updated from the device or 1 if the coordinate is fixed (default is fixed if lat and lng are valid)

      Example:

      curl -X POST -d '{\"location\":\"Google\", \"lat\":\"37.4220041\",\"lng\":\"-122.0862462\"}' -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/locations\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Location added with id #45\"\n}\n
      "},{"location":"API/Locations/#delete_location","title":"delete_location","text":"

      Deletes an existing location

      Route: /api/v0/locations/:location

      • location: name or id of the location to delete

      Example:

      curl -X DELETE -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/locations/Google\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Location Google has been deleted successfully\"\n\n}\n
      "},{"location":"API/Locations/#edit_location","title":"edit_location","text":"

      Edits a location

      Route: /api/v0/locations/:location

      • location: name or id of the location to edit

      Input:

      • lat: latitude
      • lng: longitude

      Example:

      curl -X PATCH -d '{\"lng\":\"100.0862462\"}' -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/locations/Google\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Location updated successfully\"\n}\n
      "},{"location":"API/Locations/#get_location","title":"get_location","text":"

      Gets a specific location

      Route: /api/v0/location/:location

      • location: name or id of the location to get

      Output:

      {\n    \"status\": \"ok\",\n    \"get_location\": [\n        {\n            \"id\": 1,\n            \"location\": \"TEST\",\n            \"lat\": 00.000000,\n            \"lng\": 00.000000,\n            \"timestamp\": \"2023-01-01 00:00:00\",\n            \"fixed_coordinates\": 1\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Logs/","title":"Logs","text":"

      All the list_*logs calls are aliased to list_logs.

      Retrieve all logs or logs for a specific device.

      • id or hostname is the specific device

      Input:

      • start: The page number to request.
      • limit: The limit of results to be returned.
      • from: The date and time or the event id to search from.
      • to: The data and time or the event id to search to.
      "},{"location":"API/Logs/#list_eventlog","title":"list_eventlog","text":"

      Route: /api/v0/logs/eventlog/:hostname

      "},{"location":"API/Logs/#list_syslog","title":"list_syslog","text":"

      Route: /api/v0/logs/syslog/:hostname

      "},{"location":"API/Logs/#list_alertlog","title":"list_alertlog","text":"

      Route: /api/v0/logs/alertlog/:hostname

      "},{"location":"API/Logs/#list_authlog","title":"list_authlog","text":"

      Route: /api/v0/logs/authlog/:hostname

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/eventlog/:hostname\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/syslog/:hostname?limit=20\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/eventlog/:hostname?limit=20&start=5&from=2017-07-22%2023:00:00\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/logs/eventlog/:hostname?sortorder=DESC\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 5,\n    \"total\": \"15\",\n    \"logs\": [\n        {\n            \"hostname\": \"localhost\",\n            \"sysName\": \"web01.1.novalocal\",\n            \"event_id\": \"10050349\",\n            \"host\": \"279\",\n            \"device_id\": \"279\",\n            \"datetime\": \"2017-07-22 19:57:47\",\n            \"message\": \"ifAlias:  ->  <pptp-something-something-tunnel-something>\",\n            \"type\": \"interface\",\n            \"reference\": \"NULL\",\n            \"username\": \"\",\n            \"severity\": \"3\"\n        },\n        ....\n        {\n            \"hostname\": \"localhost\",\n            \"sysName\": \"web01.1.novalocal\",\n            \"event_id\": \"10050353\",\n            \"host\": \"279\",\n            \"device_id\": \"279\",\n            \"datetime\": \"2017-07-22 19:57:47\",\n            \"message\": \"ifHighSpeed:  ->  0\",\n            \"type\": \"interface\",\n            \"reference\": \"NULL\",\n            \"username\": \"\",\n            \"severity\": \"3\"\n        }\n    ]\n}\n
      "},{"location":"API/Logs/#syslogsink","title":"syslogsink","text":"

      Route: /api/v0/logs/syslogsink

      Accept any json messages and passes to further syslog processing. single messages or an array of multiple messages is accepted. see Syslog for more details and logstash integration

      Example

      curl -L -X POST 'https://sink.librenms.org/api/v0/syslogsink/' -H 'X-Auth-Token: xxxxxxxLibreNMSApiToken' --data-raw '[   \n    {\n        \"msg\": \"kernel: minimum Message\",\n        \"host\": \"mydevice.fqdn.com\"\n    },\n    {\n        \"msg\": \"Line protocol on Interface GigabitEthernet1/0/41, changed state to up\",\n        \"facility\": 23,\n        \"priority\": \"189\",\n        \"program\": \"LINEPROTO-5-UPDOWN\",\n        \"host\": \"172.29.10.24\",\n        \"@timestamp\": \"2022-12-01T20:14:28.257Z\",\n        \"severity\": 5,\n        \"level\": \"ERROR\"\n    },\n    {\n        \"msg\": \"kernel: a unknown host\",\n        \"host\": \"unknown.fqdn.com\"\n    }\n]'\n

      "},{"location":"API/PollerGroups/","title":"PollerGroups","text":""},{"location":"API/PollerGroups/#get_poller_group","title":"get_poller_group","text":"

      Gets a specific poller group or all if none is specified

      Route: /api/v0/poller_group/:poller_group

      • poller_group: optional name or id of the poller group to get

      Output:

      {\n    \"status\": \"ok\",\n    \"get_poller_group\": [\n        {\n            \"id\": 1,\n            \"group_name\": \"test\",\n            \"descr\": \"test group\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/PortGroups/","title":"PortGroups","text":""},{"location":"API/PortGroups/#get_graph_by_portgroup","title":"get_graph_by_portgroup","text":"

      Get the graph based on the group type.

      Route: /api/v0/portgroups/:group

      • group is the type of port group graph you want, I.e Transit, Peering, etc. You can specify multiple types comma separated.

      Input:

      • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • width: The graph width, defaults to 1075.
      • height: The graph height, defaults to 300.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/portgroups/transit,peering\n

      Output:

      Output is an image.

      "},{"location":"API/PortGroups/#get_graph_by_portgroup_multiport_bits","title":"get_graph_by_portgroup_multiport_bits","text":"

      Get the graph based on the multiple port id separated by commas ,.

      Route: /api/v0/portgroups/multiport/bits/:id

      • id is a comma separated list of port ids you want, I.e 1,2,3,4, etc. You can specify multiple IDs comma separated.

      Input:

      • from: This is the date you would like the graph to start - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • to: This is the date you would like the graph to end - See http://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html for more information.
      • width: The graph width, defaults to 1075.
      • height: The graph height, defaults to 300.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/portgroups/multiport/bits/1,2,3\n

      Output:

      Output is an image.

      "},{"location":"API/Port_Groups/","title":"Port_Groups","text":""},{"location":"API/Port_Groups/#get_port_groups","title":"get_port_groups","text":"

      List all port groups.

      Route: /api/v0/port_groups

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/port_groups\n

      Output:

      [\n    {\n        \"status\": \"ok\",\n        \"message\": \"Found 1 port groups\",\n        \"count\": 1,\n        \"groups\": [\n        {\n            \"id\": \"1\",\n            \"name\": \"Testing\",\n            \"desc\": \"Testing\"\n        }\n        ]\n    }\n]\n
      "},{"location":"API/Port_Groups/#get_ports_by_group","title":"get_ports_by_group","text":"

      List all ports matching the group provided.

      Route: /api/v0/port_groups/:name

      • name Is the name of the port group which can be obtained using get_port_groups. Please ensure that the name is urlencoded if it needs to be (i.e Linux Servers would need to be urlencoded.

      Params:

      • full: set to any value to return all data for the devices in a given group

      Examples:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/port_groups/Billable\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ports\": [\n        {\n            \"port_id\": 1376\n        },\n        {\n            \"port_id\": 2376\n        }\n    ],\n    \"count\": 2\n}\n
      "},{"location":"API/Port_Groups/#add_port_group","title":"add_port_group","text":"

      Add a new port group. Upon success, the ID of the new port group is returned and the HTTP response code is 201.

      Route: /api/v0/port_groups

      Input (JSON):

      • name: required - The name of the port group
      • desc: optional - Description of the port group

      Examples:

      Dynamic Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' \\\n  -X POST \\\n  -d '{\"name\": \"New Port Group\", \\\n       \"desc\": \"A very fancy port group\"}' \\\n  https://librenms.org/api/v0/port_groups\n

      Output:

      {\n    \"status\": \"ok\",\n    \"id\": 86,\n    \"message\": \"Port group New Port Group created\"\n}\n
      "},{"location":"API/Port_Groups/#assign_port_group","title":"assign_port_group","text":"

      Assign a Port Group to a list of Ports

      Route: /api/v0/port_groups/:port_group_id/assign

      Input (JSON):

      • port_ids: required - List of Port Ids

      Examples:

      Dynamic Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' -X POST -d '{\"port_ids\": [\"4\",\"34\",\"25,\"983\"]}' https://librenms.org/api/v0/port_groups/3/assign\n

      Output:

      {\n    \"status\": \"ok\",\n    \"Port Ids 4, 34, 25, 983 have been added to Port Group Id 3\": 200\n}\n
      "},{"location":"API/Port_Groups/#remove_port_group","title":"remove_port_group","text":"

      Remove a Port Group from a list of Ports

      Route: /api/v0/port_groups/:port_group_id/remove

      Input (JSON):

      • port_ids: required - List of Port Ids

      Examples:

      Dynamic Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' -X POST -d '{\"port_ids\": [\"4\",\"34\",\"25,\"983\"]}' https://librenms.org/api/v0/port_groups/3/remove\n

      Output:

      {\n    \"status\": \"ok\",\n    \"Port Ids 4, 34, 25, 983 have been removed from Port Group Id 3\": 200\n}\n
      "},{"location":"API/Ports/","title":"Ports","text":""},{"location":"API/Ports/#get_all_ports","title":"get_all_ports","text":"

      Get info for all ports on all devices. Strongly recommend that you use the columns parameter to avoid pulling too much data.

      Route: /api/v0/ports

      -

      Input:

      • columns: Comma separated list of columns you want returned.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports?columns=ifName%2Cport_id\n

      Output:

      {\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"ports\": [\n        {\n          \"ifName\": \"Gi0/0/0\",\n          \"port_id\": \"1\"\n        },\n        {\n          \"ifName\": \"Gi0/0/1\",\n          \"port_id\": \"2\"\n        },\n        ...\n        {\n          \"ifName\": \"Vlan 3615\",\n          \"port_id\": \"5488\"\n        }\n    ]\n}\n
      "},{"location":"API/Ports/#search_ports","title":"search_ports","text":"

      Search for ports matching the query.

      Route: /api/v0/ports/search/:search

      • search string to search in fields: ifAlias, ifDescr, and ifName

      Input:

      • columns: Comma separated list of columns you want returned.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/search/lo\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ports\": [\n        {\n            \"device_id\": 1,\n            \"port_id\": 1,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 2,\n            \"port_id\": 3,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 3,\n            \"port_id\": 5,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        }\n    ]\n}\n
      "},{"location":"API/Ports/#search_ports-in-specific-fields","title":"search_ports in specific field(s)","text":"

      Specific search for ports matching the query.

      Route: /api/v0/ports/search/:field/:search

      • field: comma separated list of field(s) to search
      • search: string to search in fields

      Input:

      • columns: Comma separated list of columns you want returned.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/search/ifName/lo\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ports\": [\n        {\n            \"device_id\": 1,\n            \"port_id\": 1,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 2,\n            \"port_id\": 3,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        },\n        {\n            \"device_id\": 3,\n            \"port_id\": 5,\n            \"ifIndex\": 1,\n            \"ifName\": \"lo\"\n        }\n    ]\n}\n
      "},{"location":"API/Ports/#ports_with_associated_mac","title":"ports_with_associated_mac","text":"

      Search for ports matching the search mac.

      Route: /api/v0/ports/mac/:search?filter=first

      • search a mac address in fdb and print the ports ordered by the mac count of the associated port.

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/00:11:22:33:44:55\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/001122.334455?filter=first\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/mac/001122334455?filter=first\n

      Output:

      {\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"port\": [\n    {\n      \"port_id\": \"323\",\n      \"device_id\": \"55\",\n      \"port_descr_type\": null,\n      \"port_descr_descr\": null,\n      \"port_descr_circuit\": null,\n      \"port_descr_speed\": null,\n      \"port_descr_notes\": null,\n      \"ifDescr\": \"GigabitEthernet0/0/0\",\n      \"ifName\": \"Gi0/0/0\",\n      \"portName\": null,\n      \"ifIndex\": \"1\",\n      \"ifSpeed\": \"1000000000\",\n      \"ifConnectorPresent\": \"true\",\n      \"ifPromiscuousMode\": \"false\",\n      \"ifHighSpeed\": \"1000\",\n      \"ifOperStatus\": \"up\",\n      \"ifOperStatus_prev\": null,\n      \"ifAdminStatus\": \"up\",\n      \"ifAdminStatus_prev\": null,\n      \"ifDuplex\": \"fullDuplex\",\n      \"ifMtu\": \"1560\",\n      \"ifType\": \"ethernetCsmacd\",\n      \"ifAlias\": \"ASR Interconnect Trunk\",\n      \"ifPhysAddress\": \"84bf20853e00\",\n      \"ifHardType\": null,\n      \"ifLastChange\": \"42407358\",\n      \"ifVlan\": \"\",\n      \"ifTrunk\": \"\",\n      \"ifVrf\": \"0\",\n      \"counter_in\": null,\n      \"counter_out\": null,\n      \"ignore\": \"0\",\n      \"disabled\": \"0\",\n      \"detailed\": \"0\",\n      \"deleted\": \"0\",\n      \"pagpOperationMode\": null,\n      \"pagpPortState\": null,\n      \"pagpPartnerDeviceId\": null,\n      \"pagpPartnerLearnMethod\": null,\n      \"pagpPartnerIfIndex\": null,\n      \"pagpPartnerGroupIfIndex\": null,\n      \"pagpPartnerDeviceName\": null,\n      \"pagpEthcOperationMode\": null,\n      \"pagpDeviceId\": null,\n      \"pagpGroupIfIndex\": null,\n      \"ifInUcastPkts\": \"128518576\",\n      \"ifInUcastPkts_prev\": \"128517284\",\n      \"ifInUcastPkts_delta\": \"1292\",\n      \"ifInUcastPkts_rate\": \"4\",\n      \"ifOutUcastPkts\": \"128510560\",\n      \"ifOutUcastPkts_prev\": \"128509268\",\n      \"ifOutUcastPkts_delta\": \"1292\",\n      \"ifOutUcastPkts_rate\": \"4\",\n      \"ifInErrors\": \"0\",\n      \"ifInErrors_prev\": \"0\",\n      \"ifInErrors_delta\": \"0\",\n      \"ifInErrors_rate\": \"0\",\n      \"ifOutErrors\": \"0\",\n      \"ifOutErrors_prev\": \"0\",\n      \"ifOutErrors_delta\": \"0\",\n      \"ifOutErrors_rate\": \"0\",\n      \"ifInOctets\": \"12827393730\",\n      \"ifInOctets_prev\": \"12827276736\",\n      \"ifInOctets_delta\": \"116994\",\n      \"ifInOctets_rate\": \"387\",\n      \"ifOutOctets\": \"14957481766\",\n      \"ifOutOctets_prev\": \"14957301765\",\n      \"ifOutOctets_delta\": \"180001\",\n      \"ifOutOctets_rate\": \"596\",\n      \"poll_time\": \"1483779150\",\n      \"poll_prev\": \"1483778848\",\n      \"poll_period\": \"302\"\n    }\n  ]\n}\n
      "},{"location":"API/Ports/#get_port_info","title":"get_port_info","text":"

      Get all info for a particular port.

      Route: /api/v0/ports/:portid

      • portid must be an integer

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323\n

      Output:

      {\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"port\": [\n    {\n      \"port_id\": \"323\",\n      \"device_id\": \"55\",\n      \"port_descr_type\": null,\n      \"port_descr_descr\": null,\n      \"port_descr_circuit\": null,\n      \"port_descr_speed\": null,\n      \"port_descr_notes\": null,\n      \"ifDescr\": \"GigabitEthernet0/0/0\",\n      \"ifName\": \"Gi0/0/0\",\n      \"portName\": null,\n      \"ifIndex\": \"1\",\n      \"ifSpeed\": \"1000000000\",\n      \"ifConnectorPresent\": \"true\",\n      \"ifPromiscuousMode\": \"false\",\n      \"ifHighSpeed\": \"1000\",\n      \"ifOperStatus\": \"up\",\n      \"ifOperStatus_prev\": null,\n      \"ifAdminStatus\": \"up\",\n      \"ifAdminStatus_prev\": null,\n      \"ifDuplex\": \"fullDuplex\",\n      \"ifMtu\": \"1560\",\n      \"ifType\": \"ethernetCsmacd\",\n      \"ifAlias\": \"ASR Interconnect Trunk\",\n      \"ifPhysAddress\": \"84bf20853e00\",\n      \"ifHardType\": null,\n      \"ifLastChange\": \"42407358\",\n      \"ifVlan\": \"\",\n      \"ifTrunk\": \"\",\n      \"ifVrf\": \"0\",\n      \"counter_in\": null,\n      \"counter_out\": null,\n      \"ignore\": \"0\",\n      \"disabled\": \"0\",\n      \"detailed\": \"0\",\n      \"deleted\": \"0\",\n      \"pagpOperationMode\": null,\n      \"pagpPortState\": null,\n      \"pagpPartnerDeviceId\": null,\n      \"pagpPartnerLearnMethod\": null,\n      \"pagpPartnerIfIndex\": null,\n      \"pagpPartnerGroupIfIndex\": null,\n      \"pagpPartnerDeviceName\": null,\n      \"pagpEthcOperationMode\": null,\n      \"pagpDeviceId\": null,\n      \"pagpGroupIfIndex\": null,\n      \"ifInUcastPkts\": \"128518576\",\n      \"ifInUcastPkts_prev\": \"128517284\",\n      \"ifInUcastPkts_delta\": \"1292\",\n      \"ifInUcastPkts_rate\": \"4\",\n      \"ifOutUcastPkts\": \"128510560\",\n      \"ifOutUcastPkts_prev\": \"128509268\",\n      \"ifOutUcastPkts_delta\": \"1292\",\n      \"ifOutUcastPkts_rate\": \"4\",\n      \"ifInErrors\": \"0\",\n      \"ifInErrors_prev\": \"0\",\n      \"ifInErrors_delta\": \"0\",\n      \"ifInErrors_rate\": \"0\",\n      \"ifOutErrors\": \"0\",\n      \"ifOutErrors_prev\": \"0\",\n      \"ifOutErrors_delta\": \"0\",\n      \"ifOutErrors_rate\": \"0\",\n      \"ifInOctets\": \"12827393730\",\n      \"ifInOctets_prev\": \"12827276736\",\n      \"ifInOctets_delta\": \"116994\",\n      \"ifInOctets_rate\": \"387\",\n      \"ifOutOctets\": \"14957481766\",\n      \"ifOutOctets_prev\": \"14957301765\",\n      \"ifOutOctets_delta\": \"180001\",\n      \"ifOutOctets_rate\": \"596\",\n      \"poll_time\": \"1483779150\",\n      \"poll_prev\": \"1483778848\",\n      \"poll_period\": \"302\"\n    }\n  ]\n}\n
      "},{"location":"API/Ports/#get_port_ip_info","title":"get_port_ip_info","text":"

      Get all IP info (v4 and v6) for a given port id.

      Route: /api/v0/ports/:portid/ip

      • portid must be an integer

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323/ip\n

      Output:

      {\n  \"status\": \"ok\",\n  \"message\": \"\",\n  \"addresses\": [\n    {\n      \"ipv4_address_id\": \"290\",\n      \"ipv4_address\": \"192.168.99.292\",\n      \"ipv4_prefixlen\": \"30\",\n      \"ipv4_network_id\": \"247\",\n      \"port_id\": \"323\",\n      \"context_name\": \"\"\n    }\n  ]\n}\n
      "},{"location":"API/Ports/#get_port_description","title":"get_port_description","text":"

      Get the description (ifAlias) for a given port id.

      Route: /api/v0/ports/:portid/description

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323/description\n

      Output:

      {\n    \"status\": \"ok\",\n    \"port_description\": \"GigabitEthernet14\"\n}\n
      "},{"location":"API/Ports/#update_port_description","title":"update_port_description","text":"

      Change the description (ifAlias) for a given port id.

      Route: /api/v0/ports/:portid/description

      Input (JSON):

      • description: The string data to use as the new port description. Sending an empty string will reset the description to default.

      Example:

      curl -X PATCH -d '{\"description\": \"Out-of-Band Management Link\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ports/323/description\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Port description updated.\"\n}\n

      "},{"location":"API/Routing/","title":"Routing","text":""},{"location":"API/Routing/#list_bgp","title":"list_bgp","text":"

      List the current BGP sessions.

      Route: /api/v0/bgp

      Input:

      • hostname = Either the devices hostname or id.
      • asn = The local ASN you would like to filter by
      • remote_asn = Filter by remote peer ASN
      • remote_address = Filter by remote peer address
      • local_address = Filter by local address
      • bgp_descr = Filter by BGP neighbor description
      • bgp_state = Filter by BGP session state (like established,idle...)
      • bgp_state = Filter by BGP admin state (start,stop,running...)
      • bgp_family = Filter by BGP address Family (4,6)

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?hostname=host.example.com\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?asn=1234\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?remote_asn=1234\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?local_address=1.1.1.1&remote_address=2.2.2.2\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_descr=UPSTREAM\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_state=established\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_adminstate=start\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_family=6\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp?bgp_state=idle&bgp_descr=CORE&bgp_family=4\n

      Output:

      {\n \"status\": \"ok\",\n \"message\": \"\",\n \"bgp_sessions\": [\n        {\n            \"bgpPeer_id\": 1260,\n            \"device_id\": 7,\n            \"vrf_id\": null,\n            \"astext\": \"Acme Ltd\",\n            \"bgpPeerIdentifier\": \"2001:0DB8:0000:24cb:0000:0000:0000:0001\",\n            \"bgpPeerRemoteAs\": 65432,\n            \"bgpPeerState\": \"established\",\n            \"bgpPeerAdminStatus\": \"start\",\n            \"bgpPeerLastErrorCode\": 6,\n            \"bgpPeerLastErrorSubCode\": 2,\n            \"bgpPeerLastErrorText\": \"administrative shutdown\",\n            \"bgpPeerIface\": 268,\n            \"bgpLocalAddr\": \"2001:0DB8:0000:24cb:0000:0000:0000:0002\",\n            \"bgpPeerRemoteAddr\": \"0.0.0.0\",\n            \"bgpPeerDescr\": \"Another one #CORE\",\n            \"bgpPeerInUpdates\": 283882969,\n            \"bgpPeerOutUpdates\": 7008,\n            \"bgpPeerInTotalMessages\": 283883031,\n            \"bgpPeerOutTotalMessages\": 1386692,\n            \"bgpPeerFsmEstablishedTime\": 1628487,\n            \"bgpPeerInUpdateElapsedTime\": 0,\n            \"context_name\": \"\"\n        },\n    ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Routing/#get_bgp","title":"get_bgp","text":"

      Retrieves a BGP session by ID

      Route: /api/v0/bgp/:id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/bgp/4\n

      Output:

      {\n    \"status\": \"ok\",\n    \"bgp_session\": [\n        {\n            \"bgpPeer_id\": \"4\",\n            \"device_id\": \"2\",\n            \"astext\": \"\",\n            \"bgpPeerIdentifier\": \"1234:1b80:1:12::2\",\n            \"bgpPeerRemoteAs\": \"54321\",\n            \"bgpPeerState\": \"established\",\n            \"bgpPeerAdminStatus\": \"running\",\n            \"bgpLocalAddr\": \"1234:1b80:1:12::1\",\n            \"bgpPeerRemoteAddr\": \"0.0.0.0\",\n            \"bgpPeerInUpdates\": \"3\",\n            \"bgpPeerOutUpdates\": \"1\",\n            \"bgpPeerInTotalMessages\": \"0\",\n            \"bgpPeerOutTotalMessages\": \"0\",\n            \"bgpPeerFsmEstablishedTime\": \"0\",\n            \"bgpPeerInUpdateElapsedTime\": \"0\",\n            \"context_name\": \"\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Routing/#edit_bgp_descr","title":"edit_bgp_descr","text":"

      This is a POST type request Set the BGP session description by ID

      Route: /api/v0/bgp/:id

      Input:

      • id = The id of the BGP Peer Session.
      • bgp_descr = The description for the bgpPeerDescr field on the BGP Session.

      Example:

      curl -v -H 'X-Auth-Token: YOURAPITOKENHERE' --data '{\"bgp_descr\": \"Your description here\"}' https://librenms.org/api/v0/bgp/4\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"BGP description for peer X.X.X.X on device 1 updated to Your description here\"\n}\n
      "},{"location":"API/Routing/#list_cbgp","title":"list_cbgp","text":"

      List the current BGP sessions counters.

      Route: /api/v0/routing/bgp/cbgp

      Input:

      • hostname = Either the devices hostname or id

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/bgp/cbgp\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/bgp/cbgp?hostname=host.example.com\n

      Output:

      {\n    \"status\": \"ok\",\n    \"bgp_counters\": [\n        {\n            \"device_id\": \"9\",\n            \"bgpPeerIdentifier\": \"192.168.99.31\",\n            \"afi\": \"ipv4\",\n            \"safi\": \"multicast\",\n            \"AcceptedPrefixes\": \"2\",\n            \"DeniedPrefixes\": \"0\",\n            \"PrefixAdminLimit\": \"0\",\n            \"PrefixThreshold\": \"0\",\n            \"PrefixClearThreshold\": \"0\",\n            \"AdvertisedPrefixes\": \"11487\",\n            \"SuppressedPrefixes\": \"0\",\n            \"WithdrawnPrefixes\": \"10918\",\n            \"AcceptedPrefixes_delta\": \"-2\",\n            \"AcceptedPrefixes_prev\": \"2\",\n            \"DeniedPrefixes_delta\": \"0\",\n            \"DeniedPrefixes_prev\": \"0\",\n            \"AdvertisedPrefixes_delta\": \"-11487\",\n            \"AdvertisedPrefixes_prev\": \"11487\",\n            \"SuppressedPrefixes_delta\": \"0\",\n            \"SuppressedPrefixes_prev\": \"0\",\n            \"WithdrawnPrefixes_delta\": \"-10918\",\n            \"WithdrawnPrefixes_prev\": \"10918\",\n            \"context_name\": \"\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Routing/#list_ip_addresses","title":"list_ip_addresses","text":"

      List all IPv4 and IPv6 addresses.

      Route: /api/v0/resources/ip/addresses

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/addresses\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ip_addresses\": [\n        {\n            \"ipv4_address_id\": \"69\",\n            \"ipv4_address\": \"127.0.0.1\",\n            \"ipv4_prefixlen\": \"8\",\n            \"ipv4_network_id\": \"55\",\n            \"port_id\": \"135\",\n            \"context_name\": \"\"\n        },\n        ...\n    ],\n    \"count\": 55\n}\n
      "},{"location":"API/Routing/#get_network_ip_addresses","title":"get_network_ip_addresses","text":"

      Get all IPv4 and IPv6 addresses for particular network.

      Route: /api/v0/resources/ip/networks/:id/ip

      • id must be integer

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/networks/55/ip\n

      Output:

      {\n    \"status\": \"ok\",\n    \"addresses\": [\n        {\n            \"ipv4_address_id\": \"69\",\n            \"ipv4_address\": \"127.0.0.1\",\n            \"ipv4_prefixlen\": \"8\",\n            \"ipv4_network_id\": \"55\",\n            \"port_id\": \"135\",\n            \"context_name\": \"\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Routing/#list_ip_networks","title":"list_ip_networks","text":"

      List all IPv4 and IPv6 networks.

      Route: /api/v0/resources/ip/networks

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/ip/networks\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ip_networks\": [\n        {\n            \"ipv4_network_id\": \"1\",\n            \"ipv4_network\": \"127.0.0.0/8\",\n            \"context_name\": \"\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Routing/#list_ipsec","title":"list_ipsec","text":"

      List the current IPSec tunnels which are active.

      Route: /api/v0/routing/ipsec/data/:hostname

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/ipsec/data/localhost\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 0,\n    \"ipsec\": [\n        \"tunnel_id\": \"1\",\n        \"device_id\": \"1\",\n        \"peer_port\": \"0\",\n        \"peer_addr\": \"127.0.0.1\",\n        \"local_addr\": \"127.0.0.2\",\n        \"local_port\": \"0\",\n        \"tunnel_name\": \"\",\n        \"tunnel_status\": \"active\"\n    ]\n}\n

      Please note, this will only show active VPN sessions not all configured.

      "},{"location":"API/Routing/#list_ospf","title":"list_ospf","text":"

      List the current OSPF neighbours.

      Route: /api/v0/ospf

      Input:

      • hostname = Either the devices hostname or id.

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ospf\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ospf?hostname=host.example.com\n

      Output:

      {\n \"status\": \"ok\",\n \"ospf_neighbours\": [\n        {\n            \"device_id\": \"1\",\n            \"port_id\": \"0\",\n            \"ospf_nbr_id\": \"172.16.1.145.0\",\n            \"ospfNbrIpAddr\": \"172.16.1.145\",\n            \"ospfNbrAddressLessIndex\": \"0\",\n            \"ospfNbrRtrId\": \"172.16.0.140\",\n            \"ospfNbrOptions\": \"82\",\n            \"ospfNbrPriority\": \"1\",\n            \"ospfNbrState\": \"full\",\n            \"ospfNbrEvents\": \"5\",\n            \"ospfNbrLsRetransQLen\": \"0\",\n            \"ospfNbmaNbrStatus\": \"active\",\n            \"ospfNbmaNbrPermanence\": \"dynamic\",\n            \"ospfNbrHelloSuppressed\": \"false\",\n            \"context_name\": \"\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Routing/#list_ospf_ports","title":"list_ospf_ports","text":"

      List the current OSPF ports.

      Route: /api/v0/ospf_ports

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/ospf_ports\n

      Output:

      {\n \"status\": \"ok\",\n \"ospf_ports\": [\n        {\n          \"id\": 189086,\n          \"device_id\": 43,\n          \"port_id\": 2838,\n          \"ospf_port_id\": \"10.10.2.86.0\",\n          \"ospfIfIpAddress\": \"10.10.2.86\",\n          \"ospfAddressLessIf\": 0,\n          \"ospfIfAreaId\": \"0.0.0.0\",\n          \"ospfIfType\": \"pointToPoint\",\n          \"ospfIfAdminStat\": \"enabled\",\n          \"ospfIfRtrPriority\": 128,\n          \"ospfIfTransitDelay\": 1,\n          \"ospfIfRetransInterval\": 5,\n          \"ospfIfHelloInterval\": 10,\n          \"ospfIfRtrDeadInterval\": 40,\n          \"ospfIfPollInterval\": 90,\n          \"ospfIfState\": \"pointToPoint\",\n          \"ospfIfDesignatedRouter\": \"0.0.0.0\",\n          \"ospfIfBackupDesignatedRouter\": \"0.0.0.0\",\n          \"ospfIfEvents\": 33,\n          \"ospfIfAuthKey\": \"\",\n          \"ospfIfStatus\": \"active\",\n          \"ospfIfMulticastForwarding\": \"unicast\",\n          \"ospfIfDemand\": \"false\",\n          \"ospfIfAuthType\": \"0\",\n          \"ospfIfMetricIpAddress\": \"10.10.2.86\",\n          \"ospfIfMetricAddressLessIf\": 0,\n          \"ospfIfMetricTOS\": 0,\n          \"ospfIfMetricValue\": 10,\n          \"ospfIfMetricStatus\": \"active\",\n          \"context_name\": null\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Routing/#list_vrf","title":"list_vrf","text":"

      List the current VRFs.

      Route: /api/v0/routing/vrf

      Input:

      • hostname = Either the devices hostname or id

      OR

      • vrfname = The VRF name you would like to filter by

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf?hostname=host.example.com\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf?vrfname=Mgmt-vrf\n

      Output:

      {\n    \"status\": \"ok\",\n    \"vrfs\": [\n        {\n            \"vrf_id\": \"2\",\n            \"vrf_oid\": \"8.77.103.109.116.45.118.114.102\",\n            \"vrf_name\": \"Mgmt-vrf\",\n            \"mplsVpnVrfRouteDistinguisher\": \"\",\n            \"mplsVpnVrfDescription\": \"\",\n            \"device_id\": \"8\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Routing/#get_vrf","title":"get_vrf","text":"

      Retrieves VRF by ID

      Route: /api/v0/routing/vrf/:id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/vrf/2\n

      Output:

      {\n    \"status\": \"ok\",\n    \"vrf\": [\n        {\n            \"vrf_id\": \"2\",\n            \"vrf_oid\": \"8.77.103.109.116.45.118.114.102\",\n            \"vrf_name\": \"Mgmt-vrf\",\n            \"mplsVpnVrfRouteDistinguisher\": \"\",\n            \"mplsVpnVrfDescription\": \"\",\n            \"device_id\": \"8\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Routing/#list_mpls_services","title":"list_mpls_services","text":"

      List MPLS services

      Route: /api/v0/routing/mpls/services

      Input:

      • hostname = Either the devices hostname or id

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/services\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/services?hostname=host.example.com\n

      Output:

      {\n    \"status\": \"ok\",\n    \"mpls_services\": [\n        {\n            \"svc_id\": 1671,\n            \"svc_oid\": 27,\n            \"device_id\": 4,\n            \"svcRowStatus\": \"active\",\n            \"svcType\": \"tls\",\n            \"svcCustId\": 1,\n            \"svcAdminStatus\": \"up\",\n            \"svcOperStatus\": \"up\",\n            \"svcDescription\": \"\",\n            \"svcMtu\": 9008,\n            \"svcNumSaps\": 1,\n            \"svcNumSdps\": 0,\n            \"svcLastMgmtChange\": 2,\n            \"svcLastStatusChange\": 168,\n            \"svcVRouterId\": 0,\n            \"svcTlsMacLearning\": \"enabled\",\n            \"svcTlsStpAdminStatus\": \"disabled\",\n            \"svcTlsStpOperStatus\": \"down\",\n            \"svcTlsFdbTableSize\": 250,\n            \"svcTlsFdbNumEntries\": 0,\n            \"hostname\": \"host.example.com\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Routing/#list_mpls_saps","title":"list_mpls_saps","text":"

      List MPLS SAPs

      Route: /api/v0/routing/mpls/saps

      Input:

      • hostname = Either the devices hostname or id

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/saps\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/routing/mpls/saps?hostname=host.example.com\n

      Output:

      {\n    \"status\": \"ok\",\n    \"saps\": [\n        {\n            \"sap_id\": 1935,\n            \"svc_id\": 1660,\n            \"svc_oid\": 7,\n            \"sapPortId\": 16108921125,\n            \"ifName\": \"1/1/c2/1\",\n            \"device_id\": 3,\n            \"sapEncapValue\": \"0\",\n            \"sapRowStatus\": \"active\",\n            \"sapType\": \"epipe\",\n            \"sapDescription\": \"\",\n            \"sapAdminStatus\": \"up\",\n            \"sapOperStatus\": \"down\",\n            \"sapLastMgmtChange\": 2,\n            \"sapLastStatusChange\": 0,\n            \"hostname\": \"hostname=host.example.com\"\n         }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Services/","title":"Services","text":""},{"location":"API/Services/#list_services","title":"list_services","text":"

      Retrieve all services

      Route: /api/v0/services

      Input:

      • state: only which have a certain state (valid options are 0=Ok, 1=Warning, 2=Critical).
      • type: service type, used sql LIKE to find services, so for tcp, use type=tcp for http use type=http

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services?state=2\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services?state=0&type=tcp\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"services\": [\n        [\n            {\n                \"service_id\": \"13\",\n                \"device_id\": \"1\",\n                \"service_ip\": \"demo1.yourdomian.net\",\n                \"service_type\": \"ntp_peer\",\n                \"service_desc\": \"NTP\",\n                \"service_param\": \"-H 192.168.1.10\",\n                \"service_ignore\": \"0\",\n                \"service_status\": \"0\",\n                \"service_changed\": \"1470962470\",\n                \"service_message\": \"NTP OK: Offset -0.000717 secs\",\n                \"service_disabled\": \"0\",\n                \"service_ds\": \"{\\\"offset\\\":\\\"s\\\"}\"\n            }\n        ],\n        [\n            {\n                \"service_id\": \"2\",\n                \"device_id\": \"2\",\n                \"service_ip\": \"demo2.yourdomian.net\",\n                \"service_type\": \"esxi_hardware.py\",\n                \"service_desc\": \"vmware hardware\",\n                \"service_param\": \"-H 192.168.1.11 -U USER -P PASS -p\",\n                \"service_ignore\": \"0\",\n                \"service_status\": \"0\",\n                \"service_changed\": \"1471702206\",\n                \"service_message\": \"OK - Server: Supermicro X9SCL/X9SCM s/n: 0123456789 System BIOS: 2.2 2015-02-20\",\n                \"service_disabled\": \"0\",\n                \"service_ds\": \"{\\\"P2Vol_0_Processor_1_Vcore\\\":\\\"\\\",\\\"P2Vol_1_System_Board_1_-12V\\\":\\\"\\\",\\\"P2Vol_2_System_Board_1_12V\\\":\\\"\\\",\\\"P2Vol_3_System_Board_1_3.3VCC\\\":\\\"\\\",\\\"P2Vol_4_System_Board_1_5VCC\\\":\\\"\\\",\\\"P2Vol_5_System_Board_1_AVCC\\\":\\\"\\\",\\\"P2Vol_6_System_Board_1_VBAT\\\":\\\"\\\",\\\"P2Vol_7_System_Board_1_\"\n            }\n        ]\n    ]\n}\n
      "},{"location":"API/Services/#get_service_for_host","title":"get_service_for_host","text":"

      Retrieve services for device

      Route: /api/v0/services/:hostname

      • id or hostname is the specific device

      Input:

      • state: only which have a certain state (valid options are 0=Ok, 1=Warning, 2=Critical).
      • type: service type, used sql LIKE to find services, so for tcp, use type=tcp for http use type=http

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/:hostname\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/:hostname?state=2\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/:hostname?state=0&type=tcp\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"\",\n    \"count\": 1,\n    \"services\": [\n        [\n            {\n                \"service_id\": \"2\",\n                \"device_id\": \"2\",\n                \"service_ip\": \"demo2.yourdomian.net\",\n                \"service_type\": \"esxi_hardware.py\",\n                \"service_desc\": \"vmware hardware\",\n                \"service_param\": \"-H 192.168.1.11 -U USER -P PASS -p\",\n                \"service_ignore\": \"0\",\n                \"service_status\": \"0\",\n                \"service_changed\": \"1471702206\",\n                \"service_message\": \"OK - Server: Supermicro X9SCL/X9SCM s/n: 0123456789 System BIOS: 2.2 2015-02-20\",\n                \"service_disabled\": \"0\",\n                \"service_ds\": \"{\\\"P2Vol_0_Processor_1_Vcore\\\":\\\"\\\",\\\"P2Vol_1_System_Board_1_-12V\\\":\\\"\\\",\\\"P2Vol_2_System_Board_1_12V\\\":\\\"\\\",\\\"P2Vol_3_System_Board_1_3.3VCC\\\":\\\"\\\",\\\"P2Vol_4_System_Board_1_5VCC\\\":\\\"\\\",\\\"P2Vol_5_System_Board_1_AVCC\\\":\\\"\\\",\\\"P2Vol_6_System_Board_1_VBAT\\\":\\\"\\\",\\\"P2Vol_7_System_Board_1_\"\n            }\n        ]\n    ]\n}\n
      "},{"location":"API/Services/#add_service_for_host","title":"add_service_for_host","text":"

      Add a service for device

      Route: /api/v0/services/:hostname

      • id or hostname is the specific device

      Input:

      • type: service type
      • ip: ip of the service
      • desc: description for the service
      • param: parameters for the service
      • ignore: ignore the service for checks

      Example:

      curl -X POST -d '{\"type\":\"ping\",\"ip\": \"192.168.1.10\",\"desc\":\"test ping\",\"param\": \"-t 10 -c 5\"}' -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/services/192.168.1.10\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Service ping has been added to device 192.168.1.10 (#10)\"\n}\n
      "},{"location":"API/Services/#edit_service_from_host","title":"edit_service_from_host","text":"

      Edits a service

      Route: /api/v0/services/:service_id

      • service id

      Input:

      • id: service id

      Example:

      curl -X PATCH -d '{\"service_disabled\":\"1\"}' 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/services/5\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Service updated successfully\"\n\n}\n
      "},{"location":"API/Services/#delete_service_from_host","title":"delete_service_from_host","text":"

      Deletes service from device

      Route: /api/v0/services/:service_id

      • service id

      Input:

      • id: service id

      Example:

      curl -X DELETE -H 'X-Auth-Token:YOUR-API-TOKEN' https://librenms.org/api/v0/services/35\n

      Output:

      {\n    \"status\": \"ok\",\n    \"message\": \"Service has been deleted successfully\"\n}\n
      "},{"location":"API/Switching/","title":"Switching","text":""},{"location":"API/Switching/#list_vlans","title":"list_vlans","text":"

      Get a list of all VLANs.

      Route: /api/v0/resources/vlans

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/vlans\n

      Output:

      {\n    \"status\": \"ok\",\n    \"vlans\": [\n        {\n            \"vlan_id\": \"31\",\n            \"device_id\": \"10\",\n            \"vlan_vlan\": \"1\",\n            \"vlan_domain\": \"1\",\n            \"vlan_name\": \"default\",\n            \"vlan_type\": \"ethernet\",\n            \"vlan_mtu\": null\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Switching/#get_vlans","title":"get_vlans","text":"

      Get a list of all VLANs for a given device.

      Route: /api/v0/devices/:hostname/vlans

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/vlans\n

      Output:

      {\n    \"status\": \"ok\",\n    \"count\": 0,\n    \"vlans\": [\n    {\n   \"vlan_vlan\": \"1\",\n   \"vlan_domain\": \"1\",\n   \"vlan_name\": \"default\",\n   \"vlan_type\": \"ethernet\",\n   \"vlan_mtu\": null\n    }\n  ]\n}\n
      "},{"location":"API/Switching/#list_links","title":"list_links","text":"

      Get a list of all Links.

      Route: /api/v0/resources/links

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/links\n

      Output:

      {\n    \"status\": \"ok\",\n    \"links\": [\n        {\n            \"id\": 10,\n            \"local_port_id\": 100,\n            \"local_device_id\": 1,\n            \"remote_port_id\": 200,\n            \"active\": 1,\n            \"protocol\": \"lldp\",\n            \"remote_hostname\": \"host2.example.com\",\n            \"remote_device_id\": 2,\n            \"remote_port\": \"xe-0/0/1\",\n            \"remote_platform\": null,\n            \"remote_version\": \"Example Router v.1.0\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Switching/#get_links","title":"get_links","text":"

      Get a list of Links per giver device.

      Route: /api/v0/devices/:hostname/links

      • hostname can be either the device hostname or id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/devices/localhost/links\n

      Output:

      {\n    \"status\": \"ok\",\n    \"links\": [\n        {\n            \"id\": 10,\n            \"local_port_id\": 100,\n            \"local_device_id\": 1,\n            \"remote_port_id\": 200,\n            \"active\": 1,\n            \"protocol\": \"lldp\",\n            \"remote_hostname\": \"host2.example.com\",\n            \"remote_device_id\": 2,\n            \"remote_port\": \"xe-0/0/1\",\n            \"remote_platform\": null,\n            \"remote_version\": \"Example Router v.1.0\"\n        },\n        ...\n    ],\n    \"count\": 10\n}\n
      "},{"location":"API/Switching/#get_link","title":"get_link","text":"

      Retrieves Link by ID

      Route: /api/v0/resources/links/:id

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/links/10\n

      Output:

      {\n    \"status\": \"ok\",\n    \"links\": [\n        {\n            \"id\": 10,\n            \"local_port_id\": 100,\n            \"local_device_id\": 1,\n            \"remote_port_id\": 200,\n            \"active\": 1,\n            \"protocol\": \"lldp\",\n            \"remote_hostname\": \"host2.example.com\",\n            \"remote_device_id\": 2,\n            \"remote_port\": \"xe-0/0/1\",\n            \"remote_platform\": null,\n            \"remote_version\": \"Example Router v.1.0\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"API/Switching/#list_fdb","title":"list_fdb","text":"

      Get a list of all ports FDB.

      Route: /api/v0/resources/fdb/:mac

      • mac is the specific MAC address you would like to query

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/fdb\ncurl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/fdb/1aaa2bbb3ccc\n

      Output:

      {\n    \"status\": \"ok\",\n    \"ports_fdb\": [\n        {\n            \"ports_fdb_id\": 10,\n            \"port_id\": 10000,\n            \"mac_address\": \"1aaa2bbb3ccc\",\n            \"vlan_id\": 20000,\n            \"device_id\": 1,\n            \"created_at\": \"2019-01-1 01:01:01\",\n            \"updated_at\": \"2019-01-1 01:01:01\"\n        },\n        ...\n    ],\n    \"count\": 100\n}\n
      "},{"location":"API/Switching/#list_fdb_detail","title":"list_fdb_detail","text":"

      Get a list of all ports FDB with human readable device and interface names.

      Route: /api/v0/resources/fdb/:mac/detail

      • mac is the specific MAC address you would like to query

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/resources/fdb/1aaa2bbb3ccc/detail\n

      Output:

      {\n    'count': 7,\n    'mac': '9c:93:aa:bb:cc:dd',\n    'mac_oui': 'Xerox Corporation',\n    'ports_fdb': [\n        {\n            'hostname': 'hq-core1',\n            'ifName': 'ae10',\n            'last_seen': '2 hours ago',\n            'updated_at': '2023-05-17 03:19:15'\n        },\n        {\n            'hostname': 'hq-sw1',\n            'ifName': 'ge-0/0/0',\n            'last_seen': '3 hours ago',\n            'updated_at': '2023-05-17 02:02:06'\n        },\n        ...\n    ],\n    'status': 'ok'\n}\n

      "},{"location":"API/System/","title":"System","text":""},{"location":"API/System/#system","title":"system","text":"

      Display Librenms instance information.

      Route: /api/v0/system

      Input:

      -

      Example:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/system\n

      Output:

      {\n    \"status\": \"ok\",\n    \"system\": [\n        {\n            \"local_ver\": \"1.37-234-g19103ee\",\n            \"local_sha\": \"19103ee36f68f009272c15be22e5a7e10a8b0b85\",\n            \"local_date\": \"1526480966\",\n            \"local_branch\": \"master\",\n            \"db_schema\": 249,\n            \"php_ver\": \"7.2.2\",\n            \"database_ver\": \"MariaDB 5.5.56-MariaDB\",\n            \"rrdtool_ver\": \"1.4.8\",\n            \"netsnmp_ver\": \"NET-SNMP 5.7.2\"\n        }\n    ],\n    \"count\": 1\n}\n
      "},{"location":"Alerting/","title":"Introduction","text":"

      To get started, you first need some alert rules which will react to changes with your devices before raising an alert.

      Creating alert rules

      After that you also need to tell LibreNMS how to notify you when an alert is raised, this is done using Alert Transports.

      Configuring alert transports

      The next step is not strictly required but most people find it useful. Creating custom alert templates will help you get the benefit out of the alert system in general. Whilst we include a default template, it is limited in the data that you will receive in the alerts.

      Configuring alert templates

      "},{"location":"Alerting/#managing-alerts","title":"Managing alerts","text":"

      When an alert has triggered you will see these in the Alerts -> Notifications page within the Web UI.

      This list has a couple of options available to it and we'll explain what these are here.

      "},{"location":"Alerting/#ack","title":"ACK","text":"

      This column provides you visibility on the status of the alert:

      This alert is currently active and sending alerts. Click this icon to acknowledge the alert.

      This alert is currently acknowledged until the alert clears. Click this icon to un-acknowledge the alert.

      This alert is currently acknowledged until the alert worsens or gets better, at which stage it will be automatically unacknowledged and alerts will resume. Click this icon to un-acknowledge the alert.

      "},{"location":"Alerting/#notes","title":"Notes","text":"

      This column will allow you access to the acknowledge/unacknowledge notes for this alert.

      "},{"location":"Alerting/Creating-Transport/","title":"Creating a new Transport","text":""},{"location":"Alerting/Creating-Transport/#file-location","title":"File location","text":"

      All transports are located in LibreNMS\\Alert\\Transport and the files are named after the Transport name. I.e Discord.php for Discord.

      "},{"location":"Alerting/Creating-Transport/#transport-structure","title":"Transport structure","text":"

      The following functions are required for a new transport to pass the unit tests:

      deliverAlert() - This is function called within alerts to invoke the transport. Here you should do any post processing of the transport config to get it ready for use.

      contact$Transport() - This is named after the transport so for Discord it would be contactDiscord(). This is what actually interacts with the 3rd party API, invokes the mail command or whatever you want your alert to do.

      configTemplate() - This is used to define the form that will accept the transport config in the webui and then what data should be validated and how. Validation is done using Laravel validation

      The following function is not required for new Transports and is for legacy reasons only. deliverAlertOld().

      "},{"location":"Alerting/Creating-Transport/#documentation","title":"Documentation","text":"

      Please don't forget to update the Transport file to include details of your new transport.

      A table should be provided to indicate the form values that we ask for and examples. I.e:

      Config Example Discord URL https://discordapp.com/api/webhooks/4515489001665127664/82-sf4385ysuhfn34u2fhfsdePGLrg8K7cP9wl553Fg6OlZuuxJGaa1d54fe Options username=myname"},{"location":"Alerting/Device-Dependencies/","title":"Device Dependencies","text":"

      It is possible to set one or more parents for a device. The aim for that is, if all parent devices are down, alert contacts will not receive redundant alerts for dependent devices. This is very useful when you have an outage, say in a branch office, where normally you'd receive hundreds of alerts, but when this is properly configured, you'd only receive an alert for the parent hosts.

      There are three ways to configure this feature. First one is from general settings of a device. The other two can be done in the 'Device Dependencies' item under 'Devices' menu. In this page, you can see all devices and with its parents. Clicking on the 'bin' icon will clear the dependency setting. Clicking on the 'pen' icon will let you edit or change the current setting for chosen device. There's also a 'Manage Device Dependencies' button on the top. This will let you set parents for multiple devices at once.

      For an intro on getting started with Device Dependencies, take a look at our Youtube video

      "},{"location":"Alerting/Entities/","title":"Entities","text":"

      Entities as described earlier are based on the table and column names within the database, if you are unsure of what the entity is you want then have a browse around inside MySQL using show tables and desc <tablename>.

      Below are some common entities that you can use within the alerting system. This list is not exhaustive and you should look at the MySQL database schema for the full list.

      "},{"location":"Alerting/Entities/#devices","title":"Devices","text":"Entity Description devices.hostname The device hostname devices.sysName The device sysName devices.sysDescr The device sysDescr devices.hardware The device hardware devices.version The device os version devices.location The device location devices.status The status of the device, 1 devices.status_reason The reason the device was detected as down (icmp or snmp) devices.ignore If the device is ignored this will be set to 1 devices.disabled If the device is disabled this will be set to 1 devices.last_polled The the last polled datetime (yyyy-mm-dd hh:mm:ss) devices.type The device type such as network, server, firewall, etc."},{"location":"Alerting/Entities/#bgp-peers","title":"BGP Peers","text":"Entity Description bgpPeers.astext This is the description of the BGP Peer bgpPeers.bgpPeerIdentifier The IP address of the BGP Peer bgpPeers.bgpPeerRemoteAs The AS number of the BGP Peer bgpPeers.bgpPeerState The operational state of the BGP session bgpPeers.bgpPeerAdminStatus The administrative state of the BGP session bgpPeers.bgpLocalAddr The local address of the BGP session."},{"location":"Alerting/Entities/#ipsec-tunnels","title":"IPSec Tunnels","text":"Entity Description ipsec_tunnels.peer_addr The remote VPN peer address ipsec_tunnels.local_addr The local VPN address ipsec_tunnels.tunnel_status The VPN tunnels operational status."},{"location":"Alerting/Entities/#memory-pools","title":"Memory pools","text":"

      Entity | Description |---|---| mempools.mempool_type | The memory pool type such as hrstorage, cmp and cemp mempools.mempool_descr | The description of the pool such as Physical memory, Virtual memory and System memory mempools.mempool_perc | The used percentage of the memory pool.

      "},{"location":"Alerting/Entities/#ports","title":"Ports","text":"Entity Description ports.ifDescr The interface description ports.ifName The interface name ports.ifSpeed The port speed in bps ports.ifHighSpeed The port speed in mbps ports.ifOperStatus The operational status of the port (up or down) ports.ifAdminStatus The administrative status of the port (up or down) ports.ifDuplex Duplex setting of the port ports.ifMtu The MTU setting of the port."},{"location":"Alerting/Entities/#processors","title":"Processors","text":"Entity Description processors.processor_usage The usage of the processor as a percentage processors.processor_descr The description of the processor."},{"location":"Alerting/Entities/#storage","title":"Storage","text":"Entity Description storage.storage_descr The description of the storage storage.storage_perc The usage of the storage as a percentage."},{"location":"Alerting/Entities/#health-sensors","title":"Health / Sensors","text":"Entity Description sensors.sensor_desc The sensors description. sensors.sensor_current The current sensors value. sensors.sensor_prev The previous sensor value. sensors.lastupdate The sensors last updated datetime stamp."},{"location":"Alerting/Macros/","title":"Macros","text":"

      Macros are shorthands to either portion of rules or pure SQL enhanced with placeholders.

      You can define your own macros in your config.php.

      Example macro-implementation of Debian-Devices

      $config['alert']['macros']['rule']['is_debian'] = 'devices.features ~ \"@debian@\"';\n

      And in the Rule:

      ...  macros.is_debian = 1 ...\n

      This Example-macro is a Boolean-macro, it applies a form of filter to the set of results defined by the rule.

      All macros that are not unary should return Boolean.

      "},{"location":"Alerting/Macros/#device-boolean","title":"Device (Boolean)","text":"

      Entity: macros.device

      Description: Only select devices that aren't deleted, ignored or disabled.

      Source: (devices.disabled = 0 AND devices.ignore = 0)

      "},{"location":"Alerting/Macros/#device-is-up-boolean","title":"Device is up (Boolean)","text":"

      Entity: macros.device_up

      Description: Only select devices that are up.

      Implies: macros.device

      Source: (devices.status = 1 AND macros.device)

      "},{"location":"Alerting/Macros/#device-is-down-boolean","title":"Device is down (Boolean)","text":"

      Entity: macros.device_down

      Description: Only select devices that are down.

      Implies: macros.device

      Source: (devices.status = 0 AND macros.device)

      "},{"location":"Alerting/Macros/#port-boolean","title":"Port (Boolean)","text":"

      Entity: macros.port

      Description: Only select ports that aren't deleted, ignored or disabled.

      Source: (ports.deleted = 0 AND ports.ignore = 0 AND ports.disabled = 0)

      "},{"location":"Alerting/Macros/#port-is-up-boolean","title":"Port is up (Boolean)","text":"

      Entity: macros.port_up

      Description: Only select ports that are up and also should be up.

      Implies: macros.port

      Source: (ports.ifOperStatus = up AND ports.ifAdminStatus = up AND macros.port)

      "},{"location":"Alerting/Macros/#port-is-down-boolean","title":"Port is down (Boolean)","text":"

      Entity: macros.port_down

      Description: Only select ports that are down.

      Implies: macros.port

      Source: (ports.ifOperStatus != \"up\" AND ports.ifAdminStatus != \"down\" AND macros.port)

      "},{"location":"Alerting/Macros/#port-usage-in-percent-decimal","title":"Port-Usage in Percent (Decimal)","text":"

      Entity: macros.port_usage_perc

      Description: Return port-usage (max value of in and out) in percent.

      Source: ((SELECT IF(ports.ifOutOctets_rate>ports.ifInOctets_rate, ports.ifOutOctets_rate, ports.ifInOctets_rate)*8) / ports.ifSpeed)*100

      "},{"location":"Alerting/Macros/#time","title":"Time","text":""},{"location":"Alerting/Macros/#now-datetime","title":"Now (Datetime)","text":"

      Entity: macros.now

      Description: Alias of MySQL's NOW()

      Source: NOW()

      "},{"location":"Alerting/Macros/#past-n-minutes-datetime","title":"Past N Minutes (Datetime)","text":"

      Entity: macros.past_$m

      Description: Returns a MySQL Timestamp dated $ Minutes in the past. $ can only be a supported Resolution.

      Example: macros.past_5m is Last 5 Minutes.

      Resolution: 5,10,15,30,60

      Source: DATE_SUB(NOW(),INTERVAL $ MINUTE)

      "},{"location":"Alerting/Macros/#sensors-boolean","title":"Sensors (Boolean)","text":"

      Entity: macros.sensor

      Description: Only select sensors that aren't ignored.

      Source: (sensors.sensor_alert = 1)

      Entity: macros.sensor_port_link = 1

      Description: Only selects sensors that have a port linked to them, the port is up and the device is up.

      Source: (sensors.entity_link_type = \"port\" AND sensors.entity_link_index = ports.ifIndex AND macros.port_up AND macros.device_up))

      "},{"location":"Alerting/Macros/#state-sensors-boolean","title":"State Sensors (Boolean)","text":"

      Entity: macros.state_sensor_ok, macros.state_sensor_warning, macros.state_sensor_critical, macros.state_sensor_unknown

      Description: Select state sensors by their generic status ok (0), warning (1), critical (2), unknown (3)

      Source: (sensors.sensor_current = state_translations.state_value AND state_translations.state_generic_value = 2)

      "},{"location":"Alerting/Macros/#misc-boolean","title":"Misc (Boolean)","text":""},{"location":"Alerting/Macros/#packet-loss","title":"Packet Loss","text":"

      Entity: (macros.packet_loss_5m)

      Description: Packet loss % value for the device within the last 5 minutes. BROKEN, only return 100 (down) or 0.

      Example: macros.packet_loss_5m > 50

      Entity: (macros.packet_loss_15m)

      Description: Packet loss % value for the device within the last 15 minutes. BROKEN, only return 100 (down) or 0.

      Example: macros.packet_loss_15m > 50

      "},{"location":"Alerting/Macros/#ports-in-usage-perc-int","title":"Ports in usage perc (Int)","text":"

      Entity: ((ports.ifInOctets_rate*8)/ports.ifSpeed)*100

      Description: Port in used more than 50%

      Example: `macros.port_in_usage_perc > 50

      "},{"location":"Alerting/Macros/#ports-out-usage-perc-int","title":"Ports out usage perc (Int)","text":"

      Entity: ((ports.ifOutOctets_rate*8)/ports.ifSpeed)*100

      Description: Port out used more than 50%

      Example: `macros.port_out_usage_perc > 50

      "},{"location":"Alerting/Macros/#ports-now-down-boolean","title":"Ports now down (Boolean)","text":"

      Entity: ports.ifOperStatus != ports.ifOperStatus_prev AND ports.ifOperStatus_prev = \"up\" AND ports.ifAdminStatus = \"up\"

      Description: Ports that were previously up and have now gone down.

      Example: macros.port_now_down = 1

      "},{"location":"Alerting/Macros/#port-has-xdp-neighbour-boolean","title":"Port has xDP neighbour (Boolean)","text":"

      Entity: %macros.port AND %links.local_port_id = %ports.port_id

      Description: Ports that have an xDP (lldp, cdp, etc) neighbour.

      Example: macros.port_has_xdp_neighbours = 1

      "},{"location":"Alerting/Macros/#port-has-xdp-neighbour-already-known-in-librenms-boolean","title":"Port has xDP neighbour already known in LibreNMS (Boolean)","text":"

      Entity: %macros.port_has_neighbours AND (%links.remote_port_id IS NOT NULL)

      Description: Ports that have an xDP (lldp, cdp, etc) neighbour that is already known in libreNMS.

      Example: macros.port_has_xdp_neighbours_device = 1

      "},{"location":"Alerting/Macros/#device-component-down-junos","title":"Device component down [JunOS]","text":"

      Entity: sensors.sensor_class = \"state\" AND sensors.sensor_current != \"6\" AND sensors.sensor_type = \"jnxFruState\" AND sensors.sensor_current != \"2\"

      Description: Device component is down such as Fan, PSU, etc for JunOS devices.

      Example: macros.device_component_down_junos = 1

      "},{"location":"Alerting/Macros/#device-component-down-cisco","title":"Device component down [Cisco]","text":"

      Entity: sensors.sensor_current != 1 AND sensors.sensor_current != 5 AND sensors.sensor_type ~ \"^cisco.*State$\"

      Description: Device component is down such as Fan, PSU, etc for Cisco devices.

      Example: macros.device_component_down_cisco = 1

      "},{"location":"Alerting/Macros/#pdu-over-amperage-apc","title":"PDU over amperage [APC]","text":"

      Entity: sensors.sensor_class = \"current\" AND sensors.sensor_descr = \"Bank Total\" AND sensors.sensor_current > sensors.sensor_limit AND devices.os = \"apc\"

      Description: APC PDU over amperage

      Example: macros.pdu_over_amperage_apc = 1

      "},{"location":"Alerting/Rules/","title":"Rules","text":"

      Rules are defined using a logical language.

      The GUI provides a simple way of creating rules.

      Creating more complicated rules which may include maths calculations and MySQL queries can be done using macros

      "},{"location":"Alerting/Rules/#syntax","title":"Syntax","text":"

      Rules must consist of at least 3 elements: An Entity, a Condition and a Value. Rules can contain braces and Glues. Entities are provided from Table and Field from the database. For Example: ports.ifOperStatus.

      Conditions can be any of:

      • Equals =
      • Not Equals !=
      • In IN
      • Not In NOT IN
      • Begins with LIKE ('...%')
      • Doesn't begin with NOT LIKE ('...%')
      • Contains LIKE ('%...%')
      • Doesn't Contain NOT LIKE ('%...%')
      • Ends with LIKE ('%...')
      • Doesn't end with NOT LIKE ('%...')
      • Between BETWEEN
      • Not Between NOT BETWEEN
      • Is Empty = ''
      • Is Not Empty != '''
      • Is Null IS NULL
      • Is Not Null IS NOT NULL
      • Greater >
      • Greater or Equal >=
      • Less <
      • Less or Equal <=
      • Regex REGEXP

      Values can be an entity or any data. If using macros as value you must include the macro name into backticks. i.e. `macros.past_60m`

      Note: Regex supports MySQL Regular expressions.

      Arithmetics are allowed as well.

      "},{"location":"Alerting/Rules/#options","title":"Options","text":"

      Here are some of the other options available when adding an alerting rule:

      • Rule name: The name associated with the rule.
      • Severity: How \"important\" the rule is.
      • Max alerts: The maximum number of alerts sent for the event. -1 means unlimited.
      • Delay: The amount of time in seconds to wait after a rule is matched before sending an alert out transport.
      • Interval: The interval of time in seconds between alerts for an event until Max alert is reached.
      • Mute alerts: Disables sending alert rule through alert transport. But will still show the alert in the Web UI.
      • Invert match: Invert the matching rule (ie. alert on items that _don't match the rule).
      • Recovery alerts: This will disable the recovery notification from being sent if turned off.
      "},{"location":"Alerting/Rules/#advanced","title":"Advanced","text":"

      On the Advanced tab, you can specify some additional options for the alert rule:

      • Override SQL: Enable this if you using a custom query
      • Query: The query to be used for the alert.

      • An example of this would be an average rule for all CPUs over 10%

      SELECT devices.device_id, devices.status, devices.disabled, devices.ignore, \nAVG(processors.processor_usage) AS cpu_avg  FROM \ndevices INNER JOIN processors ON devices.device_id \n= processors.device_id WHERE devices.device_id \n= ? AND devices.status = 1 AND devices.disabled = \n0 AND devices.ignore = 0 GROUP BY devices.device_id, \ndevices.status, devices.disabled, devices.ignore \nHAVING AVG(processors.processor_usage) \n> 10\n

      The 10 would then contain the average CPU usage value, you can change this value to be whatever you like.

      • You will to need copy and paste this into the Alert Rule under Advanced then paste into Query box and switch the Override SQL.
      "},{"location":"Alerting/Rules/#procedure","title":"Procedure","text":"

      You can associate a rule to a procedure by giving the URL of the procedure when creating the rule. Only links like \"http://\" are supported, otherwise an error will be returned. Once configured, procedure can be opened from the Alert widget through the \"Open\" button, which can be shown/hidden from the widget configuration box.

      "},{"location":"Alerting/Rules/#examples","title":"Examples","text":"

      Alert when:

      • Device goes down: devices.status != 1
      • Any port changes: ports.ifOperStatus != 'up'
      • Root-directory gets too full: storage.storage_descr = '/' AND storage.storage_perc >= '75'
      • Any storage gets fuller than the 'warning': storage.storage_perc >= storage_perc_warn
      • If device is a server and the used storage is above the warning level, but ignore /boot partitions: storage.storage_perc > storage.storage_perc_warn AND devices.type = \"server\" AND storage.storage_descr != \"/boot\"
      • VMware LAG is not using \"Source ip address hash\" load balancing: devices.os = \"vmware\" AND ports.ifType = \"ieee8023adLag\" AND ports.ifDescr REGEXP \"Link Aggregation .*, load balancing algorithm: Source ip address hash\"
      • Syslog, authentication failure during the last 5m: syslog.timestamp >= macros.past_5m AND syslog.msg REGEXP \".*authentication failure.*\"
      • High memory usage: macros.device_up = 1 AND mempools.mempool_perc >= 90 AND mempools.mempool_descr REGEXP \"Virtual.*\"
      • High CPU usage(per core usage, not overall): macros.device_up = 1 AND processors.processor_usage >= 90
      • High port usage, where description is not client & ifType is not softwareLoopback: macros.port_usage_perc >= 80 AND port.port_descr_type != \"client\" AND ports.ifType != \"softwareLoopback\"
      • Alert when mac address is located on your network ipv4_mac.mac_address = \"2c233a756912\"
      "},{"location":"Alerting/Rules/#alert-rules-collection","title":"Alert Rules Collection","text":"

      You can also select Alert Rule from the Alerts Collection. These Alert Rules are submitted by users in the community :) If would like to submit your alert rules to the collection, please submit them here Alert Rules Collection

      "},{"location":"Alerting/Templates/","title":"Templates","text":"

      This page is for installs running version 1.42 or later. You can find the older docs here

      Templates can be assigned to a single or a group of rules and can contain any kind of text. There is also a default template which is used for any rule that isn't associated with a template. This template can be found under Alert Templates page and can be edited. It also has an option revert it back to its default content.

      To attach a template to a rule just open the Alert Templates settings page, choose the template to assign and click the yellow button in the Actions column. In the appearing popupbox select the rule(s) you want the template to be assigned to and click the Attach button. You might hold down the CTRL key to select multiple rules at once.

      The templating engine in use is Laravel Blade. We will cover some of the basics here, however the official Laravel docs will have more information here

      "},{"location":"Alerting/Templates/#syntax","title":"Syntax","text":"

      Controls:

      • if-else (Else can be omitted): @if ($alert->placeholder == 'value') Some Text @else Other Text @endif
      • foreach-loop: @foreach ($alert->faults as $key => $value) Key: $key Value: $value @endforeach

      Placeholders:

      Placeholders are special variables that if used within the template will be replaced with the relevant data, I.e:

      The device {{ $alert->hostname }} has been up for {{ $alert->uptime }} seconds would result in the following The device localhost has been up for 30344 seconds.

      When using placeholders to echo data, you need to wrap the placeholder in {{ }}. I.e {{ $alert->hostname }}.

      • Device ID: $alert->device_id
      • Hostname of the Device: $alert->hostname
      • sysName of the Device: $alert->sysName
      • sysDescr of the Device: $alert->sysDescr
      • display name of the Device: $alert->display
      • sysContact of the Device: $alert->sysContact
      • OS of the Device: $alert->os
      • Type of Device: $alert->type
      • IP of the Device: $alert->ip
      • Hardware of the Device: $alert->hardware
      • Software version of the Device: $alert->version
      • Features of the Device: $alert->features
      • Serial number of the Device: $alert->serial
      • Location of the Device: $alert->location
      • uptime of the Device (in seconds): $alert->uptime
      • Short uptime of the Device (28d 22h 30m 7s): $alert->uptime_short
      • Long uptime of the Device (28 days, 22h 30m 7s): $alert->uptime_long
      • Description (purpose db field) of the Device: $alert->description
      • Notes of the Device: $alert->notes
      • Notes of the alert (ack notes): $alert->alert_notes
      • ping timestamp (if icmp enabled): $alert->ping_timestamp
      • ping loss (if icmp enabled): $alert->ping_loss
      • ping min (if icmp enabled): $alert->ping_min
      • ping max (if icmp enabled): $alert->ping_max
      • ping avg (if icmp enabled): $alert->ping_avg
      • debug (array)
      • Title for the Alert: $alert->title
      • Time Elapsed, Only available on recovery ($alert->state == 0): $alert->elapsed
      • Rule Builder (the actual rule) (use {!! $alert->builder !!}): $alert->builder
      • Alert-ID: $alert->id
      • Unique-ID: $alert->uid
      • Faults, Only available on alert ($alert->state != 0), must be iterated in a foreach (@foreach ($alert->faults as $key => $value) @endforeach). Holds all available information about the Fault, accessible in the format $value['Column'], for example: $value['ifDescr']. Special field $value['string'] has most Identification-information (IDs, Names, Descrs) as single string, this is the equivalent of the default used and must be encased in {{ }}
      • State: $alert->state
      • Severity: $alert->severity
      • Rule: $alert->rule
      • Rule-Name: $alert->name
      • Procedure URL: $alert->proc
      • Timestamp: $alert->timestamp
      • Transport type: $alert->transport
      • Transport name: $alert->transport_name
      • Contacts, must be iterated in a foreach, $key holds email and $value holds name: $alert->contacts

      Placeholders can be used within the subjects for templates as well although $faults is most likely going to be worthless.

      The Default Template is a 'one-size-fit-all'. We highly recommend defining your own templates for your rules to include more specific information.

      "},{"location":"Alerting/Templates/#base-templates","title":"Base Templates","text":"

      If you'd like to reuse a common template for your alerts follow below

      A default file is located in resources/views/alerts/templates/default.blade.php Displays the following:

      <html>\n    <head>\n        <title>LibreNMS Alert</title>\n    </head>\n    <body>\n        <div class=\"container\">\n            @yield('content')\n        </div>\n    </body>\n</html>\n

      The important part being the @yield('content')

      You can use plain text or html as per Alert templates and this will form the basis of your common template, feel free to make as many templates in the directory as needed.

      In your alert template just use

      @extends('alerts.templates.default')\n\n@section('content')\n  {{ $alert->title }}\n  Severity: {{ $alert->severity }}\n  ...\n@endsection\n

      More info: https://laravel.com/docs/blade#extending-a-layout

      "},{"location":"Alerting/Templates/#examples","title":"Examples","text":""},{"location":"Alerting/Templates/#default-template","title":"Default Template","text":"
      {{ $alert->title }}\nSeverity: {{ $alert->severity }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nUnique-ID: {{ $alert->uid }}\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif\n@if ($alert->faults) Faults:\n@foreach ($alert->faults as $key => $value)\n  {{ $key }}: {{ $value['string'] }}\n@endforeach\n@endif\nAlert sent to:\n@foreach ($alert->contacts as $key => $value)\n  {{ $value }} <{{ $key }}>\n@endforeach\n
      "},{"location":"Alerting/Templates/#ports-utilization-template","title":"Ports Utilization Template","text":"
      {{ $alert->title }}\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif\n@foreach ($alert->faults as $key => $value)\nPhysical Interface: {{ $value['ifDescr'] }}\nInterface Description: {{ $value['ifAlias'] }}\nInterface Speed: {{ ($value['ifSpeed']/1000000000) }} Gbs\nInbound Utilization: {{ (($value['ifInOctets_rate']*8)/$value['ifSpeed'])*100 }}\nOutbound Utilization: {{ (($value['ifOutOctets_rate']*8)/$value['ifSpeed'])*100 }}\n@endforeach\n
      "},{"location":"Alerting/Templates/#storage","title":"Storage","text":"
      {{ $alert->title }}\n\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\nUptime: {{ $alert->uptime_short }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nLocation: {{ $alert->location }}\nDescription: {{ $alert->description }}\nFeatures: {{ $alert->features }}\nNotes: {{ $alert->notes }}\n\nServer: {{ $alert->sysName }}\n@foreach ($alert->faults as $key => $value)\nMount Point: {{ $value['storage_descr'] }}\nPercent Utilized: {{ $value['storage_perc'] }}\n@endforeach\n
      "},{"location":"Alerting/Templates/#value-sensors-temperature-humidity-fanspeed","title":"Value Sensors (Temperature, Humidity, Fanspeed, ...)","text":"
      {{ $alert->title }}\n\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\nTimestamp: {{ $alert->timestamp }}\nUptime: {{ $alert->uptime_short }}\n@if ($alert->state == 0)\nTime elapsed: {{ $alert->elapsed }}\n@endif\nLocation: {{ $alert->location }}\nDescription: {{ $alert->description }}\nFeatures: {{ $alert->features }}\nNotes: {{ $alert->notes }}\n\nRule: {{ $alert->name ?? $alert->rule }}\n@if ($alert->faults)\nFaults:\n@foreach ($alert->faults as $key => $value)\n@php($unit = __(\"sensors.${value[\"sensor_class\"]}.unit\"))\n#{{ $key }}: {{ $value['sensor_descr'] ?? 'Sensor' }}\n\nCurrent: {{ $value['sensor_current'].$unit }}\nPrevious: {{ $value['sensor_prev'].$unit }}\nLimit: {{ $value['sensor_limit'].$unit }}\nOver Limit: {{ round($value['sensor_current']-$value['sensor_limit'], 2).$unit }}\n\n@endforeach\n@endif\n
      "},{"location":"Alerting/Templates/#memory-alert","title":"Memory Alert","text":"
      {{ $alert->title }}\n\nDevice Name: {{ $alert->hostname }}\nSeverity: {{ $alert->severity }}\nUptime: {{ $alert->uptime_short }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nLocation: {{ $alert->location }}\nDescription: {{ $alert->description }}\nNotes: {{ $alert->notes }}\n\nServer: {{ $alert->hostname }}\n@foreach ($alert->faults as $key => $value)\nMemory Description: {{ $value['mempool_descr'] }}\nPercent Utilized: {{ $value['mempool_perc'] }}\n@endforeach\n
      "},{"location":"Alerting/Templates/#advanced-options","title":"Advanced options","text":""},{"location":"Alerting/Templates/#conditional-formatting","title":"Conditional formatting","text":"

      Conditional formatting example, will display a link to the host in email or just the hostname in any other transport:

      @if ($alert->transport == 'mail')<a href=\"https://my.librenms.install/device/device={{ $alert->hostname }}/\">{{ $alert->hostname }}</a>\n@else\n{{ $alert->hostname }}\n@endif\n
      "},{"location":"Alerting/Templates/#traceroute-debugs","title":"Traceroute debugs","text":"
      @if ($alert->status == 0)\n    @if ($alert->status_reason == 'icmp')\n        {{ $alert->debug['traceroute'] }}\n    @endif\n@endif\n
      "},{"location":"Alerting/Templates/#examples-html","title":"Examples HTML","text":"

      Note: To use HTML emails you must set HTML email to Yes in the WebUI under Global Settings > Alerting Settings > Email transport > Use HTML emails

      "},{"location":"Alerting/Templates/#graphs","title":"Graphs","text":"

      There are two helpers for graphs that will use a signed url to allow secure external access. Anyone using the signed url will be able to view the graph.

      • Your LibreNMS web must be accessible from the location where the graph is viewed. Some alert transports require publicly accessible urls.
      • APP_URL must be set in .env to use signed graphs.
      • Changing APP_KEY will invalidate all previously issued singed urls.

      You may specify the graph one of two ways, a php array of parameters, or a direct url to a graph.

      Note that to and from can be specified either as timestamps with time() or as relative time -3d or -36h. When using relative time, the graph will show based on when the user views the graph, not when the event happened. Sharing a graph image with a relative time will always give the recipient access to current data, where a specific timestamp will only allow access to that timeframe.

      "},{"location":"Alerting/Templates/#signedgraphtag","title":"@signedGraphTag","text":"

      This will insert a specially formatted html img tag linking to the graph. Some transports may search the template for this tag to attach images properly for that transport.

      @signedGraphTag([\n    'id' => $value['port_id'],\n    'type' => 'port_bits',\n    'from' => time() - 43200,\n    'to' => time(),\n    'width' => 700, \n    'height' => 250\n])\n

      Output:

      <img class=\"librenms-graph\" src=\"https://librenms.org/graph?from=1662176216&amp;height=250&amp;id=20425&amp;to=1662219416&amp;type=port_bits&amp;width=700&amp;signature=f6e516e8fd893c772eeaba165d027cb400e15a515254de561a05b63bc6f360a4\">\n

      Specific graph using url input:

      @signedGraphTag('https://librenms.org/graph.php?type=device_processor&from=-2d&device=2&legend=no&height=400&width=1200')\n
      "},{"location":"Alerting/Templates/#signedgraphurl","title":"@signedGraphUrl","text":"

      This is used when you need the url directly. One example is using the API Transport, you may want to include the url only instead of a html tag.

      @signedGraphUrl([\n    'id' => $value['port_id'],\n    'type' => 'port_bits',\n    'from' => time() - 43200,\n    'to' => time(),\n])\n
      "},{"location":"Alerting/Templates/#using-models-for-optional-data","title":"Using models for optional data","text":"

      If some value does not exist within the $faults[]-array, you may query fields from the database using Laravel models. You may use models to query additional values and use them on the template by placing the model and the value to search for within the braces. For example, ISIS-alerts do have a port_id value associated with the alert but ifName is not directly accessible from the $faults[]-array. If the name of the port was needed, it's value could be queried using a template such as:

      {{ $alert->title }}\nSeverity: {{ $alert->severity }}\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }}\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif\n@if ($alert->faults) Faults:\n@foreach ($alert->faults as $key => $value)\n  Local interface: {{ \\App\\Models\\Port::find($value['port_id'])->ifName }}\n  Adjacent IP: {{ $value['isisISAdjIPAddrAddress'] }}\n  Adjacent state: {{ $value['isisISAdjState'] }}\n\n@endforeach\n@endif\n
      "},{"location":"Alerting/Templates/#service-alert","title":"Service Alert","text":"
      <div style=\"font-family:Helvetica;\">\n<h2>@if ($alert->state == 1) <span style=\"color:red;\">{{ $alert->severity }} @endif\n@if ($alert->state == 2) <span style=\"color:goldenrod;\">acknowledged @endif</span>\n@if ($alert->state == 3) <span style=\"color:green;\">recovering @endif</span>\n@if ($alert->state == 0) <span style=\"color:green;\">recovered @endif</span>\n</h2>\n<b>Host:</b> {{ $alert->hostname }}<br>\n<b>Duration:</b> {{ $alert->elapsed }}<br>\n<br>\n\n@if ($alert->faults)\n@foreach ($alert->faults as $key => $value) <b>{{ $value['service_desc'] }} - {{ $value['service_type'] }}</b><br>\n{{ $value['service_message'] }}<br>\n<br>\n@endforeach\n@endif\n</div>\n
      "},{"location":"Alerting/Templates/#processor-alert-with-graph","title":"Processor Alert with Graph","text":"
      {{ $alert->title }} <br>\nSeverity: {{ $alert->severity }}  <br>\n@if ($alert->state == 0) Time elapsed: {{ $alert->elapsed }} @endif\nTimestamp: {{ $alert->timestamp }} <br>\nAlert-ID: {{ $alert->id }} <br>\nRule: @if ($alert->name) {{ $alert->name }} @else {{ $alert->rule }} @endif <br>\n@if ($alert->faults) Faults:\n@foreach ($alert->faults as $key => $value)\n{{ $key }}: {{ $value['string'] }}<br>\n@endforeach\n@if ($alert->faults) <b>Faults:</b><br>\n@foreach ($alert->faults as $key => $value)\n@signedGraphTag(['device' => $value['device_id'], 'type' => 'device_processor', 'width' => 459, 'height' => 213, 'from' => time() - 259200])<br>\nhttps://server/graphs/device={{ $value['device_id'] }}/type=device_processor/<br>\n@endforeach\nTemplate: CPU alert <br>\n@endif\n@endif\n
      "},{"location":"Alerting/Templates/#included","title":"Included","text":"

      We include a few templates for you to use, these are specific to the type of alert rules you are creating. For example if you create a rule that would alert on BGP sessions then you can assign the BGP template to this rule to provide more information.

      The included templates apart from the default template are:

      • BGP Sessions
      • Ports
      • Temperature
      "},{"location":"Alerting/Templates/#other-examples","title":"Other Examples","text":""},{"location":"Alerting/Templates/#microsoft-teams-markdown","title":"Microsoft Teams - Markdown","text":"
      [{{ $alert->title }}](https://your.librenms.url/device/device={{ $alert->device_id }}/)\n**Device name:** {{ $alert->sysName }}\n**Severity:** {{ $alert->severity }}\n@if ($alert->state == 0)\n**Time elapsed:** {{ $alert->elapsed }}\n@endif\n**Timestamp:** {{ $alert->timestamp }}\n**Unique-ID:** {{ $alert->uid }}\n@if ($alert->name)\n**Rule:** {{ $alert->name }}\n@else\n**Rule:** {{ $alert->rule }}\n@endif\n@if ($alert->faults)\n**Faults:**@foreach ($alert->faults as $key => $value) {{ $key }}: {{ $value['string'] }}\n@endforeach\n@endif\n
      "},{"location":"Alerting/Templates/#microsoft-teams-json","title":"Microsoft Teams - JSON","text":"
      {\n    \"@context\": \"https://schema.org/extensions\",\n    \"@type\": \"MessageCard\",\n    \"title\": \"{{ $alert->title }}\",\n@if ($alert->state === 0)\n    \"themeColor\": \"00FF00\",\n@elseif ($alert->state === 1)\n    \"themeColor\": \"FF0000\",\n@elseif ($alert->state === 2)\n    \"themeColor\": \"337AB7\",\n@elseif ($alert->state === 3)\n    \"themeColor\": \"FF0000\",\n@elseif ($alert->state === 4)\n    \"themeColor\": \"F0AD4E\",\n@else\n    \"themeColor\": \"337AB7\",\n@endif\n    \"summary\": \"LibreNMS\",\n    \"sections\": [\n        {\n@if ($alert->name)\n            \"facts\": [\n                {\n                    \"name\": \"Rule:\",\n                    \"value\": \"[{{ $alert->name }}](https://your.librenms.url/device/device={{ $alert->device_id }}/tab=alert/)\"\n                },\n@else\n                {\n                    \"name\": \"Rule:\",\n                    \"value\": \"[{{ $alert->rule }}](https://your.librenms.url/device/device={{ $alert->device_id }}/tab=alert/)\"\n                },\n@endif\n                {\n                    \"name\": \"Severity:\",\n                    \"value\": \"{{ $alert->severity }}\"\n                },\n                {\n                    \"name\": \"Unique-ID:\",\n                    \"value\": \"{{ $alert->uid }}\"\n                },\n                {\n                    \"name\": \"Timestamp:\",\n                    \"value\": \"{{ $alert->timestamp }}\"\n                },\n@if ($alert->state == 0)\n                {\n                    \"name\": \"Time elapsed:\",\n                    \"value\": \"{{ $alert->elapsed }}\"\n                },\n@endif\n                {\n                    \"name\": \"Hostname:\",\n                    \"value\": \"[{{ $alert->hostname }}](https://your.librenms.url/device/device={{ $alert->device_id }}/)\"\n                },\n                {\n                    \"name\": \"Hardware:\",\n                    \"value\": \"{{ $alert->hardware }}\"\n                },\n                {\n                    \"name\": \"IP:\",\n                    \"value\": \"{{ $alert->ip }}\"\n                },\n                {\n                    \"name\": \"Faults:\",\n                    \"value\": \" \"\n                }\n            ]\n@if ($alert->faults)\n@foreach ($alert->faults as $key => $value)\n        },\n        {\n            \"facts\": [\n                {\n                    \"name\": \"Port:\",\n                    \"value\": \"[{{ $value['ifName'] }}](https://your.librenms.url/device/device={{ $alert->device_id }}/tab=port/port={{ $value['port_id'] }}/)\"\n                },\n                {\n                    \"name\": \"Description:\",\n                    \"value\": \"{{ $value['ifAlias'] }}\"\n                },\n@if ($alert->state != 0)\n                {\n                    \"name\": \"Status:\",\n                    \"value\": \"down\"\n                }\n            ]\n@else\n                {\n                    \"name\": \"Status:\",\n                    \"value\": \"up\"\n                }\n            ]\n@endif\n@endforeach\n@endif\n        }\n    ]\n}\n
      "},{"location":"Alerting/Testing/","title":"Rules","text":"

      The simplest way of testing if an alert rule will match a device is by going to the device, clicking edit (the cog), select Capture. From this new screen choose Alerts and click run.

      The output will cycle through all alerts applicable to this device and show you the Rule name, rule, MySQL query and if the rule matches.

      See Device Troubleshooting

      "},{"location":"Alerting/Testing/#transports","title":"Transports","text":"

      You can test your transports by forcing an actual active alert to run regardless of the interval or delay values.

      ./scripts/test-alert.php. This script accepts -r for the rule id, -h for the device id or hostname and -d for debug.

      "},{"location":"Alerting/Testing/#templates","title":"Templates","text":"

      It's possible to test your new template before assigning it to a rule. To do so you can run ./scripts/test-template.php. The script will provide the help info when ran without any parameters.

      As an example, if you wanted to test template ID 10 against localhost running rule ID 2 then you would run:

      ./scripts/test-template.php -t 10 -d -h localhost -r 2

      If the rule is currently alerting for localhost then you will get the full template as expected to see on email, if it's not then you will just see the template without any fault information.

      "},{"location":"Alerting/Transports/","title":"Transports","text":"

      Transports are located within LibreNMS/Alert/Transport/ and can be configured within the WebUI under Alerts -> Alert Transports.

      Contacts will be gathered automatically and passed to the configured transports. By default the Contacts will be only gathered when the alert triggers and will ignore future changes in contacts for the incident. If you want contacts to be re-gathered before each dispatch, please set 'Updates to contact email addresses not honored' to Off in the WebUI.

      The contacts will always include the SysContact defined in the Device's SNMP configuration and also every LibreNMS user that has at least read-permissions on the entity that is to be alerted.

      At the moment LibreNMS only supports Port or Device permissions.

      You can exclude the SysContact by toggling 'Issue alerts to sysContact'.

      To include users that have Global-Read, Administrator or Normal-User permissions it is required to toggle the options:

      • Issue alerts to admins.
      • Issue alerts to read only users
      • Issue alerts to normal users.
      "},{"location":"Alerting/Transports/#using-a-proxy","title":"Using a Proxy","text":"

      Proxy Configuration

      "},{"location":"Alerting/Transports/#using-a-amqp-based-transport","title":"Using a AMQP based Transport","text":"

      You need to install an additional php module : bcmath

      "},{"location":"Alerting/Transports/#alerta","title":"Alerta","text":"

      The alerta monitoring system is a tool used to consolidate and de-duplicate alerts from multiple sources for quick \u2018at-a-glance\u2019 visualisation. With just one system you can monitor alerts from many other monitoring tools on a single screen.

      Example:

      Config Example API Endpoint http://alerta.example.com/api/alert Environment Production Apy key api key with write permission Alert state critical Recover state cleared"},{"location":"Alerting/Transports/#alertops","title":"AlertOps","text":"

      Using AlertOps integration with LibreNMS, you can seamlessly forward alerts to AlertOps with detailed information. AlertOps acts as a dispatcher for LibreNMS alerts, allowing you to determine the right individuals or teams to notify based on on-call schedules. Notifications can be sent via various channels including email, text messages (SMS), phone calls, and mobile push notifications for iOS & Android devices. Additionally, AlertOps provides escalation policies to ensure alerts are appropriately managed until they are assigned or closed. You can also filter out/aggregate alerts based on different values.

      To set up the integration:

      • Create a LibreNMS Integration: Sign up for an AlertOps account and create a LibreNMS integration from the integrations page. This will generate an Inbound Integration Endpoint URL that you'll need to copy to LibreNMS.

      • Configure LibreNMS Integration: In LibreNMS, navigate to the integration settings and paste the inbound integration URL obtained from AlertOps.

      Example:

      Config Example WebHook URL https://url/path/to/webhook"},{"location":"Alerting/Transports/#alertmanager","title":"Alertmanager","text":"

      Alertmanager is an alert handling software, initially developed for alert processing sent by Prometheus.

      It has built-in functionality for deduplicating, grouping and routing alerts based on configurable criteria.

      LibreNMS uses alert grouping by alert rule, which can produce an array of alerts of similar content for an array of hosts, whereas Alertmanager can group them by alert meta, ideally producing one single notice in case an issue occurs.

      It is possible to configure as many label values as required in Alertmanager Options section. Every label and its value should be entered as a new line.

      Labels can be a fixed string or a dynamic variable from the alert. To set a dynamic variable your label must start with extra_ then complete with the name of your label (only characters, figures and underscore are allowed here). The value must be the name of the variable you want to get (you can see all the variables in Alerts->Notifications by clicking on the Details icon of your alert when it is pending). If the variable's name does not match with an existing value the label's value will be the string you provided just as it was a fixed string.

      Multiple Alertmanager URLs (comma separated) are supported. Each URL will be tried and the search will stop at the first success.

      Basic HTTP authentication with a username and a password is supported. If you let those value blank, no authentication will be used.

      Alertmanager Docs

      Example:

      Config Example Alertmanager URL(s) http://alertmanager1.example.com,http://alertmanager2.example.com Alertmanager Username myUsername Alertmanager Password myPassword Alertmanager Options: source=librenms customlabel=value extra_dynamic_value=variable_name"},{"location":"Alerting/Transports/#api","title":"API","text":"

      The API transport allows to reach any service provider using POST, PUT or GET URLs (Like SMS provider, etc). It can be used in multiple ways:

      • The same text built from the Alert template is available in the variable

      $msg, which can then be sent as an option to the API. Be carefull that HTTP GET requests are usually limited in length.

      • The API-Option fields can be directly built from the variables defined in Template-Syntax but without the 'alert->' prefix. For instance, $alert->uptime is available as $uptime in the API transport

      • The API-Headers allows you to add the headers that the api endpoint requires.

      • The API-body allow sending data in the format required by the API endpoint.

      A few variables commonly used :

      Variable Description {{ $hostname\u00a0}} Hostname {{ $sysName\u00a0}} SysName {{ $sysDescr\u00a0}} SysDescr {{ $os\u00a0}} OS of device (librenms defined) {{ $type\u00a0}} Type of device (librenms defined) {{ $ip\u00a0}} IP Address {{ $hardware\u00a0}} Hardware {{ $version\u00a0}} Version {{ $uptime\u00a0}} Uptime in seconds {{ $uptime_short\u00a0}} Uptime in human-readable format {{ $timestamp\u00a0}} Timestamp of alert {{ $description\u00a0}} Description of device {{ $title\u00a0}} Title (as built from the Alert Template) {{ $msg\u00a0}} Body text (as built from the Alert Template)

      Example:

      The example below will use the API named sms-api of my.example.com and send the title of the alert to the provided number using the provided service key. Refer to your service documentation to configure it properly.

      Config Example API Method GET API URL http://my.example.com/sms-api API Options rcpt=0123456789 key=0987654321abcdef msg=(LNMS) {{ $title }} API Username myUsername API Password myPassword

      The example below will use the API named wall-display of my.example.com and send the title and text of the alert to a screen in the Network Operation Center.

      Config Example API Method POST API URL http://my.example.com/wall-display API Options title={{ $title }} msg={{ $msg }}

      The example below will use the API named component of my.example.com with id 1, body as json status value and headers send token authentication and content type required.

      Config Example API Method PUT API URL http://my.example.com/comonent/1 API Headers X-Token=HASH Content-Type=application/json API Body { \"status\": 2 }"},{"location":"Alerting/Transports/#aspsms","title":"aspSMS","text":"

      aspSMS is a SMS provider that can be configured by using the generic API Transport. You need a token you can find on your personnal space.

      aspSMS docs

      Example:

      Config Example Transport type Api API Method POST API URL https://soap.aspsms.com/aspsmsx.asmx/SimpleTextSMS Options UserKey=USERKEYPassword=APIPASSWORDRecipient=RECIPIENT Originator=ORIGINATORMessageText={{ $msg }}"},{"location":"Alerting/Transports/#browser-push","title":"Browser Push","text":"

      Browser push notifications can send a notification to the user's device even when the browser is not open. This requires HTTPS, the PHP GMP extension, Push API support, and permissions on each device to send alerts.

      Simply configure an alert transport and allow notification permission on the device(s) you wish to receive alerts on. You may disable alerts on a browser on the user preferences page.

      "},{"location":"Alerting/Transports/#canopsis","title":"Canopsis","text":"

      Canopsis is a hypervision tool. LibreNMS can send alerts to Canopsis which are then converted to canopsis events.

      Canopsis Docs

      Example:

      Config Example Hostname www.xxx.yyy.zzz Port Number 5672 User admin Password my_password Vhost canopsis"},{"location":"Alerting/Transports/#cisco-spark-aka-webex-teams","title":"Cisco Spark (aka Webex Teams)","text":"

      Cisco Spark (now known as Webex Teams). LibreNMS can send alerts to a Cisco Spark room. To make this possible you need to have a RoomID and a token. You can also choose to send alerts using Markdown syntax. Enabling this option provides for more richly formatted alerts, but be sure to adjust your alert template to account for the Markdown syntax.

      For more information about Cisco Spark RoomID and token, take a look here :

      • Getting started
      • Rooms

      Example:

      Config Example API Token ASd23r23edewda RoomID 34243243251 Use Markdown? x"},{"location":"Alerting/Transports/#clickatell","title":"Clickatell","text":"

      Clickatell provides a REST-API requiring an Authorization-Token and at least one Cellphone number.

      Clickatell Docs

      Here an example using 3 numbers, any amount of numbers is supported:

      Example:

      Config Example Token dsaWd3rewdwea Mobile Numbers +1234567890,+1234567891,+1234567892"},{"location":"Alerting/Transports/#discord","title":"Discord","text":"

      The Discord transport will POST the alert message to your Discord Incoming WebHook. Simple html tags are stripped from the message.

      The only required value is for url, without this no call to Discord will be made. The Options field supports the JSON/Form Params listed in the Discord Docs below.

      Discord Docs

      Example:

      Config Example Discord URL https://discordapp.com/api/webhooks/4515489001665127664/82-sf4385ysuhfn34u2fhfsdePGLrg8K7cP9wl553Fg6OlZuuxJGaa1d54fe Options username=myname"},{"location":"Alerting/Transports/#elasticsearch","title":"Elasticsearch","text":"

      You can have LibreNMS send alerts to an elasticsearch database. Each fault will be sent as a separate document.

      Example:

      Config Example Host 127.0.0.1 Port 9200 Index Pattern \\l\\i\\b\\r\\e\\n\\m\\s-Y.m.d"},{"location":"Alerting/Transports/#gitlab","title":"GitLab","text":"

      LibreNMS will create issues for warning and critical level alerts however only title and description are set. Uses Personal access tokens to authenticate with GitLab and will store the token in cleartext.

      Example:

      Config Example Host http://gitlab.host.tld Project ID 1 Personal Access Token AbCdEf12345"},{"location":"Alerting/Transports/#grafana-oncall","title":"Grafana Oncall","text":"

      Send alerts to Grafana Oncall using a Formatted Webhook

      Example:

      Config Example Webhook URL https://a-prod-us-central-0.grafana.net/integrations/v1/formatted_webhook/m12xmIjOcgwH74UF8CN4dk0Dh/"},{"location":"Alerting/Transports/#hipchat","title":"HipChat","text":"

      See the HipChat API Documentation for rooms/message for details on acceptable values.

      You may notice that the link points at the \"deprecated\" v1 API. This is because the v2 API is still in beta.

      Example:

      Config Example API URL https://api.hipchat.com/v1/rooms/message?auth_token=109jawregoaihj Room ID 7654321 From Name LibreNMS Options color=red

      At present the following options are supported: color.

      Note: The default message format for HipChat messages is HTML. It is recommended that you specify the text message format to prevent unexpected results, such as HipChat attempting to interpret angled brackets (< and >).

      "},{"location":"Alerting/Transports/#irc","title":"IRC","text":"

      The IRC transports only works together with the LibreNMS IRC-Bot. Configuration of the LibreNMS IRC-Bot is described here.

      Example:

      Config Example IRC enabled"},{"location":"Alerting/Transports/#jira","title":"JIRA","text":"

      You can have LibreNMS create issues on a Jira instance for critical and warning alerts using either the Jira REST API or webhooks. Custom fields allow you to add any required fields beyond summary and description fields in case mandatory fields are required by your Jira project/issue type configuration. Custom fields are defined in JSON format but ustom fields allow you to add any required fields beyond summary and description fields in case mandatory fields are required by your Jira project/issue type configuration. Custom fields are defined in JSON format. Currently http authentication is used to access Jira and Jira username and password will be stored as cleartext in the LibreNMS database.

      "},{"location":"Alerting/Transports/#rest-api","title":"REST API","text":"

      The config fields that need to set for Jira REST API are: Jira Open URL, Jira username, Jira password, Project key, and issue type.

      Note: REST API is that it is only able to open new tickets.

      "},{"location":"Alerting/Transports/#webhooks","title":"Webhooks","text":"

      The config fields that need to set for webhooks are: Jira Open URL, Jira Close URL, Jira username, Jira password and webhook ID.

      Note: Webhooks allow more control over how alerts are handled in Jira. With webhooks, recovery messages can be sent to a different URL than alerts. Additionally, a custom conditional logic can be built using the webhook payload and ID to automatically close an open ticket if predefined conditions are met.

      Jira Issue Types Jira Webhooks

      Example:

      Config Example Project Key JIRAPROJECTKEY Issue Type Myissuetype Open URL https://myjira.mysite.com / https://webhook-open-url Close URL https://webhook-close-url Jira Username myjirauser Jira Password myjirapass Enable webhook ON/OFF Webhook ID alert_id Custom Fileds {\"components\":[{\"id\":\"00001\"}], \"source\": \"LibrenNMS\"}"},{"location":"Alerting/Transports/#jira-service-management","title":"Jira Service Management","text":"

      Using Jira Service Management LibreNMS integration, LibreNMS forwards alerts to Jira Service Management with detailed information. Jira Service Management acts as a dispatcher for LibreNMS alerts, determines the right people to notify based on on-call schedules and notifies via email, text messages (SMS), phone calls and iOS & Android push notifications. Then escalates alerts until the alert is acknowledged or closed.

      :warning: If the feature isn\u2019t available on your site, keep checking Jira Service Management for updates.

      Example:

      Config Example WebHook URL https://url/path/to/webhook"},{"location":"Alerting/Transports/#line-messaging-api","title":"LINE Messaging API","text":"

      LINE Messaging API Docs

      Here is the step for setup a LINE bot and using it in LibreNMS.

      1. Use your real LINE account register in developer protal.

      2. Add a new channel, choose Messaging API and continue fill up the forms, note that Channel name cannot edit later.

      3. Go to \"Messaging API\" tab of your channel, here listing some important value.

        • Bot basic ID and QR code is your LINE bot's ID and QR code.
        • Channel access token (long-lived), will use it in LibreNMS, keep it safe.
      4. Use your real Line account add your LINE bot as a friend.

      5. Recipient ID can be groupID, userID or roomID, it will be used in LibreNMS to send message to a group or a user. Use the following NodeJS program and ngrok for temporally https webhook to listen it.

        LINE-bot-RecipientFetcher

      6. Run the program and using ngrok expose port to public

        $ node index.js\n$ ngrok http 3000\n
      7. Go to \"Messaging API\" tab of your channel, fill up Webhook URL to https://<your ngrok domain>/webhook

      8. If you want to let LINE bot send message to a yourself, use your real account to send a message to your LINE bot. Program will print out the userID in console.

        sample value:

        {\"type\":\"user\",\"userId\":\"U527xxxxxxxxxxxxxxxxxxxxxxxxxc0ee\"}\n
      9. If you want to let LINE bot send message to a group, do the following steps.

        • Add your LINE bot into group
        • Use your real account to send a message to group

        Program will print out the groupID in console, it will be Recipient ID, keep it safe.

        sample value:

        {\"type\":\"group\",\"groupId\":\"Ce51xxxxxxxxxxxxxxxxxxxxxxxxxx6ef\",\"userId\":\"U527xxxxxxxxxxxxxxxxxxxxxxxxxc0ee\"} ```\n

      Example:

      Config Example Access token fhJ9vH2fsxxxxxxxxxxxxxxxxxxxxlFU= Recipient (groupID, userID or roomID) Ce51xxxxxxxxxxxxxxxxxxxxxxxxxx6ef"},{"location":"Alerting/Transports/#line-notify","title":"LINE Notify","text":"

      LINE Notify

      LINE Notify API Document

      Example:

      Config Example Token AbCdEf12345"},{"location":"Alerting/Transports/#mail","title":"Mail","text":"

      The E-Mail transports uses the same email-configuration as the rest of LibreNMS. As a small reminder, here is its configuration directives including defaults:

      Emails will attach all graphs included with the @signedGraphTag directive. If the email format is set to html, they will be embedded. To disable attaching images, set email_attach_graphs to false.

      alerting/email

      lnms config:set email_html true\nlnms config:set email_attach_graphs false\n

      Example:

      Config Example Email me@example.com"},{"location":"Alerting/Transports/#matrix","title":"Matrix","text":"

      For using the Matrix transports, you have to create a room on the Matrix-server. The provided Auth_token belongs to an user, which is member of this room. The Message, sent to the matrix-room can be built from the variables defined in Template-Syntax but without the 'alert->' prefix. See API-Transport. The variable $msg is contains the result of the Alert template.The Matrix-Server URL is cutted before the beginning of the _matrix/client/r0/... API-part.

      Example:

      Config Example Matrix-Server URL https://matrix.example.com/ Room !ajPbbPalmVbNuQoBDK:example.com Auth_token: MDAyYmxvY2F0aW9uI...z1DCn6lz_uOhtW3XRICg Message: Alert: {{ $msg }} https://librenms.example.com"},{"location":"Alerting/Transports/#messagebird","title":"Messagebird","text":"

      LibreNMS can send text messages through Messagebird Rest API transport.

      Config Example Api Key Api rest key given in the messagebird dashboard Originator E.164 formatted originator Recipient E.164 formatted recipient for multi recipents comma separated Character limit Range 1..480 (max 3 split messages)"},{"location":"Alerting/Transports/#messagebird-voice","title":"Messagebird Voice","text":"

      LibreNMS can send messages through Messagebird voice Rest API transport (text to speech).

      Config Example Api Key Api rest key given in the messagebird dashboard Originator E.164 formatted originator Recipient E.164 formatted recipient for multi recipents comma separated Language Select box for options Spoken voice Female or Male Repeat X times the message is repeated"},{"location":"Alerting/Transports/#microsoft-teams","title":"Microsoft Teams","text":"

      LibreNMS can send alerts to Microsoft Teams Incoming Webhooks which are then posted to a specific channel. Microsoft recommends using markdown formatting for connector cards. Administrators can opt to compose the MessageCard themselves using JSON to get the full functionality.

      Example:

      Config Example WebHook URL https://outlook.office365.com/webhook/123456789 Use JSON? x"},{"location":"Alerting/Transports/#nagios-compatible","title":"Nagios Compatible","text":"

      The nagios transport will feed a FIFO at the defined location with the same format that nagios would. This allows you to use other alerting systems with LibreNMS, for example Flapjack.

      Example:

      Config Example Nagios FIFO /path/to/my.fifo"},{"location":"Alerting/Transports/#opsgenie","title":"OpsGenie","text":"

      Using OpsGenie LibreNMS integration, LibreNMS forwards alerts to OpsGenie with detailed information. OpsGenie acts as a dispatcher for LibreNMS alerts, determines the right people to notify based on on-call schedules and notifies via email, text messages (SMS), phone calls and iOS & Android push notifications. Then escalates alerts until the alert is acknowledged or closed.

      Create a LibreNMS Integration from the integrations page once you signup. Then copy the API key from OpsGenie to LibreNMS.

      If you want to automatically ack and close alerts, leverage Marid integration. More detail with screenshots is available in OpsGenie LibreNMS Integration page.

      Example:

      Config Example WebHook URL https://url/path/to/webhook"},{"location":"Alerting/Transports/#osticket","title":"osTicket","text":"

      LibreNMS can send alerts to osTicket API which are then converted to osTicket tickets.

      Example:

      Config Example API URL http://osticket.example.com/api/http.php/tickets.json API Token 123456789"},{"location":"Alerting/Transports/#pagerduty","title":"PagerDuty","text":"

      LibreNMS can make use of PagerDuty, this is done by utilizing an API key and Integraton Key.

      API Keys can be found under 'API Access' in the PagerDuty portal.

      Integration Keys can be found under 'Integration' for the particular Service you have created in the PagerDuty portal.

      Example:

      Config Example API Key randomsample Integration Key somerandomstring"},{"location":"Alerting/Transports/#philips-hue","title":"Philips Hue","text":"

      Want to spice up your noc life? LibreNMS will flash all lights connected to your philips hue bridge whenever an alert is triggered.

      To setup, go to the you http://your-bridge-ip/debug/clip.html

      • Update the \"URL:\" field to /api
      • Paste this in the \"Message Body\" {\"devicetype\":\"librenms\"}
      • Press the round button on your philips Hue Bridge
      • Click on POST
      • In the Command Response You should see output with your username. Copy this without the quotes

      More Info: Philips Hue Documentation

      Example:

      Config Example Host http://your-bridge-ip Hue User username Duration 1 Second"},{"location":"Alerting/Transports/#playsms","title":"PlaySMS","text":"

      PlaySMS is an open source SMS-Gateway that can be used via their HTTP API using a Username and WebService Token. Please consult PlaySMS's documentation regarding number formatting.

      PlaySMS Docs

      Here an example using 3 numbers, any amount of numbers is supported:

      Example:

      Config Example PlaySMS https://localhost/index.php User user1 Token MYFANCYACCESSTOKEN From My Name Mobiles +1234567892,+1234567890,+1234567891"},{"location":"Alerting/Transports/#pushbullet","title":"Pushbullet","text":"

      Get your Access Token from your Pushbullet's settings page and set it in your transport:

      Example:

      Config Example Access Token MYFANCYACCESSTOKEN"},{"location":"Alerting/Transports/#pushover","title":"Pushover","text":"

      If you want to change the default notification sound for all notifications then you can add the following in Pushover Options:

      sound=falling

      You also have the possibility to change sound per severity: sound_critical=falling sound_warning=siren sound_ok=magic

      Enabling Pushover support is fairly easy, there are only two required parameters.

      Firstly you need to create a new Application (called LibreNMS, for example) in your account on the Pushover website (https://pushover.net/apps).

      Now copy your API Key and obtain your User Key from the newly created Application and setup the transport.

      Pushover Docs

      Example:

      Config Example Api Key APPLICATIONAPIKEYGOESHERE User Key USERKEYGOESHERE Pushover Options sound_critical=falling sound_warning=siren sound_ok=magic"},{"location":"Alerting/Transports/#rocketchat","title":"Rocket.chat","text":"

      The Rocket.chat transport will POST the alert message to your Rocket.chat Incoming WebHook using the attachments option. Simple html tags are stripped from the message. All options are optional, the only required value is for url, without this then no call to Rocket.chat will be made.

      Rocket.chat Docs

      Example:

      Config Example Webhook URL https://rocket.url/api/v1/chat.postMessage Rocket.chat Options channel=#Alerting username=myname icon_url=http://someurl/image.gif icon_emoji=:smirk:"},{"location":"Alerting/Transports/#sensu","title":"Sensu","text":"

      The Sensu transport will POST an Event to the Agent API upon an alert being generated.

      It will be categorised (ok, warning or critical), and if you configure the alert to send recovery notifications, Sensu will also clear the alert automatically. No configuration is required - as long as you are running the Sensu Agent on your poller with the HTTP socket enabled on tcp/3031, LibreNMS will start generating Sensu events as soon as you create the transport.

      Acknowledging alerts within LibreNMS is not directly supported, but an annotation (acknowledged) is set, so a mutator or silence, or even the handler could be written to look for it directly in the handler. There is also an annotation (generated-by) set, to allow you to treat LibreNMS events differently from agent events.

      The 'shortname' option is a simple way to reduce the length of device names in configs. It replaces the last 3 domain components with single letters (e.g. websrv08.dc4.eu.corp.example.net gets shortened to websrv08.dc4.eu.cen).

      "},{"location":"Alerting/Transports/#limitations","title":"Limitations","text":"
      • Only a single namespace is supported
      • Sensu will reject rules with special characters - the Transport will attempt to fix up rule names, but it's best to stick to letters, numbers and spaces
      • The transport only deals in absolutes - it ignores the got worse/got better states
      • The agent will buffer alerts, but LibreNMS will not - if your agent is offline, alerts will be dropped
      • There is no backchannel between Sensu and LibreNMS - if you make changes in Sensu to LibreNMS alerts, they'll be lost on the next event (silences will work)

      Example:

      Config Example Sensu Endpoint http://localhost:3031 Sensu Namespace eu-west Check Prefix lnms Source Key hostname"},{"location":"Alerting/Transports/#signl4","title":"SIGNL4","text":"

      SIGNL4 offers critical alerting, incident response and service dispatching for operating critical infrastructure. It alerts you persistently via app push, SMS text, voice calls, and email including tracking, escalation, on-call duty scheduling and collaboration.

      Integrating SIGNL4 with LibreNMS to forward critical alerts with detailed information to responsible people or on-call teams. The integration supports triggering as well as closing alerts.

      In the configuration for your SIGNL4 alert transport you just need to enter your SIGNL4 webhook URL including team or integration secret.

      Example:

      Config Example Webhook URL https://connect.signl4.com/webhook/{team-secret}

      You can find more information about the integration here.

      "},{"location":"Alerting/Transports/#slack","title":"Slack","text":"

      The Slack transport will POST the alert message to your Slack Incoming WebHook using the attachments option, you are able to specify multiple webhooks along with the relevant options to go with it. Simple html tags are stripped from the message. All options are optional, the only required value is for url, without this then no call to Slack will be made.

      We currently support the following attachment options:

      • author_name

      We currently support the following global message options:

      • channel_name : Slack channel name (without the leading '#') to which the alert will go
      • icon_emoji : Emoji name in colon format to use as the author icon

      Slack docs

      The alert template can make use of Slack markdown. In the Slack markdown dialect, custom links are denoted with HTML angled brackets, but LibreNMS strips these out. To support embedding custom links in alerts, use the bracket/parentheses markdown syntax for links. For example if you would typically use this for a Slack link:

      <https://www.example.com|My Link>

      Use this in your alert template:

      [My Link](https://www.example.com)

      Example:

      Config Example Webhook URL https://slack.com/url/somehook Channel network-alerts Author Name LibreNMS Bot Icon :scream:"},{"location":"Alerting/Transports/#smseagle","title":"SMSEagle","text":"

      SMSEagle is a hardware SMS Gateway that can be used via their HTTP API using a Username and password.

      Destination numbers are one per line, with no spaces. They can be in either local or international dialling format.

      SMSEagle Docs

      Example:

      Config Example SMSEagle Host ip.add.re.ss User smseagle_user Password smseagle_user_password Mobiles +3534567890 0834567891"},{"location":"Alerting/Transports/#smsmode","title":"SMSmode","text":"

      SMSmode is a SMS provider that can be configured by using the generic API Transport. You need a token you can find on your personnal space.

      SMSmode docs

      Example:

      Config Example Transport type Api API Method POST API URL http://api.smsmode.com/http/1.6/sendSMS.do Options accessToken=PUT_HERE_YOUR_TOKEN numero=PUT_HERE_DESTS_NUMBER_COMMA_SEPARATEDmessage={{ $msg }}"},{"location":"Alerting/Transports/#splunk","title":"Splunk","text":"

      LibreNMS can send alerts to a Splunk instance and provide all device and alert details.

      Example output:

      Feb 21 15:21:52 nms  hostname=\"localhost\", sysName=\"localhost\", \nsysDescr=\"\", sysContact=\"\", os=\"fortigate\", type=\"firewall\", ip=\"localhost\", \nhardware=\"FGT_50E\", version=\"v5.6.9\", serial=\"\", features=\"\", location=\"\", \nuptime=\"387\", uptime_short=\" 6m 27s\", uptime_long=\" 6 minutes 27 seconds\", \ndescription=\"\", notes=\"\", alert_notes=\"\", device_id=\"0\", rule_id=\"0\", \nid=\"0\", proc=\"\", status=\"1\", status_reason=\"\", ping_timestamp=\"\", ping_loss=\"0\", \nping_min=\"25.6\", ping_max=\"26.8\", ping_avg=\"26.3\", \ntitle=\"localhost recovered from  Device up/down  \", elapsed=\"14m 54s\", uid=\"0\", \nalert_id=\"0\", severity=\"critical\", name=\"Device up/down\", \ntimestamp=\"2020-02-21 15:21:33\", state=\"0\", device_device_id=\"0\", \ndevice_inserted=\"\", device_hostname=\"localhost\", device_sysName=\"localhost\", \ndevice_ip=\"localhost\", device_overwrite_ip=\"\", device_timeout=\"\", device_retries=\"\", \ndevice_snmp_disable=\"0\", device_bgpLocalAs=\"0\", \ndevice_sysObjectID=\"\", device_sysDescr=\"\", \ndevice_sysContact=\"\", device_version=\"v5.6.9\", device_hardware=\"FGT_50E\", \ndevice_features=\"build1673\", device_location_id=\"\", device_os=\"fortigate\", \ndevice_status=\"1\", device_status_reason=\"\", device_ignore=\"0\", device_disabled=\"0\", \ndevice_uptime=\"387\", device_agent_uptime=\"0\", device_last_polled=\"2020-02-21 15:21:33\", \ndevice_last_poll_attempted=\"\", device_last_polled_timetaken=\"7.9\", \ndevice_last_discovered_timetaken=\"11.77\", device_last_discovered=\"2020-02-21 13:16:42\", \ndevice_last_ping=\"2020-02-21 15:21:33\", device_last_ping_timetaken=\"26.3\", \ndevice_purpose=\"\", device_type=\"firewall\", device_serial=\"FGT50EXXX\", \ndevice_icon=\"images/os/fortinet.svg\", device_poller_group=\"0\", \ndevice_override_sysLocation=\"0\", device_notes=\"\", device_port_association_mode=\"1\", \ndevice_max_depth=\"0\", device_disable_notify=\"0\", device_location=\"\", \ndevice_vrf_lites=\"Array\", device_lat=\"\", device_lng=\"\", - \nsysObjectID => \"\"; `\n

      Each alert will be sent as a separate message.

      Example:

      Config Example Host 127.0.0.1 UDP Port 514"},{"location":"Alerting/Transports/#syslog","title":"Syslog","text":"

      You can have LibreNMS emit alerts as syslogs complying with RFC 3164.

      More information on RFC 3164 can be found here: https://tools.ietf.org/html/rfc3164

      Example output: <26> Mar 22 00:59:03 librenms.host.net librenms[233]: [Critical] network.device.net: Port Down - port_id => 98939; ifDescr => xe-1/1/0;

      Each fault will be sent as a separate syslog.

      Example:

      Config Example Host 127.0.0.1 Port 514 Facility 3"},{"location":"Alerting/Transports/#telegram","title":"Telegram","text":"

      Thank you to snis for these instructions.

      1. First you must create a telegram account and add BotFather to you list. To do this click on the following url: https://telegram.me/botfather

      2. Generate a new bot with the command \"/newbot\" BotFather is then asking for a username and a normal name. After that your bot is created and you get a HTTP token. (for more options for your bot type \"/help\")

      3. Add your bot to telegram with the following url: http://telegram.me/<botname> to use app or https://web.telegram.org/<botname> to use in web, and send some text to the bot.

      4. The BotFather should have responded with a token, copy your token code and go to the following page in chrome: https://api.telegram.org/bot<tokencode>/getUpdates (this could take a while so continue to refresh until you see something similar to below)

      5. You see a json code with the message you sent to the bot. Copy the Chat id. In this example that is \u201c-9787468\u201d within this example: \"message\":{\"message_id\":7,\"from\":\"id\":656556,\"first_name\":\"Joo\",\"last_name\":\"Doo\",\"username\":\"JohnDoo\"},\"chat\":{\"id\":-9787468,\"title\":\"Telegram Group\"},\"date\":1435216924,\"text\":\"Hi\"}}]}.

      6. Now create a new \"Telegram transport\" in LibreNMS (Global Settings -> Alerting Settings -> Telegram transport). Click on 'Add Telegram config' and put your chat id and token into the relevant box.

      7. If want to use a group to receive alerts, you need to pick the Chat ID of the group chat, and not of the Bot itself.

      Telegram Docs

      Example:

      Config Example Chat ID 34243432 Token 3ed32wwf235234 Format HTML or MARKDOWN"},{"location":"Alerting/Transports/#twilio-sms","title":"Twilio SMS","text":"

      Twilio will send your alert via SMS. From your Twilio account you will need your account SID, account token and your Twilio SMS phone number that you would like to send the alerts from. Twilio's APIs are located at: https://www.twilio.com/docs/api?filter-product=sms

      Example:

      Config Example SID ACxxxxxxxxxxxxxxxxxxxxxxxxxxxx Token 7xxxx573acxxxbc2xxx308d6xxx652d32 Twilio SMS Number 8888778660"},{"location":"Alerting/Transports/#ukfast-pss","title":"UKFast PSS","text":"

      UKFast PSS tickets can be raised from alerts using the UKFastPSS transport. This required an API key with PSS write permissions

      Example:

      Config Example API Key ABCDefgfg12 Author 5423 Priority Critical Secure true"},{"location":"Alerting/Transports/#victorops","title":"VictorOps","text":"

      VictorOps provide a webHook url to make integration extremely simple. To get the URL required login to your VictorOps account and go to:

      Settings -> Integrations -> REST Endpoint -> Enable Integration.

      The URL provided will have $routing_key at the end, you need to change this to something that is unique to the system sending the alerts such as librenms. I.e:

      https://alert.victorops.com/integrations/generic/20132414/alert/2f974ce1-08fc-4dg8-a4f4-9aee6cf35c98/librenms

      Example:

      Config Example Post URL https://alert.victorops.com/integrations/generic/20132414/alert/2f974ce1-08fc-4dg8-a4f4-9aee6cf35c98/librenms"},{"location":"Alerting/Transports/#kayako-classic","title":"Kayako Classic","text":"

      LibreNMS can send alerts to Kayako Classic API which are then converted to tickets. To use this module, you need REST API feature enabled in Kayako Classic and configured email account at LibreNMS. To enable this, do this:

      AdminCP -> REST API -> Settings -> Enable API (Yes)

      Also you need to know the department id to provide tickets to appropriate department and a user email to provide, which is used as ticket author. To get department id: navigate to appropriate department name at the departments list page in Admin CP and watch the number at the end of url. Example: http://servicedesk.example.com/admin/Base/Department/Edit/17. Department ID is 17

      As a requirement, you have to know API Url, API Key and API Secret to connect to servicedesk

      Kayako REST API Docs

      Example:

      Config Example Kayako URL http://servicedesk.example.com/api/ Kayako API Key 8cc02f38-7465-4a0c-8730-bb3af122167b Kayako API Secret Y2NhZDIxNDMtNjVkMi0wYzE0LWExYTUtZGUwMjJiZDI0ZWEzMmRhOGNiYWMtNTU2YS0yODk0LTA1MTEtN2VhN2YzYzgzZjk5 Kayako Department 1"},{"location":"Alerting/Transports/#signal-cli","title":"Signal CLI","text":"

      Use the Signal Mesenger for Alerts. Run the Signal CLI with the D-Bus option.

      GitHub Project

      Example:

      Config Example Path /opt/signal-cli/bin/signal-cli Recipient type Group Recipient dfgjsdkgljior4345=="},{"location":"Alerting/Transports/#smsfeedback","title":"SMSFeedback","text":"

      SMSFeedback is a SAAS service, which can be used to deliver Alerts via API, using API url, Username & Password.

      They can be in international dialling format only.

      SMSFeedback Api Docs

      Example:

      Config Example User smsfeedback_user Password smsfeedback_password Mobiles 71234567890 Sender name CIA"},{"location":"Alerting/Transports/#zenduty","title":"Zenduty","text":"

      Leveraging LibreNMS<>Zenduty Integration, users can send new LibreNMS alerts to the right team and notify them based on on-call schedules via email, SMS, Phone Calls, Slack, Microsoft Teams and mobile push notifications. Zenduty provides engineers with detailed context around the LibreNMS alert along with playbooks and a complete incident command framework to triage, remediate and resolve incidents with speed.

      Create a LibreNMS Integration from inside Zenduty, then copy the Webhook URL from Zenduty to LibreNMS.

      For a detailed guide with screenshots, refer to the LibreNMS documentation at Zenduty.

      Example:

      Config Example WebHook URL https://www.zenduty.com/api/integration/librenms/integration-key/"},{"location":"Developing/Application-Notes/","title":"Notes On Application Development","text":""},{"location":"Developing/Application-Notes/#librenms-json-snmp-extends","title":"LibreNMS JSON SNMP Extends","text":"

      The polling function json_app_get makes it easy to poll complex data using SNMP extends and JSON.

      The following exceptions are provided by it.

      It takes three parameters, in order in the list below.

      • Integer :: Device ID to fetch it for.
      • String :: The extend name. For example, if 'zfs' is passed it will be converted to 'nsExtendOutputFull.3.122.102.115'.
      • Integer :: Minimum expected version of the JSON return.

      The required keys for the returned JSON are as below.

      • version :: The version of the snmp extend script. Should be numeric and at least 1.
      • error :: Error code from the snmp extend script. Should be > 0 (0 will be ignored and negatives are reserved)
      • errorString :: Text to describe the error.
      • data :: An key with an array with the data to be used.

      The supported exceptions are as below.

      • JsonAppPollingFailedException :: Empty return from SNMP.
      • JsonAppParsingFailedException :: Could not parse the JSON
      • JsonAppBlankJsonException :: Blank JSON.
      • JsonAppMissingKeysException :: Missing required keys.
      • JsonAppWrongVersionException :: Older version than supported.
      • JsonAppExtendErroredException :: Polling and parsing was good, but the returned data has an error set. This may be checked via $e->getParsedJson() and then checking the keys error and errorString.

      The error value can be accessed via $e->getCode(). The output can be accessed via $->getOutput() Only returned JsonAppParsingFailedException. The parsed JSON can be access via $e->getParsedJson().

      An example below from includes/polling/applications/zfs.inc.php...

      try {\n    $zfs = json_app_get($device, $name, 1)['data'];\n} catch (JsonAppMissingKeysException $e) {\n    //old version with out the data key\n    $zfs = $e->getParsedJson();\n} catch (JsonAppException $e) {\n    echo PHP_EOL . $name . ':' . $e->getCode() . ':' . $e->getMessage() . PHP_EOL;\n    update_application($app, $e->getCode() . ':' . $e->getMessage(), []);\n\n    return;\n}\n
      "},{"location":"Developing/Application-Notes/#compression","title":"Compression","text":"

      Also worth noting that json_app_get supports compressed data via base64 encoded gzip. If base64 encoding is detected on the the SNMP return, it will be gunzipped and then parsed.

      https://github.com/librenms/librenms-agent/blob/master/utils/librenms_return_optimizer may be used to optimize JSON returns.

      "},{"location":"Developing/Application-Notes/#application-data-storage","title":"Application Data Storage","text":"

      The $app model is supplied for each application poller and graph. You may access and update the $app->data field to store arrays of data the Application model.

      When you call update_application() the $app model will be saved along with any changes to the data field.

      // set the varaible data to $foo\n$app->data = [\n    'item_A' => 123,\n    'item_B' => 4.5,\n    'type' => 'foo',\n    'other_items' => [ 'a', 'b', 'c' ],\n];\n\n// save the change\n$app->save();\n\n// var_dump the contents of the variable\nvar_dump($app->data);\n
      "},{"location":"Developing/Code-Structure/","title":"Code structure","text":"

      This document will try and provide a good overview of how the code is structured within LibreNMS. We will go through the main directories and provide information on how and when they are used. LibreNMS now uses Laravel for much of it's frontend (webui) and database code. Much of the Laravel documentation applies: https://laravel.com/docs/structure

      Directories from the (filtered) structure tree below are some of the directories that will be most interesting during development:

      .\n\u251c\u2500 app\n\u251c\u2500 database\n\u2502  \u2514\u2500 migrations\n\u251c\u2500 doc\n\u251c\u2500 html\n\u2502  \u251c\u2500 css\n\u2502  \u2502  \u2514\u2500 custom\n\u2502  \u2514\u2500 js\n\u251c\u2500 includes\n\u2502  \u251c\u2500 definitions\n\u2502  \u251c\u2500 discovery\n\u2502  \u251c\u2500 html\n\u2502  \u2502  \u251c\u2500 forms\n\u2502  \u2502  \u251c\u2500 graphs\n\u2502  \u2502  \u251c\u2500 pages\n\u2502  \u2502  \u2514\u2500 reports\n\u2502  \u2514\u2500 polling\n\u251c\u2500 LibreNMS\n\u251c\u2500 logs\n\u251c\u2500 mibs\n\u2514\u2500 rrd\n
      "},{"location":"Developing/Code-Structure/#doc","title":"doc/","text":"

      This is the location of all the documentation for LibreNMS, this is in GitHub markdown format and can be viewed online

      "},{"location":"Developing/Code-Structure/#app","title":"app/","text":"

      Most Laravel and Eloquent classes should be under this directory.

      "},{"location":"Developing/Code-Structure/#librenms","title":"LibreNMS/","text":"

      Classes that don't belong to the Laravel application belong in this directory, with a directory structure that matches the namespace. One class per file. See PSR-0 for details.

      "},{"location":"Developing/Code-Structure/#html","title":"html/","text":"

      All legacy web accessible files are located here. New pages should follow the Laravel conventions.

      "},{"location":"Developing/Code-Structure/#htmlapi_v0php","title":"html/api_v0.php","text":"

      This is the API routing file which directs users to the correct API function based on the API endpoint call.

      "},{"location":"Developing/Code-Structure/#htmlindexphp","title":"html/index.php","text":"

      This is the main file which all links within LibreNMS are parsed through. It loads the majority of the relevant includes needed for the control panel to function. CSS and JS files are also loaded here.

      "},{"location":"Developing/Code-Structure/#htmlcss","title":"html/css/","text":"

      All used CSS files are located here.

      "},{"location":"Developing/Code-Structure/#htmlcsscustom","title":"html/css/custom/","text":"

      This is a directory you can put custom css files into that won't interfere with auto updates

      "},{"location":"Developing/Code-Structure/#htmljs","title":"html/js/","text":"

      All used JS files are located here.

      "},{"location":"Developing/Code-Structure/#includes","title":"includes/","text":"

      This directory is quite big and contains all the files to make the cli and polling / discovery to work. This code is not currently accessible from Laravel code (intentionally).

      "},{"location":"Developing/Code-Structure/#includesdiscovery-includespolling","title":"includes/discovery/, includes/polling/","text":"

      All the discovery and polling code. The format is usually quite similar between discovery and polling. Both are made up of modules and the files within the relevant directories will match that module. So for instance if you want to update the os detection for a device, you would look in includes/discovery/os/ for a file named after the operating system such as linux: includes/discovery/linux.inc.php. Within here you would update or add support for newer OS'. This is the same for polling as well.

      "},{"location":"Developing/Code-Structure/#includeshtml","title":"includes/html/","text":"

      This is where the majority of the website core files are located. These tend to be files that contain functions or often used code segments that can be included where needed rather than duplicating code.

      "},{"location":"Developing/Code-Structure/#includeshtmlforms","title":"includes/html/forms/","text":"

      This directory contains all of the files that are dynamically included from an ajax call to ajax/form.

      "},{"location":"Developing/Code-Structure/#includeshtmlapi_functionsincphp","title":"includes/html/api_functions.inc.php","text":"

      All of the functions and calls for the API are located here.

      "},{"location":"Developing/Code-Structure/#includeshtmlfunctionsincphp","title":"includes/html/functions.inc.php","text":"

      This contains the majority of functions used throughout the standard web ui.

      "},{"location":"Developing/Code-Structure/#includeshtmlgraphs","title":"includes/html/graphs/","text":"

      This directory contains global and OS specific graph definitions.

      "},{"location":"Developing/Code-Structure/#includeshtmlreports","title":"includes/html/reports/","text":"

      In here is a list of of files that generate PDF reports available to the user. These are dynamically called in from html/pdf.php based on the report the user requests.

      "},{"location":"Developing/Code-Structure/#includeshtmltable","title":"includes/html/table/","text":"

      This directory contains all of the ajax calls when generating the table of data. Most have been converted over so if you are planning to add a new table of data then you will do so here for all of the back end data calls.

      "},{"location":"Developing/Code-Structure/#includeshtmlpages","title":"includes/html/pages/","text":"

      This directory contains the URL structure when browsing the Web UI. So for example /devices/ is actually a call to includes/html/pages/devices.inc.php, /device/tab=ports/ is includes/html/pages/device/ports.inc.php.

      "},{"location":"Developing/Code-Structure/#logs","title":"logs/","text":"

      Contains the main librenms.log file by default, but can also contain your web server's logs, poller logs, and other items.

      "},{"location":"Developing/Code-Structure/#mibs","title":"mibs/","text":"

      Here is where all of the mibs are located. Generally standard mibs should be in the root directory and specific vendor mibs should be in their own subdirectory.

      "},{"location":"Developing/Code-Structure/#rrd","title":"rrd/","text":"

      Simple enough, this is where all of the rrd files are created. They are stored in directory based on the device hostname.

      "},{"location":"Developing/Code-Structure/#databasemigrations","title":"database/migrations","text":"

      Contains all the database migrations. See Laravel docs for additional info: https://laravel.com/docs/migrations

      In general to create a new table you should run:

      php artisan make:model ModelName -m -c -r\n
      "},{"location":"Developing/Creating-Documentation/","title":"Creating Documentation","text":"

      One of the goals of the LibreNMS project is to enable users to get all of the help they need from our documentation.

      The documentation uses the markdown markup language and is generated with mkdocs. To edit or create markdown you only need a text editor, but it is recommended to build your docs before submitting, in order to check them visually. The section on this page has instructions for this step.

      "},{"location":"Developing/Creating-Documentation/#writing-docs","title":"Writing docs","text":"

      When you are adding a new feature or extension, we need to have full documentation to go along with it. It's quite simple to do this:

      • Find the relevant directory to store your new document in, General, Support and Extensions are the most likely choices.
      • Think of a descriptive name that's not too long, it should match what they may be looking for or describes the feature.
      • Add the new document into the nav section of mkdocs.yml if it needs to appear in the table of contents
      • Ensure the first line contains: source: path/to/file.md - don't include the initial doc/.
      • In the body of the document, be descriptive but keep things simple. Some tips:
      • If the document could cover different distros like CentOS and Ubuntu please try and include the information for them all. If that's not possible then at least put a placeholder in asking for contributions.
      • Ensure you use the correct formatting for commands and code blocks by wrapping one liners in backticks or blocks in ```.
      • Put content into sub-headings where possible to organise the content.
      • If you rename a file, please add a redirect for the old file in mkdocs.yml like so:
          - redirects:\n      redirect_maps:\n        'old/page.md': 'new/page.md'\n

      Please ensure you add the document to the relevant section within pages of mkdocs.yml so that it's in the correct menu and is built. Forgetting this step will result in your document never seeing the light of day :)

      "},{"location":"Developing/Creating-Documentation/#formatting-docs","title":"Formatting docs","text":"

      Our docs are based on Markdown using mkdocs which adheres to markdown specs and nothing more, because of that we also import a couple of extra libraries:

      • pymdownx.tasklist
      • pymdownx.tilde

      This means you can use:

      • ~~strikethrough~~ to perform strikethrough
      • - [X] List items
      • Url's can be made [like this](https://www.librenms.org) like this
      • Code can be placed in `` for single line or ``` for multiline.
      • # Can be used for main headings which translates to a <h1> tag, increasing the #'s will increase the hX tags.
      • ### Can be used for sub-headings which will appear in the TOC to the left.
      • Settings should be prefixed with !!! setting \"<webui setting path>\"

      Markdown CheatSheet Link

      "},{"location":"Developing/Creating-Documentation/#building-docs","title":"Building docs","text":"

      This is achieved with mkdocs, a python package.

      1. Install the required packages.

      pip install mkdocs mkdocs-exclude mkdocs-material mkdocs-macros-plugin mkdocs-minify-plugin mkdocs-redirects\n
      If you encounter permissions issues, these might be reoslved by using the user option, with whatever user you are building as, e.g. -u librenms

      1. A configuration file for building LibreNMS docs is already included in the distribution: /opt/librenms/mkdocs.yml. The various configuration directives are documented here.

      2. Build from the librenms base directory: cd /opt/librenms.

      3. Building is simple:

      mkdocs build\n

      This will output all the documentation in html format to /opt/librenms/out (this folder will be ignored from any commits).

      "},{"location":"Developing/Creating-Documentation/#viewing-docs","title":"Viewing docs","text":"

      mkdocs includes it's own light-weight webserver for this purpose.

      Viewing is as simple as running the following command:

      $ mkdocs serve\nINFO    -  Building documentation...\n<..>\nINFO    -  Documentation built in 12.54 seconds\n<..>\nINFO    -  Serving on http://127.0.0.1:8000\n<..>\nINFO    -  Start watching changes\n

      Now you will find the complete set of LibreNMS documentation by opening your browser to localhost:8000.

      Note it is not necessary to build before viewing as the serve command will do this for you. Also the server will update the documents it is serving whenever changes to the markdown are made, such as in another terminal.

      "},{"location":"Developing/Creating-Documentation/#viewing-docs-from-another-machine","title":"Viewing docs from another machine","text":"

      By default the server will only listen for connections from the local machine. If you are building on a different machine you can use the following directive to listen on all interfaces:

      mkdocs serve --dev-addr=0.0.0.0:8000\n

      WARNING: this is not a secure webserver, do this at your own risk, with appropriate host security and do not leave the server running.

      "},{"location":"Developing/Creating-Release/","title":"Creating a release","text":""},{"location":"Developing/Creating-Release/#github","title":"GitHub","text":"

      You can create a new release on GitHub.

      Enter the tag version that month, i.e for September 2016 you would enter 201609.

      Enter a title, we usually use August 2016 Release

      Enter a placeholder for the body, we will edit this later.

      "},{"location":"Developing/Creating-Release/#create-changelog","title":"Create changelog","text":"

      For this, we assume you are using the master branch to create the release against.

      We now generate the changelog using the GitHub API itself so it shouldn't matter what state your local branch is in so long as it has the code to generate the changelog itself.

      Using the GitHub API means we can use the labels associated with merged pull requests to categorise the changelog. We also then record who made the pull request to thank them in the changelog itself.

      You will be asked for a GitHub personal access token. You can generate this here. No permissions should be needed so just give it a name and click Generate Token. You can then export the token as an environment variable GH_TOKEN or place it in your .env file.

      The basic command to run is by using artisan. Here you pass new tag (1.41) and previous tag (1.40). For further help run php artisan release:tag --help. This will generate a changelog up to the latest master branch, if you want it to be done against something else then pass the latest pull request number with --pr $PR_NUMBER.

      php artisan release:tag 1.41 1.40\n
      • Now commit and push the change that has been made to doc/General/Changelog.md.
      • Once the pull request has been merged in for the Changelog, you can create a new release on GitHub.
      • Create two threads on the community site:
      • A changelog thread example
      • An info thread example
      • Tweet it
      • Facebook it
      • Google Plus it
      • LinkedIn it
      "},{"location":"Developing/Dynamic-Config/","title":"Adding new config settings","text":"

      Adding support for users to update a new config option via the WebUI is now a lot easier for general options. This document shows you how to add a new config option and even section to the WebUI.

      Config settings are defined in misc/config_definitions.json

      You should give a little thought to the name of your config setting. For example: a good setting for snmp community, would be snmp.community. The dot notation is path and when the config is hydrated, it is converted to a nested array. If the user is overriding the option in config.php it would use the format $config['snmp']['community']

      "},{"location":"Developing/Dynamic-Config/#translation","title":"Translation","text":"

      The config definition system inherently supports translation. You must add the English names in the resoures/lang/en/settings.php file (and other languages if you can).

      To update the javascript translation files, run:

      ./lnms translation:generate\n
      "},{"location":"Developing/Dynamic-Config/#definition-format","title":"Definition Format","text":"

      For snmp.community, this is the definition:

      \"snmp.community\": {\n    \"group\": \"poller\",\n    \"section\": \"snmp\",\n    \"order\": 2,\n    \"type\": \"array\",\n    \"default\": [\n        \"public\"\n    ]\n}\n
      "},{"location":"Developing/Dynamic-Config/#fields","title":"Fields","text":"

      All fields are optional. To show in the web ui, group and section are required, order is recommended.

      • type: Defines the type, there are a few predefined types and custom types can be defined and implemented in a vue.js component
      • default: the default value for this setting
      • options: the options for the select type. An object with {\"value1\": \"display string\", \"value2\": \"display string\"}
      • validate: Defines more complex validation than the default simple type check. Uses Laravel validation syntax.
      • group: The web ui tab this is under
      • section: A panel grouping settings in the web ui
      • order: The order to display this setting within the section
      "},{"location":"Developing/Dynamic-Config/#predefined-types","title":"Predefined Types","text":"
      • string: A string
      • integer: A number
      • boolean: A simple toggle switch
      • array: A list of values that can be added, removed, and re-ordered.
      • select: A dropdown box with predefined options. Requires the option field.
      • email: Will validate the input is the correct format for an email
      • password: Will mask the value of the input (but does not keep it fully private)
      "},{"location":"Developing/Dynamic-Config/#custom-types","title":"Custom Types","text":"

      You may set the type field to a custom type and define a Vue.js component to display it to the user.

      The Vue.js component should be named as \"SettingType\" where type is the custom type entered with the first letter capitalized. Vue.js components exist in the resources/js/components directory.

      Here is an empty component named SettingType (make sure to rename it). It pulls in BaseSetting mixin for basic setting code to reuse. You should review the BaseSetting component.

      <template>\n    <div></div>\n</template>\n\n<script>\n    import BaseSetting from \"./BaseSetting\";\n\n    export default {\n        name: \"SettingType\",\n        mixins: [BaseSetting]\n    }\n</script>\n\n<style scoped>\n\n</style>\n

      Using Vue.js is beyond the scope of this document. Documentation can be found at vuejs.org.

      "},{"location":"Developing/Getting-Started/","title":"Get ready to contribute to LibreNMS","text":"

      This document is intended to help you get your local environment set up to contribute code to the LibreNMS project.

      "},{"location":"Developing/Getting-Started/#setting-up-a-development-environment","title":"Setting up a development environment","text":"

      When starting to develop, it may be tempting to just make changes on your production server, but that will make things harder for you. Taking a little time to set up somewhere to work on code changes can really help.

      Possible options:

      • A Linux computer, VM, or container
      • Another directory on your LibreNMS server
      • Windows Subsystem for Linux
      "},{"location":"Developing/Getting-Started/#set-up-your-development-git-clone","title":"Set up your development git clone","text":"
      1. Follow the documentation on using git

      2. Install development dependencies ./scripts/composer_wrapper.php install

      3. Set variables in .env, including database settings. Which could be a local or remote MySQL server including your production DB.

      APP_ENV=local\nAPP_DEBUG=true\n...\n
      1. Start a development webserver ./lnms serve

      2. Access the Web UI at http://localhost:8000

      "},{"location":"Developing/Getting-Started/#automated-testing","title":"Automated testing","text":"

      LibreNMS uses continuous integration to test code changes to help reduce bugs. This also helps guarantee the changes you contribute won't be broken in the future. You can find out more in our Validating Code Documentation

      The default database connection for automated testing is testing.

      To override the database parameters for unit tests, configure your .env file accordingly. The defaults (from config/database.php) are:

      DB_TEST_DRIVER=\"mysql\"   # PDO driver\nDB_TEST_HOST=\"localhost\" # hostname or IP address\nDB_TEST_PORT=\"\"          # port\nDB_TEST_DATABASE=\"librenms_phpunit_78hunjuybybh\" # database\nDB_TEST_USERNAME=\"root\"  # username\nDB_TEST_PASSWORD=\"\"      # password\nDB_TEST_SOCKET=\"\"        # unix socket path\n
      "},{"location":"Developing/Getting-Started/#polling-debug-output","title":"Polling debug output","text":"

      You can see detailed info by running your polling code in debug mode by adding a -d flag.

      ./discovery.php -d -h HOSTNAME\nlnms device:poll HOSTNAME -vv\n
      "},{"location":"Developing/Getting-Started/#inspecting-variables","title":"Inspecting variables","text":"

      Sometimes you want to find out what a variable contains (such as the data return from an snmpwalk). You can dump one or more variables and halt execution with the dd() function.

      dd($variable1, $variable2);\n
      "},{"location":"Developing/Getting-Started/#inspecting-web-pages","title":"Inspecting web pages","text":"

      Installing the development dependencies and setting APP_DEBUG enables the Laravel Debugbar This will allow you to inspect page generation and errors right in your web browser.

      "},{"location":"Developing/Getting-Started/#better-code-completion-in-ides-and-editors","title":"Better code completion in IDEs and editors","text":"

      You can generate some files to improve code completion. (These file are not updated automatically, so you may need to re-run these command periodically)

      ./lnms ide-helper:generate\n./lnms ide-helper:models -N\n
      "},{"location":"Developing/Getting-Started/#emulating-devices","title":"Emulating devices","text":"

      You can capture and emulate devices using Snmpsim. LibreNMS has a set of scripts to make it easier to work with snmprec files. LibreNMS Snmpsim helpers

      "},{"location":"Developing/Getting-Started/#laravel-documentation","title":"Laravel documentation","text":"

      You can find a lot of how LibreNMS works by following the Laravel Documentation

      "},{"location":"Developing/Merging-Pull-Requests/","title":"Merging Pull Requests","text":""},{"location":"Developing/Merging-Pull-Requests/#github","title":"GitHub","text":"

      We will now build the monthly change log from our GitHub commits. When merging a commit, please ensure you:

      • Click the Merge pull request button
      • Give the merge a descriptive but short title
      • For the commit message prepend it with one of the following tags for the pull request to appear in the changelog:
      • devices: or newdevice: For new device support.
      • feature: or feat: To indicate this is a new or updated feature
      • webui: or web: To indicate this is an update to the WebUI
      • fix: or bugfix: To show this is a bug fix.
      • refactoring: or refactor: When the changes are refactoring a large portion of code
      • You can reference an issue number with #xyz, i.e #1234
      • Use the Confirm squash and merge button to merge.
      "},{"location":"Developing/Merging-Pull-Requests/#example-commits","title":"Example commits","text":""},{"location":"Developing/Merging-Pull-Requests/#feature","title":"Feature","text":"

      feature: Added new availability map #4401

      "},{"location":"Developing/Merging-Pull-Requests/#new-device","title":"New device","text":"

      newdevice: Added support for Cisco ASA #4402

      "},{"location":"Developing/SNMP-Traps/","title":"Creating snmp trap handlers","text":"

      You must have a working snmptrapd. See SNMP TRAP HANDLER

      Make sure the MIB is loaded from the trap you are adding. Edit /etc/systemd/system/snmptrapd.service.d/mibs.conf to add it then restart snmptrapd.

      MIBDIRS option is not recursive, so you need to specify each directory individually.

      Create a new class in LibreNMS\\Snmptrap\\Handlers that implements the LibreNMS\\Interfaces\\SnmptrapHandler interface. For example:

      <?php\n/**\n * ColdBoot.php\n *\n * Handles the SNMPv2-MIB::coldStart trap\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <https://www.gnu.org/licenses/>.\n *\n * @package    LibreNMS\n * @link       https://www.librenms.org\n */\n\nnamespace LibreNMS\\Snmptrap\\Handlers;\n\nuse App\\Models\\Device;\nuse LibreNMS\\Enum\\Severity;\nuse LibreNMS\\Interfaces\\SnmptrapHandler;\nuse LibreNMS\\Snmptrap\\Trap;\n\nclass ColdBoot implements SnmptrapHandler\n{\n    /**\n     * Handle snmptrap.\n     * Data is pre-parsed and delivered as a Trap.\n     *\n     * @param Device $device\n     * @param Trap $trap\n     * @return void\n     */\n    public function handle(Device $device, Trap $trap)\n    {\n        $trap->log('SNMP Trap: Device ' . $device->displayName() . ' cold booted', $device->device_id, 'reboot', Severity::Warning);\n    }\n}\n

      where number on the end means color of the eventlog:

      Severity::Ok = green\nSeverity::Info = cyan\nSeverity::Notice = blue\nSeverity::Warning = yellow\nSeverity::Error = red\n

      Register the mapping in the config/snmptraps.php file. Make sure to use the full trap OID and correct class.

      'SNMPv2-MIB::coldStart' => \\LibreNMS\\Snmptrap\\Handlers\\ColdBoot::class,\n

      The handle function inside your new class will receive a LibreNMS/Snmptrap/Trap object containing the parsed trap. It is common to update the database and create event log entries within the handle function.

      "},{"location":"Developing/SNMP-Traps/#getting-information-from-the-trap","title":"Getting information from the Trap","text":""},{"location":"Developing/SNMP-Traps/#source-information","title":"Source information","text":"
      $trap->getDevice();   // gets Device model for the device associated with this trap\n$trap->ip;            // gets source IP of this trap\n$trap->getTrapOid();  // returns the string you registered your class with\n
      "},{"location":"Developing/SNMP-Traps/#retrieving-data-from-the-trap","title":"Retrieving data from the Trap","text":"
      $trap->getOidData('IF-MIB::ifDescr.114');\n

      getOidData() requires the full name including any additional index. You can use these functions to search the OID keys.

      $trap->findOid('ifDescr');  // returns the first oid key that contains the string\n$trap->findOids('ifDescr'); // returns all oid keys containing the string\n
      "},{"location":"Developing/SNMP-Traps/#advanced","title":"Advanced","text":"

      If the above isn't adequate, you can get the entire trap text:

      $trap->raw;\n
      "},{"location":"Developing/SNMP-Traps/#tests","title":"Tests","text":"

      Submitting new traps requires them to be fully tested. You can find many examples in the tests/Feature/SnmpTraps/ directory.

      Here is a basic example of a test that trap handler only creates a log message. If your trap modifies the database, you should also test that it does so.

      <?php\n\nnamespace LibreNMS\\Tests\\Feature\\SnmpTraps;\n\nclass ColdStratTest extends SnmpTrapTestCase\n{\n    public function testColdStart(): void\n    {\n        $this->assertTrapLogsMessage(rawTrap: <<<'TRAP'\n{{ hostname }}\nUDP: [{{ ip }}]:44298->[192.168.5.5]:162\nDISMAN-EVENT-MIB::sysUpTimeInstance 0:0:1:12.7\nSNMPv2-MIB::snmpTrapOID.0 SNMPv2-MIB::coldStart\nTRAP,\n            log: 'SNMP Trap: Device {{ hostname }} cold booted', // The log message sent\n            failureMessage: 'Failed to handle SNMPv2-MIB::coldStart', // an informative message to let user know what failed\n            args: [4, 'reboot'], // the additional arguments to the log method\n        );\n    }\n}\n
      "},{"location":"Developing/Sensor-State-Support/","title":"Sensor State Support","text":""},{"location":"Developing/Sensor-State-Support/#introduction","title":"Introduction","text":"

      In this section we are briefly going to walk through, what it takes to write sensor state support. We will also briefly get around the concepts of the current sensor state monitoring.

      "},{"location":"Developing/Sensor-State-Support/#logic","title":"Logic","text":"

      For sensor state monitoring, we have 4 DB tables we need to concentrate about.

      • sensors
      • state_indexes
      • state_translations
      • sensors_to_state_indexes

      We will just briefly tie a comment to each one of them.

      "},{"location":"Developing/Sensor-State-Support/#sensors","title":"Sensors","text":"

      Each time a sensor needs to be polled, the system needs to know which sensor is it that it need to poll, at what oid is this sensor located and what class the sensor is etc. This information is fetched from the sensors table.

      "},{"location":"Developing/Sensor-State-Support/#state_indexes","title":"state_indexes","text":"

      Is where we keep track of which state sensors we monitor.

      "},{"location":"Developing/Sensor-State-Support/#state_translations","title":"state_translations","text":"

      Is where we map the possible returned state sensor values to a generic LibreNMS value, in order to make displaying and alerting more generic. We also map these values to the actual state sensor(state_index) where these values are actually returned from.

      The LibreNMS generic states are derived from Nagios:

      0 = OK\n1 = Warning\n2 = Critical\n3 = Unknown\n
      "},{"location":"Developing/Sensor-State-Support/#sensors_to_state_indexes","title":"sensors_to_state_indexes","text":"

      Is as you might have guessed, where the sensor_id is mapped to a state_index_id.

      "},{"location":"Developing/Sensor-State-Support/#example","title":"Example","text":"

      For YAML based state discovery:

      mib: NETBOTZV2-MIB\nmodules:\n    sensors:\n        state:\n            data:\n                -\n                    oid: dryContactSensorTable\n                    value: dryContactSensorValue\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.1.1.2.{{ $index }}'\n                    descr: dryContactSensorLabel\n                    group: Contact Sensors\n                    index: 'dryContactSensor.{{ $index }}'\n                    state_name: dryContactSensor\n                    states:\n                        - { value: -1, generic: 3, graph: 0, descr: 'null' }\n                        - { value:  0, generic: 0, graph: 0, descr: open }\n                        - { value:  1, generic: 2, graph: 0, descr: closed }\n                -\n                    oid: doorSwitchSensorTable\n                    value: doorSwitchSensorValue\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.2.1.2.{{ $index }}'\n                    descr: doorSwitchSensorLabel\n                    group: Switch Sensors\n                    index: 'doorSwitchSensor.{{ $index }}'\n                    state_name: doorSwitchSensor\n                    states:\n                        - { value: -1, generic: 3, graph: 0, descr: 'null' }\n                        - { value:  0, generic: 0, graph: 0, descr: open }\n                        - { value:  1, generic: 2, graph: 0, descr: closed }\n                -\n                    oid: cameraMotionSensorTable\n                    value: cameraMotionSensorValue\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.3.1.2.{{ $index }}'\n                    descr: cameraMotionSensorLabel\n                    group: Camera Motion Sensors\n                    index: 'cameraMotionSensor.{{ $index }}'\n                    state_name: cameraMotionSensor\n                    states:\n                        - { value: -1, generic: 3, graph: 0, descr: 'null' }\n                        - { value:  0, generic: 0, graph: 0, descr: noMotion }\n                        - { value:  1, generic: 2, graph: 0, descr: motionDetected }\n                -\n                    oid: otherStateSensorTable\n                    value: otherStateSensorErrorStatus\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.2.10.1.3.{{ $index }}'\n                    descr: otherStateSensorLabel\n                    index: '{{ $index }}'\n                    state_name: otherStateSensorErrorStatus\n                    states:\n                        - { value: 0, generic: 0, graph: 0, descr: normal }\n                        - { value: 1, generic: 1, graph: 0, descr: info }\n                        - { value: 2, generic: 1, graph: 0, descr: warning }\n                        - { value: 3, generic: 2, graph: 0, descr: error }\n                        - { value: 4, generic: 2, graph: 0, descr: critical }\n                        - { value: 5, generic: 2, graph: 0, descr: failure }\n
      "},{"location":"Developing/Sensor-State-Support/#advanced-example","title":"Advanced Example","text":"

      For advanced state discovery:

      This example will be based on a Cisco power supply sensor and is all it takes to have sensor state support for Cisco power supplies in Cisco switches. The file should be located in /includes/discovery/sensors/state/cisco.inc.php.

      <?php\n\n$oids = snmpwalk_group($device, 'ciscoEnvMonSupplyStatusTable', 'CISCO-ENVMON-MIB');\n\nif (!empty($oids)) {\n    //Create State Index\n    $state_name = 'ciscoEnvMonSupplyState';\n    $states = [\n        ['value' => 1, 'generic' => 0, 'graph' => 0, 'descr' => 'normal'],\n        ['value' => 2, 'generic' => 1, 'graph' => 0, 'descr' => 'warning'],\n        ['value' => 3, 'generic' => 2, 'graph' => 0, 'descr' => 'critical'],\n        ['value' => 4, 'generic' => 3, 'graph' => 0, 'descr' => 'shutdown'],\n        ['value' => 5, 'generic' => 3, 'graph' => 0, 'descr' => 'notPresent'],\n        ['value' => 6, 'generic' => 2, 'graph' => 0, 'descr' => 'notFunctioning'],\n    ];\n    create_state_index($state_name, $states);\n\n    $num_oid = '.1.3.6.1.4.1.9.9.13.1.5.1.3.';\n    foreach ($oids as $index => $entry) {\n        //Discover Sensors\n        discover_sensor($valid['sensor'], 'state', $device, $num_oid.$index, $index, $state_name, $entry['ciscoEnvMonSupplyStatusDescr'], '1', '1', null, null, null, null, $entry['ciscoEnvMonSupplyState'], 'snmp', $index);\n\n        //Create Sensor To State Index\n        create_sensor_to_state_index($device, $state_name, $index);\n    }\n}\n
      "},{"location":"Developing/Support-New-OS/","title":"Intro","text":"

      This document is broken down into the relevant sections depending on what support you are adding. During all of these examples we will be using the OS of pulse as the example OS we will add.

      • Adding the initial detection.
      • Adding Memory and CPU information.
      • Adding Health / Sensor information.
      • Adding Wireless Sensor information.
      • Adding custom graphs.
      • Adding Unit tests (required).
      • Optional Settings

      We currently have a script in pre-beta stages that can help speed up the process of deploying a new OS. It has support for add sensors in a basic form (except state sensors).

      In this example, we will add a new OS called test-os using the device ID 101 that has already been added. It will be of the type network and belongs to the vendor, Cisco:

      ./scripts/new-os.php -h 101 -o test-os -t network -v cisco

      The process will then step you through the process with some more questions. Please be warned, this is currently pre-beta and may cause some issues. Please let us know of any on Discord.

      "},{"location":"Developing/Using-Git/","title":"Using Git","text":"

      Git can have a bit of a steep learning curve, stick with it as it is worth learning the basics2 at least.

      If you want to help develop LibreNMS and haven't really used Git before then this quick primer will help you get started.

      Some assumptions:

      • Work is being done on a Linux box.
      • LibreNMS is to be installed in /opt/librenms
      • You have git installed.
      • You have a GitHub Account.
      • You are using ssh to connect to GitHub (If not, replace git@github.com:/yourusername/librenms.git with https://github.com/yourusername/librenms.git.

      ** Replace yourusername with your GitHub username. **

      "},{"location":"Developing/Using-Git/#fork-librenms-repo","title":"Fork LibreNMS repo","text":"

      You do this directly within GitHub, click the 'Fork' button near the top right.

      If you are associated with multiple organisations within GitHub then you might need to select which account you want to push the fork to.

      "},{"location":"Developing/Using-Git/#prepare-your-git-environment","title":"Prepare your git environment","text":"

      These are the defaults that are recommended.

      git config branch.autosetupmerge true\ngit config --global user.name \"John Doe\"\ngit config --global user.email johndoe@example.com\n
      "},{"location":"Developing/Using-Git/#clone-the-repo","title":"Clone the repo","text":"

      Ok so now that you have forked the repo, you now need to clone it to your local install where you can then make the changes you need and submit them back.

      cd /opt/\ngit clone git@github.com:/yourusername/librenms.git\n
      "},{"location":"Developing/Using-Git/#add-upstream-repo","title":"Add Upstream repo","text":"

      To be able to pull in changes from the master LibreNMS repo you need to have it setup on your system.

      git remote add upstream https://github.com/librenms/librenms.git\n

      Now you have two configured remotes:

      • origin: This is your repository, you can push and pull changes here.
      • upstream: This is the main LibreNMS repository and you can only pull changes.
      "},{"location":"Developing/Using-Git/#workflow-guide","title":"Workflow guide","text":"

      As you become more familiar you may find a better workflow that fits your needs, until then this should be a safe workflow for you to follow.

      Before you start work on a new branch / feature. Make sure you are up to date.

      cd /opt/librenms\ngit checkout master\ngit pull upstream master\ngit push origin master\n

      At this stage it's worth pointing out that we have some standard checks that are performed when you submit a pull request, you can run these checks yourself to be sure no issues are present in your pull request.

      Now, create a new branch to do you work on. It's important that you do this as you are then able to work on more than one feature at a time and submit them as pull requests individually. If you did all your work in the master branch then it gets a bit messy!

      You need to give your branch a name. If an issue is open (or closed on GitHub) then you can use that, in this example if the issue number is 123 then we will use issue-123. If a post exists on the community forum then you can use the post id like community-123. You're also welcome to use any arbitrary name for your branch but try and make it relevant to what the branch is.

      git checkout -b issue-123\n

      Now, code away. Make the changes you need, test, change and test again :) When you are ready to submit the updates as a pull request then commit away.

      git add path/to/new/files/or/folders\ngit commit -a -m 'Added feature to do X, Y and Z'\ngit push origin issue-123\n

      If you need to rebase against master then you can do this with:

      git pull upstream master\ngit push origin issue-123\n

      If after do this you get some merge conflicts then you need to resolve these before carrying on.

      Please try to squash all commits into one, this isn't essential as we can do this when we merge but it would be helpful to do this before you submit your pull request.

      Now you will be ready to submit a pull request from within GitHub. To do this, go to your GitHub page for the LibreNMS repo. Now select the branch you have just been working on (issue-123) from the drop down to the left and then click 'Pull Request'. Fill in the details to describe the work you have done and click 'Create pull request'.

      Thanks for your first pull request :)

      Ok, that should get you started on the contributing path. If you have any other questions then stop by our Discord Server

      "},{"location":"Developing/Using-Git/#hints-and-tips","title":"Hints and tips","text":"

      Undo last commit

      git reset --soft 'HEAD^'

      Remove specific commit

      git revert <HASH>

      Restore deleted file

      git checkout $(git rev-list -n 1 HEAD -- \"$file\")^ -- \"$file\"

      Merge last two commits

      git rebase --interactive HEAD~2

      In the text file that opens, change the last commit to squash from pick then save an exit.

      For more tips take a look at Oh shit, git!

      "},{"location":"Developing/Validating-Code/","title":"Validating Code","text":""},{"location":"Developing/Validating-Code/#validating-code","title":"Validating Code","text":"

      As part of the pull request process with GitHub we run some automated build tests to ensure that the code is error free, standards compliant and our test suite builds successfully.

      Rather than submit a pull request and wait for the results, you can run these checks yourself to ensure a more seamless merge.

      All of these commands should be run from within the librenms directory and can be run as the librenms user unless otherwise noted.

      Install composer (you can skip this if composer is already installed).

      curl -sS https://getcomposer.org/installer | php

      Composer will now be installed into /opt/librenms/composer.phar.

      Now install the dependencies we require:

      ./composer.phar install

      Once composer is installed you can now run the code validation script:

      ./lnms dev:check

      If you see Tests ok, submit away :) then all is well. If you see other output then it should contain what you need to resolve the issues and re-test.

      "},{"location":"Developing/Validating-Code/#git-hooks","title":"Git Hooks","text":"

      Git has a hook system which you can use to trigger checks at various stages. Utilising the ./lnms dev:check you can make this part of your commit process.

      Add ./lnms dev:check to your .git/hooks/pre-commit:

      echo \"/opt/librenms/lnms dev:check\" >> /opt/librenms/.git/hooks/pre-commit\nchmod +x /opt/librenms/.git/hooks/pre-commit\n
      "},{"location":"Developing/os/Custom-Graphs/","title":"Custom Graphs","text":"

      First we define our graphs in includes/definitions.inc.php to share our work and contribute in the development of LibreNMS. :-) (or place in config.php if you don't plan to contribute)

      // Pulse Secure Graphs\n$config['graph_types']['device']['pulse_sessions'] = ['section' => 'firewall', 'order' => 0, 'descr' => 'Active Sessions'];\n$config['graph_types']['device']['pulse_users'] = ['section' => 'firewall', 'order' => 0, 'descr' => 'Active Users'];\n
      "},{"location":"Developing/os/Custom-Graphs/#polling-os","title":"Polling OS","text":"

      OS polling is not necessarily where custom polling should be done, please speak to one of the core devs in Discord for guidance.

      Let's update our example file to add additional polling:

      includes/polling/os/pulse.inc.php\n

      We declare two specific graphs for users and sessions numbers. Theses two graphs will be displayed on the firewall section of the graphs tab as it was written in the definition include file.

      <?php\n\nuse LibreNMS\\RRD\\RrdDefinition;\n\n$users = snmp_get($device, 'iveConcurrentUsers.0', '-OQv', 'PULSESECURE-PSG-MIB');\n\nif (is_numeric($users)) {\n    $rrd_def = RrdDefinition::make()->addDataset('users', 'GAUGE', 0);\n\n    $fields = array(\n        'users' => $users,\n    );\n\n    $tags = compact('rrd_def');\n    data_update($device, 'pulse_users', $tags, $fields);\n    $os->enableGraph('pulse_users');\n}\n\n$sessions = snmp_get($device, 'iveConcurrentUsers.0', '-OQv', 'PULSESECURE-PSG-MIB');\n\nif (is_numeric($sessions)) {\n    $rrd_def = RrdDefinition::make()->addDataset('sessions', 'GAUGE', 0);\n\n    $fields = array(\n        'sessions' => $sessions,\n    );\n\n    $tags = compact('rrd_def');\n    data_update($device, 'pulse_sessions', $tags, $fields);\n    $os->enableGraph('pulse_sessions');\n}\n
      "},{"location":"Developing/os/Custom-Graphs/#displaying","title":"Displaying","text":"

      The specific graphs are not displayed automatically so we need to write the following PHP code:

      Pulse Sessions

      includes/html/graphs/device/pulse_sessions.inc.php\n
      <?php\n\n$rrd_filename = Rrd::name($device['hostname'], 'pulse_sessions');\n\nrequire 'includes/html/graphs/common.inc.php';\n\n$ds = 'sessions';\n\n$colour_area = '9999cc';\n$colour_line = '0000cc';\n\n$colour_area_max = '9999cc';\n\n$graph_max = 1;\n\n$unit_text = 'Sessions';\n\nrequire 'includes/graphs/generic_simplex.inc.php';\n

      Pulse Users

      includes/html/graphs/device/pulse_users.inc.php\n
      <?php\n\n$rrd_filename = Rrd::name($device['hostname'], 'pulse_users');\n\nrequire 'includes/html/graphs/common.inc.php';\n\n$ds = 'users';\n\n$colour_area = '9999cc';\n$colour_line = '0000cc';\n\n$colour_area_max = '9999cc';\n\n$graph_max = 1;\n\n$unit_text = 'Users';\n\nrequire 'includes/html/graphs/generic_simplex.inc.php';\n

      That should be it, after data has started to be collected graphs should appear in the WebUI.

      "},{"location":"Developing/os/Health-Information/","title":"Health Information","text":""},{"location":"Developing/os/Health-Information/#sensors","title":"Sensors","text":"

      This document will guide you through adding health / sensor information for your new device.

      Currently, we have support for the following health metrics along with the values we expect to see the data in:

      Class Measurement airflow cfm ber ratio charge % chromatic_dispersion ps/nm cooling W count # current A dbm dBm delay s eer eer fanspeed rpm frequency Hz humidity % load % loss % power W power_consumed kWh power_factor ratio pressure kPa quality_factor dB runtime Min signal dBm snr SNR state # temperature C tv_signal dBmV bitrate bps voltage V waterflow l/m percent %"},{"location":"Developing/os/Health-Information/#simple-health-discovery","title":"Simple health discovery","text":"

      We have support for defining health / sensor discovery using YAML files so that you don't need to know how to write PHP.

      Please note that DISPLAY-HINTS are disabled so ensure you use the correct divisor / multiplier if applicable.

      All yaml files are located in includes/definitions/discovery/$os.yaml. Defining the information here is not always possible and is heavily reliant on vendors being sensible with the MIBs they generate. Only snmp walks are supported, and you must provide a sane table that can be traversed and contains all the data you need. We will use netbotz as an example here.

      includes/definitions/discovery/netbotz.yaml

      mib: NETBOTZV2-MIB\nmodules:\n    sensors:\n        airflow:\n            options:\n                skip_value_lt: 0\n            data:\n                -\n                    oid: airFlowSensorTable\n                    value: airFlowSensorValue\n                    divisor: 10\n                    num_oid: '.1.3.6.1.4.1.5528.100.4.1.5.1.2.{{ $index }}'\n                    descr: '{{ $airFlowSensorLabel }}'\n                    index: 'airFlowSensorValue.{{ $index }}'\n

      At the top you can define one or more mibs to be used in the lookup of data:

      mib: NETBOTZV2-MIB For use of multiple MIB files separate them with a colon: mib: NETBOTZV2-MIB:SECOND-MIB

      For data: you have the following options:

      The only sensor we have defined here is airflow. The available options are as follows:

      • oid (required): This is the name of the table you want to snmp walk for data.
      • value (optional): This is the key within the table that contains the value. If not provided will use oid
      • num_oid (required for PullRequests): If not provided, this parameter should be computed automatically by discovery process. This parameter is still required to submit a pull request. This is the numerical OID that contains value. This should usually include {{ $index }}. In case the index is a string, {{ $str_index_as_numeric }} can be used instead and will convert the string to the equivalent OID representation.
      • divisor (optional): This is the divisor to use against the returned value.
      • multiplier (optional): This is the multiplier to use against the returned value.
      • low_limit (optional): This is the critical low threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
      • low_warn_limit (optional): This is the warning low threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
      • warn_limit (optional): This is the warning high threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
      • high_limit (optional): This is the critical high threshold that value should be (used in alerting). If an OID is specified then divisor / multiplier are used.
      • descr (required): The visible label for this sensor. It can be a key with in the table or a static string, optionally using {{ index }}.
      • group (optional): Groups sensors together under in the webui, displaying this text. Not specifying this will put the sensors in the default group.
      • index (optional): This is the index value we use to uniquely identify this sensor. {{ $index }} will be replaced by the index from the snmp walk.
      • skip_values (optional): This is an array of values we should skip over (see note below).
      • skip_value_lt (optional): If sensor value is less than this, skip the discovery.
      • skip_value_gt (optional): If sensor value is greater than this, skip the discovery.
      • entPhysicalIndex and entPhysicalIndex_measured (optional) : If the sensor belongs to a physical entity then you can link them here. The currently supported variants are :
        • entPhysicalIndex contains the entPhysicalIndex from entPhysical table, and entPhysicalIndex_measured is NULL
        • entPhysicalIndex contains \"ifIndex\" value of the linked port and entPhysicalIndex_measured contains \"ports\"
      • user_func (optional): You can provide a function name for the sensors value to be processed through (i.e. Convert fahrenheit to celsius use fahrenheit_to_celsius)
      • snmp_flags (optional): this sets the flags to be sent to snmpwalk, it overrides flags set on the sensor type and os. The default is '-OQUb'. A common issue is dealing with string indexes, setting '-OQUsbe' will change them to numeric oids. Setting ['-OQUsbe', '-Pu'] will also allow _ in oid names. You can find more in the Man Page
      • rrd_type (optional): You can change the type of the RRD file that will be created to store the data. By default, type GAUGE is used. More details can be found here: https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html

      For options: you have the following available:

      • divisor: This is the divisor to use against the returned value.
      • multiplier: This is the multiplier to use against the returned value.
      • skip_values: This is an array of values we should skip over (see note below).
      • skip_value_lt: If sensor value is less than this, skip the discovery.
      • skip_value_gt: If sensor value is greater than this, skip the discovery.

      Multiple variables can be used in the sensor's definition. The syntax is {{ $variable }}. Any oid in the current table can be used, as well as pre_cached data. The index ($index) and the sub_indexes (in case the oid is indexed multiple times) are also available: if $index=\"1.20\", then $subindex0=\"1\" and $subindex1=\"20\".

      When referencing an oid in another table the full index will be used to match the other table. If this is undesirable, you may use a single sub index by appending the sub index after a colon to the variable name. Example {{ $ifName:2 }}

      skip_values can also compare items within the OID table against values. The index of the sensor is used to retrieve the value from the OID, unless a target index is appended to the OID. Additionally, you may check fields from the device. Comparisons behave on a logical OR basis when chained, so only one of them needs to be matched for that particular sensor to be skipped during discovery. An example of this is below:

                          skip_values:\n                    -\n                      oid: sensUnit\n                      op: '!='\n                      value: 4\n                    -\n                      oid: sensConfig.0\n                      op: '!='\n                      value: 1\n                    -\n                      device: hardware\n                      op: 'contains'\n                      value: 'rev2'\n

      op can be any of the following operators :

      =, !=, ==, !==, <=, >=, <, >, starts, ends, contains, regex, in_array, not_starts, not_ends, not_contains, not_regex, not_in_array, exists

      Example:

                          skip_values:\n                    -\n                      oid: sensorName\n                      op: 'not_in_array'\n                      value: ['sensor1', 'sensor2']\n
                          skip_values:\n                    -\n                      oid: sensorOptionalOID\n                      op: 'exists'\n                      value: false\n
              temperature:\n            data:\n                -\n                    oid: hwOpticalModuleInfoTable\n                    value: hwEntityOpticalTemperature\n                    descr: '{{ $entPhysicalName }}'\n                    index: '{{ $index }}'\n                    skip_values:\n                        -\n                            oid: hwEntityOpticalMode\n                            op: '='\n                            value: '1'\n

      If you aren't able to use yaml to perform the sensor discovery, you will most likely need to use Advanced health discovery.

      "},{"location":"Developing/os/Health-Information/#advanced-health-discovery","title":"Advanced health discovery","text":"

      If you can't use the yaml files as above, then you will need to create the discovery code in php. If it is possible to create via yaml, php discovery will likely be rejected due to the much higher chance of later problems, so it is highly suggested to use yaml.

      The directory structure for sensor information is includes/discovery/sensors/$class/$os.inc.php. The format of all the sensors follows the same code format which is to collect sensor information via SNMP and then call the discover_sensor() function; except state sensors which requires additional code. Sensor information is commonly found in an ENTITY mib supplied by device's vendor in the form of a table. Other mib tables may be used as well. Sensor information is first collected by includes/discovery/sensors/pre_cache/$os.inc.php. This program will pull in data from mib tables into a $pre_cache array that can then be used in includes/discovery/sensors/$class/$os.inc.php to extract specific values which are then passed to discover_sensor().

      discover_sensor() Accepts the following arguments:

      • &$valid = This is always $valid['sensor'], do not pass any other values.
      • $class = Required. This is the sensor class from the table above (i.e humidity).
      • $device = Required. This is the $device array.
      • $oid = Required. This must be the numerical OID for where the data can be found, i.e .1.2.3.4.5.6.7.0
      • $index = Required. This must be unique for this sensor class, device and type. Typically it's the index from the table being walked, or it could be the name of the OID if it's a single value.
      • $type = Required. This should be the OS name, i.e. pulse.
      • $descr = Required. This is a descriptive value for the sensor. Some devices will provide names to use.
      • $divisor = Defaults to 1. This is used to divide the returned value.
      • $multiplier = Defaults to 1. This is used to multiply the returned value.
      • $low_limit = Defaults to null. Sets the low threshold limit for the sensor, used in alerting to report out range sensors.
      • $low_warn_limit = Defaults to null. Sets the low warning limit for the sensor, used in alerting to report near out of range sensors.
      • $warn_limit = Defaults to null. Sets the high warning limit for the sensor, used in alerting to report near out of range sensors.
      • $high_limit = Defaults to null. Sets the high limit for the sensor, used in alerting to report out range sensors.
      • $current = Defaults to null. Can be used to set the current value on discovery. Poller will update this on the next poll cycle anyway.
      • $poller_type = Defaults to snmp. Things like the unix-agent can set different values but for the most part this should be left as snmp.
      • $entPhysicalIndex = Defaults to null. Sets the entPhysicalIndex to be used to look up further hardware if available.
      • $entPhysicalIndex_measured = Defaults to null. Sets the type of entPhysicalIndex used, i.e ports.
      • $user_func = Defaults to null. You can provide a function name for the sensors value to be processed through (i.e. Convert fahrenheit to celsius use fahrenheit_to_celsius)
      • $group = Defaults to null. Groups sensors together under in the webui, displaying this text.
      • $rrd_type = Default to 'GAUGE'. Allows to change the type of the RRD file created for this sensor. More details can be found here in the RRD documentation: https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html

      For the majority of devices, this is all that's required to add support for a sensor. Polling is done based on the data gathered using discover_sensor(). If custom polling is needed then the file format is similar to discovery: includes/polling/sensors/$class/$os.inc.php. Whilst it's possible to perform additional snmp queries within polling this should be avoided where possible. The value for the OID is already available as $sensor_value.

      Graphing is performed automatically for sensors, no custom graphing is required or supported.

      "},{"location":"Developing/os/Health-Information/#adding-a-new-sensor-class","title":"Adding a new sensor class","text":"

      You will need to add code for your new sensor class in the following existing files:

      • app/Models/Sensor.php: add a free icon from Font Awesome in the $icons array.
      • doc/Developing/os/Health-Information.md: documentation for every sensor class is mandatory.
      • includes/discovery/sensors.inc.php: add the sensor class to the $run_sensors array.
      • includes/discovery/functions.inc.php: optional - if sensible low_limit and high_limit values are guessable when a SNMP-retrievable threshold is not available, add a case for the sensor class to the sensor_limit() and/or sensor_low_limit() functions.
      • LibreNMS/Util/ObjectCache.php: optional - choose menu grouping for the sensor class.
      • includes/html/pages/device/health.inc.php: add a dbFetchCell(), $datas[], and $type_text[] entry for the sensor class.
      • includes/html/pages/device/overview.inc.php: add require 'overview/sensors/$class.inc.php' in the desired order for the device overview page.
      • includes/html/pages/health.inc.php: add a $type_text[] entry for the sensor class.
      • lang/en/sensors.php: add human-readable names and units for the sensor class in English, feel free to do so for other languages as well.

      Create and populate new files for the sensor class in the following places:

      • includes/discovery/sensors/$class/: create the folder where advanced php-based discovery files are stored. Not used for yaml discovery. =======
      • includes/html/pages/device/health.inc.php: add a dbFetchCell(), $datas[], and $type_text[] entry for the sensor class.
      • includes/html/pages/device/overview.inc.php: add require 'overview/sensors/$class.inc.php' in the desired order for the device overview page.
      • includes/html/pages/health.inc.php: add a $type_text[] entry for the sensor class.
      • lang/en/sensors.php: add human-readable names and units for the sensor class in English, feel free to do so for other languages as well.

      Create and populate new files for the sensor class in the following places:

      • includes/discovery/sensors/$class/: create the folder where advanced php-based discovery files are stored. Not used for yaml discovery.
      • includes/html/graphs/device/$class.inc.php: define unit names used in RRDtool graphs.
      • includes/html/graphs/sensor/$class.inc.php: define various parameters for RRDtool graphs.
      • includes/html/pages/device/health/$class.inc.php
      • includes/html/pages/device/overview/sensors/$class.inc.php
      • includes/html/pages/health/$class.inc.php
      "},{"location":"Developing/os/Health-Information/#advanced-health-sensor-example","title":"Advanced health sensor example","text":"

      This example shows how to build sensors using the advanced method. In this example we will be collecting optical power level (dBm) from Adva FSP150CC family MetroE devices. This example will assume an understanding of SNMP and MIBs.

      First we setup includes/discovery/sensors/pre_cache/adva_fsp150.inc as shown below. The first line walks the cmEntityObject table to get information about the chassis and line cards. From this information we extract the model type which will identify which tables in the CM-Facility-Mib the ports are populated in. The program then reads the appropriate table into the $pre_cache array adva_fsp150_ports. This array will have OID indexies for each port, which we will use later to identify our sensor OIDs.

      $pre_cache['adva_fsp150'] = snmpwalk_cache_multi_oid($device, 'cmEntityObjects', [], 'CM-ENTITY-MIB', null, '-OQUbs');\n$neType = $pre_cache['adva_fsp150'][1]['neType'];\n\nif ($neType == 'ccxg116pro') {\n    $pre_cache['adva_fsp150_ports'] = snmpwalk_cache_multi_oid($device, 'cmEthernetTrafficPortTable', $pre_cache['adva_fsp150_ports'], 'CM-FACILITY-MIB', null, '-OQUbs');\n} else {\n    $pre_cache['adva_fsp150_ports'] = snmpwalk_cache_multi_oid($device, 'cmEthernetNetPortTable', $pre_cache['adva_fsp150_ports'], 'CM-FACILITY-MIB', null, '-OQUbs');\n    $pre_cache['adva_fsp150_ports'] = snmpwalk_cache_multi_oid($device, 'cmEthernetAccPortTable', $pre_cache['adva_fsp150_ports'], 'CM-FACILITY-MIB', null, '-OQUbs');\n}\n

      Next we are going to build our sensor discovery code. These are optical readings, so the file will be created as the dBm sensor type in includes/discover/sensors/dbm/adva_fsp150.inc.php. Below is a snippet of the code:

      foreach ($pre_cache['adva_fsp150_ports'] as $index => $entry) {\n    if ($entry['cmEthernetTrafficPortMediaType'] == 'fiber') {\n        //Discover received power level\n        $oidRx = '.1.3.6.1.4.1.2544.1.12.5.1.21.1.34.' . $index . '.3';\n        $oidTx = '.1.3.6.1.4.1.2544.1.12.5.1.21.1.33.' . $index . '.3';\n        $currentRx = snmp_get($device, $oidRx, '-Oqv', 'CM-PERFORMANCE-MIB', '/opt/librenms/mibs/adva');\n        $currentTx = snmp_get($device, $oidTx, '-Oqv', 'CM-PERFORMANCE-MIB', '/opt/librenms/mibs/adva');\n        if ($currentRx != 0 || $currentTx != 0) {\n            $entPhysicalIndex = $entry['cmEthernetTrafficPortIfIndex'];\n            $entPhysicalIndex_measured = 'ports';\n            $descrRx = dbFetchCell('SELECT `ifName` FROM `ports` WHERE `ifIndex`= ? AND `device_id` = ?', [$entry['cmEthernetTrafficPortIfIndex'], $device['device_id']]) . ' Rx Power';\n\n            discover_sensor(\n                $valid['sensor'],\n                'dbm',\n                $device,\n                $oidRx,\n                'cmEthernetTrafficPortStatsOPR.' . $index,\n                'adva_fsp150',\n                $descrRx,\n                $divisor,\n                $multiplier,\n                null,\n                null,\n                null,\n                null,\n                $currentRx,\n                'snmp',\n                $entPhysicalIndex,\n                $entPhysicalIndex_measured\n            );\n\n            $descrTx = dbFetchCell('SELECT `ifName` FROM `ports` WHERE `ifIndex`= ? AND `device_id` = ?', [$entry['cmEthernetTrafficPortIfIndex'], $device['device_id']]) . ' Tx Power';\n\n            discover_sensor(\n                $valid['sensor'],\n                'dbm',\n                $device,\n                $oidTx,\n                'cmEthernetTrafficPortStatsOPT.' . $index,\n                'adva_fsp150',\n                $descrTx,\n                $divisor,\n                $multiplier,\n                null,\n                null,\n                null,\n                null,\n                $currentTx,\n                'snmp',\n                $entPhysicalIndex,\n                $entPhysicalIndex_measured\n            );\n        }\n    }\n}\n

      First the program will loop through each port's index value. In the case of Advas, the ports are names Ethernet 1-1-1-1, 1-1-1-2, etc, and they are indexed as oid.1.1.1.1, oid.1.1.1.2, etc in the mib.

      Next the program checks which table the port exists in and that the connector type is 'fiber'. There are other port tables in the full code that were ommitted from the example for brevity. Copper media won't have optical readings, so if the media type isn't fiber we skip discovery for that port.

      The next two lines build the OIDs for getting the optical receive and transmit values using the $index for the port. Using the OIDs the program gets the current receive and transmit values ($currentRx and $currentTx repectively) to verify the values are not 0. Not all SFPs collect digital optical monitoring (DOM) data, in the case of Adva the value of both transmit and recieve will be 0 if DOM is not available. While 0 is a valid value for optical power, its extremely unlikely that both will be 0 if DOM is present. If DOM is not available, then the program stops discovery for that port. Note that while this is the case with Adva, other vendors may differ in how they handle optics that do not supply DOM. Please check your vendor's mibs.

      Next the program assigns the values of $entPhysicalIndex and $entPhysicalIndex_measured. In this case $entPhysicalIndex is set to the value of the cmEthernetTrafficPortIfIndex so that it is associated with port. This will also allow the sensor graphs to show up on the associated port's page in the GUI in addition to the Health page.

      Following that the program uses a database call to get the description of the port which will be used as the title for the graph in the GUI.

      Lastly the program calls discover_sensor() and passes the information collected in the previous steps. The null values are for low, low warning, high, and high warning values, which are not collected in the Adva's MIB.

      You can manually run discovery to verify the code works by running ./discovery.php -h $device_id -m sensors. You can use -v to see what calls are being used during discovery and -d to see debug output. In the output under #### Load disco module sensors #### you can see a list of sensors types. If there is a + a sensor is added, if there is a - one was deleted, and a . means no change. If there is nothing next to the sensor type then the sensor was not discovered. There is is also information about changes to the database and RRD files at the bottom.

      [librenms@nms-test ~]$ ./discovery.php -h 2 -m sensors\nLibreNMS Discovery\n164.113.194.250 2 adva_fsp150\n\n#### Load disco module core ####\n\n>> Runtime for discovery module 'core': 0.0240 seconds with 66536 bytes\n>> SNMP: [2/0.06s] MySQL: [3/0.00s] RRD: [0/0.00s]\n#### Unload disco module core ####\n\n\n#### Load disco module sensors ####\nPre-cache adva_fsp150:\n ENTITY-SENSOR: Caching OIDs: entPhysicalDescr entPhysicalName entPhySensorType entPhySensorScale entPhySensorPrecision entPhySensorValue entPhySensorOperStatus\nAirflow:\nCurrent: .\nCharge:\nDbm: Adva FSP-150 dBm..\nFanspeed:\nFrequency:\nHumidity:\nLoad:\nPower:\nPower_consumed:\nPower_factor:\nRuntime:\nSignal:\nState:\nCount:\nTemperature: ..\nTv_signal:\nBitrate:\nVoltage: .\nSnr:\nPressure:\nCooling:\nDelay:\nQuality_factor:\nChromatic_dispersion:\nBer:\nEer:\nWaterflow:\nPercent:\n\n>> Runtime for discovery module 'sensors': 3.9340 seconds with 190024 bytes\n>> SNMP: [16/3.89s] MySQL: [36/0.03s] RRD: [0/0.00s]\n#### Unload disco module sensors ####\n\nDiscovered in 5.521 seconds\n\nSNMP [18/3.96s]: Get[8/0.81s] Getnext[0/0.00s] Walk[10/3.15s]\nMySQL [41/0.03s]: Cell[10/0.01s] Row[-4/-0.00s] Rows[31/0.02s] Column[0/0.00s] Update[2/0.00s] Insert[2/0.00s] Delete[0/0.00s]\nRRD [0/0.00s]: Update[0/0.00s] Create [0/0.00s] Other[0/0.00s]\n
      "},{"location":"Developing/os/Initial-Detection/","title":"Initial Detection","text":"

      This document will provide the information you should need to add basic detection for a new OS.

      "},{"location":"Developing/os/Initial-Detection/#discovery","title":"Discovery","text":"

      OS discovery is how LibreNMS detects which OS should be used for a device. Generally detection should use sysObjectID or sysDescr, but you can also snmpget an oid and check for a value. snmpget is discouraged because it slows down all os detections, not just the added os.

      To begin, create the new OS file which should be called includes/definitions/pulse.yaml. Here is a working example:

      os: pulse\ntext: 'Pulse Secure'\ntype: firewall\nicon: pulse\nover:\n    - { graph: device_bits, text: 'Device Traffic' }\n    - { graph: device_processor, text: 'CPU Usage' }\n    - { graph: device_mempool, text: 'Memory Usage' }\ndiscovery:\n    - sysObjectID:\n        - .1.3.6.1.4.1.12532.\n

      over: This is a list of the graphs which will be shown within the device header bar (mini graphs top right).

      discovery: Here we are detecting this new OS using sysObjectID, this is the preferred method for detection. Other options are available:

      • sysObjectID The preferred operator. Checks if the sysObjectID starts with one of the strings under this item
      • sysDescr Use this in addition to sysObjectID if required. Check that the sysDescr contains one of the strings under this item
      • sysObjectID_regex Please avoid use of this. Checks if the sysObjectID matches one of the regex statements under this item
      • sysDescr_regex Please avoid use of this. Checks if the sysDescr matches one of the regex statements under this item
      • snmpget Do not use this unless none of the other methods work. Fetch an oid and compare it against a value.
        discovery:\n    -\n      snmpget:\n        - oid: <someoid>\n        - op: <[\"=\",\"!=\",\"==\",\"!==\",\"<=\",\">=\",\"<\",\">\",\"starts\",\"ends\",\"contains\",\"regex\",\"not_starts\",\"not_ends\",\"not_contains\",\"not_regex\",\"in_array\",\"not_in_array\",\"exists\"]>\n        - value: <'string' | boolean>\n
      • _except You can add this to any of the above to exclude that element. As an example:
      discovery:\n    -\n      sysObjectID:\n          - .1.3.6.1.4.1.12532.\n      sysDescr_except:\n          - 'Not some pulse'\n

      group: You can group certain OS' together by using group, for instance ios, nx-os, iosxr are all within a group called cisco.

      bad_ifXEntry: This is a list of models for which to tell LibreNMS that the device doesn't support ifXEntry and to ignore it:

       bad_ifXEntry:\n     - cisco1941\n     - cisco886Va\n     - cisco2811\n

      mib_dir: You can use this to specify an additional directory to look in for MIBs. An array is not accepted, only one directory may be specified.

      mib_dir: juniper\n

      poller_modules: This is a list of poller modules to either enable (1) or disable (0). Check misc/config_definitions.json to see which modules are enabled/disabled by default.

      poller_modules:\n    cisco-ace-serverfarms: false\n    cisco-ace-loadbalancer: false\n

      discovery_modules: This is the list of discovery modules to either enable (1) or disable (0). Check misc/config_definitions.json to see which modules are enabled/disabled by default.

      discovery_modules:\n     cisco-cef: true\n     slas: true\n     cisco-mac-accounting: false\n
      "},{"location":"Developing/os/Initial-Detection/#discovery-logic","title":"Discovery Logic","text":"

      YAML is converted to an array in PHP. Consider the following YAML:

      discovery:\n  - sysObjectID: foo\n  -\n    sysDescr: [ snafu, exodar ]\n    sysObjectID: bar\n

      This is how the discovery array would look in PHP:

      [\n     [\n       \"sysObjectID\" => \"foo\",\n     ],\n     [\n       \"sysDescr\" => [\n         \"snafu\",\n         \"exodar\",\n       ],\n       \"sysObjectID\" => \"bar\",\n     ]\n]\n

      The logic for the discovery is as follows:

      1. One of the first level items must match
      2. ALL of the second level items must match (sysObjectID, sysDescr)
      3. One of the third level items (foo, [snafu,exodar], bar) must match

      So, considering the example:

      • sysObjectID: foo, sysDescr: ANYTHING matches
      • sysObjectID: bar, sysDescr: ANYTHING does not match
      • sysObjectID: bar, sysDescr: exodar matches
      • sysObjectID: bar, sysDescr: snafu matches
      "},{"location":"Developing/os/Initial-Detection/#os-discovery","title":"OS discovery","text":"

      OS discovery collects additional standardized data about the OS. These are specified in the discovery yaml includes/definitions/discovery/<os>.yaml or LibreNMS/OS/<os>.php if more complex collection is required.

      • version The version of the OS running on the device.
      • hardware The hardware version for the device. For example: 'WS-C3560X-24T-S'
      • features Features for the device, for example a list of enabled software features.
      • serial The main serial number of the device.
      "},{"location":"Developing/os/Initial-Detection/#yaml-based-os-discovery","title":"Yaml based OS discovery","text":"
      • sysDescr_regex apply a regex or list of regexes to the sysDescr to extract named groups, this data has the lowest precedence
      • <field> specify an oid or list of oids to attempt to pull the data from, the first non-empty response will be used
      • <field>_regex parse the value out of the returned oid data, must use a named group
      • <field>_template combine multiple oid results together to create a final string value. The result is trimmed.
      • <field>_replace An array of replacements ['search regex', 'replace'] or regex to remove
      • hardware_mib MIB used to translate sysObjectID to get hardware. hardware_regex can process the result.
      modules:\n    os:\n        sysDescr_regex: '/(?<hardware>MSM\\S+) .* Serial number (?<serial>\\S+) - Firmware version (?<version>\\S+)/'\n        features: UPS-MIB::upsIdentAttachedDevices.0\n        hardware:\n            - ENTITY-MIB::entPhysicalName.1\n            - ENTITY-MIB::entPhysicalHardwareRev.1\n        hardware_template: '{{ ENTITY-MIB::entPhysicalName.1 }} {{ ENTITY-MIB::entPhysicalHardwareRev.1 }}'\n        serial: ENTITY-MIB::entPhysicalSerialNum.1\n        version: ENTITY-MIB::entPhysicalSoftwareRev.1\n        version_regex: '/V(?<version>.*)/'\n
      "},{"location":"Developing/os/Initial-Detection/#php-based-os-discovery","title":"PHP based OS discovery","text":"
      public function discoverOS(\\App\\Models\\Device $device): void\n{\n    $info = snmp_getnext_multi($this->getDeviceArray(), ['enclosureModel', 'enclosureSerialNum', 'entPhysicalFirmwareRev'], '-OQUs', 'NAS-MIB:ENTITY-MIB');\n    $device->version = $info['entPhysicalFirmwareRev'];\n    $device->hardware = $info['enclosureModel'];\n    $device->serial = $info['enclosureSerialNum'];\n}\n
      "},{"location":"Developing/os/Initial-Detection/#mibs","title":"MIBs","text":"

      If the device has MIBs available and you use it in the detection then you can add these in. It is highly recommended that you add mibs to a vendor specific directory. For instance HP mibs are in mibs/hp. Please ensure that these directories are specified in the yaml detection file, see mib_dir above.

      "},{"location":"Developing/os/Initial-Detection/#icon-and-logo","title":"Icon and Logo","text":"

      It is highly recommended to use SVG images where possible, these scale and provide a nice visual image for users with HiDPI screens. If you can't find SVG images then please use png.

      Create an SVG image of the icon and logo. Legacy PNG bitmaps are also supported but look bad on HiDPI.

      • A vector image should not contain padding.
      • The file should not be larger than 20 Kb. Simplify paths to reduce large files.
      • Use plain SVG without gzip compression.
      • The SVG root element must not contain length and width attributes, only viewBox.
      "},{"location":"Developing/os/Initial-Detection/#icon","title":"Icon","text":"
      • Save the icon SVG to html/images/os/$os.svg.
      • Icons should look good when viewed at 32x32 px.
      • Square icons are preferred to full logos with text.
      • Remove small ornaments that are almost not visible when displayed with 32px width (e.g. \u00ae or \u2122).
      "},{"location":"Developing/os/Initial-Detection/#logo","title":"Logo","text":"
      • Save the logo SVG to html/images/logos/$os.svg.
      • Logos can be any dimension, but often are wide and contain the company name.
      • If a logo is not present, the icon will be used.
      "},{"location":"Developing/os/Initial-Detection/#hints","title":"Hints","text":"

      Hints for Inkscape:

      • You can open a PDF or EPS to extract the logo.
      • Ungroup elements to isolate the logo.
      • Use Path -> Simplify to simplify paths of large files.
      • Use File -> Document Properties\u2026 -> Resize page to content\u2026 to remove padding.
      • Use File -> Clean up document to remove unused gradients, patterns, or markers.
      • Use File -> Save As -> Plain SVG to save the final image.

      By optimizing the SVG you can shrink the file size in some cases to less than 20 %. SVG Optimizer does a great job. There is also an online version.

      "},{"location":"Developing/os/Initial-Detection/#the-final-check","title":"The final check","text":"

      Discovery

      ./discovery.php -d -h HOSTNAME\n

      Polling

      lnms device:poll HOSTNAME\n

      At this step we should see all the values retrieved in LibreNMS.

      Note: If you have made a number of changes to either the OS's Discovery files, it's possible earlier edits have been cached. As such, if you do not get expected behaviour when completing the final check above, try removing the cache file first:

      rm -f cache/os_defs.cache\n
      "},{"location":"Developing/os/Mem-CPU-Information/","title":"Mem/CPU Information","text":"

      This document will guide you through adding detection for Memory / Processor for your new device.

      "},{"location":"Developing/os/Mem-CPU-Information/#memory","title":"Memory","text":"

      LibreNMS will attempt to detect memory statistics using the standard HOST-RESOURCES-MIB and UCD-SNMP-MIB MIBs. To detect non-standard MIBs, they can be defined via Yaml.

      "},{"location":"Developing/os/Mem-CPU-Information/#yaml","title":"YAML","text":"

      In order to successfully detect memory amount and usage, two of the for keys below are required. Some OS only provide a usage percentage, which will work, but a total RAM amount will not be displayed.

      • total
      • used
      • free
      • percent_used

      includes/definitions/discovery/mempools/arubaos.yaml

      mempools:\n    data:\n        -\n            total: WLSX-SWITCH-MIB::sysXMemorySize\n            used: WLSX-SWITCH-MIB::sysXMemoryUsed\n            precision: 1024\n

      The code can also interpret table based OIDs and supports many of the same features as Health Sensors including {{ }} parsing, skip_values, and precache.

      Valid data entry keys:

      • oid oid to walk to collect processor data
      • total oid or integer total memory size in bytes (or precision)
      • used oid memory used in bytes (or precision)
      • free oid memory free in bytes (or precision)
      • percent_used oid of percentage of used memory
      • descr A visible description of the memory measurement defaults to \"Memory\"
      • warn_percent Usage percentage to used for alert purposes
      • precision precision for all byte values, typically a power of 2 (1024 for example)
      • classused to generate rrd filename, defaults to system. If system, buffers, and cached exist they will be combined to calculate available memory.
      • type used to generate rrd filename, defaults to the os name
      • index used to generate rrd filename, defaults to the oid index
      • skip_values skip values see Health Sensors for specification
      • snmp_flags additional net-snmp flags
      "},{"location":"Developing/os/Mem-CPU-Information/#custom-processor-discovery-and-polling","title":"Custom Processor Discovery and Polling","text":"

      If you need to implement custom discovery or polling you can implement the MempoolsDiscovery interface and the MempoolsPolling interface in the OS class. MempoolsPolling is optional, standard polling will be used based on OIDs stored in the database.

      OS Class files reside under LibreNMS\\OS

      <?php\n\nnamespace LibreNMS\\OS;\n\nuse LibreNMS\\Interfaces\\Discovery\\MempoolsDiscovery;\nuse LibreNMS\\Interfaces\\Polling\\MempoolsPolling;\n\nclass Example extends \\LibreNMS\\OS implements MempoolsDiscovery, MempoolsPolling\n{\n    /**\n     * Discover a Collection of Mempool models.\n     * Will be keyed by mempool_type and mempool_index\n     *\n     * @return \\Illuminate\\Support\\Collection \\App\\Models\\Mempool\n     */\n    public function discoverMempools()\n    {\n        // TODO: Implement discoverMempools() method.\n    }\n\n    /**\n     * @param \\Illuminate\\Support\\Collection $mempools \\App\\Models\\Mempool\n     * @return \\Illuminate\\Support\\Collection \\App\\Models\\Mempool\n     */\n    public function pollMempools($mempools)\n    {\n        // TODO: Implement pollMempools() method.\n    }\n}\n
      "},{"location":"Developing/os/Mem-CPU-Information/#processor","title":"Processor","text":"

      Detection for processors is done via a yaml file unless custom processing of data is required.

      "},{"location":"Developing/os/Mem-CPU-Information/#yaml_1","title":"YAML","text":"

      includes/definitions/discovery/pulse.yaml

      mib: PULSESECURE-PSG-MIB\nmodules:\n    processors:\n          data:\n              -\n                  oid: iveCpuUtil\n                  num_oid: '.1.3.6.1.4.1.12532.10.{{ $index }}'\n                  type: pulse\n

      Available yaml data keys:

      Key Default Description oid required The string based oid to fetch data, could be a table or a single value num_oid optional The numerical oid to fetch data from when polling, usually should be appended by {{ $index }}. Computed by discovery process if not provided. value optional Oid to retrieve data from, primarily used for tables precision 1 The multiplier to multiply the data by. If this is negative, the data will be multiplied then subtracted from 100. descr Processor Description of this processor, may be an oid or plain string. Helpful values {{ $index }} and {{$count}} type Name of this sensor. This is used with the index to generate a unique id for this sensor. index {{ $index }} The index of this sensor, defaults to the index of the oid. skip_values optional Do not detect this sensor if the value matches

      Accessing values within yaml:

      {{ $index }} The index after the given oid {{ $count }} The count of entries (starting with 1) {{ $oid }} Any oid in the table or pre-fetched"},{"location":"Developing/os/Mem-CPU-Information/#custom-processor-discovery-and-polling_1","title":"Custom Processor Discovery and Polling","text":"

      If you need to implement custom discovery or polling you can implement the ProcessorDiscovery interface and the ProcessorPolling interface in the OS class.

      OS Class files reside under LibreNMS\\OS

      <?php\nnamespace LibreNMS\\OS;\n\nuse LibreNMS\\Device\\Processor;\nuse LibreNMS\\Interfaces\\Discovery\\ProcessorDiscovery;\nuse LibreNMS\\Interfaces\\Polling\\ProcessorPolling;\nuse LibreNMS\\OS;\n\nclass ExampleOS extends OS implements ProcessorDiscovery, ProcessorPolling\n{\n    /**\n     * Discover processors.\n     * Returns an array of LibreNMS\\Device\\Processor objects that have been discovered\n     *\n     * @return array Processors\n     */\n    public function discoverProcessors()\n    {\n        // discovery code here\n    }\n\n    /**\n     * Poll processor data.  This can be implemented if custom polling is needed.\n     *\n     * @param array $processors Array of processor entries from the database that need to be polled\n     * @return array of polled data\n     */\n    public function pollProcessors(array $processors)\n    {\n        // polling code here\n    }\n}\n
      "},{"location":"Developing/os/Settings/","title":"Optional OS Settings","text":"

      This page documents settings that can be set in the os yaml files or in config.php. All settings listed here are optional. If they are not set, the global default will be used.

      "},{"location":"Developing/os/Settings/#user-override-in-configphp","title":"User override in config.php","text":"

      Users can override these settings in their config.php.

      For example, to set an alternate icon for ios:

      $config['os']['ios']['icon'] = 'fuzzybunny';\n
      "},{"location":"Developing/os/Settings/#ignoring-sensors","title":"Ignoring Sensors","text":"

      It is possible to filter some sensors from the configuration:

      • Filter all 'current' sensors for Operating System 'vrp'.
      $config['os']['vrp']['disabled_sensors']['current'] = true;\n
      • Filter all sensors with description matching regexp '/PEM Iout/' for Operating System iosxe.
      $config['os']['iosxe']['disabled_sensors_regex'][] = '/PEM Iout/';\n
      • Filter all 'power' sensors with description matching regexp '/ Power [TR]x /' for Operating System iosxr.
      $config['os']['iosxr']['disabled_sensors_regex']['power'][] = '/ Power [TR]x /';\n
      • Ignore all temperature sensors
      $config['disabled_sensors']['temperature'] = true;\n
      • Filter all sensors matching with description regexp '/PEM Iout/'.
      $config['disabled_sensors_regex'][] = '/PEM Iout/';\n
      "},{"location":"Developing/os/Settings/#ignoring-interfaces","title":"Ignoring Interfaces","text":"

      See also: Global Ignoring Interfaces Config

      These settings are merged with the global settings, so you can only undo global ones with good_if

      empty_ifdescr: false # allow empty ifDescr\nbad_if: # ifDescr (substring, case insensitive)\n    - lp0\nbad_if_regexp: # ifDescr (regex, case insensitive)\n    - \"/^ng[0-9]+$/\"\nbad_ifname_regexp: # ifName (regex, case insensitive)\n    - \"/^xdsl_channel /\"\nbad_ifalias_regexp: # ifAlias (regex, case insensitive)\n    - \"/^vlan/\"\nbad_iftype: # ifType (substring)\n    - sonet\ngood_if: # ignore all other bad_if settings ifDescr (substring, case insensitive)\n    - virtual\nbad_ifoperstatus # IfOperStatus (substring, case insensitive)\n    - notPresent\n
      "},{"location":"Developing/os/Settings/#controlling-interface-labels","title":"Controlling interface labels","text":"

      By default we use ifDescr to label ports/interfaces. Setting either ifname or ifalias will override that. Only set one of these. ifAlias is user supplied. ifindex will append the ifindex to the port label.

      ifname: true\nifalias: true\n\nifindex: true\n
      "},{"location":"Developing/os/Settings/#poller-and-discovery-modules","title":"Poller and Discovery Modules","text":"

      The various discovery and poller modules can be enabled or disabled per OS. The defaults are usually reasonable, so likely you won't want to change more than a few. These modules can be enabled or disabled per-device in the webui and per os or globally in config.php. Usually, a poller module will not work if it's corresponding discovery module is not enabled.

      You should avoid setting these to false in the OS definitions unless it has a significant negative impact on polling. Setting modules in the definition reduces user control of modules.

      poller_modules:\n    bgp-peers: true\ndiscovery_modules:\n    arp-table: false\n
      "},{"location":"Developing/os/Settings/#snmp-settings","title":"SNMP Settings","text":""},{"location":"Developing/os/Settings/#disable-snmpbulkwalk","title":"Disable snmpbulkwalk","text":"

      Some devices have buggy snmp implementations and don't respond well to the more efficient snmpbulkwalk. To disable snmpbulkwalk and only use snmpwalk for an OS set the following.

      snmp_bulk: false\n

      If only some specific OIDs fail with snmpbulkwalk. You can disable just those OIDs. This needs to match exactly the OID being walked by LibreNMS. MIB::oid is preferred to prevent name collisions.

      oids:\n    no_bulk:\n        - UCD-SNMP-MIB::laLoadInt\n
      "},{"location":"Developing/os/Settings/#limit-the-oids-per-snmpget","title":"Limit the oids per snmpget","text":"
      snmp_max_oid: 8\n
      "},{"location":"Developing/os/Settings/#storage-settings","title":"Storage Settings","text":"

      See also: Global Storage Config

      ignore_mount_array: # exact match\n    - /var/run\nignore_mount_string: # substring\n    - run\nignore_mount_regexp: # regex\n    - \"/^\\/var/\"\n
      "},{"location":"Developing/os/Test-Units/","title":"Tests","text":"

      Tests ensure LibreNMS works as expected, now and in the future. New OS should provide as much test data as needed and added test data for existing OS is welcome.

      Saved snmp data can be found in tests/snmpsim/*.snmprec and saved database data can be found in tests/data/*.json. Please review this for any sensitive data before submitting. When replacing data, make sure it is modified in a consistent manner.

      We utilise snmpsim to do unit testing. For OS discovery, we can mock snmpsim, but for other tests you will need it installed and functioning. We run snmpsim during our integration tests, but not by default when running lnms dev:check. You can install snmpsim with the command pip3 install snmpsim.

      "},{"location":"Developing/os/Test-Units/#capturing-test-data","title":"Capturing test data","text":"If test data already exists

      If test data already exists, but is for a different device/configuration with the same OS. Then you should use the --variant (-v) option to specify a different variant of the OS, this will be tested completely separate from other variants. If there is only one variant, please do not specify one.

      "},{"location":"Developing/os/Test-Units/#1-collect-snmp-data","title":"1. Collect SNMP data","text":"

      ./scripts/collect-snmp-data.php is provided to make it easy to collect data for tests. Running collect-snmp-data.php with the --hostname (-h) allows you to capture all data used to discover and poll a device already added to LibreNMS. Make sure to re-run the script if you add additional support. Check the command-line help for more options.

      "},{"location":"Developing/os/Test-Units/#2-save-test-data","title":"2. Save test data","text":"

      After you have collected snmp data, run ./scripts/save-test-data.php with the --os (-o) option to dump the post discovery and post poll database entries to json files. This step requires snmpsim, if you are having issues, the maintainers may help you generate it from the snmprec you created in the previous step.

      Generally, you will only need to collect data once. After you have the data you need in the snmprec file, you can just use save-test-data.php to update the database dump (json) after that.

      "},{"location":"Developing/os/Test-Units/#running-tests","title":"Running tests","text":"

      Note: To run tests, ensure you have executed ./scripts/composer_wrapper.php install from your LibreNMS root directory. This will read composer.json and install any dependencies required.

      After you have saved your test data, you should run lnms dev:check verify they pass.

      To run the full suite of tests enable database and snmpsim reliant tests: lnms dev:check unit --db --snmpsim

      "},{"location":"Developing/os/Test-Units/#specific-os","title":"Specific OS","text":"

      lnms dev:check unit -o osname

      "},{"location":"Developing/os/Test-Units/#specific-module","title":"Specific Module","text":"

      lnms dev:check unit -m modulename

      "},{"location":"Developing/os/Test-Units/#using-snmpsim-for-testing","title":"Using snmpsim for testing","text":"

      You can run snmpsim to access test data by running

      lnms dev:simulate\n

      You may then run snmp queries against it using the os (and variant) as the community and 127.1.6.1:1161 as the host.

      snmpget -v 2c -c ios_c3560e 127.1.6.1:1161 sysDescr.0\n
      "},{"location":"Developing/os/Test-Units/#snmprec-format","title":"Snmprec format","text":"

      Snmprec files are simple files that store the snmp data. The data format is simple with three columns: numeric oid, type code, and data. Here is an example snippet.

      1.3.6.1.2.1.1.1.0|4|Pulse Secure,LLC,MAG-2600,8.0R14 (build 41869)\n1.3.6.1.2.1.1.2.0|6|1.3.6.1.4.1.12532.254.1.1\n

      During testing LibreNMS will use any info in the snmprec file for snmp calls. This one provides sysDescr (.1.3.6.1.2.1.1.1.0, 4 = Octet String) and sysObjectID (.1.3.6.1.2.1.1.2.0, 6 = Object Identifier), which is the minimum that should be provided for new snmprec files.

      To look up the numeric OID and type of an string OID with snmptranslate:

      snmptranslate -On -Td SNMPv2-MIB::sysDescr.0\n

      List of SNMP data types:

      Type Value OCTET STRING 4 HEX STRING 4x Integer32 2 NULL 5 OBJECT IDENTIFIER 6 IpAddress 64 Counter32 65 Gauge32 66 TimeTicks 67 Opaque 68 Counter64 70

      Hex encoded strings (4x) should be used for any strings that contain line returns.

      "},{"location":"Developing/os/Test-Units/#new-discoverypoller-modules","title":"New discovery/poller modules","text":"

      New discovery or poller modules should define database capture parameters in /tests/module_tables.yaml.

      "},{"location":"Developing/os/Test-Units/#example-workflow","title":"Example workflow","text":"

      If the base os (.snmprec) already contains test data for the module you are testing or that data conflicts with your new data, you must use a variant to store your test data (-v)."},{"location":"Developing/os/Test-Units/#add-initial-detection","title":"Add initial detection","text":"

      1. Add device to LibreNMS. It is generic and device_id = 42
      2. Run ./scripts/collect-snmp-data.php -h 42, initial snmprec will be created
      3. Add initial detection for example-os
      4. Run discovery to make sure it detects properly ./discovery.php -h 42
      5. Add any additional os items like version, hardware, features, or serial.
      6. If there is additional snmp data required, run ./scripts/collect-snmp-data.php -h 42
      7. Run ./scripts/save-test-data.php -o example-os to update the dumped database data.
      8. Review data. If you modified the snmprec or code (don't modify json manually) run ./scripts/save-test-data.php -o example-os -m os
      9. Run lnms dev:check unit --db --snmpsim
      10. If the tests succeed submit a pull request
      "},{"location":"Developing/os/Test-Units/#additional-module-support-or-test-data","title":"Additional module support or test data","text":"
      1. Add code to support module or support already exists.
      2. ./scripts/collect-snmp-data.php -h 42 -m <module>, this will add more data to the snmprec file
      3. Review data. If you modified the snmprec (don't modify json manually) run ./scripts/save-test-data.php -o example-os -m <module>
      4. Run lnms dev:check unit --db --snmpsim
      5. If the tests succeed submit a pull request
      "},{"location":"Developing/os/Test-Units/#json-application-test-writing-using-scriptsjson-app-toolphp","title":"JSON Application Test Writing Using ./scripts/json-app-tool.php","text":"
      1. First you will need a good example JSON output produced via SNMP extend in question.
      2. Read the help via ./scripts/json-app-tool.php -h.
      3. Generate the SNMPrec data via ./scripts/json-app-tool.php -a appName -s > ./tests/snmpsim/linux_appName-v1.snmprec. If the SNMP extend name OID different than the application name, then you will need to pass the -S flag for over riding that.
      4. Generate the test JSON data via ./scripts/json-app-tool.php -a appName -t > ./tests/data/linux_appName-v1.json.
      5. Update the generated './tests/data/linux_appName-v1.json' making sure that all the expected metrics are present. This assumes that everything under .data in the JSON will be collapsed and used.

      During test runs if it does not appear to be detecting the app and it has a different app name and SNMP extend name OID, make sure that -S is set properly and that 'includes/discovery/applications.inc.php' has been updated.

      "},{"location":"Developing/os/Wireless-Sensors/","title":"Wireless Sensors","text":"

      This document will guide you through adding wireless sensors for your new wireless device.

      Currently we have support for the following wireless metrics along with the values we expect to see the data in:

      Type Measurement Interface Description ap-count % WirelessApCountDiscovery The number of APs attached to this controller capacity % WirelessCapacityDiscovery The % of operating rate vs theoretical max ccq % WirelessCcqDiscovery The Client Connection Quality channel count WirelessChannelDiscovery The channel, use of frequency is preferred cell count WirelessCellDiscovery The cell in a multicell technology clients count WirelessClientsDiscovery The number of clients connected to/managed by this device distance km WirelessDistanceDiscovery The distance of a radio link in Kilometers error-rate bps WirelessErrorRateDiscovery The rate of errored packets or bits, etc error-ratio % WirelessErrorRatioDiscovery The percent of errored packets or bits, etc errors count WirelessErrorsDiscovery The total bits of errored packets or bits, etc frequency MHz WirelessFrequencyDiscovery The frequency of the radio in MHz, channels can be converted mse dB WirelessMseDiscovery The Mean Square Error noise-floor dBm WirelessNoiseFloorDiscovery The amount of noise received by the radio power dBm WirelessPowerDiscovery The power of transmit or receive, including signal level quality % WirelessQualityDiscovery The % of quality of the link, 100% = perfect link rate bps WirelessRateDiscovery The negotiated rate of the connection (not data transfer) rssi dBm WirelessRssiDiscovery The Received Signal Strength Indicator snr dB WirelessSnrDiscovery The Signal to Noise ratio, which is signal - noise floor sinr dB WirelessSinrDiscovery The Signal-to-Interference-plus-Noise Ratio rsrq dB WirelessRsrqDiscovery The Reference Signal Received Quality rsrp dBm WirelessRsrpDiscovery The Reference Signals Received Power xpi dBm WirelessXpiDiscovery The Cross Polar Interference values ssr dB WirelessSsrDiscovery The Signal strength ratio, the ratio(or difference) of Vertical rx power to Horizontal rx power utilization % WirelessUtilizationDiscovery The % of utilization compared to the current rate

      You will need to create a new OS class for your os if one doesn't exist under LibreNMS/OS. The name of this file should be the os name in camel case for example airos -> Airos, ios-wlc -> IosWlc.

      Your new OS class should extend LibreNMS\\OS and implement the interfaces for the sensors your os supports.

      namespace LibreNMS\\OS;\n\nuse LibreNMS\\Device\\WirelessSensor;\nuse LibreNMS\\Interfaces\\Discovery\\Sensors\\WirelessClientsDiscovery;\nuse LibreNMS\\OS;\n\nclass Airos extends OS implements WirelessClientsDiscovery\n{\n    public function discoverWirelessClients()\n    {\n        $oid = '.1.3.6.1.4.1.41112.1.4.5.1.15.1'; //UBNT-AirMAX-MIB::ubntWlStatStaCount.1\n        return array(\n            new WirelessSensor('clients', $this->getDeviceId(), $oid, 'airos', 1, 'Clients')\n        );\n    }\n}\n

      All discovery interfaces will require you to return an array of WirelessSensor objects.

      new WirelessSensor() Accepts the following arguments:

      • $type = Required. This is the sensor class from the table above (i.e humidity).
      • $device_id = Required. You can get this value with $this->getDeviceId()
      • $oids = Required. This must be the numerical OID for where the data can be found, i.e .1.2.3.4.5.6.7.0. If this is an array of oids, you should probably specify an $aggregator.
      • $subtype = Required. This should be the OS name, i.e airos.
      • $index = Required. This must be unique for this sensor type, device and subtype. Typically it's the index from the table being walked or it could be the name of the OID if it's a single value.
      • $description = Required. This is a descriptive value for the sensor. Shown to the user, if this is a per-ssid statistic, using SSID: $ssid here is appropriate
      • $current = Defaults to null. Can be used to set the current value on discovery. If this is null the values will be polled right away and if they do not return valid value(s), the sensor will not be discovered. Supplying a value here implies you have already verified this sensor is valid.
      • $multiplier = Defaults to 1. This is used to multiply the returned value.
      • $divisor = Defaults to 1. This is used to divided the returned value.
      • $aggregator = Defaults to sum. Valid values: sum, avg. This will combine multiple values from multiple oids into one.
      • $access_point_id = Defaults to null. If this is a wireless controller, you can link sensors to entries in the access_points table.
      • $high_limit = Defaults to null. Sets the high limit for the sensor, used in alerting to report out range sensors.
      • $low_limit = Defaults to null. Sets the low threshold limit for the sensor, used in alerting to report out range sensors.
      • $high_warn = Defaults to null. Sets the high warning limit for the sensor, used in alerting to report near out of range sensors.
      • $low_warn = Defaults to null. Sets the low warning limit for the sensor, used in alerting to report near out of range sensors.
      • $entPhysicalIndex = Defaults to null. Sets the entPhysicalIndex to be used to look up further hardware if available.
      • $entPhysicalIndexMeasured = Defaults to null. Sets the type of entPhysicalIndex used, i.e ports.

      Polling is done automatically based on the discovered data. If for some reason you need to override polling, you can implement the required polling interface in LibreNMS/Interfaces/Polling/Sensors. Using the polling interfaces should be avoided if possible.

      Graphing is performed automatically for wireless sensors, no custom graphing is required or supported.

      "},{"location":"Extensions/Agent-Setup/","title":"Check_MK Setup","text":"

      The agent can be used to gather data from remote systems you can use LibreNMS in combination with check_mk (found here). The agent can be extended to include data about applications on the remote system.

      "},{"location":"Extensions/Agent-Setup/#installation","title":"Installation","text":""},{"location":"Extensions/Agent-Setup/#linux-bsd","title":"Linux / BSD","text":"

      Make sure that systemd or xinetd is installed on the host you want to run the agent on.

      The agent uses TCP-Port 6556, please allow access from the LibreNMS host and poller nodes if you're using the Distributed Polling setup.

      On each of the hosts you would like to use the agent on, you need to do the following:

      1: Clone the librenms-agent repository:

      cd /opt/\ngit clone https://github.com/librenms/librenms-agent.git\ncd librenms-agent\n

      2: Copy the relevant check_mk_agent to /usr/bin:

      linux freebsd cp check_mk_agent /usr/bin/check_mk_agent cp check_mk_agent_freebsd /usr/bin/check_mk_agent
      chmod +x /usr/bin/check_mk_agent\n

      3: Copy the service file(s) into place.

      xinetd systemd cp check_mk_xinetd /etc/xinetd.d/check_mk cp check_mk@.service check_mk.socket /etc/systemd/system

      4: Create the relevant directories.

      mkdir -p /usr/lib/check_mk_agent/plugins /usr/lib/check_mk_agent/local\n

      5: Copy each of the scripts from agent-local/ into /usr/lib/check_mk_agent/local that you require to be graphed. You can find detail setup instructions for specific applications above.

      6: Make each one executable that you want to use with chmod +x /usr/lib/check_mk_agent/local/$script

      7: Enable the check_mk service

      xinetd systemd /etc/init.d/xinetd restart systemctl enable check_mk.socket && systemctl start check_mk.socket

      8: Login to the LibreNMS web interface and edit the device you want to monitor. Under the modules section, ensure that unix-agent is enabled.

      9: Then under Applications, enable the apps that you plan to monitor.

      10: Wait for around 10 minutes and you should start seeing data in your graphs under Apps for the device.

      "},{"location":"Extensions/Agent-Setup/#restrict-the-devices-on-which-the-agent-listens-linux-systemd","title":"Restrict the devices on which the agent listens: Linux systemd","text":"

      If you want to restrict which network adapter the agent listens on, do the following:

      1: Edit /etc/systemd/system/check_mk.socket

      2: Under the [Socket] section, add a new line BindToDevice= and the name of your network adapter.

      3: If the script has already been enabled in systemd, you may need to issue a systemctl daemon-reload and then systemctl restart check_mk.socket

      "},{"location":"Extensions/Agent-Setup/#windows","title":"Windows","text":"
      1. Grab version 1.2.6b5 of the check_mk agent from the check_mk github repo (exe/msi or compile it yourself depending on your usage): https://github.com/tribe29/checkmk/tree/v1.2.6b5/agents/windows
      2. Run the msi / exe
      3. Make sure your LibreNMS instance can reach TCP port 6556 on your target.
      "},{"location":"Extensions/Applications/","title":"Applications","text":"

      You can use Application support to graph performance statistics of many applications.

      Different applications support a variety of ways to collect data:

      1. By direct connection to the application
      2. snmpd extend
      3. The agent.

      The monitoring of applications could be added before or after the hosts have been added to LibreNMS.

      If multiple methods of collection are listed you only need to enable one.

      "},{"location":"Extensions/Applications/#snmp-extend","title":"SNMP Extend","text":"

      When using the snmp extend method, the application discovery module will pick up which applications you have set up for monitoring automatically, even if the device is already in LibreNMS. The application discovery module is enabled by default for most *nix operating systems, but in some cases you will need to manually enable the application discovery module.

      "},{"location":"Extensions/Applications/#sudo","title":"SUDO","text":"

      One major thing to keep in mind when using SNMP extend is these run as the snmpd user that can be an unprivileged user. In these situations you need to use sudo.

      To test if you need sudo, first check the user snmpd is running as. Then test if you can run the extend script as that user without issue. For example if snmpd is running as 'Debian-snmp' and we want to run the extend for proxmox, we check that the following run without error:

      sudo -u Debian-snmp /usr/local/bin/proxmox\n

      If it doesn't work, then you will need to use sudo with the extend command. For the example above, that would mean adding the line below to the sudoers file:

      Debian-snmp ALL = NOPASSWD: /usr/local/bin/proxmox\n

      Finally we would need to add sudo to the extend command, which would look like that for proxmox:

      extend proxmox /usr/bin/sudo /usr/local/bin/proxmox\n
      "},{"location":"Extensions/Applications/#json-return-optimization-using-librenms_return_optimizer","title":"JSON Return Optimization Using librenms_return_optimizer","text":"

      While the json_app_get does allow for more complex and larger data to be easily returned by a extend and the data to then be worked with, this can also sometimes result in large returns that occasionally don't play nice with SNMP on some networks.

      librenms_return_optimizer fixes this via taking the extend output piped to it, gzipping it, and then converting it to base64. The later is needed as net-snmp does not play that nice with binary data, converting most of the non-printable characters to .. This does add a bit of additional overhead to the gzipped data, but still tends to be result in a return that is usually a third of the size for JSONs items.

      The change required is fairly simply. So for the portactivity example below...

      extend portactivity /etc/snmp/extends/portactivity smtps,http,imap,imaps,postgresql,https,ldap,ldaps,nfsd,syslog-conn,ssh,matrix,gitea\n

      Would become this...

      extend portactivity /usr/local/bin/lnms_return_optimizer -- /etc/snmp/extends/portactivity smtps,http,imap,imaps,postgresql,https,ldap,ldaps,nfsd,syslog-conn,ssh,matrix,gitea\n

      The requirements for this are Perl, MIME::Base64, and Gzip::Faster.

      Installing on FreeBSD...

      pkg install p5-MIME-Base64 p5-Gzip-Faster wget\nwget https://raw.githubusercontent.com/librenms/librenms-agent/master/utils/librenms_return_optimizer -O /usr/local/bin/librenms_return_optimizer\nchmod +x /usr/local/bin/librenms_return_optimizer\n

      Installing on Debian...

      apt-get install zlib1g-dev cpanminus wget\ncpanm Gzip::Faster\ncpanm MIME::Base64\nwget https://raw.githubusercontent.com/librenms/librenms-agent/master/utils/librenms_return_optimizer -O /usr/local/bin/librenms_return_optimizer\nchmod +x /usr/local/bin/librenms_return_optimizer\n

      Currently supported applications as are below.

      • backupninja
      • certificate
      • chronyd
      • dhcp-stats
      • docker
      • fail2ban
      • fbsd-nfs-client
      • fbsd-nfs-server
      • gpsd
      • mailcow-postfix
      • mdadm
      • ntp-client
      • ntp-server
      • portactivity
      • powerdns
      • powermon
      • puppet-agent
      • pureftpd
      • redis
      • seafile
      • supervisord
      • ups-apcups
      • zfs

      The following apps have extends that have native support for this, if congiured to do so.

      • suricata
      "},{"location":"Extensions/Applications/#enable-the-application-discovery-module","title":"Enable the application discovery module","text":"
      1. Edit the device for which you want to add this support
      2. Click on the Modules tab and enable the applications module.
      3. This will be automatically saved, and you should get a green confirmation pop-up message.

      After you have enabled the application module, it would be wise to then also enable which applications you want to monitor, in the rare case where LibreNMS does not automatically detect it.

      Note: Only do this if an application was not auto-discovered by LibreNMS during discovery and polling.

      "},{"location":"Extensions/Applications/#enable-the-applications-to-be-discovered","title":"Enable the application(s) to be discovered","text":"
      1. Go to the device you have just enabled the application module for.
      2. Click on the Applications tab and select the applications you want to monitor.
      3. This will also be automatically saved, and you should get a green confirmation pop-up message.
      "},{"location":"Extensions/Applications/#agent","title":"Agent","text":"

      The unix-agent does not have a discovery module, only a poller module. That poller module is always disabled by default. It needs to be manually enabled if using the agent. Some applications will be automatically enabled by the unix-agent poller module. It is better to ensure that your application is enabled for monitoring. You can check by following the steps under the SNMP Extend heading.

      "},{"location":"Extensions/Applications/#apache","title":"Apache","text":"

      Either use SNMP extend or use the agent.

      Note that you need to install and configure the Apache mod_status module before trying the script.

      "},{"location":"Extensions/Applications/#snmp-extend_1","title":"SNMP Extend","text":"
      1. Download the script onto the desired host (the host must be added to LibreNMS devices)

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/apache-stats.py -O /etc/snmp/apache-stats.py\n

      2. Make the script executable

        chmod +x /etc/snmp/apache-stats.py\n

      3. Create the cache directory, '/var/cache/librenms/' and make sure that it is owned by the user running the SNMP daemon.

        mkdir -p /var/cache/librenms/\n

      4. Verify it is working by running /etc/snmp/apache-stats.py Package urllib3 for python3 needs to be installed. In Debian-based systems for example you can achieve this by issuing:

        apt-get install python3-urllib3\n

      5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend apache /etc/snmp/apache-stats.py\n

      6. Restart snmpd on your host

      7. Test by running

        snmpwalk <various options depending on your setup> localhost NET-SNMP-EXTEND-MIB::nsExtendOutput2Table\n

      "},{"location":"Extensions/Applications/#agent_1","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the apache script to /usr/lib/check_mk_agent/local/

      1. Verify it is working by running /usr/lib/check_mk_agent/local/apache (If you get error like \"Can't locate LWP/Simple.pm\". libwww-perl needs to be installed: apt-get install libwww-perl)

      2. Create the cache directory, '/var/cache/librenms/' and make sure that it is owned by the user running the SNMP daemon.

        mkdir -p /var/cache/librenms/\n

      3. On the device page in Librenms, edit your host and check the Apache under the Applications tab.

      "},{"location":"Extensions/Applications/#asterisk","title":"Asterisk","text":"

      A small shell script that reports various Asterisk call status.

      "},{"location":"Extensions/Applications/#snmp-extend_2","title":"SNMP Extend","text":"
      1. Download the asterisk script to /etc/snmp/ on your asterisk server.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/asterisk -O /etc/snmp/asterisk\n

      2. Make the script executable

        chmod +x /etc/snmp/asterisk\n

      3. Configure ASCLI in the script.

      4. Verify it is working by running /etc/snmp/asterisk

      5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend asterisk /etc/snmp/asterisk\n

      6. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#backupninja","title":"backupninja","text":"

      A small shell script that reports status of last backupninja backup.

      "},{"location":"Extensions/Applications/#snmp-extend_3","title":"SNMP Extend","text":"
      1. Download the backupninja script to /etc/snmp/backupninja.py on your backuped server.
        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/backupninja.py -O /etc/snmp/backupninja.py`\n
      2. Make the script executable:

        chmod +x /etc/snmp/backupninja.py\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend backupninja /etc/snmp/backupninja.py\n

      4. Restart snmpd on your host

      "},{"location":"Extensions/Applications/#bind9-aka-named","title":"BIND9 aka named","text":"
      1. Create stats file with appropriate permissions:

        touch /var/cache/bind/stats\nchown bind:bind /var/cache/bind/stats\n
        Change user:group to the user and group that's running bind/named.

      2. Bind/named configuration:

        options {\n    ...\n    statistics-file \"/var/cache/bind/stats\";\n    zone-statistics yes;\n    ...\n};\n

      3. Restart your bind9/named after changing the configuration.

      4. Verify that everything works by executing rndc stats && cat /var/cache/bind/stats. In case you get a Permission Denied error, make sure you changed the ownership correctly.

      5. Also be aware that this file is appended to each time rndc stats is called. Given this it is suggested you setup file rotation for it. Alternatively you can also set zero_stats to 1 in the config.

      6. The script for this also requires the Perl module File::ReadBackwards.

        FreeBSD       => p5-File-ReadBackwards\nCentOS/RedHat => perl-File-ReadBackwards\nDebian/Ubuntu => libfile-readbackwards-perl\n

      If it is not available, it can be installed by cpan -i File::ReadBackwards.

      1. You may possibly need to configure the agent/extend script as well.

      The config file's path defaults to the same path as the script, but with .config appended. So if the script is located at /etc/snmp/bind, the config file will be /etc/snmp/bind.config. Alternatively you can also specify a config via -c $file.

      Anything starting with a # is comment. The format for variables are $variable=$value. Empty lines are ignored. Spaces and tabs at either the start or end of a line are ignored.

      Content of an example /etc/snmp/bind.config . Please edit with your own settings.

      rndc = The path to rndc. Default: /usr/bin/env rndc\ncall_rndc = A 0/1 boolean on whether or not to call rndc stats.\n    Suggest to set to 0 if using netdata. Default: 1\nstats_file = The path to the named stats file. Default: /var/cache/bind/stats\nagent = A 0/1 boolean for if this is being used as a LibreNMS\n    agent or not. Default: 0\nzero_stats = A 0/1 boolean for if the stats file should be zeroed\n    first. Default: 0 (1 if guessed)\n

      If you want to guess at the configuration, call the script with -g and it will print out what it thinks it should be.

      "},{"location":"Extensions/Applications/#snmp-extend_4","title":"SNMP Extend","text":"
      1. Copy the bind shell script, to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/bind -O /etc/snmp/bind\n

      2. Make the script executable

        chmod +x /etc/snmp/bind\n

      3. Edit your snmpd.conf file and add:

        extend bind /etc/snmp/bind\n

      4. Restart snmpd on the host in question.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_2","title":"Agent","text":"
      1. Install the agent on this device if it isn't already and copy the script to /usr/lib/check_mk_agent/local/bind via wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/bind -O /usr/lib/check_mk_agent/local/bind

      2. Make the script executable

        chmod +x /usr/lib/check_mk_agent/local/bind\n

      3. Set the variable 'agent' to '1' in the config.

      "},{"location":"Extensions/Applications/#bird2","title":"BIRD2","text":"

      The BIRD Internet Routing Daemon (BGP)

      Due to the lack of SNMP support in the BIRD daemon, this application extracts all configured BGP protocols and parses it into LibreNMS. This application supports both IPv4 and IPv6 Peer processing.

      "},{"location":"Extensions/Applications/#snmp-extend_5","title":"SNMP Extend","text":"
      1. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:
      extend bird2 '/usr/bin/sudo /usr/sbin/birdc -r show protocols all'\n
      1. Edit your sudo users (usually visudo) and add at the bottom:
      Debian-snmp ALL=(ALL) NOPASSWD: /usr/sbin/birdc\n

      If your snmp daemon is running on a user that isnt Debian-snmp make sure that user has the correct permission to execute birdc

      1. Verify the time format for bird2 is defined. Otherwise iso short ms (hh:mm:ss) is the default value that will be used. Which is not compatible with the datetime parsing logic used to parse the output from the bird show command. timeformat protocol is the one important to be defibned for the bird2 app parsing logic to work.

      Example starting point using Bird2 shorthand iso long (YYYY-MM-DD hh:mm:ss):

      timeformat base iso long;\ntimeformat log iso long;\ntimeformat protocol iso long;\ntimeformat route iso long;\n

      Timezone can be manually specified, example \"%F %T %z\" (YYYY-MM-DD hh:mm:ss +11:45). See the Bird 2 docs for more information

      1. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#certificate","title":"Certificate","text":"

      A small python3 script that checks age and remaining validity of certificates

      This script needs following packages on Debian/Ubuntu Systems:

      • python3
      • python3-openssl

      Content of an example /etc/snmp/certificate.json . Please edit with your own settings.

      {\"domains\": [\n    {\"fqdn\": \"www.mydomain.com\"},\n    {\"fqdn\": \"some.otherdomain.org\",\n     \"port\": 8443},\n    {\"fqdn\": \"personal.domain.net\"},\n    {\"fqdn\": \"selfsignedcert_host.domain.com\",\n     \"cert_location\": \"/etc/pki/tls/certs/localhost.pem\"}\n]\n}\n
      a. (Required): Key 'domains' contains a list of domains to check. b. (Optional): You can define a port. By default it checks on port 443. c. (Optional): You may define a certificate location for self-signed certificates.

      "},{"location":"Extensions/Applications/#snmp-extend_6","title":"SNMP Extend","text":"
      1. Copy the shell script to the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/certificate.py -O /etc/snmp/certificate.py\n

      2. Make the script executable

        chmod +x /etc/snmp/certificate.py\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend certificate /etc/snmp/certificate.py\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#borgbackup","title":"BorgBackup","text":""},{"location":"Extensions/Applications/#snmp-extend_7","title":"SNMP Extend","text":"
      1. Copy the shell script to the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/borgbackup -O /etc/snmp/borgbackup\n

      2. Make the script executable

        chmod +x /etc/snmp/borgbackup\n

      3. Install depends.

        # FreeBSD\npkg p5-Config-Tiny p5-JSON p5-File-Slurp p5-MIME-Base64 p5-String-ShellQuote\n# Debian\napt-get install libconfig-tiny-perl libjson-perl libfile-slurp-perl libmime-base64-perl libstring-shellquote-perl\n# generic cpanm\ncpanm Config::Tiny File::Slurp JSON MIME::Base64 String::ShellQuote\n

      4. Set it up in cron.

        */5 * * * /etc/snmp/borgbackup 2> /dev/null > /dev/null\n

      5. Configure it. See further down below or /etc/snmp/borgbackup --help.

      6. Add the following to the SNMPD config.

        extend borgbackup /bin/cat /var/cache/borgbackup_extend/extend_return\n

      7. Restart SNMPD and wait for the device to rediscover or tell it to manually.

      "},{"location":"Extensions/Applications/#config","title":"Config","text":"

      The config file is a ini file and handled by Config::Tiny.

      - mode :: single or multi, for if this is a single repo or for\n        multiple repos.\n    - Default :: single\n\n- repo :: Directory for the borg backup repo.\n    - Default :: undef\n\n- passphrase :: Passphrase for the borg backup repo.\n    - Default :: undef\n\n- passcommand :: Passcommand for the borg backup repo.\n    - Default :: undef\n

      For single repos all those variables are in the root section of the config, so lets the repo is at '/backup/borg' with a passphrase of '1234abc'.

      repo=/backup/borg\nrepo=1234abc\n

      For multi, each section outside of the root represents a repo. So if there is '/backup/borg1' with a passphrase of 'foobar' and '/backup/derp' with a passcommand of 'pass show backup' it would be like below.

      mode=multi\n\n[borg1]\nrepo=/backup/borg1\npassphrase=foobar\n\n[derp]\nrepo=/backup/derp\npasscommand=pass show backup\n

      If 'passphrase' and 'passcommand' are both specified, then passcommand is used.

      "},{"location":"Extensions/Applications/#metrics","title":"Metrics","text":"

      The metrics are all from .data.totals in the extend return.

      Value Type Description errored repos Total number of repos that info could not be fetched for. locked repos Total number of locked repos locked_for seconds Longest time any repo has been locked. time_since_last_modified seconds Largest time - mtime for the repo nonce total_chunks chunks Total number of chunks total_csize bytes Total compressed size of all archives in all repos. total_size byes Total uncompressed size of all archives in all repos. total_unique_chunks chunks Total number of unique chuckes in all repos. unique_csize bytes Total deduplicated size of all archives in all repos. unique_size chunks Total number of chunks in all repos."},{"location":"Extensions/Applications/#capev2","title":"CAPEv2","text":"
      1. Copy the shell script to the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/cape -O /etc/snmp/cape\n

      2. Make the script executable

        chmod +x /etc/snmp/cape\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend cape /etc/snmp/cape\n

      4. Install the required packages.

        apt-get install libfile-readbackwards-perl libjson-perl libconfig-tiny-perl libdbi-perl libfile-slurp-perl libstatistics-lite-perl\n

      5. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#chip","title":"C.H.I.P","text":"

      C.H.I.P. is a $9 R8 based tiny computer ideal for small projects. Further details: https://getchip.com/pages/chip

      1. Copy the shell script to the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/chip.sh -O /etc/snmp/power-stat.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/power-stat.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend power-stat /etc/snmp/power-stat.sh\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#docker-stats","title":"Docker Stats","text":"

      It gathers metrics about the docker containers, including: - cpu percentage - memory usage - container size - uptime - Totals per status

      This script requires python3 and the pip module python-dateutil

      "},{"location":"Extensions/Applications/#snmp-extend_8","title":"SNMP Extend","text":"
      1. Install pip module

        pip3 install python-dateutil\n

      2. Copy the shell script to the desired host. By default, it will only show the status for containers that are running. To include all containers modify the constant in the script at the top of the file and change it to ONLY_RUNNING_CONTAINERS = False

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/docker-stats.py -O /etc/snmp/docker-stats.py\n

      3. Make the script executable

        chmod +x /etc/snmp/docker-stats.py\n

      4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend docker /etc/snmp/docker-stats.py\n

      5. If your run Debian, you need to add the Debian-snmp user to the docker group

        usermod -a -G docker Debian-snmp\n

      6. Restart snmpd on your host

        systemctl restart snmpd\n

      "},{"location":"Extensions/Applications/#entropy","title":"Entropy","text":"

      A small shell script that checks your system's available random entropy.

      "},{"location":"Extensions/Applications/#snmp-extend_9","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/entropy.sh -O /etc/snmp/entropy.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/entropy.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend entropy /etc/snmp/entropy.sh\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#exim-stats","title":"EXIM Stats","text":"

      SNMP extend script to get your exim stats data into your host.

      "},{"location":"Extensions/Applications/#snmp-extend_10","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/exim-stats.sh -O /etc/snmp/exim-stats.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/exim-stats.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend exim-stats /etc/snmp/exim-stats.sh\n

      4. If you are using sudo edit your sudo users (usually visudo) and add at the bottom:

        snmp ALL=(ALL) NOPASSWD: /etc/snmp/exim-stats.sh, /usr/bin/exim*\n

      5. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#fail2ban","title":"Fail2ban","text":""},{"location":"Extensions/Applications/#snmp-extend_11","title":"SNMP Extend","text":"
      1. Copy the shell script, fail2ban, to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/fail2ban -O /etc/snmp/fail2ban\n

      2. Make the script executable

        chmod +x /etc/snmp/fail2ban\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend fail2ban /etc/snmp/fail2ban\n

        1. If you want to use the cache, it is as below, by using the -c switch.

          extend fail2ban /etc/snmp/fail2ban -c\n

        2. If you want to use the cache and update it if needed, this can by using the -c and -U switches.

          extend fail2ban /etc/snmp/fail2ban -c -U\n

        3. If you need to specify a custom location for the fail2ban-client, that can be done via the -f switch.

          extend fail2ban /etc/snmp/fail2ban -f /foo/bin/fail2ban-client\n
          If not specified, \"/usr/bin/env fail2ban-client\" is used.

      4. Restart snmpd on your host

      5. If you wish to use caching, add the following to /etc/crontab and restart cron.

        */3    *    *    *    *    root    /etc/snmp/fail2ban -u\n

      6. Restart or reload cron on your system.

      If you have more than a few jails configured, you may need to use caching as each jail needs to be polled and fail2ban-client can't do so in a timely manner for than a few. This can result in failure of other SNMP information being polled.

      For additional details of the switches, please see the POD in the script it self at the top.

      "},{"location":"Extensions/Applications/#freebsd-nfs-client","title":"FreeBSD NFS Client","text":"

      Superseded by the generalized NFS support.

      "},{"location":"Extensions/Applications/#snmp-extend_12","title":"SNMP Extend","text":"
      1. Copy the shell script, fbsdnfsserver, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/fbsdnfsclient -O /etc/snmp/fbsdnfsclient\n

      2. Make the script executable

        chmod +x /etc/snmp/fbsdnfsclient\n

      3. Edit your snmpd.conf file and add:

        extend fbsdnfsclient /etc/snmp/fbsdnfsclient\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#freebsd-nfs-server","title":"FreeBSD NFS Server","text":"

      Superseded by the generalized NFS support.

      "},{"location":"Extensions/Applications/#snmp-extend_13","title":"SNMP Extend","text":"
      1. Copy the shell script, fbsdnfsserver, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/fbsdnfsserver -O /etc/snmp/fbsdnfsserver\n

      2. Make the script executable

        chmod +x /etc/snmp/fbsdnfsserver\n

      3. Edit your snmpd.conf file and add:

        extend fbsdnfsserver /etc/snmp/fbsdnfsserver\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#freeradius","title":"FreeRADIUS","text":"

      The FreeRADIUS application extension requires that status_server be enabled in your FreeRADIUS config. For more information see: https://wiki.freeradius.org/config/Status

      You should note that status requests increment the FreeRADIUS request stats. So LibreNMS polls will ultimately be reflected in your stats/charts.

      1. Go to your FreeRADIUS configuration directory (usually /etc/raddb or /etc/freeradius).

      2. cd sites-enabled

      3. ln -s ../sites-available/status status

      4. Restart FreeRADIUS.

      5. You should be able to test with the radclient as follows...

        echo \"Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type = 31, Response-Packet-Type = Access-Accept\" | \\\nradclient -x localhost:18121 status adminsecret\n

      Note that adminsecret is the default secret key in status_server. Change if you've modified this.

      "},{"location":"Extensions/Applications/#snmp-extend_14","title":"SNMP Extend","text":"
      1. Copy the freeradius shell script, to the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/freeradius.sh -O /etc/snmp/freeradius.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/freeradius.sh\n

      3. If you've made any changes to the FreeRADIUS status_server config (secret key, port, etc.) edit freeradius.sh and adjust the config variable accordingly.

      4. Edit your snmpd.conf file and add:

        extend freeradius /etc/snmp/freeradius.sh\n

      5. Restart snmpd on the host in question.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_3","title":"Agent","text":"
      1. Install the script to your agent

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/freeradius.sh -O /usr/lib/check_mk_agent/local/freeradius.sh`\n

      2. Make the script executable

        chmod +x /usr/lib/check_mk_agent/local/freeradius.sh\n

      3. If you've made any changes to the FreeRADIUS status_server config (secret key, port, etc.) edit freeradius.sh and adjust the config variable accordingly.

      4. Edit the freeradius.sh script and set the variable 'AGENT' to '1' in the config.

      "},{"location":"Extensions/Applications/#freeswitch","title":"Freeswitch","text":"

      A small shell script that reports various Freeswitch call status.

      "},{"location":"Extensions/Applications/#agent_4","title":"Agent","text":"
      1. Install the agent on this device if it isn't already and copy the freeswitch script to /usr/lib/check_mk_agent/local/

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/freeswitch -O /usr/lib/check_mk_agent/local/freeswitch`\n

      2. Make the script executable

        chmod +x /usr/lib/check_mk_agent/local/freeswitch\n

      3. Configure FSCLI in the script. You may also have to create an /etc/fs_cli.conf file if your fs_cli command requires authentication.

      4. Verify it is working by running /usr/lib/check_mk_agent/local/freeswitch

      "},{"location":"Extensions/Applications/#snmp-extend_15","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/agent-local/freeswitch -O /etc/snmp/freeswitch\n

      2. Make the script executable

        chmod +x /etc/snmp/freeswitch\n

      3. Configure FSCLI in the script. You may also have to create an /etc/fs_cli.conf file if your fs_cli command requires authentication.

      4. Verify it is working by running /etc/snmp/freeswitch

      5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend freeswitch /etc/snmp/freeswitch\n

      6. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#gpsd","title":"GPSD","text":""},{"location":"Extensions/Applications/#snmp-extend_16","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/gpsd -O /etc/snmp/gpsd\n

      2. Make the script executable

        chmod +x /etc/snmp/gpsd\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend gpsd /etc/snmp/gpsd\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading at the top of the page.

      "},{"location":"Extensions/Applications/#agent_5","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the gpsd script to /usr/lib/check_mk_agent/local/

      You may need to configure $server or $port.

      Verify it is working by running /usr/lib/check_mk_agent/local/gpsd

      "},{"location":"Extensions/Applications/#hv-monitor","title":"HV Monitor","text":"

      HV Monitor provides a generic way to monitor hypervisors. Currently CBSD+bhyve on FreeBSD and Libvirt+QEMU on Linux are support.

      For more information see HV::Monitor on Github or MetaCPAN.

      "},{"location":"Extensions/Applications/#snmp-extend_17","title":"SNMP Extend","text":"
      1. Install the SNMP Extend.

      For Debian based systems this is as below.

      apt-get install zlib1g-dev cpanminus libjson-perl\ncpanm HV::Monitor\n

      And on FreeBSD as below.

      pkg install p5-App-cpanminus p5-JSON p5-MIME-Base64 p5-Gzip-Faster\ncpanm HV::Monitor\n
      1. Set it up to be be ran by cron by root. Yes, you can directly call this script from SNMPD, but be aware, especially with Libvirt, there is a very real possibility of the snmpget timing out, especially if a VM is spinning up/down as virsh domstats can block for a few seconds or so then.
      */5 * * * * /usr/local/bin/hv_monitor > /var/cache/hv_monitor.json -c 2> /dev/null\n
      1. Setup snmpd.conf as below.
      extend hv-monitor /bin/cat\n/var/cache/hv_monitor.json\n
      1. Restart SNMPD.

      2. Either wait for it to be re-discovered or manually enable it.

      "},{"location":"Extensions/Applications/#icecast","title":"Icecast","text":"

      Shell script that reports load average/memory/open-files stats of Icecast

      "},{"location":"Extensions/Applications/#snmp-extend_18","title":"SNMP Extend","text":"
      1. Copy the shell script, icecast-stats.sh, to the desired host (the host must be added to LibreNMS devices)

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/icecast-stats.sh -O /etc/snmp/icecast-stats.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/icecast-stats.sh\n

      3. Verify it is working by running /etc/snmp/icecast-stats.sh

      4. Edit your snmpd.conf file (usually /etc/snmp/icecast-stats.sh) and add:

        extend icecast /etc/snmp/icecast-stats.sh\n

      "},{"location":"Extensions/Applications/#isc-dhcp-stats","title":"ISC DHCP Stats","text":"

      A small python3 script that reports current DHCP leases stats and pool usage of ISC DHCP Server.

      Also you have to install the dhcpd-pools and the required Perl modules. Under Ubuntu/Debian just run apt install cpanminus ; cpanm Net::ISC::DHCPd::Leases Mime::Base64 File::Slurp or under FreeBSD pkg install p5-JSON p5-MIME-Base64 p5-App-cpanminus p5-File-Slurp ; cpanm Net::ISC::DHCPd::Leases.

      "},{"location":"Extensions/Applications/#snmp-extend_19","title":"SNMP Extend","text":"
      1. Copy the shell script to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/dhcp -O /etc/snmp/dhcp\n

      2. Make the script executable

        chmod +x /etc/snmp/dhcp\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        # without using cron\nextend dhcpstats /etc/snmp/dhcp -Z\n# using cron\nextend dhcpstats /bin/cat /var/cache/dhcp_extend\n

      4. If on a slow system running it via cron may be needed.

        */5 * * * * /etc/snmp/dhcp -Z -w /var/cache/dhcp_extend\n

      The following options are also supported.

      Option Description -c $file Path to dhcpd.conf. -l $file Path to lease file. -Z Enable GZip+Base64 compression. -d Do not de-dup. -w $file File to write it out to.
      1. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#logsize","title":"Logsize","text":""},{"location":"Extensions/Applications/#snmp-extend_20","title":"SNMP Extend","text":"
      1. Download the script and make it executable.
      wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/logsize -O /etc/snmp/logsize\nchmod +x /etc/snmp/logsize\n
      1. Install the requirements.
      # FreeBSD\npkg install p5-File-Find-Rule p5-JSON p5-TOML p5-Time-Piece p5-MIME-Base64 p5-File-Slurp p5-Statistics-Lite\n# Debian\napt-get install cpanminus\ncpanm File::Find::Rule JSON TOML Time::Piece MIME::Base64 File::Slurp Statistics::Lite\n
      1. Configure the config at /usr/local/etc/logsize.conf. You can find the documentation for the config file in the extend. Below is a small example.
      # monitor log sizes of logs directly udner /var/log\n[sets.var_log]\ndir=\"/var/log/\"\n\n# monitor remote logs from network devices\n[sets.remote_network]\ndir=\"/var/log/remote/network/\"\n\n# monitor remote logs from windows sources\n[sets.remote_windows]\ndir=\"/var/log/remote/windows/\"\n\n# monitor suricata flows logs sizes\n[sets.suricata_flows]\ndir=\"/var/log/suricata/flows/current\"\n
      1. If the directories all readable via SNMPD, this script can be ran via snmpd. Otherwise it needs setup in cron. Similarly is processing a large number of files, it may also need setup in cron if it takes the script awhile to run.
      */5 * * * * /etc/snmp/logsize -b 2> /dev/null > /dev/null\n
      1. Make sure that /var/cache/logsize_extend exists and is writable by the user running the extend.
      mkdir -p /var/cache/logsize_extend\n
      1. Configure it in the SNMPD config.
      # if not using cron\nextend logsize  /etc/snmp/logsize -b\n# if using cron\nextend logsize /bin/cat /var/cache/logsize_extend/extend_return\n
      "},{"location":"Extensions/Applications/#linux_config_files","title":"linux_config_files","text":"

      linux_config_files is an application intended to monitor a Linux distribution's configuration files via that distribution's configuration management tool/system. At this time, ONLY RPM-based (Fedora/RHEL) SYSTEMS ARE SUPPORTED utilizing the rpmconf tool. The linux_config_files application collects and graphs the total count of configuration files that are out of sync and graphs that number.

      Fedora/RHEL: Rpmconf is a utility that analyzes rpm configuration files using the RPM Package Manager. Rpmconf reports when a new configuration file standard has been issued for an upgraded/downgraded piece of software. Typically, rpmconf is used to provide a diff of the current configuration file versus the new, standard configuration file. The administrator can then choose to install the new configuration file or keep the old one.

      "},{"location":"Extensions/Applications/#snmp-extend_21","title":"SNMP Extend","text":"
      1. Copy the python script, linux_config_files.py, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/linux_config_files.py -O /etc/snmp/linux_config_files.py\n

      2. Make the script executable

        chmod +x /etc/snmp/linux_config_files.py\n

      3. Edit your snmpd.conf file and add:

        extend linux_config_files /etc/snmp/linux_config_files.py\n

      4. (Optional on an RPM-based distribution) Create a /etc/snmp/linux_config_files.json file and specify the following:

        1. \"pkg_system\" - String designating the distribution name of the system. At the moment only \"rpm\" is supported [\"rpm\"]
        2. \"pkg_tool_cmd\" - String path to the package tool binary [\"/sbin/rpmconf\"]
          {\n    \"pkg_system\": \"rpm\",\n    \"pkg_tool_cmd\": \"/bin/rpmconf\",\n}\n
      5. Restart snmpd.

      "},{"location":"Extensions/Applications/#linux-softnet-stat","title":"Linux Softnet Stat","text":""},{"location":"Extensions/Applications/#snmp-extend_22","title":"SNMP Extend","text":"

      1: Install the depends, which on a Debian based system would be as below.

      apt-get install -y cpanminus zlib1g-dev\ncpanm File::Slurp MIME::Base64 JSON Gzip::Faster\n

      1. Download the script into the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/linux_softnet_stat -O /etc/snmp/linux_softnet_stat\n

      2. Make the script executable

        chmod +x /etc/snmp/linux_softnet_stat\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend linux_softnet_stat /etc/snmp/linux_softnet_stat -b\n

      Then either enable the application Linux Softnet Stat or wait for it to be re-discovered.

      "},{"location":"Extensions/Applications/#mailcow-dockerized-postfix","title":"mailcow-dockerized postfix","text":""},{"location":"Extensions/Applications/#snmp-extend_23","title":"SNMP Extend","text":"
      1. Download the script into the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mailcow-dockerized-postfix -O /etc/snmp/mailcow-dockerized-postfix\n

      2. Make the script executable

        chmod +x /etc/snmp/mailcow-dockerized-postfix\n

        Maybe you will need to install pflogsumm on debian based OS. Please check if you have package installed.

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend mailcow-postfix /etc/snmp/mailcow-dockerized-postfix\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#mailscanner","title":"Mailscanner","text":""},{"location":"Extensions/Applications/#snmp-extend_24","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mailscanner.php -O /etc/snmp/mailscanner.php\n

      2. Make the script executable

        chmod +x /etc/snmp/mailscanner.php\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend mailscanner /etc/snmp/mailscanner.php\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#mdadm","title":"Mdadm","text":"

      It allows you to checks mdadm health and array data

      This script require: jq

      "},{"location":"Extensions/Applications/#snmp-extend_25","title":"SNMP Extend","text":"
      1. Install jq

        sudo apt install jq\n

      2. Download the script onto the desired host.

        sudo wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/mdadm -O /etc/snmp/mdadm\n

      3. Make the script executable

        sudo chmod +x /etc/snmp/mdadm\n

      4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend mdadm /etc/snmp/mdadm\n

      5. Verify it is working by running

        sudo /etc/snmp/mdadm\n

      6. Restart snmpd on your host

        sudo service snmpd restart\n

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#megaraid","title":"MegaRAID","text":"

      This software from Broadcom/LSI let you monitor MegaRAID controller.

      1. Download the external software and follow the included install instructions.

      2. Add the following line to your snmpd.conf file (usually /etc/snmp/snmpd.conf)

        pass .1.3.6.1.4.1.3582 /usr/sbin/lsi_mrdsnmpmain\n

      3. Restart snmpd on your host

      "},{"location":"Extensions/Applications/#memcached","title":"Memcached","text":""},{"location":"Extensions/Applications/#snmp-extend_26","title":"SNMP Extend","text":"
      1. Copy the memcached script to /etc/snmp/ on your remote server.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/memcached -O /etc/snmp/memcached\n

      2. Make the script executable:

        chmod +x /etc/snmp/memcached\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend memcached /etc/snmp/memcached\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#mojo-cape-submit","title":"Mojo CAPE Submit","text":""},{"location":"Extensions/Applications/#snmp","title":"SNMP","text":"

      This assumes you've already configured mojo_cape_submit from CAPE::Utils.

      1. Add the following to snmpd.conf and restarted SNMPD
        extend mojo_cape_submit /usr/local/bin/mojo_cape_submit_extend\n

      Then just wait for the machine in question to be rediscovered or enabled it in the device settings app page.

      "},{"location":"Extensions/Applications/#munin","title":"Munin","text":""},{"location":"Extensions/Applications/#agent_6","title":"Agent","text":"
      1. Install the script to your agent:

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/munin -O /usr/lib/check_mk_agent/local/munin\n

      2. Make the script executable

        chmod +x /usr/lib/check_mk_agent/local/munin\n

      3. Create the munin scripts dir:

        mkdir -p /usr/share/munin/munin-scripts\n

      4. Install your munin scripts into the above directory.

      To create your own custom munin scripts, please see this example:

      #!/bin/bash\nif [ \"$1\" = \"config\" ]; then\n    echo 'graph_title Some title'\n    echo 'graph_args --base 1000 -l 0' #not required\n    echo 'graph_vlabel Some label'\n    echo 'graph_scale no' #not required, can be yes/no\n    echo 'graph_category system' #Choose something meaningful, can be anything\n    echo 'graph_info This graph shows something awesome.' #Short desc\n    echo 'foobar.label Label for your unit' # Repeat these two lines as much as you like\n    echo 'foobar.info Desc for your unit.'\n    exit 0\nfi\necho -n \"foobar.value \" $(date +%s) #Populate a value, here unix-timestamp\n
      "},{"location":"Extensions/Applications/#mysql","title":"MySQL","text":"

      Create the cache directory, '/var/cache/librenms/' and make sure that it is owned by the user running the SNMP daemon.

      mkdir -p /var/cache/librenms/\n

      The MySQL script requires PHP-CLI and the PHP MySQL extension, so please verify those are installed.

      CentOS (May vary based on PHP version)

      yum install php-cli php-mysql\n

      Debian (May vary based on PHP version)

      apt-get install php-cli php-mysql\n

      Unlike most other scripts, the MySQL script requires a configuration file mysql.cnf in the same directory as the extend or agent script with following content:

      <?php\n$mysql_user = 'root';\n$mysql_pass = 'toor';\n$mysql_host = 'localhost';\n$mysql_port = 3306;\n

      Note that depending on your MySQL installation (chrooted install for example), you may have to specify 127.0.0.1 instead of localhost. Localhost make a MySQL connection via the mysql socket, while 127.0.0.1 make a standard IP connection to mysql.

      Note also if you get a mysql error Uncaught TypeError: mysqli_num_rows(): Argument #1, this is because you are using a newer mysql version which doesnt support UNBLOCKING for slave statuses, so you need to also include the line $chk_options['slave'] = false; into mysql.cnf to skip checking slave statuses

      "},{"location":"Extensions/Applications/#agent_7","title":"Agent","text":"

      Install the agent on this device if it isn't already

      and copy the mysql script to /usr/lib/check_mk_agent/local/

      Verify it is working by running /usr/lib/check_mk_agent/local/mysql

      "},{"location":"Extensions/Applications/#snmp-extend_27","title":"SNMP extend","text":"
      1. Copy the mysql script to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/mysql -O /etc/snmp/mysql\n

      2. Make the file executable

        chmod +x /etc/snmp/mysql\n

      3. Edit /etc/snmp/mysql to set your MySQL connection constants or declare them in /etc/snmp/mysql.cnf (new file)

      4. Edit your snmpd.conf file and add:

        extend mysql /etc/snmp/mysql\n

      5. Restart snmpd.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#nginx","title":"NGINX","text":"

      NGINX is a free, open-source, high-performance HTTP server: https://www.nginx.org/

      It's required to have the following directive in your nginx configuration responsible for the localhost server:

      location /nginx-status {\n    stub_status on;\n    access_log  off;\n    allow 127.0.0.1;\n    allow ::1;\n    deny  all;\n}\n

      "},{"location":"Extensions/Applications/#snmp-extend_28","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/nginx -O /etc/snmp/nginx\n

      2. Make the script executable

        chmod +x /etc/snmp/nginx\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend nginx /etc/snmp/nginx\n

      4. (Optional) If you have SELinux in Enforcing mode, you must add a module so the script can request /nginx-status:

        cat << EOF > snmpd_nginx.te\nmodule snmpd_nginx 1.0;\n\nrequire {\n        type httpd_t;\n        type http_port_t;\n        type snmpd_t;\n        class tcp_socket name_connect;\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t http_port_t:tcp_socket name_connect;\nEOF\ncheckmodule -M -m -o snmpd_nginx.mod snmpd_nginx.te\nsemodule_package -o snmpd_nginx.pp -m snmpd_nginx.mod\nsemodule -i snmpd_nginx.pp\n

      5. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_8","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the nginx script to /usr/lib/check_mk_agent/local/

      "},{"location":"Extensions/Applications/#nfs","title":"NFS","text":"

      Provides both NFS client and server support.

      Currently supported OSes are as below.

      • FreeBSD
      • Linux
      "},{"location":"Extensions/Applications/#snmpd-extend","title":"SNMPd extend","text":"
      1. Download the extend.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/nfs -O /etc/snmp/nfs\n

      2. Make it executable.

        chmod +x /etc/snmp/nfs\n

      3. Add it to snmpd.conf.

        extend nfs /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /etc/snmp/nfs\n

      4. Restart snmpd on your host

      5. Either wait for it to be rediscovered, rediscover it, or enable it.

      If using SELinux, the following is needed.

      1. setsebool -P nis_enabled 1

      2. Make a file (snmp_nfs.te) with the following contents and install the policy with the command semodule -i snmp_nfs.te.

        module snmp_nfs 1.0;\n\nrequire {\n        type mountd_port_t;\n        type snmpd_t;\n        type hi_reserved_port_t;\n        class tcp_socket { name_bind name_connect };\n        class udp_socket name_bind;\n}\n\n#============= snmpd_t ==============\nallow snmpd_t hi_reserved_port_t:tcp_socket name_bind;\nallow snmpd_t hi_reserved_port_t:udp_socket name_bind;\nallow snmpd_t mountd_port_t:tcp_socket name_connect;\n

      "},{"location":"Extensions/Applications/#linux-nfs-server","title":"Linux NFS Server","text":"

      Superseded by the generalized NFS support.

      Export the NFS stats from as server.

      "},{"location":"Extensions/Applications/#snmp-extend_29","title":"SNMP Extend","text":"
      1. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add :

        extend nfs-server /bin/cat /proc/net/rpc/nfsd\n

        find out where cat is located using : which cat

      2. reload snmpd service to activate the configuration

      "},{"location":"Extensions/Applications/#ntp-client","title":"NTP Client","text":"

      A shell script that gets stats from ntp client.

      "},{"location":"Extensions/Applications/#snmp-extend_30","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/ntp-client -O /etc/snmp/ntp-client\n

      2. Make the script executable

        chmod +x /etc/snmp/ntp-client\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend ntp-client /etc/snmp/ntp-client\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#ntp-server-aka-ntpd","title":"NTP Server aka NTPD","text":"

      A shell script that gets stats from ntp server (ntpd).

      "},{"location":"Extensions/Applications/#snmp-extend_31","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/ntp-server.sh -O /etc/snmp/ntp-server.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/ntp-server.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend ntp-server /etc/snmp/ntp-server.sh\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#chronyd","title":"Chronyd","text":"

      A shell script that gets the stats from chronyd and exports them with SNMP Extend.

      "},{"location":"Extensions/Applications/#snmp-extend_32","title":"SNMP Extend","text":"
      1. Download the shell script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/chrony -O /etc/snmp/chrony\n

      2. Make the script executable

        chmod +x /etc/snmp/chrony\n

      3. Edit the snmpd.conf file to include the extend by adding the following line to the end of the config file:

        extend chronyd /etc/snmp/chrony\n

      Note: Some distributions need sudo-permissions for the script to work with SNMP Extend. See the instructions on the section SUDO for more information.

      1. Restart snmpd service on the host

      Application should be auto-discovered and its stats presented on the Apps-page on the host. Note: Applications module needs to be enabled on the host or globally for the statistics to work as intended.

      "},{"location":"Extensions/Applications/#nvidia-gpu","title":"Nvidia GPU","text":""},{"location":"Extensions/Applications/#snmp-extend_33","title":"SNMP Extend","text":"
      1. Copy the shell script, nvidia, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/nvidia -O /etc/snmp/nvidia\n

      2. Make the script executable

        chmod +x /etc/snmp/nvidia\n

      3. Edit your snmpd.conf file and add:

        extend nvidia /etc/snmp/nvidia\n

      4. Restart snmpd on your host.

      5. Verify you have nvidia-smi installed, which it generally should be if you have the driver from Nvida installed.

      The GPU numbering on the graphs will correspond to how the nvidia-smi sees them as being.

      For questions about what the various values are/mean, please see the nvidia-smi man file under the section covering dmon.

      "},{"location":"Extensions/Applications/#opensearchelasticsearch","title":"Opensearch\\Elasticsearch","text":""},{"location":"Extensions/Applications/#snmp-extend_34","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/opensearch -O /etc/snmp/opensearch\n

      2. Make it executable

        chmod +x /etc/snmp/opensearch\n

      3. Install the required Perl dependencies.

        # FreeBSD\npkg install p5-JSON p5-libwww\n# Debian/Ubuntu\napt-get install libjson-perl libwww-perl\n# cpanm\ncpanm JSON Libwww\n

      4. Update your snmpd.conf.

        extend opensearch /bin/cat /var/cache/opensearch.json\n

      5. Update root crontab with. This is required as it will this will likely time out otherwise. Use */1 if you want to have the most recent stats when polled or to */5 if you just want at exactly a 5 minute interval.

        */5 * * * * /etc/snmp/opensearch > /var/cache/opensearch.json\n

      6. Enable it or wait for the device to be re-disocvered.

      "},{"location":"Extensions/Applications/#open-grid-scheduler","title":"Open Grid Scheduler","text":"

      Shell script to track the OGS/GE jobs running on clusters.

      "},{"location":"Extensions/Applications/#snmp-extend_35","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/rocks.sh -O /etc/snmp/rocks.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/rocks.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend ogs /etc/snmp/rocks.sh\n

      4. Restart snmpd.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#opensips","title":"Opensips","text":"

      Script that reports load-average/memory/open-files stats of Opensips

      "},{"location":"Extensions/Applications/#snmp-extend_36","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/opensips-stats.sh -O /etc/snmp/opensips-stats.sh\n

      2. Make the script executable:

        chmod +x /etc/snmp/opensips-stats.sh\n

      3. Verify it is working by running /etc/snmp/opensips-stats.sh

      4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend opensips /etc/snmp/opensips-stats.sh\n

      "},{"location":"Extensions/Applications/#os-updates","title":"OS Updates","text":"

      A small shell script that checks your system package manager for any available updates. Supports apt-get/pacman/yum/zypper package managers.

      For pacman users automatically refreshing the database, it is recommended you use an alternative database location --dbpath=/var/lib/pacman/checkupdate

      "},{"location":"Extensions/Applications/#snmp-extend_37","title":"SNMP Extend","text":"
      1. Download the script onto the desired host.

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/osupdate -O /etc/snmp/osupdate\n

      2. Make the script executable

        chmod +x /etc/snmp/osupdate\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend osupdate /etc/snmp/osupdate\n

      4. Restart snmpd on your host

      Note: apt-get depends on an updated package index. There are several ways to have your system run apt-get update automatically. The easiest is to create /etc/apt/apt.conf.d/10periodic and pasting the following in it: APT::Periodic::Update-Package-Lists \"1\";. If you have apticron, cron-apt or apt-listchanges installed and configured, chances are that packages are already updated periodically .

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_9","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the osupdate script to /usr/lib/check_mk_agent/local/

      Then uncomment the line towards the top marked to be uncommented if using it as a agent.

      "},{"location":"Extensions/Applications/#php-fpm","title":"PHP-FPM","text":""},{"location":"Extensions/Applications/#snmp-extend_38","title":"SNMP Extend","text":"
      1. Copy the shell script, phpfpmsp, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/php-fpm -O /etc/snmp/php-fpm\n

      2. Make the script executable

        chmod +x /etc/snmp/php-fpm\n

      3. Install the depends.

        # FreeBSD\npkg install p5-File-Slurp p5-JSON p5-String-ShellQuote p5-MIME-Base64\n# Debian\napt-get install libfile-slurp-perl libjson-perl libstring-shellquote-perl libmime-base64-perl\n

      4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend phpfpmsp /etc/snmp/php-fpm\n

      5. Create the config file /usr/local/etc/php-fpm_extend.json. Alternate locations may be specified using the the -f switch. Akin to like below. For more information, see /etc/snmp/php-fpm --help.

        {\n\"pools\":{\n         \"thefrog\": \"https://thefrog/fpm-status\",\n         \"foobar\": \"https://foo.bar/fpm-status\"\n    }\n}\n

      6. Restart snmpd on the host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_10","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the phpfpmsp script to /usr/lib/check_mk_agent/local/

      "},{"location":"Extensions/Applications/#pi-hole","title":"Pi-hole","text":""},{"location":"Extensions/Applications/#snmp-extend_39","title":"SNMP Extend","text":"
      1. Copy the shell script, pi-hole, to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/pi-hole -O /etc/snmp/pi-hole\n

      2. Make the script executable

        chmod +x /etc/snmp/pi-hole\n

      3. Edit your snmpd.conf file and add:

        extend pi-hole /etc/snmp/pi-hole\n

      4. To get all data you must get your API auth token from Pi-hole server and change the API_AUTH_KEY entry inside the snmp script.

      5. Restard snmpd.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#portactivity","title":"Portactivity","text":""},{"location":"Extensions/Applications/#snmp-extend_40","title":"SNMP Extend","text":"
      1. Install missing packages - Ubuntu is shown below.

        apt install libparse-netstat-perl\napt install libjson-perl\n

      2. Copy the Perl script to the desired host (the host must be added to LibreNMS devices)

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/portactivity -O /etc/snmp/portactivity\n

      3. Make the script executable

        chmod +x /etc/snmp/portactivity\n

      4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend portactivity /etc/snmp/portactivity -p http,ldap,imap\n

        Will monitor HTTP, LDAP, and IMAP. The -p switch specifies what ports to use. This is a comma seperated list.

        These must be found in '/etc/services' or where ever NSS is set to fetch it from. If not, it will throw an error.

        If you want to JSON returned by it to be printed in a pretty format use the -P flag.

      5. Restart snmpd on your host.

      Please note that for only TCP[46] services are supported.

      "},{"location":"Extensions/Applications/#postfix","title":"Postfix","text":""},{"location":"Extensions/Applications/#snmp-extend_41","title":"SNMP Extend","text":"
      1. Copy the shell script, postfix-queues, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/postfix-queues -O /etc/snmp/postfix-queues\n

      2. Copy the Perl script, postfixdetailed, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/postfixdetailed -O /etc/snmp/postfixdetailed\n

      3. Make both scripts executable

        chmod +x /etc/snmp/postfixdetailed /etc/snmp/postfix-queues\n

      4. Edit your snmpd.conf file and add:

        extend mailq /etc/snmp/postfix-queues\nextend postfixdetailed /etc/snmp/postfixdetailed\n

      5. Restart snmpd.

      6. Install pflogsumm for your OS.

      7. Make sure the cache file in /etc/snmp/postfixdetailed is some place that snmpd can write too. This file is used for tracking changes between various values between each time it is called by snmpd. Also make sure the path for pflogsumm is correct.

      8. Run /etc/snmp/postfixdetailed to create the initial cache file so you don't end up with some crazy initial starting value. Please note that each time /etc/snmp/postfixdetailed is ran, the cache file is updated, so if this happens in between LibreNMS doing it then the values will be thrown off for that polling period.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      NOTE: If using RHEL for your postfix server, qshape must be installed manually as it is not officially supported. CentOs 6 rpms seem to work without issues.

      "},{"location":"Extensions/Applications/#postgres","title":"Postgres","text":""},{"location":"Extensions/Applications/#snmp-extend_42","title":"SNMP Extend","text":"
      1. Copy the shell script, postgres, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/postgres -O /etc/snmp/postgres\n

      2. Make the script executable

        chmod +x /etc/snmp/postgres\n

      3. Edit your snmpd.conf file and add:

        extend postgres /etc/snmp/postgres\n

      4. Restart snmpd on your host

      5. Install the Nagios check check_postgres.pl on your system: https://github.com/bucardo/check_postgres

      6. Verify the path to check_postgres.pl in /etc/snmp/postgres is correct.

      7. (Optional) If you wish to change the DB username (default: pgsql), enable the postgres DB in totalling (e.g. set ignorePG to 0, default: 1), or set a hostname for check_postgres.pl to connect to (default: the Unix Socket postgresql is running on), then create the file /etc/snmp/postgres.config with the following contents (note that not all of them need be defined, just whichever you'd like to change):

        DBuser=monitoring\nignorePG=0\nDBhost=localhost\n

      Note that if you are using netdata or the like, you may wish to set ignorePG to 1 or otherwise that total will be very skewed on systems with light or moderate usage.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#poudriere","title":"Poudriere","text":""},{"location":"Extensions/Applications/#snmp-extend_43","title":"SNMP Extend","text":"
      1. Copy the extend into place

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/poudriere -O /usr/local/etc/snmp/poudriere\n

      2. Make it executable.

        chmod +x /usr/local/etc/snmp/poudriere\n

      3. Install the depends

        pkg install p5-Data-Dumper p5-JSON p5-MIME-Base64 p5-File-Slurp\n

      4. Setup the cronjob. The extend needs to be ran as root. See poudriere --help for option info.

        4/5 * * * * root /usr/local/etc/snmp/poudriere -q -a -w -z\n

      5. Add the extend to snmpd.conf and restart snmpd

        extend poudriere cat /var/cache/poudriere.json.snmp\n

      "},{"location":"Extensions/Applications/#powerdns","title":"PowerDNS","text":"

      An authoritative DNS server: https://www.powerdns.com/auth.html

      "},{"location":"Extensions/Applications/#snmp-extend_44","title":"SNMP Extend","text":"
      1. Copy the shell script, powerdns.py, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns.py -O /etc/snmp/powerdns.py\n

      2. Make the script executable

        chmod +x /etc/snmp/powerdns.py\n

      3. Edit your snmpd.conf file and add:

        extend powerdns /etc/snmp/powerdns.py\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_11","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the powerdns script to /usr/lib/check_mk_agent/local/

      "},{"location":"Extensions/Applications/#powerdns-recursor","title":"PowerDNS Recursor","text":"

      A recursive DNS server: https://www.powerdns.com/recursor.html

      "},{"location":"Extensions/Applications/#direct","title":"Direct","text":"

      The LibreNMS polling host must be able to connect to port 8082 on the monitored device. The web-server must be enabled, see the Recursor docs: https://doc.powerdns.com/md/recursor/settings/#webserver

      "},{"location":"Extensions/Applications/#variables","title":"Variables","text":"

      $config['apps']['powerdns-recursor']['api-key'] required, this is defined in the Recursor config

      $config['apps']['powerdns-recursor']['port'] numeric, defines the port to connect to PowerDNS Recursor on. The default is 8082

      $config['apps']['powerdns-recursor']['https'] true or false, defaults to use http.

      "},{"location":"Extensions/Applications/#snmp-extend_45","title":"SNMP Extend","text":"
      1. Copy the shell script, powerdns-recursor, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns-recursor -O /etc/snmp/powerdns-recursor\n

      2. Make the script executable

        chmod +x /etc/snmp/powerdns-recursor\n

      3. Edit your snmpd.conf file and add:

        extend powerdns-recursor /etc/snmp/powerdns-recursor\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#agent_12","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the powerdns-recursor script to /usr/lib/check_mk_agent/local/

      This script uses rec_control get-all to collect stats.

      "},{"location":"Extensions/Applications/#powerdns-dnsdist","title":"PowerDNS-dnsdist","text":""},{"location":"Extensions/Applications/#snmp-extend_46","title":"SNMP Extend","text":"
      1. Copy the BASH script to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns-dnsdist -O /etc/snmp/powerdns-dnsdist\n

      2. Make the script executable

        chmod +x /etc/snmp/powerdns-dnsdist\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend powerdns-dnsdist /etc/snmp/powerdns-dnsdist\n

      4. Restart snmpd on your host.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#powermon","title":"PowerMon","text":"

      PowerMon tracks the power usage on your host and can report on both consumption and cost, using a python script installed on the host.

      PowerMon consumption graph

      Currently the script uses one of two methods to determine current power usage:

      • ACPI via libsensors

      • HP-Health (HP Proliant servers only)

      The ACPI method is quite unreliable as it is usually only implemented by battery-powered devices, e.g. laptops. YMMV. However, it's possible to support any method as long as it can return a power value, usually in Watts.

      TIP: You can achieve this by adding a method and a function for that method to the script. It should be called by getData() and return a dictionary.

      Because the methods are unreliable for all hardware, you need to declare to the script which method to use. The are several options to assist with testing, see --help.

      "},{"location":"Extensions/Applications/#snmp-extend_47","title":"SNMP Extend","text":""},{"location":"Extensions/Applications/#initial-setup","title":"Initial setup","text":"
      1. Download the python script onto the host:

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/powermon-snmp.py -O /usr/local/bin/powermon-snmp.py\n

      2. Make the script executable:

        chmod +x /usr/local/bin/powermon-snmp.py\n

      3. Edit the script and set the cost per kWh for your supply. You must uncomment this line for the script to work:

        vi /usr/local/bin/powermon-snmp.py\n#costPerkWh = 0.15\n

      4. Choose you method below:

        Method 1. sensorsMethod 2. hpasmcli
        • Install dependencies:

          dnf install lm_sensors\npip install PySensors\n

        • Test the script from the command-line. For example:

          $ /usr/local/bin/powermon-snmp.py -m sensors -n -p\n{\n  \"meter\": {\n    \"0\": {\n      \"reading\": 0.0\n    }\n  },\n  \"psu\": {},\n  \"supply\": {\n    \"rate\": 0.15\n  },\n  \"reading\": \"0.0\"\n}\n

        If you see a reading of 0.0 it is likely this method is not supported for your system. If not, continue.

        • Obtain the hp-health package for your system. Generally there are three options:

          • Standalone package from HPE Support
          • From the HP Management Component Pack (MCP).
          • Included in the HP Service Pack for Proliant (SPP)
        • If you've downloaded the standalone package, install it. For example:

          rpm -ivh hp-health-10.91-1878.11.rhel8.x86_64.rpm\n

        • Check the service is running:

          systemctl status hp-health\n

        • Test the script from the command-line. For example:

          $ /usr/local/bin/powermon-snmp.py -m hpasmcli -n -p\n{\n  \"meter\": {\n    \"1\": {\n      \"reading\": 338.0\n    }\n  },\n  \"psu\": {\n    \"1\": {\n      \"present\": \"Yes\",\n      \"redundant\": \"No\",\n      \"condition\": \"Ok\",\n      \"hotplug\": \"Supported\",\n      \"reading\": 315.0\n    },\n    \"2\": {\n      \"present\": \"Yes\",\n      \"redundant\": \"No\",\n      \"condition\": \"FAILED\",\n      \"hotplug\": \"Supported\"\n    }\n  },\n  \"supply\": {\n    \"rate\": 0.224931\n  },\n  \"reading\": 338.0\n}\n

        If you see a reading of 0.0 it is likely this method is not supported for your system. If not, continue.

      5. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add the following:

        extend  powermon   /usr/local/bin/powermon-snmp.py -m hpasmcli\n

        NOTE: Avoid using other script options in the snmpd config as the results may not be interpreted correctly by LibreNMS.

      6. Reload your snmpd service:

        systemctl reload snmpd\n

      7. You're now ready to enable the application in LibreNMS.

      "},{"location":"Extensions/Applications/#finishing-up","title":"Finishing Up","text":""},{"location":"Extensions/Applications/#privoxy","title":"Privoxy","text":"

      For this to work, the following log items need enabled for Privoxy.

      debug     2 # show each connection status\ndebug   512 # Common Log Format\ndebug  1024 # Log the destination for requests Privoxy didn't let through, and the reason why.\ndebug  4096 # Startup banner and warnings\ndebug  8192 # Non-fatal errors\n
      "},{"location":"Extensions/Applications/#snmp-extend_48","title":"SNMP Extend","text":"
      1. Download the extend and make sure it is executable.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/privoxy -O /etc/snmp/privoxy\nchmod +x /etc/snmp/privoxy\n

      2. Install the depdenencies.

        # FreeBSD\npkg install p5-File-ReadBackwards p5-Time-Piece p5-JSON p5-IPC-Run3 p5-Gzip-Faster p5-MIME-Base64\n# Debian\napt-get install cpanminus zlib1g\ncpanm File::ReadBackwards Time::Piece JSON IPC::Run3 MIME::Base64 Gzip::Faster\n

      3. Add the extend to snmpd.conf and restart snmpd.

        extend privoxy /etc/snmp/privoxy\n

      If your logfile is not at /var/log/privoxy/logfile, that may be changed via the -f option.

      If privoxy-log-parser.pl is not found in your standard $PATH setting, you may will need up call the extend via /usr/bin/env with a $PATH set to something that includes it.

      Once that is done, just wait for the server to be rediscovered or just enable it manually.

      "},{"location":"Extensions/Applications/#pwrstatd","title":"Pwrstatd","text":"

      Pwrstatd (commonly known as powerpanel) is an application/service available from CyberPower to monitor their PSUs over USB. It is currently capable of reading the status of only one PSU connected via USB at a time. The powerpanel software is available here: https://www.cyberpowersystems.com/products/software/power-panel-personal/

      "},{"location":"Extensions/Applications/#snmp-extend_49","title":"SNMP Extend","text":"
      1. Copy the python script, pwrstatd.py, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/pwrstatd.py -O /etc/snmp/pwrstatd.py\n

      2. Make the script executable

        chmod +x /etc/snmp/pwrstatd.py\n

      3. Edit your snmpd.conf file and add:

        extend pwrstatd /etc/snmp/pwrstatd.py\n

      4. (Optional) Create a /etc/snmp/pwrstatd.json file and specify the path to the pwrstat executable [the default path is /sbin/pwrstat]:

        {\n    \"pwrstat_cmd\": \"/sbin/pwrstat\"\n}\n

      5. Restart snmpd.

      "},{"location":"Extensions/Applications/#proxmox","title":"Proxmox","text":"
      1. For Proxmox 4.4+ install the libpve-apiclient-perl package

        apt install libpve-apiclient-perl\n

      2. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/proxmox -O /usr/local/bin/proxmox\n

      3. Make the script executable

        chmod +x /usr/local/bin/proxmox\n

      4. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend proxmox /usr/local/bin/proxmox\n

      5. Note: if your snmpd doesn't run as root, you might have to invoke the script using sudo and modify the \"extend\" line

      extend proxmox /usr/bin/sudo /usr/local/bin/proxmox\n

      after, edit your sudo users (usually visudo) and add at the bottom:

      Debian-snmp ALL=(ALL) NOPASSWD: /usr/local/bin/proxmox\n
      1. Restart snmpd on your host
      "},{"location":"Extensions/Applications/#puppet-agent","title":"Puppet Agent","text":"

      SNMP extend script to get your Puppet Agent data into your host.

      "},{"location":"Extensions/Applications/#snmp-extend_50","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/puppet_agent.py -O /etc/snmp/puppet_agent.py\n

      2. Make the script executable

        chmod +x /etc/snmp/puppet_agent.py\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend puppet-agent /etc/snmp/puppet_agent.py\n

      The Script needs python3-yaml package to be installed.

      Per default script searches for on of this files:

      • /var/cache/puppet/state/last_run_summary.yaml
      • /opt/puppetlabs/puppet/cache/state/last_run_summary.yaml

      optionally you can add a specific summary file with creating /etc/snmp/puppet.json

      {\n     \"agent\": {\n        \"summary_file\": \"/my/custom/path/to/summary_file\"\n     }\n}\n
      custom summary file has highest priority

      1. Restart snmpd on the host
      "},{"location":"Extensions/Applications/#pureftpd","title":"PureFTPd","text":"

      SNMP extend script to monitor PureFTPd.

      "},{"location":"Extensions/Applications/#snmp-extend_51","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/pureftpd.py -O /etc/snmp/pureftpd.py\n

      2. Make the script executable

        chmod +x /etc/snmp/pureftpd.py\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend pureftpd sudo /etc/snmp/pureftpd.py\n

      4. Edit your sudo users (usually visudo) and add at the bottom:

        snmp ALL=(ALL) NOPASSWD: /etc/snmp/pureftpd.py\n
        or the path where your pure-ftpwho is located

      5. If pure-ftpwho is not located in /usr/sbin

      you will also need to create a config file, which is named

      pureftpd.json. The file has to be located in /etc/snmp/.

      {\"pureftpwho_cmd\": \"/usr/sbin/pure-ftpwho\"\n}\n
      1. Restart snmpd on your host
      "},{"location":"Extensions/Applications/#raspberry-pi","title":"Raspberry PI","text":"

      SNMP extend script to get your PI data into your host.

      "},{"location":"Extensions/Applications/#snmp-extend_52","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/raspberry.sh -O /etc/snmp/raspberry.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/raspberry.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend raspberry /usr/bin/sudo /bin/sh /etc/snmp/raspberry.sh\n

      4. Edit your sudo users (usually visudo) and add at the bottom:

        snmp ALL=(ALL) NOPASSWD: /bin/sh /etc/snmp/raspberry.sh\n

      Note: If you are using Raspian, the default user is Debian-snmp. Change snmp above to Debian-snmp. You can verify the user snmpd is using with ps aux | grep snmpd

      1. Restart snmpd on PI host
      "},{"location":"Extensions/Applications/#raspberry-pi-gpio-monitor","title":"Raspberry Pi GPIO Monitor","text":"

      SNMP extend script to monitor your IO pins or sensor modules connected to your GPIO header.

      "},{"location":"Extensions/Applications/#snmp-extend_53","title":"SNMP Extend","text":"

      1: Make sure you have wiringpi installed on your Raspberry Pi. In Debian-based systems for example you can achieve this by issuing:

      apt-get install wiringpi\n

      2: Download the script to your Raspberry Pi. wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/rpigpiomonitor.php -O /etc/snmp/rpigpiomonitor.php

      3: (optional) Download the example configuration to your Raspberry Pi. wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/rpigpiomonitor.ini -O /etc/snmp/rpigpiomonitor.ini

      4: Make the script executable: chmod +x /etc/snmp/rpigpiomonitor.php

      5: Create or edit your rpigpiomonitor.ini file according to your needs.

      6: Check your configuration with rpigpiomonitor.php -validate

      7: Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

      extend rpigpiomonitor /etc/snmp/rpigpiomonitor.php\n

      8: Restart snmpd on your Raspberry Pi and, if your Raspberry Pi is already present in LibreNMS, perform a manual rediscover.

      "},{"location":"Extensions/Applications/#redis","title":"Redis","text":"

      Script to monitor your Redis Server

      "},{"location":"Extensions/Applications/#snmp-extend_54","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/redis.py -O /etc/snmp/redis.py\n

      2. Make the script executable

        chmod +x /etc/snmp/redis.py\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend redis /etc/snmp/redis.py\n

      4. (Optional) If you have SELinux in Enforcing mode, you must add a module so the script can get redis informations and write them:

        cat << EOF > snmpd_redis.te\nmodule snmpd_redis 1.0;\n\nrequire {\n        type tmp_t;\n        type redis_port_t;\n        type snmpd_t;\n        class tcp_socket name_connect;\n        class dir { add_name write };\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t redis_port_t:tcp_socket name_connect;\nallow snmpd_t tmp_t:dir { write add_name };\nEOF\ncheckmodule -M -m -o snmpd_redis.mod snmpd_redis.te\nsemodule_package -o snmpd_redis.pp -m snmpd_redis.mod\nsemodule -i snmpd_redis.pp\n

      "},{"location":"Extensions/Applications/#agent_13","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the redis script to /usr/lib/check_mk_agent/local/

      "},{"location":"Extensions/Applications/#rrdcached","title":"RRDCached","text":"

      Install/Setup: For Install/Setup Local Librenms RRDCached: Please see RRDCached

      Will collect stats by: 1. Connecting directly to the associated device on port 42217 2. Monitor thru snmp with SNMP extend, as outlined below 3. Connecting to the rrdcached server specified by the rrdcached setting

      SNMP extend script to monitor your (remote) RRDCached via snmp

      "},{"location":"Extensions/Applications/#snmp-extend_55","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/agent-local/rrdcached -O /etc/snmp/rrdcached\n

      2. Make the script executable

        chmod +x /etc/snmp/rrdcached\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend rrdcached /etc/snmp/rrdcached\n

      "},{"location":"Extensions/Applications/#sdfs-info","title":"SDFS info","text":"

      A small shell script that exportfs SDFS volume info.

      "},{"location":"Extensions/Applications/#snmp-extend_56","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/sdfsinfo -O /etc/snmp/sdfsinfo\n

      2. Make the script executable

        chmod +x /etc/snmp/sdfsinfo\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend sdfsinfo /etc/snmp/sdfsinfo\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#seafile","title":"Seafile","text":"

      SNMP extend script to monitor your Seafile Server

      "},{"location":"Extensions/Applications/#snmp-extend_57","title":"SNMP Extend","text":"
      1. Copy the Python script, seafile.py, to the desired host
        wget https://github.com/librenms/librenms-agent/raw/master/snmp/seafile.py -O /etc/snmp/seafile.py\n

      Also you have to install the requests Package for Python3. Under Ubuntu/Debian just run apt install python3-requests

      1. Make the script executable

        chmod +x /etc/snmp/seafile.py\n

      2. Edit your snmpd.conf file and add:

        extend seafile /etc/snmp/seafile.py\n

      3. You will also need to create the config file, which is named seafile.json . The script has to be located at /etc/snmp/.

        {\"url\": \"https://seafile.mydomain.org\",\n \"username\": \"some_admin_login@mail.address\",\n \"password\": \"password\",\n \"account_identifier\": \"name\"\n \"hide_monitoring_account\": true\n}\n

      The variables are as below.

      url = Url how to get access to Seafile Server\nusername = Login to Seafile Server.\n           It is important that used Login has admin privileges.\n           Otherwise most API calls will be denied.\npassword = Password to the configured login.\naccount_identifier = Defines how user accounts are listed in RRD Graph.\n                     Options are: name, email\nhide_monitoring_account = With this Boolean you can hide the Account which you\n                          use to access Seafile API\n

      Note:It is recommended to use a dedicated Administrator account for monitoring.

      "},{"location":"Extensions/Applications/#smart","title":"SMART","text":""},{"location":"Extensions/Applications/#snmp-extend_58","title":"SNMP Extend","text":"
      1. Copy the Perl script, smart, to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/smart-v1 -O /etc/snmp/smart\n

      2. Install the depends.

        # FreeBSD\npkg install p5-JSON p5-MIME-Base64 smartmontools\n# Debian\napt-get install cpanminus smartmontools\ncpanm MIME::Base64 JSON\n# CentOS\ndnf install smartmontools perl-JSON perl-MIME-Base64\n

      3. Make the script executable

        chmod +x /etc/snmp/smart\n

      4. Setup a cronjob to run it. This ensures slow to poll disks won't result in errors.

       */5 * * * * /etc/snmp/smart -u -Z\n
      1. Edit your snmpd.conf file and add:

        extend smart /bin/cat /var/cache/smart\n

      2. You will also need to create the config file, which defaults to the same path as the script, but with .config appended. So if the script is located at /etc/snmp/smart, the config file will be /etc/snmp/smart.config. Alternatively you can also specific a config via -c.

      Anything starting with a # is comment. The format for variables is $variable=$value. Empty lines are ignored. Spaces and tabes at either the start or end of a line are ignored. Any line with out a matched variable or # are treated as a disk.

      #This is a comment\ncache=/var/cache/smart\nsmartctl=/usr/bin/env smartctl\nuseSN=1\nada0\nada1\nda5 /dev/da5 -d sat\ntwl0,0 /dev/twl0 -d 3ware,0\ntwl0,1 /dev/twl0 -d 3ware,1\ntwl0,2 /dev/twl0 -d 3ware,2\n

      The variables are as below.

      cache = The path to the cache file to use. Default: /var/cache/smart\nsmartctl = The path to use for smartctl. Default: /usr/bin/env smartctl\nuseSN = If set to 1, it will use the disks SN for reporting instead of the device name.\n        1 is the default. 0 will use the device name.\n

      A disk line is can be as simple as just a disk name under /dev/. Such as in the config above The line \"ada0\" would resolve to \"/dev/ada0\" and would be called with no special argument. If a line has a space in it, everything before the space is treated as the disk name and is what used for reporting and everything after that is used as the argument to be passed to smartctl.

      If you want to guess at the configuration, call it with -g and it will print out what it thinks it should be.

      1. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      1. Optionally setup nightly self tests for the disks. The exend will run the specified test on all configured disks if called with the -t flag and the name of the SMART test to run.
       0 0 * * * /etc/snmp/smart -t long\n
      "},{"location":"Extensions/Applications/#sneck","title":"Sneck","text":"

      This is for replacing Nagios/Icinga or the LibreNMS service integration in regards to NRPE. This allows LibreNMS to query what checks were ran on the server and keep track of totals of OK, WARNING, CRITICAL, and UNKNOWN statuses.

      The big advantage over this compared to a NRPE are as below.

      • It does not need to know what checks are configured on it.
      • Also does not need to wait for the tests to run as sneck is meant to be ran via cron and the then return the cache when queried via SNMP, meaning a lot faster response time, especially if slow checks are being performed.
      • Works over proxied SNMP connections.

      Included are alert examples. Although for setting up custom ones, the metrics below are provided.

      Metric Description ok Total OK checks warning Total WARNING checks critical Total CRITICAL checks unknown Total UNKNOWN checks errored Total checks that errored time_to_polling Differnce in seconds between when polling data was generated and when polled time_to_polling_abs The absolute value of time_to_polling. check_$CHECK Exit status of a specific check $CHECK is equal to the name of the check in question. So foo would be check_foo

      The standard Nagios/Icinga style exit codes are used and those are as below.

      Exit Meaning 0 okay 1 warning 2 critical 3+ unknown

      To use time_to_polling, it will need to enabled via setting the config item below. The default is false. Unless set to true, this value will default to 0. If enabling this, one will want to make sure that NTP is in use every were or it will alert if it goes over a difference of 540s.

      lnms config:set app.sneck.polling_time_diff true\n

      For more information on Sneck, check it out at MetaCPAN or Github.

      For poking systems using Sneck, also check out boop_snoot if one wants to query those systems via the CLI. Docs on it at MetaCPAN and Github.

      "},{"location":"Extensions/Applications/#snmp-extend_59","title":"SNMP Extend","text":"
      1. Install the extend.
      # FreeBSD\npkg install p5-JSON p5-File-Slurp p5-MIME-Base64 p5-Gzip-Faster p5-App-cpanminus\ncpanm Monitoring::Sneck\n# Debian based systems\napt-get install zlib1g-dev cpanminus\ncpanm Monitoring::Sneck\n
      1. Configure any of the checks you want to run in /usr/local/etc/sneck.conf. You con find it documented here.

      2. Set it up in cron. This will mean you don't need to wait for all the checks to complete when polled via SNMP, which for like SMART or other long running checks will mean it timing out. Also means it does not need called via sudo as well.

      */5 * * * * /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /usr/local/bin/sneck -u 2> /dev/null > /dev/null\n
      1. Set it up in the snmpd config and restart snmpd. The -c flag will tell read it to read from cache instead of rerunning the checks.
      extend sneck /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /usr/local/bin/sneck -c\n
      1. In LibreNMS, enable the application for the server in question or wait for auto discovery to find it.
      "},{"location":"Extensions/Applications/#squid","title":"Squid","text":""},{"location":"Extensions/Applications/#snmp-proxy","title":"SNMP Proxy","text":"
      1. Enable SNMP for Squid like below, if you have not already, and restart it.

        acl snmppublic snmp_community public\nsnmp_port 3401\nsnmp_access allow snmppublic localhost\nsnmp_access deny all\n

      2. Restart squid on your host.

      3. Edit your snmpd.conf file and add, making sure you have the same community, host, and port as above:

        proxy -v 2c -Cc -c public 127.0.0.1:3401 1.3.6.1.4.1.3495\n

      For more advanced information on Squid and SNMP or setting up proxying for net-snmp, please see the links below.

      http://wiki.squid-cache.org/Features/Snmp http://www.net-snmp.org/wiki/index.php/Snmpd_proxy

      "},{"location":"Extensions/Applications/#supervisord","title":"Supervisord","text":"

      It shows you the totals per status and also the uptime per process. That way you can add alerts for instance when there are process in state FATAL.

      "},{"location":"Extensions/Applications/#snmp-extend_60","title":"SNMP Extend","text":"
      1. Copy the python script to the desired host.

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/supervisord.py -O /etc/snmp/supervisord.py\n
        Notice that this will use the default unix socket path. Modify the unix_socket_path variable in the script if your path differs from the default.

      2. Make the script executable

        chmod +x /etc/snmp/supervisord.py\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend supervisord /etc/snmp/supervisord.py\n

      4. Restart snmpd on your host

        systemctl restart snmpd\n

      "},{"location":"Extensions/Applications/#sagan","title":"Sagan","text":"

      For metrics the stats are migrated as below from the stats JSON.

      f_drop_percent and drop_percent are computed based on the found data.

      Instance Key Stats JSON Key uptime .stats.uptime total .stats.captured.total drop .stats.captured.drop ignore .stats.captured.ignore threshold .stats.captured.theshold after .stats.captured.after match .stats.captured.match bytes .stats.captured.bytes_total bytes_ignored .stats.captured.bytes_ignored max_bytes_log_line .stats.captured.max_bytes_log_line eps .stats.captured.eps f_total .stats.flow.total f_dropped .stats.flow.dropped

      Those keys are appended with the name of the instance running with _ between the instance name and instance metric key. So uptime for ids would be ids_uptime.

      The default is named 'ids' unless otherwise specified via the extend.

      There is a special instance name of .total which is the total of all the instances. So if you want the total eps, the metric would be .total_eps. Also worth noting that the alert value is the highest one found among all the instances.

      "},{"location":"Extensions/Applications/#snmp-extend_61","title":"SNMP Extend","text":"
      1. Install the extend.

        cpanm Sagan::Monitoring\n

      2. Setup cron. Below is a example.

        */5 * * * * /usr/local/bin/sagan_stat_check > /dev/null\n

      3. Configure snmpd.conf

        extend sagan-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin sagan_stat_check -c\n

      4. Restart snmpd on your system.

      You will want to make sure that sagan is setup to with the values set below for stats-json processor, for a single instance setup..

      enabled: yes\ntime: 300\nsubtract_old_values: true\nfilename: \"$LOG_PATH/stats.json\"\n

      Any configuration of sagan_stat_check should be done in the cron setup. If the default does not work, check the docs for it at MetaCPAN for sagan_stat_check

      "},{"location":"Extensions/Applications/#socket-statistics-ss","title":"Socket Statistics (ss)","text":"

      The Socket Statistics application polls ss and scrapes socket statuses. Individual sockets and address-families may be filtered out within the script's optional configuration JSON file.

      1. The following socket types are polled directly. Filtering a socket type will disable direct polling as-well-as indirect polling within any address-families that list the socket type as their child:

        dccp (also exists within address-families \"inet\" and \"inet6\")\nmptcp (also exists within address-families \"inet\" and \"inet6\")\nraw (also exists within address-families \"inet\" and \"inet6\")\nsctp (also exists within address-families \"inet\" and \"inet6\")\ntcp (also exists within address-families \"inet\" and \"inet6\")\nudp (also exists within address-families \"inet\" and \"inet6\")\nxdp\n

      2. The following socket types are polled within an address-family only:

        inet6 (within address-family \"inet6\")\np_dgr (within address-family \"link\")\np_raw (within address-family \"link\")\nti_dg (within address-family \"tipc\")\nti_rd (within address-family \"tipc\")\nti_sq (within address-family \"tipc\")\nti_st (within address-family \"tipc\")\nv_dgr (within address-family \"vsock\")\nv_str (within address-family \"vsock\")\nunknown (within address-families \"inet\", \"inet6\", \"link\", \"tipc\", and \"vsock\")\n

      3. The following address-families are polled directly and have their child socket types tab-indented below them. Filtering a socket type (see \"1\" above) will filter it from the address-family. Filtering an address-family will filter out all of its child socket types. However, if those socket types are not DIRECTLY filtered out (see \"1\" above), then they will continue to be monitored either directly or within other address-families in which they exist:

        inet\n    dccp\n    mptcp\n    raw\n    sctp\n    tcp\n    udp\n    unknown\ninet6\n    dccp\n    icmp6\n    mptcp\n    raw\n    sctp\n    tcp\n    udp\n    unknown\nlink\n    p_dgr\n    p_raw\n    unknown\nnetlink\ntipc\n    ti_dg\n    ti_rd\n    ti_sq\n    ti_st\n    unknown\nunix\n    u_dgr\n    u_seq\n    u_str\nvsock\n    v_dgr\n    v_str\n    unknown\n

      "},{"location":"Extensions/Applications/#snmp-extend_62","title":"SNMP Extend","text":"
      1. Copy the python script, ss.py, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/ss.py -O /etc/snmp/ss.py\n

      2. Make the script executable

        chmod +x /etc/snmp/ss.py\n

      3. Edit your snmpd.conf file and add:

        extend ss /etc/snmp/ss.py\n

      4. (Optional) Create a /etc/snmp/ss.json file and specify:

        1. \"ss_cmd\" - String path to the ss binary: [\"/sbin/ss\"]
        2. \"socket_types\" - A comma-delimited list of socket types to include. The following socket types are valid: dccp, icmp6, mptcp, p_dgr, p_raw, raw, sctp, tcp, ti_dg, ti_rd, ti_sq, ti_st, u_dgr, u_seq, u_str, udp, unknown, v_dgr, v_dgr, xdp. Please note that the \"unknown\" socket type is represented in /sbin/ss output with the netid \"???\". Please also note that the p_dgr and p_raw socket types are specific to the \"link\" address family; the ti_dg, ti_rd, ti_sq, and ti_st socket types are specific to the \"tipc\" address family; the u_dgr, u_seq, and u_str socket types are specific to the \"unix\" address family; and the v_dgr and v_str socket types are specific to the \"vsock\" address family. Filtering out the parent address families for the aforementioned will also filter out their specific socket types. Specifying \"all\" includes all of the socket types. For example: to include only tcp, udp, icmp6 sockets, you would specify \"tcp,udp,icmp6\": [\"all\"]
        3. \"addr_families\" - A comma-delimited list of address families to include. The following families are valid: inet, inet6, link, netlink, tipc, unix, vsock. As mentioned above under (b), filtering out the link, tipc, unix, or vsock address families will also filter out their respective socket types. Specifying \"all\" includes all of the families. For example: to include only inet and inet6 families, you would specify \"inet,inet6\": [\"all\"]
          {\n    \"ss_cmd\": \"/sbin/ss\",\n    \"socket_types\": \"all\"\n    \"addr_families\": \"all\"\n}\n
          In order to filter out uncommon/unused socket types, the following JSON configuration is recommended:
          {\n    \"ss_cmd\": \"/sbin/ss\",\n    \"socket_types\": \"icmp6,p_dgr,p_raw,raw,tcp,u_dgr,u_seq,u_str,udp\",\n    \"addr_families\": \"inet,inet6,link,netlink,unix\"\n}\n
      5. (Optional) If SELinux is in Enforcing mode, you must add a module so the script can poll sockets:

        cat << EOF > snmpd_ss.te\nmodule snmp_ss 1.0;\n\nrequire {\n    type snmpd_t;\n    class netlink_tcpdiag_socket { bind create getattr nlmsg_read read setopt write };\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t self:netlink_tcpdiag_socket { bind create getattr nlmsg_read read setopt write };\nEOF\ncheckmodule -M -m -o snmpd_ss.mod snmpd_ss.te\nsemodule_package -o snmpd_ss.pp -m snmpd_ss.mod\nsemodule -i snmpd_ss.pp\n

      6. Restart snmpd.

      "},{"location":"Extensions/Applications/#suricata","title":"Suricata","text":""},{"location":"Extensions/Applications/#snmp-extend_63","title":"SNMP Extend","text":"
      1. Install the extend.

        cpanm Suricata::Monitoring\n

      2. Setup cron. Below is a example.

        */5 * * * * /usr/local/bin/suricata_stat_check > /dev/null\n

      3. Configure snmpd.conf

        extend suricata-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin suricata_stat_check -c\n

      Or if you want to use try compressing the return via Base64+GZIP...

      extend suricata-stats /usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin suricata_stat_check -c -b\n
      1. Restart snmpd on your system.

      You will want to make sure Suricata is set to output the stats to the eve file once a minute. This will help make sure that it won't be to far back in the file and will make sure it is recent when the cronjob runs.

      Any configuration of suricata_stat_check should be done in the cron setup. If the default does not work, check the docs for it at MetaCPAN for suricata_stat_check

      "},{"location":"Extensions/Applications/#suricata-extract","title":"Suricata Extract","text":""},{"location":"Extensions/Applications/#snmp_1","title":"SNMP","text":"
      1. Add the following to your snmpd config and restart. Path may have to be adjusted depending on where suricata_extract_submit_extend is installed to.
        extend suricata_extract /usr/local/bin/suricata_extract_submit_extend\n

      Then just wait for the system to be rediscovered or enable it manually for the server in question.

      "},{"location":"Extensions/Applications/#systemd","title":"Systemd","text":"

      The systemd application polls systemd and scrapes systemd units' load, activation, and sub states.

      "},{"location":"Extensions/Applications/#snmp-extend_64","title":"SNMP Extend","text":"
      1. Copy the python script, systemd.py, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/systemd.py -O /etc/snmp/systemd.py\n

      2. Make the script executable

        chmod +x /etc/snmp/systemd.py\n

      3. Edit your snmpd.conf file and add:

        extend systemd /etc/snmp/systemd.py\n

      4. (Optional) Create a /etc/snmp/systemd.json file and specify:

        1. \"systemctl_cmd\" - String path to the systemctl binary [Default: \"/usr/bin/systemctl\"]
        2. \"include_inactive_units\" - True/False string to include inactive units in results [Default: \"False\"]
          {\n    \"systemctl_cmd\": \"/bin/systemctl\",\n    \"include_inactive_units\": \"True\"\n}\n
      5. (Optional) If you have SELinux in Enforcing mode, you must add a module so the script can access systemd state:

        cat << EOF > snmpd_systemctl.te\nmodule snmpd_systemctl 1.0;\n\nrequire {\n        type snmpd_t;\n        type systemd_systemctl_exec_t;\n        type init_t;\n        class file { execute execute_no_trans map open read };\n        class unix_stream_socket connectto;\n        class system status;\n}\n\n#============= snmpd_t ==============\nallow snmpd_t init_t:system status;\nallow snmpd_t init_t:unix_stream_socket connectto;\nallow snmpd_t systemd_systemctl_exec_t:file { execute execute_no_trans map open read };\nEOF\ncheckmodule -M -m -o snmpd_systemctl.mod snmpd_systemctl.te\nsemodule_package -o snmpd_systemctl.pp -m snmpd_systemctl.mod\nsemodule -i snmpd_systemctl.pp\n

      6. Restart snmpd.

      "},{"location":"Extensions/Applications/#tinydns-aka-djbdns","title":"TinyDNS aka djbdns","text":""},{"location":"Extensions/Applications/#agent_14","title":"Agent","text":"

      Install the agent on this device if it isn't already and copy the tinydns script to /usr/lib/check_mk_agent/local/

      Note: We assume that you use DJB's Daemontools to start/stop tinydns. And that your tinydns instance is located in /service/dns, adjust this path if necessary.

      1. Replace your log's run file, typically located in /service/dns/log/run with:

        #!/bin/sh\nexec setuidgid dnslog tinystats ./main/tinystats/ multilog t n3 s250000 ./main/\n

      2. Create tinystats directory and chown:

        mkdir /service/dns/log/main/tinystats\nchown dnslog:nofiles /service/dns/log/main/tinystats\n

      3. Restart TinyDNS and Daemontools: /etc/init.d/svscan restart Note: Some say svc -t /service/dns is enough, on my install (Gentoo) it doesn't rehook the logging and I'm forced to restart it entirely.

      "},{"location":"Extensions/Applications/#unbound","title":"Unbound","text":"

      Unbound configuration:

      # Enable extended statistics.\nserver:\n        extended-statistics: yes\n        statistics-cumulative: yes\n\nremote-control:\n        control-enable: yes\n        control-interface: 127.0.0.1\n

      Restart your unbound after changing the configuration, verify it is working by running unbound-control stats.

      "},{"location":"Extensions/Applications/#option-1-snmp-extend-preferred-and-easiest-method","title":"Option 1. SNMP Extend (Preferred and easiest method)","text":"
      1. Copy the shell script, unbound, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/unbound -O /etc/snmp/unbound\n

      2. Make the script executable

        chmod +x /etc/snmp/unbound\n

      3. Edit your snmpd.conf file and add:

        extend unbound /usr/bin/sudo /etc/snmp/unbound\n

      4. Restart snmpd.

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#option-2-agent","title":"Option 2. Agent","text":"

      Install the agent on this device if it isn't already and copy the unbound.sh script to /usr/lib/check_mk_agent/local/

      "},{"location":"Extensions/Applications/#ups-nut","title":"UPS-nut","text":"

      A small shell script that exports nut ups status.

      "},{"location":"Extensions/Applications/#snmp-extend_65","title":"SNMP Extend","text":"
      1. Copy the shell script, unbound, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/ups-nut.sh -O /etc/snmp/ups-nut.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/ups-nut.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend ups-nut /etc/snmp/ups-nut.sh\n

      4. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      Optionally if you have multiple UPS or your UPS is not named APCUPS you can specify its name as an argument into /etc/snmp/ups-nut.sh

      extend ups-nut /etc/snmp/ups-nut.sh ups1\nextend ups-nut /etc/snmp/ups-nut.sh ups2\n

      "},{"location":"Extensions/Applications/#ups-apcups","title":"UPS-apcups","text":"

      A small shell script that exports apcacess ups status.

      "},{"location":"Extensions/Applications/#snmp-extend_66","title":"SNMP Extend","text":"
      1. Copy the shell script, unbound, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/ups-apcups -O /etc/snmp/ups-apcups\n

      2. Make the script executable

        chmod +x /etc/snmp/ups-apcups\n

      3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:

        extend ups-apcups /etc/snmp/ups-apcups\n

      If 'apcaccess' is not in the PATH enviromental variable snmpd is using, you may need to do something like below.

      extend ups-apcups/usr/bin/env PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin /etc/snmp/ups-apcups\n
      1. Restart snmpd on your host

      The application should be auto-discovered as described at the top of the page. If it is not, please follow the steps set out under SNMP Extend heading top of page.

      "},{"location":"Extensions/Applications/#voip-monitor","title":"Voip-monitor","text":"

      Shell script that reports cpu-load/memory/open-files files stats of Voip Monitor

      "},{"location":"Extensions/Applications/#snmp-extend_67","title":"SNMP Extend","text":"
      1. Download the script onto the desired host

        wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/voipmon-stats.sh -O /etc/snmp/voipmon-stats.sh\n

      2. Make the script executable

        chmod +x /etc/snmp/voipmon-stats.sh\n

      3. Edit your snmpd.conf file (usually /etc/snmp/voipmon-stats.sh) and add:

        extend voipmon /etc/snmp/voipmon-stats.sh\n

      "},{"location":"Extensions/Applications/#wireguard","title":"Wireguard","text":"

      The Wireguard application polls the Wireguard service and scrapes all client statistics for all interfaces configured as Wireguard interfaces.

      "},{"location":"Extensions/Applications/#snmp-extend_68","title":"SNMP Extend","text":"
      1. Copy the python script, wireguard.py, to the desired host

        wget https://github.com/librenms/librenms-agent/raw/master/snmp/wireguard.pl -O /etc/snmp/wireguard.pl\n

      2. Install the depends.

        # FreeBSD\npkg install p5-JSON p5-File-Slurp p5-MIME-Base64\n# Debian\napt-get install libjson-perl libmime-base64-perl libfile-slurp-perl\n

      3. Make the script executable

        chmod +x /etc/snmp/wireguard.pl\n

      4. Edit your snmpd.conf file and add:

        extend wireguard /etc/snmp/wireguard.pl\n

      5. Create the optional config file, /usr/local/etc/wireguard_extend.json.

      key default description include_pubkey 0 Include the pubkey with the return. use_short_hostname 1 If the hostname should be shortened to just the first part. public_key_to_arbitrary_name {} A hash of pubkeys to name mappings. pubkey_resolvers Resolvers to use for the pubkeys.

      The default for pubkey_resolvers is config,endpoint_if_first_allowed_is_subnet_use_hosts,endpoint_if_first_allowed_is_subnet_use_ip,first_allowed_use_hosts,first_allowed_use_ip.

      resolver description config Use the mappings from .public_key_to_arbitrary_name . endpoint_if_first_allowed_is_subnet_use_hosts If the first allowed IP is a subnet, see if a matching IP can be found in hosts for the endpoint. endpoint_if_first_allowed_is_subnet_use_getent If the first allowed IP is a subnet, see if a hit can be found for the endpoint IP via getent hosts. endpoint_if_first_allowed_is_subnet_use_ip If the first allowed IP is a subnet, use the endpoint IP for the name. first_allowed_use_hosts See if a match can be found in hosts for the first allowed IP. first_allowed_use_getent Use getent hosts to see try to fetch a match for the first allowed IP. first_allowed_use_ip Use the first allowed IP as the name.
      1. Restart snmpd.
      "},{"location":"Extensions/Applications/#zfs","title":"ZFS","text":""},{"location":"Extensions/Applications/#snmp-extend_69","title":"SNMP Extend","text":"

      1: Install the depends.

      ### FreeBSD\npkg install p5-JSON p5-MIME-Base64 p5-Gzip-Faster p5-File-Slurp\n### Debian\napt-get install -y cpanminus zlib1g-dev\ncpanm Mime::Base64 JSON Gzip::Faster\n

      2: Fetch the script in question and make it executable.

      wget https://github.com/librenms/librenms-agent/raw/master/snmp/zfs -O /etc/snmp/zfs\nchmod +x /etc/snmp/zfs\n

      3: Add the following to snmpd.conf and restart snmpd.

      extend zfs /etc/snmp/zfs\n

      "},{"location":"Extensions/Authentication/","title":"Authentication Options","text":"

      LibreNMS supports multiple authentication modules along with Two Factor Auth. Here we will provide configuration details for these modules. Alternatively, you can use Socialite Providers which supports a wide variety of social/OAuth/SAML authentication methods.

      "},{"location":"Extensions/Authentication/#available-authentication-modules","title":"Available authentication modules","text":"
      • MySQL: mysql

      • Active Directory: active_directory

      • LDAP: ldap

      • Radius: radius

      • HTTP Auth: http-auth, ad_authorization, ldap_authorization

      • Single Sign-on: sso

      \u26a0\ufe0f When enabling a new authentication module, the local users will no longer be available to log in.

      "},{"location":"Extensions/Authentication/#enable-authentication-module","title":"Enable authentication module","text":"

      To enable a particular authentication module you need to set this up in config.php. Please note that only ONE module can be enabled. LibreNMS doesn't support multiple authentication mechanisms at the same time.

      auth/general

      lnms config:set auth_mechanism mysql\n
      "},{"location":"Extensions/Authentication/#user-levels-and-user-account-type","title":"User levels and User account type","text":"
      • 1: Normal User: You will need to assign device / port permissions for users at this level.

      • 5: Global Read: Read only Administrator.

      • 10: Administrator: This is a global read/write admin account.

      • 11: Demo Account: Provides full read/write with certain restrictions (i.e can't delete devices).

      Note Oxidized configs can often contain sensitive data. Because of that only Administrator account type can see configs.

      "},{"location":"Extensions/Authentication/#note-for-selinux-users","title":"Note for SELinux users","text":"

      When using SELinux on the LibreNMS server, you need to allow Apache (httpd) to connect LDAP/Active Directory server, this is disabled by default. You can use SELinux Booleans to allow network access to LDAP resources with this command:

      setsebool -P httpd_can_connect_ldap=1\n
      "},{"location":"Extensions/Authentication/#testing-authentication","title":"Testing authentication","text":"

      You can test authentication with this script:

      ./scripts/auth_test.php\n

      Enable debug output to troubleshoot issues

      "},{"location":"Extensions/Authentication/#mysql-authentication","title":"MySQL Authentication","text":"

      auth/general

      lnms config:set auth_mechanism mysql\n

      This is default option with LibreNMS so you should have already have the following configuration setup in your environment file (.env).

      DB_HOST=HOSTNAME\nDB_DATABASE=DBNAME\nDB_USERNAME=DBUSER\nDB_PASSWORD=\"DBPASS\"\n
      "},{"location":"Extensions/Authentication/#active-directory-authentication","title":"Active Directory Authentication","text":"

      auth/general

      lnms config:set auth_mechanism active_directory\n

      Install php-ldap or php8.1-ldap, making sure to install the same version as PHP.

      If you have issues with secure LDAP try setting

      auth/ad

      lnms config:set auth_ad_check_certificates 0\n

      this will ignore certificate errors.

      "},{"location":"Extensions/Authentication/#require-actual-membership-of-the-configured-groups","title":"Require actual membership of the configured groups","text":"

      auth/ad

      lnms config:set auth_ad_require_groupmembership 1\n

      If you set auth_ad_require_groupmembership to 1, the authenticated user has to be a member of the specific group. Otherwise all users can authenticate, and will be either level 0 or you may set auth_ad_global_read to 1 and all users will have read only access unless otherwise specified.

      "},{"location":"Extensions/Authentication/#old-account-cleanup","title":"Old account cleanup","text":"

      Cleanup of old accounts is done by checking the authlog. You will need to set the number of days when old accounts will be purged AUTOMATICALLY by daily.sh.

      Please ensure that you set the authlog_purge value to be greater than active_directory.users_purge otherwise old users won't be removed.

      "},{"location":"Extensions/Authentication/#sample-configuration","title":"Sample configuration","text":"

      auth/general

      lnms config:set auth_mechanism active_directory\nlnms config:set auth_ad_url ldaps://server.example.com\nlnms config:set auth_ad_domain\nlnms config:set auth_ad_base_dn dc=example,dc=com\nlnms config:set auth_ad_check_certificates true\nlnms config:set auth_ad_binduser examplebinduser\nlnms config:set auth_ad_bindpassword examplepassword\nlnms config:set auth_ad_timeout 5\nlnms config:set auth_ad_debug false\nlnms config:set active_directory.users_purge 30\nlnms config:set auth_ad_require_groupmembership true\nlnms config:set auth_ad_groups.ad-admingroup.level 10\nlnms config:set auth_ad_groups.ad-usergroup.level 5\n

      Replace ad-admingroup with your Active Directory admin-user group and ad-usergroup with your standard user group. It is highly suggested to create a bind user, otherwise \"remember me\", alerting users, and the API will not work.

      "},{"location":"Extensions/Authentication/#active-directory-redundancy","title":"Active Directory redundancy","text":"

      You can set two Active Directory servers by editing the auth_ad_url setting like this example:

      auth/ad

      lnms config:set auth_ad_url \"ldaps://dc1.example.com ldaps://dc2.example.com\"\n
      "},{"location":"Extensions/Authentication/#active-directory-ldap-filters","title":"Active Directory LDAP filters","text":"

      You can add an LDAP filter to be ANDed with the builtin user filter ((sAMAccountName=$username)).

      The defaults are:

      auth/ad

      lnms config:set auth_ad_user_filter \"(objectclass=user)\"\nlnms config:set auth_ad_group_filter \"(objectclass=group)\"\n

      This yields (&(objectclass=user)(sAMAccountName=$username)) for the user filter and (&(objectclass=group)(sAMAccountName=$group)) for the group filter.

      "},{"location":"Extensions/Authentication/#selinux-configuration","title":"SELinux configuration","text":"

      On RHEL / CentOS / Fedora, in order for LibreNMS to reach Active Directory, you need to allow LDAP requests in SELinux:

      setsebool -P httpd_can_connect_ldap 1\n

      "},{"location":"Extensions/Authentication/#ldap-authentication","title":"LDAP Authentication","text":"

      auth/general

      lnms config:set auth_mechanism ldap\n

      Install php_ldap or php7.0-ldap, making sure to install the same version as PHP.

      For the below, keep in mind the auth DN is composed using a string join of auth_ldap_prefix, the username, and auth_ldap_suffix. This means it needs to include = in the prefix and , in the suffix. So lets say we have a prefix of uid=, the user derp, and the suffix of ,ou=users,dc=foo,dc=bar, then the result is uid=derp,ou=users,dc=foo,dc=bar.

      "},{"location":"Extensions/Authentication/#standard-config","title":"Standard config","text":"

      auth/ldap

      lnms config:set auth_ldap_server ldap.example.com\nlnms config:set auth_ldap_suffix ',ou=People,dc=example,dc=com'\nlnms config:set auth_ldap_groupbase 'ou=groups,dc=example,dc=com'\nlnms config:set auth_ldap_groups.admin.level 10\nlnms config:set auth_ldap_groups.pfy.level 5\nlnms config:set auth_ldap_groups.support.level 1\n
      "},{"location":"Extensions/Authentication/#additional-options-usually-not-needed","title":"Additional options (usually not needed)","text":"

      auth/ldap

      lnms config:set auth_ldap_version 3\nlnms config:set auth_ldap_port 389\nlnms config:set auth_ldap_starttls true\nlnms config:set auth_ldap_prefix 'uid='\nlnms config:set auth_ldap_group 'cn=groupname,ou=groups,dc=example,dc=com'\nlnms config:set auth_ldap_groupmemberattr memberUid\nlnms config:set auth_ldap_groupmembertype username\nlnms config:set auth_ldap_uid_attribute uidnumber\nlnms config:set auth_ldap_timeout 5\nlnms config:set auth_ldap_emailattr mail\nlnms config:set auth_ldap_attr.uid uid\nlnms config:set auth_ldap_debug false\nlnms config:set auth_ldap_userdn true\nlnms config:set auth_ldap_userlist_filter service=informatique\nlnms config:set auth_ldap_wildcard_ou false\nlnms config:set auth_ldap_cacertfile /opt/librenms/ldap-ca-cert\nlnms config:set auth_ldap_ignorecert false\n
      "},{"location":"Extensions/Authentication/#ldap-bind-user-optional","title":"LDAP bind user (optional)","text":"

      If your ldap server does not allow anonymous bind, it is highly suggested to create a bind user, otherwise \"remember me\", alerting users, and the API will not work.

      auth/ldap

      lnms config:set auth_ldap_binduser ldapbind\nlnms config:set auth_ldap_binddn 'CN=John.Smith,CN=Users,DC=MyDomain,DC=com'\nlnms config:set auth_ldap_bindpassword password\n
      "},{"location":"Extensions/Authentication/#ldap-server-redundancy","title":"LDAP server redundancy","text":"

      You can set two LDAP servers by editing the auth_ldap_server like this example:

      auth/ldap

      lnms config:set auth_ldap_server ldaps://dir1.example.com ldaps://dir2.example.com\n

      An example config setup for use with Jumpcloud LDAP as a service is:

      auth/ldap

      lnms config:set auth_mechanism ldap\nlnms config:set auth_ldap_version 3\nlnms config:set auth_ldap_server ldap.jumpcloud.com\nlnms config:set auth_ldap_port 389\nlnms config:set auth_ldap_prefix 'uid=';\nlnms config:set auth_ldap_suffix ',ou=Users,o={id},dc=jumpcloud,dc=com'\nlnms config:set auth_ldap_groupbase 'ou=Users,o={id},dc=jumpcloud,dc=com'\nlnms config:set auth_ldap_groupmemberattr member\nlnms config:set auth_ldap_groups.{group}.level 10\nlnms config:set auth_ldap_userdn true\n

      Replace {id} with the unique ID provided by Jumpcloud. Replace {group} with the unique group name created in Jumpcloud. This field is case sensitive.

      Note: If you have multiple user groups to define individual access levels replace the auth_ldap_groups line with the following:

      auth/ldap

      lnms config:set auth_ldap_groups.{admin_group}.level 10]\nlnms config:set auth_ldap_groups.global_readonly_group.level 5\n
      "},{"location":"Extensions/Authentication/#selinux-configuration_1","title":"SELinux configuration","text":"

      On RHEL / CentOS / Fedora, in order for LibreNMS to reach LDAP, you need to allow LDAP requests in SELinux:

      setsebool -P httpd_can_connect_ldap 1\n

      "},{"location":"Extensions/Authentication/#radius-authentication","title":"Radius Authentication","text":"

      Please note that a mysql user is created for each user the logs in successfully. Users are assigned the user role by default, unless radius sends a reply attribute with a role.

      You can change the default role(s) by setting

      auth/radius

      lnms config:set radius.default_roles '[\"csr\"]'\n

      The attribute Filter-ID is a standard Radius-Reply-Attribute (string) that can be assigned a specially formatted string to assign a single role to the user.

      The string to send in Filter-ID reply attribute must start with librenms_role_ followed by the role name. For example to set the admin role send librenms_role_admin.

      The following strings correspond to the built-in roles, but any defined role can be used: - librenms_role_normal - Sets the normal user level. - librenms_role_admin - Sets the administrator level. - librenms_role_global-read - Sets the global read level

      LibreNMS will ignore any other strings sent in Filter-ID and revert to default role that is set in your config.

      $config['radius']['hostname']      = 'localhost';\n$config['radius']['port']          = '1812';\n$config['radius']['secret']        = 'testing123';\n$config['radius']['timeout']       = 3;\n$config['radius']['users_purge']   = 14;  // Purge users who haven't logged in for 14 days.\n$config['radius']['default_level'] = 1;  // Set the default user level when automatically creating a user.\n
      "},{"location":"Extensions/Authentication/#radius-huntgroup","title":"Radius Huntgroup","text":"

      Freeradius has a function called Radius Huntgroup which allows to send different attributes based on NAS. This may be utilized if you already use Filter-ID in your environment and also want to use radius with LibreNMS.

      "},{"location":"Extensions/Authentication/#old-account-cleanup_1","title":"Old account cleanup","text":"

      Cleanup of old accounts is done by checking the authlog. You will need to set the number of days when old accounts will be purged AUTOMATICALLY by daily.sh.

      Please ensure that you set the $config['authlog_purge'] value to be greater than $config['radius']['users_purge'] otherwise old users won't be removed.

      "},{"location":"Extensions/Authentication/#http-authentication","title":"HTTP Authentication","text":"

      Config option: http-auth

      LibreNMS will expect the user to have authenticated via your webservice already. At this stage it will need to assign a userlevel for that user which is done in one of two ways:

      • A user exists in MySQL still where the usernames match up.

      • A global guest user (which still needs to be added into MySQL:

      $config['http_auth_guest'] = \"guest\";\n

      This will then assign the userlevel for guest to all authenticated users.

      "},{"location":"Extensions/Authentication/#http-authentication-ad-authorization","title":"HTTP Authentication / AD Authorization","text":"

      Config option: ad-authorization

      This module is a combination of http-auth and active_directory

      LibreNMS will expect the user to have authenticated via your webservice already (e.g. using Kerberos Authentication in Apache) but will use Active Directory lookups to determine and assign the userlevel of a user. The userlevel will be calculated by using AD group membership information as the active_directory module does.

      The configuration is the same as for the active_directory module with two extra, optional options: auth_ad_binduser and auth_ad_bindpassword. These should be set to a AD user with read capabilities in your AD Domain in order to be able to perform searches. If these options are omitted, the module will attempt an anonymous bind (which then of course must be allowed by your Active Directory server(s)).

      There is also one extra option for controlling user information caching: auth_ldap_cache_ttl. This option allows to control how long user information (user_exists, userid, userlevel) are cached within the PHP Session. The default value is 300 seconds. To disable this caching (highly discourage) set this option to 0.

      $config['auth_ad_binduser']     = \"ad_binduser\";\n$config['auth_ad_bindpassword'] = \"ad_bindpassword\";\n$config['auth_ldap_cache_ttl']  = 300;\n
      "},{"location":"Extensions/Authentication/#http-authentication-ldap-authorization","title":"HTTP Authentication / LDAP Authorization","text":"

      Config option: ldap-authorization

      This module is a combination of http-auth and ldap

      LibreNMS will expect the user to have authenticated via your webservice already (e.g. using Kerberos Authentication in Apache) but will use LDAP to determine and assign the userlevel of a user. The userlevel will be calculated by using LDAP group membership information as the ldap module does.

      The configuration is similar to the ldap module with one extra option: auth_ldap_cache_ttl. This option allows to control how long user information (user_exists, userid, userlevel) are cached within the PHP Session. The default value is 300 seconds. To disabled this caching (highly discourage) set this option to 0.

      "},{"location":"Extensions/Authentication/#standard-config_1","title":"Standard config","text":"
      $config['auth_mechanism'] = 'ldap-authorization';\n$config['auth_ldap_server'] = 'ldap.example.com';               // Set server(s), space separated. Prefix with ldaps:// for ssl\n$config['auth_ldap_suffix'] = ',ou=People,dc=example,dc=com';   // appended to usernames\n$config['auth_ldap_groupbase'] = 'ou=groups,dc=example,dc=com'; // all groups must be inside this\n$config['auth_ldap_groups']['admin']['roles'] = ['admin'];             // set admin group to admin role\n$config['auth_ldap_groups']['pfy']['roles'] = ['global-read'];                // set pfy group to global read only role\n$config['auth_ldap_groups']['support']['roles'] = ['user'];            // set support group as a normal user\n
      "},{"location":"Extensions/Authentication/#additional-options-usually-not-needed_1","title":"Additional options (usually not needed)","text":"
      $config['auth_ldap_version'] = 3; # v2 or v3\n$config['auth_ldap_port'] = 389;                    // 389 or 636 for ssl\n$config['auth_ldap_starttls'] = True;               // Enable TLS on port 389\n$config['auth_ldap_prefix'] = 'uid=';               // prepended to usernames\n$config['auth_ldap_group']  = 'cn=groupname,ou=groups,dc=example,dc=com'; // generic group with level 0\n$config['auth_ldap_groupmemberattr'] = 'memberUid'; // attribute to use to see if a user is a member of a group\n$config['auth_ldap_groupmembertype'] = 'username';  // username type to find group members by, either username (default), fulldn or puredn\n$config['auth_ldap_emailattr'] = 'mail';            // attribute for email address\n$config['auth_ldap_attr.uid'] = 'uid';              // attribute to check username against\n$config['auth_ldap_userlist_filter'] = 'service=informatique'; // Replace 'service=informatique' by your ldap filter to limit the number of responses if you have an ldap directory with thousand of users\n$config['auth_ldap_cache_ttl'] = 300;\n
      "},{"location":"Extensions/Authentication/#ldap-bind-user-optional_1","title":"LDAP bind user (optional)","text":"

      If your ldap server does not allow anonymous bind, it is highly suggested to create a bind user, otherwise \"remember me\", alerting users, and the API will not work.

      $config['auth_ldap_binduser'] = 'ldapbind'; // will use auth_ldap_prefix and auth_ldap_suffix\n#$config['auth_ldap_binddn'] = 'CN=John.Smith,CN=Users,DC=MyDomain,DC=com'; // overrides binduser\n$config['auth_ldap_bindpassword'] = 'password';\n
      "},{"location":"Extensions/Authentication/#viewembedded-graphs-without-being-logged-into-librenms","title":"View/embedded graphs without being logged into LibreNMS","text":"

      webui/graph

      ```bash lnms config:set allow_unauth_graphs_cidr ['127.0.0.1/32'] lnms config:set allow_unauth_graphs true

      ```

      "},{"location":"Extensions/Authentication/#single-sign-on","title":"Single Sign-on","text":"

      The single sign-on mechanism is used to integrate with third party authentication providers that are managed outside of LibreNMS - such as ADFS, Shibboleth, EZProxy, BeyondCorp, and others. A large number of these methods use SAML the module has been written assuming the use of SAML, and therefore these instructions contain some SAML terminology, but it should be possible to use any software that works in a similar way.

      In order to make use of the single sign-on module, you need to have an Identity Provider up and running, and know how to configure your Relying Party to pass attributes to LibreNMS via header injection or environment variables. Setting these up is outside of the scope of this documentation.

      As this module deals with authentication, it is extremely careful about validating the configuration - if it finds that certain values in the configuration are not set, it will reject access rather than try and guess.

      "},{"location":"Extensions/Authentication/#basic-configuration","title":"Basic Configuration","text":"

      To get up and running, all you need to do is configure the following values:

      $config['auth_mechanism']        = \"sso\";\n$config['sso']['mode']           = \"env\";\n$config['sso']['group_strategy'] = \"static\";\n$config['sso']['static_level']   = 10;\n

      This, along with the defaults, sets up a basic Single Sign-on setup that:

      • Reads values from environment variables
      • Automatically creates users when they're first seen
      • Automatically updates users with new values
      • Gives everyone privilege level 10

      This happens to mimic the behaviour of http-auth, so if this is the kind of setup you want, you're probably better of just going and using that mechanism.

      "},{"location":"Extensions/Authentication/#security","title":"Security","text":"

      If there is a proxy involved (e.g. EZProxy, Azure AD Application Proxy, NGINX, mod_proxy) it's essential that you have some means in place to prevent headers being injected between the proxy and the end user, and also prevent end users from contacting LibreNMS directly.

      This should also apply to user connections to the proxy itself - the proxy must not be allowed to blindly pass through HTTP headers. modsecurity_ should be considered a minimum, with a full WAF being strongly recommended. This advice applies to the IDP too.

      The mechanism includes very basic protection, in the form of an IP whitelist with should contain the source addresses of your proxies:

      $config['sso']['trusted_proxies'] = ['127.0.0.1/8', '::1/128', '192.0.2.0', '2001:DB8::'];\n

      This configuration item should contain an array with a list of IP addresses or CIDR prefixes that are allowed to connect to LibreNMS and supply environment variables or headers.

      "},{"location":"Extensions/Authentication/#advanced-configuration-options","title":"Advanced Configuration Options","text":""},{"location":"Extensions/Authentication/#user-attribute","title":"User Attribute","text":"

      If for some reason your relying party doesn't store the username in REMOTE_USER, you can override this choice.

      $config['sso']['user_attr'] = 'HTTP_UID';\n

      Note that the user lookup is a little special - normally headers are prefixed with HTTP_, however this is not the case for remote user - it's a special case. If you're using something different you need to figure out of the HTTP_ prefix is required or not yourself.

      "},{"location":"Extensions/Authentication/#automatic-user-createupdate","title":"Automatic User Create/Update","text":"

      These are enabled by default:

      $config['sso']['create_users'] = true;\n$config['sso']['update_users'] = true;\n

      If these are not enabled, user logins will be (somewhat silently) rejected unless an administrator has created the account in advance. Note that in the case of SAML federations, unless release of the users true identity has been negotiated with the IDP, the username (probably ePTID) is not likely to be predicable.

      "},{"location":"Extensions/Authentication/#personalisation","title":"Personalisation","text":"

      If the attributes are being populated, you can instruct the mechanism to add additional information to the user's database entry:

      $config['sso']['email_attr']    = \"mail\";\n$config['sso']['realname_attr'] = \"displayName\";\n$config['sso']['descr_attr']    = \"unscoped-affiliation\n
      "},{"location":"Extensions/Authentication/#group-strategies","title":"Group Strategies","text":""},{"location":"Extensions/Authentication/#static","title":"Static","text":"

      As used above, static gives every single user the same privilege level. If you're working with a small team, or don't need access control, this is probably suitable.

      "},{"location":"Extensions/Authentication/#attribute","title":"Attribute","text":"
      $config['sso']['group_strategy'] = \"attribute\";\n$config['sso']['level_attr']     = \"entitlement\";\n

      If your Relying Party is capable of calculating the necessary privilege level, you can configure the module to read the privilege number straight from an attribute. sso_level_attr should contain the name of the attribute that the Relying Party exposes to LibreNMS - as long as sso_mode is correctly set, the mechanism should find the value.

      "},{"location":"Extensions/Authentication/#group-map","title":"Group Map","text":"

      This is the most flexible (and complex) way of assigning privileges.

      $config['sso']['group_strategy']  = \"map\";\n$config['sso']['group_attr']      = \"member\";\n$config['sso']['group_level_map'] = ['librenms-admins' => 10, 'librenms-readers' => 1, 'librenms-billingcontacts' => 5];\n$config['sso']['group_delimiter'] = ';';\n

      This mechanism expects to find a delimited list of groups within the attribute that sso_group_attr points to. This should be an associative array of group name keys, with privilege levels as values. The mechanism will scan the list and find the highest privilege level that the user is entitled to, and assign that value to the user.

      If there are no matches between the user's groups and the sso_group_level_map, the user will be assigned the privilege level specified in the sso_static_level variable, with a default of 0 (no access). This feature can be used to provide a default access level (such as read-only) to all authenticated users.

      Additionally, this format may be specific to Shibboleth; other relying party software may need changes to the mechanism (e.g. mod_auth_mellon may create pseudo arrays).

      There is an optional value for sites with large numbers of groups:

      $config['sso']['group_filter']  = \"/librenms-(.*)/i\";\n

      This filter causes the mechanism to only consider groups matching a regular expression.

      "},{"location":"Extensions/Authentication/#logout-behaviour","title":"Logout Behaviour","text":"

      LibreNMS has no capability to log out a user authenticated via Single Sign-On - that responsibility falls to the Relying Party.

      If your Relying Party has a magic URL that needs to be called to end a session, you can configure LibreNMS to direct the user to it:

      # Example for Shibboleth\n$config['auth_logout_handler'] = '/Shibboleth.sso/Logout';\n\n# Example for oauth2-proxy\n$config['auth_logout_handler'] = '/oauth2/sign_out';\n

      This option functions independently of the Single Sign-on mechanism.

      "},{"location":"Extensions/Authentication/#complete-configuration","title":"Complete Configuration","text":"

      This configuration works on my deployment with a Shibboleth relying party, injecting environment variables, with the IDP supplying a list of groups.

      $config['auth_mechanism'] = 'sso';\n$config['auth_logout_handler'] = '/Shibboleth.sso/Logout';\n$config['sso']['mode'] = 'env';\n$config['sso']['create_users'] = true;\n$config['sso']['update_users'] = true;\n$config['sso']['realname_attr'] = 'displayName';\n$config['sso']['email_attr'] = 'mail';\n$config['sso']['group_strategy'] = 'map';\n$config['sso']['group_attr'] = 'member';\n$config['sso']['group_filter'] = '/(librenms-.*)/i';\n$config['sso']['group_delimiter'] = ';';\n$config['sso']['group_level_map'] = ['librenms-demo' => 11, 'librenms-globaladmin' => 10, 'librenms-globalread' => 5, 'librenms-lowpriv'=> 1];\n
      "},{"location":"Extensions/Auto-Discovery/","title":"Auto Discovery Support","text":""},{"location":"Extensions/Auto-Discovery/#getting-started","title":"Getting Started","text":"

      LibreNMS provides the ability to automatically add devices on your network, we can do this via a few methods which will be explained below and also indicate if they are enabled by default.

      All discovery methods run when discovery runs (every 6 hours by default and within 5 minutes for new devices).

      Please note that you need at least ONE device added before auto-discovery will work.

      The first thing to do though is add the required configuration options to config.php.

      "},{"location":"Extensions/Auto-Discovery/#snmp-details","title":"SNMP Details","text":"

      To add devices automatically we need to know your snmp details, examples of SNMP v1, v2c and v3 are below:

      // v1 or v2c\n$config['snmp']['community'][] = \"my_custom_community\";\n$config['snmp']['community'][] = \"another_community\";\n\n// v3\n$config['snmp']['v3'][0]['authlevel'] = 'authPriv';\n$config['snmp']['v3'][0]['authname'] = 'my_username';\n$config['snmp']['v3'][0]['authpass'] = 'my_password';\n$config['snmp']['v3'][0]['authalgo'] = 'SHA';\n$config['snmp']['v3'][0]['cryptopass'] = 'my_crypto';\n$config['snmp']['v3'][0]['cryptoalgo'] = 'AES';\n

      These details will be attempted when adding devices, you can specify any mixture of these.

      "},{"location":"Extensions/Auto-Discovery/#allowed-networks","title":"Allowed Networks","text":""},{"location":"Extensions/Auto-Discovery/#your-networks","title":"Your Networks","text":"

      To add devices, we need to know what are your subnets so we don't go blindly attempting to add devices not under your control.

      discovery/networks

      lnms config:set nets.+ '192.168.0.0/24'\nlnms config:set nets.+ '172.2.4.0/22'\n
      "},{"location":"Extensions/Auto-Discovery/#exclusions","title":"Exclusions","text":"

      If you have added a network as above but a single device exists within it that you can't auto add, then you can exclude this with the following:

      discovery/networks

      lnms config:set autodiscovery.nets-exclude.+ '192.168.0.1/32'\n
      "},{"location":"Extensions/Auto-Discovery/#additional-options","title":"Additional Options","text":""},{"location":"Extensions/Auto-Discovery/#discovering-devices-by-ip","title":"Discovering devices by IP","text":"

      By default we don't add devices by IP address, we look for a reverse dns name to be found and add with that. If this fails and you would like to still add devices automatically then you will need to set $config['discovery_by_ip'] = true;

      "},{"location":"Extensions/Auto-Discovery/#short-hostnames","title":"Short hostnames","text":"

      If your devices only return a short hostname such as lax-fa0-dc01 but the full name should be lax-fa0-dc01.example.com then you can set

      discovery/general

      lnms config:set mydomain example.com\n
      "},{"location":"Extensions/Auto-Discovery/#allow-duplicate-sysname","title":"Allow Duplicate sysName","text":"

      By default we require unique sysNames when adding devices (this is returned over snmp by your devices). If you would like to allow devices to be added with duplicate sysNames then please set

      discovery/discovery_modules

      lnms config:set allow_duplicate_sysName true\n
      "},{"location":"Extensions/Auto-Discovery/#discovery-methods","title":"Discovery Methods","text":"

      Below are the methods for auto discovering devices. Each one can be enabled or disabled and may have additional configuration options.

      "},{"location":"Extensions/Auto-Discovery/#arp","title":"ARP","text":"

      Disabled by default.

      Adds devices that are listed in another device's arp table. This module depends on the arp-table module being enabled and returning data.

      To enable, switch on globally the discovery_modules.discovery-arp or per device within the Modules section.

      discovery/discovery_modules

      lnms config:set discovery_modules.discovery-arp true\n
      "},{"location":"Extensions/Auto-Discovery/#xdp","title":"XDP","text":"

      Enabled by default.

      $config['autodiscovery']['xdp'] = false; to disable.

      This includes FDP, CDP and LLDP support based on the device type.

      The LLDP/xDP links with neighbours will always be discovered as soon as the discovery module is enabled. However, LibreNMS will only try to add the new devices discovered with LLDP/xDP if $config['autodiscovery']['xdp'] = true;.

      Devices may be excluded from xdp discovery by sysName and sysDescr.

      //Exclude devices by name\n$config['autodiscovery']['xdp_exclude']['sysname_regexp'][] = '/host1/';\n$config['autodiscovery']['xdp_exclude']['sysname_regexp'][] = '/^dev/';\n\n//Exclude devices by description\n$config['autodiscovery']['xdp_exclude']['sysdesc_regexp'][] = '/Vendor X/';\n$config['autodiscovery']['xdp_exclude']['sysdesc_regexp'][] = '/Vendor Y/';\n

      Devices may be excluded from cdp discovery by platform.

      //Exclude devices by platform(Cisco only)\n$config['autodiscovery']['cdp_exclude']['platform_regexp'][] = '/WS-C3750G/';\n

      These devices are excluded by default:

      $config['autodiscovery']['xdp_exclude']['sysdesc_regexp'][] = '/-K9W8/'; // Cisco Lightweight Access Point\n$config['autodiscovery']['cdp_exclude']['platform_regexp'][] = '/^Cisco IP Phone/'; //Cisco IP Phone\n
      "},{"location":"Extensions/Auto-Discovery/#ospf","title":"OSPF","text":"

      Enabled by default.

      $config['autodiscovery']['ospf'] = false; to disable.

      "},{"location":"Extensions/Auto-Discovery/#bgp","title":"BGP","text":"

      Enabled by default.

      $config['autodiscovery']['bgp'] = false; to disable.

      This module is invoked from bgp-peers discovery module.

      "},{"location":"Extensions/Auto-Discovery/#snmp-scan","title":"SNMP Scan","text":"

      Apart from the aforementioned Auto-Discovery options, LibreNMS is also able to proactively scan a network for SNMP-enabled devices using the configured version/credentials.

      SNMP Scan will scan nets by default and respects autodiscovery.nets-exclude.

      To run the SNMP-Scanner you need to execute the snmp-scan.py from within your LibreNMS installation directory.

      Here the script's help-page for reference:

      usage: snmp-scan.py [-h] [-t THREADS] [-g GROUP] [-l] [-v] [--ping-fallback] [--ping-only] [-P] [network ...]\n\nScan network for snmp hosts and add them to LibreNMS.\n\npositional arguments:\n  network          CIDR noted IP-Range to scan. Can be specified multiple times\n                   This argument is only required if 'nets' config is not set\n                   Example: 192.168.0.0/24\n                   Example: 192.168.0.0/31 will be treated as an RFC3021 p-t-p network with two addresses, 192.168.0.0 and 192.168.0.1\n                   Example: 192.168.0.1/32 will be treated as a single host address\n\noptional arguments:\n  -h, --help       show this help message and exit\n  -t THREADS       How many IPs to scan at a time.  More will increase the scan speed, but could overload your system. Default: 32\n  -g GROUP         The poller group all scanned devices will be added to. Default: The first group listed in 'distributed_poller_group', or 0 if not specificed\n  -l, --legend     Print the legend.\n  -v, --verbose    Show debug output. Specifying multiple times increases the verbosity.\n  --ping-fallback  Add the device as an ICMP only device if it replies to ping but not SNMP.\n  --ping-only      Always add the device as an ICMP only device.\n  -P, --ping       Deprecated. Use --ping-fallback instead.\n
      "},{"location":"Extensions/Auto-Discovery/#discovered-devices","title":"Discovered devices","text":"

      Newly discovered devices will be added to the default_poller_group, this value defaults to 0 if unset.

      When using distributed polling, this value can be changed locally by setting $config['default_poller_group'] in config.php or globally by using lnms config:set.

      "},{"location":"Extensions/Availability-Map/","title":"Availability Map","text":"

      LibreNMS has the following page to show an availability map:

      • Overview -> Maps -> Availability

      This map will show all devices on a single page, with each device having either a box or a coloured square representing its status.

      "},{"location":"Extensions/Availability-Map/#widget","title":"Widget","text":"

      There is an availability map widget that can be added to a dashboard to give a quick overview of the status of all devices on the network.

      "},{"location":"Extensions/Availability-Map/#settings","title":"Settings","text":"
      # Set the compact view mode for the availability map\nlnms config:set webui.availability_map_compact false\n\n# Size of the box for each device in the availability map (not compact)\nlnms config:set webui.availability_map_box_size 165\n\n# Sort by status instead of hostname\nlnms config:set webui.availability_map_sort_status false\n\n# Show the device group drop-down on the availabiltiy map page\nlnms config:set webui.availability_map_use_device_groups true\n
      "},{"location":"Extensions/Billing-Module/","title":"Billing Module","text":"

      With the billing module you can create a bill, assign a quota to it and add ports to it. It then tracks the ports usage and shows you the usage in the bill, including any overage. Accounting by both total transferred data and 95th percentile is supported.

      To enable and use the billing module you need to perform the following steps:

      Edit config.php and add (or enable) the following line near the end of the config

      $config['enable_billing'] = 1; # Enable Billing\n

      Edit /etc/cron.d/librenms and add the following:

      */5 * * * * librenms /opt/librenms/poll-billing.php >> /dev/null 2>&1\n01  * * * * librenms /opt/librenms/billing-calculate.php >> /dev/null 2>&1\n

      Create billing graphs as required.

      "},{"location":"Extensions/Billing-Module/#data-retention","title":"Data Retention","text":"

      Billing data is stored in the MySQL database, and you may wish to purge the detailed stats for old data (per-month totals will always be kept). To enable this, add the following to config.php:

      $config['billing_data_purge'] = 12;     // Number of months to retain\n

      Data for the last complete billing cycle will always be retained - only data older than this by the configured number of months will be removed. This task is performed in the daily cleanup tasks.

      "},{"location":"Extensions/Billing-Module/#95th-percentile-calculation","title":"95th Percentile Calculation","text":"

      For 95th Percentile billing, the default behavior is to use the highest of the input or output 95th Percentile calculation.

      To instead use the combined total of inout + output to derive the 95th percentile, This can be changed on a per bill basis by setting 95th Calculation to \"Aggregate\".

      To change the default option to Aggregate, add the following the config.php:

      $config['billing']['95th_default_agg'] = 1;  // Set aggregate 95th as default\n

      This configuration setting is cosmetic and only changes the default selected option when adding a new bill.

      "},{"location":"Extensions/Component/","title":"About","text":"

      The Component extension provides a generic database storage mechanism for discovery and poller modules. The Driver behind this extension was to provide the features of ports, in a generic manner to discovery/poller modules.

      It provides a status (Nagios convention), the ability to Disable (do not poll), or Ignore (do not Alert).

      "},{"location":"Extensions/Component/#database-structure","title":"Database Structure","text":"

      The database structure contains the component table:

      mysql> select * from component limit 1;\n+----+-----------+------+------------+--------+----------+--------+-------+\n| id | device_id | type | label      | status | disabled | ignore | error |\n+----+-----------+------+------------+--------+----------+--------+-------+\n|  9 |         1 | TEST | TEST LABEL |      0 |        1 |      1 |       |\n+----+-----------+------+------------+--------+----------+--------+-------+\n1 row in set (0.00 sec)\n

      These fields are described below:

      • id - ID for each component, unique index
      • device_id - device_id from the devices table
      • type - name from the component_type table
      • label - Display label for the component
      • status - The status of the component, retrieved from the device
      • disabled - Should this component be polled?
      • ignore - Should this component be alerted on
      • error - Error message if in Alert state

      The component_prefs table holds custom data in an Attribute/Value format:

      mysql> select * from component_prefs limit 1;\n+----+-----------+-----------+-----------+\n| id | component | attribute | value     |\n+----+-----------+-----------+-----------+\n|  4 |         9 | TEST_ATTR | TEST_ATTR |\n+----+-----------+-----------+-----------+\n2 rows in set (0.00 sec)\n
      "},{"location":"Extensions/Component/#reserved-fields","title":"Reserved Fields","text":"

      When this data from both the component and component_prefs tables is returned in one single consolidated array, there is the potential for someone to attempt to set an attribute (in the component_prefs) table that is used in the component table. Because of this all fields of the component table are reserved, they cannot be used as custom attributes, if you update these the module will attempt to write them to the component table, not the component_prefs table.

      "},{"location":"Extensions/Component/#using-components","title":"Using Components","text":"

      Create an instance of the component class:

      $COMPONENT = new LibreNMS\\Component();\n
      "},{"location":"Extensions/Component/#retrieving-components","title":"Retrieving Components","text":"

      Now you can retrieve an array of the available components:

      $ARRAY = $COMPONENT->getComponents($DEVICE_ID, $OPTIONS);\n

      getComponents takes 2 arguments:

      • DEVICE_ID or null for all devices.
      • OPTIONS - an array of various options.

      getComponents will return an array containing components in the following format:

      Array\n(\n    [X] => Array\n    (\n        [Y1] => Array\n        (\n            [device_id] => 1\n            [TEST_ATTR] => TEST_ATTR\n            [type] => TEST\n            [label] => TEST LABEL\n            [status] => 0\n            [ignore] => 1\n            [disabled] => 1\n            [error] =>\n        ),\n        [Y2] => Array\n        (\n            [device_id] => 1\n            [TEST_ATTR] => TEST_ATTR\n            [type] => TESTING\n            [label] => TEST LABEL\n            [status] => 0\n            [ignore] => 1\n            [disabled] => 0\n            [error] =>\n        ),\n    )\n)\n

      Where X is the Device ID and Y1/Y2 is the Component ID. In the example above, TEST_ATTR is a custom field, the rest are reserved fields.

      "},{"location":"Extensions/Component/#options","title":"Options","text":"

      Options can be supplied to getComponents to influence which and how components are returned.

      "},{"location":"Extensions/Component/#filtering","title":"Filtering","text":"

      You can filter on any of the reserved fields. Filters are created in the following format:

      $options['filter']['FIELD'] = array ('OPERATOR', 'CRITERIA');\n

      Where:

      • FIELD - The reserved field to filter on
      • OPERATOR - 'LIKE' or '=', are we checking if the FIELD equals or contains the CRITERIA.
      • CRITERIA - The criteria to search on

      There are 2 filtering shortcuts:

      $DEVICE_ID is a synonym for:

      $OPTIONS['filter']['device_id'] = array ('=', $DEVICE_ID);\n

      $OPTIONS['type'] = $TYPE is a synonym for:

      $OPTIONS['filter']['type'] = array ('=', $TYPE);\n
      "},{"location":"Extensions/Component/#sorting","title":"Sorting","text":"

      You can sort the records that are returned by specifying the following option:

      $OPTIONS['sort'][FIELD] = 'DIRECTION';\n

      Where Direction is one of:

      • ASC - Ascending, from Low to High
      • DESC - Descending, from High to Low
      "},{"location":"Extensions/Component/#creating-components","title":"Creating Components","text":"

      To create a new component, run the createComponent function.

      $ARRAY = $COMPONENT->createComponent($DEVICE_ID, $TYPE);\n

      createComponent takes 2 arguments:

      • DEVICE_ID - The ID of the device to attach the component to.
      • TYPE - The unique type for your module.

      This will return a new, empty array with a component ID and Type set, all other fields will be set to defaults.

      Array\n(\n    [1] => Array\n    (\n        [type] => TESTING\n        [label] =>\n        [status] => 1\n        [ignore] => 0\n        [disabled] => 0\n        [error] =>\n    )\n)\n
      "},{"location":"Extensions/Component/#deleting-components","title":"Deleting Components","text":"

      When a component is no longer needed, it can be deleted.

      $COMPONENT->deleteComponent($COMPONENT_ID)\n

      This will return True on success or False on failure.

      "},{"location":"Extensions/Component/#editing-components","title":"Editing Components","text":"

      To edit a component, the procedure is:

      1. Get the Current Components
      2. Edit the array
      3. Write the components
      "},{"location":"Extensions/Component/#edit-the-array","title":"Edit the Array","text":"

      Once you have a component array from getComponents the first thing to do is extract the components for only the single device you are editing. This is required because the setComponentPrefs function only saves a single device at a time.

      $ARRAY = $COMPONENT->getComponents($DEVICE_ID, $OPTIONS);\n$ARRAY = $ARRAY[$DEVICE_ID];\n

      Then simply edit this array to suit your needs. If you need to add a new Attribute/Value pair you can:

      $ARRAY[COMPONENT_ID]['New Attribute'] = \"Value\";\n

      If you need to delete a previously set Attribute/Value pair you can:

      unset($ARRAY[COMPONENT_ID]['New Attribute']);\n

      If you need to edit a previously set Attribute/Value pair you can:

      $ARRAY[COMPONENT_ID]['Existing Attribute'] = \"New Value\";\n
      "},{"location":"Extensions/Component/#write-the-components","title":"Write the components","text":"

      To write component changes back to the database simply:

      $COMPONENT->setComponentPrefs($DEVICE_ID, $ARRAY)\n

      When writing the component array there are several caveats to be aware of, these are:

      • $ARRAY must be in the format of a single device ID - $ARRAY[$COMPONENT_ID][Attribute] = 'Value'; NOT in the multi device format returned by getComponents - $ARRAY[$DEVICE_ID][$COMPONENT_ID][Attribute] = 'Value';
      • You cannot edit the Component ID or the Device ID
      • reserved fields can not be removed
      • if a change is found an entry will be written to the eventlog.
      "},{"location":"Extensions/Component/#api","title":"API","text":"

      Component details are available via the API. Please see the API-Docs for details.

      "},{"location":"Extensions/Component/#alerting","title":"Alerting","text":"

      It is intended that discovery/poller modules will detect the status of a component during the polling cycle. Status is logged using the Nagios convention for status codes, where:

      0 = Ok,\n1 = Warning,\n2 = Critical\n

      If you are creating a poller module which can detect a fault condition simply set STATUS to something other than 0 and ERROR to a message that indicates the problem.

      To actually raise an alert, the user will need to create an alert rule. To assist with this several Alerting Macro's have been created:

      • %macro.component_normal - A component that is not disabled or ignored and in a Normal state.
      • %macro.component_warning - A component that is not disabled or ignored and NOT in a Warning state.
      • %macro.component_critical - A component that is not disabled or ignored and NOT in a Critical state.

      To raise alerts for components, the following rules could be created:

      • %macros.component_critical = \"1\" - To alert on all Critical components
      • %macros.component_critical = \"1\" && %component.type = \"<Type of Component>\" - To alert on all Critical components of a particular type.

      If there is a particular component you would like excluded from alerting, simply set the ignore field to 1.

      The data that is written to each alert when it is raised is in the following format:

      COMPONENT_TYPE - LABEL - ERROR

      "},{"location":"Extensions/Component/#example-code","title":"Example Code","text":"

      To see an example of how the component module can used, please see the following modules:

      • Cisco CBQoS
      • includes/discovery/cisco-cbqos.inc.php
      • includes/polling/cisco-cbqos.inc.php
      • html/includes/graphs/device/cbqos_traffic.inc.php
      • Cisco OTV
      • includes/discovery/cisco-otv.inc.php
      • includes/polling/cisco-otv.inc.php
      • html/includes/graphs/device/cisco-otv-mac.inc.php
      • html/pages/routing/cisco-otv.inc.php
      "},{"location":"Extensions/Custom-Map/","title":"Custom Map","text":"

      LibreNMS has the ability to create custom maps to give a quick overview of parts of the network including up/down status of devices and link utilisation. These are also referred to as weather maps.

      "},{"location":"Extensions/Custom-Map/#viewer","title":"Viewer","text":"

      Once some maps have been created, they will be visible to any users who have read access to all devices on a given map. Custom maps are available through the Overview -> Maps -> Custom Maps menu.

      Some key points about the viewer are:

      • Nodes will change colour if they are down or disabled
      • Links are only associated with a single network interface
      • Link utilisation can only be shown if the link speed is known
      • Link speed is decoded from SNMP if possible (Upload/Download) and defaults to the physical speed if SNMP data is not available, or cannot be decoded
      • Links will change colour as follows:
      • Black if the link is down, or the max speed is unknown
      • Green at 0% utilisation, with a gradual change to
      • Yellow at 50% utilisation, with a gradual change to
      • Orange at 75% utilisation, with a gradual change to
      • Red at 100% utilisation, with a gradual change to
      • Purple at 150% utilisation and above
      "},{"location":"Extensions/Custom-Map/#viewer-url-options","title":"Viewer URL options","text":"

      You can manually add the following parameters to a URL to alter the display of a custom map.

      The following URL options are available:

      • bare=yes : Removes the control bar from the top of the page.
      • screenshot=yes : Removes all labels from the nodes and links

      e.g. If you want bare and screenshot enabled, https://nmsserver/maps/custom/2 becomes https://nmsserver/maps/custom/2?bare=yes&screenshot=yes

      "},{"location":"Extensions/Custom-Map/#editor","title":"Editor","text":"

      To access the custom map editor, a user must be an admin. The editor is accessed through the Overview -> Maps -> Custom Map Editor menu.

      Once you are in the editor, you will be given a drop-down list of all the custom maps so you can choose one to edit, or select \"Create New Map\" to create a new map.

      "},{"location":"Extensions/Custom-Map/#map-settings","title":"Map Settings","text":"

      When you create a new map, you will be presented with a page to set some global map settings. These are:

      • Name: The name for the map
      • Width: The width of the map in pixels
      • Height: The height of the map in pixels
      • Node Alignment: When devices are added to the map, this will align the devices to an invisible grid this many pixels wide, which can help to make the maps look better. This can be set to 0 to disable.
      • Background: An image (PNG/JPG) up to 2MB can be uploaded as a background.

      These settings can be changed at any stage by clicking on the \"Edit Map Settings\" button in the top-left of the editor.

      "},{"location":"Extensions/Custom-Map/#nodes","title":"Nodes","text":"

      Once you have a map, you can start by adding \"nodes\" to the map. A node represents a device, or an external point in the network (e.g. the internet) To add a node, you click on the \"Add Node\" button in the control bar, then click on the map area where you want to add the node. You will then be aked for the following information:

      • Label: The text to display on this point in the network
      • Device: If this node represents a device, you can select the device from the drop-down. This will overwrite the label, which you can then change if you want to.
      • Style: You can select the style of the node. If a device has been selected you can choose the LibreNMS icon by choosing \"Device Image\". You can also choose \"Icon\" to select an image for the device.
      • Icon: If you choose \"Icon\" in the style box, you can select from a list of images to represent this node

      There are also options to choose the size and colour of the node and the font.

      Once you have finished choosing the options for the node, you can press Save to add it to the map. NOTE: This does not save anything to the database immediately. You need to click on the \"Save Map\" button in the top-right to save your changes to the database.

      You can edit a node at any time by selecting it on the map and clicking on the \"Edit Node\" button in the control bar.

      You can also modify the default settings for all new nodes by clicking on the \"Edit Node Default\" button at the top of the page.

      "},{"location":"Extensions/Custom-Map/#edges","title":"Edges","text":"

      Once you have 2 or more nodes, you can add links between the nodes. These are called edges in the editor. To add a link, click on the \"Add Edge\" button in the control bar, then click on one of the nodes you want to link and drag the cursor to the second node that you want to link. You will then be prompted for the following information:

      • From: The node that the link runs from (it will default to first node you selected)
      • To: The node that the link runs to (it will default to the second node you selected)
      • Port: If the From or To node is linked to a device, you can select an interface from one of the devices and the custom map will show traffic utilisation for the selected interface.
      • Reverse Port Direction: If the selected port displays data in the wrong direction for the link, you can reverse it by toggling this option.
      • Line Style: You can try different line styles, especially if you are running multiple links between the same 2 nodes
      • Show percent usage: Choose whether to have text on the lines showing the link utilisation as a percentage
      • Recenter Line: If you tick this box, the centre point of the line will be moved back to half way between the 2 nodes when you click on the save button.

      Once you have finished choosing the options for the node, you can press Save to add it to the map. NOTE: This does not save anything to the database immediately. You need to click on the \"Save Map\" button in the top-right to save your changes to the database.

      Once you press save, you it will create 3 objects on the screen, 2 arrows and a round node in the middle. Having the 3 objects allows you to move the mid point of the line off centre, and also allows us to display bandwidth information for both directions of the link.

      You can edit an edge at any time by selecting it on the map and clicking on the \"Edit Edge\" button in the control bar.

      You can also modify the default settings for all new edges by clicking on the \"Edit Edge Default\" button at the top of the page.

      "},{"location":"Extensions/Custom-Map/#re-render","title":"Re-Render","text":"

      When you drag items around the map, some of the lines will bend. This will cause a \"Re-Render Map\" button to appear at the top-right of the page. This button can be clicked on to cause all lines to be re-drawn the way they will be shown in the viewer.

      "},{"location":"Extensions/Custom-Map/#save-map","title":"Save Map","text":"

      Once you are happy with a set of changes that you have made, you can click on the \"Save Map\" button in the top-right of the page to commit changes to the database. This will cause anyone viewing the map to see the new version the next time their page refreshes.

      "},{"location":"Extensions/Custom-Map/#adding-images","title":"Adding Images","text":"

      You can add your own images to use on the custom map by copying files into the html/images/custommap/icons/ directory. Any files with a .svg, .png or .jpg extension will be shown in the image selection drop-down in the custom map editor.

      "},{"location":"Extensions/Customizing-the-Web-UI/","title":"Customizing the Web UI","text":""},{"location":"Extensions/Customizing-the-Web-UI/#custom-menu-entry","title":"Custom menu entry","text":"

      Create the file resources/views/menu/custom.blade.php

      Example contents:

      <li class=\"dropdown\">\n    <a href=\"#\" class=\"dropdown-toggle\" data-hover=\"dropdown\" data-toggle=\"dropdown\"><i class=\"fa fa-star fa-fw fa-lg fa-nav-icons hidden-md\" aria-hidden=\"true\"></i>\n        <span class=\"hidden-sm\">Custom Menu</span></a>\n    <ul class=\"dropdown-menu\">\n        @admin\n            <li><a href=\"plugins/Weathermap/output/history/index.html\"><i class=\"fa fa-film fa-fw fa-lg\" aria-hidden=\"true\"></i> Weathermap Animation</a></li>\n            <li role=\"presentation\" class=\"divider\"></li>\n            <li><a href=\"#\"><i class=\"fa fa-database fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 1</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-smile-o fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 2</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-anchor fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 3</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-plug fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 4</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-code-fork fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 5</a></li>\n            <li><a href=\"#\"><i class=\"fa fa-truck fa-fw fa-lg\" aria-hidden=\"true\"></i> Item 63</a></li>\n        @else\n            <li><a href=\"#\">You need admin rights to see this</a></li>\n        @endadmin\n    </ul>\n</li>\n
      "},{"location":"Extensions/Customizing-the-Web-UI/#custom-device-menu-action","title":"Custom device menu action","text":"

      You can add custom external links in the menu on the device page.

      This feature allows you to easily link applications to related systems, as shown in the example of Open-audIT.

      The url value is parsed by the Laravel Blade templating engine. You can access device variables such as $device->hostname, $device->sysName and use full PHP.

      settings/webui/device

      lnms config:set html.device.links.+ '{\"url\": \"http://atssrv/open-audit/index/devices/{{ $device->sysName }}\", \"title\": \"Open-AudIT\"}'\n
      Field Description url Url blade template resulting in valid url. Required. title Title text displayed in the menu. Required. icon Font Awesome icon class. Default: fa-external-link external Open link in new window. Default: true action Show as action on device list. Default: false"},{"location":"Extensions/Customizing-the-Web-UI/#launching-windows-programs-from-the-librenms-device-menu","title":"Launching Windows programs from the LibreNMS device menu","text":"

      You can launch windows programs from links in LibreNMS, but it does take some registry entries on the client device. Save the following as winbox.reg, edit for your winbox.exe path and double click to add to your registry.

      Windows Registry Editor Version 5.00\n[HKEY_CLASSES_ROOT\\winbox]\n@=\"URL:Winbox Protocol\"\n\"URL Protocol\"=\"\"\n[HKEY_CLASSES_ROOT\\winbox\\shell]\n[HKEY_CLASSES_ROOT\\winbox\\shell\\open]\n[HKEY_CLASSES_ROOT\\winbox\\shell\\open\\command]\n@=\"C:\\Windows\\System32\\WindowsPowerShell\u000b1.0\\powershell.exe -Command \"$val='%l'; $val = $val.TrimEnd('/');if ($val.StartsWith('winbox://' { $val = $val.SubString(9) }; & 'C:\\Program Files\\winbox64.exe' \"$val\"\"\"\n

      Now we can use that in the device menu entry to open winbox.

      settings/webui/device

      lnms config:set html.device.links.+ '{\"url\": \"winbox://{{ $device->hostname }}\", \"title\": \"Winbox\"}'\n
      "},{"location":"Extensions/Customizing-the-Web-UI/#setting-the-primary-device-menu-action","title":"Setting the primary device menu action","text":"

      You can change the icon that is clickable in the device without having to open the dropdown menu. The primary button is edit device by default.

      settings/webui/device

      lnms config:set html.device.primary_link web\n
      Value Description edit Edit device web Connect to the device via https/http ssh launch ssh:// protocol to the device, make sure you have a handler registered telnet launch telnet:// protocol to the device capture Link to the device capture page custom1 Custom Link 1 custom2 Custom Link 2 custom3 Custom Link 3 custom4 Custom Link 4 custom5 Custom Link 5 custom6 Custom Link 6 custom7 Custom Link 7 custom8 Custom Link 8

      !!! Custom http, ssh, telnet ports

      Custom ports can be set through the device setting misc tab and will be appended to the Uri. Empty value will not append anything and automatically default to the standard. - custom ssh port set to 2222 will result in ssh://10.0.0.0:2222 - custom telnet port set to 2323 will result in telnet://10.0.0.0:2323

      "},{"location":"Extensions/Dashboards/","title":"Dashboards","text":"

      Create customised dashboards in LibreNMS per user. You can share dashboards with other users. You can also make a custom dashboard and default it for all users in LibreNMS.

      Example Dashboard

      "},{"location":"Extensions/Dashboards/#widgets","title":"Widgets","text":"

      LibreNMS has a whole list of Widgets to select from.

      • Alerts Widget: Displays all alert notifications.
      • Availability Map: Displays all devices with colored tiles, green up, yellow for warning (device has been restarted in last 24 hours), red for down. You can also list all services and ignored/disabled devices in this widget.
      • Components Status: List all components Ok state, Warning state, Critical state.
      • Device Summary horizontal: List device totals, up, down, ignored, disabled. Same for ports and services.
      • Device Summary vertical: List device totals, up, down, ignored, disabled. Same for ports and services.
      • Eventlog: Displays all events with your devices and LibreNMS.
      • External Image: can be used to show external images on your dashboard. Or images from inside LibreNMS.
      • Globe Map: Will display map of the globe.
      • Graph: Can be used to display graphs from devices.
      • Graylog: Displays all Graylog's syslog entries.
      • Notes: use for html tags, embed links and external web pages. Or just notes in general.
      • Server Stats: Will display gauges for CPU, Memory, Storage usage. Note the device type has to be listed as \"Server\".
      • Syslog: Displays all syslog entries.
      • Top Devices: By Traffic, or Uptime, or Response time, or Poller Duration, or Processor load, or Memory Usage, or Storage Usage.
      • Top Interfaces: Lists top interfaces by traffic utilization.
      • World Map: displays all your devices locations. From syslocation or from override sysLocation.

      List of Widgets:

      "},{"location":"Extensions/Dashboards/#dashboard-permissions","title":"Dashboard Permissions","text":"
      • Private: Sets the dashboard to only the user that created the dashboard can view and edit.
      • Shared Read: Sets the dashboard to allow other users to view the dashboard, but cant make changes to the dashboard.
      • Shared: Allows all users to view the dashboard and make changes.
      "},{"location":"Extensions/Dashboards/#setting-a-global-default-dashboard","title":"Setting a global default dashboard","text":"

      Step 1: Set the dashboard to either shared read or shared, depending on what you want the users access to change.

      Step 2: Then go to Settings -> WebUI settings -> Dashboard Settings and set the global default dashboard.

      "},{"location":"Extensions/Dashboards/#setting-embedded-webpage","title":"Setting embedded webpage","text":"

      Using the Notes Widget.

      <iframe src=\"your_url\" frameBorder=\"0\" width=\"100%\" height = \"100%\">\n  <p>Your browser does not support iframes.</p>\n</iframe>\n

      Note you may need to play with the width and height and also size your widget properly.

      src=\"url\" needs to be URL to webpage you are linking to. Also some web pages may not support html embedded or iframe.

      "},{"location":"Extensions/Dashboards/#how-to-create-ports-graph","title":"How to create ports graph","text":"

      In the dashboard, you want to create an interface graph select the widget called

      'Graph' then select \"Port\" -> \"Bits\"

      Note: you can map the port by description or the alias or by port id. You will need to know this in order to map the port to the graph.

      "},{"location":"Extensions/Dashboards/#dimension-parameter-replacement-for-generic-image-widget","title":"Dimension parameter replacement for Generic-image widget","text":"

      When using the Generic-image widget you can provide the width and height of the widget with your request. This will ensure that the image will fit nicely with the dimensions if the Generic-image widget. You can add @AUTO_HEIGHT@ and @AUTO_WIDTH@ to the Image URL as parameters.

      Examples:

      • http://librenms.example.com/graph.php?id=333%2C444&type=multiport_bits_separate&legend=no&absolute=1&from=-14200&width=@AUTO_WIDTH@&height=@AUTO_HEIGHT@
      • http://example.com/myimage.php?size=@AUTO_WIDTH@x@AUTO_HEIGHT@
      "},{"location":"Extensions/Dell-OpenManage/","title":"Dell OpenManage Support","text":"

      For Dell OpenManage support you will need to install Dell OpenManage (yeah - really :)) (minimum 5.1) onto the device you want to monitor. Ensure that net-snmp is using srvadmin, you should see something similar to:

      master agentx\nview all included .1\naccess notConfigGroup \"\" any noauth exact all none none\nsmuxpeer .1.3.6.1.4.1.674.10892.1\n

      Restart net-snmp:

      service snmpd restart\n

      Ensure that srvadmin is started, this is usually done by executing:

      /opt/dell/srvadmin/sbin/srvadmin-services.sh start\n

      Once this has been done, add the device to LibreNMS as normal and you will start to receive Temperatures and Fan speed data.

      "},{"location":"Extensions/Dell-OpenManage/#windows","title":"Windows","text":"

      Download OpenManage from Dell's support page Link and install OpenManage on your windows server. Make sure you have SNMP setup and running on your windows server.

      "},{"location":"Extensions/Dependency-Map/","title":"Dependency Map","text":"

      LibreNMS has the ability to show you a dynamic network map based on device dependencies that have been configure. These maps are accessed through the following menu options:

      • Overview -> Maps -> Device Dependency
      • Overview -> Maps -> Device Groups Dependencies
      "},{"location":"Extensions/Dependency-Map/#settings","title":"Settings","text":"

      The map display can be configured by altering the VisJS-Config.md

      "},{"location":"Extensions/Device-Groups/","title":"Grouping Devices","text":"

      LibreNMS supports grouping your devices together in much the same way as you can configure alerts. This document will hopefully help you get started.

      "},{"location":"Extensions/Device-Groups/#dynamic-groups","title":"Dynamic Groups","text":""},{"location":"Extensions/Device-Groups/#rule-editor","title":"Rule Editor","text":"

      The rule is based on the MySQL structure your data is in. Such as tablename.columnname. If you already know the entity you want, you can browse around inside MySQL using show tables and desc <tablename>.

      As a working example and a common question, let's assume you want to group devices by hostname. If your hostname format is dcX.[devicetype].example.com. You would use the field devices.hostname.

      If you want to group them by device type, you would add a rule for routers of devices.hostname endswith rtr.example.com.

      If you want to group them by DC, you could use the rule devices.hostname regex dc1\\..*\\.example\\.com (Don't forget to escape periods in the regex)

      "},{"location":"Extensions/Device-Groups/#static-groups","title":"Static Groups","text":"

      You can create static groups (and convert dynamic groups to static) to put specific devices in a group. Just select static as the type and select the devices you want in the group.

      You can now select this group from the Devices -> All Devices link in the navigation at the top. You can also use the group to map alert rules to by creating an alert mapping Overview -> Alerts -> Rule Mapping.

      "},{"location":"Extensions/Dispatcher-Service/","title":"Dispatcher Service","text":"

      Status: Release Candidate

      The LibreNMS dispatcher service (librenms-service.py) is a new method of running the poller service at set times. It does not replace the php scripts, just the cron entries running them.

      "},{"location":"Extensions/Dispatcher-Service/#external-requirements","title":"External Requirements","text":""},{"location":"Extensions/Dispatcher-Service/#a-recent-version-of-python","title":"A recent version of Python","text":"

      The LibreNMS service requires Python 3 and some features require behaviour only found in Python3.4+.

      "},{"location":"Extensions/Dispatcher-Service/#python-modules","title":"Python modules","text":"
      • PyMySQL is recommended as it requires no C compiler to install. MySQLclient can also be used, but does require compilation.
      • python-dotenv .env loader
      • redis-py 4.0+ and Redis 5.0+ server (if using distributed polling)
      • psutil

      These can be obtained from your OS package manager, or from PyPI with the below commands.

      pip3 install -r requirements.txt\n
      "},{"location":"Extensions/Dispatcher-Service/#redis-distributed-polling","title":"Redis (distributed polling)","text":"

      If you want to use distributed polling, you'll need a Redis instance to coordinate the nodes. It's recommended that you do not share the Redis database with any other system - by default, Redis supports up to 16 databases (numbered 0-15). You can also use Redis on a single host if you want

      It's strongly recommended that you deploy a resilient cluster of redis systems, and use redis-sentinel.

      You should not rely on the password for the security of your system. See https://redis.io/topics/security

      "},{"location":"Extensions/Dispatcher-Service/#memcached-distributed-polling","title":"Memcached (distributed polling)","text":"

      LibreNMS can still use memcached as a locking mechanism when using distributed polling. So you can configure memcached for this purpose unless you have updates disabled.

      See Locking Mechanisms at https://docs.librenms.org/Extensions/Distributed-Poller/

      "},{"location":"Extensions/Dispatcher-Service/#mysql","title":"MySQL","text":"

      You should already have this, but the pollers do need access to the SQL database. The LibreNMS service runs faster and more aggressively than the standard poller, so keep an eye on the number of open connections and other important health metrics.

      "},{"location":"Extensions/Dispatcher-Service/#configuration","title":"Configuration","text":"

      Connection settings are required in .env. The .env file is generated after composer install and APP_KEY and NODE_ID are set. Remember that the APP_KEY value must be the same on all your pollers.

      #APP_KEY=   #Required, generated by composer install\n#NODE_ID=   #Required, generated by composer install\n\nDB_HOST=localhost\nDB_DATABASE=librenms\nDB_USERNAME=librenms\nDB_PASSWORD=\n
      "},{"location":"Extensions/Dispatcher-Service/#distributed-polling-configuration","title":"Distributed Polling Configuration","text":"

      Once you have your Redis database set up, configure it in the .env file on each node. Configure the redis cache driver for distributed locking.

      There are a number of options - most of them are optional if your redis instance is standalone and unauthenticated (neither recommended).

      ##\n## Standalone\n##\nREDIS_HOST=127.0.0.1\nREDIS_PORT=6379\nREDIS_DB=0\nREDIS_TIMEOUT=60\n\n# If requirepass is set in redis set everything above as well as: (recommended)\nREDIS_PASSWORD=PasswordGoesHere\n\n# If ACL's are in use, set everything above as well as: (highly recommended)\nREDIS_USERNAME=UsernameGoesHere\n\n##\n## Sentinel\n##\nREDIS_SENTINEL=redis-001.example.org:26379,redis-002.example.org:26379,redis-003.example.org:26379\nREDIS_SENTINEL_SERVICE=mymaster\n\n# If requirepass is set in sentinel, set everything above as well as: (recommended)\nREDIS_SENTINEL_PASSWORD=SentinelPasswordGoesHere\n\n# If ACL's are in use, set everything above as well as: (highly recommended)\nREDIS_SENTINEL_USERNAME=SentinelUsernameGoesHere\n

      For more information on ACL's, see https://redis.io/docs/management/security/acl/

      Note that if you use Sentinel, you may still need REDIS_PASSWORD, REDIS_USERNAME, REDIS_DB and REDIS_TIMEOUT - Sentinel just provides the address of the instance currently accepting writes and manages failover. It's possible (and recommended) to have authentication both on Sentinel and the managed Redis instances.

      "},{"location":"Extensions/Dispatcher-Service/#basic-configuration","title":"Basic Configuration","text":"

      Additional configuration settings can be set in your config.

      The defaults are shown here - it's recommended that you at least tune the number of workers.

      poller/distributed

      lnms config:set service_poller_workers 24\nlnms config:set service_services_workers 8\nlnms config:set service_discovery_workers 16\n

      Optional Settings

      poller/distributed

      lnms config:set service_poller_frequency 300\nlnms config:set service_services_frequency 300\nlnms config:set service_discovery_frequency 21600\nlnms config:set service_billing_frequency 300\nlnms config:set service_billing_calculate_frequency 60\nlnms config:set service_poller_down_retry 60\nlnms config:set service_loglevel INFO\nlnms config:set service_update_frequency 86400\n

      There are also some SQL options, but these should be inherited from your LibreNMS web UI configuration.

      Logs are sent to the system logging service (usually journald or rsyslog) - see https://docs.python.org/3/library/logging.html#logging-levels for the options available.

      $config['distributed_poller']                    = true;            # Set to true to enable distributed polling\n$config['distributed_poller_name']               = php_uname('n');  # Uniquely identifies the poller instance\n$config['distributed_poller_group']              = 0;               # Which group to poll\n
      "},{"location":"Extensions/Dispatcher-Service/#tuning-the-number-of-workers","title":"Tuning the number of workers","text":"

      See https://your_librenms_install/poller

      You want to keep Consumed Worker Seconds comfortably below Maximum Worker Seconds. The closer the values are to each other, the flatter the CPU graph of the poller machine. Meaning that you are utilizing your CPU resources well. As long as Consumed WS stays below Maximum WS and Devices Pending is 0, you should be ok.

      If Consumed WS is below Maximum WS and Devices Pending is > 0, your hardware is not up to the task.

      Maximum WS equals the number of workers multiplied with the number of seconds in the polling period. (default 300)

      "},{"location":"Extensions/Dispatcher-Service/#fast-ping","title":"Fast Ping","text":"

      The fast ping scheduler is disabled by default. You can enable it by setting the following:

      $config['service_ping_enabled'] = true;\n
      "},{"location":"Extensions/Dispatcher-Service/#watchdog","title":"Watchdog","text":"

      The watchdog scheduler is disabled by default. You can enable it by setting the following:

      $config['service_watchdog_enabled'] = true;\n

      The watchdog scheduler will check that the poller log file has been written to within the last poll period. If there is no change to the log file since, the watchdog will restart the polling service. The poller log file is set by $config['log_file'] and defaults to ./logs/librenms.log

      "},{"location":"Extensions/Dispatcher-Service/#cron-scripts","title":"Cron Scripts","text":"

      Once the LibreNMS service is installed, the cron scripts used by LibreNMS to start alerting, polling, discovery and maintenance tasks are no longer required and must be disabled either by removing or commenting them out. The service handles these tasks when enabled.

      "},{"location":"Extensions/Dispatcher-Service/#service-installation","title":"Service Installation","text":"

      A systemd unit file is provided - You must adapt ExecStart and WorkingDirectory if you did not install librenms in /opt/librenms

      The sysv and upstart init scripts could also be used with a little modification.

      "},{"location":"Extensions/Dispatcher-Service/#systemd-service","title":"systemd service","text":"

      A systemd unit file can be found in misc/librenms.service. To install run:

      cp /opt/librenms/misc/librenms.service /etc/systemd/system/librenms.service && systemctl enable --now librenms.service\n

      "},{"location":"Extensions/Dispatcher-Service/#systemd-service-with-watchdog","title":"systemd service with watchdog","text":"

      This service file is an alternative to the above service file. It uses the systemd WatchdogSec= option to restart the service if it does not receive a keep-alive from the running process.

      A systemd unit file can be found in misc/librenms-watchdog.service. To install run:

      cp /opt/librenms/misc/librenms-watchdog.service /etc/systemd/system/librenms.service && systemctl enable --now librenms.service\n

      This requires: python3-systemd (or python-systemd on older systems) or https://pypi.org/project/systemd-python/ If you run this systemd service without python3-systemd it will restart every 30 seconds.

      "},{"location":"Extensions/Dispatcher-Service/#os-specific-instructions","title":"OS-Specific Instructions","text":""},{"location":"Extensions/Dispatcher-Service/#rhelcentos","title":"RHEL/CentOS","text":"

      To get the LibreNMS service running under python3.4+ on RHEL-derivatives with minimal fuss, you can use the software collections build:

      First, enable SCL's on your system:

      "},{"location":"Extensions/Dispatcher-Service/#centos-7","title":"CentOS 7","text":"
      # yum install centos-release-scl\n
      "},{"location":"Extensions/Dispatcher-Service/#rhel-7","title":"RHEL 7","text":"
      # subscription-manager repos --enable rhel-server-rhscl-7-rpms\n

      Then install and configure the runtime and service:

      # yum install gcc rh-python36 rh-python36-python-devel epel-release\n# yum --enablerepo=remi install redis\n# vi /opt/librenms/config.php\n# vi /etc/redis.conf\n# systemctl enable --now redis.service\n# scl enable rh-python36 bash\n# change directory to librenms (default /opt/librenms)\n# pip3 install -r requirements.txt\n# cp /opt/librenms/misc/librenms.service.scl /etc/systemd/system/librenms.service\n# systemctl enable --now librenms.service\n

      If you want to use another version of python 3, change rh-python36 in the unit file and the commands above to match the name of the replacement scl.

      "},{"location":"Extensions/Dispatcher-Service/#debianubuntu","title":"Debian/Ubuntu","text":""},{"location":"Extensions/Dispatcher-Service/#debian-11-bullseye","title":"Debian 11 (Bullseye)","text":"

      Warning: Bullseye provide PHP 7.4 that is too old to run LibreNMS.

      "},{"location":"Extensions/Dispatcher-Service/#debian-12-bookworm","title":"Debian 12 (Bookworm)","text":"

      Install dependancies

      apt install python3 python3-mysqldb python3-dotenv\n

      Add the python3-systemd package for service with watchdog.

      "},{"location":"Extensions/Distributed-Poller/","title":"Distributed Poller","text":"

      A normal install contains all parts of LibreNMS:

      • Poller/Discovery/etc workers
      • RRD (Time series data store) *
      • Database *
      • Webserver (Web UI/API) *

      * may only be installed on one server (however, some can be clustered)

      Distributed Polling allows the workers to be spread across additional servers for horizontal scaling. Distributed polling is not intended for remote polling.

      Devices can be grouped together into a poller_group to pin these devices to a single or a group of designated pollers.

      All pollers need to write to the same set of RRD files, preferably via RRDcached.

      It is also a requirement that at least one locking service is in place to which all pollers can connect. There are currently three locking mechanisms available

      • memcached
      • redis (preferred)
      • sql locks (default)

      All of the above locking mechanisms are natively supported in LibreNMS. If none are specified, it will default to using SQL.

      "},{"location":"Extensions/Distributed-Poller/#requirements-for-distributed-polling","title":"Requirements for distributed polling","text":"

      These requirements are above the normal requirements for a full LibreNMS install.

      • rrdtool version 1.4 or above
      • At least one locking mechanism configured
      • a rrdcached install

      By default, all hosts are shared and have the poller_group = 0. To pin a device to a poller, set it to a value greater than 0 and set the same value in the poller's config with distributed_poller_group. One can also specify a comma separated string of poller groups in distributed_poller_group. The poller will then poll devices from any of the groups listed. If new devices get added from the poller they will be assigned to the first poller group in the list unless the group is specified when adding the device.

      The following is a standard config, combined with a locking mechanism below:

      poller/distributed

      lnms config:set distributed_poller true\nlnms config:set distributed_poller_group 0\n

      If you want to customise the hostname for the poller then you will need to set this in config.php:

      $config['distributed_poller_name']           = php_uname('n');\n
      "},{"location":"Extensions/Distributed-Poller/#locking-mechanisms","title":"Locking mechanisms","text":"

      Pick one of the following setups, do not use all of them at the same time.

      "},{"location":"Extensions/Distributed-Poller/#using-redis","title":"Using REDIS","text":"

      In your .env file you will need to specify a redis server, port and the driver.

      REDIS_HOST=HOSTNAME or IP\nREDIS_PORT=6379\nCACHE_DRIVER=redis\n
      "},{"location":"Extensions/Distributed-Poller/#using-memcached","title":"Using Memcached","text":"

      Preferably you should set the memcached server settings via the web UI. Under Settings > Global Settings > Distributed poller, you fill out the memcached host and port, and then in your .env file you will need to add:

      CACHE_DRIVER=memcached\n
      If you want to use memcached, you will also need to install an additional Python 3 python-memcached package.

      "},{"location":"Extensions/Distributed-Poller/#example-setups","title":"Example Setups","text":""},{"location":"Extensions/Distributed-Poller/#openstack","title":"OpenStack","text":"

      Below is an example setup based on a real deployment which at the time of writing covers over 2,500 devices and 50,000 ports. The setup is running within an OpenStack environment with some commodity hardware for remote pollers. Here's a diagram of how you can scale LibreNMS out:

      "},{"location":"Extensions/Distributed-Poller/#esxi","title":"ESXi","text":"

      This is a distributed setup that I created for a regional hybrid ISP (fixed wireless/fiber optic backhaul). It was created at around the ~4,000 device mark to transition from multiple separate instances to one more central. When I left the company, it was monitoring: * 10,800 devices * 307,700 ports * 37,000 processors * 17,000 wireless sensors * ~480,000 other objects/sensors.

      As our goal was more to catch alerts and monitor overall trends we went with a 10 minute polling cycle. Polling the above would take roughly 8 minutes and 120GHz worth of CPU across all VMs. CPUs were older Xeons (E5). The diagram below shows the CPU and RAM utilization of each VM during polling. Disk space utilization for SQL/RRD is also included.

      Device discovery was split off into its own VM as that process would take multiple hours.

      Workers were assigned in the following way:

      • Web/RRD Server:
      • alerting: 1
      • billing: 2
      • discovery: 0
      • ping: 1
      • poller: 10
      • services: 16
      • Discovery Server:
      • alerting: 1
      • billing: 2
      • discovery: 60
      • ping: 1
      • poller: 5
      • services: 8
      • Pollers
      • alerting: 1
      • billing: 2
      • discovery: 0
      • ping: 1
      • poller: 40
      • services: 8

      Each poller had on average 19,500/24,000 worker seconds consumed.

      RRDCached is incredibly important; this setup ran on spinning disks due to the wonders of caching.

      I very strongly recommend setting up recursive DNS on your discovery and polling servers. While I used DNSMASQ there are many options.

      SQL tuner will help you quite a bit. You'll also want to increase your maximum connections amount to support the pollers. This setup was at 500. Less important, but putting ~12GB of the database in RAM was reported to have helped web UI performance as well as some DB-heavy Tableau reports. RAM was precious in this environment or it would've been more, but it wasn't necessary either.

      Be careful with keeping the default value for 'Device Down Retry' as it can eat up quite a lot of poller activity. I freed up over 20,000 worker seconds when setting this to only happen once or twice per 10-minute polling cycle. The impact of this will vary depending on the percentage of down device in your system. This example had it set at 400 seconds.

      Also be wary of keeping event log and syslog entries for too long as it can have a pretty negative effect on web UI performance.

      To resolve an issue with large device groups the php fpm max input vars was increased to 20000.

      All of these VMs were within the same physical data center so latency was minimal.

      The decision of redis over the other locking methods was arbitrary but in over 2 years I never had to touch that VM aside from security updates.

      This install used the service instead of cron.

      "},{"location":"Extensions/Distributed-Poller/#architecture","title":"Architecture","text":"

      How you set the distribution up is entirely up to you. You can choose to host the majority of the required services on a single virtual machine or server and then a poller to actually query the devices being monitored, all the way through to having a dedicated server for each of the individual roles. Below are notes on what you need to consider both from the software layer, but also connectivity.

      "},{"location":"Extensions/Distributed-Poller/#web-api-layer","title":"Web / API Layer","text":"

      This is typically Apache but we have setup guides for both Nginx and Lighttpd which should work perfectly fine. There is nothing unique about the role this service is providing except that if you are adding devices from this layer then the web service will need to be able to connect to the end device via SNMP and perform an ICMP test.

      It is advisable to run RRDCached within this setup so that you don't need to share the rrd folder via a remote file share such as NFS. The web service can then generate rrd graphs via RRDCached. If RRDCached isn't an option then you can mount the rrd directory to read the RRD files directly.

      "},{"location":"Extensions/Distributed-Poller/#database-server","title":"Database Server","text":"

      MySQL / MariaDB - At the moment these are the only database servers that are supported.

      The pollers, web and API layers should all be able to access the database server directly.

      "},{"location":"Extensions/Distributed-Poller/#rrd-storage","title":"RRD Storage","text":"

      Central storage should be provided so all RRD files can be read from and written to in one location. As suggested above, it's recommended that RRD Cached is configured and used.

      For this example, we are running RRDCached to allow all pollers and web/api servers to read/write to the rrd files with the rrd directory also exported by NFS for simple access and maintenance.

      "},{"location":"Extensions/Distributed-Poller/#pollers","title":"Pollers","text":"

      Pollers can be installed and run from anywhere, the only requirements are:

      • They can access the Memcache instance
      • They can create RRD files via some method such as a shared filesystem or RRDTool >=1.5.5
      • They can access the MySQL server

      You can either assign pollers into groups and set a poller group against certain devices, this will mean that those devices will only be processed by certain pollers (default poller group is 0) or you can assign all pollers to the default poller group for them to process any and all devices.

      This will provide the ability to have a single poller behind a NAT firewall monitor internal devices and report back to your central system. You will then be able to monitor those devices from the Web UI as normal.

      Another benefit to this is that you can provide N+x pollers, i.e if you know that you require three pollers to process all devices within 300 seconds then adding a 4th poller will mean that should any one single poller fail then the remaining three will complete polling in time. You could also use this to take a poller out of service for maintenance, i.e OS updates and software updates.

      It is extremely advisable to either run a central recursive dns server such as pdns-recursor and have all of your pollers use this or install a recursive dns server on each poller - the volume of DNS requests on large installs can be significant and will slow polling down enough to cause issues with a large number of devices.

      A last note to make sure of, is that all pollers writing to the same DB need to have the same APP_KEY value set in the .env file.

      "},{"location":"Extensions/Distributed-Poller/#discovery","title":"Discovery","text":"

      Depending on your setup will depend on how you configure your discovery processes.

      Cron based polling

      It's not necessary to run discovery services on all pollers. In fact, you should only run one discovery process per poller group. Designate a single poller to run discovery (or a separate server if required).

      If you run billing, you can do this in one of two ways:

      1. Run poll-billing.php and calculate-billing.php on a single poller which will create billing information for all bills. Please note this poller must have snmp access to all of your devices which have ports within a bill.
      2. The other option is to enable $config['distributed_billing'] = true; in config.php. Then run poll-billing.php on a single poller per group. You can run calculate-billing.php on any poller but only one poller overall.

      Dispatcher service When using the dispatcher service, discovery can run on all nodes.

      "},{"location":"Extensions/Distributed-Poller/#configuration","title":"Configuration","text":"

      Settings in config.php should be copied to all servers as they only apply locally.

      One way around this is to set settings in the database via the web ui or ./lnms config:set

      "},{"location":"Extensions/Distributed-Poller/#config-sample","title":"Config sample","text":"

      The following config is taken from a live setup which consists of a Web server, DB server, RRDCached server and 3 pollers.

      Web Server:

      Running Apache and an install of LibreNMS in /opt/librenms

      poller/distributed

      lnms config:set distributed_poller true\n

      poller/rrdtool

      lnms config:set rrdcached \"example.com:42217\"\n

      Database Server: Running Memcache and MariaDB

      • Memcache

      Ubuntu (/etc/memcached.conf)

      -d\n-m 64\n-p 11211\n-u memcache\n-l ip.ip.ip.ip\n

      RRDCached Server: Running RRDCached

      • RRDCached

      Ubuntu (/etc/default/rrdcached)

      OPTS=\"-l 0:42217\"\nOPTS=\"$OPTS -j /var/lib/rrdcached/journal/ -F\"\nOPTS=\"$OPTS -b /opt/librenms/rrd -B\"\nOPTS=\"$OPTS -w 1800 -z 900\"\n

      Ubuntu (/etc/default/rrdcached) - RRDCached 1.5.5 and above.

      BASE_OPTIONS=\"-l 0:42217\"\nBASE_OPTIONS=\"$BASE_OPTIONS -R -j /var/lib/rrdcached/journal/ -F\"\nBASE_OPTIONS=\"$BASE_OPTIONS -b /opt/librenms/rrd -B\"\nBASE_OPTIONS=\"$BASE_OPTIONS -w 1800 -z 900\"\n

      Poller 1: Running an install of LibreNMS in /opt/librenms

      config.php

      $config['distributed_poller_name']           = php_uname('n');\n$config['distributed_poller_group']          = '0';\n$config['distributed_billing']               = true;\n

      poller/distributed

      lnms config:set distributed_poller_memcached_host \"example.com\"\nlnms config:set distributed_poller_memcached_port 11211\nlnms config:set distributed_poller true\n

      poller/rrdtool

      lnms config:set rrdcached \"example.com:42217\"\n

      /etc/cron.d/librenms

      Runs discovery and polling for group 0, daily.sh to deal with notifications and DB cleanup and alerts.

      33   */6  * * *   librenms    /opt/librenms/cronic /opt/librenms/discovery-wrapper.py 1\n*/5  *    * * *   librenms    /opt/librenms/discovery.php -h new >> /dev/null 2>&1\n*/5  *    * * *   librenms    /opt/librenms/cronic /opt/librenms/poller-wrapper.py 16\n15   0    * * *   librenms    /opt/librenms/daily.sh >> /dev/null 2>&1\n*    *    * * *   librenms    /opt/librenms/alerts.php >> /dev/null 2>&1\n

      Poller 2: Running an install of LibreNMS in /opt/librenms

      config.php

      $config['distributed_poller_name']           = php_uname('n');\n$config['distributed_poller_group']          = '0';\n$config['distributed_billing']               = true;\n

      poller/distributed

      lnms config:set distributed_poller_memcached_host \"example.com\"\nlnms config:set distributed_poller_memcached_port 11211\nlnms config:set distributed_poller true\n

      poller/rrdtool

      lnms config:set rrdcached \"example.com:42217\"\n

      /etc/cron.d/librenms

      Runs billing as well as polling for group 0.

      */5 * * * * librenms /opt/librenms/poller-wrapper.py 16 >> /opt/librenms/logs/wrapper.log\n*/5 * * * * librenms /opt/librenms/poll-billing.php >> /dev/null 2>&1\n01  * * * * librenms /opt/librenms/billing-calculate.php >> /dev/null 2>&1\n15  0 * * * librenms    /opt/librenms/daily.sh >> /dev/null 2>&1\n

      Poller 3: Running an install of LibreNMS in /opt/librenms

      config.php

      $config['distributed_poller_name']           = php_uname('n');\n$config['distributed_poller_group']          = '2,3';\n$config['distributed_billing']               = true;\n

      poller/distributed

      lnms config:set distributed_poller_memcached_host \"example.com\"\nlnms config:set distributed_poller_memcached_port 11211\nlnms config:set distributed_poller true\n

      poller/rrdtool

      lnms config:set rrdcached \"example.com:42217\"\n

      /etc/cron.d/librenms Runs discovery and polling for groups 2 and 3.

      33  */6 * * *   librenms    /opt/librenms/cronic /opt/librenms/discovery-wrapper.py 1\n*/5 *   * * *   librenms    /opt/librenms/discovery.php -h new >> /dev/null 2>&1\n*/5 *   * * *   librenms    /opt/librenms/poll-billing.php >> /dev/null 2>&1\n*/5 *   * * *   librenms    /opt/librenms/cronic /opt/librenms/poller-wrapper.py 16\n15  0   * * *   librenms    /opt/librenms/daily.sh >> /dev/null 2>&1\n
      "},{"location":"Extensions/Fast-Ping-Check/","title":"Fast up/down checking","text":"

      Normally, LibreNMS sends an ICMP ping to the device before polling to check if it is up or down. This check is tied to the poller frequency, which is normally 5 minutes. This means it may take up to 5 minutes to find out if a device is down.

      Some users may want to know if devices stop responding to ping more quickly than that. LibreNMS offers a ping.php script to run ping checks as quickly as possible without increasing snmp load on your devices by switching to 1 minute polling.

      WARNING: If you do not have an alert rule that alerts on device status, enabling this will be a waste of resources. You can find one in the Alert Rules Collection.

      "},{"location":"Extensions/Fast-Ping-Check/#setting-the-ping-check-to-1-minute","title":"Setting the ping check to 1 minute","text":"

      1: If you are using RRDCached, stop the service.

      - This will flush all pending writes so that the rrdstep.php script can change the steps.\n

      2: Change the ping_rrd_step setting in config.php

      poller/rrdtool

      lnms config:set ping_rrd_step 60\n

      3: Update the rrd files to change the step (step is hardcoded at file creation in rrd files)

      ./scripts/rrdstep.php -h all\n

      4: Add the following line to /etc/cron.d/librenms to allow 1 minute ping checks

      *    *    * * *   librenms    /opt/librenms/ping.php >> /dev/null 2>&1\n

      5: If applicable: Start the RRDCached service

      NOTE: If you are using distributed pollers you can restrict a poller to a group by appending -g to the cron entry. Alternatively, you should only run ping.php on a single node.

      "},{"location":"Extensions/Fast-Ping-Check/#sub-minute-ping-check","title":"Sub minute ping check","text":"

      Cron only has a resolution of one minute, so for sub-minute ping checks we need to adapt both ping and alerts entries. We add two entries per function, but add a delay before one of these entries.

      Remember, you need to remove the original ping.php and alerts.php entries in crontab before proceeding!

      1: Set ping_rrd_step

      poller/rrdtool

      lnms config:set ping_rrd_step 30\n

      2: Update the rrd files

      ./scripts/rrdstep.php -h all\n

      3: Update cron (removing any other ping.php or alert.php entries)

      *    *    * * *   librenms    /opt/librenms/ping.php >> /dev/null 2>&1\n*    *    * * *   librenms    sleep 30 && /opt/librenms/ping.php >> /dev/null 2>&1\n*    *    * * *   librenms    sleep 15 && /opt/librenms/alerts.php >> /dev/null 2>&1\n*    *    * * *   librenms    sleep 45 && /opt/librenms/alerts.php >> /dev/null 2>&1\n
      "},{"location":"Extensions/Fast-Ping-Check/#device-dependencies","title":"Device dependencies","text":"

      The ping.php script respects device dependencies, but the main poller does not (for technical reasons). However, using this script does not disable the icmp check in the poller and a child may be reported as down before the parent.

      "},{"location":"Extensions/Fast-Ping-Check/#settings","title":"Settings","text":"

      ping.php uses much the same settings as the poller fping with one exception: retries is used instead of count. ping.php does not measure loss and avg response time, only up/down, so once a device responds it stops pinging it.

      poller/ping

      lnms config:set fping_options.retries 2\nlnms config:set fping_options.timeout 500\nlnms config:set fping_options.interval 500\n
      "},{"location":"Extensions/Galera-Cluster/","title":"MariaDB Galera Cluster","text":"

      This is currently being tested, use at your own risk.

      LibreNMS can be used with a MariaDB Galera Cluster. This is a Multi Master cluster, meaning each node in the cluster can read and write to the database. They all have the same ability. LibreNMS will randomly choose a working node to read and write requests to.

      For more information see https://laravel.com/docs/database#read-and-write-connections

      "},{"location":"Extensions/Galera-Cluster/#getting-started","title":"Getting Started","text":"
      • It is best practice to have a minimum of 3 nodes in the cluster, A odd number of nodes is recommended in the event nodes have a disagreement on data, they will have a tie breaker.
      • It's recommended that all servers be similar in hardware performance, cluster performance can be affected by the slowest server in the cluster.
      • Backup the database before starting, and backing up the database regularly is still recommended even in a working cluster environment.
      "},{"location":"Extensions/Galera-Cluster/#install-and-configure-galera","title":"Install and Configure Galera","text":""},{"location":"Extensions/Galera-Cluster/#install-galera4-and-mariadb-server","title":"Install Galera4 and MariaDB Server","text":"

      These can be obtained from your OS package manager. For example in Ubuntu.

      sudo apt-get install mariadb-server mariadb-client galera-4\n

      "},{"location":"Extensions/Galera-Cluster/#create-galera-config","title":"Create Galera Config","text":"

      Create a new file /etc/mysql/conf.d/galera.conf on each node

      [mysqld]\nbinlog_format=ROW\ndefault-storage-engine=innodb\ninnodb_autoinc_lock_mode=2\nbind-address=0.0.0.0\n\n# Galera Provider Configuration\nwsrep_on=ON\nwsrep_provider=/usr/lib/galera/libgalera_smm.so\n\n# Galera Cluster Configuration\nwsrep_cluster_name=\"librenms_cluster\"\nwsrep_cluster_address=\"gcomm://192.168.1.35,192.168.1.36,192.168.1.37,192.168.1.38,192.168.1.39\"\n\n# Galera Synchronization Configuration\nwsrep_sst_method=rsync\n\n# Galera Node Configuration\nwsrep_node_address=\"192.168.1.35\"\nwsrep_node_name=\"librenms1.35\"\n
      Change the following values for your environment. * wsrep_cluster_address - All the IP address's of your nodes. * wsrep_cluster_name - Name of cluster, should be the same for all nodes * wsrep_node_address - IP address of this node. * wsrep_node_name - Name of this node.

      "},{"location":"Extensions/Galera-Cluster/#edit-librenms-env","title":"Edit LibreNMS .env","text":"

      LibreNMS supports up to 9 galera nodes, you define these nodes in the .env file. For each node we have the ability to define if this librenms installation/poller is able to write, read or both to that node. The galera nodes you define here can be the same or differnt for each librenms poller. If you have a poller you only want to write/read to one galera node, you would simply add one DB_HOST, and omit all the rest. This allows you to precisely control what galera nodes a librenms poller is reading and or writing too.

      • DB_HOST is always set to read/write.
      • DB_HOST must be set, however, it does not have to be the same on each poller, it can be different as long as it's part of the same galera cluster.
      • If the node that is set to DB_HOST is down, things like lnms db command no longer work, as they only use DB_HOST and don't failover to other nodes.
      • Set DB_CONNECTION=mysql_cluster to enable
      • DB_STICKY can be used if you are pulling out of sync data form the database in a read request. For more information see https://laravel.com/docs/database#the-sticky-option

      The below example setting up 5 nodes

      DB_HOST=192.168.1.35\nDB_HOST_R2=192.168.1.36\nDB_HOST_R3=192.168.1.37\nDB_HOST_R4=192.168.1.38\nDB_HOST_R5=192.168.1.39\nDB_HOST_W2=192.168.1.36\nDB_HOST_W3=192.168.1.37\n\nDB_STICKY=true\nDB_CONNECTION=mysql_cluster\nDB_DATABASE=librenms\nDB_USERNAME=librenms\nDB_PASSWORD=password\n
      The above .env on a librenms installation/poller would communicate to each galera node as follows.

      • 192.168.1.35 - Read/Write
      • 192.168.1.36 - Read/Write
      • 192.168.1.37 - Read/Write
      • 192.168.1.38 - Read Only
      • 192.168.1.39 - Read Only
      "},{"location":"Extensions/Galera-Cluster/#starting-galera-cluster-for-the-first-time","title":"Starting Galera Cluster for the first time.","text":"

      1) Shutdown MariaDB server on ALL nodes.

      sudo systemctl stop mariadb-server\n
      2) On the server with your existing database or any mariadb server if you are starting without existing data, run the following command
      sudo galera_new_cluster\n
      3) Start the rest of the nodes normally.
      sudo systemctl start mariadb-server\n

      "},{"location":"Extensions/Galera-Cluster/#galera-cluster-status","title":"Galera Cluster Status","text":"

      To see some stats on how the Galera cluster is preforming run the following.

      lnms db\n
      In the database run following mysql query
      SHOW GLOBAL STATUS LIKE 'wsrep_%';\n

      Variable Name Value Notes ----------------------------------- ---------------------------------------------------------------- --------------------------------------------------------- wsrep_cluster_size 2 Current number of nodes in Cluster wsrep_cluster_state_uuid e71582f3-cf14-11eb-bcf6-a23029e16405 Last Transaction UUID, Should be the same for each node wsrep_connected On On = Connected with other nodes wsrep_local_state_comment Synced Synced with other nodes"},{"location":"Extensions/Galera-Cluster/#restarting-the-entire-cluster","title":"Restarting the Entire Cluster","text":"

      In a cluster environment, steps should be taken to ensure that ALL nodes are not offline at the same time. Failed nodes can recover without issue as long as one node remains online. In the event that ALL nodes are offline, the following should be done to ensure you are starting the cluster with the most up-to-date database. To do this login to each node and running the following

      sudo cat /var/lib/data/grastate.dat\n
      # GALERA saved state\nversion: 2.1\nuuid:    e71582f3-cf14-11eb-bcf6-a23029e16405\nseqno:   -1\nsafe_to_bootstrap: 1\n

      If the safe_to_bootstrap = 1, then Galera determined that this node has the most up-to-date database and can be safeley used to start the cluster.

      Once you have found a node that can be used for starting the cluster, follow the steps in starting for the first time.

      "},{"location":"Extensions/Gateone/","title":"GateOne integration","text":"

      We have simple integration for GateOne, you will be redirected to your Gateone command line frontend to access your equipment. (Currently this only works with SSH)

      GateOne itself isn't included within LibreNMS, you will need to install this separately either on the same infrastructure as LibreNMS or as a totally standalone appliance. The installation is beyond the scope of this document.

      Config is simple, include the following in your config.php:

      $config['gateone']['server'] = 'http://<your_gateone_url/';\n

      Note: You must use the full url including the trailing /!

      We also support prefixing the currently logged in Librenms user to the SSH connection URL that is created, eg. ssh://admin@localhost To enable this, put the following in your config.php:

      $config['gateone']['use_librenms_user'] = true;\n
      "},{"location":"Extensions/Graylog/","title":"Graylog integration","text":"

      We have simple integration for Graylog, you will be able to view any logs from within LibreNMS that have been parsed by the syslog input from within Graylog itself. This includes logs from devices which aren't in LibreNMS still, you can also see logs for a specific device under the logs section for the device.

      Currently, LibreNMS does not associate shortnames from Graylog with full FQDNS. If you have your devices in LibreNMS using full FQDNs, such as hostname.example.com, be aware that rsyslogd, by default, sends the shortname only. To fix this, add

      $PreserveFQDN on

      to your rsyslog config to send the full FQDN so device logs will be associated correctly in LibreNMS. Also see near the bottom of this document for tips on how to enable/suppress the domain part of hostnames in syslog-messages for some platforms.

      Graylog itself isn't included within LibreNMS, you will need to install this separately either on the same infrastructure as LibreNMS or as a totally standalone appliance.

      Config is simple, here's an example based on Graylog 2.4:

      external/graylog

      lnms config:set graylog.server 'http://127.0.0.1'\nlnms config:set graylog.port 9000\nlnms config:set graylog.username admin\nlnms config:set graylog.password 'admin'\nlnms config:set graylog.version 2.4\n
      "},{"location":"Extensions/Graylog/#timezone","title":"Timezone","text":"

      Graylog messages are stored using GMT timezone. You can display graylog messages in LibreNMS webui using your desired timezone by setting the following option using lnms config:set:

      external/graylog

      lnms config:set graylog.timezone 'Europe/Bucharest'\n

      Timezone must be PHP supported timezones, available at: https://php.net/manual/en/timezones.php

      "},{"location":"Extensions/Graylog/#graylog-version","title":"Graylog Version","text":"

      If you are running a version earlier than Graylog then please set

      external/graylog

      lnms config:set graylog.version 2.1\n

      to the version number of your Graylog install. Earlier versions than 2.1 use the default port 12900

      "},{"location":"Extensions/Graylog/#uri","title":"URI","text":"

      If you have altered the default uri for your Graylog setup then you can override the default of /api/ using

      external/graylog

      lnms config:set graylog.base_uri '/somepath/'\n
      "},{"location":"Extensions/Graylog/#user-credentials","title":"User Credentials","text":"

      If you don't want to use an admin account for connection to Graylog Log into http:///api/api-browser/global/index.html using graylog admin credentials Browse to: Roles: User roles Click on: Create a new role In JSON body paste this:

      {\n    \"name\": \"LibreNMS-Read\",\n    \"description\": \"Extended reading permissions for LibreNMS\",\n    \"permissions\" : [\n        \"searches:relative\",\n        \"streams:read\"\n    ]\n}\n
      Press \u201cTry it out\u201d Log into graylog web ui as admin and add the role to the user

      Otherwise you must give the user \"admin\" permissions from within Graylog, \"read\" permissions alone are not sufficient.

      "},{"location":"Extensions/Graylog/#tls-certificate","title":"TLS Certificate","text":"

      If you have enabled TLS for the Graylog API and you are using a self-signed certificate, please make sure that the certificate is trusted by your LibreNMS host, otherwise the connection will fail. Additionally, the certificate's Common Name (CN) has to match the FQDN or IP address specified in

      external/graylog

      lnms config:set graylog.server example.com\n
      "},{"location":"Extensions/Graylog/#match-any-address","title":"Match Any Address","text":"

      If you want to match the source address of the log entries against any IP address of a device instead of only against the primary address and the host name to assign the log entries to a device, you can activate this function using

      lnms config:set graylog.match-any-address true\n
      "},{"location":"Extensions/Graylog/#recent-devices","title":"Recent Devices","text":"

      There are 2 configuration parameters to influence the behaviour of the \"Recent Graylog\" table on the overview page of the devices.

      external/graylog

      lnms config:set graylog.device-page.rowCount 10\n

      Sets the maximum number of rows to be displayed (default: 10)

      external/graylog

      lnms config:set graylog.device-page.loglevel 7\n

      You can set which loglevels that should be displayed on the overview page. (default: 7, min: 0, max: 7)

      external/graylog

      lnms config:set graylog.device-page.loglevel 4\n

      Shows only entries with a log level less than or equal to 4 (Emergency, Alert, Critical, Error, Warning).

      You can set a default Log Level Filter with

      lnms config:set graylog.loglevel 7\n
      (applies to /graylog and /device/device=/tab=logs/section=graylog/ (min: 0, max: 7)

      "},{"location":"Extensions/Graylog/#domain-and-hostname-handling","title":"Domain and hostname handling","text":"

      Suppressing/enabling the domain part of a hostname for specific platforms

      You should see if what you get in syslog/Graylog matches up with your configured hosts first. If you need to modify the syslog messages from specific platforms, this may be of assistance:

      "},{"location":"Extensions/Graylog/#ios-cisco","title":"IOS (Cisco)","text":"
      router(config)# logging origin-id hostname\n

      or

      router(config)# logging origin-id string\n
      "},{"location":"Extensions/Graylog/#junos-juniper-networks","title":"JunOS (Juniper Networks)","text":"
      set system syslog host yourlogserver.corp log-prefix YOUR_PREFERRED_STRING\n
      "},{"location":"Extensions/Graylog/#panos-palo-alto-networks","title":"PanOS (Palo Alto Networks)","text":"
      set deviceconfig setting management hostname-type-in-syslog hostname\n

      or

      set deviceconfig setting management hostname-type-in-syslog FQDN\n
      "},{"location":"Extensions/IRC-Bot-Extensions/","title":"IRC Bot Extensions","text":"

      Okay this is a very quick walk-through in writing your own commands for the IRC-Bot.

      First of all, create a file in includes/ircbot, the file-name should be in this format: command.inc.php.

      When editing the file, do not open nor close PHP-tags. Any variable you assign will be discarded as soon as your command returns. Some variables, specially all listed under $this->, have special meanings or effects. Before a command is executed, the IRC-Bot ensures that the MySQL-Socket is working, that $this->user points to the right user and that the user is authenticated. Below you will find a table with related functions and attributes. You can chain-load any built-in command by calling $this->_command(\"My Parameters\"). You cannot chain-load external commands.

      To enable your command, edit your config.php and add something like this:

         ...\n   $config['irc_external'][] = \"mycommand\";\n   ...\n

      See: Example

      "},{"location":"Extensions/IRC-Bot-Extensions/#functions-and-attributes","title":"Functions and Attributes","text":"

      ... that are accessible from within an extension

      "},{"location":"Extensions/IRC-Bot-Extensions/#functions","title":"Functions","text":"Function( (Type) $Variable [= Default] [,...] ) Returns Description $this->getChan( ) String Returns channel of current event. $this->getData( (boolean) $Block = false ) String/Boolean Returns a line from the IRC-Buffer if it's not matched against any other command. If $Block is true, wait until a suitable line is returned. $this->getUser( ) String Returns nick of current user. Not to confuse with $this->user! $this->get_user( ) Array See $this->user in Attributes. $this->irc_raw( (string) $Protocol ) Boolean Sends raw IRC-Protocol. $this->isAuthd( ) Boolean true if the user is authenticated. $this->joinChan( (string) $Channel ) Boolean Joins given $Channel. $this->log( (string) $Message ) Boolean Logs given $Message into STDOUT. $this->read( (string) $Buffer ) String/Boolean Returns a line from given $Buffer or false if there's nothing suitable inside the Buffer. Please use $this->getData() for handler-safe data retrieval. $this->respond( (string) $Message ) Boolean Responds to the request auto-detecting channel or private message."},{"location":"Extensions/IRC-Bot-Extensions/#attributes","title":"Attributes","text":"Attribute Type Description $params String Contains all arguments that are passed to the .command. $this->chan Array Channels that are configured. $this->commands Array Contains accessible commands. $this->config Array Contains $config from config.php. $this->data String Contains raw IRC-Protocol. $this->debug Boolean Debug-Flag. $this->external Array Contains loaded extra commands. $this->nick String Bot's nick on the IRC. $this->pass String IRC-Server's passphrase. $this->port Int IRC-Server's port-number. $this->server String IRC-Server's hostname. $this->ssl Boolean SSL-Flag. $this->tick Int Interval to check buffers in microseconds. $this->user Array Array containing details about the user that sent the request."},{"location":"Extensions/IRC-Bot-Extensions/#example","title":"Example","text":"

      includes/ircbot/join-ng.inc.php

         if( $this->user['level'] != 10 ) {\n      return $this->respond(\"Sorry only admins can make me join.\");\n   }\n   if( $this->getChan() == \"#noc\") {\n      $this->respond(\"Joining $params\");\n      $this->joinChan($params);\n   } else {\n      $this->respond(\"Sorry, only people from #noc can make join.\");\n   }\n

      config.php

         ...\n   $config['irc_external'][] = \"join-ng\";\n   ...\n
      "},{"location":"Extensions/IRC-Bot/","title":"IRC Bot","text":"

      LibreNMS has an easy to use IRC-Interface for basic tasks like viewing last log-entry, current device/port status and such.

      By default the IRC-Bot will not start when executed and will return an error until at least $config['irc_host'] and $config['irc_port'] has been specified inside config.php. (To start the IRC-Bot run ./irc.php )

      If no channel has been specified with $config['irc_chan'], ##librenms will be used. The default Nick for the bot is LibreNMS.

      The Bot will reply the same way it's being called. If you send it the commands via Query, it will respond in the Query. If you send the commands via a Channel, then it will respond in the Channel.

      "},{"location":"Extensions/IRC-Bot/#configuration-defaults","title":"Configuration & Defaults","text":"Option Default-Value Notes $config['irc_alert'] false Optional; Enables Alerting-Socket. EXPERIMENTAL $config['irc_alert_chan'] false Optional; Multiple channels can be defined as Array or delimited with ,. EXPERIMENTAL $config['irc_alert_utf8'] false Optional; Enables use of strikethrough in alerts via UTF-8 encoded characters. Might cause trouble for some clients. $config['irc_alert_short'] false Optional; Send a one line alert summary instead of multi-line detailed alert. $config['irc_authtime'] 3 Optional; Defines how long in Hours an auth-session is valid. $config['irc_chan'] ##librenms Optional; Multiple channels can be defined as Array or delimited with ,. Passwords are defined after a space-character. $config['irc_debug'] false Optional; Enables debug output (Wall of text) $config['irc_external'] Optional; Array or , delimited string with commands to include from includes/ircbot/*.inc.php $config['irc_host'] Required; Domain or IP to connect. If it's an IPv6 Address, embed it in []. (Example: [::1]) $config['irc_maxretry'] 5 Optional; How many connection attempts should be made before giving up $config['irc_nick'] LibreNMS Optional; $config['irc_pass'] Optional; This sends the IRC-PASS Sequence to IRC-Servers that require Password on Connect $config['irc_port'] 6667 Required; To enable SSL append a + before the Port. (Example: +6697) $config['irc_ctcp'] false Optional; Enable/disable ctcp-replies from the bot (currently VERSION, PING and TIME). $config['irc_ctcp_version'] LibreNMS IRCbot. https://www.librenms.org/ Optional; Reply-string to CTCP VERSION requests $config['irc_auth'] Optional; Array of hostmasks that are automatically authenticated."},{"location":"Extensions/IRC-Bot/#irc-commands","title":"IRC-Commands","text":"Command Description .auth <User/Token> If <user>: Request an Auth-Token. If <token>: Authenticate session. .device <hostname> Prints basic information about given hostname. .down List hostnames that are down, if any. .help List available commands. .join <channel> Joins <channel> if user has admin-level. .listdevices Lists the hostnames of all known devices. .log [<N>] Prints N lines or last line of the eventlog. .port <hostname> <ifname> Prints Port-related information from ifname on given hostname. .quit Disconnect from IRC and exit. .reload Reload configuration. .status <type> Prints status information for given type. Type can be devices, services, ports. Shorthands are: dev,srv,prt .version Prints $this->config['project_name_version'].

      ( /!\\ All commands are case-insensitive but their arguments are case-sensitive)

      "},{"location":"Extensions/IRC-Bot/#examples","title":"Examples","text":""},{"location":"Extensions/IRC-Bot/#server-examples","title":"Server examples","text":"

      Unencrypted Connection to irc.libera.chat:

         ...\n   $config['irc_host'] = \"irc.libera.chat\";\n   $config['irc_port'] = 6667;\n   ...\n

      SSL-Encrypted Connection to irc.libera.chat:

         ...\n   $config['irc_host'] = \"irc.libera.chat\";\n   $config['irc_port'] = \"+6697\";\n   ...\n

      SSL-Encrypted Connection to irc.localdomain with Server-Password and odd port:

         ...\n   $config['irc_host'] = \"irc.localdomain\";\n   $config['irc_port'] = \"+12345\";\n   $config['irc_pass'] = \"Super Secret Passphrase123\";\n   ...\n
      "},{"location":"Extensions/IRC-Bot/#channel-notations","title":"Channel notations","text":"

      Channels can be defined using Array-Notation like:

         ...\n   $config['irc_chan'][] = \"#librenms\";\n   $config['irc_chan'][] = \"#otherchan\";\n   $config['irc_chan'][] = \"#noc\";\n   ...\n

      Or using a single string using , as delimiter between various channels:

         ...\n   $config['irc_chan'] = \"#librenms,#otherchan,#noc\";\n   ...\n
      "},{"location":"Extensions/IRC-Bot/#hostmask-authentication","title":"Hostmask authentication","text":"
         ...\n   $config['irc_auth']['admin'][] = \"*!root@nms.host.invalid\";\n   $config['irc_auth']['admin'][] = \"*!*peter@peters.computer.invalid\";\n   $config['irc_auth']['john][] = \"john!doe@login.server.invalid\";\n   ...\n

      Any client matching one of the first two hostmasks will automatically be authenticated as the \"admin\" user in LibreNMS, and clients matching the last line will be authenticated as the user \"john\" in LibreNMS, without using .auth and a waiting for a valid token.

      "},{"location":"Extensions/IRC-Bot/#extensions","title":"Extensions?!","text":"

      The bot is coded in a unified way. This makes writing extensions by far less painful. Simply add your command to the $config['irc_external'] directive and create a file called includes/ircbot/command.inc.php containing your code. The string behind the call of .command is passed as $params. The user who requested something is accessible via $this->user. Send your reply/ies via $this->respond($string).

      A more detailed documentation of the functions and variables available for extensions can be found at IRC-Bot Extensions;

      Confused? Here an Echo-Example:

      File: config.php

         ...\n   $config['irc_external'][] = \"echo\";\n   ...\n

      File: includes/ircbot/echo.inc.php

         //Prefix everything with `You said: '...'`  and return what was sent.\n   if( $this->user['name'] != \"root\" ) {\n      return $this->respond(\"You said: '\".$params.\"'\");\n   } else {\n      return $this->respond(\"root shouldn't be online so late!\");\n   }\n
      "},{"location":"Extensions/IRC-Bot/#systemd-start-up-script","title":"Systemd start up script","text":"

      Basic systemd start up script to be placed in /etc/systemd/system/ to start irc service at boot.

      librenms-irc.service script is located at /opt/librenms/misc/

      Once copied to /etc/systemd/system/ you must run the following commands:

      a) chmod 664 /etc/systemd/system/librenms-irc.service

      b) systemctl daemon-reload

      c) systemctl enable librenms-irc.service

      d) systemctl start librenms-irc.service

      It can be stopped or started just like any other systemd script such as systemctl start librenms-irc.service

      "},{"location":"Extensions/Interface-Description-Parsing/","title":"Interface Description Parsing","text":"

      Librenms can interpret, display and group certain additional information on ports. This is done based on the format that the port description is written although it's possible to customise the parser to be specific for your setup.

      "},{"location":"Extensions/Interface-Description-Parsing/#keywords","title":"Keywords","text":"

      See examples for formats.

      • Keywords
      • Cust - Customer
      • Transit - Transit link
      • Peering - Peering link
      • Core - Infrastructure link (non-customer)
      • Info-keywords
      • () contains a note
      • {} contains your circuit id
      • [] contains the service type or speed
      "},{"location":"Extensions/Interface-Description-Parsing/#examples","title":"Examples","text":"

      Cisco IOS / NXOS / IOSXR:

      interface Gi0/1\ndescr Transit: Example Provider (AS65000)\ninterface Gi0/2\ndescr Peering: Peering Exchange\ninterface Gi0/3\ndescr Core: core.router01 FastEthernet0/0 (Telco X CCID023141)\ninterface Gi0/4\ndescr Cust: Example Customer [10Mbit] (T1 Telco Y CCID129031) {EXAMP0001}\n

      Unix / Linux:

      This requires an additional script to be setup

      # eth3: Cust: Example Customer [10Mbit] (T1 Telco Y CCID129031) {EXAMP0001}\n# eth0: Transit: Example Provider (AS65000)\n# eth1: Core: core.router01 FastEthernet0/0 (Telco X CCID023141)\n# eth2: Peering: Peering Exchange\n
      "},{"location":"Extensions/Interface-Description-Parsing/#customisation","title":"Customisation","text":"

      The following config options can be set to enable more custom types:

      webui/port-descr

      lnms config:set customers_descr.+ 'cust'\nlnms config:set transit_descr.+ 'transit'\nlnms config:set peering_descr.+ 'peering'\";'\nlnms config:set core_descr.+ 'core'\nlnms config:set custom_descr.+ 'something_made_up'\n
      "},{"location":"Extensions/Interface-Description-Parsing/#custom-interface-parser","title":"Custom interface parser","text":"

      It's also possible to write your own parser, the existing one is: includes/port-descr-parser.inc.php

      Once you've created your own then you can enable it with:

      $config['port_descr_parser'] = \"includes/custom/my-port-descr-parser.inc.php\";\n
      "},{"location":"Extensions/Interface-Description-Parsing/#setup","title":"Setup","text":"

      For Unix / Linux based systems, you need to run an additional script to support the parsing of interface information.

      • Add ifAlias from /opt/librenms/scripts/ or download it from here to the Server and make it executable chmod +x /path/to/ifAlias
      • Add to snmpd.conf something like: pass .1.3.6.1.2.1.31.1.1.1.18 /path/to/ifAlias
      • Add aliasses with
      • iproute2 package like: ip link set eth0.427 alias 'Cust: CustomerA'
      • in /etc/network/interfaces or /etc/network/interfaces.d/* with a comment like: # eth0.427: Cust CustomerA

      • Restart snmpd - systemctl restart snmpd

      There are no changes to be made or additions to install for the polling librenms.

      Now you can set up your keywords in your aliases.

      "},{"location":"Extensions/Metric-Storage/","title":"Metric storage","text":"

      By default we ship all metrics to RRD files, either directly or via RRDCached. On top of this you can ship metrics to Graphite, InfluxDB (v1 or v2 API), OpenTSDB or Prometheus. At present you can't use these backends to display graphs within LibreNMS and will need to use something like Grafana.

      For further information on configuring LibreNMS to ship data to one of the other backends then please see the documentation below.

      • Graphite
      • InfluxDB
      • InfluxDBv2
      • OpenTSDB
      • Prometheus
      "},{"location":"Extensions/NFSen/","title":"NFSen","text":"

      The installation of NFSen is out of scope for this document / LibreNMS

      "},{"location":"Extensions/NFSen/#configuration","title":"Configuration","text":"

      The following is the configuration that can be used:

      external/nfsen

      lnms config:set nfsen_enable true\nlnms config:set nfsen_split_char '_'\nlnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/live/'\nlnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat'\nlnms config:set nfsen_base.+ '/var/nfsen/'\nlnms config:set nfsen_suffix '_yourdomain_com'\n

      Set lnms config:set nfsen_enable true to enable NFSen support.

      nfsen_rrds This value tells us where your NFSen rrd files live. This can also be an array to specify more directories like:

      external/nfsen

      lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/sitea/'\nlnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/siteb/'\n

      Although for most setups, it will look like below, with the profiles-stat/live directory being where it stores the general RRDs for data sources.

      external/nfsen

      lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat/live'\n

      If you wish to render info for configure channels for a device, you need add the various profile-stat directories your system uses, which for most systems will be as below.

      external/nfsen

      lnms config:set nfsen_rrds.+ '/var/nfsen/profiles-stat'\n

      When adding sources to nfsen.conf, it is important to use the hostname that matches what is configured in LibreNMS, because the rrd files NfSen creates is named after the source name (ident), and it doesn't allow you to use an IP address instead. However, in LibreNMS, if your device is added by an IP address, add your source with any name of your choice, and create a symbolic link to the rrd file.

      cd /var/nfsen/profiles-stat/sitea/\nln -s mychannel.rrd librenmsdeviceIP.rrd\n

      external/nfsen

      lnms config:set nfsen_split_char '_'\n

      This value tells us what to replace the full stops . in the devices hostname with.

      external/nfsen

      lnms config:set nfsen_suffix '_yourdomain_com'\n

      The above is a very important bit as device names in NfSen are limited to 21 characters. This means full domain names for devices can be very problematic to squeeze in, so therefor this chunk is usually removed.

      On a similar note, NfSen profiles for channels should be created with the same name.

      "},{"location":"Extensions/NFSen/#stats-defaults-and-settings","title":"Stats Defaults and Settings","text":"

      Below are the default settings used with nfdump for stats.

      For more defaulted information on that, please see nfdump(1). The default location for nfdump is /usr/bin/nfdump. If nfdump is located elsewhere, set it with

      external/binaries

      ```bash lnms config:set nfdump /usr/local/bin/nfdump

      ```

      external/nfsen

      lnms config:set nfsen_last_max 153600\nlnms config:set nfsen_top_max 500\nlnms config:set nfsen_top_N '[10, 20, 50, 100, 200, 500]'\nlnms config:set nfsen_top_default 20\nlnms config:set nfsen_stat_default srcip\nlnms config:set nfsen_order_default packets\nlnms config:set nfsen_last_default 900\nlnms config:set nfsen_lasts \"{'300':'5 minutes', '600':'10 minutes', '900':'15 minutes', '1800':'30 minutes', '3600':'1 hour', '9600':'3 hours', '38400':'12 hours', '76800':'24 hours', '115200':'36 hours', '153600':'48 hours'}\"\n

      external/nfsen

      lnms config:set nfsen_last_max 153600\n

      The above is the max value in seconds one may pull stats for. The higher this is, the more CPU and disk intensive the search will be.

      Numbers larger than this will be set to this.

      external/nfsen

      lnms config:set nfsen_top_max 500\n

      The above is max number of items to be displayed.

      Numbers larger than this will be set to this.

      external/nfsen

      lnms config:set nfsen_top_N '[10, 20, 50, 100, 200, 500]'\n

      The above is a array containing a list for the drop down menu how many top items should be returned.

      external/nfsen

      lnms config:set nfsen_top_default 20\n

      The above sets default top number to use from the drop down.

      external/nfsen

      lnms config:set nfsen_stat_default srcip\n

      The above sets default stat type to use from the drop down.

      record   Flow Records\nip       Any IP Address\nsrcip    SRC IP Address\ndstip    DST IP Address\nport     Any Port\nsrcport  SRC Port\ndstport  DST Port\nsrctos   SRC TOS\ndsttos   DST TOS\ntos      TOS\nas       AS\nsrcas    SRC AS\ndstas    DST AS\n

      external/nfsen

      lnms config:set nfsen_order_default packets\n

      The above sets default order type to use from the drop down. Any of the following below are currently supported.

      flows    Number of total flows for the time period.\npacket   Number of total packets for the time period.\nbytes    Number of total bytes for the time period.\npps      Packets Per Second\nbps      Bytes Per Second\nbpp      Bytes Per Packet\n

      external/nfsen

      lnms config:set nfsen_last_default 900\n

      The above is the last default to use from the drop down.

      external/nfsen

      lnms config:set nfsen_lasts \"{'300':'5 minutes', '600':'10 minutes', '900':'15 minutes', '1800':'30 minutes', '3600':'1 hour', '9600':'3 hours', '38400':'12 hours', '76800':'24 hours', '115200':'36 hours', '153600':'48 hours'}\"\n

      The above associative array contains time intervals for how far back to go. The keys are the length in seconds and the value is just a description to display.

      "},{"location":"Extensions/Network-Map/","title":"Network Map","text":"

      LibreNMS has the ability to show you a dynamic network map based on data collected from devices. These maps are accessed through the following menu options:

      • Overview -> Maps -> Network
      • Overview -> Maps -> Device Group Maps
      • The Neighbours -> Map tab when viewing a single device (the Neighbours tab will only show if a device has xDP neighbours)

      These network maps can be based on:

      • xDP Discovery
      • MAC addresses (ARP entries matching interface IP and MAC)

      By default, both are are included but you can enable / disable either one using the following config option:

      lnms config:set network_map_items '[\"mac\",\"xdp\"]'\n

      Either remove mac or xdp depending on which you want. XDP is based on FDP, CDP and LLDP support based on the device type.

      It is worth noting that the global map could lead to a large network map that is slow to render and interact with. The network map on the device neighbour page, or building device groups and using the device group maps will be more usable on large networks.

      "},{"location":"Extensions/Network-Map/#settings","title":"Settings","text":"

      The map display can be configured by altering the Vis JS Options

      "},{"location":"Extensions/OAuth-SAML/","title":"OAuth and SAML Support","text":""},{"location":"Extensions/OAuth-SAML/#introduction","title":"Introduction","text":"

      LibreNMS has support for Laravel Socialite to try and simplify the use of OAuth 1 or 2 providers such as using GitHub, Microsoft, Twitter + many more and SAML.

      Socialite Providers supports more than 100+ 3rd parties so you will most likely find support for the SAML or OAuth provider you need without too much trouble.

      Please do note however, these providers are not maintained by LibreNMS so we cannot add support for new ones and we can only provide you basic help with general configuration. See the Socialite Providers website for more information on adding a new OAuth provider.

      Below we will guide you on how to install SAML or some of these OAth providers, you should be able to use these as a guide on how to install any others you may need but please, please, ensure you read the Socialite Providers documentation carefully.

      GitHub Provider Microsoft Provider Okta Provider SAML2

      "},{"location":"Extensions/OAuth-SAML/#requirements","title":"Requirements","text":"

      LibreNMS version 22.3.0 or later.

      Please ensure you set APP_URL within your .env file so that callback URLs work correctly with the identify provider.

      Note

      Once you have configured your OAuth or SAML2 provider, please ensure you check the Post configuration settings section at the end.

      "},{"location":"Extensions/OAuth-SAML/#github-and-microsoft-examples","title":"GitHub and Microsoft Examples","text":""},{"location":"Extensions/OAuth-SAML/#install-plugin","title":"Install plugin","text":"

      Note

      First we need to install the plugin itself. The plugin name can be slightly different so be sure to check the Socialite Providers documentation and look for this line, composer require socialiteproviders/github which will give you the name you need for the command, i.e: socialiteproviders/github.

      GitHubMicrosoftOkta

      lnms plugin:add socialiteproviders/github

      lnms plugin:add socialiteproviders/microsoft

      lnms plugin:add socialiteproviders/okta

      "},{"location":"Extensions/OAuth-SAML/#find-the-provider-name","title":"Find the provider name","text":"

      Next we need to find the provider name and writing it down

      Note

      It's almost always the name of the provider in lowercase but can be different so check the Socialite Providers documentation and look for this line, github => [ which will give you the name you need for the above command: github.

      GitHubMicrosoftOkta

      For GitHub we can find the line:

      'github' => [\n  'client_id' => env('GITHUB_CLIENT_ID'),\n  'client_secret' => env('GITHUB_CLIENT_SECRET'),\n  'redirect' => env('GITHUB_REDIRECT_URI')\n],\n
      So our provider name is github, write this down.

      For Microsoft we can find the line:

      'microsoft' => [\n  'client_id' => env('MICROSOFT_CLIENT_ID'),\n  'client_secret' => env('MICROSOFT_CLIENT_SECRET'),\n  'redirect' => env('MICROSOFT_REDIRECT_URI')\n],\n
      So our provider name is microsoft, write this down.

      For Okta we can find the line:

      'okta' => [\n  'base_url' => env('OKTA_BASE_URL'),\n  'client_id' => env('OKTA_CLIENT_ID'),\n  'client_secret' => env('OKTA_CLIENT_SECRET'),\n  'redirect' => env('OKTA_REDIRECT_URI')\n],\n
      So our provider name is okta, write this down.

      "},{"location":"Extensions/OAuth-SAML/#register-oauth-application","title":"Register OAuth application","text":""},{"location":"Extensions/OAuth-SAML/#register-a-new-application","title":"Register a new application","text":"

      Now we need some values from the OAuth provider itself, in most cases you need to register a new \"OAuth application\" at the providers site. This will vary from provider to provider but the process itself should be similar to the examples below.

      Note

      The callback URL is always: https://your-librenms-url/auth/provider/callback It doesn't need to be a public available site, but it almost always needs to support TLS (https)!

      GitHubMicrosoftOkta

      For our example with GitHub we go to GitHub Developer Settings and press \"Register a new application\":

      Fill out the form accordingly (with your own values):

      For our example with Microsoft we go to \"Azure Active Directory\" > \"App registrations\" and press \"New registration\"

      Fill out the form accordingly using your own values):

      Copy the value of the Application (client) ID and Directory (tenant) ID and save them, you will need them in the next step.

      For our example with Okta, we go to Applications>Create App Integration, Select OIDC - OpenID Connect, then Web Application.

      Fill in the Name, Logo, and Assignments based on your preferred settings. Leave the Sign-In Redirect URI field, this is where you will edit this later:

      Note your Okta domain or login url. Sometimes this can be a vanity url like login.company.com, or sometimes just company.okta.com.

      Click save.

      "},{"location":"Extensions/OAuth-SAML/#generate-a-new-client-secret","title":"Generate a new client secret","text":"GitHubMicrosoftOkta

      Press 'Generate a new client secret' to get a new client secret.

      Copy the Client ID and Client secret

      In the example above it is:

      Client ID: 7a41f1d8215640ca6b00 Client secret: ea03957288edd0e590be202b239e4f0ff26b8047

      Select Certificates & secrets under Manage. Select the 'New client secret' button. Enter a value in Description and select one of the options for Expires and select 'Add'.

      Copy the client secret Value (not Secret ID!) before you leave this page. You will need it in the next step.

      This step is done for you when creating the app. All you have to do is copy down the client secret. You will need it in the next step.

      "},{"location":"Extensions/OAuth-SAML/#saving-configuration","title":"Saving configuration","text":"

      Now we need to set the configuration options for your provider within LibreNMS itself. Please replace the values in the examples below with the values you collected earlier:

      The format of the configuration string is auth.socialite.configs.*provider name*.*value*

      GitHubMicrosoftOkta

      settings/auth/socialite

      lnms config:set auth.socialite.configs.github.client_id 7a41f1d8215640ca6b00\nlnms config:set auth.socialite.configs.github.client_secret ea03957288edd0e590be202b239e4f0ff26b8047\n

      settings/auth/socialite

      lnms config:set auth.socialite.configs.microsoft.client_id 7983ac13-c955-40e9-9b85-5ba27be52a52\nlnms config:set auth.socialite.configs.microsoft.client_secret J9P7Q~K2F5C.L243sqzbGj.cOOcjTBgAPak_l\nlnms config:set auth.socialite.configs.microsoft.tenant a15edc05-152d-4eb4-973c-14f1fdc57d8b\n

      settings/auth/socialite

      lnms config:set auth.socialite.configs.okta.client_id 0oa1c08tti8D7xgXb697\nlnms config:set auth.socialite.configs.okta.client_secret sWew90IKqKDmURj1XLsCPjXjre0U3zmJuFR6SzsG\nlnms config:set auth.socialite.configs.okta.base_url \"https://<okta_login_url>\"\n
      "},{"location":"Extensions/OAuth-SAML/#add-provider-event-listener","title":"Add provider event listener","text":"

      The final step is to now add an event listener.

      Note

      It's important to copy exactly the right value here, It should begin with a \\ and end before the ::class.'@handle'

      GitHubMicrosoftOkta

      Find the section looking like:

      protected $listen = [\n    \\SocialiteProviders\\Manager\\SocialiteWasCalled::class => [\n        // ... other providers\n        \\SocialiteProviders\\GitHub\\GitHubExtendSocialite::class.'@handle',\n    ],\n];\n

      Copy the part: \\SocialiteProviders\\GitHub\\GitHubExtendSocialite and run;

      settings/auth/socialite

      lnms config:set auth.socialite.configs.github.listener \"\\SocialiteProviders\\GitHub\\GitHubExtendSocialite\"\n

      Don't forget the initial backslash (\\) !

      Find the section looking like:

      protected $listen = [\n    \\SocialiteProviders\\Manager\\SocialiteWasCalled::class => [\n        // ... other providers\n        \\SocialiteProviders\\Microsoft\\MicrosoftExtendSocialite::class.'@handle',\n    ],\n];\n

      Copy the part: \\SocialiteProviders\\Microsoft\\MicrosoftExtendSocialite and run;

      settings/auth/socialite

      lnms config:set auth.socialite.configs.microsoft.listener \"\\SocialiteProviders\\Microsoft\\MicrosoftExtendSocialite\"\n

      Don't forget the initial backslash (\\) !

      Find the section looking like:

      protected $listen = [\n\\SocialiteProviders\\Manager\\SocialiteWasCalled::class => [\n    // ... other providers\n    \\SocialiteProviders\\Okta\\OktaExtendSocialite::class.'@handle',\n],\n];\n

      Copy the part: \\SocialiteProviders\\Okta\\OktaExtendSocialite and run;

      settings/auth/socialite

      lnms config:set auth.socialite.configs.okta.listener \"\\SocialiteProviders\\Okta\\OktaExtendSocialite\"\n

      Don't forget the initial backslack (\\) !

      Now you are done with setting up the OAuth provider! If it doesn't work, please double check your configuration values by using the config:get command below.

      settings/auth/socialite

      lnms config:get auth.socialite\n
      "},{"location":"Extensions/OAuth-SAML/#default-role","title":"Default Role","text":"

      Since most Socialite Providers don't provide Authorization only Authentication it is possible to set the default User Role for Authorized users. Appropriate care should be taken.

      • none: No Access: User has no access

      • normal: Normal User: You will need to assign device / port permissions for users at this level.

      • global-read: Global Read: Read only Administrator.

      • admin: Administrator: This is a global read/write admin account.

      settings/auth/socialite

      lnms config:set auth.socialite.default_role global-read\n
      "},{"location":"Extensions/OAuth-SAML/#claims-access-scopes","title":"Claims / Access Scopes","text":"

      Socialite can specifiy scopes that should be included with in the authentication request. (see Larvel docs )

      For example, if Okta is configured to expose group information it is possible to use these group names to configure User Roles.

      This requires configuration in Okta. You can set the 'Groups claim type' to 'Filter' and supply a regex of which groups should be returned which can be mapped below.

      First enable sending the 'groups' claim (along with the normal openid, profile, and email claims). Be aware that the scope name must match the claim name. For identity providers where the scope does not match (e.g. Keycloak: roles -> groups) you need to configure a custom scope.

      settings/auth/socialite

      lnms config:set auth.socialite.scopes.+ groups\n

      Then setup mappings from the returned claim arrays to the User levels you want

      settings/auth/socialite

      lnms config:set auth.socialite.claims.RETURN_FROM_CLAIM.roles '[\"admin\"]'\nlnms config:set auth.socialite.claims.OTHER_RETURN_FROM_CLAIM.roles '[\"global-read\",\"cleaner\"]'\n
      "},{"location":"Extensions/OAuth-SAML/#saml2-example","title":"SAML2 Example","text":""},{"location":"Extensions/OAuth-SAML/#install-plugin_1","title":"Install plugin","text":"

      The first step is to install the plugin itself.

      lnms plugin:add socialiteproviders/saml2\n
      "},{"location":"Extensions/OAuth-SAML/#add-configuration","title":"Add configuration","text":"

      Depending on what your identity provider (Google, Azure, ...) supports, the configuration could look different from what you see next so please use this as a rough guide. It is up the IdP to provide the relevant details that you will need for configuration.

      GoogleAzure

      Go to https://admin.google.com/ac/apps/unified

      Press \"DOWNLOAD METADATA\" and save the file somewhere accessible by your LibreNMS server

      ACS URL = https://your-librenms-url/auth/saml2/callback Entity ID = https://your-librenms-url/auth/saml2 Name ID format = PERSISTANT Name ID = Basic Information > Primary email

      First name = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname Last name = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname Primary email = http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.metadata \"$(cat /tmp/GoogleIDPMetadata.xml)\"\n

      Alternatively, you can copy the content of the file and run it like so, this will result in the exact same result as above.

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.metadata '''<?xml version=\"1.0\" encoding\n...\n...\n</md:EntityDescriptor>'''\n

      echo \"SESSION_SAME_SITE_COOKIE=none\" >> .env\nlnms plugin:add socialiteproviders/saml2\nlnms config:set auth.socialite.redirect true\nlnms config:set auth.socialite.register true\nlnms config:set auth.socialite.configs.saml2.acs https://login.microsoftonline.com/xxxidfromazurexxx/saml2\nlnms config:set auth.socialite.configs.saml2.entityid https://sts.windows.net/xxxidfromazurexxx/\nlnms config:set auth.socialite.configs.saml2.certificate xxxcertinonelinexxx\nlnms config:set auth.socialite.configs.saml2.listener \"\\SocialiteProviders\\Saml2\\Saml2ExtendSocialite\"\nlnms config:set auth.socialite.configs.saml2.metadata https://nexus.microsoftonline-p.com/federationmetadata/saml20/federationmetadata.xml\nlnms config:set auth.socialite.configs.saml2.sp_default_binding_method urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\nlnms config:clear\n

      "},{"location":"Extensions/OAuth-SAML/#using-an-identity-provider-metadata-url","title":"Using an Identity Provider metadata URL","text":"

      Note

      This is the prefered and easiest way, if your IdP supports it!

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.metadata https://idp.co/metadata/xml\n
      "},{"location":"Extensions/OAuth-SAML/#using-an-identity-provider-metadata-xml-file","title":"Using an Identity Provider metadata XML file","text":"

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.metadata \"$(cat GoogleIDPMetadata.xml)\"\n
      "},{"location":"Extensions/OAuth-SAML/#manually-configuring-the-identity-provider-with-a-certificate-string","title":"Manually configuring the Identity Provider with a certificate string","text":"

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.acs https://idp.co/auth/acs\nlnms config:set auth.socialite.configs.saml2.entityid http://saml.to/trust\nlnms config:set auth.socialite.configs.saml2.certificate MIIC4jCCAcqgAwIBAgIQbDO5YO....\n
      "},{"location":"Extensions/OAuth-SAML/#manually-configuring-the-identity-provider-with-a-certificate-file","title":"Manually configuring the Identity Provider with a certificate file","text":"

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.acs https://idp.co/auth/acs\nlnms config:set auth.socialite.configs.saml2.entityid http://saml.to/trust\nlnms config:set auth.socialite.configs.saml2.certificate \"$(cat /path/to/certificate.pem)\"\n
      "},{"location":"Extensions/OAuth-SAML/#add-provider-event-listener_1","title":"Add provider event listener","text":"

      Now we just need to define the listener service within LibreNMS:

      settings/auth/socialite

      lnms config:set auth.socialite.configs.saml2.listener \"\\SocialiteProviders\\Saml2\\Saml2ExtendSocialite\"\n
      "},{"location":"Extensions/OAuth-SAML/#session_same_site_cookie","title":"SESSION_SAME_SITE_COOKIE","text":"

      You most likely will need to set SESSION_SAME_SITE_COOKIE=none in .env if you use SAML2! If you get an error with http code 419, you should try to remove SESSION_SAME_SITE_COOKIE=none from your .env.

      Note

      Don't forget to run lnms config:clear after you modify .env to flush the config cache

      "},{"location":"Extensions/OAuth-SAML/#service-provider-metadata","title":"Service provider metadata","text":"

      Your identify provider might ask you for your Service Provider (SP) metadata. LibreNMS exposes all of this information from your LibreNMS install

      "},{"location":"Extensions/OAuth-SAML/#troubleshooting","title":"Troubleshooting","text":"

      If it doesn't work, please double check your configuration values by using the config:get command below.

      settings/auth/socialite

      lnms config:get auth.socialite\n
      "},{"location":"Extensions/OAuth-SAML/#redirect-url","title":"Redirect URL","text":"

      If you have a need to, then you can override redirect url with the following commands:

      OAuthSAML2

      Replace github and the relevant URL below with your identity provider details. lnms config:set auth.socialite.configs.github.redirect https://demo.librenms.org/auth/github/callback

      lnms config:set auth.socialite.configs.saml2.sp_acs auth/saml2/callback

      "},{"location":"Extensions/OAuth-SAML/#post-configuration-settings","title":"Post configuration settings","text":"

      settings/auth/socialite

      From here you can configure the settings for any identity providers you have configured along with some bespoke options.

      Redirect Login page: This setting will skip your LibreNMS login and take the end user straight to the first idP you configured.

      Allow registration via provider: If this setting is disabled, new users signing in via the idP will not be authenticated. This setting allows a local user to be automatically created which permits their login.

      "},{"location":"Extensions/Oxidized/","title":"Oxidized","text":"

      Integrating LibreNMS with Oxidized brings the following benefits:

      • Config viewing: Current, History, and Diffs all under the Configs tab of each device
      • Automatic addition of devices to Oxidized: Including filtering and grouping to ease credential management
      • Configuration searching (Requires oxidized-web 0.8.0 or newer)

      First you will need to install Oxidized following their documentation.

      Then you can procede to the LibreNMS Web UI and go to Oxidized Settings in the External Settings section of Global Settings. Enable it and enter the url to your oxidized instance.

      To have devices automatically added, you will need to configure oxidized to pull them from LibreNMS Feeding Oxidized Note: this means devices will be controlled by the LibreNMS API, and not router.db, passwords will still need to be in the oxidized config file.

      LibreNMS will automatically map the OS to the Oxidized model name if they don't match. this means you shouldn't need to use the model_map config option within Oxidized.

      "},{"location":"Extensions/Oxidized/#detailed-integration-information","title":"Detailed integration information","text":"

      This is a straight forward use of Oxidized, it relies on you having a working Oxidized setup which is already taking config snapshots for your devices. When you have that, you only need the following config to enable the display of device configs within the device page itself:

      external/oxidized

      lnms config:set oxidized.enabled true\nlnms config:set oxidized.url http://127.0.0.1:8888\n

      LibreNMS supports config versioning if Oxidized does. This is known to work with the git output module.

      external/oxidized

      lnms config:set oxidized.features.versioning true\n

      Oxidized supports various ways to utilise credentials to login to devices, you can specify global username/password within Oxidized, Group level username/password or per device. LibreNMS currently supports sending groups back to Oxidized so that you can then define group credentials within Oxidized. To enable this support please switch on 'Enable the return of groups to Oxidized':

      external/oxidized

      lnms config:set oxidized.group_support true\n

      You can set a default group that devices will fall back to with:

      external/oxidized

      lnms config:set oxidized.default_group default\n

      You can ignore specific groups

      external/oxidized

      lnms config:set oxidized.ignore_groups '[\"badgroup\", \"nobackup\"]'\n

      One trick you can do to ignore all ungrouped devices is set both of these settings

      external/oxidized

      lnms config:set oxidized.default_group nobackup\nlnms config:set oxidized.ignore_groups.+ nobackup\n
      "},{"location":"Extensions/Oxidized/#selinux","title":"SELinux","text":"

      If you're running SELinux, you'll need to allow httpd to connect outbound to the network, otherwise Oxidized integration in the web UI will silently fail:

      setsebool -P httpd_can_network_connect 1\n
      "},{"location":"Extensions/Oxidized/#feeding-oxidized","title":"Feeding Oxidized","text":"

      Oxidized has support for feeding devices into it via an API call, support for Oxidized has been added to the LibreNMS API. A sample config for Oxidized is provided below.

      You will need to configure default credentials for your devices in the Oxidized config, LibreNMS doesn't provide login credentials at this time.

            source:\n        default: http\n        debug: false\n        http:\n          url: https://librenms/api/v0/oxidized\n          map:\n            name: hostname\n            model: os\n            group: group\n          headers:\n            X-Auth-Token: '01582bf94c03104ecb7953dsadsadwed'\n

      LibreNMS is able to reload the Oxidized list of nodes, each time a device is added to LibreNMS. To do so, edit the option in Global Settings>External Settings>Oxidized Integration or add the following to your config.

      external/oxidized

      lnms config:set oxidized.reload_nodes true\n
      "},{"location":"Extensions/Oxidized/#creating-overrides","title":"Creating overrides","text":"

      To return an override to Oxidized you can do this by providing the override key, followed by matching a lookup for a host (or hosts), and finally by defining the overriding value itself. LibreNMS does not check for the validity of these attributes but will deliver them to Oxidized as defined.

      Matching of hosts can be done using hostname, sysname, os, location, sysDescr, hardware, purpose or notes and including either a 'match' key and value, or a 'regex' key and value. The order of matching is:

      • hostname
      • sysName
      • sysDescr
      • hardware
      • os
      • location
      • ip
      • purpose
      • notes

      To match on the device hostnames or sysNames that contain 'lon-sw' or if the location contains 'London' then you would set the following:

      external/oxidized

      lnms config:set oxidized.maps.group.hostname.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-switches\"}'\nlnms config:set oxidized.maps.group.sysName.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-switches\"}'\nlnms config:set oxidized.maps.group.location.+ '{\"regex\": \"/london/\", \"value\": \"london-switches\"}'\n

      To match on a device os of edgeos then please use the following:

      external/oxidized

      lnms config:set oxidized.maps.group.os.+ '{\"match\": \"edgeos\", \"value\": \"wireless\"}'\n

      Matching on OS requires system name of the OS. For example, \"match\": \"RouterOS\" will not work, while \"match\": \"routeros\" will.

      To match on a device purpose or device notes that contains 'lon-net' then you would set the following:

      external/oxidized

      lnms config:set oxidized.maps.group.purpose.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-network\"}'\nlnms config:set oxidized.maps.group.notes.+ '{\"regex\": \"/^lon-sw/\", \"value\": \"london-network\"}'\n

      To edit an existing map, you must use the index to override it.

      external/oxidized

      lnms config:get oxidized.maps.os.os\n[\n    {\n        \"match\": \"airos-af-ltu\",\n        \"value\": \"airfiber\"\n    },\n    {\n        \"match\": \"airos-af\",\n        \"value\": \"airfiber\"\n    },\n]\n\nlnms config:set oxidized.maps.os.os.1 '{\"match\": \"airos-af\", \"value\": \"something-else\"}'\n

      To override the IP Oxidized uses to poll the device, set the following:

      external/oxidized

      lnms config:set oxidized.maps.ip.sysName.+ '{\"regex\": \"/^my.node/\", \"value\": \"192.168.1.10\"}'\nlnms config:set oxidized.maps.ip.sysName.+ '{\"match\": \"my-other.node\", \"value\": \"192.168.1.20\"}'\n

      This allows extending the configuration further by providing a completely flexible model for custom flags and settings, for example, below shows the ability to add an ssh_proxy host within Oxidized simply by adding the below to your configuration:

      external/oxidized

      lnms config:set oxidized.maps.ssh_proxy.sysName.+ '{\"regex\": \"/^my.node/\", \"value\": \"my-ssh-gateway.node\"}'\n

      Or of course, any custom value that could be needed or wanted can be applied, for example, setting a \"myAttribute\" to \"Super cool value\" for any configured and enabled \"routeros\" device.

      external/oxidized

      lnms config:set oxidized.maps.myAttribute.os.+ '{\"match\": \"routeros\", \"value\": \"Super cool value\"}'\n

      Verify the return of groups by querying the API:

      curl -H 'X-Auth-Token: YOURAPITOKENHERE' https://librenms.org/api/v0/oxidized\n

      If you need to, you can specify credentials for groups by using the following in your Oxidized config:

      groups:\n  <groupname>:\n    username: <user>\n    password: <password>\n
      "},{"location":"Extensions/Oxidized/#miscellaneous","title":"Miscellaneous","text":"

      If you have devices which you do not wish to appear in Oxidized then you can edit those devices in Device -> Edit -> Misc and enable \"Exclude from Oxidized?\"

      The use of custom ssh and telnet ports can be set through device settings misc tab, and can be passed on to oxidized with the following vars_map

            source:\n        http:\n          map:\n            name: hostname\n            model: os\n            group: group\n          vars_map:\n            ssh_port: ssh_port\n            telnet_port: telnet_port\n

      It's also possible to exclude certain device types and OS' from being output via the API.

      external/oxidized

      lnms config:set oxidized.ignore_types '[\"server\", \"power\"]'\nlnms config:set oxidized.ignore_os '[\"linux\", \"windows\"]'\n

      You can also ignore whole groups of devices

      external/oxidized

      lnms config:set oxidized.ignore_groups '[\"london-switches\", \"default\"]'\n
      "},{"location":"Extensions/Oxidized/#trigger-configuration-backups","title":"Trigger configuration backups","text":"

      Using the Oxidized REST API and Syslog Hooks, Oxidized can trigger configuration downloads whenever a configuration change event has been logged. An example script to do this is included in ./scripts/syslog-notify-oxidized.php. Oxidized can spawn a new worker thread and perform the download immediately with the following configuration

      next_adds_job: true\n
      "},{"location":"Extensions/Oxidized/#validate-oxidized-config","title":"Validate Oxidized config","text":"

      You can perform basic validation of the Oxidized configuration by going to the Overview -> Tools -> Oxidized link and in the Oxidized config validation page, paste your yaml file into the input box and click 'Validate YAML'.

      We check for yaml syntax errors and also actual config values to ensure they are used in the correct location.

      "},{"location":"Extensions/Oxidized/#accessing-configuration-of-a-disabledremoved-device","title":"Accessing configuration of a disabled/removed device","text":"

      When you're disabling or removing a device from LibreNMS, the configuration will no longer be available via the LibreNMS web interface. You can gain access to these configurations directly in the Git repository of Oxidized (if using Git for version control).

      1: Check in your Oxidized where are stored your Git repositories:

      /home/oxidized/.config/oxidized/config\n

      2: Go the correct Git repository for the needed device (the .git one) and get the list of devices using this command:

      git ls-files -s\n

      3: Save the object ID of the device, and run the command to get the file content:

      git cat-file -p <object id>\n
      "},{"location":"Extensions/Oxidized/#remove-disabledremoved-device","title":"Remove disabled/removed device","text":"

      If you want to purge saved config of a device that is not in LibreNMS anymore, you can run the following command:

      git rm --cached <object id>\n
      "},{"location":"Extensions/PeeringDB/","title":"PeeringDB Support","text":"

      LibreNMS has integration with PeeringDB to match up your BGP sessions with the peering exchanges you are connected to.

      To enable the integration please do so within the WebUI

      external/peeringdb

      lnms config:set peeringdb.enabled true\n

      Data will be collated the next time daily.sh is run or you can manually force this by running php daily.php -f peeringdb, the initial collection is delayed for a random amount of time to avoid overloading the PeeringDB API.

      Once enabled you will have an additional menu item under Routing -> PeeringDB

      "},{"location":"Extensions/Plugin-System/","title":"Developing for the Plugin System","text":"

      With plugins you can extend LibreNMS with special functions that are specific to your setup or are not relevant or interesting for all community members.

      You are able to intervene in defined places in the behavior of the website, without it coming to problems with future updates.

      This documentation will give you a basis for writing a plugin for LibreNMS. An example plugin is included in the LibreNMS distribution.

      "},{"location":"Extensions/Plugin-System/#version-2-plugin-system-structure","title":"Version 2 Plugin System structure","text":"

      Plugins in version 2 need to be installed into app/Plugins

      Note: Plugins are disabled when the have an error, to show errors instead set plugins.show_errors

      The structure of a plugin is follows:

      app/Plugins\n            /PluginName\n                       /DeviceOverview.php\n                       /Menu.php\n                       /Page.php\n                       /PortTab.php\n                       /Settings.php\n                       /resources/views\n                                       /device-overview.blade.php\n                                       /menu.blade.php\n                                       /page.blade.php\n                                       /port-tab.blade.php\n                                       /settings.blade.php\n

      The above structure is checked before a plugin can be installed.

      All file/folder names are case sensitive and must match the structure.

      Only the blade files that are really needed need to be created. A plugin manager will then load a hook that has a basic functionality.

      If you want to customize the basic behavior of the hooks, you can create a class in 'app/Plugins/PluginName' and overload the hook methods.

      • device-overview.blade.php :: This is called in the Device Overview page. You receive the $device as a object per default, you can do your work here and display your results in a frame.
      <div class=\"row\">\n    <div class=\"col-md-12\">\n        <div class=\"panel panel-default panel-condensed\">\n            <div class=\"panel-heading\">\n                <strong>{{ $title }}</strong>\n            </div>\n            <div class=\"panel-body\">\n                <div class=\"row\">\n                    <div class=\"col-sm-12\">\n                         {{ $device->hostname }}\n                 <!-- Do you stuff here -->\n                    </div>\n        </div>\n        </div>\n    </div>\n    </div>\n</div>\n
      • port-tab.blade.php :: This is called in the Port page, in the \"Plugins\" menu_option that will appear when your plugin gets enabled. In this blade, you can do your work and display your results in a frame.

      • menu.blade.php :: For a menu entry

      • page.blade.pho :: Here is a good place to add a own LibreNMS page without dependence with a device. A good place to create your own lists with special requirements and behavior.

      • settings.blade.php :: If you need your own settings and variables, you can have a look in the ExamplePlugin.

      "},{"location":"Extensions/Plugin-System/#php-hooks-customization","title":"PHP Hooks customization","text":"

      PHP code should run inside your hooks method and not your blade view. The built in hooks support authorize and data methods.

      These methods are called with Dependency Injection Hooks with relevant database models will include them in these calls. Additionally, the settings argument may be included to inject the plugin settings into the method.

      "},{"location":"Extensions/Plugin-System/#data","title":"Data","text":"

      You can overrid the data method to supply data to your view. You should also do any processing here. You can do things like access the database or configuration settings and more.

      In the data method we are injecting settings here to count how many we have for display in the menu entry blade view. Note that you must specify a default value (= [] here) for any arguments that don't exist on the parent method.

      class Menu extends MenuEntryHook\n{\n    public function data(array $settings = []): array\n    {\n        return [\n            'count' => count($settings),\n        ];\n    }\n}\n
      "},{"location":"Extensions/Plugin-System/#authorize","title":"Authorize","text":"

      By default hooks are always shown, but you may control when the user is authorized to view the hook content.

      As an example, you could imagine that the device-overview.blade.php should only be displayed when the device is in maintanence mode and the current user has the admin role.

      class DeviceOverview extends DeviceOverviewHook\n{\n    public function authorize(User $user, Device $device): bool\n    {\n        return $user->can('admin') && $device->isUnderMaintenance();\n    }\n}\n
      "},{"location":"Extensions/Plugin-System/#full-plugin","title":"Full plugin","text":"

      You may create a full plugin that can publish multiple routes, views, database migrations and more. Create a package according to the Laravel documentation you may call any of the supported hooks to tie into LibreNMS.

      https://laravel.com/docs/packages

      This is untested, please come to discord and share any expriences and update this documentation!

      "},{"location":"Extensions/Plugin-System/#version-1-plugin-system-structure-legacy-version","title":"Version 1 Plugin System structure (legacy version)","text":"

      Plugins need to be installed into html/plugins

      The structure of a plugin is follows:

      html/plugins\n            /PluginName\n                       /PluginName.php\n                       /PluginName.inc.php\n

      The above structure is checked before a plugin can be installed.

      All files / folder names are case sensitive and must match.

      PluginName - This is a directory and needs to be named as per the plugin you are creating.

      • PluginName.php :: This file is used to process calls into the plugin from the main LibreNMS install. Here only functions within the class for your plugin that LibreNMS calls will be executed. For a list of currently enabled system hooks, please see further down. The minimum code required in this file is (replace Test with the name of your plugin):
      <?php\n\nclass Test {\n}\n\n?>\n
      • PluginName.inc.php :: This file is the main included file when browsing to the plugin itself. You can use this to display / edit / remove whatever you like. The minimum code required in this file is:
      <?php\n\n?>\n
      "},{"location":"Extensions/Plugin-System/#system-hooks","title":"System Hooks","text":"

      System hooks are called as functions within your plugin class. The following system hooks are currently available:

      • menu() :: This is called to build the plugin menu system and you can use this to link to your plugin (you don't have to).
          public static function menu() {\n        echo('<li><a href=\"plugin/p='.get_class().'\">'.get_class().'</a></li>');\n    }\n
      • device_overview_container($device) :: This is called in the Device Overview page. You receive the $device as a parameter, can do your work here and display your results in a frame.
          public static function device_overview_container($device) {\n        echo('<div class=\"container-fluid\"><div class=\"row\"> <div class=\"col-md-12\"> <div class=\"panel panel-default panel-condensed\"> <div class=\"panel-heading\"><strong>'.get_class().' Plugin </strong> </div>');\n        echo('  Example plugin in \"Device - Overview\" tab <br>');\n        echo('</div></div></div></div>');\n    }\n
      • port_container($device, $port) :: This is called in the Port page, in the \"Plugins\" menu_option that will appear when your plugin gets enabled. In this function, you can do your work and display your results in a frame.
          public static function port_container($device, $port) {\n        echo('<div class=\"container-fluid\"><div class=\"row\"> <div class=\"col-md-12\"> <div class=\"panel panel-default panel-condensed\"> <div class=\"panel-heading\"><strong>'.get_class().' plugin in \"Port\" tab</strong> </div>');\n        echo ('Example display in Port tab</br>');\n        echo('</div></div></div></div>');\n    }\n
      "},{"location":"Extensions/Proxmox/","title":"Proxmox graphing","text":"

      It is possible to create graphs of the Proxmox VMs that run on your monitored machines. Currently, only traffic graphs are created. One for each interface on each VM. Possibly, IO graphs will be added later on.

      The ultimate goal is to be able to create traffic bills for VMs, no matter on which physical machine that VM runs.

      "},{"location":"Extensions/Proxmox/#enabling-proxmox-graphs","title":"Enabling Proxmox graphs","text":"

      To enable Proxmox graphs, do the following:

      In config.php, enable Proxmox:

      $config['enable_proxmox'] = 1;\n

      Then, install git and librenms-agent on the machines running Proxmox and enable the Proxmox-script using:

      cp /opt/librenms-agent/agent-local/proxmox /usr/lib/check_mk_agent/local/proxmox\nchmod +x /usr/lib/check_mk_agent/local/proxmox\n

      Then, enable and start the check_mk service using systemd

      cp /opt/librenms-agent/check_mk@.service /opt/librenms-agent/check_mk.socket /etc/systemd/system\nsystemctl daemon-reload\nsystemctl enable check_mk.socket && systemctl start check_mk.socket\n

      Then in LibreNMS active the librenms-agent and proxmox application flag for the device you are monitoring. You should now see an application in LibreNMS, as well as a new menu-item in the topmenu, allowing you to choose which cluster you want to look at.

      "},{"location":"Extensions/Proxmox/#note-if-you-want-to-use-use-xinetd-instead-of-systemd","title":"Note, if you want to use use xinetd instead of systemd","text":"

      Its possible to use the librenms-agent started by xinetd instead of systemd. One use case is if you are forced to use a old Proxmox installation. After installing the librenms-agent (see above) please copy enable the xinetd config, then restart the xinetd service:

      cp check_mk_xinetd /etc/xinetd.d/check_mk\n/etc/init.d/xinetd restart\n
      "},{"location":"Extensions/RRDCached/","title":"Setting up RRDCached","text":"

      This document will explain how to set up RRDCached for LibreNMS.

      Since version 1.5, rrdtool / rrdcached now supports creating rrd files over rrdcached. If you have rrdcached 1.5.5 or above, you can also tune over rrdcached. To enable this set the following config:

      poller/rrdtool

      lnms config:set rrdtool_version '1.5.5'\n

      This setting has to be the exact version of rrdtool you are running.

      NOTE: This feature requires your client version of rrdtool to be 1.5.5 or newer, in addition to your rrdcached version.

      "},{"location":"Extensions/RRDCached/#distributed-poller-support-matrix","title":"Distributed Poller Support Matrix","text":"

      Shared FS: Is a shared filesystem required?

      Features: Supported features in the version indicated.

      G = Graphs.\nC = Create RRD files.\nU = Update RRD files.\nT = Tune RRD files.\n
      Version Shared FS Features 1.4.x Yes G,U <1.5.5 Yes G,U >=1.5.5 No G,C,U >=1.6.x No G,C,U >=1.8.x No G,C,U,T

      It is recommended that you monitor your LibreNMS server with LibreNMS so you can view the disk I/O usage delta.

      "},{"location":"Extensions/RRDCached/#installation-manual-for","title":"Installation Manual for","text":"
      1. RRDCached installation Ubuntu 16
      2. RRDCached installation Debian Buster
      3. RRDCached installation Debian Stretch
      4. RRDCached installation CentOS 7 or 8
      5. RRDCached installation CentOS 6
      6. Securing RRCached
      "},{"location":"Extensions/RRDCached/#rrdcached-installation-ubuntu-16","title":"RRDCached installation Ubuntu 16","text":"

      1: Install rrdcached

      sudo apt-get install rrdcached\n

      2: Edit /etc/default/rrdcached to include:

      DAEMON=/usr/bin/rrdcached\nDAEMON_USER=librenms\nDAEMON_GROUP=librenms\nWRITE_THREADS=4\nWRITE_TIMEOUT=1800\nWRITE_JITTER=1800\nBASE_PATH=/opt/librenms/rrd/\nJOURNAL_PATH=/var/lib/rrdcached/journal/\nPIDFILE=/run/rrdcached.pid\nSOCKFILE=/run/rrdcached.sock\nSOCKGROUP=librenms\nBASE_OPTIONS=\"-B -F -R\"\n

      2: Fix permissions

      chown librenms:librenms /var/lib/rrdcached/journal/\n

      3: Restart the rrdcached service

      systemctl restart rrdcached.service\n

      5: Edit your config to include:

      poller/rrdtool

      lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n
      "},{"location":"Extensions/RRDCached/#rrdcached-installation-debian-buster","title":"RRDCached installation Debian Buster","text":"

      (rrdcached 1.7.1)

      1: Install rrdcached

      sudo apt-get install rrdcached\n

      2; Edit /etc/default/rrdcached to include:

      DAEMON=/usr/bin/rrdcached\nWRITE_TIMEOUT=1800\nWRITE_JITTER=1800\nWRITE_THREADS=4\nBASE_PATH=/opt/librenms/rrd/\nJOURNAL_PATH=/var/lib/rrdcached/journal/\nPIDFILE=/var/run/rrdcached.pid\nSOCKFILE=/run/rrdcached.sock\nSOCKGROUP=librenms\nDAEMON_GROUP=librenms\nDAEMON_USER=librenms\nBASE_OPTIONS=\"-B -F -R\"\n

      3: Fix permissions

      chown librenms:librenms /var/lib/rrdcached/journal/\n

      4: Restart the rrdcached service

      systemctl restart rrdcached.service\n

      5: Edit your config to include:

      For local RRDCached server

      poller/rrdtool

      lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n

      For remote RRDCached server make sure you have network option in /var/default/rrdcached

      NETWORK_OPTIONS=\"-L\"\n

      poller/rrdtool

      lnms config:set rrdcached \"IPADDRESS:42217\"\n

      NOTE: change IPADDRESS to the ip the rrdcached server is listening on.

      "},{"location":"Extensions/RRDCached/#rrdcached-installation-debian-stretch","title":"RRDCached installation Debian Stretch","text":"

      (rrdcached 1.6.0)

      1: Install rrdcached

      sudo apt-get install rrdcached\n

      2; Edit /etc/default/rrdcached to include:

      DAEMON=/usr/bin/rrdcached\nWRITE_TIMEOUT=1800\nWRITE_JITTER=1800\nWRITE_THREADS=4\nBASE_PATH=/opt/librenms/rrd/\nJOURNAL_PATH=/var/lib/rrdcached/journal/\nPIDFILE=/var/run/rrdcached.pid\nSOCKFILE=/run/rrdcached.sock\nSOCKGROUP=librenms\nDAEMON_GROUP=librenms\nDAEMON_USER=librenms\nBASE_OPTIONS=\"-B -F -R\"\n

      3: Fix permissions

      chown librenms:librenms /var/lib/rrdcached/journal/\n

      4: Restart the rrdcached service

      systemctl restart rrdcached.service\n

      5: Edit your config to include:

      For local RRDCached server

      poller/rrdtool

      lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n

      For remote RRDCached server make sure you have network option in /var/default/rrdcached

      NETWORK_OPTIONS=\"-L\"\n

      poller/rrdtool

      lnms config:set rrdcached \"IPADDRESS:42217\"\n

      NOTE: change IPADDRESS to the ip the rrdcached server is listening on.

      "},{"location":"Extensions/RRDCached/#rrdcached-installation-centos-7-or-8","title":"RRDCached installation CentOS 7 or 8","text":"

      1: Create /etc/systemd/system/rrdcached.service with this content:

      [Unit]\nDescription=Data caching daemon for rrdtool\nAfter=network.service\n\n[Service]\nType=forking\nPIDFile=/run/rrdcached.pid\nExecStart=/usr/bin/rrdcached -w 1800 -z 1800 -f 3600 -s librenms -U librenms -G librenms -B -R -j /var/tmp -l unix:/run/rrdcached.sock -t 4 -F -b /opt/librenms/rrd/\n\n[Install]\nWantedBy=default.target\n

      2: Configure SELinux for RRDCached

      cat > rrdcached_librenms.te << EOF\nmodule rrdcached_librenms 1.0;\n\nrequire {\n        type var_run_t;\n        type tmp_t;\n        type httpd_t;\n        type rrdcached_t;\n        type httpd_sys_rw_content_t;\n        class dir { add_name getattr open read remove_name rmdir search write };\n        class file { create getattr open read rename setattr unlink write map lock };\n        class sock_file { create setattr unlink write };\n        class capability { fsetid sys_resource };\n        class unix_stream_socket connectto;\n}\n\n#============= rrdcached_t ==============\n\nallow rrdcached_t httpd_sys_rw_content_t:dir { add_name getattr remove_name search write };\nallow rrdcached_t httpd_sys_rw_content_t:file { create getattr open read rename setattr unlink write map lock };\nallow rrdcached_t self:capability fsetid;\nallow rrdcached_t var_run_t:sock_file { create setattr unlink };\nallow httpd_t var_run_t:sock_file write;\nallow httpd_t rrdcached_t:unix_stream_socket connectto;\nEOF\n\ncheckmodule -M -m -o rrdcached_librenms.mod rrdcached_librenms.te\nsemodule_package -o rrdcached_librenms.pp -m rrdcached_librenms.mod\nsemodule -i rrdcached_librenms.pp\n

      3: Start rrdcached

      systemctl enable --now rrdcached.service\n

      4: Edit your config to include:

      poller/rrdtool

      lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n
      "},{"location":"Extensions/RRDCached/#rrdcached-installation-centos-6","title":"RRDCached installation CentOS 6","text":"

      This example is based on a fresh LibreNMS install, on a minimal CentOS 6 installation. In this example, we'll use the Repoforge repository.

      rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm\nvi /etc/yum.repos.d/rpmforge.repo\n
      • Enable the Extra repo
      yum update rrdtool\nvi /etc/yum.repos.d/rpmforge.repo\n
      • Disable the [rpmforge] and [rpmforge-extras] repos again
      vi /etc/sysconfig/rrdcached\n\n# Settings for rrdcached\nOPTIONS=\"-w 1800 -z 1800 -f 3600 -s librenms -U librenms -G librenms -B -R -j /var/tmp -l unix:/run/rrdcached.sock -t 4 -F -b /opt/librenms/rrd/\"\nRRDC_USER=librenms\n\nmkdir /var/run/rrdcached\nchown librenms:librenms /var/run/rrdcached/\nchown librenms:librenms /var/rrdtool/\nchown librenms:librenms /var/rrdtool/rrdcached/\nchkconfig rrdcached on\nservice rrdcached start\n
      • Edit your config to include:

      poller/rrdtool

      lnms config:set rrdcached \"unix:/run/rrdcached.sock\"\n
      "},{"location":"Extensions/RRDCached/#verify","title":"Verify","text":"

      Check to see if the graphs are being drawn in LibreNMS. This might take a few minutes. After at least one poll cycle (5 mins), check the LibreNMS disk I/O performance delta. Disk I/O can be found under the menu Devices>All Devices>[localhost hostname]>Health>Disk I/O.

      Depending on many factors, you should see the Ops/sec drop by ~30-40%.

      "},{"location":"Extensions/RRDCached/#securing-rrcached","title":"Securing RRCached","text":"

      According to the man page, under \"SECURITY CONSIDERATIONS\", rrdcached has no authentication or security except for running under a unix socket. If you choose to use a network socket instead of a unix socket, you will need to secure your rrdcached installation. To do so you can proxy rrdcached using nginx to allow only specific IPs to connect.

      Using the same setup above, using nginx version 1.9.0 or later, you can follow this setup to proxy the default rrdcached port to the local unix socket.

      (You can use ./conf.d for your configuration as well)

      mkdir /etc/nginx/streams-{available,enabled}

      add the following to your nginx.conf file:

      #/etc/nginx/nginx.conf\n...\nstream {\n    include /etc/nginx/streams-enabled/*;\n}\n

      Add this to /etc/nginx/streams-available/rrd

      server {\n    listen 42217;\n\n    error_log  /var/log/nginx/rrd.stream.error.log;\n\n    allow $LibreNMS_IP;\n    deny all;\n\n    proxy_pass unix:/run/rrdcached.sock;\n}\n

      Replace $LibreNMS_IP with the ip of the server that will be using rrdcached. You can specify more than one allow statement. This will bind nginx to TCP 42217 (the default rrdcached port), allow the specified IPs to connect, and deny all others.

      next, we'll symlink the config to streams-enabled: ln -s /etc/nginx/streams-{available,enabled}/rrd

      and reload nginx service nginx reload

      "},{"location":"Extensions/RRDTune/","title":"RRDTune","text":"

      When we create rrd files for ports, we currently do so with a max value of 12500000000 (100G). Because of this if a device sends us bad data back then it can appear as though a 100M port is doing 40G+ which is impossible. To counter this you can enable the rrdtool tune option which will fix the max value to the interfaces physical speed (minimum of 10M).

      To enable this you can do so in three ways!

      • Globally under Global Settings -> Poller -> Datastore: RRDTool
      • For the actual device, Edit Device -> Misc
      • For each port, Edit Device -> Port Settings

      Now when a port interface speed changes (this can happen because of a physical change or just because the device has misreported) the max value is set. If you don't want to wait until a port speed changes then you can run the included script:

      ./scripts/tune_port.php -h <hostname> -p <ifName>

      Wildcards are supported using *, i.e:

      ./scripts/tune_port.php -h local* -p eth*

      This script will then perform the rrdtool tune on each port found using the provided ifSpeed for that port.

      Run ./scripts/tune_port.php to see help page.

      "},{"location":"Extensions/Rancid/","title":"Rancid","text":"

      Librenms can generate a list of hosts that can be monitored by RANCID. We assume you have currently a running Rancid, and you just need to create and update the file 'router.db'

      "},{"location":"Extensions/Rancid/#included-rancid-script","title":"Included Rancid script","text":"

      To generate the config file (maybe even add a cron to schedule this). We've assumed a few locations for Rancid, the config file you want to call it and where LibreNMS is:

      cd /opt/librenms/scripts/\nphp ./gen_rancid.php > /the/path/where/is/rancid/core/router.db\n

      Sample cron:

      15   0    * * * root cd /opt/librenms/scripts && php ./gen_rancid.php > /the/path/where/is/rancid/core/router.db\n

      Now configure LibreNMS (make sure you point dir to your rancid data directory):

      $config['rancid_configs']['core'] = '/the/path/where/is/rancid/core';\n$config['rancid_ignorecomments'] = 0;\n

      After that, you should see some \"config\" tab on routers that have a rancid update.

      "},{"location":"Extensions/Rancid/#ubuntu-rancid-install","title":"Ubuntu Rancid Install","text":"

      The options shown below also contains the default values.

      NOTE - This is Only for Ubuntu 16.04 at this time, and may not work on other distros!

      sudo apt-get install rancid subversion

      Edit Rancid config file to use subversion or git instead of default cvs, and adds a group: sudo vi /etc/rancid/rancid.conf

      LIST_OF_GROUPS=\"librenms\"

      Now change these two lines:

      CVSROOT=$BASEDIR/CVS; export CVSROOT\nRCSSYS=cvs; export RCSSYS\n

      to:

      CVSROOT=$BASEDIR/SVN; export CVSROOT\nRCSSYS=svn; export RCSSYS\n

      NOTE - This only creates 1 group! You can of course make more when you get the hang of it, this is just a basic 'Need it to work\" deal.

      sudo su -c /var/lib/rancid/bin/rancid-cvs -s /bin/bash -l rancid

      NOTE - do NOT change cvs to svn here! Leave command as is!

      Get a list of devices from Librenms you can pull configs from:

      cd /opt/librenms/scripts\nsudo ./gen_rancid.php\n

      Copy the output. Replace all \":\" with \";\" example:

      alphcr1:cisco:up will change to:\nalphcr1;cisco;up\n

      copy and past results into the below file: sudo vi /var/lib/rancid/librenms/router.db

      NOTE - This ONLY applies to newer RANCID versions and Linux distros. Older versions will need to retain the : and not the ;

      Create/edit rancids login file:

      sudo vi /var/lib/rancid/.cloginrc

      Add following at minimum:

      add user * <your username here>\nadd password * <your password here>\nadd method * ssh\nadd noenable * {1}                         ******This disables the enable when using radius etc *******\n

      Grant permissions for rancid:

      sudo chown rancid /var/lib/rancid/.cloginrc\nsudo chmod 600 /var/lib/rancid/.cloginrc\n

      Test config: sudo /usr/lib/rancid/bin/clogin -f /var/lib/rancid/.cloginrc <device hostname>

      NOTE: IF you run into a 'diffie-hellmen' kind of error, then it is because your Linux distro is using newer encryption methods etc. This is basically just letting you know that the device you tested on is running an outdated encryption type. I recommend updating downstream device if able. If not, the following should fix:

      sudo vi /etc/ssh/ssh_config

      Add:

      KexAlgorithms diffie-hellman-group1-sha1

      Re-try logging into your device again

      Upon success, run rancid:

      sudo su -c /var/lib/rancid/bin/rancid-run -s /bin/bash -l rancid

      Ensure your configs pulled:

      sudo su - rancid\ncd librenms/configs/\nls\n

      Make sure your config files are there :-)

      sudo usermod -a -G rancid librenms\n

      Add Rancid into LibreNMS config.php:

      ### Rancid\n$config['rancid_configs'][]             = '/var/lib/rancid/librenms/configs/';\n$config['rancid_repo_type']             = 'svn';  //'svn' or 'git'\n$config['rancid_ignorecomments']        = 0;\n

      Now restart apache sudo /etc/init.d/apache2 restart

      "},{"location":"Extensions/SNMP-Proxy/","title":"SNMP Proxy","text":"

      If you have machines that you want to monitor but are not reachable directly, you can use SNMPD Proxy. This will use the reachable SNMPD to proxy requests to the unreachable SNMPD.

      "},{"location":"Extensions/SNMP-Proxy/#example-configuration","title":"Example configuration","text":"

      We want to poll 'unreachable.example.com' via

      'hereweare.example.com'. Use the following config:

      On 'hereweare.example.com':

              view all included .1\n        com2sec -Cn ctx_unreachable readonly <poller-ip> unreachable\n        access MyROGroup ctx_unreachable any noauth prefix all none none\n        proxy -Cn ctx_unreachable -v 2c -c private unreachable.example.com  .1.3\n

      On 'unreachable.example.com':

              view all included .1                               80\n        com2sec readonly <hereweare.example.com ip address> private\n        group MyROGroup v1 readonly\n        group MyROGroup v2c readonly\n        group MyROGroup usm readonly\n        access MyROGroup \"\" any noauth exact all none none\n

      You can now poll community 'private' on 'unreachable.example.com' via community 'unreachable' on host 'hereweare.example.com'. Please note that requests on 'unreachable.example.com' will be coming from 'hereweare.example.com', not your poller.

      "},{"location":"Extensions/SNMP-Trap-Handler/","title":"SNMP trap handling","text":"

      Currently, LibreNMS supports a lot of trap handlers. You can check them on GitHub here. To add more see Adding new SNMP Trap handlers. Traps are handled via snmptrapd.

      snmptrapd is an SNMP application that receives and logs SNMP TRAP and INFORM messages.

      The default is to listen on UDP port 162 on all IPv4 interfaces. Since 162 is a privileged port, snmptrapd must typically be run as root.

      "},{"location":"Extensions/SNMP-Trap-Handler/#configure-snmptrapd","title":"Configure snmptrapd","text":"

      Install snmptrapd via your package manager.

      For example (Debian based systems):

      sudo apt install snmptrapd -y\n

      In /etc/snmp/snmptrapd.conf, add :

      disableAuthorization yes\nauthCommunity log,execute,net COMMUNITYSTRING\ntraphandle default /opt/librenms/snmptrap.php\n

      To enable snmptrapd to properly parse traps, we will need to add MIBs to service.

      "},{"location":"Extensions/SNMP-Trap-Handler/#option-1","title":"Option 1","text":"

      Make the folder /etc/systemd/system/snmptrapd.service.d/ and edit the file /etc/systemd/system/snmptrapd.service.d/mibs.conf and add the following content.

      You may want to tweak to add vendor directories for devices you care about. In the example below, standard and cisco directories are defined, and only IF-MIB is loaded.

      [Service]\nEnvironment=MIBDIRS=+/opt/librenms/mibs:/opt/librenms/mibs/cisco\nEnvironment=MIBS=+IF-MIB\n

      For non-systemd systems, you can edit TRAPDOPTS in the init script in /etc/init.d/snmptrapd.

      TRAPDOPTS=\"-Lsd -M /opt/librenms/mibs -m IF-MIB -f -p $TRAPD_PID\"

      Along with any necessary configuration to receive the traps from your devices (community, etc.)

      "},{"location":"Extensions/SNMP-Trap-Handler/#option-2","title":"Option 2","text":"

      Tested on Ubuntu 18

      Just set up your service like:

      [Unit]\nDescription=Simple Network Management Protocol (SNMP) Trap Daemon.\nAfter=network.target\nConditionPathExists=/etc/snmp/snmptrapd.conf\n\n[Service]\nEnvironment=\"MIBSDIR=/opt/librenms/mibs\"\nType=simple\nExecStart=/usr/sbin/snmptrapd -f -m IF-MIB -M /opt/librenms/mibs\nExecReload=/bin/kill -HUP $MAINPID\n\n[Install]\nWantedBy=multi-user.target\n

      In Ubuntu 18 is service located by default in /etc/systemd/system/multi-user.target.wants/snmptrapd.service

      Here is a list of snmptrapd options:

      Option Description -a Ignore authenticationFailure traps. [OPTIONAL] -f Do not fork from the shell -n Use numeric addresses instead of attempting hostname lookups (no DNS) [OPTIONAL] -m MIBLIST: use MIBLIST (FILE1-MIB:FILE2-MIB). ALL = Load all MIBS in DIRLIST. (usually fails) -M DIRLIST: use DIRLIST as the list of locations to look for MIBs. Option is not recursive, so you need to specify each DIR individually, separated by :. (For example: /opt/librenms/mibs:/opt/librenms/mibs/cisco:/opt/librenms/mibs/edgecos)

      Good practice is to avoid -m ALL because then it will try to load all the MIBs in DIRLIST, which will typically fail (snmptrapd cannot load that many mibs). Better is to specify the exact MIB files defining the traps you are interested in, for example for LinkDown and LinkUp as well as BGP traps, use -m IF-MIB:BGP4-MIB. Multiple files can be added, separated with :.

      If you want to test or store original TRAPS in log then:

      Create a folder for storing traps for example in file traps.log

      sudo mkdir /var/log/snmptrap\n

      Add the following config to your snmptrapd.service after ExecStart=/usr/sbin/snmptrapd -f -m ALL -M /opt/librenms/mibs

      -tLf /var/log/snmptrap/traps.log\n

      On SELinux, you need to configure SELinux for SNMPd to communicate to LibreNMS:

      cat > snmptrap.te << EOF\nmodule snmptrap 1.0;\n\nrequire {\n        type httpd_sys_rw_content_t;\n        type snmpd_t;\n        class file { append getattr open read };\n        class capability dac_override;\n}\n\n#============= snmpd_t ==============\n\nallow snmpd_t httpd_sys_rw_content_t:file { append getattr open read };\nallow snmpd_t self:capability dac_override;\nEOF\ncheckmodule -M -m -o snmptrap.mod snmptrap.te\nsemodule_package -o snmptrap.pp -m snmptrap.mod\nsemodule -i snmptrap.pp\n

      After successfully configuring the service, reload service files, enable, and start the snmptrapd service:

      sudo systemctl daemon-reload\nsudo systemctl enable snmptrapd\nsudo systemctl restart snmptrapd\n
      "},{"location":"Extensions/SNMP-Trap-Handler/#testing","title":"Testing","text":"

      The easiest test is to generate a trap from your device. Usually, changing the configuration on a network device, or plugging/unplugging a network cable (LinkUp, LinkDown) will generate a trap. You can confirm it using a with tcpdump, tshark or wireshark.

      You can also generate a trap using the snmptrap command from the LibreNMS server itself (if and only if the LibreNMS server is monitored).

      "},{"location":"Extensions/SNMP-Trap-Handler/#how-to-send-snmp-v2-trap","title":"How to send SNMP v2 Trap","text":"

      The command below takes the form of:

      snmptrap -v <snmp_version> -c <community> <destination_host> <uptime> <OID_or_MIB> <object> <value_type> <value>\n

      Using OID's:

      snmptrap -v 2c -c public localhost '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 123456\n

      If you have configured logging of traps to /var/log/snmptrap/traps.log then you will see in traps.log new entry:

      2020-03-09 16:22:59 localhost [UDP: [127.0.0.1]:58942->[127.0.0.1]:162]:\nSNMPv2-MIB::sysUpTime.0 = Timeticks: (149721964) 17 days, 7:53:39.64    SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.8072.2.3.0.1   SNMPv2-SMI::enterprises.8072.2.3.2.1 = INTEGER: 123456\n

      and in LibreNMS your localhost device eventlog like:

      2020-03-09 16:22:59             SNMP trap received: SNMPv2-SMI::enterprises.8072.2.3.0.1\n
      "},{"location":"Extensions/SNMP-Trap-Handler/#why-we-need-uptime","title":"Why we need Uptime","text":"

      When you send a trap, it must of course conform to a set of standards. Every trap needs an uptime value. Uptime is how long the system has been running since boot. Sometimes this is the operating system, other devices might use the SNMP engine uptime. Regardless, a value will be sent.

      So what value should you type in the commands below? Oddly enough, simply supplying no value by using two single quotes '' will instruct the command to obtain the value from the operating system you are executing this on.

      "},{"location":"Extensions/SNMP-Trap-Handler/#event-logging","title":"Event logging","text":"

      You can configure generic event logging for snmp traps. This will log an event of the type trap for received traps. These events can be used for alerting. By default, only the TrapOID is logged. But you can enable the \"detailed\" variant, and all the data received with the trap will be logged.

      The parameter can be found in General Settings / External / SNMP Traps Integration.

      It can also be configured in your config.

      external/snmptrapd

      lnms config:set snmptraps.eventlog 'unhandled'\nlnms config:set snmptraps.eventlog_detailed false\n

      Valid options are:

      • unhandled only unhandled traps will be logged (default value)
      • all log all traps
      • none no traps will create a generic event log (handled traps may still log events)
      "},{"location":"Extensions/Services/","title":"Nagios Plugins - Services","text":"

      Services within LibreNMS provides the ability to leverage Nagios plugins to perform additional monitoring outside of SNMP. Services can also be used in conjunction with your SNMP monitoring for larger monitoring functionality.

      "},{"location":"Extensions/Services/#setting-up-services","title":"Setting up Services","text":"

      Services must be tied to a device to function properly. A good generic option is to use localhost, but it is suggested to attach the check to the device you are monitoring.

      "},{"location":"Extensions/Services/#nagios-plugins-source","title":"Nagios plugins source","text":"

      Plugins come from two main sources:

      • monitoring-plugins
      • pkg-nagios-plugins-contrib

      Note: Plugins will only load if they are prefixed with check_. The check_ prefix is stripped out when displaying in the \"Add Service\" GUI \"Type\" dropdown list.

      "},{"location":"Extensions/Services/#service-templates","title":"Service Templates","text":"

      Service Templates within LibreNMS provides the same ability as Nagios does with Host Groups. Known as Device Groups in LibreNMS. They are applied devices that belong to the specified Device Group.

      Use the Apply buttons to manually create or update Services for the Service Template. Use the Remove buttons to manually remove Services for the Service Template.

      After you Edit a Service Template, and then use Apply, all relevant changes are pushed to existing Services previously created.

      You can also enable Service Templates Auto Discovery to have Services added / removed / updated on regular discover intervals.

      When a Device is a member of multiple Device Groups, templates from all of those Device Groups are applied.

      If a Device is added or removed from a Device Group, when the Apply button is used or Auto Discovery runs Services will be added / removed as appropriate.

      Service Templates are tied into Device Groups, you need at least one Device Group to be able to add Service Templates - You can define a dummy one. The Device Group does not need members to add Service Templates.

      "},{"location":"Extensions/Services/#service-auto-discovery","title":"Service Auto Discovery","text":"

      To automatically create services for devices with available checks.

      You need to enable the discover services within config.php with the following:

      $config['discover_services']           = true;\n
      "},{"location":"Extensions/Services/#service-templates-auto-discovery","title":"Service Templates Auto Discovery","text":"

      To automatically create services for devices with configured Service Templates.

      You need to enable the discover services within config.php with the following:

      $config['discover_services_templates']           = true;\n
      "},{"location":"Extensions/Services/#setup","title":"Setup","text":"

      Service checks are now distributable if you run a distributed setup. To leverage this, use the dispatch service. Alternatively, you could also replace check-services.php with services-wrapper.py in cron instead to run across all polling nodes.

      If you need to debug the output of services-wrapper.py then you can add -d to the end of the command - it is NOT recommended to do this in cron.

      Firstly, install Nagios plugins.

      Debian / Ubuntu: sudo apt install monitoring-plugins Centos: yum install nagios-plugins-all

      Note: The plugins are bundled with the pre-build VM and Docker images.

      Next, you need to enable the services within config.php with the following:

      $config['show_services']           = 1;\n

      This will enable a new service menu within your navbar.

      Debian/Ubuntu:

      $config['nagios_plugins']   = \"/usr/lib/nagios/plugins\";\n

      Centos:

      $config['nagios_plugins']   = \"/usr/lib64/nagios/plugins\";\n

      This will point LibreNMS at the location of the nagios plugins - please ensure that any plugins you use are set to executable. For example:

      Debian/Ubuntu:

      chmod +x /usr/lib/nagios/plugins/*\n

      Centos:

      chmod +x /usr/lib64/nagios/plugins/*\n

      Finally, you now need to add services-wrapper.py to the current cron file (/etc/cron.d/librenms typically) like:

      */5 * * * * librenms /opt/librenms/services-wrapper.py 1\n

      Now you can add services via the main Services link in the navbar, or via the 'Add Service' link within the device, services page.

      Note that some services (procs, inodes, load and similar) will always poll the local LibreNMS server it's running on, regardless of which device you add it to.

      "},{"location":"Extensions/Services/#performance-data","title":"Performance data","text":"

      By default, the check-services script will collect all performance data that the Nagios script returns and display each datasource on a separate graph. LibreNMS expects scripts to return using Nagios convention for the response message structure: AEN200

      However for some modules it would be better if some of this information was consolidated on a single graph. An example is the ICMP check. This check returns: Round Trip Average (rta), Round Trip Min (rtmin) and Round Trip Max (rtmax). These have been combined onto a single graph.

      If you find a check script that would benefit from having some datasources graphed together, please log an issue on GitHub with the debug information from the script, and let us know which DS's should go together. Example below:

          ./check-services.php -d\n    -- snip --\n    Nagios Service - 26\n    Request:  /usr/lib/nagios/plugins/check_icmp localhost\n    Perf Data - DS: rta, Value: 0.016, UOM: ms\n    Perf Data - DS: pl, Value: 0, UOM: %\n    Perf Data - DS: rtmax, Value: 0.044, UOM: ms\n    Perf Data - DS: rtmin, Value: 0.009, UOM: ms\n    Response: OK - localhost: rta 0.016ms, lost 0%\n    Service DS: {\n        \"rta\": \"ms\",\n        \"pl\": \"%\",\n        \"rtmax\": \"ms\",\n        \"rtmin\": \"ms\"\n    }\n    OK u:0.00 s:0.00 r:40.67\n    RRD[update /opt/librenms/rrd/localhost/services-26.rrd N:0.016:0:0.044:0.009]\n    -- snip --\n
      "},{"location":"Extensions/Services/#alerting","title":"Alerting","text":"

      Services uses the Nagios Alerting scheme where exit code:

          0 = Ok,\n    1 = Warning,\n    2 = Critical,\n

      To create an alerting rule to alert on service=critical, your alerting rule would look like:

          %services.service_status = \"2\"\n
      "},{"location":"Extensions/Services/#debug","title":"Debug","text":"

      Change user to librenms for example

      su - librenms\n

      then you can run the following command to help troubleshoot services.

      ./check-services.php -d\n
      "},{"location":"Extensions/Services/#related-polling-discovery-options","title":"Related Polling / Discovery Options","text":"

      These settings are related and should be investigated and set accordingly. The below values are not defaults or recommended.

      $config['service_poller_enabled']           = true;\n
      $config['service_poller_workers']           = 16;\n
      $config['service_poller_frequency']         = 300;\n
      $config['service_poller_down_retry']        = 5;\n
      $config['service_discovery_enabled']        = true;\n
      $config['service_discovery_workers']        = 16;\n
      $config['service_discovery_frequency']      = 3600;\n
      $config['service_services_enabled']         = true;\n
      $config['service_services_workers']         = 16;\n
      $config['service_services_frequency']       = 60;\n

      "},{"location":"Extensions/Services/#service-checks-polling-logic","title":"Service checks polling logic","text":"

      Service check is skipped when the associated device is not pingable, and an appropriate entry is populated in the event log. Service check is polled if it's IP address parameter is not equal to associated device's IP address, even when the associated device is not pingable.

      To override the default logic and always poll service checks, you can disable ICMP testing for any device by switching Disable ICMP Test setting (Edit -> Misc) to ON.

      Service checks will never be polled on disabled devices.

      "},{"location":"Extensions/Services/#check_mrpe","title":"CHECK_MRPE","text":"

      In most cases, only Nagios plugins that run against a remote host with the -H option are available as services. However, if you're remote host is running the Check_MK agent you may be able to use MRPE to monitor Nagios plugins that only execute locally as services.

      For example, consider the fairly common check_cpu.sh Nagios plugin. If you added..

      cpu_check /usr/lib/nagios/plugins/check_cpu.sh -c 95 -w 75

      ...to /etc/check_mk/mrpe.cfg on your remote host, you should be able to check its output by configuring a service using the check_mrpe script.

      • Add check_mrpe to the Nagios plugins directory on your LibreNMS server and make it executable.
      • In LibreNMS, add a new service to the desired device with the type mrpe.
      • Enter the IP address of the remote host and in parameters enter -a cpu_check (this should match the name used at the beginning of the line in the mrpe.cfg file).
      "},{"location":"Extensions/Smokeping/","title":"Smokeping integration","text":"

      SmokePing is a tool which lets us keep track of network latency, and visualise this through RRD graphs.

      LibreNMS has support for both new and pre-existing SmokePing installations.

      For new installations, we can use the lnms cli to generate a Smokeping configuration file.

      "},{"location":"Extensions/Smokeping/#pre-existing-smokeping-installation","title":"Pre-Existing Smokeping Installation","text":"

      If you have an existing smokeping server, follow the instructions, you only need to look at Configure LibreNMS - All Operating Systems.

      "},{"location":"Extensions/Smokeping/#new-installation","title":"New Installation","text":"

      All installation steps assume a clean configuration - if you have an existing smokeping setup, you'll need to adapt these steps somewhat.

      "},{"location":"Extensions/Smokeping/#install-and-integrate-smokeping-backend-rhel-centos-and-alike","title":"Install and integrate Smokeping Backend - RHEL, CentOS and alike","text":"

      Smokeping is available via EPEL, which if you're running LibreNMS, you probably already have. If you want to do something like run Smokeping on a seperate host and ship data via RRCached though, here's the install command:

      sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm\nsudo yum install smokeping\n

      Once installed, you should need a cron script installed to make sure that the configuration file is updated. You can find an example in misc/librenms-smokeping-rhel.example. Put this into /etc/cron.d/hourly, and mark it executable:

      sudo cp /opt/librenms/misc/smokeping-rhel.example /etc/cron.hourly/librenms-smokeping\nsudo chmod +x /etc/cron.hourly/librenms-smokeping\n

      Finally, update the default configuration. Strip everything from the *** Probes *** and *** Targets *** stanza's, and replace with:

      *** Probes ***\n\n@include /etc/smokeping/librenms-probes.conf\n
      *** Targets ***\n\nprobe = FPing\n\nmenu = Top\ntitle = Network Latency Grapher\nremark = Welcome to the SmokePing website of <b>Insert Company Name Here</b>. \\\n         Here you will learn all about the latency of our network.\n\n@include /etc/smokeping/librenms-targets.conf\n

      Note there may be other stanza's (possibly *** Slaves ***) between the *** Probes *** and *** Targets *** stanza's - leave these intact.

      Leave everything else untouched. If you need to add other configuration, make sure it comes after the LibreNMS configuration, and keep in mind that Smokeping does not allow duplicate modules, and cares about the configuration file sequence.

      Once you're happy, manually kick off the cron once, then enable and start smokeping:

      sudo /etc/cron.hourly/librenms-smokeping\nsudo systemctl enable --now smokeping\n
      "},{"location":"Extensions/Smokeping/#install-and-integrate-smokeping-backend-ubuntu-debian-and-alike","title":"Install and integrate Smokeping Backend - Ubuntu, Debian and alike","text":"

      Smokeping is available via the default repositories.

      sudo apt-get install smokeping\n

      Once installed, you should need a cron script installed to make sure that the configuration file is updated. You can find an example in misc/librenms-smokeping-debian.example. Put this into /etc/cron.d/hourly, and mark it executable:

      sudo cp /opt/librenms/misc/smokeping-debian.example /etc/cron.hourly/librenms-smokeping\nsudo chmod +x /etc/cron.hourly/librenms-smokeping\n

      Finally, update the default configuration. Strip everything from /etc/smokeping/config.d/Probes and replace with:

      *** Probes ***\n\n@include /etc/smokeping/config.d/librenms-probes.conf\n

      Strip everything from /etc/smokeping/config.d/Targets and replace with:

      *** Targets ***\n\nprobe = FPing\n\nmenu = Top\ntitle = Network Latency Grapher\nremark = Welcome to the SmokePing website of <b>Insert Company Name Here</b>. \\\n         Here you will learn all about the latency of our network.\n\n@include /etc/smokeping/config.d/librenms-targets.conf\n

      Leave everything else untouched. If you need to add other configuration, make sure it comes after the LibreNMS configuration, and keep in mind that Smokeping does not allow duplicate modules, and cares about the configuration file sequence.

      "},{"location":"Extensions/Smokeping/#configure-librenms-all-operating-systems","title":"Configure LibreNMS - All Operating Systems","text":"

      external/smokeping

      lnms config:set smokeping.dir '/var/lib/smokeping'\nlnms config:set smokeping.pings 20\nlnms config:set smokeping.probes 2\nlnms config:set smokeping.integration true\nlnms config:set smokeping.url 'smokeping/'\n

      dir should match the location that smokeping writes RRD's to pings should match the default smokeping value, default 20 probes should be the number of processes to spread pings over, default 2

      These settings can also be set in the Web UI.

      "},{"location":"Extensions/Smokeping/#configure-smokepings-web-ui-optional","title":"Configure Smokeping's Web UI - Optional","text":"

      This section covers the required configuration for your web server of choice. This covers the required configuration for either Apache or Nginx.

      LibreNMS does not need the Web UI - you can find the graphs in LibreNMS on the latency tab.

      "},{"location":"Extensions/Smokeping/#apache-configuration-ubuntu-debian-and-alike","title":"Apache Configuration - Ubuntu, Debian and alike","text":"

      Edit the General configuration file's Owner and contact, and cgiurl hostname details:

      nano /etc/smokeping/config.d/General\nowner    = LibreNMS-Admin\ncontact  = admin@ACME.xxx\ncgiurl   = http://yourlibrenms/cgi-bin/smokeping.cgi\n

      Smokeping should automatically install an Apache configuration file in /etc/apache2/conf-available/. Verify this using :

      librenms@librenms:~/scripts$ ls /etc/apache2/conf-available/ | grep smokeping\nsmokeping.conf\n

      If you don't see smokeping.conf listed, you'll need to create a symlink for it:

      ln -s /etc/smokeping/apache2.conf /etc/apache2/conf-available/smokeping.conf\n

      After creating the symlink, restart Apache with sudo systemctl apache2 restart

      You should be able to load the Smokeping web interface at http://yourhost/cgi-bin/smokeping.cgi

      "},{"location":"Extensions/Smokeping/#nginx-configuration-rhel-centos-and-alike","title":"Nginx Configuration - RHEL, CentOS and alike","text":"

      This section assumes you have configured LibreNMS with Nginx as specified in Configure Nginx.

      Note, you need to install fcgiwrap for CGI wrapper interact with Nginx

      yum install fcgiwrap\n
      Then create a new configuration file for fcgiwrap in /etc/nginx/fcgiwrap.conf
      # Include this file on your nginx.conf to support debian cgi-bin scripts using\n# fcgiwrap\nlocation /cgi-bin/ {\n  # Disable gzip (it makes scripts feel slower since they have to complete\n  # before getting gzipped)\n  gzip off;\n\n  # Set the root to /usr/lib (inside this location this means that we are\n  # giving access to the files under /usr/lib/cgi-bin)\n  #root /usr/lib;\n  root /usr/share/nginx;\n\n  # Fastcgi socket\n  fastcgi_pass  unix:/var/run/fcgiwrap.socket;\n\n  # Fastcgi parameters, include the standard ones\n  include /etc/nginx/fastcgi_params;\n\n  # Adjust non standard parameters (SCRIPT_FILENAME)\n  fastcgi_param SCRIPT_FILENAME  /usr/lib$fastcgi_script_name;\n} \n
      Be sure to create the folder cgi-bin folder with required permissions (755)
      mkdir /usr/share/nginx/cgi-bin\n
      Create fcgiwrap systemd service in /usr/lib/systemd/system/fcgiwrap.service
      # create new\n[Unit]\nDescription=Simple CGI Server\nAfter=nss-user-lookup.target\nRequires=fcgiwrap.socket\n\n[Service]\nEnvironmentFile=/etc/sysconfig/fcgiwrap\nExecStart=/usr/sbin/fcgiwrap ${DAEMON_OPTS} -c ${DAEMON_PROCS}\nUser=librenms\nGroup=librenms\n\n[Install]\nAlso=fcgiwrap.socket\n
      The socket file in /usr/lib/systemd/system/fcgiwrap.socket
      # create new\n[Unit]\nDescription=fcgiwrap Socket\n\n[Socket]\nListenStream=/var/run/fcgiwrap.socket\n\n[Install]\nWantedBy=sockets.target\n
      Enable fcgiwrap
      systemctl enable --now fcgiwrap\n

      Add the following configuration to your /etc/nginx/conf.d/librenms.conf file within server section.

      The following will configure Nginx to respond to http://yourlibrenms/smokeping:

      location = /smokeping/ {\n        fastcgi_intercept_errors on;\n        fastcgi_param   SCRIPT_FILENAME         /usr/share/smokeping/cgi/smokeping.fcgi;\n        fastcgi_param   QUERY_STRING            $query_string;\n        fastcgi_param   REQUEST_METHOD          $request_method;\n        fastcgi_param   CONTENT_TYPE            $content_type;\n        fastcgi_param   CONTENT_LENGTH          $content_length;\n        fastcgi_param   REQUEST_URI             $request_uri;\n        fastcgi_param   DOCUMENT_URI            $document_uri;\n        fastcgi_param   DOCUMENT_ROOT           $document_root;\n        fastcgi_param   SERVER_PROTOCOL         $server_protocol;\n        fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;\n        fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;\n        fastcgi_param   REMOTE_ADDR             $remote_addr;\n        fastcgi_param   REMOTE_PORT             $remote_port;\n        fastcgi_param   SERVER_ADDR             $server_addr;\n        fastcgi_param   SERVER_PORT             $server_port;\n        fastcgi_param   SERVER_NAME             $server_name;\n        fastcgi_param   HTTPS                   $https if_not_empty;\n        fastcgi_pass unix:/var/run/fcgiwrap.socket;\n}\n\nlocation ^~ /smokeping/ {\n        alias /usr/share/smokeping/cgi/;\n        index smokeping.fcgi;\n        gzip off;\n}\n
      If images/js/css don't load, you might have to add
      location ^~ /smokeping/css {\n        alias /usr/share/smokeping/htdocs/css/;\n        gzip off;\n}\nlocation ^~ /smokeping/js {\n        alias /usr/share/smokeping/htdocs/js/;\n        gzip off;\n}\nlocation ^~ /smokeping/images {\n        alias /opt/librenms/rrd/smokeping/images;\n        gzip off;\n}\n
      After saving the configuration file, verify your Nginx configuration file syntax is OK with sudo nginx -t, then restart Nginx with sudo systemctl restart nginx

      You should be able to load the Smokeping web interface at http://yourlibrenms/smokeping

      "},{"location":"Extensions/Smokeping/#nginx-configuration-ubuntu-debian-and-alike","title":"Nginx Configuration - Ubuntu, Debian and alike","text":"

      This section assumes you have configured LibreNMS with Nginx as specified in Configure Nginx.

      Note, you need to install fcgiwrap for CGI wrapper interact with Nginx

      apt install fcgiwrap\n
      Then configure Nginx with the default configuration

      cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf\n

      Add the following configuration to your /etc/nginx/conf.d/librenms.conf file within server section.

      The following will configure Nginx to respond to http://yourlibrenms/smokeping:

      # Browsing to `http://yourlibrenms/smokeping/` should bring up the smokeping web interface\n\nlocation = /smokeping/ {\n        fastcgi_intercept_errors on;\n\n        fastcgi_param   SCRIPT_FILENAME         /usr/lib/cgi-bin/smokeping.cgi;\n        fastcgi_param   QUERY_STRING            $query_string;\n        fastcgi_param   REQUEST_METHOD          $request_method;\n        fastcgi_param   CONTENT_TYPE            $content_type;\n        fastcgi_param   CONTENT_LENGTH          $content_length;\n        fastcgi_param   REQUEST_URI             $request_uri;\n        fastcgi_param   DOCUMENT_URI            $document_uri;\n        fastcgi_param   DOCUMENT_ROOT           $document_root;\n        fastcgi_param   SERVER_PROTOCOL         $server_protocol;\n        fastcgi_param   GATEWAY_INTERFACE       CGI/1.1;\n        fastcgi_param   SERVER_SOFTWARE         nginx/$nginx_version;\n        fastcgi_param   REMOTE_ADDR             $remote_addr;\n        fastcgi_param   REMOTE_PORT             $remote_port;\n        fastcgi_param   SERVER_ADDR             $server_addr;\n        fastcgi_param   SERVER_PORT             $server_port;\n        fastcgi_param   SERVER_NAME             $server_name;\n        fastcgi_param   HTTPS                   $https if_not_empty;\n\n        fastcgi_pass unix:/var/run/fcgiwrap.socket;\n}\n\nlocation ^~ /smokeping/ {\n        alias /usr/share/smokeping/www/;\n        index smokeping.cgi;\n        gzip off;\n}\n

      After saving the configuration file, verify your Nginx configuration file syntax is OK with sudo nginx -t, then restart Nginx with sudo systemctl restart nginx

      You should be able to load the Smokeping web interface at http://yourlibrenms/smokeping

      "},{"location":"Extensions/Smokeping/#nginx-password-authentication","title":"Nginx Password Authentication","text":"

      You can use the purpose-made htpasswd utility included in the apache2-utils package (Nginx password files use the same format as Apache). You can install it on Ubuntu with

      apt install apache2-utils\n

      After that you need to create password for your user

      htpasswd -c /etc/nginx/.htpasswd USER\n

      You can verify your user and password with

      cat /etc/nginx/.htpasswd\n

      Then you just need to add to your config auth_basic parameters

              location ^~ /smokeping/ {\n                alias /usr/share/smokeping/www/;\n                index smokeping.cgi;\n                gzip off;\n                auth_basic \"Private Property\";\n                auth_basic_user_file /etc/nginx/.htpasswd;\n        }\n
      "},{"location":"Extensions/Smokeping/#common-problems","title":"Common Problems","text":""},{"location":"Extensions/Smokeping/#rrdsupdate-error-opening-permission-denied","title":"RRDs::update ERROR: opening ... Permission denied","text":"

      There is a problem writing to the RRD directory. This is somewhat out of scope of LibreNMS, but make sure that file permissions and SELinux labels allow the smokeping user to write to the directory.

      If you're using RRDCacheD, make sure that the permissions are correct there too, and that if you're using -B that the smokeping RRD's are inside the base directory; update the smokeping rrd directory if required.

      It's not recommended to run RRDCachedD without the -B switch.

      "},{"location":"Extensions/Smokeping/#share-rrdcached-with-librenms","title":"Share RRDCached with LibreNMS","text":"

      Move the RRD's and give smokeping access rights to the LibreNMS RRD directory:

      sudo systemctl stop smokeping\nsudo mv /var/lib/smokeping /opt/librenms/rrd/\nsudo usermod -a -G librenms smokeping\n

      Update data directory in /etc/smokeping:

      datadir = /opt/librenms/rrd/smokeping\ndyndir = /opt/librenms/rrd/smokeping/__cgi\n

      If you have SELinux on, see next section before starting smokeping. Finally restart the smokeping service:

      sudo systemctl start smokeping\n

      Remember to update your config with the new locations.

      "},{"location":"Extensions/Smokeping/#configure-selinux-to-allow-smokeping-to-write-in-librenms-directory-on-centos-rhel","title":"Configure SELinux to allow smokeping to write in LibreNMS directory on Centos / RHEL","text":"

      If you are using RRDCached with the -B switch and smokeping RRD's inside the LibreNMS RRD base directory, you can install this SELinux profile:

      cat > smokeping_librenms.te << EOF\nmodule smokeping_librenms 1.0;\n\nrequire {\ntype httpd_t;\ntype smokeping_t;\ntype smokeping_var_lib_t;\ntype var_run_t;\ntype httpd_sys_rw_content_t;\nclass dir { add_name create getattr read remove_name search write };\nclass file { create getattr ioctl lock open read rename setattr unlink write };\n}\n\n#============= httpd_t ==============\n\nallow httpd_t smokeping_var_lib_t:dir read;\nallow httpd_t var_run_t:file { read write };\n\n#============= smokeping_t ==============\n\nallow smokeping_t httpd_sys_rw_content_t:dir { add_name create getattr remove_name search write };\nallow smokeping_t httpd_sys_rw_content_t:file { create getattr ioctl lock open read rename setattr unlink write };\nEOF\ncheckmodule -M -m -o smokeping_librenms.mod smokeping_librenms.te\nsemodule_package -o smokeping_librenms.pp -m smokeping_librenms.mod\nsemodule -i smokeping_librenms.pp\n
      "},{"location":"Extensions/Smokeping/#probe-fping-missing-missing-from-the-probes-section","title":"Probe FPing missing missing from the probes section","text":"

      Take a look at the instructions again - something isn't correct in your configuration.

      "},{"location":"Extensions/Smokeping/#section-or-variable-already-exists","title":"Section or variable already exists","text":"

      Most likely, content wasn't fully removed from the *** Probes *** *** Targets*** stanza's as instructed. If you're trying to integrate LibreNMS, smokeping and another source of configuration, you're probably trying to redefine a module (e.g. '+ FPing' more than once) or stanza. Otherwise, look again at the instructions.

      "},{"location":"Extensions/Smokeping/#mandatory-variable-probe-not-defined","title":"Mandatory variable 'probe' not defined","text":"

      The target block must have a default probe. If you follow the instructions you will have one. If you're trying to integrate LibreNMS, smokeping and another source of configuration, you need to make sure there are no duplicate or missing definitions.

      "},{"location":"Extensions/Smokeping/#file-usrsbinsendmail-does-not-exist","title":"File '/usr/sbin/sendmail' does not exist`","text":"

      If you got this error at the end of the installation, simply edit or comment out the sendmail entry in the configuration:

      -sendmail = /usr/sbin/sendmail\n+#sendmail = /usr/sbin/sendmail\n
      "},{"location":"Extensions/Sub-Directory/","title":"Sub-directory Support","text":"

      To run LibreNMS under a subdirectory on your Apache server, the directives for the LibreNMS directory are placed in the base server configuration, or in a virtual host container of your choosing. If using a virtual host, place the directives in the file where the virtual host is configured. If using the base server on RHEL distributions (CentOS, Scientific Linux, etc.) the directives can be placed in /etc/httpd/conf.d/librenms.conf. For Debian distributions (Ubuntu, etc.) place the directives in /etc/apache2/sites-available/default.

      #These directives can be inside a virtual host or in the base server configuration\nAllowEncodedSlashes On\nAlias /librenms /opt/librenms/html\n\n<Directory \"/opt/librenms/html\">\n    AllowOverride All\n    Options FollowSymLinks MultiViews\n</Directory>\n

      The RewriteBase directive in html/.htaccess must be rewritten to reference the subdirectory name. Assuming LibreNMS is running at http://example.com/librenms/, you will need to change RewriteBase / to RewriteBase /librenms.

      Finally, set APP_URL=/librenms/ in .env and lnms config:set base_url '/librenms/'.

      "},{"location":"Extensions/Supermicro/","title":"Supermicro","text":"

      For some Supermicro information to show up in LibreNMS, you will need to install an agent.

      "},{"location":"Extensions/Supermicro/#supermicro-superdoctor","title":"Supermicro SuperDoctor","text":"

      Install Supermicro SuperDoctor onto the device you want to monitor.

      Then add the following to /etc/snmp/snmpd.conf:

      pass .1.3.6.1.4.1.10876 /usr/bin/sudo /opt/Supermicro/SuperDoctor5/libs/native/snmpagent\n

      Restart net-snmp:

      service snmpd restart\n
      "},{"location":"Extensions/Syslog/","title":"Syslog support","text":""},{"location":"Extensions/Syslog/#syslog-integration-variants","title":"Syslog integration variants","text":"

      This section explain different ways to recieve and process syslog with LibreNMS. Except of graylog, all Syslogs variants store their logs in the LibreNMS database. You need to enable the Syslog extension in config.php:

      $config['enable_syslog'] = 1;\n
      A Syslog integration gives you a centralized view of information within the LibreNMS (device view, traps, event). Further more you can trigger alerts based on syslog messages (see rule collections).

      "},{"location":"Extensions/Syslog/#traditional-syslog-server","title":"Traditional Syslog server","text":""},{"location":"Extensions/Syslog/#syslog-ng","title":"syslog-ng","text":"Debian / UbuntuCentOS / RedHat
      apt-get install syslog-ng-core\n
      yum install syslog-ng\n

      Once syslog-ng is installed, create the config file (/etc/syslog-ng/conf.d/librenms.conf) and paste the following:

      source s_net {\n        tcp(port(514) flags(syslog-protocol));\n        udp(port(514) flags(syslog-protocol));\n};\n\ndestination d_librenms {\n        program(\"/opt/librenms/syslog.php\" template (\"$HOST||$FACILITY||$PRIORITY||$LEVEL||$TAG||$R_YEAR-$R_MONTH-$R_DAY $R_HOUR:$R_MIN:$R_SEC||$MSG||$PROGRAM\\n\") template-escape(yes));\n};\n\nlog {\n        source(s_net);\n        source(s_src);\n        destination(d_librenms);\n};\n

      Next start syslog-ng:

      service syslog-ng restart\n

      If no messages make it to the syslog tab in LibreNMS, chances are you experience an issue with SELinux. If so, create a file mycustom-librenms-rsyslog.te , with the following content:

      module mycustom-librenms-rsyslog 1.0;\n\nrequire {\n        type syslogd_t;\n        type httpd_sys_rw_content_t;\n        type ping_exec_t;\n        class process execmem;\n        class dir { getattr search write };\n        class file { append getattr execute open read };\n}\n\n#============= syslogd_t ==============\nallow syslogd_t httpd_sys_rw_content_t:dir { getattr search write };\nallow syslogd_t httpd_sys_rw_content_t:file { open read append getattr };\nallow syslogd_t self:process execmem;\nallow syslogd_t ping_exec_t:file execute;\n

      Then, as root, execute the following commands:

      checkmodule -M -m -o mycustom-librenms-rsyslog.mod mycustom-librenms-rsyslog.te\nsemodule_package -o mycustom-librenms-rsyslog.pp -m mycustom-librenms-rsyslog.mod\nsemodule -i mycustom-librenms-rsyslog.pp\n
      "},{"location":"Extensions/Syslog/#rsyslog","title":"rsyslog","text":"

      If you prefer rsyslog, here are some hints on how to get it working.

      Add the following to your rsyslog config somewhere (could be at the top of the file in the step below, could be in rsyslog.conf if you are using remote logs for something else on this host)

      # Listen for syslog messages on UDP:514\n$ModLoad imudp\n$UDPServerRun 514\n

      Create a file called /etc/rsyslog.d/30-librenms.confand add the following depending on your version of rsyslog.

      Version 8Version 7Legacy
      # Feed syslog messages to librenms\nmodule(load=\"omprog\")\n\ntemplate(name=\"librenms\"\n        type=\"string\"\n        string= \"%fromhost%||%syslogfacility%||%syslogpriority%||%syslogseverity%||%syslogtag%||%$year%-%$month%-%$day% %timegenerated:8:25%||%msg%||%programname%\\n\")\n        action(type=\"omprog\"\n        binary=\"/opt/librenms/syslog.php\"\n        template=\"librenms\")\n\n& stop\n
      #Feed syslog messages to librenms\n$ModLoad omprog\n\n$template librenms,\"%fromhost%||%syslogfacility%||%syslogpriority%||%syslogseverity%||%syslogtag%||%$year%-%$month%-%$day% %timegenerated:8:25%||%msg%||%programname%\\n\"\n\n*.* action(type=\"omprog\" binary=\"/opt/librenms/syslog.php\" template=\"librenms\")\n\n& stop\n
      # Feed syslog messages to librenms\n$ModLoad omprog\n$template librenms,\"%FROMHOST%||%syslogfacility-text%||%syslogpriority-text%||%syslogseverity%||%syslogtag%||%$YEAR%-%$MONTH%-%$DAY%    %timegenerated:8:25%||%msg%||%programname%\\n\"\n\n$ActionOMProgBinary /opt/librenms/syslog.php\n*.* :omprog:;librenms\n

      If your rsyslog server is receiving messages relayed by another syslog server, you may try replacing %fromhost% with %hostname%, since fromhost is the host the message was received from, not the host that generated the message. The fromhost property is preferred as it avoids problems caused by devices sending incorrect hostnames in syslog messages.

      "},{"location":"Extensions/Syslog/#local-logstash","title":"Local Logstash","text":"

      If you prefer logstash, and it is installed on the same server as LibreNMS, here are some hints on how to get it working.

      First, install the output-exec plugin for logstash:

      /usr/share/logstash/bin/logstash-plugin install logstash-output-exec\n

      Next, create a logstash configuration file (ex. /etc/logstash/conf.d/logstash-simple.conf), and add the following:

      input {\nsyslog {\n    port => 514\n  }\n}\n\n\noutput {\n        exec {\n        command => \"echo `echo %{host},,,,%{facility},,,,%{priority},,,,%{severity},,,,%{facility_label},,,,``date --date='%{timestamp}' '+%Y-%m-%d %H:%M:%S'``echo ',,,,%{message}'``echo ,,,,%{program} | sed 's/\\x25\\x7b\\x70\\x72\\x6f\\x67\\x72\\x61\\x6d\\x7d/%{facility_label}/'` | sed 's/,,,,/||/g' | /opt/librenms/syslog.php &\"\n        }\n        elasticsearch {\n        hosts => [\"10.10.10.10:9200\"]\n        index => \"syslog-%{+YYYY.MM.dd}\"\n        }\n}\n

      Replace 10.10.10.10 with your primary elasticsearch server IP, and set the incoming syslog port. Alternatively, if you already have a logstash config file that works except for the LibreNMS export, take only the \"exec\" section from output and add it.

      "},{"location":"Extensions/Syslog/#remote-logstash-or-any-json-source","title":"Remote Logstash (or any json source)","text":"

      If you have a large logstash / elastic installation for collecting and filtering syslogs, you can simply pass the relevant logs as json to the LibreNMS API \"syslog sink\". This variant may be more flexible and secure in transport. It does not require any major changes to existing ELK setup. You can also pass simple json kv messages from any kind of application or script (example below) to this sink.

      For long term or advanced aggregation searches you might still use Kibana/Grafana/Graylog etc. It is recommended to keep config['syslog_purge'] short.

      A schematic setup can look like this:

        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2502Device\u251c\u2500\u25ba\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518  \u2502Logstash Cluster   \u251c\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba\u2502ElasticSearch \u251c\u2510\n            \u2502  RabbitMQ         \u2502\u2502               \u2502 Cluster      \u2502\u2502\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u25ba\u2502    Filtering etc  \u2502\u2502 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u2514\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2502\n \u2502Device\u2502   \u2514\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2502        \u2502       \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518        \u25bc\n                                      ~~~WAN~~~\n                                          \u2502\n                                        \u250c\u2500\u253c\u2500\u2510\n                                        \u2502\u253c\u253c\u253c\u2502 LB / Firewall / etc\n                                        \u2514\u2500\u253c\u2500\u2518\n                                          \u2502\n                                          \u25bc\n                         \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                         \u2502LibreNMS Sink       \u251c\u252c\u2500\u2500\u25ba\u2502LibreNMS Master     \u2502\n                         \u2502/api/v0/syslogsink/ \u2502\u2502   \u2502 MariaDB            \u2502\n                         \u2514\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2502   \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                          \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n

      A minimal Logstash http output configuration can look like this:

      output {\n....\n        #feed it to LibreNMS\n        http {\n            http_method => \"post\"\n            url => \"https://sink.librenms.org/api/v0/syslogsink/    # replace with your librenms host\n            format => \"json_batch\"                                  # put multiple syslogs in on HTTP message\n                retry_failed => false                               # if true, logstash is blocking if the API is unavailable, be careful! \n                headers => [\"X-Auth-Token\",\"xxxxxxxLibreNMSApiToken]\n\n                # optional if your mapping is not already done before or does not match. \"msg\" and \"host\" is mandatory. \n                # you might also use out the clone {} function to duplicate your log stream and a dedicated log filtering/mapping etc.\n                # mapping => {\n                # \"host\"=> \"%{host}\"\n                # \"program\" => \"%{program}\"\n                # \"facility\" => \"%{facility_label}\"\n                # \"priority\" => \"%{syslog5424_pri}\"\n                # \"level\" => \"%{facility_label}\"                \n                # \"tag\" => \"%{topic}\"\n                # \"msg\" => \"%{message}\"\n                # \"timestamp\" => \"%{@timestamp}\"\n                # }\n        }\n}\n

      Sample test data:

      curl -L -X POST 'https://sink.librenms.org/api/v0/syslogsink/' -H 'X-Auth-Token: xxxxxxxLibreNMSApiToken' --data-raw '[   \n    {\n        \"msg\": \"kernel: minimum Message\",\n        \"host\": \"mydevice.fqdn.com\"\n    },\n    {\n        \"msg\": \"Line protocol on Interface GigabitEthernet1/0/41, changed state to up\",\n        \"facility\": 23,\n        \"priority\": \"189\",\n        \"program\": \"LINEPROTO-5-UPDOWN\",\n        \"host\": \"172.29.10.24\",\n        \"@timestamp\": \"2022-12-01T20:14:28.257Z\",\n        \"severity\": 5,\n        \"level\": \"ERROR\"\n    },\n    {\n        \"msg\": \"kernel: a unknown host\",\n        \"host\": \"unknown.fqdn.com\"\n    }\n]'\n
      msg and host are the minimum keys.

      "},{"location":"Extensions/Syslog/#graylog","title":"Graylog","text":"

      This variant method use a external Graylog installation and its database. Please refer to the dedicated Graylog documentation.

      "},{"location":"Extensions/Syslog/#client-configuration","title":"Client configuration","text":"

      Below are sample configurations for a variety of clients. You should understand the config before using it as you may want to make some slight changes. Further configuration hints may be found in the file Graylog.md.

      Replace librenms.ip with IP or hostname of your LibreNMS install.

      Replace any variables in with the relevant information."},{"location":"Extensions/Syslog/#syslog","title":"syslog","text":"

      *.*     @librenms.ip\n
      "},{"location":"Extensions/Syslog/#rsyslog_1","title":"rsyslog","text":"
      *.* @librenms.ip:514\n
      "},{"location":"Extensions/Syslog/#cisco-asa","title":"Cisco ASA","text":"
      logging enable\nlogging timestamp\nlogging buffer-size 200000\nlogging buffered debugging\nlogging trap notifications\nlogging host <outside interface name> librenms.ip\n
      "},{"location":"Extensions/Syslog/#cisco-ios","title":"Cisco IOS","text":"
      logging trap debugging\nlogging facility local6\nlogging librenms.ip\n
      "},{"location":"Extensions/Syslog/#cisco-nxos","title":"Cisco NXOS","text":"
      logging server librenms.ip 5 use-vrf default facility local6\n
      "},{"location":"Extensions/Syslog/#juniper-junos","title":"Juniper Junos","text":"
      set system syslog host librenms.ip authorization any\nset system syslog host librenms.ip daemon any\nset system syslog host librenms.ip kernel any\nset system syslog host librenms.ip user any\nset system syslog host librenms.ip change-log any\nset system syslog host librenms.ip source-address <management ip>\nset system syslog host librenms.ip exclude-hostname\nset system syslog time-format\n
      "},{"location":"Extensions/Syslog/#huawei-vrp","title":"Huawei VRP","text":"
      info-center loghost librenms.ip\ninfo-center timestamp debugging short-date without-timezone // Optional\ninfo-center timestamp log short-date // Optional\ninfo-center timestamp trap short-date // Optional\n//This is optional config, especially if the device is in public ip and you dont'want to get a lot of messages of ACL\ninfo-center filter-id bymodule-alias VTY ACL_DENY\ninfo-center filter-id bymodule-alias SSH SSH_FAIL\ninfo-center filter-id bymodule-alias SNMP SNMP_FAIL\ninfo-center filter-id bymodule-alias SNMP SNMP_IPLOCK\ninfo-center filter-id bymodule-alias SNMP SNMP_IPUNLOCK\ninfo-center filter-id bymodule-alias HTTP ACL_DENY\n
      "},{"location":"Extensions/Syslog/#huawei-smartax-gpon-olt","title":"Huawei SmartAX (GPON OLT)","text":"
      loghost add librenms.ip librenms\nloghost activate name librenms\n
      "},{"location":"Extensions/Syslog/#allied-telesis-alliedware-plus","title":"Allied Telesis Alliedware Plus","text":"
      log date-format iso // Required so syslog-ng/LibreNMS can correctly interpret the log message formatting.\nlog host x.x.x.x\nlog host x.x.x.x level <errors> // Required. A log-level must be specified for syslog messages to send.\nlog host x.x.x.x level notices program imish // Useful for seeing all commands executed by users.\nlog host x.x.x.x level notices program imi // Required for Oxidized Syslog hook log message.\nlog host source <eth0>\n
      "},{"location":"Extensions/Syslog/#hpearuba-procurve","title":"HPE/Aruba Procurve","text":"
      configure\nlogging severity warning\nlogging facility local6\nlogging librenms.ip control-descr \u201cLibreNMS\u201d\nlogging notify running-config-change\nwrite memory\n

      If you have permitted udp and tcp 514 through any firewall then that should be all you need. Logs should start appearing and displayed within the LibreNMS web UI.

      "},{"location":"Extensions/Syslog/#windows","title":"Windows","text":"

      By Default windows has no native way to send logs to a remote syslog server.

      Using this how to you can download Datagram-Syslog Agent to send logs to a remote syslog server (LibreNMS).

      "},{"location":"Extensions/Syslog/#note","title":"Note","text":"

      Keep in mind you can use any agent or program to send the logs. We are just using this Datagram-Syslog Agent for this example.

      Link to How to

      You will need to download and install \"Datagram-Syslog Agent\" for this how to Link to Download

      "},{"location":"Extensions/Syslog/#external-hooks","title":"External hooks","text":"

      Trigger external scripts based on specific syslog patterns being matched with syslog hooks. Add the following to your LibreNMS config.php to enable hooks:

      $config['enable_syslog_hooks'] = 1;\n

      The below are some example hooks to call an external script in the event of a configuration change on Cisco ASA, IOS, NX-OS and IOS-XR devices. Add to your config.php file to enable.

      "},{"location":"Extensions/Syslog/#cisco-asa_1","title":"Cisco ASA","text":"
      $config['os']['asa']['syslog_hook'][] = Array('regex' => '/%ASA-(config-)?5-111005/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#cisco-ios_1","title":"Cisco IOS","text":"
      $config['os']['ios']['syslog_hook'][] = Array('regex' => '/%SYS-(SW[0-9]+-)?5-CONFIG_I/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#cisco-nxos_1","title":"Cisco NXOS","text":"
      $config['os']['nxos']['syslog_hook'][] = Array('regex' => '/%VSHD-5-VSHD_SYSLOG_CONFIG_I/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#cisco-iosxr","title":"Cisco IOSXR","text":"
      $config['os']['iosxr']['syslog_hook'][] = Array('regex' => '/%GBL-CONFIG-6-DB_COMMIT/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#juniper-junos_1","title":"Juniper Junos","text":"
      $config['os']['junos']['syslog_hook'][] = Array('regex' => '/UI_COMMIT:/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#juniper-screenos","title":"Juniper ScreenOS","text":"
      $config['os']['screenos']['syslog_hook'][] = Array('regex' => '/System configuration saved/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#allied-telesis-alliedware-plus_1","title":"Allied Telesis Alliedware Plus","text":"

      Note: At least software version 5.4.8-2.1 is required. log host x.x.x.x level notices program imi may also be required depending on configuration. This is to ensure the syslog hook log message gets sent to the syslog server.

      $config['os']['awplus']['syslog_hook'][] = Array('regex' => '/IMI.+.Startup-config saved on/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#hpearuba-procurve_1","title":"HPE/Aruba Procurve","text":"
      $config['os']['procurve']['syslog_hook'][] = Array('regex' => '/Running Config Change/', 'script' => '/opt/librenms/scripts/syslog-notify-oxidized.php');\n
      "},{"location":"Extensions/Syslog/#configuration-options","title":"Configuration Options","text":""},{"location":"Extensions/Syslog/#syslog-clean-up","title":"Syslog Clean Up","text":"

      Can be set inside of config.php

      $config['syslog_purge'] = 30;\n

      The cleanup is run by daily.sh and any entries over X days old are automatically purged. Values are in days. See here for more Clean Up Options Link

      "},{"location":"Extensions/Syslog/#matching-syslogs-to-hosts-with-different-names","title":"Matching syslogs to hosts with different names","text":"

      In some cases, you may get logs that aren't being associated with the device in LibreNMS. For example, in LibreNMS the device is known as \"ne-core-01\", and that's how DNS resolves. However, the received syslogs are for \"loopback.core-nw\".

      To fix this issue, you can configure LibreNMS to translate the incoming syslog hostname into another hostname, so that the logs get associated with the correct device.

      Example:

      $config['syslog_xlate'] = array(\n        'loopback0.core7k1.noc.net' => 'n7k1-core7k1',\n        'loopback0.core7k2.noc.net' => 'n7k2-core7k2'\n);\n
      "},{"location":"Extensions/Two-Factor-Auth/","title":"Two-Factor Authentication","text":"

      Over the last couple of years, the primary attack vector for internet accounts has been static passwords. Therefore static passwords are no longer sufficient to protect unauthorized access to accounts. Two Factor Authentication adds a variable part in authentication procedures. A user is now required to supply a changing 6-digit passcode in addition to their password to obtain access to the account.

      LibreNMS has a RFC4226 conformant implementation of both Time and Counter based One-Time-Passwords. It also allows the administrator to configure a throttle time to enforce after 3 failures exceeded. Unlike RFC4226 suggestions, this throttle time will not stack on the amount of failures.

      "},{"location":"Extensions/Two-Factor-Auth/#types","title":"Types","text":"

      In general, these two types do not differ in algorithmic terms. The types only differ in the variable being used to derive the passcodes from. The underlying HMAC-SHA1 remains the same for both types, security advantages or disadvantages of each are discussed further down.

      "},{"location":"Extensions/Two-Factor-Auth/#timebased-one-time-password-totp","title":"Timebased One-Time-Password (TOTP)","text":"

      Like the name suggests, this type uses the current Time or a subset of it to generate the passcodes. These passcodes solely rely on the secrecy of their Secretkey in order to provide passcodes. An attacker only needs to guess that Secretkey and the other variable part is any given time, presumably the time upon login. RFC4226 suggests a resynchronization attempt in case the passcode mismatches, providing the attacker a range of up to +/- 3 Minutes to create passcodes.

      "},{"location":"Extensions/Two-Factor-Auth/#counterbased-one-time-password-hotp","title":"Counterbased One-Time-Password (HOTP)","text":"

      This type uses an internal counter that needs to be in sync with the server's counter to successfully authenticate the passcodes. The main advantage over timebased OTP is the attacker doesn't only need to know the Secretkey but also the server's Counter in order to create valid passcodes. RFC4226 suggests a resynchronization attempt in case the passcode mismatches, providing the attacker a range of up to +4 increments from the actual counter to create passcodes.

      "},{"location":"Extensions/Two-Factor-Auth/#configuration","title":"Configuration","text":""},{"location":"Extensions/Two-Factor-Auth/#webui","title":"WebUI","text":"

      Enable 'Two-Factor' Via Global Settings in the Web UI under Authentication -> General Authentication Settings.

      Optionally enter a throttle timer in seconds. This will unlock an account after this time once it has failed 3 attempt to authenticate. Set to 0 (default) to disable this feature, meaning accounts will remain locked after 3 attempts and will need an administrator to clear.

      "},{"location":"Extensions/Two-Factor-Auth/#cli","title":"CLI","text":"

      Enable Two-Factor:

      ./lnms config:set twofactor true

      Set throttle-time (in seconds):

      ./lnms config:set twofactor_lock 300

      "},{"location":"Extensions/Two-Factor-Auth/#user-administation","title":"User Administation","text":"

      If Two-Factor is enabled, the Settings -> Manage Users grid will show a '2FA' column containing a green tick for users with active 2FA.

      There is no functionality to mandate 2FA for users.

      If a user has failed 3 attempts, their account can be unlocked or 2FA disabled by editing the user from the Manage Users table.

      If a throttle timer is set, it will unlock accounts after this time. If set to the default of 0, accounts will need to be manually unlocked by an administrator after 3 failed attempts.

      Locked accounts will report to the user stating to wait for the throttle time period, or to contact the administrator if no timer set.

      "},{"location":"Extensions/Two-Factor-Auth/#end-user-enrolment","title":"End-User Enrolment","text":"

      These steps imply that Two-Factor has been enabled system wide as above under Configuration.

      2FA is enabled by each user once they are logged in normally:

      • Go to 'My Settings' (/preferences/)
      • Choose TwoFactor type
      • Click on 'Generate TwoFactor Secret Key'
      • If your browser didn't reload, reload manually
      • Scan provided QR or click on 'Manual' to see the Key
      "},{"location":"Extensions/Two-Factor-Auth/#google-authenticator","title":"Google Authenticator","text":"

      Installation guides for Google Authenticator can be found here.

      Usage:

      • Create a key as described above
      • Scan provided QR or click on 'Manual' and enter the Secret
      • On next login, enter the passcode that the App provides
      "},{"location":"Extensions/Two-Factor-Auth/#lastpass-authenticator","title":"LastPass Authenticator","text":"

      LastPass Authenticator is confirmed to work with Timebased One-Time Passwords (TOTP).

      Installation guide for LastPass Authenticator can be found here.

      Usage:

      • Create a Timerbased key as described above
      • Click Add (+) and scan provided QR or click on 'NO QR CODE?' and enter naming details and the Secret
      • On next login, enter the passcode that the App provides
      "},{"location":"Extensions/Varnish/","title":"Varnish Installation Guide","text":"

      This document explains how to install Varnish Reverse Proxy for LibreNMS.

      Varnish is caching software that sits logically between an HTTP client and an HTTP server. Varnish caches HTTP responses from the HTTP server. If an HTTP request can not be responded to by the Varnish cache it directs the request to the HTTP Server. This type of HTTP caching is called a reverse proxy server. Caching your HTTP server can decrease page load times significantly.

      "},{"location":"Extensions/Varnish/#architecture","title":"Architecture","text":"

      Simplified block diagram of an Apache HTTP server with Varnish 4.0 Reverse Proxy

      "},{"location":"Extensions/Varnish/#centos-7-varnish-installation","title":"CentOS 7 Varnish Installation","text":"

      In this example we will assume your Apache 2.4.X HTTP server is working and configured to process HTTP requests on port 80. If not, please see Installing LibreNMS

      "},{"location":"Extensions/Varnish/#install-varnish-40-rpm","title":"Install Varnish 4.0 RPM","text":"
      • Enable the Varnish CentOS 7 repo and install
      rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el7.rpm\nyum install varnish\n

      By default Varnish listens for HTTP requests on port 6081.

      • Temporarily add a firewalld rule for testing Varnish.
      firewall-cmd --zone=public --add-port=6081/tcp\n
      "},{"location":"Extensions/Varnish/#test-varnish","title":"Test Varnish","text":"
      • Start Varnish
      systemctl start varnish\n

      Using a web browser navigate to :6081 or 127.0.0.1:6081. You should see a Varnish error message, this shows that Varnish is working. Example error message:

      Error 503 Backend fetch failed\n\nBackend fetch failed\n\nGuru Meditation:\n\nXID: 3\n\nVarnish cache server\n
      "},{"location":"Extensions/Varnish/#edit-varnish-parameters","title":"Edit Varnish Parameters","text":"

      Now we need to configure Varnish to listen to HTTP requests on port 80 and relay those requests to the Apache HTTP server on port 8080 (see block diagram).

      • Stop Varnish.
      systemctl stop varnish\n
      • Create a back-up of varnish.params just in case you make a mistake.
      cp /etc/varnish/varnish.params /etc/varnish/varnish.params.bak\n
      • Edit the varnish.params config.
      vim /etc/varnish/varnish.params\n

      Set the VCL location, IP address, port, and cache location and size. malloc sets the cache location to RAM, and 512M sets the cache size to 512MB.

      VARNISH_LISTEN_ADDRESS=192.168.1.10\nVARNISH_LISTEN_PORT=80\nVARNISH_VCL_CONF=/etc/varnish/librenms.vcl\nVARNISH_STORAGE=\"malloc,512M\"\n

      Example varnish.params:

      # Set this to 1 to make systemd reload try to switch vcl without restart.\nRELOAD_VCL=1\n\n# Main configuration file. You probably want to change it.\nVARNISH_VCL_CONF=/etc/varnish/librenms.vcl\n\n# Default address and port to bind to. Blank address means all IPv4\n# and IPv6 interfaces, otherwise specify a host name, an IPv4 dotted\n# quad, or an IPv6 address in brackets.\nVARNISH_LISTEN_ADDRESS=192.168.1.10\nVARNISH_LISTEN_PORT=80\n\n# Admin interface listen address and port\nVARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1\nVARNISH_ADMIN_LISTEN_PORT=6082\n\n# Shared secret file for admin interface\nVARNISH_SECRET_FILE=/etc/varnish/secret\n\n# Backend storage specification, see Storage Types in the varnishd(5)\n# man page for details.\nVARNISH_STORAGE=\"malloc,512M\"\n\n# Default TTL used when the backend does not specify one\nVARNISH_TTL=120\n\n# User and group for the varnishd worker processes\nVARNISH_USER=varnish\nVARNISH_GROUP=varnish\n\n# Other options, see the man page varnishd(1)\nDAEMON_OPTS=\"-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300\"\n
      "},{"location":"Extensions/Varnish/#configure-apache-for-varnish","title":"Configure Apache for Varnish","text":"

      Edit librenms.conf and modify the Apache Virtual Host listening port.

      • Modify: <VirtualHost *:80> to <VirtualHost *:8080>
      vim /etc/httpd/conf.d/librenms.conf\n

      Varnish can not share a port with Apache. Change the Apache listening port to 8080.

      • Modify: Listen 80 to Listen 8080
      vim /etc/httpd/conf/httpd.conf\n
      • Create the librenms.vcl
      cd /etc/varnish\ntouch librenms.vcl\n
      • Set ownership and permissions for Varnish files.
      chown varnish:varnish default.vcl varnish.params secret\nchmod 644 default.vcl varnish.params secret\n

      Edit the librenms.vcl.

      vim librenms.vcl\n

      Paste example VCL config, read config comments for more information.

      #\n# This is an example VCL file for Varnish.\n#\n# It does not do anything by default, delegating control to the\n# builtin VCL. The builtin VCL is called when there is no explicit\n# return statement.\n#\n# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/\n# and http://varnish-cache.org/trac/wiki/VCLExamples for more examples.\n\n# Marker to tell the VCL compiler that this VCL has been adapted to the\n# new 4.0 format.\nvcl 4.0;\n\n# Default backend definition. Set this to point to your Apache server.\nbackend librenms {\n    .host = \"127.0.0.1\";\n    .port = \"8080\";\n}\n\n# In this example our objective is to cache static content with Varnish and temporarily\n# cache dynamic content in the client web browser.\n\nsub vcl_recv {\n    # HTTP requests from client web browser.\n    # Here we remove any cookie HTTP requests for the 'librenms.domain.net' host\n    # containing the matching file extensions. We don't have to match by host if you\n    # only have LibreNMS running on Apache.\n    # If the cookies are not removed from the HTTP request then Varnish will not cache\n    # the files. 'else' function is set to 'pass', or don't cache anything that doesn't\n    # match.\n\n    if (req.http.host ~ \"^librenms.domain.net\") {\n        set req.backend_hint = librenms;\n        if (req.url ~ \"\\.(png|gif|jpg|jpeg|ico|pdf|js|css|svg|eot|otf|woff|woff2|ttf)$\") {\n            unset req.http.Cookie;\n        }\n\n        else{\n            return(pass);\n        }\n    }\n}\n\nsub vcl_backend_response {\n    # 'sub vcl_backend_response' is the same function as 'sub vcl_fetch' in Varnish 3, however,\n    # the syntax is slightly different\n    # This function happens after we read the response headers from the backend (Apache).\n    # First function 'if (bereq.url ~ \"\\' removes cookies from the Apache HTTP responses\n    # that match the file extensions that are between the quotes, and cache the files for 24 hours.\n    # This assumes you update LibreNMS once a day, otherwise restart Varnish to clear cache.\n    # Second function 'if (bereq.url ~ \"^/' removes the Pragma no-cache statements and sets the age\n    # of how long the client browser will cache the matching urls.\n    # LibreNMS graphs are updated every 300 seconds, 'max-age=300' is set to match this behavior.\n    # We could cache these URLs in Varnish but it would add to the complexity of the config.\n\n    if (bereq.http.host ~ \"^librenms.domain.net\") {\n        if (bereq.url ~ \"\\.(png|gif|jpg|jpeg|ico|pdf|js|css|svg|eot|otf|woff|woff2|ttf)$\") {\n            unset beresp.http.Set-cookie;\n            set beresp.ttl = 24h;\n        }\n\n        if (bereq.url ~ \"^/graph.php\" || \"^/device/\" || \"^/iftype/\" || \"^/customers/\" || \"^/health/\" || \"^/apps/\" || \"^/(plugin)$\" || \"^/(alert)$\" || \"^/eventlog/\" || \"^/graphs/\" || \"^/ports/\" ) {\n            unset beresp.http.Pragma;\n            set beresp.http.Cache-Control = \"max-age=300\";\n        }\n    }\n}\n\nsub vcl_deliver {\n    # Happens when we have all the pieces we need, and are about to send the\n    # response to the client.\n    # You can do accounting or modifying the final object here.\n\n    return (deliver);\n}\n
      • Reload rules to remove the temporary port rule we added earlier.
      firewall-cmd --reload\n

      Varnish caching does not take effect immediately. You will need to browse the LibreNMS website to build up the cache.

      Use the command varnishstat to monitor Varnish caching. Over time you should see 'MAIN.cache_hit' and 'MAIN.client_req' increase. With the above VCL the hit to request ratio is approximately 84%.

      • Session based VCL (coming soon)

      • Testing and debugging VCL (coming soon)

      "},{"location":"Extensions/VisJS-Config/","title":"Vis JS Configuration","text":"

      The Network Maps and Dependency Maps all use a common configuration for the vis.js library, which affects the way the maps are rendered, as well as the way that users can interact with the maps. This configuration can be adjusted by following the instructions below.

      This link will show you all the options and explain what they do.

      You may also access the dynamic configuration interface example here from within LibreNMS by adding the following to config.php

      $config['network_map_vis_options'] = '{\n  \"configure\": { \"enabled\": true},\n}';\n
      "},{"location":"Extensions/VisJS-Config/#note","title":"Note","text":"

      You may want to disable the automatic page refresh while you're tweaking your configuration, as the refresh will reset the dynamic configuration UI to the values currently saved in config.php This can be done by clicking on the Settings Icon then Refresh Pause.

      "},{"location":"Extensions/VisJS-Config/#configurator-output","title":"Configurator Output","text":"

      Once you've achieved your desired map appearance, click the generate options button at the bottom to be given the necessary parameters to add to your config.php file. You will need to paste the generated config into config.php the format will need to look something like this. Note that the configurator will output the config with var options you will need to strip them out and at the end of the config you need to add an }'; see the example below.

      $config['network_map_vis_options'] = '{\n  \"nodes\": {\n    \"color\": {\n      \"background\": \"rgba(20,252,18,1)\"\n    },\n    \"font\": {\n      \"face\": \"tahoma\"\n    },\n    \"physics\": false\n  },\n  \"edges\": {\n    \"smooth\": {\n      \"forceDirection\": \"none\"\n    }\n  },\n  \"interaction\": {\n    \"hover\": true,\n    \"multiselect\": true,\n    \"navigationButtons\": true\n  },\n  \"manipulation\": {\n    \"enabled\": true\n  },\n  \"physics\": {\n    \"barnesHut\": {\n      \"avoidOverlap\": 0.11\n    },\n    \"minVelocity\": 0.75\n  }\n}';\n

      "},{"location":"Extensions/Weathermap/","title":"Network-WeatherMap with LibreNMS","text":"

      Integrating LibreNMS with Network-Weathermap, allows you to build network maps to help visulaize network traffic flow rates.

      "},{"location":"Extensions/Weathermap/#prerequisites","title":"Prerequisites","text":"

      Network-WeatherMap requires php pear to work.

      "},{"location":"Extensions/Weathermap/#installing-network-weathermap","title":"Installing Network-WeatherMap","text":""},{"location":"Extensions/Weathermap/#step-1","title":"Step 1","text":"

      Extract to your LibreNMS plugins directory /opt/librenms/html/plugins so you should see something like /opt/librenms/html/plugins/Weathermap/ The best way to do this is via git. Go to your install directory and then /opt/librenms/html/plugins enter:

      git clone https://github.com/librenms-plugins/Weathermap.git\n

      "},{"location":"Extensions/Weathermap/#step-2","title":"Step 2","text":"

      Inside the html/plugins directory, change the ownership of the Weathermap directory by typing

      chown -R librenms:librenms Weathermap/\n

      Make the configs directory writeable.

      chmod 775 /opt/librenms/html/plugins/Weathermap/configs\n

      Note if you are using SELinux you need to input the following command

      chcon -R -t httpd_cache_t Weathermap/\n
      "},{"location":"Extensions/Weathermap/#step-3","title":"Step 3","text":"

      Enable the cron process by editing your current LibreNMS cron file (typically /etc/cron.d/librenms) and add the following:

      */5 * * * * librenms /opt/librenms/html/plugins/Weathermap/map-poller.php >> /dev/null 2>&1\n
      "},{"location":"Extensions/Weathermap/#step-4","title":"Step 4","text":"

      Enable the plugin from LibreNMS Web UI in OverView -> Plugins -> Plugin Admin menu.

      "},{"location":"Extensions/Weathermap/#step-5","title":"Step 5","text":"

      Now you should see Weathermap Overview -> Plugins -> Weathermap Create your maps, please note when you create a MAP, please click Map Style, ensure Overlib is selected for HTML Style and click submit. Also, ensure you set an output image filename and output HTML filename in Map Properties. I'd recommend you use the output folder as this is excluded from git updates (i.e. use output/mymap.png and output/mymap.html).

      Optional: If your install is in another directory than standard, set $basehref within map-poller.php.

      "},{"location":"Extensions/Weathermap/#weathermapper","title":"WeatherMapper","text":"

      Automatically generate weathermaps from a LibreNMS database using WeatherMapper.

      "},{"location":"Extensions/Weathermap/#adding-your-network-weathermaps-to-the-dashboards","title":"Adding your Network Weathermaps to the Dashboards","text":"

      Once you have created your Network Weather Map you can add it to a dashboard page by doing the following.

      "},{"location":"Extensions/Weathermap/#step-1_1","title":"Step 1","text":"

      When you create the Weathermap make sure to export as HTML and PNG you will need this for the out to the dashboard.

      In the Weathermap Plugin page, you will see the output maps. Right click on one of the maps and click on copy image address.

      Example URL: http://yourlibrenms.org/plugins/Weathermap/output/yourmap.html

      "},{"location":"Extensions/Weathermap/#step-2_1","title":"Step 2","text":"

      Then go back to your Dashboard, create a new dashboard and give it a name. select the widget as External Images.

      Give the Widget a Title.

      The Image URL will need to be the address you copied but at the end remove the .html and replace it with .png

      Example Image URL http://yourlibrenms.org/plugins/Weathermap/output/yourmap.png

      The Target URL will be the URL you copied but with the .html at the end of the URL.

      Example Target URL http://yourlibrenms.org/plugins/Weathermap/output/yourmap.html

      Then Click on Set

      You should now be able to see the Weathermap you have created in your list of dashboards. You could also add this to existing dashboards.

      "},{"location":"Extensions/World-Map/","title":"World Map Configuration","text":"

      LibreNMS comes with a configurable Geo Map based on World Map Widget to visualize where your equipment is located geographically.

      "},{"location":"Extensions/World-Map/#world-map-widget","title":"World Map Widget","text":"

      World Map Widget, requires you to have properly formatted addresses in sysLocation or sysLocation override. As part of the standard poller these addresses will be Geocoded by Google and stored in the database.

      Location resolution happens as follows

      1. If device['location'] contains [lat, lng] (note the square brackets), that is used
      2. If there is a location overide for the device in the WebUI and it contains [lat, lng] (note the square brackets), that is used.
      3. Attempt to resolve lat, lng using lnms config:set geoloc.engine
      4. Properly formatted addresses in sysLocation or sysLocation override, under device settings.

      Example:

      [40.424521, -86.912755]\n

      or

      1100 Congress Ave, Austin, TX 78701 (3rd floor cabinet)\n
      Information inside parentheses is ignored during GEO lookup

      We have two current mapping engines available:

      • Leaflet (default)
      • Jquery-Mapael
      "},{"location":"Extensions/World-Map/#world-map-widget-settings","title":"World Map Widget Settings","text":"
      • Initial Latitude / Longitude: The map will be centered on those coordinates.
      • Initial Zoom: Initial zoom of the map. More information about zoom levels.
      • Grouping radius: Markers are grouped by area. This value define the maximum size of grouping areas.
      • Show devices: Show devices based on status.

      Example Settings:

      "},{"location":"Extensions/World-Map/#device-overview-world-map-settings","title":"Device Overview World Map Settings","text":"

      If a device has a location with a valid latitude and logitude, the device overview page will have a panel showing the device on a world map. The following settings affect this map:

      # Does the world map start opened, or does the user need to clivk to view\nlnms config:set device_location_map_open false\n# Do we show all other devices on the map as well\nlnms config:set device_location_map_show_devices false\n# Do we show a network map based on device dependencies\nlnms config:set device_location_map_show_device_dependencies false\n
      "},{"location":"Extensions/World-Map/#offline-openstreet-map","title":"Offline OpenStreet Map","text":"

      If you can't access OpenStreet map directly you can run a local tile server. To specify a different url you can set:

      lnms config:set leaflet.tile_url 'localhost.com'\n
      "},{"location":"Extensions/World-Map/#additional-leaflet-config","title":"Additional Leaflet config","text":"
      lnms config:set map.engine leaflet\nlnms config:set leaflet.default_lat \"51.981074\"\nlnms config:set leaflet.default_lng \"5.350342\"\nlnms config:set leaflet.default_zoom 8\n# Device grouping radius in KM default 80KM\nlnms config:set leaflet.group_radius 1\n# Enable network map on world map\nlnms config:set network_map_show_on_worldmap true\n# Use CDP/LLDP for network map, or device dependencies\nlnms config:set network_map_worldmap_link_type xdp/depends\n# Do not show devices that have notifications disabled\nlnms config:set network_map_worldmap_show_disabled_alerts false\n
      "},{"location":"Extensions/World-Map/#geocode-engine-config","title":"Geocode engine config","text":"

      external/location

      lnms config:set geoloc.engine google\nlnms config:set geoloc.api_key 'abcdefghijklmnopqrstuvwxyz'\n

      Google: Pros: fast, accurate Cons: requires a credit card even for a free account

      MapQuest: Pros: free, no credit card required Cons: inaccurate: most addresses are returned as locations at the center of the US

      Bing: Pros: free, no credit card required, accurate Cons: Microsoft (debatable)

      "},{"location":"Extensions/World-Map/#jquery-mapael-config","title":"Jquery-Mapael config","text":"

      Further custom options are available to load different maps of the world, set default coordinates of where the map will zoom and the zoom level by default. An example of this is:

      lnms config:set map.engine jquery-mapael\nlnms config:set mapael.default_map 'mapael-maps/united_kingdom/united_kingdom.js'\nlnms config:set mapael.map_width 400\nlnms config:set mapael.default_lat '50.898482'\nlnms config:set mapael.default_lng '-3.401402'\nlnms config:set mapael.default_zoom 20\n

      A list of maps can be found in html/js/maps/ or html/js/mapael-maps/.

      "},{"location":"Extensions/metrics/Graphite/","title":"Enabling support for Graphite","text":"

      This module sends all metrics to a remote graphite service. You need something like Grafana for graphing.

      "},{"location":"Extensions/metrics/Graphite/#what-you-dont-get","title":"What you don't get","text":"
      • Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.

      RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

      "},{"location":"Extensions/metrics/Graphite/#configuration","title":"Configuration","text":"

      poller/graphite

      lnms config:set graphite.enable true\nlnms config:set graphite.host 'your.graphite.server'\nlnms config:set graphite.port 2003\nlnms config:set graphite.prefix 'your.metric.prefix'\n

      Your metric path can be prefixed if required, otherwise the metric path for Graphite will be in the form of hostname.measurement.fieldname, interfaces will be stored as hostname.ports.ifName.fieldname.

      The same data then stored within rrd will be sent to Graphite and recorded. You can then create graphs within Grafana to display the information you need.

      "},{"location":"Extensions/metrics/Graphite/#graphite-configuration","title":"Graphite Configuration","text":"

      As LibreNMS updates its metrics every 5 minutes, the following addition to your storage-schemas.conf is suggested.

      [network]\npattern = your\\.metric\\.prefix\\..*\nretentions = 5m:30d,15m:90d,1h:1y\n
      "},{"location":"Extensions/metrics/InfluxDB/","title":"Enabling support for InfluxDB","text":"

      Before we get started it is important that you know and understand that InfluxDB support is currently alpha at best. All it provides is the sending of data to a InfluxDB install. Due to the current changes that are constantly being made to InfluxDB itself then we cannot guarantee that your data will be ok so enabling this support is at your own risk!

      "},{"location":"Extensions/metrics/InfluxDB/#requirements","title":"Requirements","text":"
      • InfluxDB >= 0.94 < 2.0
      • Grafana

      The setup of the above is completely out of scope here and we aren't really able to provide any help with this side of things.

      "},{"location":"Extensions/metrics/InfluxDB/#what-you-dont-get","title":"What you don't get","text":"
      • Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.
      • Support for InfluxDB or Grafana, we would highly recommend that you have some level of experience with these.

      RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

      "},{"location":"Extensions/metrics/InfluxDB/#configuration","title":"Configuration","text":"

      poller/influxdb

      lnms config:set influxdb.enable true\nlnms config:set influxdb.transport http\nlnms config:set influxdb.host '127.0.0.1'\nlnms config:set influxdb.port 8086\nlnms config:set influxdb.db 'librenms'\nlnms config:set influxdb.username 'admin'\nlnms config:set influxdb.password 'admin'\nlnms config:set influxdb.timeout 0\nlnms config:set influxdb.verifySSL false\n

      No credentials are needed if you don't use InfluxDB authentication.

      The same data then stored within rrd will be sent to InfluxDB and recorded. You can then create graphs within Grafana to display the information you need.

      "},{"location":"Extensions/metrics/InfluxDBv2/","title":"Enabling support for InfluxDBv2","text":"

      Before we get started it is important that you know and understand that InfluxDBv2 support is currently alpha at best. All it provides is the sending of data to a InfluxDBv2 bucket. Due to the current changes that are constantly being made to InfluxDB itself then we cannot guarantee that your data will be ok so enabling this support is at your own risk!

      It is also important to understand that InfluxDBv2 only supports the InfluxDBv2 API used in InfluxDB version 2.0 or higher. If you are looking to send data to any other version of InfluxDB than you should use the InfluxDB datastore instead.

      "},{"location":"Extensions/metrics/InfluxDBv2/#requirements","title":"Requirements","text":"
      • InfluxDB >= 2.0

      The setup of the above is completely out of scope here and we aren't really able to provide any help with this side of things.

      "},{"location":"Extensions/metrics/InfluxDBv2/#what-you-dont-get","title":"What you don't get","text":"
      • Support for InfluxDB, we would highly recommend that you have some level of experience with these.

      RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

      "},{"location":"Extensions/metrics/InfluxDBv2/#configuration","title":"Configuration","text":"

      poller/influxdbv2

      lnms config:set influxdbv2.enable true\nlnms config:set influxdbv2.transport http\nlnms config:set influxdbv2.host '127.0.0.1'\nlnms config:set influxdbv2.port 8086\nlnms config:set influxdbv2.bucket 'librenms'\nlnms config:set influxdbv2.token 'admin'\nlnms config:set influxdbv2.allow_redirect true\nlmns config:set influxdbv2.organization 'librenms'\nlmns config:set influxdbv2.debug false\nlmns config:set influxdbv2.groups-exclude [\"group_name_1\",\"group_name_2\"]\n

      The same data stored within rrd will be sent to InfluxDB and recorded. You can then create graphs within Grafana or InfluxDB to display the information you need.

      Please note that polling will slow down when the poller isn't able to reach or write data to InfluxDBv2.

      "},{"location":"Extensions/metrics/OpenTSDB/","title":"Enabling support for OpenTSDB","text":"

      This module sends all metrics to OpenTSDB server. You need something like Grafana for graphing.

      "},{"location":"Extensions/metrics/OpenTSDB/#requirements","title":"Requirements","text":"
      • OpenTSDB
      • Grafana
      "},{"location":"Extensions/metrics/OpenTSDB/#what-you-dont-get","title":"What you don't get","text":"

      Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.

      RRD will continue to function normally so LibreNMS itself should continue to function normally.

      You can add the following to your config:

      "},{"location":"Extensions/metrics/OpenTSDB/#configuration","title":"Configuration","text":"

      poller/opentsdb

      lnms config:set opentsdb.enable true\nlnms config:set opentsdb.host '127.0.0.1'\nlnms config:set opentsdb.port 4242\n

      The same data than the one stored within rrd will be sent to OpenTSDB and recorded. You can then create graphs within Grafana to display the information you need.

      "},{"location":"Extensions/metrics/Prometheus/","title":"Enabling support for Prometheus","text":"

      Please be aware Prometheus support is alpha at best, It hasn't been extensively tested and is still in development All it provides is the sending of data to a a Prometheus PushGateway. Please be careful when enabling this support you use it at your own risk!

      "},{"location":"Extensions/metrics/Prometheus/#requirements-older-versions-may-work-but-havent-been-tested","title":"Requirements (Older versions may work but haven't been tested","text":"
      • Prometheus >= 2.0
      • PushGateway >= 0.4.0
      • Grafana
      • PHP-CURL

      The setup of the above is completely out of scope here and we aren't really able to provide any help with this side of things.

      "},{"location":"Extensions/metrics/Prometheus/#what-you-dont-get","title":"What you don't get","text":"
      • Pretty graphs, this is why at present you need Grafana. You need to build your own graphs within Grafana.
      • Support for Prometheus or Grafana, we would highly recommend that you have some level of experience with these.

      RRD will continue to function as normal so LibreNMS itself should continue to function as normal.

      "},{"location":"Extensions/metrics/Prometheus/#configuration","title":"Configuration","text":"

      poller/prometheus

      lnms config:set prometheus.enable true\nlnms config:set prometheus.url 'http://127.0.0.1:9091'\nlnms config:set prometheus.job 'librenms'\nlnms config:set prometheus.prefix 'librenms'\n

      If your pushgateway uses basic authentication, configure the following:

      poller/prometheus

      lnms config:set prometheus.user username\nlnms config:set prometheus.password password\n
      "},{"location":"Extensions/metrics/Prometheus/#prefix","title":"Prefix","text":"

      Setting the 'prefix' option will cause all metric names to begin with the configured value.

      For instance without setting this option metric names will be something like this:

      OUTUCASTPKTS\nifOutUcastPkts_rate\nINOCTETS\nifInErrors_rate\n

      Configuring a prefix name, for example 'librenms', instead caused those metrics to be exposed with the following names:

      librenms_OUTUCASTPKTS\nlibrenms_ifOutUcastPkts_rate\nlibrenms_INOCTETS\nlibrenms_ifInErrors_rate\n
      "},{"location":"Extensions/metrics/Prometheus/#sample-prometheus-scrape-config-for-scraping-the-push-gateway","title":"Sample Prometheus Scrape Config (for scraping the Push Gateway)","text":"
      - job_name: pushgateway\n  scrape_interval: 300s\n  honor_labels: true\n  static_configs:\n    - targets: ['127.0.0.1:9091']\n

      The same data then stored within rrd will be sent to Prometheus and recorded. You can then create graphs within Grafana to display the information you need.

      "},{"location":"General/Acknowledgement/","title":"Acknowledgements","text":"

      LibreNMS wouldn't be what it is today without the use of some other amazing projects. We list below what we make use of including the license compliance.

      "},{"location":"General/Acknowledgement/#3rd-party-gplv3-compliant","title":"3rd Party GPLv3 Compliant","text":"
      • Bootstrap: MIT
      • Font Awesome: MIT License
      • Jquery Bootgrid: MIT License
      • Pace: Open License
      • Twitter typeahead: Open License
      • Vis: MIT / Apache 2.0
      • TCPDF: LGPLv3
      • Bootstrap 3 Datepicker:MIT
      • Bootstrap Dropdown Hover Plugin: MIT
      • Bootstrap Switch: Apache 2.0
      • Handlebars: Open License
      • Cycle2: MIT/GPL
      • Jquery: MIT
      • Jquery UI: MIT
      • Jquery QRCode: MIT
      • Mktree: Open License
      • Moment: MIT
      • Tag Manager: MIT
      • TW Sack: GPLv3
      • Gridster: MIT
      • Pure PHP radius class: GPLv3
      • GeSHi - Generic Syntax Highlighter: GPLv2+
      • MalaysiaMap.svg - By Exiang CC BY 3.0, via Wikimedia Commons
      • Code for UBNT Devices Mark Gibbons mgibbons@oemcomp.com Initial code base submitted via PR721
      • Jquery LazyLoad: MIT License
      • influxdb-php: MIT License
      • influxdb-client-php: MIT License
      • HTML Purifier: LGPL v2.1
      • Symfony Yaml: MIT
      • PHPMailer: LGPL v2.1
      • pbin: GPLv2 (or later - see script header)
      • CorsSlim: MIT
      • Confluence HTTP Authenticator
      • Graylog SSO Authentication Plugin
      • Select2: MIT License
      • JustGage: MIT
      • jQuery.extendext: MIT
      • doT: MIT
      • jQuery-queryBuilder: MIT
      • sql-parser: MIT (Currently a custom build is used)
      "},{"location":"General/Acknowledgement/#3rd-party-gplv3-non-compliant","title":"3rd Party GPLv3 Non-compliant","text":"
      • JpGraph (html/includes/jpgraph): QPL 1.0 license
      • MIBS (mibs): unknown/various
      • html/graph-realtime.php: BSD (original?)
      • html/includes/collectd/: GPLv2 only
      • overLIB (html/js/overlib_mini.js): modified Artistic 1.0?
      "},{"location":"General/Callback-Stats-and-Privacy/","title":"Submitting Stats","text":""},{"location":"General/Callback-Stats-and-Privacy/#stats-data-and-your-privacy","title":"Stats data and your privacy","text":"

      This document has been put together to explain what LibreNMS does when it calls back home to report some anonymous statistics.

      Let's start off by saying, all of the code that processes the data and submits it is included in the standard LibreNMS branch you've installed, the code that accepts this data and in turn generates some pretty graphs is all open source and available on GitHub. Please feel free to review the code, comment on it and suggest changes / improvements. Also, don't forget - by default installations DO NOT call back home, you need to opt into this.

      Above all we respect users privacy which is why this system has been designed like it has.

      Now onto the bit you're interested in, what is submitted and what we do with that data.

      "},{"location":"General/Callback-Stats-and-Privacy/#what-is-submitted","title":"What is submitted","text":"
      • All data is anonymous.
      • Generic statistics are taken from the database, these include things like device count, device type, device OS, port types, port speeds, port count and BGP peer count. Take a look at the code for full details.
      • Pairs of sysDescr and sysObjectID from devices with a small amount of sanitation to prevent things like hostnames from being submitted.
      • We record version numbers of php, mysql, net-snmp and rrdtool
      • A random UUID is generated on your own install.
      • That's it!
      • Your IP isn't logged, even via our web service accepting the data. We don't need to know who you are so we don't ask.
      "},{"location":"General/Callback-Stats-and-Privacy/#what-we-do-with-the-data","title":"What we do with the data","text":"
      • We store it, not for long - 3 months at the moment although this could change.
      • We use it to generate pretty graphs for people to see.
      • We use it to help prioritise issues and features that need to be worked on.
      • We use sysDescr and sysObjectID to create unit tests and improve OS discovery
      "},{"location":"General/Callback-Stats-and-Privacy/#how-do-i-enable-stats-submission","title":"How do I enable stats submission?","text":"

      If you're happy with all of this - please consider switching the call back system on, you can do this within the About LibreNMS page within your control panel. In the Statistics section you will find a toggle switch to enable / disable the feature. If you've previously had it switched on and want to opt out and remove your data, click the 'Clear remote stats' button and on the next submission all the data you've sent us will be removed!

      "},{"location":"General/Callback-Stats-and-Privacy/#questions","title":"Questions?","text":""},{"location":"General/Callback-Stats-and-Privacy/#how-often-is-data-submitted","title":"How often is data submitted?","text":"

      We submit the data once a day according to running daily.sh via cron. If you disable this then opting in will not have any affect.

      "},{"location":"General/Callback-Stats-and-Privacy/#where-can-i-see-the-data-i-submitted","title":"Where can I see the data I submitted?","text":"

      You can't see the data raw, but we collate all of the data together and provide a dynamic site so you can see the results of all contributed stats here

      "},{"location":"General/Callback-Stats-and-Privacy/#i-want-my-data-removed","title":"I want my data removed.","text":"

      That's easy, simply press 'Clear remote stats' in the About LibreNMS page of your control panel, the next time the call back script is run it will remove all the data we have.

      "},{"location":"General/Callback-Stats-and-Privacy/#i-clicked-the-clear-remote-stats-button-by-accident","title":"I clicked the 'Clear remote stats' button by accident.","text":"

      No problem, before daily.sh runs again - just opt back in, all of your existing data will stay.

      Hopefully this answers the questions you might have on why and what we are doing here, if not, please pop into our discord server or community forum and ask any questions you like.

      "},{"location":"General/Changelog/","title":"Changelog","text":""},{"location":"General/Changelog/#2480","title":"24.8.0","text":"

      (2024-08-15)

      A big thank you to the following 19 contributors this last month:

      • murrant (18)
      • PipoCanaja (5)
      • Npeca75 (2)
      • Jellyfrog (2)
      • nicolasberens (2)
      • electrocret (2)
      • dethmetaljeff (2)
      • xorrkaz (2)
      • rudybroersma (2)
      • TheMysteriousX (1)
      • dependabot (1)
      • ethan-bmn (1)
      • suom1 (1)
      • hatboxen (1)
      • freddy36 (1)
      • Ferris-0815 (1)
      • mib1185 (1)
      • ervin09 (1)
      • x0ul (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • murrant (11)
      • Jellyfrog (10)
      • PipoCanaja (7)
      • electrocret (4)
      • f0o (1)
      • VVelox (1)
      "},{"location":"General/Changelog/#breaking-change","title":"Breaking Change","text":"
      • Fix Port Channel (#16227) - murrant
      "},{"location":"General/Changelog/#device","title":"Device","text":"
      • Bug - Fix CISCO-BGP4-MIB logic (#16260) - PipoCanaja
      • Add support for GUDE Expert Sensor Box (#16257) - Jellyfrog
      • Add skip_values to iosxr hsrp (#16251) - electrocret
      • Improve Fiberstore S3900 series support (#16225) - freddy36
      • Add support for FortiNet FortiExtender (#16219) - rudybroersma
      • F5-Loadbalancer module to support an expiration check of the installed certificates (#16217) - Ferris-0815
      • Add value 0 to HP Physical Drive Status (meaning no disk is inserted) (#16211) - rudybroersma
      • Tripplite console server (#16156) - nicolasberens
      • Device - Adding support to Infortrend DS3016 (#16070) - ervin09
      • Device - Added Baicells Atom OD04 CPE support (#14838) - x0ul
      "},{"location":"General/Changelog/#webui","title":"Webui","text":"
      • [webui] sort vlan tooltip by vlanid (#16266) - Npeca75
      • Add Servicename to Alert Detail (#16249) - electrocret
      • Update graph timezone data (#16244) - murrant
      • Fix custom map default settings error (#16236) - murrant
      • Add link on alert-rules page to display active alerts for rule (#16232) - dethmetaljeff
      • Custom map defaults (#16212) - murrant
      • Make also the total in and out interface errors selectable on the ports list (#16073) - mib1185
      "},{"location":"General/Changelog/#alerting","title":"Alerting","text":"
      • Add bgp peer description to alert_detail (#16233) - dethmetaljeff
      "},{"location":"General/Changelog/#api","title":"Api","text":"
      • Fix list_arp API (#16243) - murrant
      "},{"location":"General/Changelog/#discovery","title":"Discovery","text":"
      • Discovery, make sure where is set (#16237) - murrant
      • Discovery - LLDPv2 support extension, and discovery-protocols tests (#16113) - PipoCanaja
      "},{"location":"General/Changelog/#polling","title":"Polling","text":"
      • Nac polling improvement (#16265) - murrant
      • Fix poller wrapper debug option (#16214) - murrant
      "},{"location":"General/Changelog/#authentication","title":"Authentication","text":"
      • Set default_role when registering instead of at every login (#16235) - suom1
      "},{"location":"General/Changelog/#bug","title":"Bug","text":"
      • Fix alert bug when key missing (#16281) - murrant
      • Remove file differing by case only (#16280) - TheMysteriousX
      • Fix runtime cache (#16272) - murrant
      • Bug - Fixing 'cisco-pw' cpwVcMplsPeerLdpID (#16268) - PipoCanaja
      • [webui] fix port_row.blade generate vlan link (#16256) - Npeca75
      • Bug - services - fix splitting of perfdata (#16255) - nicolasberens
      • Cleanup - Ensure percentage is calculated out of positive values only (#16250) - PipoCanaja
      • Fix error from MikroTik routers when updating BGP peer info (#16224) - xorrkaz
      • Fix snmpsim in CI (#16213) - murrant
      "},{"location":"General/Changelog/#refactor","title":"Refactor","text":"
      • Refactor SnmpResponse mapTable (#16238) - murrant
      "},{"location":"General/Changelog/#cleanup","title":"Cleanup","text":"
      • Mark addhost.php as deprecated (#16283) - murrant
      • Validate.php proper exit code (#16274) - murrant
      • Remove FILTER_SANITIZE_STRING (#16264) - murrant
      "},{"location":"General/Changelog/#documentation","title":"Documentation","text":"
      • Update Devices.md (#16252) - ethan-bmn
      • Docs Update: Large Scale LibreNMS Deployment Example (#16226) - hatboxen
      "},{"location":"General/Changelog/#misc","title":"Misc","text":"
      • Add support for Prometheus pushgateway basic auth (#16230) - xorrkaz
      "},{"location":"General/Changelog/#internal-features","title":"Internal Features","text":"
      • Improve Snmpsim usage to ease testing (#15471) - murrant
      "},{"location":"General/Changelog/#dependencies","title":"Dependencies","text":"
      • Update PHP dependencies (#16263) - murrant
      • Bump postcss from 7.0.39 to 8.4.40 (#16262) - dependabot
      "},{"location":"General/Changelog/#2470","title":"24.7.0","text":"

      (2024-07-17)

      A big thank you to the following 25 contributors this last month:

      • murrant (28)
      • freddy36 (6)
      • VVelox (5)
      • rudybroersma (2)
      • nicolasberens (2)
      • electrocret (2)
      • slashdoom (2)
      • dependabot (2)
      • fabriciotm (1)
      • TridTech (1)
      • PipoCanaja (1)
      • Walkablenormal (1)
      • jediblair (1)
      • westerterp (1)
      • Npeca75 (1)
      • kanokc (1)
      • dennypage (1)
      • normand-hue (1)
      • peejaychilds (1)
      • bonzo81 (1)
      • schnobbc (1)
      • dasdromedar (1)
      • VoipTelCH (1)
      • f7naz (1)
      • jepke (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • murrant (26)
      • PipoCanaja (10)
      • Jellyfrog (5)
      • electrocret (3)
      • ottorei (2)
      • SourceDoctor (1)
      "},{"location":"General/Changelog/#feature","title":"Feature","text":"
      • Lnms snmp:translate always show textual and numeric translations (#16187) - murrant
      • InfluxDBv2 allow filter by group and disable debug by default (#16186) - Walkablenormal
      "},{"location":"General/Changelog/#device_1","title":"Device","text":"
      • Fix FortiGate Cluster Sync status (#16206) - rudybroersma
      • Add transceiver threshold support (#16203) - freddy36
      • Add NAC to Arubaos-CX (#16194) - TridTech
      • Add Hardware and frmware detection for moxa P510 (#16185) - nicolasberens
      • Fix up the Siteboss571 discovery yaml to split pdnOutputCurrentValue and pdnMainCurrentValue indexes (#16181) - jediblair
      • Adjust Line Nominal default limits (#16180) - freddy36
      • Add more Synology disk health info (#16178) - westerterp
      • Add support for Fiberstore branded Centec switches (#16175) - freddy36
      • Fix php issue in cisco ntp code (#16172) - murrant
      • Allow for AXIS Panoramic cameras such as the P4707 (#16166) - dennypage
      • Add support for Fiberstore branded BDCOM switches (#16162) - freddy36
      • Add transceiver monitoring (#16160) - freddy36
      • Add support for more Cisco FTD devices (#16150) - normand-hue
      • ArubaOS - Addtional support to poll Active VPN sessions (#16137) - schnobbc
      • Update eaton-sc200.yaml (#16133) - dasdromedar
      • Update axis detection (#16130) - nicolasberens
      • New OS broadworks / broadsoft (#16078) - jepke
      "},{"location":"General/Changelog/#webui_1","title":"Webui","text":"
      • Maps - Keep edge black when link is 0 bps (#16192) - PipoCanaja
      • [webui] Ports: correct sorting order when using ifName (#16170) - Npeca75
      • Handle missing device when linking (#16164) - murrant
      • WebUI - Dark mode menu fix (#16152) - slashdoom
      • Fix port link device missing (#16151) - murrant
      • Port link component easier graphs (#16147) - murrant
      • Fix graph row lazy loading (#16145) - murrant
      • Left align text for dashboard widgets (#16138) - bonzo81
      • Device Ports settings (#16132) - murrant
      • Change port pagination default to 32 (#16131) - murrant
      • Ports UI update (#16115) - murrant
      "},{"location":"General/Changelog/#alerting_1","title":"Alerting","text":"
      • Alertmanager, Striptag Dynamic Variables! (#16141) - electrocret
      "},{"location":"General/Changelog/#snmp-traps","title":"Snmp Traps","text":"
      • SnmpTrap Handler for Cisco IOS LDP Session UP and DOWN (#16107) - f7naz
      "},{"location":"General/Changelog/#applications","title":"Applications","text":"
      • Add missing graphs for NFS app page (#16197) - VVelox
      • Extend update for wireguard, correct is_int to is_numeric for polling purposes, and clean up the app page (#16182) - VVelox
      • PHP-FPM app update to handle multiple pools (#16122) - VVelox
      • Add some alert template items for CAPEv2 (#16077) - VVelox
      • Add generic and improved NFS support with initial support for both FreeBSD and Linux (#15906) - VVelox
      "},{"location":"General/Changelog/#api_1","title":"Api","text":"
      • Convert list_arp API to Eloquent (#16111) - murrant
      • Fixed wrong column and parameter used when deleting a location via API (#16109) - VoipTelCH
      "},{"location":"General/Changelog/#authentication_1","title":"Authentication","text":"
      • Handle ad/ldap authorizer search error (#16139) - murrant
      "},{"location":"General/Changelog/#bug_1","title":"Bug","text":"
      • Fix null in sensors discovery (#16201) - murrant
      • Fix incorrect get_class call (#16179) - murrant
      • Fix some testing issues (#16174) - murrant
      • BGP integer fields fix (#16173) - murrant
      • Fix for lnms snmp:translate (#16159) - murrant
      "},{"location":"General/Changelog/#documentation_1","title":"Documentation","text":"
      • Changelog cleanup (#16154) - murrant
      • Fortigate append-index doc (#16153) - electrocret
      • Clarify okta claim configuration requirement (#16142) - peejaychilds
      • [DOC] - Update doc/API/DeviceGroups.md (#16140) - slashdoom
      "},{"location":"General/Changelog/#translation","title":"Translation","text":"
      • Support to Brazilian Portuguese (#16209) - fabriciotm
      "},{"location":"General/Changelog/#tests","title":"Tests","text":"
      • Add entity physical test data (#16183) - murrant
      • Add support for snmpsim-lextudio (#16161) - freddy36
      "},{"location":"General/Changelog/#misc_1","title":"Misc","text":"
      • Change entPhysical table column defaults (#16199) - murrant
      "},{"location":"General/Changelog/#internal-features_1","title":"Internal Features","text":"
      • SnmpQuery default improvements (#16204) - murrant
      "},{"location":"General/Changelog/#mibs","title":"Mibs","text":"
      • Radwin MIB update (#16200) - murrant
      • Misc Junos MIB updates (#16171) - murrant
      "},{"location":"General/Changelog/#dependencies_1","title":"Dependencies","text":"
      • Bump tecnickcom/tcpdf from 6.7.4 to 6.7.5 (#16148) - dependabot
      • Bump ws from 8.17.0 to 8.17.1 (#16143) - dependabot
      "},{"location":"General/Changelog/#2460","title":"24.6.0","text":"

      (2024-06-16)

      A big thank you to the following 20 contributors this last month:

      • murrant (13)
      • VVelox (7)
      • PipoCanaja (3)
      • dependabot (2)
      • Npeca75 (2)
      • ashwath129 (2)
      • electrocret (2)
      • scamp (1)
      • nicolasberens (1)
      • sorano (1)
      • GonBlank (1)
      • jepke (1)
      • EinGlasVollKakao (1)
      • Cougar (1)
      • whitej46 (1)
      • cadirol (1)
      • santiag0z (1)
      • rons4 (1)
      • freddy36 (1)
      • cjsoftuk (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • murrant (18)
      • Jellyfrog (12)
      • electrocret (9)
      • PipoCanaja (1)
      "},{"location":"General/Changelog/#feature_1","title":"Feature","text":"
      • ESRI ArcGIS geo map support (#16059) - murrant
      "},{"location":"General/Changelog/#device_2","title":"Device","text":"
      • Update Dell MIBs (#16120) - murrant
      • Add TI-G102i (.46) and TI-PG1284i (.34) (#16099) - nicolasberens
      • Add \"Bullet Camera\" in Axis discovery. (#16098) - sorano
      • [vlans] Add VLANs information to Huawei VRP os (#16089) - Npeca75
      • Cisco Catalyst 1300 recognition (#16080) - jepke
      • Fix Ruckus Unleashed product ID for OS detection (#16067) - Cougar
      • Fix error in riverbed (#16066) - murrant
      • Update Hatteras DSLAM name (#16054) - cadirol
      • Add initial support for socomec-ups (#16018) - Npeca75
      • Fix bdcom/pbn neighbour discovery (#15935) - freddy36
      • Add support for new sensors on Firebrick 9000 models. (#15842) - cjsoftuk
      "},{"location":"General/Changelog/#webui_2","title":"Webui","text":"
      • Fix popup toast messages (Remove Flasher) (#16090) - murrant
      • Handle $app_data['disks'] not being set for SMART app page display (#16087) - VVelox
      • Edit Current Map menu entry (#16084) - murrant
      • Fix device summary widget alignment and dropdown color on dark theme (#16083) - GonBlank
      • Fix duplicate maps in relationship (#16081) - murrant
      • Manage Maps limit width (#16055) - murrant
      • Widget hot refresh & worldmap cleanup (#16053) - murrant
      • Align the buttons (Edit and Delete) to the right in Map Management (#16052) - santiag0z
      "},{"location":"General/Changelog/#alerting_2","title":"Alerting","text":"
      • AlertOps alert transport (#16050) - ashwath129
      • SIGNL4 Alert Transport (#16037) - rons4
      "},{"location":"General/Changelog/#applications_1","title":"Applications","text":"
      • Fix display of graphs on the multi-server app page for Mojo CAPE Submit (#16094) - VVelox
      • Two minor fixes for sagan (#16082) - VVelox
      • Fix path related issues for ss and systemd applications (#16045) - VVelox
      • Add Suricata 7 support to Suricata (#16044) - VVelox
      "},{"location":"General/Changelog/#api_2","title":"Api","text":"
      • Return error when no device ports found (#16043) - murrant
      "},{"location":"General/Changelog/#settings","title":"Settings","text":"
      • Add nfsen_base to config_definitions.json (#16065) - whitej46
      • Remove device_perf_purge (#16057) - electrocret
      • Remove enable_ports_poe (#16056) - electrocret
      "},{"location":"General/Changelog/#bug_2","title":"Bug","text":"
      • Bug - Sorting FDB table by devices (#16116) - PipoCanaja
      • Fix typo in device edit page (#16096) - murrant
      • Fix fping bulk (#16085) - murrant
      • Fix duplication of processor entries & limit length of type (#16075) - EinGlasVollKakao
      "},{"location":"General/Changelog/#refactor_1","title":"Refactor","text":"
      • Rename index_string to str_index_as_numeric (#15916) - PipoCanaja
      "},{"location":"General/Changelog/#documentation_2","title":"Documentation","text":"
      • Note the suffix/prefix stuff for LDAP auth (#16091) - VVelox
      • Clean up SMART docs a bit (#16086) - VVelox
      • Update Transports.md to add documentation for AlertOps (#16058) - ashwath129
      "},{"location":"General/Changelog/#misc_2","title":"Misc","text":"
      • Don't run poller validations when there are no devices (#16088) - murrant
      "},{"location":"General/Changelog/#mibs_1","title":"Mibs","text":"
      • Fix ECS4120 MIB, resolves #16093 (#16101) - scamp
      "},{"location":"General/Changelog/#dependencies_2","title":"Dependencies","text":"
      • Bump braces from 3.0.2 to 3.0.3 (#16105) - dependabot
      • Bump composer/composer from 2.7.1 to 2.7.7 (#16104) - dependabot
      "},{"location":"General/Changelog/#2450","title":"24.5.0","text":"

      (2024-05-19)

      A big thank you to the following 23 contributors this last month:

      • murrant (24)
      • santiag0z (5)
      • eskyuu (3)
      • sogadm (2)
      • Jarod2801 (2)
      • Pikamander2 (1)
      • scamp (1)
      • ottorei (1)
      • whitej46 (1)
      • sonic45132 (1)
      • fbouynot (1)
      • EinGlasVollKakao (1)
      • h-barnhart (1)
      • sarabveer (1)
      • netravnen (1)
      • jthiltges (1)
      • hatboxen (1)
      • electrocret (1)
      • washcroft (1)
      • Npeca75 (1)
      • paulierco (1)
      • drshawnkwang (1)
      • systeembeheerder (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • murrant (22)
      • Jellyfrog (13)
      • electrocret (3)
      • ottorei (1)
      • PipoCanaja (1)
      "},{"location":"General/Changelog/#feature_2","title":"Feature","text":"
      • Custom Maps: geo map and color backgrounds (#16020) - murrant
      • Show custom maps in device overview (#15985) - murrant
      • New Map Menu (#15969) - murrant
      • Mysql PDO options to support SSL/TLS client communication (#15832) - drshawnkwang
      • Snmpscan.py output errors and nodns (#15673) - murrant
      "},{"location":"General/Changelog/#breaking-change_1","title":"Breaking Change","text":"
      • Linux MegaRAID SAS fixes (#15566) - eskyuu
      "},{"location":"General/Changelog/#device_3","title":"Device","text":"
      • Use null coalescing on Panos.php (#16019) - ottorei
      • Improved powerwalker sensors (#15999) - EinGlasVollKakao
      • Added initial support for ULAF+ devices (#15997) - Jarod2801
      • Correct swapped SET and WHERE parameters in bgp-peers/dell-os10.inc.php (#15983) - jthiltges
      • Added FibroLAN devices (#15967) - Jarod2801
      • New velocloud devices (#15958) - paulierco
      "},{"location":"General/Changelog/#webui_3","title":"Webui","text":"
      • Fix issue loading session preferences (#16041) - murrant
      • Device location map zoom out when location N/A (#16034) - murrant
      • Added read permission test to the custom map model (#16030) - eskyuu
      • Do not allow the legend nodes to trigger the node edit modal (#16026) - eskyuu
      • Mobile menu full height (#16011) - murrant
      • Map Management: Show Groups (#16005) - murrant
      • Change custom map editor icon (#16004) - murrant
      • Custom Map: Show crosshairs when adding (#15978) - murrant
      • On-demand map menu items (#15971) - murrant
      • Custom Maps: make edit title clickable (#15965) - murrant
      • [webui] sort ports in VLANs blade (#15960) - Npeca75
      "},{"location":"General/Changelog/#graphs","title":"Graphs","text":"
      • Fix icmp ping y-axis over 1000ms (#16039) - murrant
      • Fix graph_type variable (svg / png) (#15972) - washcroft
      "},{"location":"General/Changelog/#snmp-traps_1","title":"Snmp Traps","text":"
      • SNMP Traps - Ciena AAA (#15998) - h-barnhart
      "},{"location":"General/Changelog/#bug_3","title":"Bug","text":"
      • Fix downtime in corner cases (#16040) - murrant
      • Fix WirelessSensor incorrect model (#16016) - whitej46
      • Merge duplicate toBytes functions (#15994) - murrant
      • Fix systemd graphs using wrong rrd filename variable (#15988) - sarabveer
      • Rrd source does not work with rrdcached (#15974) - murrant
      • Git ignore custom map images (#15966) - murrant
      • Packet_loss macros quick fix (#15961) - murrant
      "},{"location":"General/Changelog/#cleanup_1","title":"Cleanup","text":"
      • Fix incorrect number of seconds in a day (#16042) - Pikamander2
      "},{"location":"General/Changelog/#documentation_3","title":"Documentation","text":"
      • [DOC] Update Customizing-the-Web-UI.md (#16025) - santiag0z
      • [DOC] Install LibreNMS: add Icons (#16017) - santiag0z
      • Set httpd_cache_t type to /opt/librenms/cache (#16000) - fbouynot
      • Update to Material for MkDocs 8.3.9 -> 9.5.20 (#15996) - santiag0z
      • Update link to LibreNMS origin blog post (#15981) - hatboxen
      • Remove poller_name from docs (#15979) - electrocret
      • Update packet_loss docs (#15962) - murrant
      • Update Dispatcher-Service.md (#15705) - systeembeheerder
      "},{"location":"General/Changelog/#translation_1","title":"Translation","text":"
      • Massive changes to the Chinese interface translation. (#16009) - sogadm
      • Chinese translation fixesChinese translation fixes (#15991) - sogadm
      "},{"location":"General/Changelog/#tests_1","title":"Tests","text":"
      • Always run tests (#16024) - murrant
      "},{"location":"General/Changelog/#mibs_2","title":"Mibs","text":"
      • Update MIB for Edge-Core ECS4120-Series (#16023) - scamp
      • Update to latest revision (#15984) - netravnen
      "},{"location":"General/Changelog/#2440","title":"24.4.0","text":"

      (2024-04-19)

      A big thank you to the following 18 contributors this last month:

      • murrant (8)
      • PipoCanaja (4)
      • xorrkaz (2)
      • moisseev (1)
      • VVelox (1)
      • Taarek (1)
      • Melhuig (1)
      • dependabot (1)
      • Lollbrant (1)
      • HolgerHees (1)
      • voileux (1)
      • hvanderheide (1)
      • jasoncheng7115 (1)
      • h-barnhart (1)
      • Jellyfrog (1)
      • CTV-2023 (1)
      • fbouynot (1)
      • OSIRIS-REx (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • Jellyfrog (13)
      • murrant (9)
      • PipoCanaja (8)
      • electrocret (1)
      "},{"location":"General/Changelog/#feature_3","title":"Feature","text":"
      • Improved Latency graph (#15940) - murrant
      "},{"location":"General/Changelog/#security","title":"Security","text":"
      • Fix Graph date selector (#15956) - murrant
      • Fix JS injection in Service Templates (#15954) - murrant
      • Fix SQL injection issues in packages search (#15950) - murrant
      • Improve order validation in list_devices (#15885) - Jellyfrog
      "},{"location":"General/Changelog/#device_4","title":"Device","text":"
      • ILO storage: fix malformed snmp data parsing (#15931) - HolgerHees
      • Add Fortigate HA state sensor definition (#15924) - hvanderheide
      • Devices - Ciena RLS 6500 (#15909) - h-barnhart
      • Cumulus mellanox discovery (#15732) - fbouynot
      • Added support for new device OS Westermo WeOS (#15674) - OSIRIS-REx
      "},{"location":"General/Changelog/#webui_4","title":"Webui","text":"
      • Fix null in services (#15945) - murrant
      "},{"location":"General/Changelog/#alerting_3","title":"Alerting","text":"
      • Pretty up Slack formatting. (#15898) - xorrkaz
      "},{"location":"General/Changelog/#graphs_1","title":"Graphs","text":"
      • Fix typo (#15952) - Taarek
      • Fix graph selection when to/from missing from url (#15946) - murrant
      "},{"location":"General/Changelog/#applications_2","title":"Applications","text":"
      • For gzip+base64 compressed json, don't call stripslashes (#15953) - VVelox
      • Fix PDNS recursor error (#15942) - murrant
      "},{"location":"General/Changelog/#api_3","title":"Api","text":"
      • Add type property to Device class to update it by API (#15930) - voileux
      • Add support for a maintenance boolean in API results. (#15904) - xorrkaz
      "},{"location":"General/Changelog/#bug_4","title":"Bug","text":"
      • Skip rrd sources that do not exist (#15959) - murrant
      • Bug - Cisco NAC key error (#15934) - PipoCanaja
      • Bug - typo for request rate + sanity on numerical not_null values (#15919) - PipoCanaja
      • Bug - vrp - fix signed-tinyint overloaded with disabled radios (#15917) - PipoCanaja
      "},{"location":"General/Changelog/#documentation_4","title":"Documentation","text":"
      • Add missing p5-File-Slurp dependency (#15955) - moisseev
      • Fix \"lnms config:set\" command syntax (#15949) - Melhuig
      • Graylog how to set up non-admin user (#15938) - Lollbrant
      • Documentation - opcache issue on Debian 12 (#15870) - CTV-2023
      "},{"location":"General/Changelog/#translation_2","title":"Translation","text":"
      • Fix wrong terminology (#15920) - jasoncheng7115
      "},{"location":"General/Changelog/#dependencies_3","title":"Dependencies","text":"
      • Bump tecnickcom/tcpdf from 6.6.5 to 6.7.4 (#15948) - dependabot
      "},{"location":"General/Changelog/#2430","title":"24.3.0","text":"

      (2024-04-01)

      A big thank you to the following 24 contributors this last month:

      • rpardim (4)
      • dependabot (3)
      • electrocret (3)
      • bionicman (2)
      • PipoCanaja (2)
      • eskyuu (2)
      • Walkablenormal (2)
      • bnerickson (2)
      • rudybroersma (2)
      • d-k-7 (1)
      • murrant (1)
      • czarnian (1)
      • dmbokhan (1)
      • TheMysteriousX (1)
      • msaringer (1)
      • Didr (1)
      • vhuk (1)
      • Jellyfrog (1)
      • KingDaveRa (1)
      • Npeca75 (1)
      • dethmetaljeff (1)
      • blknight88 (1)
      • gunkaaa (1)
      • pjordanovic (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • Jellyfrog (25)
      • electrocret (7)
      • PipoCanaja (5)
      • murrant (2)
      • laf (2)
      • mpikzink (1)
      • VVelox (1)
      "},{"location":"General/Changelog/#feature_4","title":"Feature","text":"
      • Support for InfluxDB V2 API (#15861) - Walkablenormal
      "},{"location":"General/Changelog/#breaking-change_2","title":"Breaking Change","text":"
      • Wireguard application graph cleanup and new wireguard interface/global metrics. (#15847) - bnerickson
      "},{"location":"General/Changelog/#device_5","title":"Device","text":"
      • Fix catos discovery (#15915) - d-k-7
      • Add health sensors (#15910) - murrant
      • Add support for Huawei YunShan OS (#15903) - czarnian
      • Add support for Ubiquiti Unifi USP-RPS device (#15900) - bionicman
      • Add support for Ubiquiti Unifi LTE devices. (#15899) - bionicman
      • Checkpoint Gaia PowerSupply state sensor (#15882) - rpardim
      • Add support for Cisco FTD 3105 (#15881) - msaringer
      • Fix for Checkpoint Gaia VPN state sensor (#15878) - rpardim
      • Support for Forcepoint NGFW 6.11 and later (#15872) - vhuk
      • A10 ACOS version, state and count sensors (#15871) - rpardim
      • F5 BIG-IP state and count sensors (#15865) - rpardim
      • Supermicro bmc updates (#15862) - dethmetaljeff
      • YAMLized version of previous PR for Ericsson SSR 80xx routers (#15834) - rudybroersma
      • Fix for FortiSwitch RPM/percentage fans (#15829) - rudybroersma
      • Move sentry3 current/voltage/power sensors to YAML (#15715) - gunkaaa
      • Device - EPSON DS-860 + Network Interface Unit DSBXNW1 (#15420) - pjordanovic
      "},{"location":"General/Changelog/#applications_3","title":"Applications","text":"
      • Systemd Application Code Cleanup and new Systemd Unit State Metrics. (#15848) - bnerickson
      "},{"location":"General/Changelog/#discovery_1","title":"Discovery","text":"
      • Bug - Fix OSes 'Junos' and 'Hirschmann' misuse of entPhysicalIndex (#15886) - TheMysteriousX
      "},{"location":"General/Changelog/#bug_5","title":"Bug","text":"
      • Fix Vrf Table (#15912) - electrocret
      • Fix for explicit timezone selection (#15890) - eskyuu
      • Bug - fix extra fields in DB entry create/update (#15883) - PipoCanaja
      • Remove config_bgp config check in bird2 app (#15877) - Didr
      • Custommap label fixes (#15875) - eskyuu
      • [ipv4] fix /32 addresses discovery (#15863) - Npeca75
      "},{"location":"General/Changelog/#refactor_2","title":"Refactor","text":"
      • Refactor - remove unused entPhysicalIndex_measured (#15892) - PipoCanaja
      "},{"location":"General/Changelog/#documentation_5","title":"Documentation","text":"
      • Added additional lines for selinux config to work with RHEL8 (#15864) - KingDaveRa
      • Fix @signedGraphTag documention (#15853) - blknight88
      "},{"location":"General/Changelog/#tests_2","title":"Tests","text":"
      • Bump Github Actions to Node.JS 20. (#15873) - Walkablenormal
      "},{"location":"General/Changelog/#dependencies_4","title":"Dependencies","text":"
      • Bump express from 4.18.2 to 4.19.2 (#15913) - dependabot
      • Bump webpack-dev-middleware from 5.3.3 to 5.3.4 (#15907) - dependabot
      • Bump follow-redirects from 1.15.4 to 1.15.6 (#15897) - dependabot
      • Update dependencies (#15869) - Jellyfrog
      "},{"location":"General/Changelog/#2420","title":"24.2.0","text":"

      (2024-02-27)

      A big thank you to the following 46 contributors this last month:

      • rudybroersma (14)
      • Npeca75 (10)
      • eskyuu (6)
      • electrocret (5)
      • PipoCanaja (5)
      • Jellyfrog (5)
      • vhuk (5)
      • murrant (5)
      • bnerickson (3)
      • fbouynot (3)
      • FlyveHest (2)
      • nickhilliard (2)
      • dependabot (2)
      • richard-ririe (2)
      • laf (2)
      • SourceDoctor (2)
      • VVelox (2)
      • VoipTelCH (1)
      • fabriciotm (1)
      • dirkx (1)
      • swerveshot (1)
      • jmesserli (1)
      • lrizzi (1)
      • Personwho (1)
      • OSIRIS-REx (1)
      • xorrkaz (1)
      • jcostom (1)
      • tevkar (1)
      • descilla (1)
      • arjitc (1)
      • My-Random-Thoughts (1)
      • dlangille (1)
      • blknight88 (1)
      • z0d1ac-RU (1)
      • lferrerfmv (1)
      • gil-obradors (1)
      • gunkaaa (1)
      • TvL2386 (1)
      • santiag0z (1)
      • EinGlasVollKakao (1)
      • kakohegyi (1)
      • i4networks (1)
      • Bierchermuesli (1)
      • mhamzak008 (1)
      • nicklockhart-fullfibre (1)
      • LoveSkylark (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • PipoCanaja (35)
      • Jellyfrog (30)
      • electrocret (26)
      • laf (21)
      • murrant (11)
      • mpikzink (1)
      • rudybroersma (1)
      • ottorei (1)
      • vhuk (1)
      "},{"location":"General/Changelog/#feature_5","title":"Feature","text":"
      • Additional custom map features (#15806) - eskyuu
      • Add/Remove devices from static devicegroups (#15775) - richard-ririe
      • Option to ignore device status (#15697) - SourceDoctor
      • Add functionality for custom maps (weathermaps) (#15633) - eskyuu
      • Alert Rule Editor: new notes field & SQL field improove (#15631) - Bierchermuesli
      • NAC - Improve search in WebUI - Keep Historical data (#15629) - PipoCanaja
      "},{"location":"General/Changelog/#security_1","title":"Security","text":"
      • Fix XSS in default example plugin (#15711) - murrant
      "},{"location":"General/Changelog/#device_6","title":"Device","text":"
      • Updated SLA poller for Cisco Nexus 9000 (#15855) - FlyveHest
      • Update geist-watchdog.yaml (#15851) - fabriciotm
      • Correctly identify FS Datacenter Switch N8560-48BC (#15837) - rudybroersma
      • Konica printers additional counters (#15826) - Npeca75
      • Add HSRP state sensors for Cisco IOSXE on L3 switches (#15823) - rudybroersma
      • Add HSRP Sensor support for IOSXR (#15821) - electrocret
      • Add support for Cisco IE1000 (#15820) - rudybroersma
      • Initial support for Eltex mes24xx (#15816) - Npeca75
      • Add support for Cadant E6000 (#15813) - nickhilliard
      • Add LRT-C / LCM-B / LRS-D / LCM-B modules to Luminato model (#15812) - nickhilliard
      • Add HSRP state sensors for Cisco IOS on L3 switches (#15809) - rudybroersma
      • [rfc1628] Add UPS Test (battery test) status sensor (#15802) - Npeca75
      • Add build 22631 as Windows 11 23H2 (#15800) - vhuk
      • Zyxel ZynOS PoE Budget sensor support (#15798) - rudybroersma
      • Add Procurve NAC support (#15794) - vhuk
      • Add ArubaOS-CX VSF state sensor support (#15793) - rudybroersma
      • Support for new os/devices, CTS (#15790) - OSIRIS-REx
      • Support for new Lancom devices (#15779) - rudybroersma
      • Add NAC support for Powerconnect (#15778) - vhuk
      • Detect UniFi U7 APs as UniFi AP type (#15776) - jcostom
      • FS.com S5810 Discovery fix (#15765) - rudybroersma
      • Device - webpower smart II snmp UPS card (#15764) - Npeca75
      • Support for temp sensors - WUT Thermometers - W57605 and W57614 (#15757) - rudybroersma
      • Initial support for Supermicro BMC (#15750) - Npeca75
      • ArubaOS-CX PSU state sensor support & OS and serial detection (#15738) - rudybroersma
      • Add FortiSwitch PSU state sensor support (#15735) - rudybroersma
      • Added support for Dlink dgs-1250-28x (#15734) - Npeca75
      • Add FortiGate DHCP Scope usage percentage sensors (#15727) - rudybroersma
      • Added MES 2348B (#15725) - z0d1ac-RU
      • Add FortiGate license status sensors (#15722) - rudybroersma
      • Handle icmpjitter SLA parsing for iosxe (#15707) - FlyveHest
      • Zyxel Wireless Controller OS ( Zyxel NXC series ) (#15694) - kakohegyi
      • Device - fix Counter64 octets value in 32bit column bgpPeerInTotalMessages (#15621) - PipoCanaja
      • Fix tp-link jetstream FDB discovery (#14321) - Npeca75
      "},{"location":"General/Changelog/#webui_5","title":"Webui","text":"
      • Disable Page Refresh on Oxidized Tools Page (#15831) - electrocret
      • Modify the date selector to use the session timezone (#15783) - eskyuu
      • Switch bill_notes input to textarea (#15749) - arjitc
      • Sort smart app disks by label (#15686) - SourceDoctor
      "},{"location":"General/Changelog/#alerting_4","title":"Alerting","text":"
      • Add support for Webex max message length. (#15789) - xorrkaz
      • Rename JiraServiceManagement.php to Jiraservicemanagement.php (#15717) - gil-obradors
      • Add JiraServiceManagement Transport (#15593) - mhamzak008
      • Transport - Jira transport rewrite (#15561) - LoveSkylark
      "},{"location":"General/Changelog/#graphs_2","title":"Graphs","text":"
      • Fixed graphs for icmp service showing PL 4 times (#15856) - VoipTelCH
      • Socket Statistic Application cleanup and application page graph fixes. (#15845) - bnerickson
      "},{"location":"General/Changelog/#applications_4","title":"Applications","text":"
      • Deliver output for a specific memcached instance (#15759) - tevkar
      • Update nvidia.inc.php (#15756) - descilla
      • Add BorgBackup monitoring support (#15591) - VVelox
      • Add dhcp-stats tests and update for v3 of the extend (#15378) - VVelox
      "},{"location":"General/Changelog/#billing","title":"Billing","text":"
      • Updated bill_data table, alter indexes and add new column (#15751) - laf
      "},{"location":"General/Changelog/#api_4","title":"Api","text":"
      • Add API endpoints to update and delete Device Groups (#15774) - richard-ririe
      • Add port description API endpoints and documentation (#15578) - nicklockhart-fullfibre
      "},{"location":"General/Changelog/#settings_1","title":"Settings","text":"
      • Fix twofactor default value (#15772) - murrant
      • Add isis module to os schema (#15710) - murrant
      "},{"location":"General/Changelog/#discovery_2","title":"Discovery","text":"
      • Fall back to IPV6-MIB IPv6 address discovery if IP-MIB IPv6 address discovery doesn't return any valid addresses (#15714) - gunkaaa
      "},{"location":"General/Changelog/#oxidized","title":"Oxidized","text":"
      • Add PollerGroup as an option for OxidizedMap (#15696) - electrocret
      "},{"location":"General/Changelog/#bug_6","title":"Bug","text":"
      • Update Port Real Time Graph error (#15846) - electrocret
      • [bugfix] Fix json-app-tool.php to work with Oid class. (#15844) - bnerickson
      • Fix for linkDown/linkUp ifOperStatus (#15835) - PipoCanaja
      • Fix \"Tempurature\" Typo (#15811) - lrizzi
      • Bug fixes for the custom maps (#15810) - eskyuu
      • Remove dumpRawSql() function in AlertUtil.php (#15803) - Personwho
      • Make all image URLs absolute and fix path for viewer (#15788) - eskyuu
      • Prevent ansi colors in key:generate output (#15773) - Jellyfrog
      • VRP - avoid emptying bgpPeers description at discovery when manually set (#15713) - PipoCanaja
      • OSPF instances and missing mandatory fields fix attempt (#15712) - PipoCanaja
      • Fixed typo in misc/alert_rules.json with regards to \"Space on ...\" alerts (#15708) - TvL2386
      • Don't escape leaflet tile url in location edit map (#15695) - EinGlasVollKakao
      • Show error if \"Check Type\" field is empty when creating new service template (#15685) - vhuk
      "},{"location":"General/Changelog/#refactor_3","title":"Refactor","text":"
      • Rewrite ups-nut discovery to SnmpQuery:: (#15850) - Npeca75
      • Rewrite lmsensors discovery to SnmpQuery:: (#15833) - Npeca75
      • Rewrite ipv4 address discovery to Eloquent (#15830) - Npeca75
      "},{"location":"General/Changelog/#documentation_6","title":"Documentation","text":"
      • Applications.md formatting update for better readability. (#15849) - bnerickson
      • Update Images.md (#15824) - swerveshot
      • More precise OAuth group/role claim information (#15817) - jmesserli
      • Add selinux open directory permission for rrdcached in RRDCached.md (#15755) - fbouynot
      • Missing dir read permission in sepolicy in RRDCached.md (#15754) - fbouynot
      • Update SQL override section after switch to SQL strict mode (#15736) - blknight88
      • Add CentOS option to SMART dependency install (#15704) - fbouynot
      "},{"location":"General/Changelog/#misc_3","title":"Misc","text":"
      • Add kelvin to celcius conversion (#15836) - dirkx
      "},{"location":"General/Changelog/#mibs_3","title":"Mibs","text":"
      • Update watchguard MIBs (#15719) - lferrerfmv
      "},{"location":"General/Changelog/#dependencies_5","title":"Dependencies","text":"
      • Bump composer/composer from 2.6.6 to 2.7.0 (#15808) - dependabot
      • Update PHP dependencies (#15737) - murrant
      • Bump follow-redirects from 1.15.3 to 1.15.4 (#15724) - dependabot
      "},{"location":"General/Changelog/#2410","title":"24.1.0","text":"

      (2024-01-07)

      A big thank you to the following 37 contributors this last month:

      • PipoCanaja (12)
      • murrant (7)
      • laf (5)
      • electrocret (3)
      • peejaychilds (3)
      • Jellyfrog (2)
      • vhuk (2)
      • MittWillson (2)
      • Bierchermuesli (2)
      • netravnen (1)
      • iliessens (1)
      • sarcastic6 (1)
      • SourceDoctor (1)
      • altf4arnold (1)
      • robje (1)
      • rudybroersma (1)
      • mtentilucci (1)
      • tuxgasy (1)
      • craig-nokia (1)
      • brianegge (1)
      • amyjohn000 (1)
      • VirTechSystems (1)
      • atj (1)
      • lhwolfarth (1)
      • bonzo81 (1)
      • Sweeny42 (1)
      • jduke-halls (1)
      • pjordanovic (1)
      • dependabot (1)
      • TheMysteriousX (1)
      • swiftnode-linden (1)
      • cguillaumie (1)
      • luc-ass (1)
      • VVelox (1)
      • Leo-FJ (1)
      • MaxPecc (1)
      • jerji (1)

      Thanks to maintainers and others that helped with pull requests this month:

      • Jellyfrog (20)
      • murrant (16)
      • PipoCanaja (15)
      • electrocret (12)
      • craig-nokia (1)
      • ottorei (1)
      "},{"location":"General/Changelog/#device_7","title":"Device","text":"
      • Ignore nameless health sensors for Fortigate (#15678) - iliessens
      • Add support for RoomAlert 32S device (#15676) - sarcastic6
      • Device - Add Cisco REP Segment state sensor (#15666) - rudybroersma
      • Added better support for some HiveOS Wireless devices (#15661) - laf
      • Fix HPE iLO CPU Status Sensor Description (#15660) - mtentilucci
      • Fix OcNOS detection for recent firmware versions (#15642) - murrant
      • Add support for Fortinet FortiAPs (#15641) - atj
      • Fixing memory scale for datacom-dmos devices (#15640) - lhwolfarth
      • Bug - Fix Cisco NTP values (#15639) - PipoCanaja
      • Add support for Forcepoint NGFW 6.10 and older (#15632) - vhuk
      • Bug - timos MPLS - more poller fixes (#15624) - PipoCanaja
      • Add memory readings for Draytek OS (#15618) - Sweeny42
      • Updated support for HiveOS Wireless newer models (#15610) - laf
      • Add HPE iLO 6 to discovery (#15607) - jduke-halls
      • Incorrect discovery APC Smart-UPS RT 3000 XL 4.1 ( APC Web/SNMP Management Card (AP9619 MB:v4.1.1 PF:v3.9.4) as multi-phase ups (#15602) - pjordanovic
      • Device - McAfee Web Gateway -> SkyHigh Web Gateway (#15596) - PipoCanaja
      • Add and extend support for Hirshmann devices (#15588) - cguillaumie
      • Updated regex for HWG STE2 r2 to better detect hardware and software version (#15573) - luc-ass
      • Update entity-sensor.inc.php for xos' os (#15552) - Leo-FJ
      • Added support of new OS for NTP/PTP systems: Meinberg OS, Safran (Orolia), Oscilloquartz (Adva) (#15453) - MaxPecc
      • Zhone health (#15276) - jerji
      • Fix wrong ASN discovery on non-BGP Devices (#14948) - Bierchermuesli
      "},{"location":"General/Changelog/#webui_6","title":"Webui","text":"
      • Clarify In/Out on Ports table. (#15680) - electrocret
      • WebUI - Filter FDB and ARP tabs in port page if empty (#15653) - PipoCanaja
      • Update Pushover.php (#15652) - brianegge
      • Mark old alert email settings as deprecated (#15650) - murrant
      • Add bad port settings to webui (#15649) - murrant
      • Bug - FDB Table - allow empty searchby as well (#15626) - PipoCanaja
      • Update alertlog query to be more efficient (#15622) - laf
      • Add vendor to searchby rules function (#15619) - bonzo81
      • Fix grabled characters when oid already UTF-8 (#15615) - MittWillson
      "},{"location":"General/Changelog/#graphs_3","title":"Graphs","text":"
      • Change default graph image to SVG (#15586) - electrocret
      "},{"location":"General/Changelog/#api_5","title":"Api","text":"
      • API add_device: Add ping_ping fallback option (#15637) - murrant
      • More filter options for the BGP peer API endpoint (#15599) - Bierchermuesli
      "},{"location":"General/Changelog/#discovery_3","title":"Discovery","text":"
      • Set array before use to stop discovery erroring (#15604) - laf
      "},{"location":"General/Changelog/#authentication_2","title":"Authentication","text":"
      • Add support for Okta Group claims to set Roles (#15592) - peejaychilds
      • Output Roles in auth_test script (#15587) - peejaychilds
      "},{"location":"General/Changelog/#bug_7","title":"Bug","text":"
      • Fix Rancid error messages (#15683) - vhuk
      • Fix smart application parsing (#15672) - SourceDoctor
      • Fix pagination in alert rules page (#15659) - tuxgasy
      • Bug - \"null\" checks for SAR 7705 release 8.X (#15657) - craig-nokia
      • Bug - missing \"use\" statement in NTP Cisco (#15656) - PipoCanaja
      • Bug - TPLink - fix null exception for LLDP discovery WIP (#15628) - PipoCanaja
      • Bug - bgp-peers error in Timos -> dbFacile cleanup (#15620) - PipoCanaja
      • Bug - ADSL ifIndex to port error not handled (#15617) - PipoCanaja
      • Bug - XDSL adslAtucCurrOutputPwr exception (Cisco CSCvj53634) (#15614) - PipoCanaja
      • Bug - null checks in Nokia MPLS polling (#15613) - PipoCanaja
      • Bug - Nokia discovery protocols (#15606) - PipoCanaja
      • Make vminfo.vmwVmGuestOS wider (#15595) - TheMysteriousX
      • Fixed state flag causing sql issues in test-template.php (#15589) - laf
      "},{"location":"General/Changelog/#documentation_7","title":"Documentation","text":"
      • Add traceroute to the installed packages doc (#15645) - VirTechSystems
      • Fix documentation formatting (#15635) - Jellyfrog
      • Fix formatting in OAuth-SAML.md (#15616) - peejaychilds
      • Update Debian 12 Installation Instructions. (#15590) - swiftnode-linden
      • Add Debian 12 to install docs (#15559) - VVelox
      "},{"location":"General/Changelog/#misc_4","title":"Misc","text":"
      • Updating the logo to higher resolution one (#15669) - altf4arnold
      • Update the type of nummonbssid column in the access_points table (#15647) - amyjohn000
      • Fix device format missing display field (#15623) - MittWillson
      • Link Model (#15611) - murrant
      • Add space to Oxidized error msg (#15603) - electrocret
      "},{"location":"General/Changelog/#internal-features_2","title":"Internal Features","text":"
      • New utility Number::constrainInteger() (#15663) - murrant
      "},{"location":"General/Changelog/#mibs_4","title":"Mibs","text":"
      • Update MIKROTIK-MIB (#15690) - netravnen
      "},{"location":"General/Changelog/#dependencies_6","title":"Dependencies","text":"
      • Update javascript dependencies (#15651) - murrant
      • Bump phpseclib/phpseclib from 3.0.21 to 3.0.34 (#15600) - dependabot
      "},{"location":"General/Changelog/#old-changelogs","title":"Old Changelogs","text":""},{"location":"General/Releases/","title":"Choosing a release","text":"

      We try to ensure that breaking changes aren't introduced by utilising various automated code testing, syntax testing and unit testing along with manual code review. However bugs can and do get introduced as well as major refactoring to improve the quality of the code base.

      We have two branches available for you to use. The default is the master branch.

      "},{"location":"General/Releases/#development-branch","title":"Development branch","text":"

      Our master branch is our dev branch, this is actively commited to and it's not uncommon for multiple commits to be merged in daily. As such sometimes changes will be introduced which will cause unintended issues. If this happens we are usually quick to fix or revert those changes.

      We appreciate everyone that runs this branch as you are in essence secondary testers to the automation and manually testing that is done during the merge stages.

      You can configure your install (this is the default) to use this branch by setting lnms config:set update_channel master and ensuring you switch to the master branch with:

      cd /opt/librenms && git checkout master

      "},{"location":"General/Releases/#stable-branch","title":"Stable branch","text":"

      With this in mind, we provide a monthly stable release which is released on or around the last Sunday of the month. Code pull requests (aside from Bug fixes) are stopped days leading up to the release to ensure that we have a clean working branch at that point.

      The changelog is also updated and will reference the release number and date so you can see what changes have been made since the last release.

      To switch to using stable branches you can set lnms config:set update_channel release

      This will pause updates until the next stable release, at that time LibreNMS will update to the stable release and continue to only update to stable releases. Downgrading is not supported on LibreNMS and will likely cause bugs.

      "},{"location":"General/Security/","title":"General","text":"

      Like any good software we take security seriously. However, bugs do make it into the software along with the history of the code base we inherited. It's how we deal with identified vulnerabilities that should show that we take things seriously.

      "},{"location":"General/Security/#securing-your-install","title":"Securing your install","text":"

      As with any system of this nature, we highly recommend that you restrict access to the install via a firewall or VPN.

      Please ensure you keep your install up to date.

      "},{"location":"General/Security/#enable-https","title":"Enable HTTPS","text":"

      It is also highly recommended that the Web interface is protected with an SSL certificate such as ones provided by LetsEncrypt.

      "},{"location":"General/Security/#secure-session-cookies","title":"Secure Session Cookies","text":"

      Once you have enabled HTTPS for your install, you should set SESSION_SECURE_COOKIE=true in your .env file. This will require cookies to be transferred by secure protocol and prevent any MiM attacks against it.

      "},{"location":"General/Security/#trusted-proxies","title":"Trusted Proxies","text":"

      When using a reverse proxy, you may restrict the hosts allowed to forward headers to LibreNMS. By default this allows all proxies, due to legacy reasons.

      Set APP_TRUSTED_PROXIES in your .env to an empty string or the urls to the proxies allowed to forward.

      "},{"location":"General/Security/#reporting-vulnerabilities","title":"Reporting vulnerabilities","text":"

      Like anyone, we appreciate the work people put in to find flaws in software and welcome anyone to do so with LibreNMS, this will lead to better quality and more secure software for everyone.

      If you think you've found a vulnerability and want to discuss it with some of the core team then you can contact us on Discord and we will endeavour to get back to as quick as we can, this is usually within 24 hours.

      We are happy to attribute credit to the findings, but we ask that we're given a chance to patch any vulnerability before public disclosure so that our users can update as soon as a fix is available.

      "},{"location":"General/Updating/","title":"Updating an Install","text":"

      By default, LibreNMS is set to automatically update. If you have disabled this feature then you can perform a manual update.

      "},{"location":"General/Updating/#manual-update","title":"Manual update","text":"

      If you would like to perform a manual update then you can do this by running the following command as the librenms user:

      ./daily.sh

      This will update both the core LibreNMS files but also update the database structure if updates are available.

      "},{"location":"General/Updating/#advanced-users","title":"Advanced users","text":"

      If you absolutely must update manually without using ./daily.sh then you can do so by running the following commands:

      cd /opt/librenms\ngit pull\n./scripts/composer_wrapper.php install --no-dev\n./lnms migrate\n./validate.php\n
      "},{"location":"General/Updating/#disabling-automatic-updates","title":"Disabling automatic updates","text":"

      LibreNMS by default performs updates on a daily basis. This can be disabled in the WebUI Global Settings under System -> Updates, or using lnms

      Warning

      You should never remove daily.sh from the cronjob! This does database cleanup and other processes in addition to updating.

      settings/system/updates

      lnms config:set update false\n
      "},{"location":"General/Welcome-to-Observium-users/","title":"Welcome to Observium users","text":"

      LibreNMS is a fork of Observium. The reason for the fork has nothing to do with Observium's move to community vs. paid versions. It is simply that we have different priorities and values to the Observium development team. We decided to fork (reluctantly) because we like using Observium, but we want to collaborate on a community-based project with like-minded IT professionals. See README.md and the references there for more information about the kind of community we're trying to promote.

      LibreNMS was forked from the last GPL-licensed version of Observium.

      Thanks to one of our users, Dan Brown, who has written a migration script, you can easily move your Observium install over to LibreNMS. This also takes care of moving from one CPU architecture to another. Give it a try :)

      How LibreNMS will be different from Observium:

      • We will have an inclusive community, where it's OK to ask stupid questions, and OK to ask for things that aren't on the roadmap. If you'd like to see something added, add or comment on the relevant issue in our Community forum.
      • Development decisions will be community-driven. We want to make software that fulfills its users' needs.
      • There are no plans for a paid version, and we don't anticipate this ever changing.
      • There are no current plans for paid support, but this may be added later if there is sufficient demand.
      • We use git for version control and GitHub for hosting to make it as easy and painless as possible to create forked or private versions.

      Reasons why you might want to use Observium instead of LibreNMS:

      • You have a financial investment in Observium and aren't concerned about community contributions.
      • You don't like the GNU General Public License, version 3 or the philosophy of Free Software/copyleft in general.

      Reasons why you might want to use LibreNMS instead of Observium:

      • You want to work with others on the project, knowing that your investment of time and effort will not be wasted.
      • You want to add and experiment with features that are not a priority for the Observium developers. See CONTRIBUTING for more details.
      • You want to make use of the additional features LibreNMS can offer.
      "},{"location":"Installation/Docker/","title":"Docker","text":"

      An official LibreNMS docker image based on Alpine Linux and Nginx is available on DockerHub.

      "},{"location":"Installation/Docker/#documentation","title":"Documentation","text":"

      Full install and configuration documentation can be found on the GitHub repository.

      "},{"location":"Installation/Docker/#quick-install","title":"Quick install","text":"
      1. Install docker: https://docs.docker.com/engine/install/
      2. Download and unzip composer files:
        mkdir librenms\ncd librenms\nwget https://github.com/librenms/docker/archive/refs/heads/master.zip\nunzip master.zip\ncd docker-master/examples/compose\n
      3. Set a new mysql password in .env and inspect compose.yml
      4. Bring up the docker containers
        sudo docker compose -f compose.yml up -d\n
      5. Open webui to finish configuration. http://localhost:8000 (use the correct ip or name instead of localhost)
      "},{"location":"Installation/Images/","title":"LibreNMS VMs","text":"

      NOTE: We highly advise that you change all passwords on this image when you deploy it!!

      NOTE: These images ship with a vagrant user, please remove this user account when you deploy it!!

      NOTE: Read the above note again!

      We have available for download a pre-built image based on Ubuntu 22.04. These images are built using packer.io.

      Details of the image and it's setup are:

      At present we provide the following builds:

      • OVA Built with VirtualBox.
      • OVA Built for VMWare ESXi.
      • Vagrant Box file.

      • Any issues and or help with these images should be reported via Community Forum or our Discord server

      "},{"location":"Installation/Images/#setup","title":"Setup","text":"
      • US Keyboard
      • Etc/UTC Timezone
      • 4 Poller Wrapper threads
      "},{"location":"Installation/Images/#software","title":"Software","text":"
      • PHP 8.1
      • MariaDB
      • Syslog-ng
      "},{"location":"Installation/Images/#features","title":"Features","text":"
      • Oxidized installed but not configured
      • Weathermap plugin enabled
      • Billing enabled
      • RRDCached enabled
      • Service checks enabled
      • Syslog enabled
      "},{"location":"Installation/Images/#download","title":"Download","text":"

      All images can be downloaded from GitHub. The tags follow the main LibreNMS repo. When a new LibreNMS release is available we will push new images out running that version. Please do note that if you download an older release with a view to running that specific version, you will need to disable updates lnms config:set update false.

      "},{"location":"Installation/Images/#accesscredentials","title":"Access/Credentials","text":"

      If you are using the VirtualBox image then to access your newly imported VM, these ports are forwarded from your machine to the VM: 8080 for WebUI and 2023 for SSH. Remember to edit/remove them if you change (and you should) the VM network configuration.

      • WebUI (http://localhost)
      • username: librenms
      • password: D32fwefwef

      • SSH (change the password ssh://localhost:2023)

      • username: librenms
      • password: CDne3fwdfds

      • SSH (remove this account)

      • username: vagrant
      • password; vagrant

      • MySQL/MariaDB

      • username: librenms
      • password: D42nf23rewD
      "},{"location":"Installation/Images/#contributing","title":"Contributing","text":"

      If you would like to help with these images whether it's add additional features or default software / settings then you can do so on GitHub.

      "},{"location":"Installation/Install-LibreNMS/","title":"Install LibreNMS","text":""},{"location":"Installation/Install-LibreNMS/#prepare-linux-server","title":"Prepare Linux Server","text":"

      You should have an installed Linux server running one of the supported OS. Make sure you select your server's OS in the tabbed options below. Choice of web server is your preference, NGINX is recommended.

      Connect to the server command line and follow the instructions below.

      Note

      These instructions assume you are the root user. If you are not, prepend sudo to the shell commands (the ones that aren't at mysql> prompts) or temporarily become a user with root privileges with sudo -s or sudo -i.

      Please note the minimum supported PHP version is 8.1

      "},{"location":"Installation/Install-LibreNMS/#install-required-packages","title":"Install Required Packages","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12 NGINX
      apt install acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd unzip python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip whois traceroute\n
      NGINX
      apt install acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd unzip python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip whois traceroute\n
      NGINXApache
      apt install software-properties-common\nadd-apt-repository universe\nadd-apt-repository ppa:ondrej/php\napt update\napt install acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd unzip python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip whois traceroute\n
      apt install software-properties-common\nadd-apt-repository universe\nadd-apt-repository ppa:ondrej/php\napt update\napt install acl curl apache2 fping git graphviz imagemagick libapache2-mod-fcgid mariadb-client mariadb-server mtr-tiny nmap php-cli php-curl php-fpm php-gd php-gmp php-json php-mbstring php-mysql php-snmp php-xml php-zip rrdtool snmp snmpd whois python3-pymysql python3-dotenv python3-redis python3-setuptools python3-systemd python3-pip unzip traceroute\n
      NGINXApache
      dnf -y install epel-release\ndnf -y install dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm\ndnf module reset php\ndnf module enable php:8.1\ndnf install bash-completion cronie fping git ImageMagick mariadb-server mtr net-snmp net-snmp-utils nginx nmap php-fpm php-cli php-common php-curl php-gd php-gmp php-json php-mbstring php-process php-snmp php-xml php-zip php-mysqlnd python3 python3-PyMySQL python3-redis python3-memcached python3-pip python3-systemd rrdtool unzip\n
      dnf -y install epel-release\ndnf -y install dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm\ndnf module reset php\ndnf module enable php:remi-8.1\ndnf install bash-completion cronie fping gcc git httpd ImageMagick mariadb-server mtr net-snmp net-snmp-utils nmap php-fpm php-cli php-common php-curl php-gd php-gmp php-json php-mbstring php-process php-snmp php-xml php-zip php-mysqlnd python3 python3-devel python3-PyMySQL python3-redis python3-memcached python3-pip python3-systemd rrdtool unzip \n
      NGINX
      apt install apt-transport-https lsb-release ca-certificates wget acl curl fping git graphviz imagemagick mariadb-client mariadb-server mtr-tiny nginx-full nmap php8.2-cli php8.2-curl php8.2-fpm php8.2-gd php8.2-gmp php8.2-mbstring php8.2-mysql php8.2-snmp php8.2-xml php8.2-zip python3-dotenv python3-pymysql python3-redis python3-setuptools python3-systemd python3-pip rrdtool snmp snmpd unzip whois\n
      "},{"location":"Installation/Install-LibreNMS/#add-librenms-user","title":"Add librenms user","text":"
      useradd librenms -d /opt/librenms -M -r -s \"$(which bash)\"\n
      "},{"location":"Installation/Install-LibreNMS/#download-librenms","title":"Download LibreNMS","text":"
      cd /opt\ngit clone https://github.com/librenms/librenms.git\n
      "},{"location":"Installation/Install-LibreNMS/#set-permissions","title":"Set permissions","text":"
      chown -R librenms:librenms /opt/librenms\nchmod 771 /opt/librenms\nsetfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/\nsetfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs /opt/librenms/bootstrap/cache/ /opt/librenms/storage/\n
      "},{"location":"Installation/Install-LibreNMS/#install-php-dependencies","title":"Install PHP dependencies","text":"

      su - librenms\n./scripts/composer_wrapper.php install --no-dev\nexit\n
      Sometimes when there is a proxy used to gain internet access, the above script may fail. The workaround is to install the composer package manually. For a global installation:
      wget https://getcomposer.org/composer-stable.phar\nmv composer-stable.phar /usr/bin/composer\nchmod +x /usr/bin/composer\n

      "},{"location":"Installation/Install-LibreNMS/#set-timezone","title":"Set timezone","text":"

      See https://php.net/manual/en/timezones.php for a list of supported timezones. Valid examples are: \"America/New_York\", \"Australia/Brisbane\", \"Etc/UTC\". Ensure date.timezone is set in php.ini to your preferred time zone.

      Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12
      vi /etc/php/8.3/fpm/php.ini\nvi /etc/php/8.3/cli/php.ini\n
      vi /etc/php/8.1/fpm/php.ini\nvi /etc/php/8.1/cli/php.ini\n
      vi /etc/php/8.1/fpm/php.ini\nvi /etc/php/8.1/cli/php.ini\n
      vi /etc/php.ini\n
      vi /etc/php/8.2/fpm/php.ini\nvi /etc/php/8.2/cli/php.ini\n

      Remember to set the system timezone as well.

      timedatectl set-timezone Etc/UTC\n
      "},{"location":"Installation/Install-LibreNMS/#configure-mariadb","title":"Configure MariaDB","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12
      vi /etc/mysql/mariadb.conf.d/50-server.cnf\n
      vi /etc/mysql/mariadb.conf.d/50-server.cnf\n
      vi /etc/mysql/mariadb.conf.d/50-server.cnf\n
      vi /etc/my.cnf.d/mariadb-server.cnf\n
      vi /etc/mysql/mariadb.conf.d/50-server.cnf\n

      Within the [mysqld] section add:

      innodb_file_per_table=1\nlower_case_table_names=0\n

      Then restart MariaDB

      systemctl enable mariadb\nsystemctl restart mariadb\n
      Start MariaDB client

      mysql -u root\n

      NOTE: Change the 'password' below to something secure.

      CREATE DATABASE librenms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\nCREATE USER 'librenms'@'localhost' IDENTIFIED BY 'password';\nGRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'localhost';\nexit\n
      "},{"location":"Installation/Install-LibreNMS/#configure-php-fpm","title":"Configure PHP-FPM","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12
      cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/librenms.conf\nvi /etc/php/8.3/fpm/pool.d/librenms.conf\n
      cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/librenms.conf\nvi /etc/php/8.1/fpm/pool.d/librenms.conf\n
      cp /etc/php/8.1/fpm/pool.d/www.conf /etc/php/8.1/fpm/pool.d/librenms.conf\nvi /etc/php/8.1/fpm/pool.d/librenms.conf\n
      cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/librenms.conf\nvi /etc/php-fpm.d/librenms.conf\n
      cp /etc/php/8.2/fpm/pool.d/www.conf /etc/php/8.2/fpm/pool.d/librenms.conf\nvi /etc/php/8.2/fpm/pool.d/librenms.conf\n

      Change [www] to [librenms]:

      [librenms]\n

      Change user and group to \"librenms\":

      user = librenms\ngroup = librenms\n

      Change listen to a unique path that must match your webserver's config (fastcgi_pass for NGINX and SetHandler for Apache) :

      listen = /run/php-fpm-librenms.sock\n

      If there are no other PHP web applications on this server, you may remove www.conf to save some resources. Feel free to tune the performance settings in librenms.conf to meet your needs.

      "},{"location":"Installation/Install-LibreNMS/#configure-web-server","title":"Configure Web Server","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12 NGINX
      vi /etc/nginx/conf.d/librenms.conf\n

      Add the following config, edit server_name as required:

      server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
      rm /etc/nginx/sites-enabled/default /etc/nginx/sites-available/default\nsystemctl restart nginx\nsystemctl restart php8.3-fpm\n
      NGINX
      vi /etc/nginx/conf.d/librenms.conf\n

      Add the following config, edit server_name as required:

      server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
      rm /etc/nginx/sites-enabled/default\nsystemctl restart nginx\nsystemctl restart php8.1-fpm\n
      NGINXApache
      vi /etc/nginx/conf.d/librenms.conf\n

      Add the following config, edit server_name as required:

      server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
      rm /etc/nginx/sites-enabled/default\nsystemctl restart nginx\nsystemctl restart php8.1-fpm\n
      vi /etc/apache2/sites-available/librenms.conf\n

      Add the following config, edit ServerName as required:

      <VirtualHost *:80>\n  DocumentRoot /opt/librenms/html/\n  ServerName  librenms.example.com\n\n  AllowEncodedSlashes NoDecode\n  <Directory \"/opt/librenms/html/\">\n    Require all granted\n    AllowOverride All\n    Options FollowSymLinks MultiViews\n  </Directory>\n\n  # Enable http authorization headers\n  <IfModule setenvif_module>\n    SetEnvIfNoCase ^Authorization$ \"(.+)\" HTTP_AUTHORIZATION=$1\n  </IfModule>\n\n  <FilesMatch \".+\\.php$\">\n    SetHandler \"proxy:unix:/run/php-fpm-librenms.sock|fcgi://localhost\"\n  </FilesMatch>\n</VirtualHost>\n
      a2dissite 000-default\na2enmod proxy_fcgi setenvif rewrite\na2ensite librenms.conf\nsystemctl restart apache2\nsystemctl restart php8.1-fpm\n
      NGINXApache
      vi /etc/nginx/conf.d/librenms.conf\n

      Add the following config, edit server_name as required:

      server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n

      NOTE: If this is the only site you are hosting on this server (it should be :)) then you will need to disable the default site.

      Delete the server section from /etc/nginx/nginx.conf

      systemctl enable --now nginx\nsystemctl enable --now php-fpm\n

      Create the librenms.conf:

      vi /etc/httpd/conf.d/librenms.conf\n

      Add the following config, edit ServerName as required:

      <VirtualHost *:80>\n  DocumentRoot /opt/librenms/html/\n  ServerName  librenms.example.com\n\n  AllowEncodedSlashes NoDecode\n  <Directory \"/opt/librenms/html/\">\n    Require all granted\n    AllowOverride All\n    Options FollowSymLinks MultiViews\n  </Directory>\n\n  # Enable http authorization headers\n  <IfModule setenvif_module>\n    SetEnvIfNoCase ^Authorization$ \"(.+)\" HTTP_AUTHORIZATION=$1\n  </IfModule>\n\n  <FilesMatch \".+\\.php$\">\n    SetHandler \"proxy:unix:/run/php-fpm-librenms.sock|fcgi://localhost\"\n  </FilesMatch>\n</VirtualHost>\n

      NOTE: If this is the only site you are hosting on this server (it should be :)) then you will need to disable the default site. rm -f /etc/httpd/conf.d/welcome.conf

      systemctl enable --now httpd\nsystemctl enable --now php-fpm\n
      NGINX
      vi /etc/nginx/sites-enabled/librenms.vhost\n

      Add the following config, edit server_name as required:

      server {\n listen      80;\n server_name librenms.example.com;\n root        /opt/librenms/html;\n index       index.php;\n\n charset utf-8;\n gzip on;\n gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;\n location / {\n  try_files $uri $uri/ /index.php?$query_string;\n }\n location ~ [^/]\\.php(/|$) {\n  fastcgi_pass unix:/run/php-fpm-librenms.sock;\n  fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n  include fastcgi.conf;\n }\n location ~ /\\.(?!well-known).* {\n  deny all;\n }\n}\n
      rm /etc/nginx/sites-enabled/default\nsystemctl reload nginx\nsystemctl restart php8.2-fpm\n
      "},{"location":"Installation/Install-LibreNMS/#selinux","title":"SELinux","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12

      SELinux not enabled by default

      SELinux not enabled by default

      SELinux not enabled by default

      Install the policy tool for SELinux:

      dnf install policycoreutils-python-utils\n

      Configure the contexts needed by LibreNMS

      semanage fcontext -a -t httpd_sys_content_t '/opt/librenms/html(/.*)?'\nsemanage fcontext -a -t httpd_sys_rw_content_t '/opt/librenms/(rrd|storage)(/.*)?'\nsemanage fcontext -a -t httpd_log_t \"/opt/librenms/logs(/.*)?\"\nsemanage fcontext -a -t httpd_cache_t '/opt/librenms/cache(/.*)?'\nsemanage fcontext -a -t bin_t '/opt/librenms/librenms-service.py'\nrestorecon -RFvv /opt/librenms\nsetsebool -P httpd_can_sendmail=1\nsetsebool -P httpd_execmem 1\nchcon -t httpd_sys_rw_content_t /opt/librenms/.env\n

      Allow fping

      Create the file http_fping.tt with the following contents. You can create this file anywhere, as it is a throw-away file. The last step in this install procedure will install the module in the proper location.

      module http_fping 1.0;\n\nrequire {\ntype httpd_t;\nclass capability net_raw;\nclass rawip_socket { getopt create setopt write read };\n}\n\n#============= httpd_t ==============\nallow httpd_t self:capability net_raw;\nallow httpd_t self:rawip_socket { getopt create setopt write read };\n

      Then run these commands

      checkmodule -M -m -o http_fping.mod http_fping.tt\nsemodule_package -o http_fping.pp -m http_fping.mod\nsemodule -i http_fping.pp\n

      Additional SELinux problems may be found by executing the following command

      audit2why < /var/log/audit/audit.log\n

      SELinux not enabled by default

      "},{"location":"Installation/Install-LibreNMS/#allow-access-through-firewall","title":"Allow access through firewall","text":"Ubuntu 24.04Ubuntu 22.04Ubuntu 20.04CentOS 8Debian 12

      Firewall not enabled by default

      Firewall not enabled by default

      Firewall not enabled by default

      firewall-cmd --zone public --add-service http --add-service https\nfirewall-cmd --permanent --zone public --add-service http --add-service https\n

      Firewall not enabled by default

      "},{"location":"Installation/Install-LibreNMS/#enable-lnms-command-completion","title":"Enable lnms command completion","text":"

      This feature grants you the opportunity to use tab for completion on lnms commands as you would for normal linux commands.

      ln -s /opt/librenms/lnms /usr/bin/lnms\ncp /opt/librenms/misc/lnms-completion.bash /etc/bash_completion.d/\n
      "},{"location":"Installation/Install-LibreNMS/#configure-snmpd","title":"Configure snmpd","text":"
      cp /opt/librenms/snmpd.conf.example /etc/snmp/snmpd.conf\n
      vi /etc/snmp/snmpd.conf\n

      Edit the text which says RANDOMSTRINGGOESHERE and set your own community string.

      curl -o /usr/bin/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro\nchmod +x /usr/bin/distro\nsystemctl enable snmpd\nsystemctl restart snmpd\n
      "},{"location":"Installation/Install-LibreNMS/#cron-job","title":"Cron job","text":"
      cp /opt/librenms/dist/librenms.cron /etc/cron.d/librenms\n

      NOTE: Keep in mind that cron, by default, only uses a very limited set of environment variables. You may need to configure proxy variables for the cron invocation. Alternatively adding the proxy settings in config.php is possible too. The config.php file will be created in the upcoming steps. Review the following URL after you finished librenms install steps: https://docs.librenms.org//Support/Configuration/#proxy-support

      "},{"location":"Installation/Install-LibreNMS/#enable-the-scheduler","title":"Enable the scheduler","text":"
      cp /opt/librenms/dist/librenms-scheduler.service /opt/librenms/dist/librenms-scheduler.timer /etc/systemd/system/\n\nsystemctl enable librenms-scheduler.timer\nsystemctl start librenms-scheduler.timer\n
      "},{"location":"Installation/Install-LibreNMS/#copy-logrotate-config","title":"Copy logrotate config","text":"

      LibreNMS keeps logs in /opt/librenms/logs. Over time these can become large and be rotated out. To rotate out the old logs you can use the provided logrotate config file:

      cp /opt/librenms/misc/librenms.logrotate /etc/logrotate.d/librenms\n
      "},{"location":"Installation/Install-LibreNMS/#web-installer","title":"Web installer","text":"

      Now head to the web installer and follow the on-screen instructions.

      http://librenms.example.com/install

      The web installer might prompt you to create a config.php file in your librenms install location manually, copying the content displayed on-screen to the file. If you have to do this, please remember to set the permissions on config.php after you copied the on-screen contents to the file. Run:

      chown librenms:librenms /opt/librenms/config.php\n
      "},{"location":"Installation/Install-LibreNMS/#final-steps","title":"Final steps","text":"

      That's it! You now should be able to log in to http://librenms.example.com/. Please note that we have not covered HTTPS setup in this example, so your LibreNMS install is not secure by default. Please do not expose it to the public Internet unless you have configured HTTPS and taken appropriate web server hardening steps.

      "},{"location":"Installation/Install-LibreNMS/#add-the-first-device","title":"Add the first device","text":"

      We now suggest that you add localhost as your first device from within the WebUI.

      "},{"location":"Installation/Install-LibreNMS/#troubleshooting","title":"Troubleshooting","text":"

      If you ever have issues with your install, run validate.php:

      sudo su - librenms\n./validate.php\n

      There are various options for getting help listed on the LibreNMS web site: https://www.librenms.org/#support

      "},{"location":"Installation/Install-LibreNMS/#what-next","title":"What next?","text":"

      Now that you've installed LibreNMS, we'd suggest that you have a read of a few other docs to get you going:

      • Performance tuning
      • Alerting
      • Device Groups
      • Auto discovery
      "},{"location":"Installation/Install-LibreNMS/#closing","title":"Closing","text":"

      We hope you enjoy using LibreNMS. If you do, it would be great if you would consider opting into the stats system we have, please see this page on what it is and how to enable it.

      If you would like to help make LibreNMS better there are many ways to help. You can also back LibreNMS on Open Collective.

      "},{"location":"Installation/Migrating-from-Observium/","title":"Migrating from Observium","text":"

      A LibreNMS user, Dan, has kindly provided full details and scripts to be able to migrate from Observium to LibreNMS.

      We have mirrored the scripts he's provided with consent, these are available in the scripts\\Migration folder of your installation..

      "},{"location":"Installation/Migrating-from-Observium/#setup","title":"Setup:","text":"

      First I had to lay out my script requirements:

      • Build the RRD directories on LibreNMS
      • Convert the RRD files on Observium to XML (x86 to x64 move)
      • Copy the RRD/XML files to LibreNMS
      • Convert the XML files back to RRD files
      • Add the device to LibreNMS
      "},{"location":"Installation/Migrating-from-Observium/#script","title":"Script:","text":"

      There are two versions of the scripts available for you to download: - One converts the RRDs to XML and then back to RRD files when they hit the destination. This is a requirement if you are moving from x86 to x64. - Assuming you\u2019re moving servers that are on the same architecture, we can skip that step and just SCP the original RRD files.

      For everything to work as originally intended, you\u2019ll need four files.\u00a0Put all four files on both servers, the scripts default to /tmp/:

      • nodelist.txt \u2013 this file contains the list of hosts you would like to move. This must match exactly to the hostname Observium uses
      • mkdir.sh \u2013 this script creates the necessary directories on your LibreNMS server
      • destwork.sh \u2013 depending on the version you choose, this script will add the device to LibreNMS and possibly convert from XML to RRD
      • convert.sh \u2013 convert is the main script we\u2019ll be calling. All of the magic happens here.

      Feel free to crack open the scripts and modify them to suit you. Each file has a handful of variables you\u2019ll need to set for your conversion. They should be self-explanatory, but please leave a comment if you have trouble.

      "},{"location":"Installation/Migrating-from-Observium/#conversion","title":"Conversion:","text":"

      This section assumes the following:

      • Root access is available on both servers
      • You have SSH access to both servers
      • All four files have been placed in the tmp directory of both servers

      I would strongly suggest you start with just one or two hosts and see how things work. For me, 10 standard sized devices took about 20 minutes with the RRD to XML conversion. Every environment will be different, so start slow and work your way up to full automation.

      "},{"location":"Installation/Migrating-from-Observium/#ssh-keys","title":"SSH Keys","text":"

      First thing we will want to do is exchange SSH keys so that we can automate the login process used by the scripts. Perform these steps on your Observium server:

      ssh-keygen -t rsa

      Accept the defaults and enter a passphrase if you wish. Then:

      ssh-copy-id librenms

      Where librenms is the hostname or IP of your destination server.

      "},{"location":"Installation/Migrating-from-Observium/#nodelisttxt","title":"Nodelist.txt","text":"

      The nodelist.txt file contains a list of hosts we want to migrate from Observium. These names must match the name of the RRD folder on Observium. You can get those names by running the following \u2013

      ls /opt/observium/rrd/

      Also important, the nodelist.txt file must be on\u00a0both your Observium and LibreNMS server. Once you have your list, edit nodelist.txt with\u00a0nano:

      nano /tmp/nodelist.txt

      And replace the dummy data with the hosts you are converting. CTRL+X and then Y to save your modifications. Make the same changes on the LibreNMS server.

      "},{"location":"Installation/Migrating-from-Observium/#script-variables","title":"Script Variables","text":"

      Now that we have nodelist.txt setup correctly, it is time to set the variables in all three shell scripts. We are going to start with convert.sh. Edit it with nano:

      nano /tmp/convert.sh

      and change the variables to suit your environment. Here is a quick list of them:

      • DEST \u2013 This should be the IP or hostname of your LibreNMS server
      • L_RRDPATH \u2013 This signifies the location of the LibreNMS RRD directory. The default value is the default install location
      • O_RRDPATH \u2013 Location of the Observium RRD directory. The default value is the default install location
      • MKDIR \u2013 Location of the mkdir.sh script
      • DESTSCRIPT \u2013 Location of the destwork.sh script
      • NODELIST \u2013 Location of the nodelist.txt file

      Next, edit the destwork.sh script:

      nano /tmp/destwork.sh

      "},{"location":"Support/","title":"How to get Help","text":"
      • Browse through the navigation on the left
      • Search in the upper right
      • Check the frequently asked questions
      "},{"location":"Support/#additional-support","title":"Additional Support","text":"

      We have a few methods for you to get in touch to ask for help.

      • Community Forum
      • Ask for Help
      • Feature Requests

      • Discord Active chat and discussion

      • Bug Reports

      "},{"location":"Support/1-Minute-Polling/","title":"1-Minute Polling","text":"

      We now have support for polling data at intervals to fit your needs.

      Please be aware of the following:

      • If you just want faster up/down alerts, Fast Ping is a much easier path to that goal.
      • You must also change your cron entry for poller-wrapper.py for this to work (if you change from the default 300 seconds).
      • Your polling MUST complete in the time you configure for the heartbeat step value. See /poller in your WebUI for your current value.
      • This will only affect RRD files created from the moment you change your settings.
      • This change will affect all data storage mechanisms such as MySQL, RRD and InfluxDB. If you decrease the values then please be aware of the increase in space use for MySQL and InfluxDB.
      • It's highly recommended to configure some performance optimizations. Keep in mind that all your devices will write all graphs every minute to the disk and that every device has many graphs. The most important thing is probably the RRDCached configuration that can save a lot of write IOPS.

      To make the changes, please navigate to /settings/poller/rrdtool/ within your WebUI. Select RRDTool Setup and then update the two values for step and heartbeat intervals:

      • Step is how often you want to insert data, so if you change to 1 minute polling then this should be 60.
      • Heartbeat is how long to wait for data before registering a null value, i.e 120 seconds.
      "},{"location":"Support/1-Minute-Polling/#converting-existing-rrd-files","title":"Converting existing RRD files","text":"

      We provide a basic script to convert the default rrd files we generate to utilise your configured step and heartbeat values. Please do ensure that you backup your RRD files before running this just in case. The script runs on a per device basis or all devices at once.

      The rrd files must be accessible from the server you run this script from.

      ./scripts/rrdstep.php

      This will provide the help information. To run it for localhost just run:

      ./scripts/rrdstep.php -h localhost

      "},{"location":"Support/Adding-a-Device/","title":"Adding Device","text":"

      You have two options for adding a new device into LibreNMS. You can add a device via the cli or by using the WebUI.

      "},{"location":"Support/Adding-a-Device/#via-webui","title":"Via WebUI","text":"

      Using the web interface, go to Devices and click Add Device. Enter the details required for the device that you want to add and then click 'Add Host'. As an example, if your device is configured to use the community my_company using snmp v2c then you would enter: SNMP Port defaults to 161.

      By default Hostname will be used for polling data. If you want to get polling Device data via a specific IP-Address (e.g. Management IP) fill out the optional field Overwrite IP with it's IP-Address.

      "},{"location":"Support/Adding-a-Device/#via-cli","title":"Via CLI","text":"

      Using the command line via ssh you can add a new device by changing to the directory of your LibreNMS install and typing (be sure to put the correct details).

      ./lnms device:add yourhostname [--v1|--v2c] [-c yourSNMPcommunity]\n

      You can use ./lnms device:add --help for a list of available options and defaults.

      As an example, if your device with the name mydevice.example.com is configured to use the community my_company using snmp v2c then you would enter:

      ./lnms device:add --v2c -c my_company mydevice.example.com\n

      Please note that if the community contains special characters such as $ then you will need to wrap it in '. I.e: 'Pa$$w0rd'.

      "},{"location":"Support/Adding-a-Device/#ping-only-device","title":"Ping Only Device","text":"

      You can add ping only devices into LibreNMS through the WebUI or CLI. When adding the device switch the SNMP button to \"off\". Device will be added into LibreNMS as Ping Only Device and will show ICMP Response Graph.

      • Hostname: IP address or DNS name.
      • Hardware: Optional you can type in whatever you like.
      • OS: Optional this will add the Device's OS Icon.

      Via CLI this is done with ./lnms device:add [-P|--ping-only] yourhostname

      A How-to video can be found here: How to add ping only devices

      "},{"location":"Support/Adding-a-Device/#automatic-discovery-and-api","title":"Automatic Discovery and API","text":"

      If you would like to add devices automatically then you will probably want to read the Auto-discovery Setup guide.

      You may also want to add devices programmatically, if so, take a look at our API documentation

      "},{"location":"Support/Bare-Dashboard/","title":"Bare Dashboard","text":"

      Settings to assist with wall/monitor displays.

      "},{"location":"Support/Bare-Dashboard/#hide-menubar","title":"Hide Menubar","text":"

      To hide Menubar e.g. for Monitoring TV Screens attach ?bare=yes on URL

      "},{"location":"Support/Bare-Dashboard/#no-search-fields-in-dashboard-widgets","title":"No Search Fields in Dashboard Widgets","text":"

      To hide Search Field in Dashboard Widgets take a look into Widget Settings.

      "},{"location":"Support/CLI-Tools/","title":"Command line tools","text":"

      Here's a brief list of command line tools, some might be missing. If you think something is missing, feel free to ask us or send a pull request :-)

      "},{"location":"Support/CLI-Tools/#purge-portsphp","title":"purge-ports.php","text":"

      This script provides CLI access to the \"delete port\" function of the WebUI. This might come in handy when trying to clean up old ports after large changes within the network or when hacking on the poller/discovery functions.

      LibreNMS Port purge tool\n-p port_id  Purge single port by it's port-id\n-f file     Purge a list of ports, read port-ids from _file_, one on each line\n            A filename of - means reading from STDIN.\n
      "},{"location":"Support/CLI-Tools/#querying-port-ids-from-the-database","title":"Querying port IDs from the database","text":"

      One simple way to obtain port IDs is by querying the SQL database.

      If you wanted to query all deleted ports from the database, you could to this with the following query:

      echo 'SELECT port_id, hostname, ifDescr FROM ports, devices WHERE devices.device_id = ports.device_id AND deleted = 1' | mysql -h your_DB_server -u your_DB_user -p --skip-column-names your_DB_name\n

      When you are sure that the list of ports is correct and you want to delete all of them, you can write the list into a file and call purge-ports.php with that file as input:

      echo 'SELECT port_id FROM ports, devices WHERE devices.device_id = ports.device_id AND deleted = 1' | mysql -h your_DB_server -u your_DB_user -p --skip-column-names your_DB_name > ports_to_delete\n./purge-port.php -f ports_to_delete\n
      "},{"location":"Support/Cleanup-options/","title":"Cleanup Options","text":"

      As the number of devices starts to grow in your LibreNMS install, so will things such as the RRD files, MySQL database containing eventlogs, Syslogs and performance data etc. Your LibreNMS install could become quite large so it becomes necessary to clean up those entries. With Cleanup Options, you can stay in control.

      These options rely on daily.sh running from cron as per the installation instructions.

      system/cleanup

      lnms config:set eventlog_purge 30\nlnms config:set syslog_purge 30\nlnms config:set route_purge 10\nlnms config:set alert_log_purge 365\nlnms config:set authlog_purge 30\nlnms config:set ports_fdb_purge 10\nlnms config:set ports_nac_purge 10\nlnms config:set rrd_purge 0\nlnms config:set ports_purge true\n

      These options will ensure data within LibreNMS over X days old is automatically purged. You can alter these individually, values are in days.

      NOTE: Please be aware that rrd_purge is NOT set by default. This option will remove any RRD files that have not been updated for the set amount of days automatically - only enable this if you are comfortable with that happening. (All active RRD files are updated every polling period.)

      "},{"location":"Support/Cleanup-options/#ports-purge","title":"Ports Purge","text":"

      Over time as you add devices some interfaces will need to be purged as they are set to be ignored or bad interfaces or marked as deleted.

      You can purge all deleted ports from the WebUI (see below) or by setting lnms config:set ports_purge true.

      In the Web UI Under the Ports Tab in the Nav Bar, Click on \"Deleted\" then click on \"Purge all deleted\". This will purge all the ports.

      "},{"location":"Support/Configuration/","title":"Configuration Docs","text":"

      LibreNMS configuration is a set of key values.

      The config is stored in two places: Database: This applies to all pollers and can be set with either lnms config:set or in the Web UI. Database config takes precedence over config.php. config.php: This applies to the local poller only. Configs set here will be disabled in the Web UI to prevent unexpected behaviour.

      The LibreNMS uses dot notation for config items:

      Database config.php snmp.community $config['snmp']['community'] snmp.community.+ $config['snmp']['community'][] snmp.v3.0.authalgo $config['snmp']['v3'][0]['authalgo']

      The documentation has not been updated to reflect using lnms config:set to set config items, but it will work for all settings. Not all settings have been defined in LibreNMS, but they can still be set with the --ignore-checks option. Without that option input is checked for correctness, that does not mean it is not possible to set bad values. Please report missing settings.

      "},{"location":"Support/Configuration/#cli","title":"CLI","text":"

      lnms config:get will fetch the current config settings (composite of database, config.php, and defaults). lnms config:set will set the config setting in the database. Calling lnms config:set on a setting with no value will reset it to the default value.

      If you set up bash completion, you can use tab completion to find config settings.

      "},{"location":"Support/Configuration/#getting-a-list-of-all-current-values","title":"Getting a list of all current values","text":"

      To get a complete list of all the current values, you can use the command lnms config:get --dump. The output may not be desirable, so you can use the jq package to pretty print it. Then it would be lnms config:get --dump | jq.

      Example output:

      librenms@librenms:~$ lnms config:get --dump | jq \n{\n  \"install_dir\": \"/opt/librenms\",\n  \"active_directory\": {\n    \"users_purge\": 0\n  },\n  \"addhost_alwayscheckip\": false,\n  \"alert\": {\n    \"ack_until_clear\": false,\n    \"admins\": true,\n    \"default_copy\": true,\n    \"default_if_none\": false,\n    \"default_mail\": false,\n    \"default_only\": true,\n    \"disable\": false,\n    \"fixed-contacts\": true,\n    \"globals\": true,\n    \"syscontact\": true,\n    \"transports\": {\n      \"mail\": 5\n    },\n    \"tolerance_window\": 5,\n    \"users\": false,\n    ...\n

      "},{"location":"Support/Configuration/#examples","title":"Examples","text":"
      lnms config:get snmp.community\n  [\n      \"public\"\n  ]\n\n\nlnms config:set snmp.community.+ testing\n\nlnms config:get snmp.community\n  [\n      \"public\",\n      \"testing\"\n  ]\n\n\nlnms config:set snmp.community.0 private\n\nlnms config:get snmp.community\n  [\n      \"private\",\n      \"testing\"\n  ]\n\nlnms config:set snmp.community test\n  Invalid format\n\nlnms config:set snmp.community '[\"test\", \"othercommunity\"]'\n\nlnms config:get snmp.community\n  [\n      \"test\",\n      \"othercommunity\"\n  ]\n\nlnms config:set snmp.community\n\n  Reset snmp.community to the default? (yes/no) [no]:\n  > yes\n\n\nlnms config:get snmp.community\n  [\n      \"public\"\n  ]\n
      "},{"location":"Support/Configuration/#pre-load-configuration","title":"Pre-load configuration","text":"

      This feature is primarily for docker images and other automation. When installing LibreNMS for the first time with a new database you can place yaml key value files in database/seeders/config to pre-populate the config database.

      Example snmp.yaml

      snmp.community:\n    - public\n    - private\nsnmp.max_repeaters: 30\n

      "},{"location":"Support/Configuration/#directories","title":"Directories","text":"
      lnms config:set temp_dir /tmp\n

      The temporary directory is where images and other temporary files are created on your filesystem.

      lnms config:set log_dir /opt/librenms/logs\n

      Log files created by LibreNMS will be stored within this directory.

      "},{"location":"Support/Configuration/#database-config","title":"Database config","text":"

      Set these variables either in .env (/opt/librenms/.env by default) or in the environment.

      DB_HOST=127.0.0.1\nDB_DATABASE=librenms\nDB_USERNAME=DBUSER\nDB_PASSWORD=\"DBPASS\"\n

      Use non-standard port:

      DB_PORT=3306\n

      Use a unix socket:

      DB_SOCKET=/run/mysqld/mysqld.sock\n
      "},{"location":"Support/Configuration/#core","title":"Core","text":""},{"location":"Support/Configuration/#php-settings","title":"PHP Settings","text":"

      You can change the memory limits for php within config.php. The value is in Megabytes and should just be an int value:

      lnms config:set php_memory_limit 128

      "},{"location":"Support/Configuration/#programs","title":"Programs","text":"

      A lot of these are self explanatory so no further information may be provided. Any extensions that have dedicated documentation page will be linked to rather than having the config provided.

      "},{"location":"Support/Configuration/#rrdtool","title":"RRDTool","text":"

      You can configure these options within the WebUI now, please avoid setting these options within config.php

      Settings -> External Settings -> RRDTool Setup

      external/binaries

      lnms config:set rrdtool /usr/bin/rrdtool\n

      Please see 1 Minute polling for information on configuring your install to record data more frequently.

      "},{"location":"Support/Configuration/#fping","title":"fping","text":"

      external/binaries

      lnms config:set fping /usr/bin/fping\nlnms config:set fping6 fping6\n

      poller/ping

      lnms config:set fping_options.timeout 500\nlnms config:set fping_options.count 3\nlnms config:set fping_options.interval 500\nlnms config:set fping_options.tos 184\n

      fping configuration options:

      • timeout (fping parameter -t): Amount of time that fping waits for a response to its first request (in milliseconds). See note below
      • count (fping parameter -c): Number of request packets to send to each target.
      • interval (fping parameter -p): Time in milliseconds that fping waits between successive packets to an individual target.
      • tos (fpingparameter -O): Set the type of service flag (TOS). Value can be either decimal or hexadecimal (0xh) format. Can be used to ensure that ping packets are queued in following QOS mecanisms in the network. Table is accessible in the TOS Wikipedia page.

      NOTE: Setting a higher timeout value than the interval value can lead to slowing down poller. Example:

      timeout: 3000

      count: 3

      interval: 500

      In this example, interval will be overwritten by the timeout value of 3000 which is 3 seconds. As we send three icmp packets (count: 3), each one is delayed by 3 seconds which will result in fping taking > 6 seconds to return results.

      You can disable the fping / icmp check that is done for a device to be determined to be up on a global or per device basis. We don't advise disabling the fping / icmp check unless you know the impact, at worst if you have a large number of devices down then it's possible that the poller would no longer complete in 5 minutes due to waiting for snmp to timeout.

      Globally disable fping / icmp check:

      lnms config:set icmp_check false\n

      If you would like to do this on a per device basis then you can do so under Device -> Edit -> Misc -> Disable ICMP Test? On

      "},{"location":"Support/Configuration/#snmp","title":"SNMP","text":"

      SNMP program locations.

      external/binaries

      lnms config:set snmpwalk /usr/bin/snmpwalk\nlnms config:set snmpget /usr/bin/snmpget\nlnms config:set snmpbulkwalk /usr/bin/snmpbulkwalk\nlnms config:set snmpgetnext /usr/bin/snmpgetnext\nlnms config:set snmptranslate /usr/bin/snmptranslate\n
      "},{"location":"Support/Configuration/#misc-binaries","title":"Misc binaries","text":"

      external/binaries

      lnms config:set whois /usr/bin/whois\nlnms config:set ping /bin/ping\nlnms config:set mtr /usr/bin/mtr\nlnms config:set nmap /usr/bin/nmap\nlnms config:set nagios_plugins /usr/lib/nagios/plugins\nlnms config:set ipmitool /usr/bin/ipmitool\nlnms config:set virsh /usr/bin/virsh\nlnms config:set dot /usr/bin/dot\nlnms config:set sfdp /usr/bin/sfdp\n
      "},{"location":"Support/Configuration/#authentication","title":"Authentication","text":"

      Generic Authentication settings.

      Password minimum length for auth that allows user creation

      lnms config:set password.min_length 8\n
      "},{"location":"Support/Configuration/#proxy-support","title":"Proxy support","text":"

      For alerting and the callback functionality, we support the use of a http proxy setting. These can be any one of the following:

      system/proxy

      lnms config:set callback_proxy proxy.domain.com\nlnms config:set http_proxy proxy.domain.com\n

      We can also make use of one of these environment variables which can be set in /etc/environment:

      http_proxy=proxy.domain.com\nhttps_proxy=proxy.domain.com\n
      "},{"location":"Support/Configuration/#rrdcached","title":"RRDCached","text":"

      Please refer to RRDCached

      "},{"location":"Support/Configuration/#webui-settings","title":"WebUI Settings","text":"
      lnms config:set base_url http://demo.librenms.org\n

      LibreNMS will attempt to detect the URL you are using but you can override that here.

      webui/style

      lnms config:set site_style light\n

      Currently we have a number of styles which can be set which will alter the navigation bar look. dark, light and mono with light being the default.

      lnms config:set webui.custom_css.+ css/custom/styles.css\n

      You can override a large number of visual elements by creating your own css stylesheet and referencing it here, place any custom css files into html/css/custom so they will be ignored by auto updates. You can specify as many css files as you like, the order they are within your config will be the order they are loaded in the browser.

      webui/style

      lnms config:set title_image images/custom/yourlogo.png\n

      You can override the default logo with yours, place any custom images files into html/images/custom so they will be ignored by auto updates.

      lnms config:set page_refresh 300\n

      Set how often pages are refreshed in seconds. The default is every 5 minutes. Some pages don't refresh at all by design.

      lnms config:set front_page default\n

      You can create your own front page by adding a blade file in resources/views/overview/custom/ and setting front_page to it's name. For example, if you create resources/views/overview/custom/foobar.blade.php, set front_page to foobar.

      webui/dashboard

      lnms config:set webui.default_dashboard_id 0\n

      Allows the specification of a global default dashboard page for any user who has not set one in their user preferences. Should be set to dashboard_id of an existing dashboard that is shared or shared(read). Otherwise, the system will automatically create each user an empty dashboard called Default on their first login.

      lnms config:set login_message \"Unauthorised access or use shall render the user liable to criminal and/or civil prosecution.\"\n

      This is the default message on the login page displayed to users.

      lnms config:set public_status true\n

      If this is set to true then an overview will be shown on the login page of devices and the status.

      lnms config:set show_locations true  # Enable Locations on menu\nlnms config:set show_locations_dropdown true  # Enable Locations dropdown on menu\nlnms config:set show_services false  # Disable Services on menu\nlnms config:set int_customers true  # Enable Customer Port Parsing\nlnms config:set summary_errors false  # Show Errored ports in summary boxes on the dashboard\nlnms config:set customers_descr '[\"cust\"]'  # The description to look for in ifDescr. Can have multiple '[\"cust\",\"cid\"]'\nlnms config:set transit_descr '[\"transit\"]'  # Add custom transit descriptions (array)\nlnms config:set peering_descr '[\"peering\"]'  # Add custom peering descriptions (array)\nlnms config:set core_descr '[\"core\"]'  # Add custom core descriptions  (array)\nlnms config:set custom_descr '[\"This is Custom\"]'  # Add custom interface descriptions (array)\nlnms config:set int_transit true  # Enable Transit Types\nlnms config:set int_peering true  # Enable Peering Types\nlnms config:set int_core true  # Enable Core Port Types\nlnms config:set int_l2tp false  # Disable L2TP Port Types\n

      Enable / disable certain menus from being shown in the WebUI.

      You are able to adjust the number and time frames of the quick select time options for graphs and the mini graphs shown per row.

      Quick select:

      lnms config:set graphs.mini.normal '{\n    \"day\": \"24 Hours\",\n    \"week\": \"One Week\",\n    \"month\": \"One Month\",\n    \"year\": \"One Year\"\n}'\n\nlnms config:set graphs.mini.widescreen '{\n    \"sixhour\": \"6 Hours\",\n    \"day\": \"24 Hours\",\n    \"twoday\": \"48 Hours\",\n    \"week\": \"One Week\",\n    \"twoweek\": \"Two Weeks\",\n    \"month\": \"One Month\",\n    \"twomonth\": \"Two Months\",\n    \"year\": \"One Year\",\n    \"twoyear\": \"Two Years\"\n}'\n

      Mini graphs:

      lnms config:set graphs.row.normal '{\n    \"sixhour\": \"6 Hours\",\n    \"day\": \"24 Hours\",\n    \"twoday\": \"48 Hours\",\n    \"week\": \"One Week\",\n    \"twoweek\": \"Two Weeks\",\n    \"month\": \"One Month\",\n    \"twomonth\": \"Two Months\",\n    \"year\": \"One Year\",\n    \"twoyear\": \"Two Years\"\n}'\n
      lnms config:set web_mouseover true\n

      You can disable the mouseover popover for mini graphs by setting this to false.

      lnms config:set enable_lazy_load true\n

      You can disable image lazy loading by setting this to false.

      lnms config:set overview_show_sysDescr true\n

      Enable or disable the sysDescr output for a device.

      webui/device

      lnms config:set device_display_default '{{ $hostname }}'\n

      This is a simple template to control the display of device names by default. You can override this setting per-device.

      You may enter any free-form text including one or more of the following template replacements:

      Template Replacement {{ $hostname }} The hostname or IP of the device that was set when added *default {{ $sysName_fallback }} The hostname or sysName if hostname is an IP {{ $sysName }} The SNMP sysName of the device, falls back to hostname/IP if missing {{ $ip }} The actual polled IP of the device, will not display a hostname

      For example, {{ $sysName_fallback }} ({{ $ip }}) will display something like server (192.168.1.1)

      lnms config:set device_traffic_iftype.+ '/loopback/'\n

      Interface types that aren't graphed in the WebUI. The default array contains more items, please see misc/config_definitions.json for the full list.

      lnms config:set enable_clear_discovery true\n

      Administrators are able to clear the last discovered time of a device which will force a full discovery run within the configured 5 minute cron window.

      lnms config:set enable_footer true\n

      Disable the footer of the WebUI by setting enable_footer to 0.

      You can enable the old style network map (only available for individual devices with links discovered via xDP) by setting:

      lnms config:set gui.network-map.style old\n
      lnms config:set percentile_value 90\n

      Show the Xth percentile in the graph instead of the default 95th percentile.

      webui/graph

      lnms config:set shorthost_target_length 15\n

      The target maximum hostname length when applying the shorthost() function. You can increase this if you want to try and fit more of the hostname in graph titles. The default value is 12 However, this can possibly break graph generation if this is very long.

      You can enable dynamic graphs within the WebUI under Global Settings -> Webui Settings -> Graph Settings.

      Graphs will be movable/scalable without reloading the page:

      "},{"location":"Support/Configuration/#stacked-graphs","title":"Stacked Graphs","text":"

      You can enable stacked graphs instead of the default inverted graphs. Enabling them is possible via webui Global Settings -> Webui Settings -> Graph settings -> Use stacked graphs

      "},{"location":"Support/Configuration/#add-host-settings","title":"Add host settings","text":"

      The following setting controls how hosts are added. If a host is added as an ip address it is checked to ensure the ip is not already present. If the ip is present the host is not added. If host is added by hostname this check is not performed. If the setting is true hostnames are resolved and the check is also performed. This helps prevents accidental duplicate hosts.

      lnms config:set addhost_alwayscheckip false # true - check for duplicate ips even when adding host by name.\n                                            # false- only check when adding host by ip.\n

      By default we allow hosts to be added with duplicate sysName's, you can disable this with the following config:

      discovery/general

      lnms config:set allow_duplicate_sysName false\n
      "},{"location":"Support/Configuration/#global-poller-and-discovery-modules","title":"Global poller and discovery modules","text":"

      Enable or disable discovery or poller modules.

      This setting has an order of precedence Device > OS > Global. So if the module is set at a more specific level, it will override the less specific settings.

      Global:

      lnms config:set discovery_modules.arp-table false\n\nlnms config:set discovery_modules.entity-state true\nlnms config:set poller_modules.entity-state true\n

      Per OS:

      lnms config:set os.ios.discovery_modules.arp-table false\n\nlnms config:set os.ios.discovery_modules.entity-state true\nlnms config:set os.ios.poller_modules.entity-state true\n
      "},{"location":"Support/Configuration/#snmp-settings","title":"SNMP Settings","text":"

      Default SNMP options including retry and timeout settings and also default version and port.

      poller/snmp

      lnms config:set snmp.timeout 1                         # timeout in seconds\nlnms config:set snmp.retries 5                         # how many times to retry the query\nlnms config:set snmp.transports '[\"udp\", \"udp6\", \"tcp\", \"tcp6\"]'    # Transports to use\nlnms config:set snmp.version '[\"v2c\", \"v3\", \"v1\"]'       # Default versions to use\nlnms config:set snmp.port 161                          # Default port\nlnms config:set snmp.exec_timeout 1200                 # execution time limit in seconds\n

      NOTE: timeout is the time to wait for an answer and exec_timeout is the max time to run a query.

      The default v1/v2c snmp community to use, you can expand this array with [1], [2], [3], etc.

      poller/snmp

      lnms config:set snmp.community.0 public\n

      NOTE: This list of SNMP communities is used for auto discovery, and as a default set for any manually added device.

      The default v3 snmp details to use, you can expand this array with [1], [2], [3], etc.

      poller/snmp

      lnms config:set snmp.v3.0 '{\n    authlevel: \"noAuthNoPriv\",\n    authname: \"root\",\n    authpass: \"\",\n    authalgo: \"MD5\",\n    cryptopass: \"\",\n    cryptoalgo: \"AES\"\n}'\n
      authlevel   noAuthNoPriv | authNoPriv | authPriv\nauthname    User Name (required even for noAuthNoPriv)\nauthpass    Auth Passphrase\nauthalgo    MD5 | SHA | SHA-224 | SHA-256 | SHA-384 | SHA-512\ncryptopass  Privacy (Encryption) Passphrase\ncryptoalgo  AES | AES-192 | AES-256 | AES-256-C | DES\n
      "},{"location":"Support/Configuration/#auto-discovery-settings","title":"Auto discovery settings","text":"

      Please refer to Auto-Discovery

      "},{"location":"Support/Configuration/#email-configuration","title":"Email configuration","text":"

      You can configure these options within the WebUI now, please avoid setting these options within config.php

      alerting/email

      lnms config:set email_backend mail\nlnms config:set email_from librenms@yourdomain.local\nlnms config:set email_user `lnms config:get project_id`\nlnms config:set email_sendmail_path /usr/sbin/sendmail\nlnms config:set email_smtp_host localhost\nlnms config:set email_smtp_port 25\nlnms config:set email_smtp_timeout 10\nlnms config:set email_smtp_secure tls\nlnms config:set email_smtp_auth false\nlnms config:set email_smtp_username NULL\nlnms config:set email_smtp_password NULL\n

      What type of mail transport to use for delivering emails. Valid options for email_backend are mail, sendmail or smtp. The varying options after that are to support the different transports.

      "},{"location":"Support/Configuration/#alerting","title":"Alerting","text":"

      Please refer to Alerting

      "},{"location":"Support/Configuration/#billing","title":"Billing","text":"

      Please refer to Billing

      "},{"location":"Support/Configuration/#global-module-support","title":"Global module support","text":"
      lnms config:set enable_syslog false # Enable Syslog\nlnms config:set enable_inventory true # Enable Inventory\nlnms config:set enable_pseudowires true # Enable Pseudowires\nlnms config:set enable_vrfs true # Enable VRFs\n
      "},{"location":"Support/Configuration/#port-extensions","title":"Port extensions","text":"

      Please refer to Port-Description-Parser

      lnms config:set enable_ports_etherlike false\nlnms config:set enable_ports_junoseatmvp false\nlnms config:set enable_ports_poe false\n

      Enable / disable additional port statistics.

      "},{"location":"Support/Configuration/#port-group","title":"Port Group","text":"

      Assign a new discovered Port automatically to Port Group with this Port Group ID (0 means no Port Group assignment)

      discovery/networks

      lnms config:set default_port_group 0\n
      "},{"location":"Support/Configuration/#external-integration","title":"External integration","text":""},{"location":"Support/Configuration/#rancid","title":"Rancid","text":"
      lnms config:set rancid_configs.+ /var/lib/rancid/network/configs/\nlnms config:set rancid_repo_type svn\nlnms config:set rancid_ignorecomments false\n

      Rancid configuration, rancid_configs is an array containing all of the locations of your rancid files. Setting rancid_ignorecomments will disable showing lines that start with #

      "},{"location":"Support/Configuration/#oxidized","title":"Oxidized","text":"

      Please refer to Oxidized

      "},{"location":"Support/Configuration/#collectd","title":"CollectD","text":"
      lnms config:set collectd_dir /var/lib/collectd/rrd\n

      Specify the location of the collectd rrd files. Note that the location in config.php should be consistent with the location set in /etc/collectd.conf and etc/collectd.d/rrdtool.conf

      <Plugin rrdtool>\n        DataDir \"/var/lib/collectd/rrd\"\n        CreateFilesAsync false\n        CacheTimeout 120\n        CacheFlush   900\n        WritesPerSecond 50\n</Plugin>\n

      /etc/collectd.conf

      LoadPlugin rrdtool\n<Plugin rrdtool>\n       DataDir \"/var/lib/collectd/rrd\"\n       CacheTimeout 120\n       CacheFlush   900\n</Plugin>\n

      /etc/collectd.d/rrdtool.conf

      lnms config:set collectd_sock unix:///var/run/collectd.sock\n

      Specify the location of the collectd unix socket. Using a socket allows the collectd graphs to be flushed to disk before being drawn. Be sure that your web server has permissions to write to this socket.

      "},{"location":"Support/Configuration/#smokeping","title":"Smokeping","text":"

      Please refer to Smokeping

      "},{"location":"Support/Configuration/#nfsen","title":"NFSen","text":"

      Please refer to NFSen

      "},{"location":"Support/Configuration/#location-parsing","title":"Location parsing","text":"

      LibreNMS can interpret sysLocation information and map the device loction based on GeoCoordinates or GeoCoding information.

      • Info-keywords
      • [] contains optional Latitude and Longitude information if manual GeoCoordinate positioning is desired.
      • () contains optional information that is ignored during GeoCoding lookups.
      "},{"location":"Support/Configuration/#geocoordinates","title":"GeoCoordinates","text":"

      If device sysLocation information contains [lat, lng] (note the comma and square brackets), that is used to determin the GeoCoordinates.

      Example:

      name_that_can_not_be_looked_up [40.424521, -86.912755]\n

      "},{"location":"Support/Configuration/#geocoding","title":"GeoCoding","text":"

      Next it will attempt to look up the sysLocation with a map engine provided you have configured one under $config['geoloc']['engine']. The information has to be accurate or no result is returned, when it does it will ignore any information inside parentheses, allowing you to add details that would otherwise interfeeer with the lookup.

      Example:

      1100 Congress Ave, Austin, TX 78701 (3rd floor)\nGeocoding lookup is:\n1100 Congress Ave, Austin, TX 78701\n

      "},{"location":"Support/Configuration/#overrides","title":"Overrides","text":"
      1. You can overwrite each device sysLocation information in the webGUI under \"Device settings\".
      2. You can overwrite the location coordinates n in the webGUI under Device>GEO Locations
      "},{"location":"Support/Configuration/#location-mapping","title":"Location mapping","text":"

      If you just want to set GPS coordinates on a location, you should visit Devices > Geo Locations > All Locations and edit the coordinates there.

      Exact Matching:

      lnms config:set location_map '{\"Under the Sink\": \"Under The Sink, The Office, London, UK\"}'\n

      Regex Matching:

      lnms config:set location_map_regex '{\"/Sink/\": \"Under The Sink, The Office, London, UK\"}'\n

      Regex Match Substitution:

      lnms config:set location_map_regex_sub '{\"/Sink/\": \"Under The Sink, The Office, London, UK [lat, long]\"}'\n

      If you have an SNMP SysLocation of \"Rack10,Rm-314,Sink\", Regex Match Substition yields \"Rack10,Rm-314,Under The Sink, The Office, London, UK [lat, long]\". This allows you to keep the SysLocation string short and keeps Rack/Room/Building information intact after the substitution.

      The above are examples, these will rewrite device snmp locations so you don't need to configure full location within snmp.

      "},{"location":"Support/Configuration/#interfaces-to-be-ignored","title":"Interfaces to be ignored","text":"

      Interfaces can be automatically ignored during discovery by modifying bad_if* entries in a default array, unsetting a default array and customizing it, or creating an OS specific array. The preferred method for ignoring interfaces is to use an OS specific array. The default arrays can be found in misc/config_definitions.json. OS specific definitions (includes/definitions/_specific_os_.yaml) can contain bad_if* arrays, but should only be modified via pull-request as manipulation of the definition files will block updating:

      Examples:

      Add entries to default arrays

      lnms config:set bad_if.+ voip-null\nlnms config:set bad_iftype.+ voiceEncap\nlnms config:set bad_if_regexp.+ '/^lo[0-9].*/'    # loopback\n

      Override default bad_if values

      lnms config:set bad_if '[\"voip-null\", \"voiceEncap\", \"voiceFXO\"]'\n

      Create an OS specific array

      lnms config:set os.iosxe.bad_iftype.+ macSecControlledIF\nlnms config:set os.iosxe.bad_iftype.+ macSecUncontrolledIF\n

      Various bad_if* selection options available

      bad_if is matched against the ifDescr value.

      bad_iftype is matched against the ifType value.

      bad_if_regexp is matched against the ifDescr value as a regular expression.

      bad_ifname_regexp is matched against the ifName value as a regular expression.

      bad_ifalias_regexp is matched against the ifAlias value as a regular expression.

      "},{"location":"Support/Configuration/#interfaces-that-shouldnt-be-ignored","title":"Interfaces that shouldn't be ignored","text":"

      Examples:

      lnms config:set good_if.+ FastEthernet\nlnms config:set os.ios.good_if.+ FastEthernet\n

      good_if is matched against ifDescr value. This can be a bad_if value as well which would stop that port from being ignored. i.e. if bad_if and good_if both contained FastEthernet then ports with this value in the ifDescr will be valid.

      "},{"location":"Support/Configuration/#interfaces-to-be-rewritten","title":"Interfaces to be rewritten","text":"
      lnms config:set rewrite_if '{\"cpu\": \"Management Interface\"}'\nlnms config:set rewrite_if_regexp '{\"/cpu /\": \"Management \"}'\n

      Entries defined in rewrite_if are being replaced completely. Entries defined in rewrite_if_regexp only replace the match. Matches are compared case-insensitive.

      "},{"location":"Support/Configuration/#entity-sensors-to-be-ignored","title":"Entity sensors to be ignored","text":"

      Some devices register bogus sensors as they are returned via SNMP but either don't exist or just don't return data. This allows you to ignore those based on the descr field in the database. You can either ignore globally or on a per os basis.

      lnms config:set bad_entity_sensor_regex.+ '/Physical id [0-9]+/'\nlnms config:set os.ios.bad_entity_sensor_regex '[\"/Physical id [0-9]+/\"]'\n
      "},{"location":"Support/Configuration/#entity-sensors-limit-values","title":"Entity sensors limit values","text":"

      Vendors may give some limit values (or thresholds) for the discovered sensors. By default, when no such value is given, both high and low limit values are guessed, based on the value measured during the initial discovery.

      When it is preferred to have no high and/or low limit values at all if these are not provided by the vendor, the guess method can be disabled:

      lnms config:set sensors.guess_limits false\n
      "},{"location":"Support/Configuration/#ignoring-health-sensors","title":"Ignoring Health Sensors","text":"

      It is possible to filter some sensors from the configuration:

      • Ignore all temperature sensors
      lnms config:set disabled_sensors.current true\n
      • Filter all sensors matching regexp '/PEM Iout/'.
      lnms config:set disabled_sensors_regex.+ '/PEM Iout/'\n
      • Filter all 'current' sensors for Operating System 'vrp'.
      lnms config:set os.vrp.disabled_sensors.current true\n
      • Filter all sensors matching regexp '/PEM Iout/' for Operating System iosxe.
      lnms config:set os.iosxe.disabled_sensors_regex '/PEM Iout/'\n
      "},{"location":"Support/Configuration/#storage-configuration","title":"Storage configuration","text":"

      Mounted storage / mount points to ignore in discovery and polling.

      discovery/storage

      lnms config:set ignore_mount_removable true\nlnms config:set ignore_mount_network true\nlnms config:set ignore_mount_optical true\n\nlnms config:set ignore_mount.+ /kern\nlnms config:set ignore_mount.+ /mnt/cdrom\nlnms config:set ignore_mount.+ /proc\nlnms config:set ignore_mount.+ /dev\n\nlnms config:set ignore_mount_string.+ packages\nlnms config:set ignore_mount_string.+ devfs\nlnms config:set ignore_mount_string.+ procfs\nlnms config:set ignore_mount_string.+ UMA\nlnms config:set ignore_mount_string.+ MALLOC\n\nlnms config:set ignore_mount_regexp.+ '/on: \\/packages/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/dev/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/proc/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/junos^/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/junos\\/dev/'\nlnms config:set ignore_mount_regexp.+ '/on: \\/jail\\/dev/'\nlnms config:set ignore_mount_regexp.+ '/^(dev|proc)fs/'\nlnms config:set ignore_mount_regexp.+ '/^\\/dev\\/md0/'\nlnms config:set ignore_mount_regexp.+ '/^\\/var\\/dhcpd\\/dev,/'\nlnms config:set ignore_mount_regexp.+ '/UMA/'\n

      Custom storage warning percentage

      lnms config:set storage_perc_warn 60\n
      "},{"location":"Support/Configuration/#irc-bot","title":"IRC Bot","text":"

      Please refer to IRC Bot

      "},{"location":"Support/Configuration/#authentication_1","title":"Authentication","text":"

      Please refer to Authentication

      "},{"location":"Support/Configuration/#cleanup-options","title":"Cleanup options","text":"

      Please refer to Cleanup Options

      "},{"location":"Support/Configuration/#syslog-options","title":"Syslog options","text":"

      Please refer to Syslog

      "},{"location":"Support/Configuration/#virtualization","title":"Virtualization","text":"
      lnms config:set enable_libvirt true\nlnms config:set libvirt_protocols '[\"qemu+ssh\",\"xen+ssh\"]'\nlnms config:set libvirt_username root\n

      Enable this to switch on support for libvirt along with libvirt_protocols to indicate how you connect to libvirt. You also need to:

      1. Generate a non-password-protected ssh key for use by LibreNMS, as the user which runs polling & discovery (usually librenms).
      2. On each VM host you wish to monitor:
      3. Configure public key authentication from your LibreNMS server/poller by adding the librenms public key to ~root/.ssh/authorized_keys.
      4. (xen+ssh only) Enable libvirtd to gather data from xend by setting (xend-unix-server yes) in /etc/xen/xend-config.sxp and restarting xend and libvirtd.

      To test your setup, run virsh -c qemu+ssh://vmhost/system list or virsh -c xen+ssh://vmhost list as your librenms polling user.

      "},{"location":"Support/Configuration/#bgp-support","title":"BGP Support","text":"
      lnms config:set astext.65332 \"Cymru FullBogon Feed\"\n

      You can use this array to rewrite the description of ASes that you have discovered.

      "},{"location":"Support/Configuration/#auto-updates","title":"Auto updates","text":"

      Please refer to Updating

      "},{"location":"Support/Configuration/#ipmi","title":"IPMI","text":"

      Setup the types of IPMI protocols to test a host for and in what order. Don't forget to install ipmitool on the monitoring host.

      lnms config:set ipmi.type '[\"lanplus\", \"lan\", \"imb\", \"open\"]'\n
      "},{"location":"Support/Configuration/#distributed-poller-settings","title":"Distributed poller settings","text":"

      Please refer to Distributed Poller

      "},{"location":"Support/Configuration/#api-settings","title":"API Settings","text":""},{"location":"Support/Configuration/#cors-support","title":"CORS Support","text":"

      https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

      CORS support for the API is disabled by default. Below you will find the standard options, all of which you can configure.

      lnms config:set api.cors.enabled false\nlnms config:set api.cors.origin '[\"*\"]'\nlnms config:set api.cors.maxage '86400'\nlnms config:set api.cors.allowmethods '[\"POST\", \"GET\", \"PUT\", \"DELETE\", \"PATCH\"]'\nlnms config:set api.cors.allowheaders '[\"Origin\", \"X-Requested-With\", \"Content-Type\", \"Accept\", \"X-Auth-Token\"]'\nlnms config:set api.cors.exposeheaders '[\"Cache-Control\", \"Content-Language\", \"Content-Type\", \"Expires\", \"Last-Modified\", \"Pragma\"]'\nlnms config:set api.cors.allowmethods '[\"POST\", \"GET\", \"PUT\", \"DELETE\", \"PATCH\"]'\nlnms config:set api.cors.allowheaders '[\"Origin\", \"X-Requested-With\", \"Content-Type\", \"Accept\", \"X-Auth-Token\"]'\nlnms config:set api.cors.exposeheaders '[\"Cache-Control\", \"Content-Language\", \"Content-Type\", \"Expires\", \"Last-Modified\", \"Pragma\"]'\nlnms config:set api.cors.allowcredentials false\n
      "},{"location":"Support/Device-Sensors/","title":"Device Sensors","text":"

      LibreNMS has a standard for device sensors they are split into categories. This doc is to help users understand device sensors in general, if you need help with developing sensors for a device please see the Contributing + Developing section.

      "},{"location":"Support/Device-Sensors/#health-sensors","title":"Health Sensors","text":"

      The High and Low values of these sensors can be edited in Web UI by going to the device settings -> Health. There you can set your own custom High and Low values. List of these sensors can be found here Link

      Note Some values are defined by the manufactures and others are auto calculated when you add the device into librenms. Keep in mind every environment is different and may require user input.

      "},{"location":"Support/Device-Sensors/#wireless-sensors","title":"Wireless Sensors","text":"

      Some Wireless have High and Low values of these sensors can be edited in Web UI by going to the device settings -> Wireless Sensors There you can set your own custom High and Low values. List of these sensors can be found here Link

      Note Some values are defined by the manufactures and others are auto calculated when you add the device into librenms. Keep in mind every environment is different and may require user input.

      "},{"location":"Support/Device-Sensors/#state-sensors","title":"State Sensors","text":"

      Return states of device entries sensors states. For example.

      Drive Status, Memory Status, Power Supply Status.

      0 = OK\n1 = Warning\n2 = Critical\n3 = Unknown\n
      "},{"location":"Support/Device-Sensors/#alerting-sensors","title":"Alerting Sensors","text":"

      These alert rules can be found inside the Alert Rules Collection. The alert rules below are the default alert rules, there are more device-specific alert rules in the alerts collection.

      Sensor Over Limit Alert Rule: Will alert on any sensor value that is over the limit.

      Sensor Under Limit Alert Rule: Will alert on any sensor value that is under the limit.

      Remember you can set these limits inside device settings in the Web UI.

      State Sensor Critical: Will alert on any state that returns critical = 2

      State Sensor Warning: Will alert on any state that returns warning = 1

      Wireless Sensor Over Limit Alert Rule: Will Alert on sensors that listed in device settings under Wireless.

      Wireless Sensor Under Limit Alert Rule: Will Alert on sensors that listed in device settings under Wireless.

      "},{"location":"Support/Device-Troubleshooting/","title":"Capture Debug Information","text":"

      You can use this feature to run Debug on Discovery, Poller, SNMP, Alerts. This output information could be helpful for you in troubleshooting a device or when requesting help.

      This feature can be found by going to the device that you are troubleshooting in the webui, clicking on the settings icon menu on far right and selecting Capture.

      "},{"location":"Support/Device-Troubleshooting/#discovery","title":"Discovery","text":"

      Discovery will run and output debug information.

      "},{"location":"Support/Device-Troubleshooting/#poller","title":"Poller","text":"

      Poller will run and output debug information.

      "},{"location":"Support/Device-Troubleshooting/#snmp","title":"SNMP","text":"

      SNMP will run SNMP Bulk Walk on the device and output the information.

      "},{"location":"Support/Device-Troubleshooting/#alerts","title":"Alerts","text":"

      Alerts Capture is handy when you are creating alerts and need to see if your alert rule matches.

      "},{"location":"Support/Discovery%20Support/","title":"discovery.php","text":"

      This document will explain how to use discovery.php to debug issues or manually running to process data.

      "},{"location":"Support/Discovery%20Support/#command-options","title":"Command options","text":"
      -h <device id> | <device hostname wildcard>  Poll single device\n-h odd                                       Poll odd numbered devices  (same as -i 2 -n 0)\n-h even                                      Poll even numbered devices (same as -i 2 -n 1)\n-h all                                       Poll all devices\n-h new                                       Poll all devices that have not had a discovery run before\n--os <os_name>                               Poll devices only with specified operating system\n--type <type>                                Poll devices only with specified type\n-i <instances> -n <number>                   Poll as instance <number> of <instances>\n                                             Instances start at 0. 0-3 for -n 4\n\nDebugging and testing options:\n-d                                           Enable debugging output\n-v                                           Enable verbose debugging output\n-m                                           Specify module(s) to be run. Comma separate modules, submodules may be added with /\n

      -h Use this to specify a device via either id or hostname (including wildcard using *). You can also specify odd and even. all will run discovery against all devices whilst new will poll only those devices that have recently been added or have been selected for rediscovery.

      -i This can be used to stagger the discovery process.

      -d Enables debugging output (verbose output but with most sensitive data masked) so that you can see what is happening during a discovery run. This includes things like rrd updates, SQL queries and response from snmp.

      -v Enables verbose debugging output with all data in tact.

      -m This enables you to specify the module you want to run for discovery.

      "},{"location":"Support/Discovery%20Support/#discovery-wrapper","title":"Discovery wrapper","text":"

      We have a discovery-wrapper.py script which is based on poller-wrapper.py by Job Snijders. This script is currently the default.

      If you need to debug the output of discovery-wrapper.py then you can add -d to the end of the command - it is NOT recommended to do this in cron.

      You also may use -m to pass a list of comma-separated modules. Please refer to Command options of discovery.php. Example: /opt/librenms/discovery-wrapper.py 1 -m bgp-peers

      If you want to switch back to discovery.php then you can replace:

      33 */6 * * * librenms /opt/librenms/discovery-wrapper.py 1 >> /dev/null 2>&1

      With:

      33 */6 * * * librenms /opt/librenms/discovery.php -h all >> /dev/null 2>&1

      "},{"location":"Support/Discovery%20Support/#discovery-config","title":"Discovery config","text":"

      These are the default discovery config items. You can globally disable a module by setting it to 0. If you just want to disable it for one device then you can do this within the WebUI -> Device -> Settings -> Modules.

      discovery/discovery_modules

      lnms config:set discovery_modules.os true\nlnms config:set discovery_modules.ports true\nlnms config:set discovery_modules.ports-stack true\nlnms config:set discovery_modules.entity-physical true\nlnms config:set discovery_modules.entity-state false\nlnms config:set discovery_modules.processors true\nlnms config:set discovery_modules.mempools true\nlnms config:set discovery_modules.cisco-vrf-lite true\nlnms config:set discovery_modules.cisco-mac-accounting false\nlnms config:set discovery_modules.cisco-pw false\nlnms config:set discovery_modules.vrf false\nlnms config:set discovery_modules.cisco-cef false\nlnms config:set discovery_modules.slas false\nlnms config:set discovery_modules.cisco-cbqos false\nlnms config:set discovery_modules.cisco-otv false\nlnms config:set discovery_modules.ipv4-addresses true\nlnms config:set discovery_modules.ipv6-addresses true\nlnms config:set discovery_modules.route false\nlnms config:set discovery_modules.sensors true\nlnms config:set discovery_modules.storage true\nlnms config:set discovery_modules.hr-device true\nlnms config:set discovery_modules.discovery-protocols true\nlnms config:set discovery_modules.arp-table true\nlnms config:set discovery_modules.discovery-arp false\nlnms config:set discovery_modules.junose-atm-vp false\nlnms config:set discovery_modules.bgp-peers true\nlnms config:set discovery_modules.vlans true\nlnms config:set discovery_modules.vminfo false\nlnms config:set discovery_modules.printer-supplies false\nlnms config:set discovery_modules.ucd-diskio true\nlnms config:set discovery_modules.applications false\nlnms config:set discovery_modules.services true\nlnms config:set discovery_modules.stp true\nlnms config:set discovery_modules.ntp true\nlnms config:set discovery_modules.loadbalancers false\nlnms config:set discovery_modules.mef false\nlnms config:set discovery_modules.wireless true\nlnms config:set discovery_modules.fdb-table true\nlnms config:set discovery_modules.xdsl false\n
      "},{"location":"Support/Discovery%20Support/#os-based-discovery-config","title":"OS based Discovery config","text":"

      You can enable or disable modules for a specific OS by using lnms config:set OS based settings have preference over global. Device based settings have preference over all others

      Discover performance improvement can be achieved by deactivating all modules that are not supported by specific OS.

      E.g. to deactivate spanning tree but activate discovery-arp module for linux OS

      discovery/discovery_modules

      lnms config:set os.linux.discovery_modules.stp false\nlnms config:set os.linux.discovery_modules.discovery-arp true\n
      "},{"location":"Support/Discovery%20Support/#discovery-modules","title":"Discovery modules","text":"

      os: Os detection. This module will pick up the OS of the device.

      ports: This module will detect all ports on a device excluding ones configured to be ignored by config options.

      ports-stack: Same as ports except for stacks.

      xdsl: Module to collect more metrics for xDSL interfaces.

      entity-physical: Module to pick up the devices hardware support.

      processors: Processor support for devices.

      mempools: Memory detection support for devices.

      cisco-vrf-lite: VRF-Lite detection and support.

      ipv4-addresses: IPv4 Address detection

      ipv6-addresses: IPv6 Address detection

      route: This module will load the routing table of the device. The default route limit is 1000 (configurable with lnms config:set routes.max_number 1000), with history data.

      sensors: Sensor detection such as Temperature, Humidity, Voltages + More

      storage: Storage detection for hard disks

      hr-device: Processor and Memory support via HOST-RESOURCES-MIB.

      discovery-protocols: Auto discovery module for xDP, OSPF and BGP.

      arp-table: Detection of the ARP table for the device.

      fdb-table: Detection of the Forwarding DataBase table for the device, with history data.

      discovery-arp: Auto discovery via ARP.

      junose-atm-vp: Juniper ATM support.

      bgp-peers: BGP detection and support.

      vlans: VLAN detection and support.

      cisco-mac-accounting: MAC Address account support.

      cisco-pw: Pseudowires wires detection and support.

      vrf: VRF detection and support.

      cisco-cef: CEF detection and support.

      slas: SLA detection and support.

      vminfo: Detection of vm guests for VMware ESXi and libvert

      printer-supplies: Toner levels support.

      ucd-diskio: Disk I/O support.

      services: *Nix services support.

      charge: APC Charge detection and support.

      "},{"location":"Support/Discovery%20Support/#running","title":"Running","text":"

      Here are some examples of running discovery from within your install directory.

      ./discovery.php -h localhost\n\n./discovery.php -h localhost -m ports\n
      "},{"location":"Support/Discovery%20Support/#debugging","title":"Debugging","text":"

      To provide debugging output you will need to run the discovery process with the -d flag. You can do this either against all modules, single or multiple modules:

      All Modules

      ./discovery.php -h localhost -d\n

      Single Module

      ./discovery.php -h localhost -m ports -d\n

      Multiple Modules

      ./discovery.php -h localhost -m ports,entity-physical -d\n

      Using -d shouldn't output much sensitive information, -v will so it is then advisable to sanitise the output before pasting it somewhere as the debug output will contain snmp details amongst other items including port descriptions.

      The output will contain:

      DB Updates

      SNMP Response

      "},{"location":"Support/Environment-Variables/","title":"Environment Variables","text":"

      LibreNMS allows certain settings to be set via the environment or through the .env file.

      "},{"location":"Support/Environment-Variables/#database","title":"Database","text":"

      Set the variables to connect to the database. The default values are shown below.

      DB_HOST=localhost\nDB_PORT=3306\nDB_DATABASE=librenms\nDB_USERNAME=librenms\nDB_PASSWORD=\nDB_SOCKET=\n
      "},{"location":"Support/Environment-Variables/#trusted-reverse-proxies","title":"Trusted Reverse Proxies","text":"

      A comma separated list of trusted reverse proxy IPs or CIDR.

      For legacy reasons the default is '*', which means any proxy is allowed. '**' means trust any proxy up the chain.

      APP_TRUSTED_PROXIES=192.168.1.0/24,192.167.8.20\n
      "},{"location":"Support/Environment-Variables/#base-url","title":"Base url","text":"

      Set the base url for generated urls.

      This will be needed when using signed graph urls for alerting. It may be needed when using reverse proxies combined with a subdirectory.

      Generally, LibreNMS will make correct URLs (especially if you have set up your proxy variables correctly)

      APP_URL=http://librenms/\n
      "},{"location":"Support/Environment-Variables/#user-group","title":"User / Group","text":"

      The user and group that LibreNMS should operate as. Group will default to the same as the user if unset.

      LIBRENMS_USER=librenms\nLIBRENMS_GROUP=librenms\n
      "},{"location":"Support/Environment-Variables/#debug","title":"Debug","text":"

      Increases the amount of information shown when an error occurs.

      WARNING: This may leak information, do not leave enabled.

      APP_DEBUG=true\n
      "},{"location":"Support/Example-Hardware-Setup/","title":"Example hardware setups","text":"

      The information in this document is direct from users, it's a place for people to share their setups so you have an idea of what may be required for your install.

      To obtain the device, port and sensor counts you can run:

      select count(*) from devices;\nselect count(*) from ports where `deleted` = 0;\nselect count(*) from sensors where `sensor_deleted` = 0;\n
      "},{"location":"Support/Example-Hardware-Setup/#laf","title":"laf","text":"

      Home

      Running in Proxmox.

      LibreNMS MySQL Type Virtual Virtual OS CentOS 7 CentOS 7 CPU 2 Sockets, 4 Cores 1 Socket, 2 Cores Memory 2GB 2GB Disk Type Raid 1, SSD Raid 1, SSD Disk Space 18GB 30GB Devices 20 - Ports 133 - Health sensors 47 - Load < 0.1 < 0.1"},{"location":"Support/Example-Hardware-Setup/#vente-privee","title":"Vente-Priv\u00e9e","text":"

      NOC

      LibreNMS MariaDB Type Dell R430 Dell R430 OS Debian 7 (dotdeb) Debian 7 (dotdeb) CPU 2 Sockets, 14 Cores 1 Socket, 2 Cores Memory 256GB 256GB Disk Type Raid 10, SSD Raid 10, SSD Disk Space 1TB 1TB Devices 1028 - Ports 26745 - Health sensors 6238 - Load < 0.5 < 0.5"},{"location":"Support/Example-Hardware-Setup/#kkrumm","title":"KKrumm","text":"

      Home

      LibreNMS MySQL Type VM Same Server OS CentOS 7 CPU 2 Sockets, 4 Cores Memory 4GB Disk Type Raid 10, SAS Drives Disk Space 40 GB Devices 12 Ports 130 Health sensors 44 Load < 2.5"},{"location":"Support/Example-Hardware-Setup/#kkrumm_1","title":"KKrumm","text":"

      Work

      LibreNMS MySQL Type HP Proliantdl380gen8 Same Server OS CentOS 7 CPU 2 Sockets, 24 Cores Memory 32GB Disk Type Raid 10, SAS Drives Disk Space 250 GB Devices 390 Ports 16167 Health sensors 3223 Load < 14.5"},{"location":"Support/Example-Hardware-Setup/#cppmonkeykodapa85","title":"CppMonkey(KodApa85)","text":"

      Home

      LibreNMS MariaDB Type i5-4690K Same Workstation OS Ubuntu 18.04.2 CPU 4 Cores Memory 16GB Disk Type Hybrid SATA Disk Space 2 TB Devices 14 Ports 0 Health sensors 70 Load < 0.5"},{"location":"Support/Example-Hardware-Setup/#cppmonkeykodapa85_1","title":"CppMonkey(KodApa85)","text":"

      Dev

      Running in Ganeti

      LibreNMS MariaDB Type VM Same VM OS CentOS 7.5 CPU 2 Cores Memory 4GB Disk Type M.2 Disk Space 40 GB Devices 38 Ports 1583 Health sensors 884 Load < 1.0"},{"location":"Support/Example-Hardware-Setup/#cppmonkeykodapa85_2","title":"CppMonkey(KodApa85)","text":"

      Work NOC

      Running in Ganeti Cluster with 2x Dell PER730xd - 64GB, Dual E5-2660 v3

      LibreNMS MariaDB Type VM VM OS Debian Stretch Debian Stretch CPU 4 Cores 2 Cores Memory 8GB 4GB Disk Type Raid 6, SAS Drives Disk Space 100 GB 40GB Devices 179 Ports 14495 Health sensors 2329 Load < 2.5 < 1.5"},{"location":"Support/Example-Hardware-Setup/#lazydk","title":"LaZyDK","text":"

      Home

      LibreNMS MariaDB Type VM - QNAP TS-453 Pro Same Server OS Ubuntu 16.04 CPU 1 vCore Memory 2GB Disk Type Raid 1, SATA Drives Disk Space 10 GB Devices 26 Ports 228 Health sensors 117 Load < 0.92"},{"location":"Support/Example-Hardware-Setup/#sirmaple","title":"SirMaple","text":"

      Home

      LibreNMS MariaDB Type VM Same Server OS Debian 11 CPU 4 vCore Memory 4GB Disk Type Raid 1, SSD Disk Space 50 GB Devices 41 Ports 317 Health sensors 243 Load < 3.15"},{"location":"Support/Example-Hardware-Setup/#vvelox","title":"VVelox","text":"

      Home / Dev

      LibreNMS MariaDB Type Supermicro X7SPA-HF Same Server OS FreeBSD 12-STABLE CPU Intel Atom D525 Memory 4GB Disk Type Raid 1, SATA Disk Space 1TB Devices 17 Ports 174 Health sensors 76 Load < 3"},{"location":"Support/Example-Hardware-Setup/#sourcedoctor","title":"SourceDoctor","text":"

      Home / Dev

      Running in VMWare Workstation Pro

      LibreNMS MariaDB Type VM Same Server OS Debian Buster CPU 2 vCore Memory 2GB Disk Type Raid 5, SSD Disk Space 20GB Devices 35 Ports 245 Health sensors 101 Load < 1"},{"location":"Support/Example-Hardware-Setup/#lazyb0nes","title":"lazyb0nes","text":"

      Lab

      LibreNMS MariaDB Type VM Same Server OS RHEL 7.7 CPU 32 cores Memory 64GB Disk Type Flash San Array Disk Space 400GB Devices 670 Ports 25678 Health sensors 2457 Load 10.92"},{"location":"Support/Example-Hardware-Setup/#dagb","title":"dagb","text":"

      Work

      Running in VMware.

      LibreNMS MariaDB Type Virtual Same Server OS CentOS 7 CPU 12 Cores Xeon 6130 Memory 8GB Disk Type SAN (SSD) Disk Space 26GB/72GB/7GB (logs/RRDs/db) Devices 650 Ports 34300 Health sensors 10500 Load 5.5 (45%)"},{"location":"Support/FAQ/","title":"FAQ","text":""},{"location":"Support/FAQ/#getting-started","title":"Getting started","text":""},{"location":"Support/FAQ/#how-do-i-install-librenms","title":"How do I install LibreNMS?","text":"

      This is currently well documented within the doc folder of the installation files.

      Please see the following doc

      "},{"location":"Support/FAQ/#how-do-i-add-a-device","title":"How do I add a device?","text":"

      You have two options for adding a new device into LibreNMS.

      1: Using the command line via ssh you can add a new device by changing to the directory of your LibreNMS install and typing:

      lnms device:add [hostname or ip]\n

      To see all options run: lnms device:add -h

      Please note that if the community contains special characters such as $ then you will need to wrap it in '. I.e: 'Pa$$w0rd'.

      2: Using the web interface, go to Devices and then Add Device. Enter the details required for the device that you want to add and then click 'Add Host'.

      "},{"location":"Support/FAQ/#how-do-i-get-help","title":"How do I get help?","text":"

      Getting Help

      "},{"location":"Support/FAQ/#what-are-the-supported-oses-for-installing-librenms-on","title":"What are the supported OSes for installing LibreNMS on?","text":"

      Supported is quite a strong word :) The 'officially' supported distros are:

      • Ubuntu / Debian
      • Red Hat / CentOS
      • Gentoo

      However we will always aim to help wherever possible so if you are running a distro that isn't one of the above then give it a try anyway and if you need help then jump on the discord server.

      "},{"location":"Support/FAQ/#do-you-have-a-demo-available","title":"Do you have a demo available?","text":"

      We do indeed, you can find access to the demo here

      "},{"location":"Support/FAQ/#support","title":"Support","text":""},{"location":"Support/FAQ/#how-does-librenms-use-mibs","title":"How does LibreNMS use MIBs?","text":"

      LibreNMS does not parse MIBs to discover sensors for devices. LibreNMS uses static discovery definitions written in YAML or PHP. Therefore, updating a MIB alone will not improve OS support, the definitions must be updated. LibreNMS only uses MIBs to make OIDs easier to read.

      "},{"location":"Support/FAQ/#why-do-i-get-blank-pages-sometimes-in-the-webui","title":"Why do I get blank pages sometimes in the WebUI?","text":"

      You can enable debug information by setting APP_DEBUG=true in your .env. (Do not leave this enabled, it could leak private data)

      If the page you are trying to load has a substantial amount of data in it then it could be that the php memory limit needs to be increased in config.php.

      "},{"location":"Support/FAQ/#why-do-i-not-see-any-graphs","title":"Why do I not see any graphs?","text":"

      The easiest way to check if all is well is to run ./validate.php as librenms from within your install directory. This should give you info on why things aren't working.

      One other reason could be a restricted snmpd.conf file or snmp view which limits the data sent back. If you use net-snmp then we suggest using the included snmpd.conf file.

      "},{"location":"Support/FAQ/#how-do-i-debug-pages-not-loading-correctly","title":"How do I debug pages not loading correctly?","text":"

      A debug system is in place which enables you to see the output from php errors, warnings and notices along with the MySQL queries that have been run for that page.

      You can enable debug information by setting APP_DEBUG=true in your .env. (Do not leave this enabled, it could leak private data) To see additional information, run ./scripts/composer_wrapper.php install, to install additional debug tools. This will add a debug bar at the bottom of every page that will show you detailed debug information.

      "},{"location":"Support/FAQ/#how-do-i-debug-the-discovery-process","title":"How do I debug the discovery process?","text":"

      Please see the Discovery Support document for further details.

      "},{"location":"Support/FAQ/#how-do-i-debug-the-poller-process","title":"How do I debug the poller process?","text":"

      Please see the Poller Support document for further details.

      "},{"location":"Support/FAQ/#why-do-i-get-a-lot-apache-or-rrdtool-zombies-in-my-process-list","title":"Why do I get a lot apache or rrdtool zombies in my process list?","text":"

      If this is related to your web service for LibreNMS then this has been tracked down to an issue within php which the developers aren't fixing. We have implemented a work around which means you shouldn't be seeing this. If you are, please report this in issue 443.

      "},{"location":"Support/FAQ/#why-do-i-see-traffic-spikes-in-my-graphs","title":"Why do I see traffic spikes in my graphs?","text":"

      This occurs either when a counter resets or the device sends back bogus data making it look like a counter reset. We have enabled support for setting a maximum value for rrd files for ports.

      Before this all rrd files were set to 100G max values, now you can enable support to limit this to the actual port speed.

      rrdtool tune will change the max value when the interface speed is detected as being changed (min value will be set for anything 10M or over) or when you run the included script (./scripts/tune_port.php) - see RRDTune doc

      SNMP ifInOctets and ifOutOctets are counters, which means they start at 0 (at device boot) and count up from there. LibreNMS records the value every 5 minutes and uses the difference between the previous value and the current value to calculate rate. (Also, this value resets to 0 when it hits the max value)

      Now, when the value is not recorded for awhile RRD (our time series storage) does not record a 0, it records the last value, otherwise, there would be even worse problems. Then finally we get the current ifIn/OutOctets value and record that. Now, it appears as though all of the traffic since it stopped getting values have occurred in the last 5 minute interval.

      So whenever you see spikes like this, it means we have not received data from the device for several polling intervals. The cause can vary quite a bit: bad snmp implementations, intermittent network connectivity, broken poller, and more.

      "},{"location":"Support/FAQ/#why-do-i-see-gaps-in-my-graphs","title":"Why do I see gaps in my graphs?","text":"

      This is most commonly due to the poller not being able to complete it's run within 300 seconds. Check which devices are causing this by going to /poll-log/ within the Web interface.

      When you find the device(s) which are taking the longest you can then look at the Polling module graph under Graphs -> Poller -> Poller Modules Performance. Take a look at what modules are taking the longest and disabled un used modules.

      If you poll a large number of devices / ports then it's recommended to run a local recursive dns server such as pdns-recursor.

      Running RRDCached is also highly advised in larger installs but has benefits no matter the size.

      "},{"location":"Support/FAQ/#how-do-i-change-the-ip-hostname-of-a-device","title":"How do I change the IP / hostname of a device?","text":"

      There is a host rename tool called renamehost.php in your librenms root directory. When renaming you are also changing the device's IP / hostname address for monitoring.

      Usage:

      ./renamehost.php <old hostname> <new hostname>\n

      You can also rename a device in the Web UI by going to the device, then clicking settings Icon -> Edit.

      "},{"location":"Support/FAQ/#my-device-doesnt-finish-polling-within-300-seconds","title":"My device doesn't finish polling within 300 seconds","text":"

      We have a few things you can try:

      • Disable unnecessary polling modules under edit device.
      • Set a max repeater value within the snmp settings for a device. What to set this to is tricky, you really should run an snmpbulkwalk with -Cr10 through -Cr50 to see what works best. 50 is usually a good choice if the device can cope.
      "},{"location":"Support/FAQ/#things-arent-working-correctly","title":"Things aren't working correctly?","text":"

      Run ./validate.php as librenms from within your install.

      Re-run ./validate.php once you've resolved any issues raised.

      You have an odd issue - we'd suggest you join our discord server to discuss.

      "},{"location":"Support/FAQ/#what-do-the-values-mean-in-my-graphs","title":"What do the values mean in my graphs?","text":"

      The values you see are reported as metric values. Thanks to a post on Reddit here are those values:

      10^-18  a - atto\n10^-15  f - femto\n10^-12  p - pico\n10^-9   n - nano\n10^-6   u - micro\n10^-3   m - milli\n0    (no unit)\n10^3    k - kilo\n10^6    M - mega\n10^9    G - giga\n10^12   T - tera\n10^15   P - peta\n
      "},{"location":"Support/FAQ/#why-does-a-device-show-as-a-warning","title":"Why does a device show as a warning?","text":"

      This is indicating that the device has rebooted within the last 24 hours (by default). If you want to adjust this threshold then you can do so by setting $config['uptime_warning'] = '86400'; in config.php. The value must be in seconds.

      "},{"location":"Support/FAQ/#why-do-i-not-see-all-interfaces-in-the-overall-traffic-graph-for-a-device","title":"Why do I not see all interfaces in the Overall traffic graph for a device?","text":"

      By default numerous interface types and interface descriptions are excluded from this graph. The excluded defaults are:

      $config['device_traffic_iftype'][] = '/loopback/';\n$config['device_traffic_iftype'][] = '/tunnel/';\n$config['device_traffic_iftype'][] = '/virtual/';\n$config['device_traffic_iftype'][] = '/mpls/';\n$config['device_traffic_iftype'][] = '/ieee8023adLag/';\n$config['device_traffic_iftype'][] = '/l2vlan/';\n$config['device_traffic_iftype'][] = '/ppp/';\n\n$config['device_traffic_descr'][] = '/loopback/';\n$config['device_traffic_descr'][] = '/vlan/';\n$config['device_traffic_descr'][] = '/tunnel/';\n$config['device_traffic_descr'][] = '/bond/';\n$config['device_traffic_descr'][] = '/null/';\n$config['device_traffic_descr'][] = '/dummy/';\n

      If you would like to re-include l2vlan interfaces for instance, you first need to unset the config array and set your options:

      unset($config['device_traffic_iftype']);\n$config['device_traffic_iftype'][] = '/loopback/';\n$config['device_traffic_iftype'][] = '/tunnel/';\n$config['device_traffic_iftype'][] = '/virtual/';\n$config['device_traffic_iftype'][] = '/mpls/';\n$config['device_traffic_iftype'][] = '/ieee8023adLag/';\n$config['device_traffic_iftype'][] = '/ppp/';\n
      "},{"location":"Support/FAQ/#how-do-i-migrate-my-librenms-install-to-another-server","title":"How do I migrate my LibreNMS install to another server?","text":"

      If you are moving from one CPU architecture to another then you will need to dump the rrd files and re-create them. If you are in this scenario then you can use Dan Brown's migration scripts.

      If you are just moving to another server with the same CPU architecture then the following steps should be all that's needed:

      • Install LibreNMS as per our normal documentation; you don't need to run through the web installer or building the sql schema.
      • Stop cron by commenting out all lines in /etc/cron.d/librenms
      • Dump the MySQL database librenms from your old server (mysqldump librenms -u root -p > librenms.sql)...
      • and import it into your new server (mysql -u root -p librenms < librenms.sql).
      • Copy the rrd/ folder to the new server.
      • Copy the .env and config.php files to the new server.
      • Check for modified files (eg specific os, ...) with git status and migrate them.
      • Ensure ownership of the copied files and folders (substitute your user if necessary) - chown -R librenms:librenms /opt/librenms
      • Delete old pollers on the GUI (gear icon --> Pollers --> Pollers)
      • Validate your installation (/opt/librenms/validate.php)
      • Re-enable cron by uncommenting all lines in /etc/cron.d/librenms
      "},{"location":"Support/FAQ/#why-is-my-edgerouter-device-not-detected","title":"Why is my EdgeRouter device not detected?","text":"

      If you have service snmp description set in your config then this will be why, please remove this. For some reason Ubnt have decided setting this value should override the sysDescr value returned which breaks our detection.

      If you don't have that set then this may be then due to an update of EdgeOS or a new device type, please create an issue.

      "},{"location":"Support/FAQ/#why-are-some-of-my-disks-not-showing","title":"Why are some of my disks not showing?","text":"

      If you are monitoring a linux server then net-snmp doesn't always expose all disks via hrStorage (HOST-RESOURCES-MIB). We have additional support which will retrieve disks via dskTable (UCD-SNMP-MIB). To expose these disks you need to add additional config to your snmpd.conf file. For example, to expose /dev/sda1 which may be mounted as /storage you can specify:

      disk /dev/sda1

      Or

      disk /storage

      Restart snmpd and LibreNMS should populate the additional disk after a fresh discovery.

      "},{"location":"Support/FAQ/#why-are-my-disks-reporting-an-incorrect-size","title":"Why are my disks reporting an incorrect size?","text":"

      There is a known issue for net-snmp, which causes it to report incorrect disk size and disk usage when the size of the disk (or raid) are larger then 16TB, a workaround has been implemented but is not active on Centos 6.8 by default due to the fact that this workaround breaks official SNMP specs, and as such could cause unexpected behaviour in other SNMP tools. You can activate the workaround by adding to /etc/snmp/snmpd.conf :

      realStorageUnits 0

      "},{"location":"Support/FAQ/#what-does-mean-ignore-alert-tag-on-device-component-service-and-port","title":"What does mean \\\"ignore alert tag\\\" on device, component, service and port?","text":"

      Tag device, component, service and port to ignore alerts. Alert checks will still run. However, ignore tag can be read in alert rules. For example on device, if devices.ignore = 0 or macros.device = 1 condition is is set and ignore alert tag is on, the alert rule won't match. The alert rule is ignored.

      "},{"location":"Support/FAQ/#how-do-i-clean-up-alerts-from-my-switches-and-routers-about-ports-being-down-or-changing-speed","title":"How do I clean up alerts from my switches and routers about ports being down or changing speed","text":"

      Some properties used for alerting (ending in _prev) are only updated when a change is detected, and not every time the poller runs. This means that if you make a permanant change to your network such as removing a device, performing a major firmware upgrade, or downgrading a WAN connection, you may be stuck with some unresolvable alerts.

      If a port will be permantly down, it's best practice to configure it to be administratively down on the device to prevent malicious access. You can then only run alerts on ports with ifAdminStatus = up. Otherwise, you'll need to reset the device port state history.

      On the device generating alerts, use the cog button to go to the edit device page. At the top of the device settings pane is a button labelled Reset Port State - this will clear the historic state for all ports on that device, allowing any active alerts to clear.

      "},{"location":"Support/FAQ/#why-cant-normal-and-global-view-users-see-oxidized","title":"Why can't Normal and Global View users see Oxidized?","text":"

      Configs can often contain sensitive data. Because of that only global admins can see configs.

      "},{"location":"Support/FAQ/#what-is-the-demo-user-for","title":"What is the Demo User for?","text":"

      Demo users allow full access except adding/editing users and deleting devices and can't change passwords.

      "},{"location":"Support/FAQ/#why-does-modifying-default-alert-template-fail","title":"Why does modifying 'Default Alert Template' fail?","text":"

      This template's entry could be missing in the database. Please run this from the LibreNMS directory:

      php artisan db:seed --class=DefaultAlertTemplateSeeder\n
      "},{"location":"Support/FAQ/#why-would-alert-un-mute-itself","title":"Why would alert un-mute itself?","text":"

      If alert un-mutes itself then it most likely means that the alert cleared and is then triggered again. Please review eventlog as it will tell you in there.

      "},{"location":"Support/FAQ/#how-do-i-change-the-device-type","title":"How do I change the Device Type?","text":"

      You can change the Device Type by going to the device you would like to change, then click on the Gear Icon -> Edit. If you would like to define custom types, we suggest using Device Groups. They will be listed in the menu similarly to device types.

      "},{"location":"Support/FAQ/#editing-large-device-groups-gives-error-messages","title":"Editing large device groups gives error messages","text":"

      If the device group contains large amount of devices, editing it from the UI might cause errors on the form even when all the data seems correct. This is caused by PHP's max_input_vars-variable. You should be able to confirm that this is the case by inspecting the PHP's error logs.

      With the basic installation on Ubuntu 22.04 LTS with Nginx and PHP 8.1 FPM this value can be tuned by editing the file /etc/php/8.1/fpm/php.ini and adjusting the value of max_input_vars to be at least the size of the large group. In larger installations a value such as 10000 should suffice.

      "},{"location":"Support/FAQ/#where-do-i-update-my-database-credentials","title":"Where do I update my database credentials?","text":"

      If you've changed your database credentials then you will need to update LibreNMS with those new details. Please edit .env

      .env:

      DB_HOST=\nDB_DATABASE=\nDB_USERNAME=\nDB_PASSWORD=\nDB_PORT=\n
      "},{"location":"Support/FAQ/#my-reverse-proxy-is-not-working","title":"My reverse proxy is not working","text":"

      Make sure your proxy is passing the proper variables. At a minimum: X-Forwarded-For and X-Forwarded-Proto (X-Forwarded-Port if needed)

      You also need to Set the proxy or proxies as trusted

      If you are using a subdirectory on the reverse proxy and not on the actual web server, you may need to set APP_URL and $config['base_url'].

      "},{"location":"Support/FAQ/#my-alerts-arent-being-delivered-on-time","title":"My alerts aren't being delivered on time","text":"

      If you're running MySQL/MariaDB on a separate machine or container make sure the timezone is set properly on both the LibreNMS and MySQL/MariaDB instance. Alerts will be delivered according to MySQL/MariaDB's time, so a mismatch between the two can cause alerts to be delivered late if LibreNMS is on a timezone later than MySQL/MariaDB.

      "},{"location":"Support/FAQ/#my-alert-templates-stopped-working","title":"My alert templates stopped working","text":"

      You should probably have a look in the documentation concerning the new template syntax. Since version 1.42, syntax changed, and you basically need to convert your templates to this new syntax (including the titles).

      "},{"location":"Support/FAQ/#how-do-i-use-trend-prediction-in-graphs","title":"How do I use trend prediction in graphs","text":"

      As of Ver. 1.55 a new feature has been added where you can view a simple linear prediction in port graphs.

      It doesn't work on non-port graphs or consolidated graphs at the time this FAQ entry was written.

      To view a prediction:

      • Click on any port graph of any network device
      • Select a From date to your liking (not earlier than the device was actually added to LNMS), and then select a future date in the To field.
      • Click update

      You should now see a linear prediction line on the graph.

      "},{"location":"Support/FAQ/#how-do-i-move-only-the-db-to-another-server","title":"How do I move only the DB to another server?","text":"

      There is already a reference how to move your whole LNMS installation to another server. But the following steps will help you to split up an \"All-in-one\" installation to one LibreNMS installation with a separate database install. *Note: This section assumes you have a MySQL/MariaDB instance

      • Stop the apache and mysql service in you LibreNMS installation.
      • Edit out all the cron entries in /etc/cron.d/librenms.
      • Dump your librenmsdatabase on your current install by issuing mysqldump librenms -u root -p > librenms.sql.
      • Stop and disable the MySQL server on your current install.
      • On your new server make sure you create a new database with the standard install command, no need to add a user for localhost though.
      • Copy this over to your new database server and import it with mysql -u root -p librenms < librenms.sql.
      • Enter to mysql and add permissions with the following two commands:
        GRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'IP_OF_YOUR_LNMS_SERVER' IDENTIFIED BY 'PASSWORD' WITH GRANT OPTION;\nGRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'FQDN_OF_YOUR_LNMS_SERVER' IDENTIFIED BY 'PASSWORD' WITH GRANT OPTION;\nFLUSH PRIVILEGES;\nexit;\n
      • Enable and restart MySQL server.
      • Edit your config.php file to point the install to the new database server location.
      • Very important: On your LibreNMS server, inside your install directory is a .env file, in it you need to edit the DBHOST paramater to point to your new server location.
      • After all this is done, enable all the cron entries again and start apache.
      "},{"location":"Support/FAQ/#what-are-the-optional-requirements-message-when-i-add-snmpv3-devices","title":"What are the \"optional requirements message\" when I add SNMPv3 devices?","text":"

      When you add a device via the WebUI you may see a little message stating \"Optional requirements are not met so some options are disabled\". Do not panic. This simply means your system does not contain openssl >= 1.1 and net-snmp >= 5.8, which are the minimum specifications needed to be able to use SHA-224|256|384|512 as auth algorithms. For crypto algorithms AES-192, AES-256 you need net-snmp compiled with --enable-blumenthal-aes.

      "},{"location":"Support/FAQ/#developing","title":"Developing","text":""},{"location":"Support/FAQ/#how-do-i-add-support-for-a-new-os","title":"How do I add support for a new OS?","text":"

      Please see Supporting a new OS if you are adding all the support yourself, i.e. writing all of the supporting code. If you are only able to supply supporting info, and would like the help of others to write up the code, please follow the below steps.

      "},{"location":"Support/FAQ/#what-information-do-you-need-to-add-a-new-os","title":"What information do you need to add a new OS?","text":"

      Please open a feature request in the community forum and provide the output of Discovery, Poller, and Snmpwalk as separate non-expiring https://p.libren.ms/ links :

      Please use preferably the command line to obtain the information. Especially, if snmpwalk results in a large amount of data. Replace the relevant information in these commands such as HOSTNAME and COMMUNITY. Use snmpwalk instead of snmpbulkwalk for v1 devices.

      These commands will automatically upload the data to LibreNMS servers.

      ./discovery.php -h HOSTNAME -d | ./pbin.sh\nlnms device:poll HOSTNAME -vv | ./pbin.sh\nsnmpbulkwalk -OUneb -v2c -c COMMUNITY HOSTNAME .  | ./pbin.sh\n

      You can use the links provided by these commands within the community post.

      If possible please also provide what the OS name should be if it doesn't exist already, as well as any useful link (MIBs from vendor, logo, etc etc)

      "},{"location":"Support/FAQ/#what-can-i-do-to-help","title":"What can I do to help?","text":"

      Thanks for asking, sometimes it's not quite so obvious and everyone can contribute something different. So here are some ways you can help LibreNMS improve.

      • Code. This is a big thing. We want this community to grow by the software developing and evolving to cater for users needs. The biggest area that people can help make this happen is by providing code support. This doesn't necessarily mean contributing code for discovering a new device:
      • Web UI, a new look and feel has been adopted but we are not finished by any stretch of the imagination. Make suggestions, find and fix bugs, update the design / layout.
      • Poller / Discovery code. Improving it (we think a lot can be done to speed things up), adding new device support and updating old ones.
      • The LibreNMS main website, this is hosted on GitHub like the main repo and we accept use contributions here as well :)
      • Hardware. We don't physically need it but if we are to add device support, it's made a whole lot easier with access to the kit via SNMP.
      • If you've got MIBs, they are handy as well :)
      • If you know the vendor and can get permission to use logos that's also great.
      • Bugs. Found one? We want to know about it. Most bugs are fixed after being spotted and reported by someone, I'd love to say we are amazing developers and will fix all bugs before you spot them but that's just not true.
      • Feature requests. Can't code / won't code. No worries, chuck a feature request into our community forum with enough detail and someone will take a look. A lot of the time this might be what interests someone, they need the same feature or they just have time. Please be patient, everyone who contributes does so in their own time.
      • Documentation. Documentation can always be improved and every little bit helps. Not all features are currently documented or documented well, there's spelling mistakes etc. It's very easy to submit updates through the GitHub website, no git experience needed.
      • Be nice, this is the foundation of this project. We expect everyone to be nice. People will fall out, people will disagree but please do it so in a respectable way.
      • Ask questions. Sometimes just by asking questions you prompt deeper conversations that can lead us to somewhere amazing so please never be afraid to ask a question.
      "},{"location":"Support/FAQ/#how-can-i-test-another-users-branch","title":"How can I test another users branch?","text":"

      LibreNMS can and is developed by anyone, this means someone may be working on a new feature or support for a device that you want. It can be helpful for others to test these new features, using Git, this is made easy.

      cd /opt/librenms\n

      Firstly ensure that your current branch is in good state:

      git status\n

      If you see nothing to commit, working directory clean then let's go for it :)

      Let's say that you want to test a users (f0o) new development branch (issue-1337) then you can do the following:

      git remote add f0o https://github.com/f0o/librenms.git\ngit remote update f0o\ngit checkout issue-1337\n

      Once you are done testing, you can easily switch back to the master branch:

      git checkout master\n

      If you want to pull any new updates provided by f0o's branch then whilst you are still in it, do the following:

      git pull f0o issue-1337\n
      "},{"location":"Support/Features/","title":"Features","text":"

      Here's a brief list of supported features, some might be missing. If you think something is missing, feel free to ask us.

      • Auto discovery
      • Alerting
      • Multiple environment sensors support
      • Multiple protocols data collection (STP, OSPF, BGP etc)
      • VLAN, ARP and FDB table collection
      • Customizable Dashboards
      • Device Backup integration (Oxidized, RANCID)
      • Distributed Polling
      • Multiple Authentication Methods (MySQL, LDAP, Active Directory, HTTP)
      • NetFlow, sFlow, IPFIX (NfSen)
      • Service monitoring (Nagios Plugins)
      • Syslog (Integrated, Graylog)
      • Traffic Billing (Quota, 95th Percentile)
      • Two Factor Authentication
      • API
      • Auto Updating
      "},{"location":"Support/Features/#supported-vendors","title":"Supported Vendors","text":"

      Here's a list of supported vendors, some might be missing. If you are unsure of whether your device is supported or not, feel free to ask us.

      "},{"location":"Support/Features/#3","title":"3","text":"
      • 3Com
      "},{"location":"Support/Features/#a","title":"A","text":"
      • A10 Networks
      • Acano OS
      • Accedian AEN
      • Adtran AOS
      • ADVA FSP150CC
      • ADVA FSP3000 R7
      • ADVA OptiSwitch
      • Advantech
      • Aerohive HiveOS
      • Airconsole Server
      • AIX
      • AKCP SensorProbe
      • Alcatel OmniPCX
      • Alcatel-Lucent Enterprise Stellar Wireless OS (AWOS)
      • Alcatel-Lucent OS
      • Alcoma
      • ALGCOM DC UPS
      • Allied Telesis Wireless (TQ)
      • Alliedware
      • Alliedware Plus
      • Allworx VoIP
      • Alpha Comp@s
      • Alpha CXC HP Controller
      • Alpha FXM
      • Alpine OptoElectronics TDCM-EDFA platform
      • AlteonOS
      • Alvarion Breeze
      • Anue
      • AnyOS
      • APC Environmental Monitoring Unit
      • APC ePDU
      • APC Management Module
      • APC MGE UPS
      • Apex Lynx
      • Apex Plus
      • Apple AirPort
      • Apple OS X
      • Aprisa
      • ApsoluteOS
      • ArbOS
      • Areca RAID Subsystem
      • Arista EOS
      • Arista MOS
      • Array Networks
      • Arris Apex
      • Arris CMTS
      • Arris D5 Universal EdgeQAM
      • ARRIS DOCSIS
      • Arris Satellite Receiver
      • Aruba Clearpass
      • Aruba Instant
      • ArubaOS
      • ArubaOS-CX
      • Ascom
      • Asentria SiteBoss
      • AsusWRT Merlin
      • Aten PDU
      • Audiocodes
      • Automatic Transfer Switch
      • Avaya Scopia
      • AvediaPlayer Receivers
      • AvediaStream Encoder
      • Aviat WTM
      • Avocent
      • Avtech Environment Sensor
      • AXIS Audio Appliances
      • AXIS Network Camera
      • AXIS Network Document Server
      "},{"location":"Support/Features/#b","title":"B","text":"
      • Barco Clickshare
      • Barracuda Email Security Gateway
      • Barracuda Load Balancer
      • Barracuda NG Firewall
      • Barracuda Web Application Firewall
      • BATS AATS
      • BDCOM(tm) Software
      • BeagleBoard
      • Benu
      • Bintec Be.IP Plus
      • Bintec Smart Router
      • BKE
      • BKtel
      • Blade Network Technologies
      • BladeShelter PDU by PowerTek
      • Blue Coat PacketShaper
      • Blue Coat SSL Visibility
      • Bluecat Networks
      • BlueCoat ProxySG
      • Broadcom BCM963xx
      • Brocade FabricOS
      • Brocade IronWare
      • Brocade NOS
      • Brocade ServerIron
      • Brother Printer
      • BTI SA-800
      • Buffalo
      "},{"location":"Support/Features/#c","title":"C","text":"
      • C&C Power Commander plus
      • Calix AXOS
      • Calix B6 System
      • Calix EXA
      • Calix Legacy
      • Cambium
      • Cambium CMM
      • Cambium CMM4
      • Cambium cnMatrix
      • Cambium cnPilot
      • Cambium cnPilot Router
      • Cambium cnWave60
      • Cambium epmp
      • Cambium PTP 250
      • Cambium PTP 300/500
      • Cambium PTP 600
      • Cambium PTP 650
      • Cambium PTP 670
      • Cambium PTP 800
      • Canon Printer
      • Carel pCOWeb
      • cdata
      • Ceragon CeraOS
      • CET TSI Controller
      • Chatsworth PDU
      • Check Point GAiA
      • CheckPoint SecurePlatform
      • Christie Projector
      • Ciena SAOS
      • Ciena Service Delivery Switch
      • Ciena Waveserver
      • Ciena Z-Series
      • cirpack
      • Cisco ACE
      • Cisco ACS
      • Cisco APIC
      • Cisco ASA
      • Cisco AsyncOS
      • Cisco Catalyst 1900
      • Cisco CatOS
      • Cisco EPC
      • Cisco FTD
      • Cisco FX-OS
      • Cisco Identity Services Engine
      • Cisco Integrated Management Controller
      • Cisco Intrusion Prevention System
      • Cisco IOS
      • Cisco IOS-XE
      • Cisco IOS-XR
      • Cisco ME1200
      • Cisco Nexus 3550 Series
      • Cisco NX-OS
      • Cisco ONS
      • Cisco PIX-OS
      • Cisco SAN-OS
      • Cisco Satellite Receiver
      • Cisco SCE
      • Cisco Services Ready Platform
      • Cisco Small Business
      • Cisco Unified Communications Manager
      • Cisco Voice Gateway
      • Cisco WAAS
      • Cisco Wireless Access Point
      • Cisco WLC
      • Citrix Netscaler
      • Comet System Web Sensor
      • Comtrol Industrial Switch
      • Controlbox TH-332B
      • CoreOS
      • Corero CMS
      • Coriant TNMS
      • CradlePoint WiPipe
      • CTC Union
      • Cumulus Linux
      • CXR Networks TS
      • Cyberoam UTM
      • Cyberpower
      "},{"location":"Support/Features/#d","title":"D","text":"
      • D-Link Access Point
      • D-Link Switch
      • Dahua NVR
      • Dantel Webmon
      • Dantherm
      • Dasan NOS
      • Datacom
      • dd-wrt
      • DDN Storage
      • Deliberant OS
      • Dell DRAC
      • Dell EMC Networking OS10 Enterprise
      • Dell EqualLogic
      • Dell Laser
      • Dell Networking OS
      • Dell OpenManage Enterprise Modular
      • Dell PowerConnect
      • Dell PowerVault
      • Dell PowerVault MD
      • Dell Rack PDU
      • Dell Remote Console
      • Dell Storage
      • Dell UPS
      • Delta Orion Controller
      • Delta UPS
      • Develop Printer
      • DHCPatriot
      • Digipower
      • Digital China Networks
      • DKT Comega
      • DPS Telecom NetGuardian
      • DragonflyBSD
      • Dragonwave Harmony Enhanced
      • Dragonwave Horizon Compact
      • Dragonwave Horizon Compact Plus
      • Dragonwave Horizon Duo
      • DrayTek
      • DVB Modulator & Ampiflier
      • DVB-T Transmitter
      "},{"location":"Support/Features/#e","title":"E","text":"
      • E3 Meter
      • E3 Meter DataConcentrator
      • Eagle-I
      • East
      • Eaton ATS
      • Eaton Matrix
      • Eaton MGE PDU
      • Eaton PDU
      • Eaton SC200 Controller
      • Eaton UPS
      • EDFA
      • Edgecore
      • EdgeOS
      • EdgeSwitch
      • EDS
      • EfficientIP SOLIDserver
      • Ekinops Optical
      • Eltek Valere
      • Eltek Valere eNexus
      • Eltek WebPower
      • Eltex OLT
      • Eltex-MES21xx
      • Eltex-MES23xx
      • EMC Data Domain
      • EMC Flare OS
      • EMC Isilon OneFS
      • Emerson Energy System
      • Emerson Netsure
      • Endian
      • EndRun
      • EnGenius Access Point
      • enLogic PDU
      • Enterasys
      • Epson Printer
      • Epson Projector
      • Ericsson 6600 series
      • Ericsson IPOS
      • Ericsson LG iPECS UCP
      • Ericsson MINI-LINK
      • Ericsson Traffic Node
      • EricssonLG IPECS ES
      • Etherwan Managed Switch
      • EUROstor RAID Subsystem
      • Exagrid
      • Exalt ExtendAir
      • Exinda
      • Extrahop Appliance
      • Extreme BOSS
      • Extreme SLX-OS
      • Extreme VOSS
      • Extreme Wireless Convergence
      • Extreme XOS
      • Extremeware
      "},{"location":"Support/Features/#f","title":"F","text":"
      • F5 Big IP
      • F5OS
      • Fiberhome
      • FiberHome Switch
      • Fibernet XMUX 4+
      • Fiberstore GBN
      • Fiberstore Switch
      • Firebrick
      • FireEye OS
      • Force10 FTOS
      • Fortinet Application Deliver Controller
      • Fortinet FortiAuthenticator
      • Fortinet Fortigate
      • Fortinet FortiMail
      • Fortinet FortiSandbox
      • Fortinet FortiSwitch
      • Fortinet FortiVoice
      • Fortinet FortiWeb
      • Fortinet FortiWLC
      • FortiOS
      • Foundry Networking
      • FreeBSD
      • FreshTomato
      • FS.COM monitored pdu
      • Fujitsu
      • Fujitsu ETERNUS
      • FUJITSU iRMC
      • Fujitsu NAS
      • FusionHub
      "},{"location":"Support/Features/#g","title":"G","text":"
      • Gamatronic UPS Stack
      • Gandi Packet Journey
      • GE Digital Energy UPS
      • GE MDS Orbit network Operating System
      • GE Pulsar
      • Geist PDU
      • Geist Watchdog
      • Generex UPS SNMP adapter
      • Generic
      • Generic Device
      • Gestetner Printer
      • GigaVUE
      • Glass Way WDM EYDFA
      • Grandstream HT
      • Greenbone OS
      • Gude Expert Transfer Switch
      • gwd
      "},{"location":"Support/Features/#h","title":"H","text":"
      • Halon
      • Hanwha Techwin
      • HAProxy ALOHA
      • Hardware Appliance
      • Hatteras Overdue DSLAM
      • Helios IP
      • Hikvision Camera
      • Hikvision NVR
      • Hillstone StoneOs
      • Himoinsa Generator Sets
      • Hirschmann Railswitch
      • Hitachi Storage Virtualization Operating System (SVOS)
      • HP Blade Management
      • HP MSM
      • HP PDU Management Module
      • HP Print server
      • HP ProCurve
      • HP UPS
      • HP Virtual Connect
      • HPE 3PAR
      • HPE Comware
      • HPE Integrated Lights Out
      • HPE iPDU
      • HPE Managed Power Distribution Unit
      • HPE MSA
      • HPE OpenVMS
      • HPE StoreEver MSL
      • Huawei iBMC Management Console
      • Huawei OceanStor
      • Huawei SmartAX
      • Huawei SmartAX MDU
      • Huawei SMU
      • Huawei UPS
      • Huawei VRP
      • HWg Poseidon
      • HWg STE
      • HWg STE2
      • HWg WLD
      • Hytera Repeater
      "},{"location":"Support/Features/#i","title":"I","text":"
      • IBM AMM
      • IBM DPI
      • IBM i
      • IBM IMM
      • IBM Networking Operating System
      • IBM Tape Library
      • iBoot PDU
      • Icotera OS
      • ICR-OS
      • ICT Digital Series Power Supply
      • ICT Distribution Series
      • ICT Modular Power System
      • ICT Sine Wave Inverter
      • Ifotec
      • IgniteNet FusionSwitch
      • IgniteNet HeliOS
      • Illustra Network Camera
      • Imco Power
      • Imco Power LS110
      • Infinera Groove
      • Infinera PON
      • Infinera XTM
      • Infoblox
      • Ingrasys iPoMan
      • Innovaphone ISDN
      • Inteno GW
      • IONODES
      • IP Infusion OcNOS
      • IP Office Firmware
      • ITWatchDogs Goose
      "},{"location":"Support/Features/#j","title":"J","text":"
      • Jacarta InterSeptor
      • Janitza
      • Janitza UMG96
      • Juniper EX2500
      • Juniper JunOS
      • Juniper JunOSe
      • Juniper JWOS
      • Juniper MSS
      • Juniper ScreenOS
      "},{"location":"Support/Features/#k","title":"K","text":"
      • Kemp Loadbalancer
      • Konica-Minolta Printer
      • KTI
      • Kyocera Mita Printer
      "},{"location":"Support/Features/#l","title":"L","text":"
      • Lambdatrail
      • Lancom OS
      • Lanier Printer
      • LANTIME v6
      • Lantronix SLC
      • Lantronix UDS
      • Last Mile Gear CTM
      • Lenovo Cloud Network Operating System
      • Lenovo XCC IMPI
      • LenovoEMC
      • Lexmark Printer
      • Liebert
      • LigoWave Infinity
      • LigoWave LigoOS
      • Linksys Smart Switch
      • Linux
      • Loadbalancer.org
      • LogMaster
      • Loop Telecom Operating System
      "},{"location":"Support/Features/#m","title":"M","text":"
      • m0n0wall
      • Maipu MyPower
      • Marathon UPS
      • McAfee Linux OS - ATD
      • McAfee Linux OS - NSP
      • McAfee SIEM Nitro
      • Mcafee Web Gateway
      • MegaTec NetAgent II
      • Mellanox
      • Meraki AP
      • Meraki MX Appliance
      • Meraki Switch
      • Microsemi PowerDsine Midspan PoE
      • Microsemi Synchronization Supply Unit
      • Microsoft Windows
      • Mikrotik RouterOS
      • Mikrotik SwOS
      • Mimosa
      • Minkels RMS
      • Mirth Connect
      • Mitel Standard Linux
      • MNI Microwave Radio
      • MobileIron
      • Montclair EDFA
      • Motorola DOCSIS Cable Modem
      • Motorola Netopia
      • Moxa
      • Moxa AWK
      • MRV LambdaDriver
      • MRV OptiDriver
      "},{"location":"Support/Features/#n","title":"N","text":"
      • NEC Univerge
      • NetApp
      • NetBotz Environment Sensor
      • NetBSD
      • Netgear ProSafe
      • NetMan Plus
      • NetModule
      • Netonix
      • NetScaler SD-WAN
      • Network Management Unit
      • Nexans
      • Nimble OS
      • NOKIA ISAM
      • Nokia SR OS (TiMOS)
      • Novell Netware
      • NRG Printer
      • NTI
      • Nutanix AOS
      • NVT Phybridge
      "},{"location":"Support/Features/#o","title":"O","text":"
      • OKI Printer
      • Omnitron iConverter
      • OneAccess
      • Open Access Netspire
      • Open-E
      • OpenBSD
      • Opengear
      • OpenIndiana
      • OpenSystems
      • OpenWrt
      • OPNsense
      • Oracle ILOM
      • Orvaldi UPS
      "},{"location":"Support/Features/#p","title":"P","text":"
      • Packetflux SiteMonitor
      • Packetlight
      • Panasonic KX-NS Series
      • Panduit PDU
      • PanOS
      • Papouch QUIDO
      • Papouch TME
      • Paradyne (by Zhone)
      • Patton SmartNode
      • PBI Digital Decoder
      • PBN
      • PBN P2P CP100 Series Platform
      • Pegasus
      • Pepwave
      • Perle
      • pfSense
      • Pica8 OS
      • Ping only
      • PLANET
      • Polycom Videoconferencing System
      • Powercode BMU
      • PowerWalker UPS
      • PowerWalker VFI
      • Prime Infrastructure
      • Procera Networks
      • Proxim
      • proxmox pve
      • Pulse Secure
      "},{"location":"Support/Features/#q","title":"Q","text":"
      • QNAP TurboNAS
      • QTECH
      • Quanta
      • QuantaStor
      "},{"location":"Support/Features/#r","title":"R","text":"
      • Radlan
      • RADWIN
      • Raisecom ROAP
      • Raisecom ROS
      • Raritan EMX
      • Raritan KVM
      • Raritan PDU
      • RAy
      • RAy3
      • RecoveryOS
      • Red Lion Sixnet
      • Redback Networks SmartEdge
      • Redlion N-Tron
      • Ribbon GSX
      • Ribbon SBC
      • Ricoh Printer
      • Rittal CMC
      • Rittal CMC III PU
      • Rittal IT Chiller
      • Rittal LCP
      • Rittal LCP DX Chiller
      • Riverbed
      • RNX UPDU
      • Rohde & Schwarz
      • Rubrik
      • Ruckus Wireless HotZone
      • Ruckus Wireless SmartZone
      • Ruckus Wireless Unleashed
      • Ruckus Wireless ZoneDirector
      • Ruijie Networks
      "},{"location":"Support/Features/#s","title":"S","text":"
      • SAF CFM
      • SAF Integra B
      • SAF Integra E
      • SAF Integra W
      • SAF Integra X
      • SAF Tehnika
      • Sagem ADR IONOS
      • Samsung Printer
      • Savin Printer
      • Schleifenbauer SPDM
      • Schneider PowerLogic
      • SCS KS
      • Sensatronics EM1
      • Sensatronics ITTM
      • ServersCheck
      • ServerTech Sentry3
      • ServerTech Sentry4
      • Sharp Printer
      • SIAE Alfoplus 80HD
      • Siemens Ruggedcom Switches (ROS)
      • Siemens SCALANCE
      • Siklu Wireless
      • Silver Peak VXOA
      • Sinetica UPS
      • SM-OS
      • SmartOptics DCP-M Series
      • SmartOptics M-Series
      • SmartOptics T-Series
      • snr
      • snr-erd
      • Socomec Net Vision
      • Socomec PDU
      • Software Appliance
      • Solid Optics EDFAMUX
      • SonicWALL
      • Sophos UTM Firewall
      • Sophos XG
      • Stormshield NS-BSD
      • Stulz GMBH Klimatechnik
      • Sub10 Systems
      • Sun OpenSolaris
      • Sun Solaris
      • Supermicro Switch
      • Symbol AP
      • SyncServer
      • Synology DSM
      "},{"location":"Support/Features/#t","title":"T","text":"
      • Tait Infra93 Series
      • Tait TN Admin OS
      • Tandberg Magnum
      • technicolor TG MediaAcces
      • Tegile IntelliFlash
      • Telco Systems BiNOS
      • Telco Systems BiNOX
      • Teldat
      • TelePresence Codec
      • TelePresence Conductor
      • Teleste Luminato
      • teltonika rutos
      • Teltonika RutOS RUTX Series
      • Teradici PCoIP
      • Terra
      • Thomson DOCSIS Cable Modem
      • Thomson Speedtouch
      • Tomato
      • TopVision
      • Toshiba Printer
      • Toshiba RemotEye4
      • TP-Link JetStream
      • TP-Link Switch
      • Transition
      • Tranzeo
      • TRENDnet Switch
      • Tripp Lite PowerAlert
      • TrueNAS
      • TSC Printer
      • Tycon Systems TPDIN
      "},{"location":"Support/Features/#u","title":"U","text":"
      • Ubiquiti AirFiber
      • Ubiquiti AirFiber 60
      • Ubiquiti AirFiber LTU
      • Ubiquiti AirOS
      • Ubiquiti Edgepower
      • Ubiquiti UniFi
      • Ubiquoss PON
      • Ucopia
      • UFiber
      • UHP Networks VSAT Terminal
      • UniPing
      "},{"location":"Support/Features/#v","title":"V","text":"
      • V-Solution
      • Vanguard ApplicationsWare
      • Vertiv Avocent MergePoint Unity
      • Vertiv PDU
      • Video Communication Server
      • Viprinux
      • Viptela
      • Vivotek Camera
      • VMware ESXi
      • VMware SD-WAN
      • VMware vCenter
      • Volius
      • Voswall
      • Vubiq Networks
      • Vutlan
      • Vyatta
      • VyOS
      "},{"location":"Support/Features/#w","title":"W","text":"
      • Watchguard Fireware
      • Waystream iBOS
      • Web-Thermo-Hygrometer
      • WebPower
      • West Mountain RMCU
      • WISI Tangram
      • WTI CONSOLE
      • WTI MPC
      • WTI POWER
      "},{"location":"Support/Features/#x","title":"X","text":"
      • Xerox Printer
      • Xirrus ArrayOS
      "},{"location":"Support/Features/#z","title":"Z","text":"
      • ZebraNet
      • Zhone MXK
      • Zmtel Greenpacket
      • ZTE ZXA10
      • ZTE ZXR10
      • ZXDSL
      • ZyXEL AC
      • ZyXEL DSLAM
      • ZyXEL Ethernet Switch
      • ZyXEL IES MSAN
      • ZyXEL IES-5000 DSLAM
      • ZyXEL NWA
      • ZyXEL Prestige
      • ZyXEL ZyWALL
      "},{"location":"Support/Install%20Validation/","title":"Install validation","text":"

      With a lot of configuration possibilities, manually editing config.php means it's not uncommon that mistakes get made. It's also impossible to validate user input in config.php when you're just using a text editor :)

      So, to try and help with some of the general issues people come across we've put together a simple validation tool which at present will:

      • Validate config.php from a php perspective including whitespace where it shouldn't be.
      • Connection to your MySQL server to verify credentials.
      • Checks if you are running the older alerting system.
      • Checks your rrd directory setup if not running rrdcached.
      • Checks disk space for where /opt/librenms is installed.
      • Checks location to fping
      • Tests MySQL strict mode being enabled
      • Tests for files not owned by librenms user (if configured)

      Optionally you can also pass -m and a module name for that to be tested. Current modules are:

      • mail - This will validate your mail transport configuration.
      • dist-poller - This will test your distributed poller configuration.
      • rrdcheck - This will test your rrd files to see if they are unreadable or corrupted (source of broken graphs).

      You can run validate.php as root by executing ./validate.php within your install directory.

      The output will provide you either a clean bill of health or a list of things you need to fix:

      OK - This is a good thing, you can skip over these :)

      WARN - You probably want to check this out.

      FAIL - This is going to need your attention!

      "},{"location":"Support/Install%20Validation/#validate-from-the-webui","title":"Validate from the WebUI","text":"

      You can validate your LibreNMS install from the WebUI, using the nav bar and clicking on the little Gear Icon -> Validate Config.

      Then You should see the results of validate.

      Below is just example of the results.

      "},{"location":"Support/Performance/","title":"Performance optimisations","text":"

      This document will give you some guidance on optimising your setup.

      The suggestions are in a rough order of how much impact they will have.

      "},{"location":"Support/Performance/#rrdcached","title":"RRDCached","text":"

      We absolutely recommend running this, it will save on IO load. RRDCached

      "},{"location":"Support/Performance/#mysql-optimisation","title":"MySQL Optimisation","text":"

      It's advisable after 24 hours of running MySQL that you run MySQL Tuner which will make suggestions on things you can change specific to your setup.

      One recommendation we can make is that you set the following in my.cnf under a [mysqld] group:

      innodb_flush_log_at_trx_commit = 0\n

      You can also set this to 2. This will have the possibility that you could lose up to 1 second on mysql data in the event MySQL crashes or your server does but it provides an amazing difference in IO use.

      "},{"location":"Support/Performance/#polling-modules","title":"Polling modules","text":"

      Review the graph of poller module time take under gear > pollers > performance to see what modules are consuming poller time. This data is shown per device under device > graphs > poller.

      Disable polling (and discovery) modules that you do not need. You can do this globally in config.php like:

      Disable OSPF polling

      poller/poller_modules

      lnms config:set poller_modules.ospf false\n

      You can disable modules globally then re-enable the module per device or the opposite way. For a list of modules please see Poller modules

      "},{"location":"Support/Performance/#snmp-max-repeaters","title":"SNMP Max Repeaters","text":"

      We have support for SNMP Max repeaters which can be handy on devices where we poll a lot of ports or bgp sessions for instance and where snmpwalk or snmpbulkwalk is used. This needs to be enabled on a per device basis under edit device -> snmp -> Max repeaters.

      You can also set this globally with the config option $config['snmp']['max_repeaters'] = X;.

      It's advisable to test the time taken to snmpwalk IF-MIB or something similar to work out what the best value is. To do this run the following but replace -REPEATERS- with varying numbers from 10 upto around 50. You will also need to set the correct snmp version, hostname and community string:

      time snmpbulkwalk -v2c -cpublic HOSTNAME -Cr-REPEATERS- -M /opt/librenms/mibs -m IF-MIB IfEntry

      NOTE: Do not go blindly setting this value as you can impact polling negatively.

      "},{"location":"Support/Performance/#snmp-max-oids","title":"SNMP Max OIDs","text":"

      For sensors polling we now do bulk snmp gets to speed things up. By default this is ten but you can overwrite this per device under edit device -> snmp -> Max OIDs.

      You can also set this globally with the config option $config['snmp']['max_oid'] = X;.

      NOTE: It is advisable to monitor sensor polling when you change this to ensure you don't set the value too high.

      "},{"location":"Support/Performance/#fping-tuning","title":"fping tuning","text":"

      You can change some of the default fping options used globally or per device. The defaults are:

      poller/ping

      lnms config:set fping_options.timeout 500\nlnms config:set fping_options.count 3\nlnms config:set fping_options.interval 500\n

      If your devices are slow to respond then you will need to increase the timeout value and potentially the interval value. However if your network is stable, you can increase poller performance by dropping the count value to 1 and/or the timeout+millsec value to 200 or 300:

      poller/ping

      lnms config:set fping_options.timeout 300\nlnms config:set fping_options.count 1\nlnms config:set fping_options.interval 300\n

      This will mean that we no longer delay each icmp packet sent (we send 3 in total by default) by 0.5 seconds. With only 1 icmp packet being sent then we will receive a response quicker. The defaults mean it will take at least 1 second for a response no matter how quick the icmp packet is returned.

      "},{"location":"Support/Performance/#optimise-poller-wrapper","title":"Optimise poller-wrapper","text":"

      poller-wrapper.py defaults to using 16 threads, this isn't necessarily optimal. A general rule of thumb is 2 threads per core but we suggest that you play around with lowering / increasing the number until you get the optimal value. Note KEEP in MIND that this doesn't always help, it depends on your system and CPU. So be careful. This can be changed by going to the cron job for librenms. Usually in /etc/cron.d/librenms and changing the \"16\"

      */5  *    * * *   librenms    /opt/librenms/cronic /opt/librenms/poller-wrapper.py 16\n
      Please also see Dispatcher Service

      "},{"location":"Support/Performance/#recursive-dns","title":"Recursive DNS","text":"

      If your install uses hostnames for devices and you have quite a lot then it's advisable to setup a local recursive dns instance on the LibreNMS server. Something like pdns-recursor can be used and then configure /etc/resolv.conf to use 127.0.0.1 for queries.

      "},{"location":"Support/Performance/#per-port-polling-experimental","title":"Per port polling - experimental","text":"

      By default the polling ports module will walk ifXEntry + some items from ifEntry regardless of the port. So if a port is marked as deleted because you don't want to see them or it's disabled then we still collect data. For the most part this is fine as the walks are quite quick. However for devices with a lot of ports and good % of those are either deleted or disabled then this approach isn't optimal. So to counter this you can enable 'selected port polling' per device within the edit device -> misc section or by globally enabling it (not recommended): $config['polling']['selected_ports'] = true;. This is truly not recommended, as it has been proven to affect cpu usage of your poller negatively. You can also set it for a specific OS: $config['os']['ios']['polling']['selected_ports'] = true;.

      Running ./scripts/collect-port-polling.php will poll your devices with both full and selective polling, display a table with the difference and optionally enable or disable selected ports polling for devices which would benefit from a change. Note that it doesn't continuously re-evaluate this, it will only be updated when the script is run. There are a number of options:

      -h <device id> | <device hostname wildcard>  Poll single device or wildcard hostname\n-e <percentage>                              Enable/disable selected ports polling for devices which would benefit <percentage> from a change\n
      If you want to run this script to have it set selected port polling on devices where a change of 10% or more is evaluated, run it with ./scripts/collect-port-polling.php -e 10. But note: it will not blindly use only the 10%. There is a second condition that the change has to be more than one second in polling time.

      "},{"location":"Support/Performance/#web-interface","title":"Web interface","text":""},{"location":"Support/Performance/#http2","title":"HTTP/2","text":"

      If you are running https then you should enable http/2 support in whatever web server you use:

      For Nginx (1.9.5 and above) change listen 443 ssl; to listen 443 ssl http2; in the Virtualhost config.

      For Apache (2.4.17 and above) set Protocols h2 http/1.1 in the Virtualhost config.

      "},{"location":"Support/Performance/#php-opcache","title":"PHP-opcache","text":"

      A lot of performance can be gained from setting up php-opcache correctly.

      Note: Memory based caching with PHP cli will increase memory usage and slow things down. File based caching is not as fast as memory based and is more likely to have stale cache issues.

      Some distributions allow separate cli, mod_php and php-fpm configurations, we can use this to set the optimal config.

      "},{"location":"Support/Performance/#for-web-servers-using-mod_php-and-php-fpm","title":"For web servers using mod_php and php-fpm","text":"

      Update your web PHP opcache.ini. Possible locations: /etc/php/8.1/fpm/conf.d/opcache.ini, /etc/php.d/opcache.ini, or /etc/php/conf.d/opcache.ini.

      zend_extension=opcache\nopcache.enable=1\nopcache.memory_consumption=256\n

      If you are having caching issues, you can clear the opcache by simply restarting httpd or php-fpm.

      "},{"location":"Support/Performance/#for-pollers","title":"For pollers","text":"

      Create a cache directory that is writable by the librenms user first: sudo mkdir -p /tmp/cache && sudo chmod 775 /tmp/cache && sudo chown -R librenms /tmp/cache

      Update your PHP opcache.ini. Possible locations: /etc/php/8.1/cli/conf.d/opcache.ini, /etc/php.d/opcache.ini, or /etc/php/conf.d/opcache.ini.

      zend_extension=opcache.so\nopcache.enable=1\nopcache.enable_cli=1\nopcache.file_cache=\"/tmp/cache/\"\nopcache.file_cache_only=0\nopcache.file_cache_consistency_checks=1\nopcache.memory_consumption=256\n

      If you are having caching issues, you can clear the file based opcache with rm -rf /tmp/cache.

      Debian 12 users, be aware php 8.2 current stable version (8.2.7) creates segmentation faults when opcache uses file cache. Issue should be this one https://github.com/php/php-src/issues/10914 Using sury packages or disabling file cache solves the issue

      "},{"location":"Support/Poller%20Support/","title":"lnms device:poll","text":"

      This document will explain how to use lnms device:poll to debug issues or manually running to process data.

      "},{"location":"Support/Poller%20Support/#command-options","title":"Command options","text":"
      Description:\n  Poll data from device(s) as defined by discovery\n\nUsage:\n  device:poll [options] [--] <device spec>\n\nArguments:\n  device spec            Device spec to poll: device_id, hostname, wildcard (*), odd, even, all\n\nOptions:\n  -m, --modules=MODULES  Specify single module to be run. Comma separate modules, submodules may be added with /\n  -x, --no-data          Do not update datastores (RRD, InfluxDB, etc)\n  -h, --help             Display help for the given command. When no command is given display help for the list command\n  -q, --quiet            Do not output any message\n  -V, --version          Display this application version\n      --ansi|--no-ansi   Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction   Do not ask any interactive question\n      --env[=ENV]        The environment the command should run under\n  -v|vv|vvv, --verbose   Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n
      "},{"location":"Support/Poller%20Support/#poller-wrapper","title":"Poller Wrapper","text":"

      We have a poller-wrapper.py script by Job Snijders. This script is currently the default.

      If you need to debug the output of poller-wrapper.py then you can add -d to the end of the command - it is NOT recommended to do this in cron.

      "},{"location":"Support/Poller%20Support/#poller-config","title":"Poller config","text":"

      These are the default poller config items. You can globally disable a module by setting it to 0. If you just want to disable it for one device then you can do this within the WebUI Device -> Edit -> Modules.

      poller/poller_modules

      lnms config:set poller_modules.unix-agent false\nlnms config:set poller_modules.os true\nlnms config:set poller_modules.ipmi true\nlnms config:set poller_modules.sensors true\nlnms config:set poller_modules.processors true\nlnms config:set poller_modules.mempools true\nlnms config:set poller_modules.storage true\nlnms config:set poller_modules.netstats true\nlnms config:set poller_modules.hr-mib true\nlnms config:set poller_modules.ucd-mib true\nlnms config:set poller_modules.ipSystemStats true\nlnms config:set poller_modules.ports true\nlnms config:set poller_modules.nac false\nlnms config:set poller_modules.bgp-peers true\nlnms config:set poller_modules.junose-atm-vp false\nlnms config:set poller_modules.printer-supplies false\nlnms config:set poller_modules.ucd-diskio true\nlnms config:set poller_modules.wireless true\nlnms config:set poller_modules.ospf true\nlnms config:set poller_modules.cisco-ipsec-flow-monitor false\nlnms config:set poller_modules.cisco-remote-access-monitor false\nlnms config:set poller_modules.cisco-cef false\nlnms config:set poller_modules.slas false\nlnms config:set poller_modules.cisco-mac-accounting false\nlnms config:set poller_modules.cipsec-tunnels false\nlnms config:set poller_modules.cisco-ace-loadbalancer false\nlnms config:set poller_modules.cisco-ace-serverfarms false\nlnms config:set poller_modules.cisco-asa-firewall false\nlnms config:set poller_modules.cisco-voice false\nlnms config:set poller_modules.cisco-cbqos false\nlnms config:set poller_modules.cisco-otv false\nlnms config:set poller_modules.cisco-vpdn false\nlnms config:set poller_modules.netscaler-vsvr false\nlnms config:set poller_modules.aruba-controller false\nlnms config:set poller_modules.entity-physical true\nlnms config:set poller_modules.entity-state false\nlnms config:set poller_modules.applications true\nlnms config:set poller_modules.availability true\nlnms config:set poller_modules.stp true\nlnms config:set poller_modules.vminfo false\nlnms config:set poller_modules.ntp true\nlnms config:set poller_modules.services true\nlnms config:set poller_modules.loadbalancers false\nlnms config:set poller_modules.mef false\nlnms config:set poller_modules.mef false\n
      "},{"location":"Support/Poller%20Support/#os-based-poller-config","title":"OS based Poller config","text":"

      You can enable or disable modules for a specific OS by add corresponding line in config.php OS based settings have preference over global. Device based settings have preference over all others

      Poller performance improvement can be achieved by deactivating all modules that are not supported by specific OS.

      E.g. to deactivate spanning tree but activate unix-agent module for linux OS

      poller/poller_modules

      lnms config:set os.linux.poller_modules.stp false\nlnms config:set os.linux.poller_modules.unix-agent true\n
      "},{"location":"Support/Poller%20Support/#poller-modules","title":"Poller modules","text":"

      unix-agent: Enable the check_mk agent for external support for applications.

      system: Provides information on some common items like uptime, sysDescr and sysContact.

      os: Os detection. This module will pick up the OS of the device.

      ipmi: Enables support for IPMI if login details have been provided for IPMI.

      sensors: Sensor detection such as Temperature, Humidity, Voltages + More.

      processors: Processor support for devices.

      mempools: Memory detection support for devices.

      storage: Storage detection for hard disks

      netstats: Statistics for IP, TCP, UDP, ICMP and SNMP.

      hr-mib: Host resource support.

      ucd-mib: Support for CPU, Memory and Load.

      ipSystemStats: IP statistics for device.

      ports: This module will detect all ports on a device excluding ones configured to be ignored by config options.

      xdsl: This module will collect more metrics for xdsl interfaces.

      nac: Network Access Control (NAC) or 802.1X support.

      bgp-peers: BGP detection and support.

      junose-atm-vp: Juniper ATM support.

      printer-supplies: Toner levels support.

      ucd-diskio: Disk I/O support.

      wifi: WiFi Support for those devices with support.

      ospf: OSPF Support.

      cisco-ipsec-flow-monitor: IPSec statistics support.

      cisco-remote-access-monitor: Cisco remote access support.

      cisco-cef: CEF detection and support.

      slas: SLA detection and support.

      cisco-mac-accounting: MAC Address account support.

      cipsec-tunnels: IPSec tunnel support.

      cisco-ace-loadbalancer: Cisco ACE Support.

      cisco-ace-serverfarms: Cisco ACE Support.

      netscaler-vsvr: Netscaler support.

      aruba-controller: Aruba wireless controller support.

      entity-physical: Module to pick up the devices hardware support.

      applications: Device application support.

      availability: Device Availability Calculation.

      cisco-asa-firewall: Cisco ASA firewall support.

      "},{"location":"Support/Poller%20Support/#running","title":"Running","text":"

      Here are some examples of running poller from within your install directory.

      lnms device:poll localhost\n\nlnms device:poll localhost -m ports\n
      "},{"location":"Support/Poller%20Support/#debugging","title":"Debugging","text":"

      To provide debugging output you will need to run the poller process with the -vv flag. You can do this either against all modules, single or multiple modules:

      All Modules

      lnms device:poll localhost -vv\n

      Single Module

      lnms device:poll localhost -m ports -vv\n

      Multiple Modules

      lnms device:poll localhost -m ports,entity-physical -vv\n

      Using -vv shouldn't output much sensitive information, -vvv will so it is then advisable to sanitise the output before pasting it somewhere as the debug output will contain snmp details amongst other items including port descriptions.

      The output will contain:

      DB Updates

      RRD Updates

      SNMP Response

      "},{"location":"Support/Remote-Monitoring-VPN/","title":"Remote monitoring using tinc VPN","text":"

      This article describes how to use tinc to connect several remote sites and their subnets to your central monitoring server. This will let you connect to devices on remote private IP ranges through one gateway on each site, routing them securely back to your LibreNMS installation.

      "},{"location":"Support/Remote-Monitoring-VPN/#configuring-the-monitoring-server","title":"Configuring the monitoring server","text":"

      tinc should be available on nearly all Linux distributions via package management. If you are running something different, just take a look at tinc's homepage to find an appropriate version for your operating system: https://www.tinc-vpn.org/download/

      I am going to describe the setup for Debian-based systems, but there are virtually no differences for e.g. CentOS or similar.

      • First make sure your firewall accepts connections on port 655 UDP and TCP.
      • Then install tinc via apt-get install tinc.
      • Create the following directory structure to hold all your configuration files: mkdir -p /etc/tinc/myvpn/hosts \"myvpn\" is your VPN network's name and can be chosen freely.
      • Create your main configuration file: vim /etc/tinc/myvpn/tinc.conf
      Name = monitoring\nAddressFamily = ipv4\nDevice = /dev/net/tun\n
      • Next we need network up- and down scripts to define a few network settings for inside our VPN: vim /etc/tinc/myvpn/tinc-up
      #!/bin/sh\nifconfig $INTERFACE 10.6.1.1 netmask 255.255.255.0\nip route add 10.6.1.1/24 dev $INTERFACE\nip route add 10.0.0.0/22 dev $INTERFACE\nip route add 10.100.0.0/22 dev $INTERFACE\nip route add 10.200.0.0/22 dev $INTERFACE\n
      • In this example we have 10.6.1.1 as the VPN IP address for the monitoring server on a /24 subnet. $INTERFACE will be automatically substituted with the name of the VPN, \"myvpn\" in this case. Then we have a route for the VPN subnet, so we can reach other sites via their VPN address. The last 3 lines designate the remote subnets. In the example I want to reach devices on three different remote private /22 subnets and be able to monitor devices on them from this server, so I set up routes for each of those remote sites in my tinc-up script.

      • The tinc-down script is relatively simple as it just removes the custom interface, which should get rid of the routes as well: vim /etc/tinc/myvpn/tinc-down

      #!/bin/sh\nifconfig $INTERFACE down\n
      • Make sure your scripts scan be executed: chmod +x /etc/tinc/myvpn/tinc-*
      • As a last step we need a host configuration file. This should be named the same as the \"Name\" you defined in tinc.conf: vim /etc/tinc/myvpn/hosts/monitoring
      Subnet = 10.6.1.1/32\n

      On the monitoring server we will just fill in the subnet and not define its external IP address to make sure it listens on all available external interfaces.

      • It's time to use tinc to create our key-pair: tincd -n myvpn -K
      • Now the file /etc/tinc/myvpn/hosts/monitoring should have an RSA public key appended to it and your private key should reside in /etc/tinc/myvpn/rsa_key.priv.
      • To make sure that the connection will be restored after each reboot, you can add your VPN name to /etc/tinc/nets.boot.
      • Now you can start tinc with tincd -n myvpn and it will listen for your remote sites to connect to it.
      "},{"location":"Support/Remote-Monitoring-VPN/#remote-site-configuration","title":"Remote site configuration","text":"

      Essentially the same steps as for your central monitoring server apply for all remote gateway devices. These can be routers, or just any computer or VM running on the remote subnet, able to reach the internet with the ability to forward IP packets externally.

      • Install tinc
      • Create directory structure: mkdir -p /etc/tinc/myvpn/hosts
      • Create main configuration: vim /etc/tinc/myvpn/tinc.conf
      Name = remote1\nAddressFamily = ipv4\nDevice = /dev/net/tun\nConnectTo = monitoring\n
      • Create up script: vim /etc/tinc/myvpn/tinc-up
      #!/bin/sh\nifconfig $INTERFACE 10.6.1.2 netmask 255.255.255.0\nip route add 10.6.1.2/32 dev $INTERFACE\n
      • Create down script: vim /etc/tinc/myvpn/tinc-down
      #!/bin/sh\nifconfig $INTERFACE down\n
      • Make executable: chmod +x /etc/tinc/myvpn/tinc*
      • Create device configuration: vim /etc/tinc/myvpn/hosts/remote1
      Address = 198.51.100.2\nSubnet = 10.0.0.0/22\n

      This defines the device IP address outside of the VPN and the subnet it will expose.

      • Copy over the monitoring server's host configuration (including the embedded public key) and add it's external IP address: vim /etc/tinc/myvpn/hosts/monitoring
      Address = 203.0.113.6\nSubnet = 10.6.1.1/32\n\n-----BEGIN RSA PUBLIC KEY-----\nVeDyaqhKd4o2Fz...\n
      • Generate this device's keys: tincd -n myvpn -K
      • Copy over this devices host file including the embedded public key to your monitoring server.
      • Add the name for the VPN to/etc/tinc/nets.boot if you want to autostart the connection upon reboot.
      • Start tinc: tincd -n myvpn

      These steps can basically be repeated for every remote site just choosing different names and other internal IP addresses. In my case I connected 3 remote sites running behind Ubiquiti EdgeRouters. Since those devices let me install software through Debian's package management it was very easy to set up. Just create the necessary configuration files and network scripts on each device and distribute the host configurations including the public keys to each device that will actively connect back.

      Now you can add all devices you want to monitor in LibreNMS using their internal IP address on the remote subnets or using some form of name resolution. I opted to declare the most important devices in my /etc/hosts file on the monitoring server.

      As an added bonus tinc is a mesh VPN, so in theory you could specify several \"ConnectTo\" on each device and they should hold connections even if one network path goes down.

      "},{"location":"Support/SNMP-Configuration-Examples/","title":"SNMP configuration examples","text":""},{"location":"Support/SNMP-Configuration-Examples/#devices","title":"Devices","text":""},{"location":"Support/SNMP-Configuration-Examples/#cisco","title":"Cisco","text":""},{"location":"Support/SNMP-Configuration-Examples/#adaptive-security-appliance-asa","title":"Adaptive Security Appliance (ASA)","text":"

      ASDM

      1. Launch ASDM and connect to your device
      2. Go to Configuration > Management Access > SNMP
      3. Add your community string
      4. Add in the \"SNMP Host Access List\" section your LibreNMS server IP address
      5. Click Apply and Save

      CLI

      # SNMPv2c\n\nsnmp-server community <YOUR-COMMUNITY>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\nsnmp-server host <INTERFACE> <LIBRENMS-IP> poll community <YOUR-COMMUNITY> version 2c\n\n# SNMPv3\n\nsnmp-server group <GROUP-NAME> v3 priv\nsnmp-server user <USER-NAME> <GROUP-NAME> v3 auth sha <AUTH-PASSWORD> priv aes 128 <PRIV-PASSWORD>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\nsnmp-server host <INTERFACE> <LIBRENMS-IP> poll version 3 <USER-NAME>\n

      Note: If the device is unable to find the SNMP user, reboot the ASA. Once rebooted, continue the steps as normal.

      "},{"location":"Support/SNMP-Configuration-Examples/#ios-ios-xe","title":"IOS / IOS XE","text":"
      # SNMPv2c\n\nsnmp-server community <YOUR-COMMUNITY> RO\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n\n# SNMPv3\n\nsnmp-server group <GROUP-NAME> v3 priv\nsnmp-server user <USER-NAME> <GROUP-NAME> v3 auth sha <AUTH-PASSWORD> priv aes 128 <PRIV-PASSWORD>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n\n# Note: The following is also required if using SNMPv3 and you want to populate the FDB table, STP info and others.\n\nsnmp-server group <GROUP-NAME> v3 priv context vlan- match prefix\n

      Note: If the device is unable to find the SNMP user, reboot the ASA. Once rebooted, continue the steps as normal.

      "},{"location":"Support/SNMP-Configuration-Examples/#nx-os","title":"NX-OS","text":"
      # SNMPv2c\n\nsnmp-server community <YOUR-COMMUNITY> RO\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n\n# SNMPv3\n\nsnmp-server user <USER-NAME> <GROUP-NAME> v3 auth sha <AUTH-PASSWORD> priv aes 128 <PRIV-PASSWORD>\nsnmp-server contact <YOUR-CONTACT>\nsnmp-server location <YOUR-LOCATION>\n
      "},{"location":"Support/SNMP-Configuration-Examples/#wireless-lan-controller-wlc","title":"Wireless LAN Controller (WLC)","text":"
      1. Access the web admin page and log in
      2. If you are running version 8.1 and later, on the new dashboard click \"Advanced\"
      3. Go to management Tab
      4. On SNMP sub-menu, select \"Communities\"
      5. Click \"New...\"
      6. Add your community name and leave IP addresses empty
      7. Click Apply and Save
      "},{"location":"Support/SNMP-Configuration-Examples/#eaton","title":"Eaton","text":""},{"location":"Support/SNMP-Configuration-Examples/#network-card-ms","title":"Network Card-MS","text":"
      1. Connect to the Web UI of the device
      2. Upgrade to the latest available manufacturer firmware which applies to your hardware revision. Refer to the release notes. For devices which can use the Lx releases, do install LD.
      3. After rebooting the card (safe for connected load), configure Network, System and Access Control. Save config for each step.
      4. Configure SNMP. The device defaults to both SNMP v1 and v3 enabled, with default credentials. Disable what you do not need. SNMP v3 works, but uses MD5/DES. You may have to add another section to your SNMP credentials table in LibreNMS. Save.
      "},{"location":"Support/SNMP-Configuration-Examples/#hpe-3par","title":"HPE / 3PAR","text":""},{"location":"Support/SNMP-Configuration-Examples/#comware","title":"Comware","text":"

      SNMPv2c

      snmp-agent community read <YOUR-COMMUNITY>\nsnmp-agent sys-info contact <YOUR-CONTACT>\nsnmp-agent sys-info location <YOUR-LOCATION>\nsnmp-agent sys-info version all\nsnmp-agent packet max-size 6000\n

      packet max-size is required for some walks to complete, but the path must support fragmentation.

      SNMPv3

      snmp-agent mib-view excluded ExcludeAll snmp\nsnmp-agent group v3 V3ROGroup privacy read-view ViewDefault write-view ExcludeAll\nsnmp-agent usm-user v3 <USER> V3ROGroup simple authentication-mode sha <AuthKey> privacy-mode aes128 <PrivacyKey>\nsnmp-agent sys-info contact <YOUR-CONTACT>\nsnmp-agent sys-info location <YOUR-LOCATION>\nsnmp-agent sys-info version v3\nundo snmp-agent sys-info version v1 v2c\nsnmp-agent packet max-size 6000\n

      packet max-size is required for some walks to complete, but the path must support fragmentation.

      "},{"location":"Support/SNMP-Configuration-Examples/#inform-os-32x","title":"Inform OS 3.2.x","text":"
      • Access the CLI
      • Add an SNMP Manager with your LibreNMS IP address:
      addsnmpmgr <librenms ip>\n
      • Add your SNMP community:
      setsnmppw <community>\n
      "},{"location":"Support/SNMP-Configuration-Examples/#infoblox","title":"Infoblox","text":""},{"location":"Support/SNMP-Configuration-Examples/#nios-7x","title":"NIOS 7.x+","text":"
      1. Access the web admin page and log in
      2. Go to Grid tab > Grid Manager
      3. In the right menu select \"Grid properties\"
      4. Select \"SNMP\" menu
      5. Click \"Enable SNMPv1/SNMPv2 Queries\"
      6. Add your community
      7. Click Save & Close
      "},{"location":"Support/SNMP-Configuration-Examples/#juniper","title":"Juniper","text":""},{"location":"Support/SNMP-Configuration-Examples/#junos-os","title":"Junos OS","text":"

      for SNMPv1/v2c

      set snmp description description\nset snmp location location\nset snmp contact contact\nset snmp community YOUR-COMMUNITY authorization read-only\n

      for SNMPv3 (authPriv):

      set snmp v3 usm local-engine user authpriv authentication-sha authentication-password YOUR_AUTH_SECRET\nset snmp v3 usm local-engine user authpriv privacy-aes128 privacy-password YOUR_PRIV_SECRET\nset snmp v3 vacm security-to-group security-model usm security-name authpriv group mysnmpv3\nset snmp v3 vacm access group mysnmpv3 default-context-prefix security-model any security-level authentication read-view mysnmpv3view\nset snmp v3 vacm access group mysnmpv3 default-context-prefix security-model any security-level privacy read-view mysnmpv3view\nset snmp view mysnmpv3view oid iso include\n
      "},{"location":"Support/SNMP-Configuration-Examples/#mikrotik","title":"Mikrotik","text":""},{"location":"Support/SNMP-Configuration-Examples/#routeros-6x","title":"RouterOS 6.x","text":"

      CLI SNMP v2 Configuration

      /snmp community\nset [ find default=yes ] read-access=no\nadd addresses=<ALLOWED-SRC-IPs/NETMASK> name=<COMMUNITY>\n/snmp\nset contact=\"<NAME>\" enabled=yes engine-id=<ENGINE ID> location=\"<LOCALTION>\"\n
      Notes:

      • About the snmp community commands:
        • The commands change the default snmp community. It is probably possible to create a new one instead.
        • specify the address and host (not network) netmask of the LibreNMS server. Example: 192.168.8.71/32
        • trap-version=2 must also be specified if some other trap-version has been set
        • trap-interfaces may also be used to limit the interfaces the router listens on
        • About the snmp command:
          • contact, engine-id and location are optional
          • trap-community is probably required if a new snmp community has been created.
        • CLI SNMP v3 Configuration for authPriv

          /snmp community\nadd name=\"<COMMUNITY>\" addresses=\"<ALLOWED-SRC-IPs/NETMASK>\"\nset \"<COMMUNITY>\" authentication-password=\"<AUTH_PASS>\" authentication-protocol=MD5\nset \"<COMMUNITY>\" encryption-password=\"<ENCRYP_PASS>\" encryption-protocol=AES\nset \"<COMMUNITY>\" read-access=yes write-access=no security=private\n#Disable public SNMP\nset public read-access=no write-access=no security=private\n/snmp\nset contact=\"<NAME>\" enabled=yes engine-id=\"<ENGINE ID>\" location=\"<LOCALTION>\"\n
          Notes:

          • Use password with length of min 8 chars

          Notes for both SNMP v2 and v3

          • In some cases of advanced routing one may need to set explicitly the source IP address from which the SNMP daemon will reply - /snmp set src-address=<SELF_IP_ADDRESS>
          "},{"location":"Support/SNMP-Configuration-Examples/#palo-alto","title":"Palo Alto","text":""},{"location":"Support/SNMP-Configuration-Examples/#panos-6x7x","title":"PANOS 6.x/7.x","text":"
          1. Access the web admin page and log in
          2. Go to Device tab > Setup
          3. Go to the sub-tab \"Operations\"
          4. Click \"SNMP Setup\"
          5. Enter your SNMP community and then click \"OK\"
          6. Click Apply

          Note that you need to allow SNMP on the needed interfaces. To do that you need to create a network \"Interface Mgmt\" profile for standard interface and allow SNMP under \"Device > Management > Management Interface Settings\" for out of band management interface.

          One may also configure SNMP from the command line, which is useful when you need to configure more than one firewall for SNMP monitoring. Log into the firewall(s) via ssh, and perform these commands for basic SNMPv3 configuration:

          username@devicename> configure\nusername@devicename# set deviceconfig system service disable-snmp no\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 views pa view iso oid 1.3.6.1\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 views pa view iso option include\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 views pa view iso mask 0xf0\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 users authpriv authpwd YOUR_AUTH_SECRET\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 users authpriv privpwd YOUR_PRIV_SECRET\nusername@devicename# set deviceconfig system snmp-setting access-setting version v3 users authpriv view pa\nusername@devicename# set deviceconfig system snmp-setting snmp-system location \"Yourcity, Yourcountry [60.4,5.31]\"\nusername@devicename# set deviceconfig system snmp-setting snmp-system contact noc@your.org\nusername@devicename# commit\nusername@devicename# exit\n
          "},{"location":"Support/SNMP-Configuration-Examples/#ubiquiti","title":"Ubiquiti","text":""},{"location":"Support/SNMP-Configuration-Examples/#edgeos","title":"EdgeOs","text":"

          If you use the HTTP interface: 1. Access the legacy web admin page and log in 1. Go to System > Advanced Configuration 1. Go to the sub-tab \"SNMP\" > \"Community\" 1. Click \"Add Community Group\" 1. Enter your SNMP community, ip address and click submit 1. Go to System > Summary 1. Go to the sub-tab \"Description\" 1. Enter your System Name, System Location and System Contact. 1. Click submit 1. Click \"Save Configuration\"

          If you use CLI:

          username@devicename> enable\nusername@devicename# configure\nusername@devicename (Config)# snmp-server community \"public\" ro\nusername@devicename (Config)# snmp-server sysname \"devicename\"\nusername@devicename (Config)# snmp-server contact \"noc@example.com\"\nusername@devicename (Config)# exit\nusername@devicename# write memory\n

          "},{"location":"Support/SNMP-Configuration-Examples/#vmware","title":"VMware","text":""},{"location":"Support/SNMP-Configuration-Examples/#esxesxi-5x6x","title":"ESX/ESXi 5.x/6.x","text":"

          Log on to your ESX server by means of ssh. You may have to enable the ssh service in the GUI first. From the CLI, execute the following commands:

          esxcli system snmp set --authentication SHA1\nesxcli system snmp set --privacy AES128\nesxcli system snmp hash --auth-hash YOUR_AUTH_SECRET --priv-hash YOUR_PRIV_SECRET --raw-secret\n

          This command produces output like this

             Authhash: f3d8982fc28e8d1346c26eee49eb2c4a5950c934\n   Privhash: 0596ab30b315576a4e9f7d7bde65bf49b749e335\n

          Now define a SNMPv3 user:

          esxcli system snmp set --users <username>/f3d8982fc28e8d1346c26eee49eb2c4a5950c934/0596ab30b315576a4e9f7d7bde65bf49b749e335/priv\nesxcli system snmp set -L \"Yourcity, Yourcountry [60.4,5.3]\"\nesxcli system snmp set -C noc@your.org\nesxcli system snmp set --enable true\n

          Note: In case of snmp timeouts, disable the firewall with esxcli network firewall set --enabled false If snmp timeouts still occur with firewall disabled, migrate VMs if needed and reboot ESXi host.

          "},{"location":"Support/SNMP-Configuration-Examples/#vcenter-6x","title":"VCenter 6.x","text":"

          Log on to your ESX server by means of ssh. You may have to enable the ssh service in the GUI first. From the CLI, execute the following commands:

          snmp.set --authentication SHA1\nsnmp.set --privacy AES128\nsnmp.hash --auth_hash YOUR_AUTH_SECRET --priv_hash YOUR_PRIV_SECRET --raw_secret true\n

          This command produces output like this

             Privhash: 0596ab30b315576a4e9f7d7bde65bf49b749e335\n   Authhash: f3d8982fc28e8d1346c26eee49eb2c4a5950c934\n

          Now define a SNMPv3 user:

          snmp.set --users authpriv/f3d8982fc28e8d1346c26eee49eb2c4a5950c934/0596ab30b315576a4e9f7d7bde65bf49b749e335/priv\nsnmp.enable\n
          "},{"location":"Support/SNMP-Configuration-Examples/#operating-systems","title":"Operating systems","text":""},{"location":"Support/SNMP-Configuration-Examples/#linux-snmpd-v2","title":"Linux (snmpd v2)","text":"

          Replace your snmpd.conf file by the example below and edit it with appropriate community in \"RANDOMSTRINGGOESHERE\".

          vi /etc/snmp/snmpd.conf\n
          # Change RANDOMSTRINGGOESHERE to your preferred SNMP community string\ncom2sec readonly  default         RANDOMSTRINGGOESHERE\n\ngroup MyROGroup v2c        readonly\nview all    included  .1                               80\naccess MyROGroup \"\"      any       noauth    exact  all    none   none\n\nsyslocation Rack, Room, Building, City, Country [GPSX,Y]\nsyscontact Your Name <your@email.address>\n\n#Distro Detection\nextend distro /usr/bin/distro\n#Hardware Detection (uncomment to enable)\n#extend hardware '/bin/cat /sys/devices/virtual/dmi/id/product_name'\n#extend manufacturer '/bin/cat /sys/devices/virtual/dmi/id/sys_vendor'\n#extend serial '/bin/cat /sys/devices/virtual/dmi/id/product_serial'\n

          NOTE: On some systems the snmpd is running as its own user, which means it can't read /sys/devices/virtual/dmi/id/product_serial which is mode 0400. One solution is to include @reboot chmod 444 /sys/devices/virtual/dmi/id/product_serial in the crontab for root or equivalent.

          Non-x86 or SMBIOS-based systems, such as ARM-based Raspberry Pi units should query device tree locations for this metadata, for example:

          extend hardware '/bin/cat /sys/firmware/devicetree/base/model'\nextend serial '/bin/cat /sys/firmware/devicetree/base/serial-number'\n

          The LibreNMS server include a copy of this example here:

          /opt/librenms/snmpd.conf.example\n

          The binary /usr/bin/distro must be copied from the original source repository:

          curl -o /usr/bin/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro\nchmod +x /usr/bin/distro\n
          "},{"location":"Support/SNMP-Configuration-Examples/#linux-snmpd-v3","title":"Linux (snmpd v3)","text":"

          Go to /etc/snmp/snmpd.conf

          Open the file in vi or nano /etc/snmp/snmpd.conf and add the following line to create SNMPV3 User (replace username and passwords with your own):

          createUser authPrivUser SHA \"authPassword\" AES \"privPassword\"\n

          Make sure the agent listens to all interfaces by adding the following line inside snmpd.conf:

          agentAddress udp:161,udp6:161\n

          This line simply means listen to connections across all interfaces IPv4 and IPv6 respectively

          Uncomment and change the following line to give read access to the username created above (rouser is what LibreNMS uses) :

          #rouser authPrivUser priv\n

          Change the following details inside snmpd.conf

          syslocation Rack, Room, Building, City, Country [GPSX,Y]\nsyscontact Your Name <your@email.address>\n

          Save and exit the file

          "},{"location":"Support/SNMP-Configuration-Examples/#restart-the-snmpd-service","title":"Restart the snmpd service","text":""},{"location":"Support/SNMP-Configuration-Examples/#centos-6-red-hat-6","title":"CentOS 6 / Red hat 6","text":"
          service snmpd restart\n
          "},{"location":"Support/SNMP-Configuration-Examples/#centos-7-red-hat-7","title":"CentOS 7 / Red hat 7","text":"
          systemctl restart snmpd\n

          Add SNMP to Firewalld

          firewall-cmd --zone=public --permanent --add-service=snmp\nfirewall-cmd --reload\n
          "},{"location":"Support/SNMP-Configuration-Examples/#ubuntu","title":"Ubuntu","text":"
          service snmpd restart\n
          "},{"location":"Support/SNMP-Configuration-Examples/#arch-linux-snmpd-v2","title":"Arch Linux (snmpd v2)","text":"
          1. Install SNMP Package pacman -S net-snmp
          2. create SNMP folder mkdir /etc/snmp/
          3. set community echo rocommunity read_only_community_string >> /etc/snmp/snmpd.conf
          4. set contact echo syscontact Firstname Lastname >> /etc/snmp/snmpd.conf
          5. set location echo syslocation L69 4RX >> /etc/snmp/snmpd.conf
          6. enable startup systemctl enable snmpd.service
          7. start snmp systemctl restart snmpd.service
          "},{"location":"Support/SNMP-Configuration-Examples/#windows-server-2008-r2","title":"Windows Server 2008 R2","text":"
          1. Log in to your Windows Server 2008 R2
          2. Start \"Server Manager\" under \"Administrative Tools\"
          3. Click \"Features\" and then click \"Add Feature\"
          4. Check (if not checked) \"SNMP Service\", click \"Next\" until \"Install\"
          5. Start \"Services\" under \"Administrative Tools\"
          6. Edit \"SNMP Service\" properties
          7. Go to the security tab
          8. In \"Accepted community name\" click \"Add\" to add your community string and permission
          9. In \"Accept SNMP packets from these hosts\" click \"Add\" and add your LibreNMS server IP address
          10. Validate change by clicking \"Apply\"
          "},{"location":"Support/SNMP-Configuration-Examples/#windows-server-2012-r2-and-newer","title":"Windows Server 2012 R2 and newer","text":""},{"location":"Support/SNMP-Configuration-Examples/#gui","title":"GUI","text":"
          1. Log in to your Windows Server 2012 R2 or newer
          2. Start \"Server Manager\" under \"Administrative Tools\"
          3. Click \"Manage\" and then \"Add Roles and Features\"
          4. Continue by pressing \"Next\" to the \"Features\" menu
          5. Install (if not installed) \"SNMP Service\"
          6. Start \"Services\" under \"Administrative Tools\"
          7. Edit \"SNMP Service\" properties
          8. Go to the security tab
          9. In \"Accepted community name\" click \"Add\" to add your community string and permission
          10. In \"Accept SNMP packets from these hosts\" click \"Add\" and add your LibreNMS server IP address
          11. Validate change by clicking \"Apply\"
          "},{"location":"Support/SNMP-Configuration-Examples/#powershell","title":"PowerShell","text":"

          The following example will install SNMP, set the Librenms IP and set a read only community string. Replace $IP and $communitystring with your values.

          Install-WindowsFeature -Name 'SNMP-Service','RSAT-SNMP'\nNew-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\services\\SNMP\\Parameters\\PermittedManagers\"  -Name 2 -Value $IP\nNew-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\services\\SNMP\\Parameters\\ValidCommunities\"  -Name $communitystring -Value 4\n

          Note: SNMPv3 can be supported on Windows platforms with the use of Net-SNMP.

          "},{"location":"Support/SNMP-Configuration-Examples/#mac-osx","title":"Mac OSX","text":"

          Step 1: sudo nano /etc/snmp/snmpd.conf

          #Allow read-access with the following SNMP Community String:\nrocommunity public\n\n# all other settings are optional but recommended.\n\n# Location of the device\nsyslocation data centre A\n\n# Human Contact for the device\nsyscontact SysAdmin\n\n# System Name of the device\nsysName SystemName\n\n# the system OID for this device. This is optional but recommended,\n# to identify this as a MAC OS system.\nsysobjectid 1.3.6.1.4.1.8072.3.2.16\n

          Step 2:

          sudo launchctl load -w /System/Library/LaunchDaemons/org.net-snmp.snmpd.plist\n
          "},{"location":"Support/Device-Notes/AsuswrtMerlin/","title":"Asuswrt-Merlin","text":"

          To use Wireless Sensors on AsuswrtMerlin, an agent of sorts is required. The purpose of the agent is to execute on the client (AsuswrtMerlin) side, to ensure that the needed Wireless Sensor information is returned for SNMP queries (from LibreNMS).

          "},{"location":"Support/Device-Notes/AsuswrtMerlin/#installation","title":"Installation","text":""},{"location":"Support/Device-Notes/AsuswrtMerlin/#asuswrtmerlin","title":"AsuswrtMerlin","text":"

          Two items are required on the AsuswrtMerlin side - scripts to generate the necessary information (for SNMP replies), and an SNMP extend configuration update (to return the information vs. the expected query).

          1: Install the scripts:

          Copy the scripts from librenms-agent/snmp/Openwrt - preferably inside /etc/librenms on AsuswrtMerlin (and add this directory to /etc/sysupgrade.conf, to survive firmware updates).

          The only file that needs to be edited is wlInterfaces.txt, which is a mapping from the wireless interfaces, to the desired display name in LibreNMS. For example,

          wlan0,wl-2.4G\nwlan1,wl-5.0G\n

          2: Update the AsuswrtMerlin SNMP configuration, adding extend support for the Wireless Sensor queries:

          vi /etc/config/snmpd, adding the following entries (assuming the scripts are installed in /etc/librenms, and are executable), and update the network interfaces as needed to match the hardware,

          config extend\n        option name     interfaces\n        option prog     \"/bin/cat /etc/librenms/wlInterfaces.txt\"\nconfig extend\n        option name     clients-wlan0\n        option prog     \"/etc/librenms/wlClients.sh wlan0\"\nconfig extend\n        option name     clients-wlan1\n        option prog     \"/etc/librenms/wlClients.sh wlan1\"\nconfig extend\n        option name     clients-wlan\n        option prog     \"/etc/librenms/wlClients.sh\"\nconfig extend\n        option name     frequency-wlan0\n        option prog     \"/etc/librenms/wlFrequency.sh wlan0\"\nconfig extend\n        option name     frequency-wlan1\n        option prog     \"/etc/librenms/wlFrequency.sh wlan1\"\nconfig extend\n        option name     rate-tx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx min\"\nconfig extend\n        option name     rate-tx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx avg\"\nconfig extend\n        option name     rate-tx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx max\"\nconfig extend\n        option name     rate-tx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx min\"\nconfig extend\n        option name     rate-tx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx avg\"\nconfig extend\n        option name     rate-tx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx max\"\nconfig extend\n        option name     rate-rx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx min\"\nconfig extend\n        option name     rate-rx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx avg\"\nconfig extend\n        option name     rate-rx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx max\"\nconfig extend\n        option name     rate-rx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx min\"\nconfig extend\n        option name     rate-rx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx avg\"\nconfig extend\n        option name     rate-rx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx max\"\nconfig extend\n        option name     noise-floor-wlan0\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan0\"\nconfig extend\n        option name     noise-floor-wlan1\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan1\"\nconfig extend\n        option name     snr-wlan0-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 min\"\nconfig extend\n        option name     snr-wlan0-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 avg\"\nconfig extend\n        option name     snr-wlan0-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 max\"\nconfig extend\n        option name     snr-wlan1-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 min\"\nconfig extend\n        option name     snr-wlan1-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 avg\"\nconfig extend\n        option name     snr-wlan1-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 max\"\n

          NOTE, any of the scripts above can be tested simply by running the corresponding command.

          NOTE, to check the output data from any of these extensions, on the LibreNMS machine, run (for example),

          snmpwalk -v 2c -c public -Osqnv <openwrt-host> 'NET-SNMP-EXTEND-MIB::nsExtendOutputFull.\"frequency-wlan0\"'

          NOTE, on the LibreNMS machine, ensure that snmp-mibs-downloader is installed.

          NOTE, on the AsuswrtMerlin machine, ensure that distro is installed (i.e. that the OS is correctly detected!).

          3: Restart the snmp service on AsuswrtMerlin:

          service snmpd restart

          And then wait for discovery and polling on LibreNMS!

          "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/","title":"Carel pCOweb Devices","text":"

          The pCOWeb card is used to interface the pCO system to networks that use the HVAC protocols based on the Ethernet physical standard such as SNMP. The problem with this card is that the implementation is based on the final manufacturer of the HVAC (Heating, Ventilation and Air Conditioning) and not based on a standard given by Carel. So each pCOweb card has a different configuration that needs a different MIB depending on the manufacturers implementation.

          The main problem is that LibreNMS will by default discover this card as pCOweb and not as your real manufacturer like it should. A solution was found to bypass this issue, but it's LibreNMS independent and you need to first configure your pCOWeb through the admin interface.

          "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#accessing-the-pcoweb-card","title":"Accessing the pCOWeb card","text":"

          Log on to the configuration page of the pCOWeb card. The pCOWeb interface is not always found when accessing the ip directly but rather a subdirectory. If you cant directly reach the configuration page try <ip address>/config. The default username and password is admin/fadmin. Modern browsers require you to enter this 2 or 3 times.

          "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#configuring-the-pcoweb-card-snmp-for-librenms","title":"Configuring the pCOweb card SNMP for LibreNMS","text":"

          First you need to configure your SNMP card using the admin interface. An SNMP tab in the configuration menu leaves you the choice to choose a System OID and a Enterprise OID. This is a little tricky but based on this information we defined a \"standard\" for all implementation of Carel products with LibreNMS.

          The base Carel OID is 1.3.6.1.4.1.9839. To this OID we will add the final manufacturer Enterprise OID. You can find all enterprise OID following this link. This will allow us to create a specific support for this device. Librenms uses this value to detect which HVAC device is connected to the pCOWeb card.

          Example for the Rittal IT Chiller that uses a pCOweb card:

          1. Base Carel OID : 1.3.6.1.4.1.9839
          2. Rittal (the manufacturer) base enterprise OID : 2606
          3. Adding value to identify this device in LibreNMS : 1
          4. Complete System OID for a Rittal Chiller using a Carel pCOweb card: 1.3.6.1.4.1.9839.2606.1
          5. Use 9839 as Enterprise OID

          The way this works is that the pCOWeb card pretends to be another device. In reality the pCOWeb card just inserts the \"enterprise OID\" in place of the vendor id in the OID.

          In the table below you can find the values needed for devices which are already supported.

          "},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#supported-devices","title":"Supported devices","text":"

          LibreNMS is ready for the devices listed in this table. You only need to configure your pCOweb card with the accorded System OID and Enterprise OID:

          Manufacturer Description System OID Enterprise OID Rittal IT Chiller 1.3.6.1.4.1.9839.2606.1 9839 Rittal LCP DX 3311 1.3.6.1.4.1.9839.2606.3311 9839.2606"},{"location":"Support/Device-Notes/Carel-pCOweb-Devices/#unsupported-devices","title":"Unsupported devices","text":"

          After constructing the correct System OID for your SNMP card, you can start the LibreNMS new OS implementation and use this new OID as sysObjectID for the YAML definition file.

          "},{"location":"Support/Device-Notes/Fortigate/","title":"Fortigate","text":"

          To gather Port IP info & routing info for Fortigates, disable the append-index feature. This feature appends VDOM to the index, breaking standard MIBs.

          config system snmp sysinfo\n    set append-index disable\nend\n
          https://docs.fortinet.com/document/fortigate/7.2.0/new-features/742119/enabling-the-index-extension-7-2-8

          "},{"location":"Support/Device-Notes/Openwrt/","title":"OpenWRT","text":"

          To use Wireless Sensors on Openwrt, an agent of sorts is required. The purpose of the agent is to execute on the client (Openwrt) side, to ensure that the needed Wireless Sensor information is returned for SNMP queries (from LibreNMS).

          "},{"location":"Support/Device-Notes/Openwrt/#installation","title":"Installation","text":""},{"location":"Support/Device-Notes/Openwrt/#openwrt","title":"Openwrt","text":"

          Two items are required on the Openwrt side - scripts to generate the necessary information (for SNMP replies), and an SNMP extend configuration update (to return the information vs. the expected query).

          1: Install the scripts:

          Copy the scripts from librenms-agent repository - preferably inside /etc/librenms on Openwrt (and add this directory to /etc/sysupgrade.conf, to survive firmware updates):

          wget -O /etc/librenms/wlClients.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlClients.sh\nwget -O /etc/librenms/wlFrequency.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlFrequency.sh\nwget -O /etc/librenms/wlInterfaces.txt https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlInterfaces.txt\nwget -O /etc/librenms/wlNoiseFloor.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlNoiseFloor.sh\nwget -O /etc/librenms/wlRate.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlRate.sh\nwget -O /etc/librenms/wlSNR.sh https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/Openwrt/wlSNR.sh\nwget -O /etc/librenms/distro https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro\nchmod +x /etc/librenms/*.sh\nchmod +x /etc/librenms/distro\n

          The only file that needs to be edited is wlInterfaces.txt, which is a mapping from the wireless interfaces, to the desired display name in LibreNMS. For example,

          wlan0,wl-2.4G\nwlan1,wl-5.0G\n

          2: Update the Openwrt SNMP configuration, adding extend support for the OS detection and the Wireless Sensor queries:

          vi /etc/config/snmpd, adding the following entries (assuming the scripts are installed in /etc/librenms, and are executable), and update the network interfaces as needed to match the hardware,

          config extend\n        option name distro\n        option prog '/etc/librenms/distro'\nconfig extend\n        option name hardware\n        option prog '/bin/cat'\n        option args '/sys/firmware/devicetree/base/model'\nconfig extend\n        option name     interfaces\n        option prog     \"/bin/cat /etc/librenms/wlInterfaces.txt\"\nconfig extend\n        option name     clients-wlan0\n        option prog     \"/etc/librenms/wlClients.sh wlan0\"\nconfig extend\n        option name     clients-wlan1\n        option prog     \"/etc/librenms/wlClients.sh wlan1\"\nconfig extend\n        option name     clients-wlan\n        option prog     \"/etc/librenms/wlClients.sh\"\nconfig extend\n        option name     frequency-wlan0\n        option prog     \"/etc/librenms/wlFrequency.sh wlan0\"\nconfig extend\n        option name     frequency-wlan1\n        option prog     \"/etc/librenms/wlFrequency.sh wlan1\"\nconfig extend\n        option name     rate-tx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx min\"\nconfig extend\n        option name     rate-tx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx avg\"\nconfig extend\n        option name     rate-tx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 tx max\"\nconfig extend\n        option name     rate-tx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx min\"\nconfig extend\n        option name     rate-tx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx avg\"\nconfig extend\n        option name     rate-tx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 tx max\"\nconfig extend\n        option name     rate-rx-wlan0-min\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx min\"\nconfig extend\n        option name     rate-rx-wlan0-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx avg\"\nconfig extend\n        option name     rate-rx-wlan0-max\n        option prog     \"/etc/librenms/wlRate.sh wlan0 rx max\"\nconfig extend\n        option name     rate-rx-wlan1-min\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx min\"\nconfig extend\n        option name     rate-rx-wlan1-avg\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx avg\"\nconfig extend\n        option name     rate-rx-wlan1-max\n        option prog     \"/etc/librenms/wlRate.sh wlan1 rx max\"\nconfig extend\n        option name     noise-floor-wlan0\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan0\"\nconfig extend\n        option name     noise-floor-wlan1\n        option prog     \"/etc/librenms/wlNoiseFloor.sh wlan1\"\nconfig extend\n        option name     snr-wlan0-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 min\"\nconfig extend\n        option name     snr-wlan0-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 avg\"\nconfig extend\n        option name     snr-wlan0-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan0 max\"\nconfig extend\n        option name     snr-wlan1-min\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 min\"\nconfig extend\n        option name     snr-wlan1-avg\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 avg\"\nconfig extend\n        option name     snr-wlan1-max\n        option prog     \"/etc/librenms/wlSNR.sh wlan1 max\"\n

          NOTE, any of the scripts above can be tested simply by running the corresponding command.

          NOTE, to check the output data from any of these extensions, on the LibreNMS machine, run (for example),

          snmpwalk -v 2c -c public -Osqnv <openwrt-host> 'NET-SNMP-EXTEND-MIB::nsExtendOutputFull.\"frequency-wlan0\"'

          NOTE, on the LibreNMS machine, ensure that snmp-mibs-downloader is installed.

          NOTE, on the AsuswrtMerlin machine, ensure that distro is installed (i.e. that the OS is correctly detected!).

          3: Restart the snmp service on Openwrt:

          service snmpd restart

          And then wait for discovery and polling on LibreNMS!

          "},{"location":"Support/Device-Notes/Routeros/","title":"RouterOS","text":"

          This agent script will allow LibreNMS to run a script on a Mikrotik / RouterOS device to gather the vlan information from both /interface/vlan/ and /interface/bridge/vlan/

          "},{"location":"Support/Device-Notes/Routeros/#installation","title":"Installation","text":"
          • Go to https://github.com/librenms/librenms-agent/tree/master/snmp/Routeros
          • Copy and paste the contents of LNMS_vlans.scr file into a script within a RouterOS device. Name this script LNMS_vlans. (This is NOT the same thing as creating a txt file and importing it into the Files section of the device)
          • If you're unsure how to create the script. Download the LNMS_vlans.scr file. Rename to remove the .scr extension. Copy this file onto all the Mikrotik devices you want to monitor.
          • Open a Terminal / CLI on each tik and run this. { :global txtContent [/file get LNMS_vlans contents]; /system/script/add name=LNMS_vlans owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=$txtContent ;} This will import the contents of that txt file into a script named LNMS_vlans
          • Enable an SNMP community that has both READ and WRITE capabilities. This is important, otherwise, LibreNMS will not be able to run the above script. It is recommended to use SNMP v3 for this.
          • Discover / Force rediscover your Mikrotik devices. After discovery has been completed the vlans menu should appear within LibreNMS for the device.
          "},{"location":"Support/Device-Notes/Routeros/#important-note","title":"*** IMPORTANT NOTE ***","text":"

          It is strongly recommended that SNMP service only be allowed to be communicated on a very limited set of IP addresses that LibreNMS and related systems will be coming from. (usually /32 address for each) because the write permission could allow an attack on a device. (such as dropping all firewall filters or changing the admin credentials)

          "},{"location":"Support/Device-Notes/Routeros/#theory-of-operation","title":"Theory of operation:","text":"

          Mikrotik vlan discovery plugin using the ability of ROS to \"fire up\" a script through SNMP.

          At first, LibreNMS check for the existence of the script, and if it is present, it will start the LNMS_vlans script.

          The script will gather information from: - /interface/bridge/vlan for tagged ports inside bridge - /interface/bridge/vlan for currently untagged ports inside bridge - /interface/bridge/port for ports PVID (untagged) inside bridge - /interface/vlan for vlan interfaces

          after the information is gathered, it is transmitted to LibreNMS over SNMP

          protocol is: type,vlanId,ifName

          i.e: T,254,ether1 is translated to Tagged vlan 254 on port ether1

          U,100,wlan2 is translated to Untagged vlan 100 on port wlan2

          "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 418fdf0d..f7f8b9ee 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,657 +2,657 @@ https://docs.librenms.org/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/ARP/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Alerts/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Bills/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/DeviceGroups/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Devices/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Inventory/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Locations/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Logs/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/PollerGroups/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/PortGroups/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Port_Groups/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Ports/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Routing/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Services/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/Switching/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/API/System/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Creating-Transport/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Device-Dependencies/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Entities/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Macros/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Rules/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Templates/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Testing/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Alerting/Transports/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Application-Notes/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Code-Structure/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Creating-Documentation/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Creating-Release/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Dynamic-Config/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Getting-Started/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Merging-Pull-Requests/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/SNMP-Traps/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Sensor-State-Support/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Support-New-OS/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Using-Git/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/Validating-Code/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Custom-Graphs/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Health-Information/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Initial-Detection/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Mem-CPU-Information/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Settings/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Test-Units/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Developing/os/Wireless-Sensors/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Agent-Setup/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Applications/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Authentication/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Auto-Discovery/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Availability-Map/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Billing-Module/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Component/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Custom-Map/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Customizing-the-Web-UI/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Dashboards/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Dell-OpenManage/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Dependency-Map/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Device-Groups/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Dispatcher-Service/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Distributed-Poller/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Fast-Ping-Check/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Galera-Cluster/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Gateone/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Graylog/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/IRC-Bot-Extensions/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/IRC-Bot/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Interface-Description-Parsing/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Metric-Storage/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/NFSen/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Network-Map/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/OAuth-SAML/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Oxidized/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/PeeringDB/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Plugin-System/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Proxmox/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/RRDCached/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/RRDTune/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Rancid/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/SNMP-Proxy/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/SNMP-Trap-Handler/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Services/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Smokeping/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Sub-Directory/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Supermicro/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Syslog/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Two-Factor-Auth/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Varnish/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/VisJS-Config/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/Weathermap/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/World-Map/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/metrics/Graphite/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/metrics/InfluxDB/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/metrics/InfluxDBv2/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/metrics/OpenTSDB/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Extensions/metrics/Prometheus/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Acknowledgement/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Callback-Stats-and-Privacy/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Changelog/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Releases/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Security/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Updating/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/General/Welcome-to-Observium-users/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Installation/Docker/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Installation/Images/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Installation/Install-LibreNMS/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Installation/Migrating-from-Observium/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/1-Minute-Polling/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Adding-a-Device/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Bare-Dashboard/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/CLI-Tools/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Cleanup-options/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Configuration/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Sensors/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Troubleshooting/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Discovery%20Support/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Environment-Variables/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Example-Hardware-Setup/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/FAQ/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Features/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Install%20Validation/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Performance/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Poller%20Support/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Remote-Monitoring-VPN/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/SNMP-Configuration-Examples/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Notes/AsuswrtMerlin/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Notes/Carel-pCOweb-Devices/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Notes/Fortigate/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Notes/Openwrt/ - 2024-08-30 + 2024-09-03 daily https://docs.librenms.org/Support/Device-Notes/Routeros/ - 2024-08-30 + 2024-09-03 daily \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 0cb58c9cf0f577ca12558694217c846793362992..1334938d8e653a9c215f0a5dba34b8bb2e2eaf9c 100644 GIT binary patch delta 86 zcmV-c0IC0(3z-WCABzYGfKk?w2O$A;kts?p_w&!UAFhK{j{I4CSi76^%KPSz!CBKzd5+P_;it>Faq+|vD3Z;2nq4(Pj^=U0OcDhQUCw| delta 86 zcmV-c0IC0(3z-WCABzYGfD6%)2O$A$kts?p)A{Gy57)seNB%56tliCd<$d$VV6fS2 sE}ZmK^Tu5mTMnG4;ukmA-yB?C{C<(4Fap=hvD3Z;2q4|sn|D_L0Gy*J!~g&Q