用Docker部署WatchYourLAN:打造局域网IP扫描与设备监控哨兵
我负责的网络不算大也就是十几个交换端口、几十台设备可真正乱起来时一台路由器的后台根本不够用。办公室、机柜、摄像头、门禁、打印机、NAS、临时接入的笔记本同时在线管理者最怕的就是某天早上发现有设备“不请自来”或者明明打印机连不上网却怎么都查不出是谁占了那个 IP。WatchYourLAN 这类基于 Docker 的网络 IP 扫描器就是在这里派上用场的。这篇文章不是教你把 nmap 装一遍而是把一台“能长年挂机、带 Web 界面、能自动扫描、能告警、能往前翻历史”的局域网哨兵部署起来。整个过程用 Docker 容器完成适合不想把主机系统搞脏的运维也适合在家里 NAS 上跑一套玩。文章会从需求分析讲到方案选型再到完整部署、界面配置、API 调用最后附上常见问题和排查思路。建议先把这篇文章通读一遍再动手操作能少踩不少坑。1. 为什么要在局域网里部署网络 IP 扫描器1.1 网络规模变大之后的三个痛点先说一个常见的场景办公网络设备一多原来靠路由器后台管理设备的方式就不太够用了。IP 冲突找不到源头。几台设备同时用了同一个 IP导致其中某台上不了网。路由器后台虽然能看到 MAC 地址但到底是哪台设备、在哪个交换机口上排查难度直线上升。陌生设备接入没有感知。有人把手机、私人的 USB 无线网卡、开发板插到办公网里在网络侧几乎没有任何预警。如果等到数据泄露或者带宽被占用才发现就已经晚了。设备上下线情况全凭人工。要了解一台服务器是否长期在线、某台打印机是不是频繁掉线往往只能手动 ping。偶尔一次两次还行24 小时盯着完全做不到。这些都是典型“设备台账不健全”的表现。真正解决问题不是靠某一次扫描而是要让扫描动作持续化、结果可视化、变化可追溯。1.2 WatchYourLAN 具体能解决什么WatchYourLAN 是一款开源局域网扫描工具启动之后会在后台周期性探测当前网段里的活跃主机并把结果保存下来。你打开浏览器就能看到一张“正在线的主机列表”每台设备的 IP、MAC、厂商信息、主机名、最近在线时间都在里面。它和一次性扫描工具最大的区别在于它是一个常驻服务而不是一条命令。Web 界面直观不用记住复杂的命令行参数可以设置扫描周期比如每 5 分钟自动扫一次生成历史记录能识别 MAC 地址对应的网卡厂商帮助判断设备类型新设备上线、已有设备离线都能通过通知渠道推给你自带 HTTP API方便和监控系统、告警平台做联动。这些功能堆在一起解决的正是“持续监测、事后追溯、快速定位”这三个运维需求。对小型企业网、家庭实验室、树莓派集群这类场景来说性价比非常高。2. 方案选型思考为什么是 WatchYourLAN Docker2.1 为什么不直接用 nmap 或者路由器后台说起扫 IP大多数人第一反应是 nmap。nmap 确实强大但它是“手动工具”不适合做持续监控服务。你不可能每天晚上手动跑一遍脚本更没法让不懂命令行的人去查看结果。虽然可以用 cron 脚本实现定时扫描但输出、告警、历史记录都得自己造轮子投入产出比不划算。再看路由器后台。家用路由器能看到 DHCP 客户端列表但一般只记录成功获取到 IP 的设备静态 IP 设备、跨交换机设备未必完整。而且它不保存历史在线记录也没法设置“新设备上线通知”。更重要的是不同路由器厂商界面差异大今天能用的功能换个牌子就得重学一遍。把范围放到专门的网络扫描服务上WatchYourLAN 算是一个挺好的平衡点。它本质上是一个跑在容器里的轻量 Web 应用内置了周期扫描、Web 展示、通知、API 这些常用能力。你不用写一堆胶水脚本部署完改改配置就能用。2.2 Docker 部署的具体优势Docker 对这个场景带来的好处很实际不污染宿主机。扫描器需要的各种依赖、二进制文件都封装在镜像里不用往宿主机系统里装 Python 包、编译工具或者专用扫描器。跨平台迁移省事。在一台机器上跑通的容器export 或通过 compose 文件就能在另一台机器上还原。升级回滚容易。官方镜像更新后重新拉一个新镜像、替换容器即可。不想要新版还能用旧镜像回滚。资源和权限可控。通过--restartunless-stopped可以保证宿主机重启后扫描器自动拉起省心。当然Docker 不是没有缺点。容器网络在默认 bridge 模式下和宿主机之间隔了一层虚拟网桥扫描局域网时可能“看不全”。这一点我第 3 章会专门讲部署网络模式选对了问题就解决了一半。2.3 镜像运行机制简析WatchYourLAN 的镜像并不算大它把扫描探测、数据存储、Web 服务合在一个容器里。用户访问 Web 界面配置扫描策略后进程会按周期在后台执行探测任务探测结果写入 SQLite 一类的本地数据库Web 界面再从数据库里读取数据展示。有一个容易忽视的细节扫描器能扫到什么取决于容器运行时拥有的网络权限。它需要看到真实的局域网网卡才能发出 ARP 广播、收到各设备的响应。如果容器被隔离在一个只有 Docker 内网的网络里那它扫到的就只是容器网络内部那几台容器不是你真正的物理局域网。这个点在第 3 章的“网络模式选型”中会展开。3. 部署前准备目录、端口与网络模式3.1 检查 Docker 环境动手之前先确认一下手里这台机器的基础条件。docker --version docker compose version如果命令能正常打印版本信息说明 Docker 已经装好。如果还没有 Docker就先去官方文档装一个社区版这里不再展开。机器性能不用太担心WatchYourLAN 属于轻量服务2 核 2G 的小主机、树莓派、NAS 都可以跑。当然扫描大网段比如 40 多个 C 段时对宿主机网络栈压力会大一些但多数人用不上的场景不必过度焦虑。3.2 目录规划与端口规划我习惯把所有运维工具的持久化数据放一起比如/opt/docker/watchyourlan。下面这个目录结构可以帮助新手建立认知/opt/docker/watchyourlan └── data容器内的数据目录我推荐挂为/data用来存放配置文件、SQLite 数据库、日志。这样即使容器被删掉再重新创建时数据还在不至于扫了一周的历史记录全部归零。端口方面默认是8080。如果宿主机 8080 已经被其他服务占用可以在部署时映射成别的宿主机端口比如18080:8080。这个映射关系要在部署前考虑好虽然后续也能改但改端口往往要重建容器。3.3 网络模式选型host 模式还是 bridge 模式这里要特别展开。刚开始接触 Docker 的运维朋友很容易在这一步翻车容器明明启动了Web 界面也能打开但扫描结果里就是没有物理网里的设备。原因在于 Docker 默认的 bridge 网络模式。在 bridge 模式下容器有一个独立的虚拟网卡容器的 IP 和宿主机不在同一个局域网里。扫描器从这个虚拟网卡出发去探测物理网段ARP 广播是隔了一层 NAT 的结果自然不准。所以我在部署这类“需要访问宿主机真实网络”的工具时通常优先使用network_mode: host。host 模式下容器直接共享宿主机的网络命名空间没有虚拟网桥扫描器能看到真实的局域网接口大量主机发现的准确性也会更好。对比项bridge 模式host 模式扫描准确性可能只能扫到部分设备能完整覆盖宿主机所在网段端口映射需要 -p 手动映射直接用宿主机端口可移植性较好Mac/Windows 也能跑Linux 支持最好使用门槛低低但需注意端口冲突如果你的宿主机是 Linux强烈建议直接用 host。如果是 Docker Desktop 这类桌面环境host 模式支持有限那就用 bridge 模式并老老实实映射端口只是扫描范围会受到限制。4. 完整搭建过程CLI 与 Compose 两种方式4.1 方式一docker run 一条命令启动先给一个最简单的命令适合第一次体验docker run -d \ --namewatchyourlan \ --networkhost \ --restartunless-stopped \ -e TZAsia/Shanghai \ -v /opt/docker/watchyourlan/data:/data \ aceberg/watchyourlan命令不长逐段拆开看-d后台运行--namewatchyourlan给容器起名方便管理--networkhost使用宿主机网络--restartunless-stopped开机自启、容器挂了自动重启-e TZAsia/Shanghai设置时区避免时间显示成 UTC-v /opt/docker/watchyourlan/data:/data持久化数据目录。如果宿主机无法使用 host 模式就退回 bridge 模式docker run -d \ --namewatchyourlan \ --restartunless-stopped \ -p 8080:8080 \ -e TZAsia/Shanghai \ -v /opt/docker/watchyourlan/data:/data \ aceberg/watchyourlan这种方式的优点是简单直接、容易记。缺点是如果容器配置文件丢失重建时所有参数都靠手敲容易漏掉某个环境变量。4.2 方式二docker-compose 管理配置当你已经确定要长期使用甚至还有多台机器要部署推荐用 Compose。新建一个目录里面放一份docker-compose.ymlservices: watchyourlan: image: aceberg/watchyourlan container_name: watchyourlan restart: unless-stopped network_mode: host environment: - TZAsia/Shanghai volumes: - /opt/docker/watchyourlan/data:/data如果你的机器不支持 host 模式可以改成services: watchyourlan: image: aceberg/watchyourlan container_name: watchyourlan restart: unless-stopped ports: - 8080:8080 environment: - TZAsia/Shanghai volumes: - /opt/docker/watchyourlan/data:/data启动就两句话docker compose up -d docker compose psCompose 的好处是“配置即文档”。下次要在另一台机器部署把这个 YAML 文件拷贝过去拉镜像、启动就能得到完全一样的服务。同事接手也容易不用靠聊天记录复述部署步骤。4.3 关键参数逐个拆解有了部署文件再补充几个值得关注的参数细节。首先是TZ环境变量。很多人会忽略时区结果界面里记录的在线时间比本地时间慢 8 小时排查问题时看到时间对不上还以为服务出 bug 了。加一行-e TZAsia/Shanghai就能解决。其次是数据目录。先用系统工具看一下挂载是否成功docker exec watchyourlan ls -lh /data正常情况下应该能看配置数据库文件。如果目录为空检查一下宿主机路径是否存在以及权限是否够。容器内进程通常以普通用户运行如果宿主机目录权限不对容器内是写不进去的。第三点是端口和 host 模式的关系。如果用了network_mode: hostWeb 服务默认就监听宿主机 8080 端口端口映射-p反而会被忽略。这时如果端口被占用要么停掉占用进程要么在界面配置里调整端口然后再重建容器。4.4 启动后的检查与 Web 后台访问容器启动后先看一下运行状态docker ps docker logs watchyourlan --tail 100日志里如果出现类似“Listening on 0.0.0.0:8080”的记录说明服务已经起来了。然后浏览器访问http://宿主机IP:8080能看到 WatchYourLAN 的 Web 界面。我这里要提醒一句网页能打开不等于扫描就能正常工作。接下来配置才是重点扫描接口、网段、周期这些设置不对界面再漂亮也没用。5. 后台配置扫描、周期、告警与 API5.1 第一次登录与初始化打开 Web 界面后先别急着配置第一件事是到设置页面把管理员密码设置好。虽然工具默认并不复杂但暴露在局域网里又没有口令保护任何能访问这台机器端口的人都能查看设备记录这是不必要的风险。设置页里还会提供几个常规选项比如界面主题、语言、时间格式。这部分按个人习惯调整即可不影响核心功能。5.2 设置扫描接口与网段扫描接口决定了扫描器从哪个网卡出发。常见的名字有eth0、ens18、enp3s0在 Linux 上可以用ip a查看。ip -br a把看到的物理网卡名填进配置里然后设置网段。如果宿主机 IP 是192.168.1.100网段通常填192.168.1.0/24。这里不建议为了省事直接写网关的 CIDR 范围比如0.0.0.0/0那样会把整个路由可达范围都扫一遍不仅耗时间还会扫出大量非本网段设备污染记录。接口和网段的关系可以理解为接口负责“入口”网段负责“范围”。选错接口扫描结果可能指向 Docker 虚拟网卡网段写太宽记录里就会出现一堆跟本工作区无关的地址。5.3 扫描周期与主机名识别扫描周期默认值一般够用不必设置得太频繁。如果网络有几十台设备每 5 分钟扫一次的负载也不高但如果是个几千 IP 的大网段建议把周期改成 10 分钟甚至更长具体根据实际情况调整。另外WatchYourLAN 会尝试识别主机名也就是往界面里填入设备的友好名称。识别手段通常来自反向解析、mDNS、NetBIOS 一类的协议。能识别出来最好识别不出来的也别太纠结只要 IP 和 MAC 对上再加上厂商信息基本能判断是什么设备。比如看到 MAC 前缀属于某打印机厂商那大概率就是那台打印机的无线网卡。5.4 通知告警配置通知功能是这个工具比较实用的地方。很多企业网管最大的需求不是“查看”而是“知道有变化立即通知我”。WatchYourLAN 支持把设备上线、离线事件推送到 webhook 渠道你可以接企业微信机器人、钉钉机器人、Telegram Bot或者自己写一个收 webhook 的小服务。配置的要点是先选定通知渠道再填写要推送消息的地址和识别凭证。填完保存之后手动做一次扫描然后看是否收到测试消息。不要批量配置完就不管等到真正有新设备上线才发现消息没推出来。5.5 HTTP API 拉取数据高级玩法WatchYourLAN 这个工具有意思的地方在于它提供了 HTTP API这意味着不需要依赖人工看网页脚本也能直接拿到设备清单。在设置页面里申请一个 API Key 之后用 curl 就能访问curl -s http://127.0.0.1:8080/api/hosts?key你的APIKey | jq .返回的 JSON 里通常会包含 IP、MAC、主机名、厂商、在线状态、最近更新时间这些字段。拿到这些数据就能写脚本做自动化比如新设备上线自动发告警、离线超过 N 天自动清理记录、把设备列表同步到 NoSQL 里做资产展示。这里额外提醒一下API Key 相当于一把钥匙不要把它明文写在浏览器的收藏夹里更不要直接在聊天工具里转发。如果怀疑泄露去设置页面重新生成一个即可。这里顺便给一个小的 Bash 示例抓取当前在线设备 MAC 列表curl -s http://127.0.0.1:8080/api/hosts?key你的APIKey \ | jq -r .[] | select(.online true) | .mac \ | sort /tmp/wyl_online.txt思路很简单周期性把快照写到临时文件再和上一次的快照 diff就能知道多出了哪些设备。 这个脚本可以挂到 cron 里只要周期和 Web 后台的扫描周期对齐就行不必太频繁。6. 常见问题与排查技巧速查6.1 镜像拉取失败如果docker pull aceberg/watchyourlan卡住或者报错可以先试试换一个时间点再拉或者换一个公共 registry 镜像。还有一种办法找一台网络环境更稳定的机器先把镜像docker save成 tar 包再拷贝到目标机器docker load。这种办法虽然朴素但在临时网络修复窗口期非常管用比反复重试省时间。6.2 扫描不到局域网主机这是最高频的问题。排查顺序建议如下确认容器是不是用了 host 网络。如果说 “我明明映射了端口为什么扫不到” 大概率就是这个问题。确认 Web 后台里选择的是宿主机物理网卡不是docker0或veth虚拟网卡。确认网段写的对不对。填成192.168.1.0/24宿主机 IP 必须是192.168.1.x。确认宿主机防火墙没有把容器的探测包挡掉。有些主机防火墙默认只放行已建立的连接会挡住主动探测建议临时放行相关协议做测试。还有一个小经验如果扫完发现部分设备在线、部分不在线先怀疑无线设备同样有睡眠机制、防止广播风暴的 AP 会过滤掉一部分探测包这类问题短暂扫描有时会漏把周期调长一点连续扫两三轮会好很多。6.3 界面端口冲突如果在宿主机上已经有一个服务占着 8080使用 host 模式的容器会直接起不来或者报 “address already in use”。解决方法是去配置里改成别的端口比如 8090再重建容器。用 compose 管理的话只需要改 YAML 里的端口映射或环境变量运行docker compose up -d重建即可。不要试图在同一台机器上开好几个监听同一个端口的容器容器网络里没有魔法冲突就是冲突。6.4 容器重启后配置丢失出现这种情况十有八九是数据目录没有挂载。排查命令docker inspect watchyourlan --format {{ json .Mounts }}如果挂载条目里没有/data那就说明上次创建容器时忘了映射。数据丢失后恢复起来比较麻烦所以这里建议在部署初期就把目录挂载路径固定在同一个位置避免来回改。6.5 时间与日志不对扫描记录的时间比本地时间慢 8 小时检查TZ环境变量是否设置正确。没设置就补上然后重建容器。日志时间、数据库时间都会跟着恢复。如果你的宿主机本身时间就不同步容器里再设置时区也没用先确保宿主机date输出正常再排查容器。7. 我的使用经验与升级建议7.1 一个小脚本新设备上线自动提醒我第一次部署完之后觉得看网页还是不方便就写了一个小脚本效果是“每当接口里多出一台新设备就通过 webhook 发一条通知”。核心逻辑不复杂就是把 API 拉下来的设备列表做快照然后对比两次结果#!/usr/bin/env bash APIhttp://127.0.0.1:8080/api/hosts?key你的APIKey SNAPSHOT/tmp/wyl_snapshot.txt curl -s $API | jq -r .[] | select(.online true) | .ip .mac | sort $SNAPSHOT.new if [ -f $SNAPSHOT ]; then diff $SNAPSHOT $SNAPSHOT.new | grep ^ | sed s/^ /新设备: / /tmp/wyl_notify.txt fi mv $SNAPSHOT.new $SNAPSHOT curl -s -X POST https://你的webhook地址 \ -H Content-Type: application/json \ -d /tmp/wyl_notify.txt /dev/null这个脚本不复杂挂在 cron 里每 5 分钟执行一次就能实现轻量级的设备变更感知。当然如果机器的安全要求比较高建议还是配合更专业的资产管理系统使用这里只作为玩法参考。7.2 数据备份与恢复有了历史记录之后备份就成了必要操作。好在目录规划时我们已经把数据放在独立目录里备份就是打包那个目录tar -czvf watchyourlan-backup-$(date %F).tar.gz /opt/docker/watchyourlan/data恢复也简单直接把压缩包解压到原路径再启动容器docker compose up -d这套流程放在 cron 里配合网盘或对象存储基本就是一个小而可靠的数据保护方案。我见过太多一次性部署完就再也不关注的案例等到数据目录挂掉才后悔当初没做备份属于“早知道系列”的典型。7.3 日常使用中的几点体会到这儿基础的部署和配置已经完整跑通了。最后说几句我在实际维护中的感受。网络扫描工具不是装完就一劳永逸的它更像一个“哨兵”。你需要隔一段时间翻一下在线列表看看有没有异常设备有同事离职、有新项目组入住时主动对一次设备台账能把很多网络隐患掐在萌芽阶段。如果你后面发现单机版不够满足需求还可以把它和 Grafana 这类可视化系统做联动通过 API 把设备在线量、厂商分布、活跃度画成面板。或者把扫描结果和交换机的端口信息做关联实现“某个 MAC 最近出现在哪个交换机口”的溯源能力。这些扩展都建立在一个稳定的基础上先让扫描器持续、准确地记录再围绕记录做文章。我在多次部署里最深的体会是通常问题不是工具不够强而是工具没有持续跑起来。Docker 方案最大的价值就是让你用最小的成本把这件事“常驻化”。你不需要记住 nmap 全家桶的参数也不需要每天手动跑一遍脚本只需要把容器启动好、把配置调对它就会在后台安静地工作。剩下的时间留给更重要的问题。如果你准备在一台长期开机的机器上部署建议首选 Compose 方式把数据目录、时区、网络模式写清楚。一次投入半小时换来的是未来很长一段时间的省心。