排查systemd-networkd配置问题

小结

树莓派连接公司wifi的问题困扰了我很久,最初是时好时不好,后来就是根本连接不上。配置完全相同情况下(百分百肯定账号及配置正确),在ThinkPad笔记本上工作正常,但是树莓派会奇怪地连接并不存在的 bssid=00:00:00:00:00:00 无线AP:

Nov 05 16:18:51 pi-worker2 wpa_supplicant[1932]: wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:00:00:00:00:00 status_code=16
Nov 05 16:10:27 pi-worker2 wpa_supplicant[1849]: wlan0: Trying to associate with SSID 'SSID-OFFICE'
Nov 05 16:10:30 pi-worker2 wpa_supplicant[1849]: wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:00:00:00:00:00 status_code=16
Nov 05 16:10:30 pi-worker2 wpa_supplicant[1849]: wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="SSID-OFFICE" auth_failures=1 duration=23 reason=CONN_FAILED

下面的排查过程很长,反复折腾走了很多弯路,但是实际上解决方法很简单:

  • 由于5G频段是一个受控频率,需要根据不同国家进行调整country code,否则无法连接。在 wpa_supplicant.conf 中需要明确指定 country=CN 参数(其他国家代码,如US可能也行)

  • ubuntu server使用netplan配置网络目前没有提供country参数,所以可以通过 iw reg set CN 命令动态设置。

  • 要持久化上述country配置,修改 /etc/default/crda 配置,将默认的

REGDOMAIN=

修改成

REGDOMAIN=CN

然后重启就可以看到5GHz的WiFi正常工作了。

以下是我一周多折腾的笔记,仅供参考

问题

我在使用Ubuntu for Raspberry Pi 2020.4.1时候,采用服务器版本,所以默认的网络配置是采用netplan。netplan可以使用NetworkManager作为后端,也可以使用systemd-networkd作为后端。为了减少服务组件,我采用 netplan 调用默认的 systemd-networkd 来配置无线网络。

我有2个树莓派,安装操作系统一致,并且采用了相同的 netplan 配置,即在 /etc/netplan 目录下创建2个配置文件:

  • 01-netcfg.yaml

  • 02-wifi.yaml

执行配置生效:

没有报错,但是非常奇怪,重启系统之后,只有有线网络IP配置正确,无线网络始终没有激活。

  • 检查 systemd-networkd 服务状态::

这里可以看到 eth0 Gained carrier 但是 waln0 没有链接成功。

  • 检查 networkctl list 输出如下::

  • 检查 networkctl status -a 输出如下::

可以看到 wlan0 接口状态不正确: State: no-carrier (configuring)

为何这个无线网卡始终处于配置状态呢?

debug

要排查 systemd-networkd 问题,可以开启日志debug模式,添加一个 /etc/systemd/system/systemd-networkd.service.d/override.conf 内容如下::

然后执行journalctl 的 -u 参数指定服务单元,并加上 -f 进行tail::

然后执行一次 netplan apply 就可以查看日志:

上述日志中有

eth network stuck at routable (configuring)#8686 提到了通过禁止DHCPv6但是设置 IPv6AcceptRA=true 来解决这个报错。看起来在办公网络DHCP并没有提供RA,参考 Networkd DHCPv6 client do not start if no RA #13770

参考 netplan reference提到 accept-ra (bool) 意思是接受路由器公告(Accept Router Advertisement)是内核配置IPv6。当激活是接受路由器公告,禁用是就不响应路由器公告。

不过,我加了这个配置无效

我发现系统日志中有

我使用 iwconfig 检查可以看到

不过,使用iwlist尝试扫描:

提示错误

这是什么原因,我对比了另一个正常的树莓派,执行上述 iwlist wlan0 scan 是完全正常的,可以输出所有扫描到的SSID。我使用了 rfkill list 检查,可以看到这个无线网卡并没有被软件或硬件关闭

经过尝试,原来是wlan0没有UP导致上述 iwlist scan失败,即使看上去 ifconfig wlan0 显示UP,也可能没有UP起来。所以重新激活一次wlan0

然后就可以执行 iwlist wlan0 scan 命令了。

我后来发现,还是要检查网络连接认证,通过命令

检查发现是认证错误

搜索关键字 wlan0: CTRL-EVENT-ASSOC-REJECT bssid=00:00:00:00:00:00 status_code=16 可以看到

我发现有实际上办公室有多个Access Point使用了相同的SSID,根据 How can I connect to a specific BSSID? 是可以指定AP的MAC地址的,也就是设置bssid参数,则在 02-wifi.yaml 添加

这样生成的wpa配置文件中有了BSSID参数。

注意,只有树莓派3B+和4B才支持 5GHz WiFi,所以,如果你使用的是早期产品,例如树莓派Zero W,就无法连接5GHz无线路由器。

wpa_supplicant: Failed to initiate AP scan 提供了一个非常好的debug方式:

这种方式可以留下详细的debug日志。

直接使用wpa_supplicant

我准备直接使用wpa_supplicant来连接,所以使用 netplan 生成的配置 /run/netplan/wpa-wlan0.conf

我尝试采用 wpa_supplicant not connecting 的建议方法

输出显示

可以看到实际上wpa_supplicant尝试连接到 SSID-OFFICE ,并且会尝试不同的BSSID(也就是无线路由器的不同mac地址)

等等,为何会有 ioctl 参数错误?

Raspberry Pi Wireless Network Setup提到上述报错是正常的。不过,我参考 [SOLVED] wpa_supplicant ioctl[SIOCSIWENCODEEXT],看起来是 -D 参数导致的,如果使用 -D nl80211 就不再报 ioctl[SIOCSIWENCODEEXT]: Invalid argument 错误

后来我查了arch linux资料,原来wpa_supplicant有两种驱动,默认是使用 nl80211 ,只有这个驱动无法支持的硬件才需要使用已经停止开发的 wext 驱动。所以,如果强制指定 -D wext 就是会有上述报错,可以忽略。

提示信息

比较奇怪,我连接的bssid怎么都是 00:00:00:00:00:00 ,但是我按下ctrl-c时候输出信息

改为纯手工设置 wpa_supplicant

  • 移除 /etc/netplan/02-wifi.yaml ,然后执行一次 netplan apply 可以看到现在 ifconfig 已经不再包含无线网卡 wlan0

  • 检查rfkill是否block了无线网卡

显示正常

  • 检查无线网卡 iwconfig 输出:

  • 使用 ifconfig 命令启用无线网卡

  • 扫描周边无线网络

我找到archlinux的wiki文档,指出有些硬件不支持驱动会有类似错误。例如,我前面看到

文档说明:

On some (especially old) hardware, wpa_supplicant may fail with the following error:

This indicates that the standard nl80211 driver does not support the given hardware. The deprecated wext driver might still support the device:

(判断错误)我怀疑我复制树莓派firmware文件覆盖ubuntu的firmware来支持USB移动硬盘启动破坏了firmware加载。但是我测试了从正常的树莓派主机上(没有使用USB存储)复制.dat和.elf文件到异常服务器上,重启系统无线依然无法工作。

脚本启动

  • 配置文件 /etc/wpa_supplicant/wpa_supplicant-office.conf:

  • 执行脚本 start_wifi:

在异常的树莓派主机上执行上述脚本,显示信息

我对比了一台正常的ThinckPad笔记本脚本执行启动脚本,显示信息则

这里我观察到出现比较奇怪的是,树莓派运行的wpa_supplicant尝试连接到 'SSID-OFFICE' 现实的 bssid 是 00:00:00:00:00:00 ,这明显不是正常的无线AP的MAC地址,正常应该连接的是 xx:yy:zz:aa:bb:cc

RPI4 cannot connect to WIFI - status_code=16 找到了相同的案例,提示信息是:

have found the root cause -- and surprisingly it's wifi-HDMI interference of RPI4.

Though I have known about this issue, I believed it's not my case, because:

  • I was able to connect to another wifi (mobile hotspot)

  • my resolution was only 1920x1080

When I lowered screen resolution to 1600x1200, wifi started to work with both of my networks.

CTRL-EVENT-ASSOC-REJECT bssid=00:00:00:00:00:00 status_code=16 提到了和我相同的困扰,也是树莓派4,重启后随机会连接不了wifi。

USB3 and 2.4 GHz Wifi #1430 提到了用户发现将任何设备插入到某个USB3接口上,就会导致无线无法连接2.4GHz Wifi网络,但是5.0 GHz无线网络工作正常。

似乎这个问题和USB3的HDMI解析问题有关 ,据说这是一个已知的问题 USB 3.0* Radio Frequency Interference on 2.4 GHz Devices

上述Intel手册需要仔细阅读一下,似乎USB 3.0影响无线接收器的性能(如果靠得很近的话),我觉得这个问题确实是硬件设计问题,包括前面提到的HDMI解析度,或许就是频率影响

在这个帖子中,GithubUser5462用户说明的问题和我一样,也是在USB 3接口上连接外接移动硬盘(他使用的是My Passport WD 2TB外接HDD,而我使用的是My Passprot WD 1TB外接SSD)。另外在 Pi4, USB3, and Wireless 2.4Ghz interference 有所讨论。

在树莓派论坛已经讨论了这个问题 Problems adding a USB 3.0 SSD to PI4

我参考前面有人说的修改HDMI分辨率,参考 Video options in config.txt/boot/firmware/config.txt 中添加2行:

似乎有一个安全模式:

安全模式相当于启动时最大的HDMI兼容:

但是我设置了 hdmi_mode=51 或者 hdmi_safe=1 都没有解决这个问题

尝试raspbian

我尝试通过TF卡启动到raspbian系统中,使用同样的启动脚本来启动,发现还是出现相同的报错信息。并且这次我是没有外接USB设备,仅仅使用TF卡。我要不要在raspbian中也使用 hdmi_safe=1 呢?

实际测试下来还是失败,看来这个问题和直接外接SSD存储没有关系,但是确实和树莓派系统更新有关。

可能找到解决方法了

我在树莓派4上通过Raspberry OS官方系统启动,只使用TF卡不使用外接SSD移动硬盘,排除了USB3.0影响因素,所以导致问题的原因应该是wpa_supplicant配置问题。

由于我发现执行 sudo wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant-office.conf -i wlan0 命令提示信息显示 wpa_suuplicant 尝试连接MAC地址 bssid=00:00:00:00:00:00 ,这明显是错误的不存在MAC,所以我尝试在 wpa_supplicant-office.conf 配置中添加指定 bssid 参数,类似如下

但是发现此时报错

经过多次对比参数,我发现原来不能同时指定 ssid=bssid= ,同时设置上述两个参数就会导致无法发起iwlist scan。所以,把上述 ssid="SSID-OFFICE" 注释掉就能够正常运行。

另外,还有一个非常奇特的参数必须在wpa_supplicant.conf中指定,就是 country=US ,这个参数是表明无线使用的国家,因为每个国家的2,4GHz使用了不同的通道 List_of_WLAN_channels (参考 Raspbian - wpa_supplicant.conf Country meaning ) 。有可能你需要根据你的路由器来设置这个参数(或者可以在配置中指定channel?)

我测试了如果不指定这个 country=US ,就会导致wpa_supplicant启动时候显示 wlan0: Failed to initiate sched scan ,使用了这个参数就能正常发起扫描。看起来,应该是某次升级过 wpa_supplicant 版本导致默认的country失效了,就会去连接 00:00:00:00:00:00 ,但是如果你强制同时指定 ssid 和 bssid ,也会导致 wlan0: Failed to initiate sched scan

Setup WiFi on a Pi Manually using wpa_supplicant.conf 提供了country解释:

The Country Code should be set the ISO/IEC alpha2 code for the country in which you are using your Pi. Common codes include :

  • gb (United Kingdom)

  • fr (France)

  • de (Germany)

  • us (United States)

  • se (Sweden)

经过验证,指定 bssid= 参数可以正常启动wpa_supplicant客户端,然后完成连接认证。存在的问题是,会反复出现EAP认证,显示认证成功,然后又断开重新认证成功。不过,反复多次以后,终于不再断开,也就完成认证,稳定连接,最终就能够完成无线认证并通过dhcpcd获得IP地址。

总之,最终的 wpa_supplicant-office.conf 如下:

折腾了好几天,终于能够完成无线连接。

不过,我在设置netplan中没有找到设置 country 的参数,例如配置 02-wifi.yaml 配置

但是 netplan apply 生成的配置 /run/netplan/wpa-wlan0.conf 内容并没有country参数

journalctl -u netplan-wpa-wlan0.service 还是看到如下报错

不过,既然已经知道是 country 导致的问题,我进一步搜索找到了 Help: Unable to connect to 5G Wifi on raspberry pi 4 using ubuntu server 18.04 ,关键点就是country code,因为5GHz是一个受控频率,需要根据不同国家进行调整country code,否则无法连接。临时的解决方法就是使用 wireless-tools 工具设置:

然后就能够正常连接。

要持久化上述country配置,修改 /etc/default/crda 配置,将默认的

修改成

然后重启就可以看到5GHz的WiFi正常工作了。

OMG 这真是一个折磨人的故障问题,我估计我断断续续花了一周时间才解决这个问题。

参考

Last updated

Was this helpful?