Open-source Wi-Fi provisioning for headless Linux

wifi-provisioner

开机没网时自动开启配置热点和强制门户。用户用手机选择目标 Wi-Fi、填写密码, 设备就会切回 station 模式、校验联网并收起热点。

单二进制
静态 Go 程序
内置门户
DHCP + DNS 劫持
双后端
nmcli / hostapd
Designed for boards, gateways, appliances

给没有屏幕、键盘和预置网络的 Linux 设备一个可靠入口。

它最初为 Radxa Cubie A7Z 这类 ARM64 Debian 设备设计,也适合任意支持 AP 模式的 Debian / Ubuntu 网关、边缘盒子和自制硬件。

Boot-time flow

从离线到上线,状态机自己收尾。

服务常驻 systemd,只有设备确实未联网或收到重新配网触发时才介入。

01

检测联网

先探测 `generate_204`,再用 TCP 拨测兜底;在线时保持待命。

02

开启热点

未联网时广播 `CubieSetup-XXXX`,SSID 可按配置覆盖。

03

弹出门户

纯 Go DHCP + DNS,把手机导向内置的配网页。

04

提交 Wi-Fi

手机端选择 SSID、填写密码,门户实时返回连接进度。

05

切回 station

单射频设备先关闭 AP,再连接目标网络并等待地址获取。

06

成功待命

联网成功后收起热点;失败时热点重新出现,方便重试。

Why this project

小工具,但把现场问题想完整。

不依赖 dnsmasq

DHCP、DNS 劫持和门户网页都内置在二进制里,部署面更小。

自动适配网络栈

有 NetworkManager 时走 `nmcli`,没有时回退到 `hostapd + wpa_supplicant`。

门户绑定热点网卡

Linux 下通过 `SO_BINDTODEVICE` 限制服务只在配网子网可见。

重新配网可触发

支持哨兵文件和 GPIO 长按触发,设备上线后也能回到配网模式。

Compatibility

重点只看一件事:网卡是否支持 AP 模式。

目标系统可以是 Debian 11+ 或 Ubuntu;Radxa Cubie A7Z 是首个目标板, 但代码不绑定具体硬件。

环境 依赖 后端
NetworkManager `nmcli` 自动创建热点和连接配置
裸 wpa 环境 `hostapd`、`wpa_supplicant`、`iw`、DHCP client 生成临时配置并切换模式
触发重配 哨兵文件,或可选 `gpiod` 设备在线后重新进入门户
Install

复制到板子上,安装为 systemd 服务。

仓库附带安装脚本。自行编译时使用 Go 1.21+,默认交叉编译 Linux ARM64 静态二进制。

sudo ./install.sh
sudo systemctl start wifi-provisioner
journalctl -u wifi-provisioner -f
make build
scp bin/wifi-provisioner root@device:/usr/local/bin/
sudo systemctl restart wifi-provisioner
iw list | sed -n '/Supported interface modes/,/Band/p'
# 输出中必须出现:* AP
Configuration

默认即用,关键行为都能改。

配置文件位于 `/etc/wifi-provisioner/config.json`。空值会回落到内置默认值, 现场部署时通常只需要设置网卡名、热点密码和重新配网触发。

`iface` 留空自动寻找第一个无线网卡。
`ap_password` 默认开放热点;设为 8 位以上启用 WPA2。
`connectivity_urls` 可替换为内网或国内更稳定的联网探测地址。
`sentinel_file` `touch` 该文件即可让已联网设备重新配网。
Operations

现场排障有明确路径。

热点不开

先看 `iw list` 是否有 `* AP`,再跟 `journalctl -u wifi-provisioner -f`。

门户不弹

手机浏览器直接打开 `http://192.168.4.1`,手动入口始终保留。

连接失败

多半是密码或 DHCP 客户端问题;热点会重新出现,重连即可重试。