This guide assumes that you have a functioning Oxidized installation. If you don’t you can head over to Part 1 and go back here when finished.
It’s time to connect Oxidized to LibreNMS so it can pull a device list instead of manually defining it in the router.db csv file. The guide below is just a summary of the things that was useful to me in my setup and written as I understood it.
For the latest, and most accurate guide, head over to the LibreNMS Documentation.
Table of Contents
Getting an API token
Go to Settings -> API Settings
Then click on the Create API access token, assign it to the appropriate user and take a note of the token.
LibreNMS config
This section is technically optional, although you probably want to read it to know what’s available.
Groups
In some cases you need to authenticate to different types of devices with different set of credentials. For instance, if you are using TACACS for routers/switches, LDAP authentication for loadbalancers and local authentication to a Wifi controller you need groups.
To configure groups we have to this we have to add some lines to the LibreNMS config.php file. Below is a made-up example with a few groups.
# Enable Oxidized support in the LibreNMS GUI
$config['oxidized']['enabled'] = TRUE;
# Tell LibreNMS where to fetch the configuration from
$config['oxidized']['url'] = 'http://127.0.0.1:8888';
# Enable groups
$config['oxidized']['group_support'] = true;
# Default group
$config['oxidized']['default_group'] = 'Other';
# Recommended if using Git for storing the configuration
$config['oxidized']['features']['versioning'] = true;
# Tell LibreNMS to tell Oxidized to update the device list when new devices has been added
$config['oxidized']['reload_nodes'] = true;
# Add WIFI-CONTROLLER-01 to the group Wifi controllers
$config['oxidized']['maps']['group']['hostname'][] = array('regex' => '/^WIFI-CONTROLLER-01$/i', 'group' => 'WIFI-controllers');
# Add ie. PROD-LB-01 to the group Production-LBs
$config['oxidized']['maps']['group']['hostname'][] = array('regex' => '/^PROD-LB-[0-9]+$/i', 'group' => 'Production-LBs');
# Add anything starting with PROD- to the group Production
$config['oxidized']['maps']['group']['hostname'][] = array('regex' => '/^PROD-/i', 'group' => 'Production');
Worth noting is that group are assigned using first match. So the default catch at the bottom will only assign Production in case the any of the patterns above does not match. If no pattern match the default group is assigned.
Ignore hosts
LibreNMS can omit certain types and OS:es by adding a few lines to the configuration. The example below ignores device of the types server and power and devices with an OS of aruba-instant, apc, hpe-rtups and linux.
$config['oxidized']['ignore_types'] = array('server','power');
$config['oxidized']['ignore_os'] = array('aruba-instant','apc','hpe-rtups','linux');
Verify the configuration
Before you start with the Oxidized configuration it might be a good idea to verify the LibreNMS configuration. You can do this with the help of curl:
curl -H 'X-Auth-Token: YOURAPITOKENHERE' http://localhost:8080/api/v0/oxidized
Note that you need to replace localhost and the port with whatever your LibreNMS instance is listening on. If running this on a vanilla LibreNMS server though the command above should work. Just remember to use your token.
[
{
"hostname": "PROD-LB-01",
"os": "f5",
"ip": "10.0.0.1",
"group": "Production-LBs"
},
{
"hostname": "PROD-ROUTER-01",
"os": "eos",
"ip": "10.1.1.1",
"group": "Production"
}
]
Look through the list and if you’re happy with the result, move on to the Oxidized configuration below.
Oxidized configuration
If you’ve followed Part 1 you should have an Oxidized installation with a functioning GitHub integration.
Groups
This is where we tie the group configuration we did above to a specific set of credentials:
groups:
WIFI-controllers:
username: localaccount
password: supersecretpassword
Production-LBs:
username: ldap-user
password: password
Production:
username: tacacs-user
password: yetanotherpassword
LibreNMS info
First you want to remove the old source configuration. Delete the following lines or prefix each line with # to comment it out:
source:
default: csv
csv:
file: "/root/.config/oxidized/router.db"
delimiter: !ruby/regexp /:/
map:
name: 0
model: 1
gpg: false
In order for Oxidized to be able to pull the device list from LibreNMS we need to tell Oxidized where the LibreNMS API is listening and which API token to authenticate with. Below is an example when Oxidized is running on the same machine as LibreNMS. Insert the following lines where your old source used to be:
source:
default: http
debug: false
http:
url: http://127.0.0.1:8080/api/v0/oxidized
map:
name: hostname
model: os
group: group
headers:
X-Auth-Token: 'YOURTOKEN'
Final configuration
Below is a final configuration example that worked for me:
---
username: xx
password: xx
resolve_dns: true
interval: 7200
use_syslog: false
debug: true
threads: 30
timeout: 20
retries: 3
prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
rest: 127.0.0.1:8888
next_adds_job: false
vars:
auth_methods: ["none", "publickey", "password", "keyboard-interactive"]
remove_secret: true
ssh_keys: "/root/.config/oxidized/.ssh/id_rsa.pem"
groups:
WIFI-controllers:
username: localaccount
password: supersecretpassword
Production-LBs:
username: ldap-user
password: password
Production:
username: tacacs-user
password: yetanotherpassword
models: {}
pid: "/root/.config/oxidized/pid"
crash:
directory: "/root/.config/oxidized/crashes"
hostnames: false
stats:
history_size: 10
input:
default: ssh, telnet
debug: true
ssh:
secure: false
utf8_encoded: true
output:
default: git
file:
directory: "/root/.config/oxidized/gitrepo"
git:
single_repo: true
user: Oxidized
email: oxidized@domain.com
repo: "/root/.config/oxidized/gitrepo/oxidized.git"
hooks:
push_to_remote:
type: githubrepo
events: [post_store]
remote_repo: "git@github.com:my-repo/oxidized.git"
publickey: "/root/.config/oxidized/.ssh/id_rsa.pub"
privatekey: "/root/.config/oxidized/.ssh/id_rsa.pem"
publickey: "/root/.config/oxidized/.ssh/id_rsa.pub"
privatekey: "/root/.config/oxidized/.ssh/id_rsa.pem"
source:
default: http
debug: false
http:
url: http://127.0.0.1:8080/api/v0/oxidized
map:
name: hostname
model: os
group: group
headers:
X-Auth-Token: 'YOURTOKEN'
model_map:
juniper: junos
cisco: ios
f5: tmos
arista: eos
fortigate: fortios
Final thoughts
This has been super useful for us as a team. It’s possible to roll back the state of a classic network infrastructure by storing the configuration changes in Git. Of course, doing this with GitOps would be better as it comes with more granularity and audit logging but I reckon this is as close as it gets if not going down that road.
Did the guide help you? Did I miss anything important or make a mistake when writing it? Feel free to leave a comment below.
How did you protect your oxidized api/web port 8888?
I am stuck mentally getting this protected with the docker mode and would love to know what you did.
Sorry for the late reply. I guess I didn’t. Ran it with network=host. Suppose one could put them on the same docker network though.
Hello,
How do you store the backed up configs with the system name instead of the ip address?
Hi there!
Not sure tbh, have you tried adding the hostname instead of IP in the config?