Oxidized pulls running-config from network devices (switches, routers, firewalls) and stores versioned backups, usually in a local git repo. Target: Ubuntu 24.04 LTS VPS, 1 vCPU / 1GB RAM is enough for a fleet under a few hundred devices.
1. Base packages
apt update && apt -y upgrade
apt -y install ruby ruby-dev build-essential git libsqlite3-dev pkg-config \
libssl-dev nginxCheck ruby version — Oxidized needs >= 2.7:
ruby -v2. Create a dedicated user
useradd -m -s /bin/bash oxidized
su - oxidizedEverything below (until noted) runs as the oxidized user.
3. Install Oxidized gem
gem install --no-document oxidized oxidized-weboxidized-web gives you the built-in web UI on port 8888.
4. Directory layout
mkdir -p ~/.config/oxidized5. Config file
~/.config/oxidized/config:
username: oxidized_ro
password: CHANGE_ME
model: junos
interval: 3600
use_syslog: false
debug: false
threads: 30
timeout: 20
retries: 3
prompt: !ruby/regexp /^([\w.@-]+[#>]\s*)$/
rest: 127.0.0.1:8888
vars:
enable: CHANGE_ME_ENABLE_SECRET # for Cisco enable mode if needed
groups: {}
models:
cisco_ios:
junos:
arista_eos:
fortios:
pid: "/home/oxidized/.config/oxidized/pid"
input:
default: ssh, telnet
debug: false
ssh:
secure: false
output:
default: git
git:
user: Oxidized
email: oxidized@ramnode.internal
repo: "/home/oxidized/.config/oxidized/oxidized.git"
source:
default: csv
csv:
file: "/home/oxidized/.config/oxidized/router.db"
delimiter: !ruby/regexp /:/
map:
name: 0
model: 1
username: 2
password: 3Adjust secure: false under SSH only if you need to allow older/weaker ciphers for legacy
switches — otherwise leave it enabled.
6. Device inventory (router.db)
~/.config/oxidized/router.db:
switch1.ramnode.internal:ios:oxidized_ro:CHANGE_ME
core-router.ramnode.internal:junos:oxidized_ro:CHANGE_ME
edge-fw.ramnode.internal:fortios:oxidized_ro:CHANGE_MEFormat is name:model:username:password (matches the map: in config). For larger fleets, switch
the source to sql or write a small script pulling from phpIPAM/NetBox via API instead of hand-editing
this file.
7. First run (foreground, to validate)
oxidizedConfirm it connects to a test device, pulls config, and commits to the git repo at
~/.config/oxidized/oxidized.git.
8. systemd service
Back to root:
exit/etc/systemd/system/oxidized.service:
[Unit]
Description=Oxidized network config backup
After=network.target
[Service]
Type=simple
User=oxidized
Group=oxidized
ExecStart=/usr/local/bin/oxidized
Restart=on-failure
RestartSec=5
WorkingDirectory=/home/oxidized
[Install]
WantedBy=multi-user.targetFind the actual gem binary path first if /usr/local/bin/oxidized doesn't exist:
su - oxidized -c 'which oxidized'Use whatever path that returns in the ExecStart line.
systemctl daemon-reload
systemctl enable --now oxidized
systemctl status oxidized9. Reverse proxy for the web UI
/etc/nginx/sites-available/oxidized:
server {
listen 80;
server_name oxidized.example.com;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}ln -s /etc/nginx/sites-available/oxidized /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d oxidized.example.comLock this down further — the web UI has no built-in auth. Either put HTTP basic auth in nginx or bind it to your internal/jump network only:
allow 10.0.0.0/8;
deny all;Or with basic auth:
apt -y install apache2-utils
htpasswd -c /etc/nginx/.oxidized-htpasswd adminlocation / {
auth_basic "Oxidized";
auth_basic_user_file /etc/nginx/.oxidized-htpasswd;
proxy_pass http://127.0.0.1:8888;
}10. Verifying backups
cd /home/oxidized/.config/oxidized/oxidized.git
git log --oneline
git show HEAD:switch1.ramnode.internal11. Nagios/NRPE integration idea
Since you're already running Nagios 4 across the fleet, a simple check script comparing
git log -1 --format=%ct <device> against interval catches devices that have stopped
checking in (stale creds, ACL change, device down for scraping).
Post-install checklist
- Restrict web UI (basic auth or IP allowlist — no built-in auth)
- Use a read-only account on every device, not admin/enable creds where avoidable
- Rotate
router.dbcredentials out of plaintext — consideroxidized-source-sqlbacked by a credentials vault instead of the flat CSV for anything beyond a lab - Confirm SSH host key checking behavior matches your security posture (default trusts on first use)
