Linuxで無線LANが繋がらない時の対処法
お伝えしたいこと
NUC10を購入してFedoraをインストールしてから約半年間、長らく無線LANが使えない状況でした。
NUCはミニPCとはいえデスクトップなので、私は基本有線で使っています。
無線LANクライアントをずっと無効化したまま使っていました。
その状況が変わり、最近正しく動くようになったので、経緯を共有します。
無線LANが動かずに困っている方に役に立てば良いなと思います。
今回は無線LANの理解を深める前にあっさり直ってしまったため、内容としては薄めです。
1つのケーススタディとして見ていただければと思います。
- お伝えしたいこと
- 環境
- 発生事象
- 無線LANが動かない原因
- (原因1) 無線LANデバイスが正しく認識されない
- (原因2) パッケージが足りていない
- (参考) 起動できないネットワークは無効化すべき
- まとめ
- 関連記事
環境
私の環境を貼っておきます。
項目 | 概要 |
---|---|
PC本体 | BXNUC10i5FNH |
無線LANクライアント (内蔵) | Intel® Wi-Fi 6 AX201 (参考元) |
OS | Fedora33 |
発生事象
GUIでの確認
トラブル発生時、GUI上で無線LANを有効化してもSSIDが全く表示されませんでした。
本来であれば、以下のように表示されるはずです。
CLIでの確認
CLIでも同様に、SSIDが表示されないことを確認しました。
1行目のコマンドで、無線LANクライアントが有効化されていることを確認しています。
無効の場合は、nmcli radio wifi on
で有効化できます。
2行目のコマンドで、SSIDを一覧表示しようとしています。
しかし、どういうわけか何も表示されません。
nmcli radio wifi # enabled nmcli device wifi list # IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
本来では、以下のように表示されるはずです。
nmcli device wifi list # IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY # AA:BB:CC:DD:EE:FF my-ssid1 Infra 11 405 Mbit/s 100 ▂▄▆█ WPA1 WPA2 # 11:12:13:14:15:16 my-ssid2 Infra 64 405 Mbit/s 100 ▂▄▆█ WPA1 WPA2 # 00:11:22:33:44:55 my-ssid3 Infra 9 270 Mbit/s 55 ▂▄__ WPA2
無線LANが動かない原因
私のケースでは、2つの原因がありました。
この2つの原因について、順を追って共有します。
(原因1) 無線LANデバイスが正しく認識されない
必要なドライバが足りてなかったことで、無線LANデバイスを正しく認識できていなかったようです。
以下に詳細なログを貼ります。
原因1の切り分け
dmesg (Linuxブート中のログ) を見ると、iwlwifi
という無線LANクライアントのドライバが無線LANクライアントを正しく検出できず、何度かフォールバックしているように見えます。
※ちなみにiwlwifi
は、Intel製無線LANに関わるドライバの名称です (iwl = Intel Wireless LAN?)
特に、以下のエラーが悪影響を与えている印象でした。
Direct firmware load for iwlwifi-QuZ-a0-hr-b0-56.ucode failed with error -2
Direct firmware load for iwl-debug-yoyo.bin failed with error -2
しかし最後にAX201という正しいデバイスを認識できているようには見えます。
Detected Intel(R) Wi-Fi 6 AX201 160MHz, REV=0x354
dmesg | grep iwlwifi # [ 5.445530] iwlwifi 0000:00:14.3: enabling device (0000 -> 0002) # [ 5.447086] iwlwifi 0000:00:14.3: Direct firmware load for iwlwifi-QuZ-a0-hr-b0-56.ucode failed with error -2 # [ 5.449460] iwlwifi 0000:00:14.3: api flags index 2 larger than supported by driver # [ 5.449471] iwlwifi 0000:00:14.3: TLV_FW_FSEQ_VERSION: FSEQ Version: 65.3.35.22 # [ 5.449475] iwlwifi 0000:00:14.3: Found debug destination: EXTERNAL_DRAM # [ 5.449476] iwlwifi 0000:00:14.3: Found debug configuration: 0 # [ 5.449698] iwlwifi 0000:00:14.3: loaded firmware version 55.d9698065.0 QuZ-a0-hr-b0-55.ucode op_mode iwlmvm # [ 5.449864] iwlwifi 0000:00:14.3: Direct firmware load for iwl-debug-yoyo.bin failed with error -2 # [ 5.628261] iwlwifi 0000:00:14.3: Detected Intel(R) Wi-Fi 6 AX201 160MHz, REV=0x354 # [ 5.806506] iwlwifi 0000:00:14.3: base HW address: 04:33:c2:81:04:11 # [ 5.821843] iwlwifi 0000:00:14.3 wlp0s20f3: renamed from wlan0
ただ、この話には続きがあります。
lspci
コマンドで、Linuxが認識しているPCIデバイスを表示できます。
正しくはAX201と表示されるはずですが、なぜかIntel Corporation Wireless-AC 9462
と表示されています。
単なる表示上の問題であれば良いのですが、iwlwifiが正しくデバイスを認識できていない可能性も出てきました。
sudo lspci -v | grep -A12 -i 'network controller' # 00:14.3 Network controller: Intel Corporation Wireless-AC 9462 # Subsystem: Intel Corporation Device 0074 # Flags: bus master, fast devsel, latency 0, IRQ 16 # Memory at 6023114000 (64-bit, non-prefetchable) [size=16K] # Capabilities: [c8] Power Management version 3 # Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+ # Capabilities: [40] Express Root Complex Integrated Endpoint, MSI 00 # Capabilities: [80] MSI-X: Enable+ Count=16 Masked- # Capabilities: [100] Latency Tolerance Reporting # Capabilities: [164] Vendor Specific Information: ID=0010 Rev=0 Len=014 <?> # Kernel driver in use: iwlwifi # Kernel modules: iwlwifi
一方で、正常なときは、以下のようなログになります。
Linux起動時には特にエラーログはなく、フォールバックも発生していません。
読み込まれたファームウェアのファイル名も事象発生時と変わっており、QuZ-a0-hr-b0-59.ucode
と記載があります。
このファイルの実体は/usr/lib/firmware/iwlwifi-QuZ-a0-hr-b0-59.ucode
にあります。
dmesg | grep iwlwifi # [ 4.339129] iwlwifi 0000:00:14.3: enabling device (0000 -> 0002) # [ 4.341962] iwlwifi 0000:00:14.3: api flags index 2 larger than supported by driver # [ 4.341971] iwlwifi 0000:00:14.3: TLV_FW_FSEQ_VERSION: FSEQ Version: 65.3.35.22 # [ 4.342152] iwlwifi 0000:00:14.3: loaded firmware version 59.601f3a66.0 QuZ-a0-hr-b0-59.ucode op_mode iwlmvm # [ 4.505557] iwlwifi 0000:00:14.3: Detected Intel(R) Wi-Fi 6 AX201 160MHz, REV=0x354 # [ 4.688618] iwlwifi 0000:00:14.3: base HW address: 04:33:c2:81:04:11 # [ 4.704444] iwlwifi 0000:00:14.3 wlp0s20f3: renamed from wlan0
Linuxが認識しているデバイス名も、AX201という正しい情報が表示されています。
sudo lspci -v | grep -A12 -i 'network controller' # 00:14.3 Network controller: Intel Corporation Comet Lake PCH-LP CNVi WiFi # Subsystem: Intel Corporation Wi-Fi 6 AX201 160MHz # Flags: bus master, fast devsel, latency 0, IRQ 16, IOMMU group 5 # Memory at 6023114000 (64-bit, non-prefetchable) [size=16K] # Capabilities: [c8] Power Management version 3 # Capabilities: [d0] MSI: Enable- Count=1/1 Maskable- 64bit+ # Capabilities: [40] Express Root Complex Integrated Endpoint, MSI 00 # Capabilities: [80] MSI-X: Enable+ Count=16 Masked- # Capabilities: [100] Latency Tolerance Reporting # Capabilities: [164] Vendor Specific Information: ID=0010 Rev=0 Len=014 <?> # Kernel driver in use: iwlwifi # Kernel modules: iwlwifi
原因1の解決策
しばらくぶりにsudo dnf upgrade
でパッケージを更新したら、上述の正常なログが出るようになりました。
ucodeファイルがそもそも足りていなかったか、iwlwifiがucodeファイルを正しく参照できていなかったか。
いずれにしても、iwlwifi自体に何らかの不具合か互換性不足があり、それがパッケージ更新によって解消されたようです。
時間が解決した、ということですね。
私の環境ではiwl7260-firmware
というrpmパッケージが関係あるようでした。
このパッケージの特定方法は、次のセクションに書きます。
(参考) 必要なrpmファイルの特定の仕方
iwlwifiのドライバが含まれるrpmパッケージは、以下のとおりたくさんあります。
ここでは、以下のrpmパッケージの中に自分が使っている無線LANクライアントに対応したものがあるか確認する方法を紹介します。
今回の方法はrpmを利用するRedHat系かつ、Intel製無線LANクライアントを使っている場合のみ使えます。
条件に該当しない方は、適宜手順をアレンジする必要があります。
rpm -qa | grep iwl # iwl100-firmware-39.31.5.1-119.fc33.noarch # iwl1000-firmware-39.31.5.1-119.fc33.noarch # iwl105-firmware-18.168.6.1-119.fc33.noarch # iwl135-firmware-18.168.6.1-119.fc33.noarch # iwl2000-firmware-18.168.6.1-119.fc33.noarch # iwl2030-firmware-18.168.6.1-119.fc33.noarch # iwl3160-firmware-25.30.13.0-119.fc33.noarch # iwl3945-firmware-15.32.2.9-119.fc33.noarch # iwl4965-firmware-228.61.2.24-119.fc33.noarch # iwl5000-firmware-8.83.5.1_1-119.fc33.noarch # iwl5150-firmware-8.24.2.2-119.fc33.noarch # iwl6000-firmware-9.221.4.1-119.fc33.noarch # iwl6000g2a-firmware-18.168.6.1-119.fc33.noarch # iwl6000g2b-firmware-18.168.6.1-119.fc33.noarch # iwl6050-firmware-41.28.5.1-119.fc33.noarch # iwl7260-firmware-25.30.13.0-119.fc33.noarch
まず、自分が利用している製品の型番を前述のlspci -v
で確認します。
lspci -vmm
の方が見やすいかもしれません。
今回の場合は、AX201だとわかったとします。
この後すぐできる最も簡単な確認方法は、dnf search
コマンドで検索することです。
パッケージの説明文に型番が書いてあるので、今回はこの方法が使えます。
この結果、iwl7260-firmware
がヒットしました。
dnf search AX201
# iwl7260-firmware.noarch : Firmware for Intel(R) Wireless WiFi Link 726x/8000/9000/AX200/AX201 Series Adapters
上記方法でヒットしないケースもあります。
例えばAX210に対応するドライバも上記パッケージに本当は含まれているのですが、説明文に書いてないのでヒットしません。
そんなときは、次の方法で確認します。
Linux Wireless WikiでサポートされているIntel製無線LAN機器の一覧を確認します。
このページでAX201を検索し、対応するドライバが含まれるtar.gzファイルをダウンロードして中身を確認します。
今回は、iwlwifi-Qu-48.13675109.0.tgz
をダウンロードします。
すると、中にいくつかのucode
ファイルが入っています。
どれでも良いので、一つのucodeファイルの名前をメモしてください。
今回は、iwlwifi-Qu-b0-hr-b0-48.ucode
にします。
続いて、dnf provides
コマンドで上記ファイルを含むrpmパッケージを検索します。
dnf provides
には、ファイルをフルパスで指定する必要があります。
今回は/usr/lib/firmware/iwlwifi-Qu-b0-hr-b0-48.ucode
が正しい指定方法なのですが、フルパスを知らなくてもワイルドカードで検索できます。
**
は、任意の文字列かつ、任意階層分だけフォルダを下った場合もマッチするワイルドカードです。
言い換えると、**
は「/を含む任意の文字列」にマッチします。
dnf provides **iwlwifi-Qu-b0-hr-b0-48.ucode
# iwl7260-firmware-1:25.30.13.0-119.fc33.noarch : Firmware for Intel(R) Wireless WiFi Link 726x/8000/9000/AX200/AX201 Series Adapters
以上の確認により、AX201に必要なrpmパッケージはiwl7260-firmware
だとわかりました。
もちろん、私の環境において必要だったQuZ-a0-hr-b0-59.ucode
も今回の検索でヒットします。
dnf provides **QuZ-a0-hr-b0-59.ucode
# iwl7260-firmware-1:25.30.13.0-119.fc33.noarch : Firmware for Intel(R) Wireless WiFi Link 726x/8000/9000/AX200/AX201 Series Adapters
本来必要なucodeファイルは、事象解消時のdmesgから読み取れます。
トラブル発生中に必要なucodeファイルを見抜く方法は、残念ながら私にはわかりませんでした。
# [ 4.342152] iwlwifi 0000:00:14.3: loaded firmware version 59.601f3a66.0 QuZ-a0-hr-b0-59.ucode op_mode iwlmvm
(原因2) パッケージが足りていない
原因1を解決してもSSIDが表示されなかったので、更に調査を進めました。
その結果、wpa_supplicant
というパッケージが不足していることが原因だとわかりました。
原因2の切り分け
無線LANを有効化したタイミングで、/var/log/messages
に以下のログが発生していました。
恐らく、journalctl -xeu NetworkManager
でも同様のログを確認できると思います。
NetworkManager[950]: <error> [1619738834.7337] device (wlp0s20f3): Couldn't initialize supplicant interface: Failed to D-Bus activate wpa_supplicant service
原因2の解決策
以下のコマンドでwpa_supplicant
をインストールすることで直りました。
sudo dnf install wpa_supplicant
このパッケージにより、wpa_supplicant.service
が作成されます。
このサービスは無線LANを有効化したタイミングで自動起動されるので、有効化する必要はないようです。
sudo systemctl enable --now wpa_supplicant.service
の実行は、私の環境では不要でした。
以上の対応により原因1と原因2を解消し、無事無線が使えるようになりました。
(参考) wpa_supplicantとは?
wpa_supplicant
とは、WEP、WPA、WPA2などの無線LAN暗号化技術における認証クライアントです。
言い換えれば、上述の暗号化技術を用いて無線LAN接続をするのに必要なプログラムです (参考:ArchLinux Wiki)。
初期状態のFedora33には、wpa_supplicant
がインストールされていないようです。
これにより、SSIDを表示することすらできなかったようです。
(参考) 起動できないネットワークは無効化すべき
主張
今回の事象のように、無線LANが使えないなどの理由でNetworkManagerのconnectionが起動できないケースはあると思います。
基本的には、connectionが使えないときはその原因を排除して使えるようにするのが良いと思います。
しかしどうしても解決できないときは、OS起動の度にconnection起動を失敗させるのではなく、connectionを初めからdownさせておくべきです。
コマンドでいうと、nmcli radio wifi off
などです。
autoconnect off
よりも更にシンプルに、デバイスレベルでwifiを無効にします。
理由
起動に失敗するconnectionを停止しておくべき理由は、OSの起動が遅くなるためです。
LinuxのOSが起動する際、様々なサービスが順番に起動します。
systemctl cat <unit>
を実行するとわかりますが、サービス間には依存関係があります。
特に多くのサービスは、ネットワークに依存しています。
つまり、ネットワーク接続が完了しないと、他のサービスの起動が開始されません。
NetworkManager.service については、ネットワーク起動を待つための専用サービスがあります。
それがNetworkManager-wait-online.serviceです。
中身を見てみましょう。
description、実行コマンド、環境変数のみ抜粋しています。
systemctl cat NetworkManager-wait-online # `nm-online -s` waits until the point when NetworkManager logs # "startup complete". That is when startup actions are settled and # devices and profiles reached a conclusive activated or deactivated # state. # ExecStart=/usr/bin/nm-online -s -q # Environment=NM_ONLINE_TIMEOUT=30
内部的にはnm-online -s -q
を実行していて、NetworkManagerがstartup complete
というログを出力するまで待つようです。
NetworkManagerが30秒以内にログを出さなければ、NetworkManager-wait-online
がタイムアウトする作りです。
NetworkManager-wait-onlineは、NetworkManagerサービスの起動を最大30秒待つことで、他のネットワークに依存するサービスの起動失敗を防ぐ仕組みです。
内部的に実行しているnm-online
のmanを見てみます。
-s
オプションの説明に以下の記述がありました。
autoconnect (connectionの自動起動) に失敗すると、NetworkManagerの起動完了を遅延させるケースがあるようです。
実際、無線LANの自動起動に失敗することでLinuxの起動が遅くなることが確認できました。
For example, by setting a connection profile to autoconnect, such a profile possibly will activate during startup and thus delay startup complete being reached.
どの程度起動が遅くなるのか
では、connection自動起動の失敗により、Linuxの起動がどの程度遅くなるのか。
systemd-analyze blame
コマンドで大体の検討がつきます。
systemd-analyze blame
を実行すると、各サービスの起動にかかった時間を長い順に表示します。
NetworkManager-wait-online
の数字が30秒の場合は、何かがおかしいことが多いです。
systemd-analyze blame # 10.568s dnf-makecache.service # 9.205s NetworkManager-wait-online.service # 948ms systemd-udev-settle.service
ただし気をつけていただきたいのは、この表示はLinux起動時間に影響を与えた時間ではありません。
純粋に各プロセスの起動から停止までにかかった時間を表しています。
上記表示は、「NetworkManager-wait-online.serviceによりLinuxの起動が9.205秒遅延した」という意味ではありません。
...今回の場合は、起動に約9秒の影響を与えていますが。
影響を見るには、次のコマンドが適切です。
起動時間のグラフをSVGファイルとして出力します。
GUIで開くことで、画像として開くことができます。
systemd-analyze plot > tmp.svg
グラフは以下のように見えます。
NetworkManager-wait-online.serviceが完了するまで9.2秒待ち続け、その後network-online.targetが起動し、他のネットワークに依存するサービスが起動開始しています。
まとめ
Linuxの無線LANが動作しない原因を2パターン紹介しました。
同じような事象で困っている方の役に立てれば嬉しいです。
無線LANがうまく動作しないときは停止させておくのもぜひ実践してみてください。
Linuxの起動が更に早くなりますよ。
一方、NetworkManager-wait-onlineを無効化するのは、やめておいたほうが良いと思います。
関連記事
Linux パソコン関連の記事をまとめてあります。