用 Oxidized 自动备份网络设备配置文件
网络设备的配置备份,最怕的不是“没有工具”,而是设备数量慢慢变多以后,备份动作开始依赖人工记忆:有人改了交换机配置却忘了留档,有人调了防火墙策略却没有版本记录,真到回滚和排障的时候,才发现手上没有一份可信的基线。
Oxidized 这类工具的价值,就在于把这件事做成一条自动化流水线:定时登录设备、抓取 running-config、检测变更、写入 Git 仓库,并通过 Web 界面或 API 做统一查看。对中小规模网络来说,它足够轻,落地成本也很低。
这篇文章整理一套比较稳的部署方式:基于 Ubuntu 22.04,使用 systemd 托管 Oxidized,配置 Git 作为版本后端,再通过 Nginx 做反向代理和密码登录加固。文中默认采用最常见的 router.db 方式管理设备清单,同时补一段可选的 LibreNMS 集成思路。
部署思路
整套链路可以先收成四个角色:
- Oxidized 负责登录网络设备并抓取配置。
- Git 仓库负责保存配置历史和差异。
- systemd 负责把服务稳定跑起来并开机自启。
- Nginx 负责把 Web 界面和 REST API 放在反向代理后面,并补上访问控制。
落地时建议优先遵循这几个原则:
- 不要用
root运行 Oxidized,单独建服务用户。 - 不要把 Oxidized 的
rest端口直接暴露到公网。 - 尽量给设备创建只读备份账号,而不是复用高权限运维账号。
- 配置仓库用 Git 保存,后续再同步到异机或远端代码仓库。
一、安装依赖与程序
官方 README 给出的 Debian 安装方式,是先装 Ruby 及依赖,再通过 gem 安装 oxidized、oxidized-script 和 oxidized-web。在 Ubuntu 22.04 上可以直接沿用这条路径。
sudo apt-get update
sudo apt-get install -y ruby ruby-dev libsqlite3-dev libssl-dev pkg-config cmake libssh2-1-dev git nginx apache2-utils
sudo gem install oxidized
sudo gem install oxidized-script oxidized-web
安装完成后先确认命令可用:
oxidized --version
oxidized-script -h
二、创建专用用户与工作目录
官方文档明确建议不要用 root 运行 Oxidized,而是单独创建一个服务用户。这样做的好处很直接:最小权限、目录边界清晰、systemd 托管也更干净。
sudo useradd -r -m -d /home/oxidized -s /usr/sbin/nologin oxidized
sudo mkdir -p /etc/oxidized
sudo mkdir -p /var/lib/oxidized/git-repos
sudo chown -R oxidized:oxidized /etc/oxidized /var/lib/oxidized /home/oxidized
这里我更倾向把配置文件统一放在 /etc/oxidized,把 Git 仓库放在 /var/lib/oxidized。后面做备份、迁移和权限审计时会更省心。
三、准备设备清单
Oxidized 支持 CSV、SQLite 和 HTTP 多种来源。最容易上手的仍然是 router.db,一台设备一行,先把自动备份跑起来,再决定要不要切到 LibreNMS API。
先创建设备清单:
sudo -u oxidized tee /etc/oxidized/router.db > /dev/null <<'EOF'
core-sw-01:ios:backupuser:StrongPassword
edge-fw-01:panos:backupuser:StrongPassword
dist-sw-01:nxos:backupuser:StrongPassword
EOF
格式是:
hostname:model:username:password
这里有两个落地建议很值得一开始就做:
- 设备账号尽量使用只读账号,权限只覆盖
show running-config、show version一类查询动作。 - 如果不同厂商或不同区域用不同凭据,后续可以再引入 group 机制,不必一开始就把所有账号揉在一起。
四、编写主配置文件
下面这份配置比较适合作为生产起步版本:轮询间隔按小时级设置,启用 Web/API,输出采用 Git,输入以 router.db 为主。
---
username: backupuser
password: StrongPassword
model: ios
interval: 3600
log: /var/log/oxidized
use_syslog: false
debug: false
threads: 20
timeout: 20
retries: 3
prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
rest: 127.0.0.1:8888
pid: /run/oxidized/oxidized.pid
input:
default: ssh, telnet
debug: false
ssh:
secure: true
output:
default: git
git:
user: Oxidized
email: oxidized@example.com
repo: /var/lib/oxidized/git-repos/default.git
source:
default: csv
csv:
file: /etc/oxidized/router.db
delimiter: !ruby/regexp /:/
map:
name: 0
model: 1
username: 2
password: 3
model_map:
cisco: ios
juniper: junos
写入配置文件:
sudo mkdir -p /var/log/oxidized /run/oxidized
sudo chown -R oxidized:oxidized /var/log/oxidized /run/oxidized
sudo nano /etc/oxidized/config
这份配置里有几个点值得单独说一下:
rest: 127.0.0.1:8888只监听本机,目的是把 Web 和 API 收在内网回环地址,后续统一交给 Nginx 暴露。output.default: git是最推荐的方式,配置变更会自动形成版本历史,回看和 diff 都方便。threads、timeout、interval这三个值不要一开始拉太激进,先以“稳定跑通”为第一目标。
如果你的设备凭据并不统一,也可以把全局 username 和 password 留作默认值,真正的设备账号从 router.db 按行覆盖。
五、使用 systemd 托管服务
生产环境不建议直接在 shell 里前台运行。最稳的方式还是交给 systemd 管理,重启、日志和开机自启都更清晰。
创建服务文件:
sudo nano /etc/systemd/system/oxidized.service
内容如下:
[Unit]
Description=Oxidized Network Configuration Backup
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=oxidized
Group=oxidized
Environment=OXIDIZED_HOME=/etc/oxidized
ExecStart=/usr/local/bin/oxidized
Restart=on-failure
RestartSec=5
WorkingDirectory=/home/oxidized
[Install]
WantedBy=multi-user.target
加载并启动:
sudo systemctl daemon-reload
sudo systemctl enable --now oxidized
sudo systemctl status oxidized
常用排错命令:
sudo journalctl -u oxidized -f
sudo -u oxidized OXIDIZED_HOME=/etc/oxidized oxidized --debug
六、验证自动备份是否生效
Oxidized 启动后,可以先从三个角度检查它是否真的在工作。
先看 Web/API 是否起来:
curl http://127.0.0.1:8888/nodes
再看 Git 仓库里有没有提交:
sudo -u oxidized git --git-dir /var/lib/oxidized/git-repos/default.git log --oneline --all
如果想立即把某台设备提到队列前面执行抓取,可以调用 REST API:
curl -X POST http://127.0.0.1:8888/node/next/core-sw-01
这一步很适合做验收:手工改一条测试配置,再看 Git 里是否出现新的 commit 和 diff。
七、可选加固:用 Nginx 反向代理并加密码登录
官方文档说明 Oxidized 的 Web 和 REST 接口由 rest 参数启用;而 Nginx 官方文档则建议把反向代理放在前面,统一处理请求转发和头部控制。真正落地时,我不建议把 8888 端口直接暴露出去,而是至少做两层收口:
- 只让 Oxidized 监听
127.0.0.1。 - 外部访问统一走 Nginx,再补上 HTTPS、Basic Auth 和来源 IP 限制。
先创建密码文件:
sudo htpasswd -c /etc/nginx/.htpasswd oxidizedadmin
然后创建站点配置:
sudo nano /etc/nginx/conf.d/oxidized.conf
server {
listen 443 ssl http2;
server_name oxidized.example.com;
ssl_certificate /etc/ssl/certs/your-fullchain.pem;
ssl_certificate_key /etc/ssl/private/your-privkey.pem;
auth_basic "Oxidized Login";
auth_basic_user_file /etc/nginx/.htpasswd;
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
检查并重载 Nginx:
sudo nginx -t
sudo systemctl reload nginx
这里要强调一个边界:Basic Auth 适合做内网管理入口的第一层门禁,但它本身并不等于强认证。Nginx 官方文档也专门提醒过,Basic Auth 的凭据只是 base64 编码,因此务必要和 HTTPS 一起使用;如果你后面要做更强的身份体系,可以继续往 OIDC 或统一 SSO 走。
八、可选进阶:接 LibreNMS 自动喂设备清单
如果你的设备资产已经在 LibreNMS 里维护,后面可以把 source 从 CSV 切到 HTTP,让 LibreNMS API 负责把设备列表送给 Oxidized。这样新增设备时,不用再手动改 router.db。
LibreNMS 文档给出的思路是让 Oxidized 从 API 拉取主机名、OS 和分组,典型配置如下:
source:
default: http
http:
url: https://librenms.example.com/api/v0/oxidized
map:
name: hostname
model: os
group: group
headers:
X-Auth-Token: 'YOUR_TOKEN'
这种方式更适合设备量已经上来、并且希望监控系统和配置备份共用一份资产清单的环境。只是要注意,LibreNMS 负责喂清单,不负责把设备登录密码下发给 Oxidized,凭据仍然需要你在 Oxidized 侧管理。
九、日常运维建议
把服务跑起来只是第一步,真正长期稳定靠的是下面这几条细节:
- 优先走管理网或 OOB 网络访问设备,避免把生产业务网当作配置抓取通道。
- 给 Oxidized 单独开一个只读账号,尽量不要复用日常变更账号。
- Git 仓库最好继续异机备份,例如再同步到另一台 Linux 或私有 Git 服务。
- 对外只开放 Nginx 入口,不直接暴露 Oxidized 原生端口。
- 上线初期先挑一小批设备做试点,先看 prompt 识别和型号映射,再扩大范围。
如果你还想继续往前走,Oxidized 自带 hooks 机制,可以在配置变更后执行脚本、推送远端 Git 仓库,甚至把变更事件打进别的系统里。对规模稍大的网络团队来说,这一步很适合接入告警和审计链路。
结语
Oxidized 的优势,不是界面多华丽,而是它把“设备配置备份”这件事做得足够简单、足够可追溯。设备清单清楚、账号权限收好、Git 仓库留痕,再配一层 Nginx 把入口收住,这套方案就已经能覆盖大多数中小网络环境的自动备份需求。
如果你当前网络里还没有一套稳定的配置归档机制,那最值得先做的,往往不是追求复杂平台,而是先把 Oxidized 这样的基础设施跑起来。很多时候,真正救命的就是那一份昨天自动留下来的 running-config。