WatchYourLAN 部署指南:Docker 一条命令跑起局域网 IP 扫描,附配置清单与 VLAN 扫描实操
【免费下载链接】WatchYourLANLightweight network IP scanner written in Go. With notifications, history, export to Grafana项目地址: https://gitcode.com/GitHub_Trending/wa/WatchYourLAN
WatchYourLAN 是一个用 Go 编写的轻量级局域网 IP 扫描器,靠arp-scan持续发现主机、记录在线/离线历史、发现未知主机时推送通知,并支持将数据导出到 InfluxDB2 / Prometheus 供 Grafana 消费。本文覆盖 Docker 与 Linux 二进制安装、三类配置方式、VLAN/多网段扫描、认证方案与 HTTP API 集成,并给出避坑清单。
项目速览:它替你盯什么
- 新主机通知:扫描到未知 MAC 时经 Shoutrrr 推送(Discord、Email、Gotify、Matrix、Ntfy、Pushover、Slack、Telegram、Generic Webhook 等)
- 在线/离线历史:每次扫描对每台主机落一条历史快照,按
TRIM_HIST自动清理 - 全网主机清单:维护 IP、MAC、厂商、接口、名称(含 DNS 解析名)、Known 状态
- Grafana 数据出口:写 InfluxDB2 行协议,或暴露 Prometheus
watch_your_lan_up指标 - 轻量部署:单 Go 二进制 + 一个
arp-scan依赖,无其他运行时依赖
启动链路见 backend/cmd/WatchYourLAN/main.go:conf.Start读配置 →gdb.Start连库建表 → 两个协程ScanRestart(周期扫描)与HistoryTrim(历史裁剪)→web.Gui起 Web 界面(默认:8840)。数据库默认 SQLite(scan.db),表now(当前清单)+history(历史),GORMAutoMigrate自动建表。
最快上手:Docker 一条命令
docker run --name wyl \ -e "IFACES=$YOURIFACE" \ -e "TZ=$YOURTIMEZONE" \ --network="host" \ -v $DOCKERDATAPATH/wyl:/data/WatchYourLAN \ aceberg/watchyourlan| 参数 | 作用 | 默认值 | 备注 |
|---|---|---|---|
IFACES | 要扫描的网口,空格分隔多个 | 空 | 必填,用ip link show查看;漏配则一轮扫描都不执行 |
TZ | 时区 | 空 | 必填,否则历史记录时间不准 |
--network="host" | 使用宿主机网络 | bridge | 必须,arp-scan要在宿主网络栈收发 ARP 包 |
-v ...:/data/WatchYourLAN | 数据卷 | 无 | 配置config_v2.yaml与scan.db都落在这里 |
| 镜像 | 官方镜像 | latest | aceberg/watchyourlan |
验证:访问http://localhost:8840(容器默认HOST=0.0.0.0、PORT=8840)。等一个扫描周期(默认 120 秒)后,Home 页面出现主机列表即为成功;也可用 API 快速确认:
curl -s http://localhost:8840/api/all curl -s "http://localhost:8840/api/status/"偏好 compose 的话,仓库自带 docker-compose.yml,写法与上面等价,并预留了注释掉的node-bootstrap服务(离线资源,见后文)。
不装 Docker 时:从 release 下载二进制包,支持.deb、.rpm、.apk(Alpine)与.tar.gz;架构覆盖amd64、i386、arm_v5、arm_v6、arm_v7、arm64。运行时依赖两个系统包:arp-scan和tzdata;amd64另有.debapt 源可跟随更新。
配置全景:哪些项必须改
配置三选一:环境变量、config_v2.yaml(数据目录内)、Web GUI。底层统一走 Viper:先设默认值,再读 YAML,最后AutomaticEnv()让环境变量覆盖(backend/internal/conf/read.go)。配置文件键名与环境变量同名但全小写(TIMEOUT↔timeout)。
基础配置
| 变量 | 说明 | 默认值 | 备注 |
|---|---|---|---|
TZ | 时区 | 空 | 必填 |
HOST/PORT | Web 监听地址/端口 | 0.0.0.0/8840 | 改端口记得同步防火墙 |
THEME/COLOR | 主题(bootswatch 主题小写名)/ 背景色 | sand/dark | |
LOG_LEVEL | 日志级别 | info | 排错时开debug可看到实际arp-scan命令 |
NODEPATH | 本地 node modules 地址 | 空 | 离线模式用,见进阶场景 |
SHOUTRRR_URL | 通知渠道 URL | 空 | 空则只记日志不推送 |
扫描配置
| 变量 | 说明 | 默认值 | 备注 |
|---|---|---|---|
IFACES | 扫描接口,空格分隔 | 空 | 必填 |
TIMEOUT | 两次扫描间隔(秒) | 120 | 协程每秒检查一次,超时即扫 |
ARP_ARGS | 追加给每个接口的arp-scan参数 | 空 | 如-r 1(重试 1 次) |
ARP_STRS/ARP_STRS_JOINED | 独立于 IFACES 的完整扫描串 | 空 | VLAN/docker0 用,见进阶场景 |
TRIM_HIST | 历史保留时长(小时) | 48 | 超期自动删 |
USE_DB/PG_CONNECT | 数据库类型 / PostgreSQL 连接串 | sqlite/ 空 | PG 连接失败静默回退 SQLite |
HIST_IN_DB | 自 2.1.3 起弃用 | 空 | 历史始终在库里,用TRIM_HIST控体积 |
集成配置
| 变量 | 说明 | 默认值 | 备注 |
|---|---|---|---|
INFLUX_ENABLE | 启用 InfluxDB2 导出 | false | 每次比对后写一条行协议 |
INFLUX_ADDR/INFLUX_BUCKET/INFLUX_ORG/INFLUX_TOKEN | InfluxDB2 连接信息 | 空 | 与 Grafana 数据源配置一致 |
INFLUX_SKIP_TLS | 跳过 TLS 校验 | false | 内网自签证书时置true |
PROMETHEUS_ENABLE | 暴露/metrics | false | 未启用时该端点返回 404 |
命令行参数(backend/cmd/WatchYourLAN/main.go 定义)
| 参数 | 说明 | 默认值 |
|---|---|---|
-d | 配置目录(配置与数据库都在这里) | /data/WatchYourLAN |
-n | node modules 路径(替代互联网拉取主题/图标/字体) | 空 |
完整配置文件示例(config_v2.yaml):
arp_args: "" color: dark host: 0.0.0.0 ifaces: enp4s0 influx_addr: "" influx_bucket: "" influx_enable: false influx_org: "" influx_skip_tls: false influx_token: "" log_level: info nodepath: "" pg_connect: "" port: "8840" prometheus_enable: false shoutrrr_url: "gotify://192.168.0.1:8083/AwQqpAae.rrl5Ob/?title=Unknown host detected&DisableTLS=yes" theme: sand timeout: 60 trim_hist: 48 use_db: sqlite
timeout: 60表示 60 秒一轮扫描(默认 120):扫描越频繁,历史数据量越大,TRIM_HIST要相应调小。port在 YAML 里建议加引号,避免被解析为整数引发类型错误。
进阶场景:多网段、离线环境与通知对接
场景一:VLAN / docker0 等多网段扫描
IFACES只能覆盖接口直接所在的网段。跨网段、VLAN 或容器网桥(docker0、virbr0)时用ARP_STRS:每条字符串原样拼成一条命令arp-scan $ONE_STRING,与 IFACES 扫描完全独立(实现见 backend/internal/arp/arpscan.go)。
# 扫 VLAN 107(-Q 指定 VLAN ID) arp-scan -gNx 10.0.107.0/24 -Q 107 -I eth0 # 扫 docker0 网段 arp-scan -gNx 172.17.0.1/24 -I docker0docker-compose / 环境变量场景用ARP_STRS_JOINED(逗号分隔,逗号前后不能有空格):
ARP_STRS_JOINED: "-gNx 172.17.0.1/24 -I docker0,-gNx 10.0.107.0/24 -Q 107 -I eth0"配置文件写法(arp_strs是字符串列表):
arp_strs: - -gNx 172.17.0.1/24 -I docker0 - -glNx -I virbr0⚠️ 坑:字符串的最后一个元素会被当作发现主机的接口名写入记录,所以接口名(如
eth0)务必放在每条字符串末尾。另注意ARP_STRS只能经配置文件/GUI 设置,docker-compose 里写ARP_STRS无效,必须用ARP_STRS_JOINED。
场景二:完全隔离的离线内网
默认 Web 界面会从互联网拉主题、图标和字体。隔离网络用辅助镜像aceberg/node-bootstrap本地化:
docker run --name node-bootstrap -p 8850:8850 aceberg/node-bootstrapdocker run --name wyl \ -e "IFACES=$YOURIFACE" \ -e "TZ=$YOURTIMEZONE" \ --network="host" \ -v $DOCKERDATAPATH/wyl:/data/WatchYourLAN \ aceberg/watchyourlan -n "http://$YOUR_IP:8850"compose 里则取消node-bootstrap服务及command: "-n http://YOUR_IP:8850"的注释。
⚠️ 坑:
-n指向的地址必须用服务器可达的 IP/域名,容器自身localhost:8850不通;资源服务没起来时页面样式会缺失但不影响扫描功能。
场景三:未知主机通知(Shoutrrr)
配置只需一个 URL(协议头决定渠道,Discord、Email、Gotify、Matrix、Ntfy、Pushover、Slack、Telegram、Webhook 等),配好后用 API 发测试消息验证:
curl http://0.0.0.0:8840/api/notify_test新主机出现时的推送格式固定为:
Unknown host found. Name: '%s', IP: '%s', MAC: '%s', Hw: '%s', Iface: '%s'⚠️ 坑:
SHOUTRRR_URL为空时程序不报错,只把事件写日志不推送——"没收到通知"先查这个变量是否真的落进了配置(GUI 保存与环境变量覆盖容易漏掉一侧)。
场景四:PostgreSQL 替换 SQLite
USE_DB=postgres PG_CONNECT="postgres://username:password@192.168.0.1:5432/dbname?sslmode=disable"backend/internal/gdb/start.go 中 PG 连接失败只会打 warn 日志并自动回退 SQLite,服务不中断。
⚠️ 坑:回退后数据写在本地
scan.db而非 PostgreSQL,表面看"一切正常"。启用后先看启动日志是否出现Connected to DB: PostgreSQL,否则核对连接串。
生态与集成:认证、监控导出与 API
认证:项目本身不带认证,官方推荐 Authelia 或作者的 ForAuth,示例见 docker-compose-auth.yml:
forauth: image: aceberg/forauth restart: unless-stopped ports: - 8800:8800 # 代理端口 - 8801:8801 # 配置端口 volumes: - ~/.dockerdata/forauth:/data/ForAuth environment: FA_TARGET: "YOUR_IP:8840" # 指向 WYL 的 host:port FA_AUTH: "true" FA_AUTH_EXPIRE: 7d FA_AUTH_PASSWORD: "$$2a$$10$$wGLUHXh2cRN1257uGg1s5eZvYgnjw8wB9vAcfcHqqqrxm5hvBqAzK" FA_AUTH_USER: user⚠️ 关键前提:WYL 必须
host网络模式,Web 端口直接暴露在宿主网络上。接入 ForAuth/SSO 只挡浏览器路径,务必再用防火墙限制8840端口的来源 IP。compose 环境变量里的$必须写成$$(bcrypt 哈希含$)。
监控导出:两个出口都是每轮扫描比对后逐主机更新,Grafana 任选其一接:
| 出口 | 数据形态 | 说明 |
|---|---|---|
| InfluxDB2 | WatchYourLAN,IP=...,iface=...,name=...,mac=...,known=... state=0/1 | 行协议,state=1在线、0离线;连接前会先 Ping 服务器 |
| Prometheus | watch_your_lan_up{ip=..., iface=..., name=..., mac=..., known=...} 0/1 | /metrics端点,gauge 向量,未启用返回 404 |
HTTP API(完整文档 docs/API.md,v2.1.4 起启动后访问/swagger/可在线浏览):
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | /api/all | 全部主机 JSON |
| GET | /api/history | 全部历史(量大,不推荐) |
| GET | /api/history/:mac/:date | 按 MAC + 日期过滤,date可取2、2025-07、2025-07-26任意粒度 |
| GET | /api/history/:mac?num=20 | 某设备最近 20 条历史 |
| GET | /api/host/:id | 按 ID 取主机 |
| GET | /api/port/:addr/:port | 端口开放检测,返回true/false |
| GET | /api/edit/:id/:name/*known | 改主机名;known传toggle切换已知状态 |
| GET | /api/host/del/:id | 删除主机 |
| GET | /api/host/add/:mac | 从 API 添加主机 |
| GET | /api/wol/:mac | 发送 Wake-on-LAN 魔法包 |
| GET | /api/notify_test | 发送测试通知 |
| GET | /api/status/*iface | 总数/在线离线/已知未知统计,可只查某接口 |
| GET | /api/rescan | 立即触发一轮重扫 |
| GET | /api/version | 版本号 |
嵌入现有工作流:定时任务里curl /api/status/即可把在线数喂给任何告警脚本;/api/port/:addr/:port可做资产端口巡检;/api/host/del/:id、/api/edit/...支持自动化纳管。社区亦有 Python API 客户端、Umbrel / YunoHost 应用、AUR 包,均基于以上端点。
避坑清单:现象 → 原因 → 解法
- 现象:Home 页面始终无主机。原因:
arp-scan未安装,或IFACES为空/接口名错误。解法:which arp-scan确认后手动执行arp-scan -glNx -I $IFACE验证有输出;把LOG_LEVEL设为debug看每轮实际执行的命令。 - 现象:历史记录时间差 6~18 小时。原因:
TZ未设置(或二进制包环境缺tzdata)。解法:补TZ=$YOURTIMEZONE,非容器环境apt install tzdata。 - 现象:docker-compose 里配了
ARP_STRS但 VLAN 网段从未出现。原因:ARP_STRS只能来自配置文件/GUI,环境变量形态是ARP_STRS_JOINED;且逗号前后带空格会拆出错误命令。解法:改用ARP_STRS_JOINED,逗号紧贴字符串,接口名放每条末尾。 - 现象:配了 PostgreSQL,但数据仍在本地
scan.db。原因:PG 连接失败自动回退 SQLite,仅一条 warn 日志。解法:查启动日志确认Connected to DB: PostgreSQL,否则核对PG_CONNECT连接串与网络连通性。 - 现象:隔离内网里页面样式/图标加载失败。原因:界面默认从互联网拉主题资源。解法:部署
aceberg/node-bootstrap并加-n "http://$YOUR_IP:8850"(或设NODEPATH)。
决策清单:下一步做什么
- 确认
IFACES与TZ两个必填项,用 Docker 一条命令或 release 二进制(装arp-scan)把服务跑起来,访问:8840验证。 - 有 VLAN/docker0 网段就配
ARP_STRS(文件/GUI)或ARP_STRS_JOINED(环境变量),接口名放字符串末尾。 - 需要告警时填
SHOUTRRR_URL,先打GET /api/notify_test确认渠道通再依赖它。 - 接 Grafana 时二选一:
PROMETHEUS_ENABLE=true走/metrics(配置最少),或配齐 InfluxDB2 五件套。 - 服务要暴露到局域网外,先接 ForAuth/Authelia,同时用防火墙限制
8840端口来源。 - 隔离内网补
node-bootstrap+-n资源地址,把最后一条外网依赖也掐掉。
【免费下载链接】WatchYourLANLightweight network IP scanner written in Go. With notifications, history, export to Grafana项目地址: https://gitcode.com/GitHub_Trending/wa/WatchYourLAN
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考