Client lidar 是百度系统部物理网络黑盒监控团队开发的 TCP SYN 可达性探测工具。它通过发送原始 TCP SYN 报文并分析响应来判定目标主机和端口的网络状态,无需在远端部署任何服务端程序。
核心特性:
lidar 基于 TCP 三次握手的前两步来判断网络可达性:
# 正常流程(三次握手前两步)
Client Server
|-- SYN (seq=N) ------------>| # lidar 发送 SYN
|<-- SYN-ACK (ack=N+1) ------| # 端口开放 → 可达
# 端口关闭
Client Server
|-- SYN (seq=N) ------------>| # lidar 发送 SYN
|<-- RST --------------------| # 端口关闭 → 拒绝
# 不可达
Client Server
|-- SYN (seq=N) ------------>| # lidar 发送 SYN
| (无响应) | # 超时 → 不可达/丢包
lidar 构造原始 IP + TCP SYN 报文,通过 raw socket 发送,并通过 BPF 设备(macOS)或 raw socket(Linux)接收响应。内核 TCP 协议栈不会处理这些报文,因此不会影响系统已有的 TCP 连接。
lidar 适用于以下网络可达性探测场景:
nettools 工具集内的三个工具各有侧重:
| 特性 | bitflip | baize | lidar |
|---|---|---|---|
| 探测协议 | UDP | UDP | TCP SYN |
| 是否需要服务端 | 需要(bitflip server) | 需要(baize server) | 不需要 |
| 探测内容 | 丢包 + bitflip | 丢包 + bitflip | 可达性(SYN-ACK/RST/Timeout) |
| 配置方式 | 命令行参数 | JSON 配置文件 | 命令行参数 / JSON 配置文件 |
| 适用场景 | UDP 质量监控 | 长期持续监控 | 快速可达性探测 |
| 运行平台 | Linux / macOS | Linux / macOS | Linux / macOS |
# 克隆仓库
git clone https://github.com/baidu/nettools.git
cd nettools
# 编译全部工具
make compile
# 或单独编译 lidar
go build -o lidar ./cmd/lidar/
| 要求 | 说明 |
|---|---|
| root 权限 | 需要 sudo 运行,因为 raw socket 和 BPF 设备需要特权 |
| macOS / Linux | macOS 通过 BPF 设备接收,Linux 通过 raw socket 接收 |
| 网络连通 | 需要能向目标 IP 发送原始 IP 报文 |
sudo 运行。raw socket(SOCK_RAW)和 BPF 设备(/dev/bpf*)都需要 root 权限。
# 探测 10.0.0.2 的 80 端口(默认 10 pps)
sudo ./lidar -t 10.0.0.2 -p 80
# 同时探测多个目标
sudo ./lidar -t 10.0.0.2,10.0.0.3,10.0.0.4 -p 22
# 以 100 pps 探测,持续 30 秒
sudo ./lidar -t 10.0.0.2 -p 80 --rate 100 -d 30s
# 发送 1000 个探测包后自动停止
sudo ./lidar -t 10.0.0.2 -p 80 -n 1000
# 用配置文件启动(适合重复性探测任务)
sudo ./lidar -c lidar.json
# 配置文件 + 命令行覆盖(临时改端口)
sudo ./lidar -c lidar.json -p 443
| 参数 | 短选项 | 默认值 | 说明 |
|---|---|---|---|
--targets | -t | — | 目标 IP 地址,逗号分隔(必填) |
--port | -p | 22 | 目标 TCP 端口 |
--local-addr | -l | 自动检测 | 源 IP 地址 |
--local-port | 54321 | 源端口起始值 | |
--local-port-count | 100 | 源端口数量(用于 ECMP 路径覆盖) | |
--rate | 10 | 每秒发送探测包数(pps) | |
--span | -s | 1s | 统计报告间隔 |
--delay | 3s | 首次统计前的等待时间(等待在途报文) | |
--count | -n | 0 | 最大发送数量(0 = 无限) |
--duration | -d | 0 | 最大发送时长(0 = 无限) |
--interface | -i | 自动检测 | 出接口名称(自动检测失败时指定) |
--verbose | -v | false | 打印丢包的详细端口信息 |
--local-port 和 --local-port-count 控制源端口轮转范围。lidar 会从 local-port 开始依次递增,达到 local-port + local-port-count - 1 后回到起始值。多源端口可以覆盖不同的 ECMP 路径。
lidar 支持通过 JSON 配置文件指定参数,适合重复性探测任务和自动化场景。使用 -c 指定配置文件路径。
当配置文件和命令行参数同时提供时:命令行参数优先,会覆盖配置文件中的同名项。未在命令行中显式指定的参数使用配置文件中的值。
| 优先级 | 来源 | 说明 |
|---|---|---|
| 高 | 命令行参数 | 显式指定的 -p、--rate 等会覆盖配置文件 |
| 中 | JSON 配置文件 | -c lidar.json 指定,未覆盖的字段使用文件值 |
| 低 | 代码默认值 | 配置文件和命令行都未指定时使用默认值 |
{
"target_addrs": "10.0.0.1,10.0.0.2",
"server_port": 80,
"local_addr": "",
"local_port": 54321,
"local_port_count": 100,
"rate": 10,
"span": "1s",
"delay": "3s",
"count": 0,
"send_duration": "0s",
"interface": "",
"verbose": false
}
| 字段 | 类型 | 对应命令行参数 | 说明 |
|---|---|---|---|
target_addrs | string | -t | 目标 IP 地址,逗号分隔 |
server_port | int | -p | 目标 TCP 端口 |
local_addr | string | -l | 源 IP 地址(空字符串自动检测) |
local_port | int | --local-port | 源端口起始值 |
local_port_count | int | --local-port-count | 源端口数量 |
rate | int | --rate | 每秒发送探测包数(pps) |
span | string | -s | 统计报告间隔(如 "1s"、"5s") |
delay | string | --delay | 首次统计前的等待时间 |
count | int | -n | 最大发送数量(0 = 无限) |
send_duration | string | -d | 最大发送时长(如 "30s"、"5m") |
interface | string | -i | 出接口名称(空字符串自动检测) |
verbose | bool | -v | 打印丢包的详细端口信息 |
# 仅使用配置文件
sudo ./lidar -c lidar.json
# 配置文件 + 命令行覆盖(临时调整端口为 443)
sudo ./lidar -c lidar.json -p 443
# 配置文件 + 命令行覆盖(临时调高速率)
sudo ./lidar -c lidar.json --rate 100 -d 30s
cmd/lidar/lidar.example.json。可以将常用参数写在配置文件中,运行时通过命令行临时覆盖需要调整的字段。
2026/06/05 21:37:14 [INFO] probing 1 target(s) on port 80 from 192.168.1.14 (rate: 10 pps)
2026/06/05 21:37:14 [INFO] bound BPF to en0 (DLT=1)
启动时打印目标数量、端口、本机 IP、探测速率和绑定的 BPF 设备信息。
2026/06/05 21:37:17 [WARN] 21:37:14, [192.168.1.14 -> 74.48.173.243], sent: 10, received: 10 (SYN-ACK: 10, RST: 0), timeout: 0
2026/06/05 21:37:18 [INFO] 21:37:15, [192.168.1.14 -> 74.48.173.243], sent: 10, received: 10 (SYN-ACK: 10, RST: 0), timeout: 0
| 字段 | 说明 |
|---|---|
sent | 该时间窗口内发送的探测包总数 |
received | 收到响应的探测包总数 |
SYN-ACK | 收到 SYN-ACK 响应的数量(目标端口开放) |
RST | 收到 RST 响应的数量(目标端口关闭/拒绝) |
timeout | 未收到响应的探测包数量(目标不可达/丢包) |
| 级别 | 条件 | 含义 |
|---|---|---|
[INFO] | timeout = 0 | 全部收到响应,网络正常 |
[WARN] | timeout > 0 | 存在丢包或不可达 |
delay(默认 3 秒)后出现。这是为了等待在途报文返回,确保统计的准确性。
开启 -v 后,丢包时会打印超时的源端口-目的端口对:
2026/06/05 21:37:18 [WARN] 21:37:15, [192.168.1.14 -> 74.48.173.243], sent: 10, received: 8 (SYN-ACK: 8, RST: 0), timeout: 2
2026/06/05 21:37:18 [WARN] 21:37:15, [192.168.1.14 -> 74.48.173.243], timeout ports: map[54322-80:1 54325-80:1]
# 检查机柜内 3 台服务器的 SSH 端口
sudo ./lidar -t 10.0.1.10,10.0.1.11,10.0.1.12 -p 22 -d 60s
# 以 10 pps 持续探测 Web 服务的 80 端口
sudo ./lidar -t www.example.com对应的IP -p 80 --rate 10
# 高速率探测海外节点(100 pps,持续 5 分钟)
sudo ./lidar -t 74.48.173.243 -p 443 --rate 100 -d 5m
# 割接前:发送 5000 个包,verbose 模式
sudo ./lidar -t 10.0.0.2 -p 80 -n 5000 -v
# 割接后:同样参数再次探测
sudo ./lidar -t 10.0.0.2 -p 80 -n 5000 -v
# 多网卡环境下指定出接口
sudo ./lidar -t 10.0.0.2 -p 80 -i eth1
# 使用更多源端口覆盖不同 ECMP 路径
sudo ./lidar -t 10.0.0.2 -p 80 --local-port 40000 --local-port-count 500 --rate 500 -d 60s
ping 使用 ICMP Echo,只能判断 IP 层可达性。lidar 使用 TCP SYN,可以判断特定 TCP 端口是否可达,并能区分端口开放(SYN-ACK)、端口关闭(RST)和不可达(timeout)三种状态。
lidar 使用 raw socket(SOCK_RAW)构造原始 IP/TCP 报文,并在 macOS 上使用 BPF 设备(/dev/bpf*)接收响应,这些操作都需要 root 权限。
不需要。lidar 利用目标主机内核的 TCP 协议栈自动响应 SYN 报文。只要目标 IP 可达且 TCP 端口有服务监听,就会返回 SYN-ACK;端口关闭则返回 RST。无需在远端安装任何软件。
不会。lidar 发送 SYN 后收到 SYN-ACK 即完成统计,不会发送 ACK 完成三次握手。目标服务器会在超时后自动清理这个半开连接,不影响已有的 TCP 连接。
--delay(默认 3 秒)是为了等待在途报文返回。如果立即统计,最后几个探测包的响应可能还没回来,会被误判为丢包。可以通过 --delay 调整等待时间。
按 Ctrl+C 发送 SIGINT 信号。lidar 会等待 delay 时间让在途报文返回后退出,确保最后的统计数据准确。如果指定了 -n 或 -d,到达限制后也会自动停止。
取决于网络环境和目标数量。默认 10 pps 适合一般探测。高速率(100-1000 pps)适合压力测试或高精度丢包检测。注意过高速率可能被网络设备限速或触发安全策略。
如果自动检测失败,使用 -i 指定出接口名称,例如 -i eth0(Linux)或 -i en0(macOS)。