一个轻量的内网设备信息采集与查询系统:客户端开机自动上报本机 MAC/IP/序列号,服务端集中存储,浏览器随时模糊查询。
运维多台服务器/终端时,经常遇到这些麻烦:
- "这台机器的 MAC 是多少?":要登录每台机器敲命令查,机器一多根本跑不过来
- IP 与 MAC 对应关系靠 Excel 手工维护:换了网卡、重装系统就失效,台账永远是过期的
- 设备序列号报修时找不到:翻箱倒柜找采购记录,尤其物理机的 SN 码
- 机器重装/开机没人管:采集一次性的,设备信息变了无人知晓
本项目的答案是:让每台机器开机时自动"报到",信息集中入库,查询页一搜即得——无需商业 CMDB、无需 agent 常驻进程,一个脚本 + 一个网页搞定。
| 功能 | 说明 |
|---|---|
| 📡 开机自动上报 | 客户端 systemd 服务,开机自动采集并上报,无需人工干预 |
| 🖥 信息采集全面 | MAC 地址、IP、主机名、主板/系统序列号(物理机)、网卡厂商 |
| 🔍 模糊查询 | 按 MAC / IP / 序列号任意片段模糊搜索 |
| 📋 最近记录 | 查询页默认展示最近 10 条上报记录 |
| ♻️ 去重更新 | 按 MAC 唯一约束,重复上报自动更新而非堆叠数据 |
| 🕗 时区处理 | 前端自动将 UTC 转为北京时间(UTC+8)显示 |
| 🧩 部署极简 | 客户端仅 1 个脚本 + 1 个 service;服务端 Node.js + MySQL + Nginx |
详细的分步部署手册见 DEPLOY.md,此处为概览。
客户端 (CentOS) 服务端 (CentOS)
┌──────────────┐ ┌──────────────────────────────────┐
│ mac-report.sh │──POST /api/──▶ │ Nginx (:8000) │
│ (开机自启) │ │ ├─ 静态页面 (mac-query.html) │
└──────────────┘ │ └─ /api/ → Node.js (:3000) │
浏览器 ─────────────────────────▶ │ └─ MySQL (mac_query) │
└──────────────────────────────────┘
# 1. 安装 MySQL 8 并初始化(建库 mac_query、建表 mac_records,SQL 见 DEPLOY.md)
# 2. 安装 Node.js 18
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash - && yum install -y nodejs
# 3. 部署后端
mkdir -p /opt/mac-query && cd /opt/mac-query
# 上传 mac-query.html 和 server.js,然后:
npm init -y && npm install express mysql2
# 编辑 server.js,填入数据库密码
# 4. 配置 systemd 服务(mac-query.service)+ Nginx 站点(:8000),详见 DEPLOY.md# 1. 上传脚本
cp mac-report.sh /usr/local/bin/ && chmod +x /usr/local/bin/mac-report.sh
# 2. 编辑脚本,把 SERVER 改为服务端地址
SERVER="http://<服务端IP>:8000"
# 3. 配置 systemd 开机自启(mac-report.service),详见 DEPLOY.md
systemctl daemon-reload && systemctl enable mac-reportcurl http://<服务端IP>:8000/api/records # 返回 JSON 数组即正常
# 浏览器打开 http://<服务端IP>:8000 应看到查询页面- 浏览器打开
http://<服务端IP>:8000 - 在搜索框输入任意片段:
- MAC:
00:1A或001A - IP:
192.168.1 - 序列号:
SN2026
- MAC:
- 结果实时展示:MAC、IP、主机名、序列号、状态、获取时间
- 不输入直接查询 / 打开页面时,默认显示最近 10 条上报记录
/usr/local/bin/mac-report.sh
# 预期输出:
# [mac-report] Reporting: iface=eth0 mac=XX:XX:XX:XX:XX:XX ip=192.168.x.x ...
# [mac-report] Success (HTTP 200)| status | 含义 |
|---|---|
| online | 正常上报中 |
| offline | 暂时未上报 |
| expired | 长期未上报,视为过期 |
页面查询:搜索框输入 192.168.1,返回该网段所有设备:
┌───────────────────┬──────────────┬──────────┬──────────────┬────────┬───────────────────┐
│ MAC │ IP │ 主机名 │ 序列号 │ 状态 │ 获取时间 │
├───────────────────┼──────────────┼──────────┼──────────────┼────────┼───────────────────┤
│ 52:54:00:12:34:56 │ 192.168.1.11 │ web-01 │ │ online │ 2026-08-06 09:12 │
│ 52:54:00:AB:CD:EF │ 192.168.1.22 │ db-01 │ │ online │ 2026-08-06 09:15 │
│ 00:1A:4B:3C:2D:1E │ 192.168.1.35 │ storage1 │ SN2026031501 │ online │ 2026-08-06 09:10 │
└───────────────────┴──────────────┴──────────┴──────────────┴────────┴───────────────────┘
客户端上报输出:
[mac-report] Reporting: iface=eth0 mac=52:54:00:12:34:56 ip=192.168.1.11 hostname=web-01
[mac-report] Success (HTTP 200)
API 直接调用:
curl "http://<服务端IP>:8000/api/search?q=001A"
# [{"id":3,"mac":"00:1A:4B:3C:2D:1E","ip":"192.168.1.35","hostname":"storage1", ...}]💡 小技巧:同一 MAC 重复上报会更新原记录(IP、时间为最新值),所以设备换 IP 后下次开机查询页自动刷新。
mac-query/
├── mac-query.html # 查询页面(服务端)
├── server.js # 后端 API:Express + MySQL(服务端)
├── mac-report.sh # 采集上报脚本(客户端)
├── mac-report.service # 客户端 systemd 开机自启服务
├── DEPLOY.md # 详细部署手册
├── LICENSE # MIT 许可证
└── README.md # 本说明
- 后端启动报
ER_ACCESS_DENIED_ERROR:检查 server.js 数据库密码,确认 root 支持 TCP 连接(mysql -h 127.0.0.1 -u root -p) - 客户端上报失败 (HTTP 000):检查网络连通性、防火墙 8000 端口、SELinux(
setsebool -P httpd_can_network_connect 1) - 序列号为空:虚拟机无 DMI 信息属正常现象,脚本已做兜底,不影响其他字段
- 时间显示不对:前端已做 UTC→UTC+8 转换;客户端上报时间格式应为
YYYY-MM-DD HH:MM:SS
更多问题见 DEPLOY.md 的常见问题章节。
本项目基于 MIT License 开源,可自由使用、修改和分发。