- PVSM.RU - https://www.pvsm.ru -

Linux WiFi из командной строки с wpa_supplicant

В этой статье я расскажу, как можно настроить WiFi с помощью wpa_supplicant, без всяких Xorg/X11 утилит. Это необходимо для того, чтобы базовые службы ОС исправно работали с минимальным набором технических средств удаленного доступа. Программа будет исполняться как служба, настройки сделаны правкой конфиг файлов.

По-быстрому, установить соединение с открытой точкой доступа можно таким образом.

[root@home ~]$ wpa_cli
> add_network
> set_network 0 ssid "MYSSID"
> set_network 0 key_mgmt NONE
> enable_network 0

Если же надо всерьез и надолго, то прошу внутрь.

Общие сведения о wpa_supplicant

Что из себя представляет wpa_supplicant?

  • Кросс-платформенная открытая реализация стандарта IEEE 802.11 [1] для Linux, *BSD, Windows, Mac OS X и прочих систем.
  • Полная поддержка WPA2, WPA и более старых протоколов безопасности беспроводной LAN сети.
  • Приложение пользовательского пространства, выполняющее функции саппликанта и SME [2] оператора, исполняющего MLME инструкции.

Wpa_supplicant поддерживает

  • WPA и полностью IEEE 802.11i/RSN/WPA2.
  • WPA-PSK и WPA2-PSK (pre-shared key) ("WPA-Personal").
  • WPA вместе с EAP (т.е., сервером аутентификации RADIUS) ("WPA-Enterprise") управление ключами CCMP, TKIP, WEP (104/128 и 40/64 бит).
  • Кэширование RSN, PMKSA: предварительную аутентификацию.

Linux WiFi из командной строки с wpa_supplicant - 1

Как wpa_supplicant устанавливает связь с точкой доступа?

  • Cетевой интерфейс должен исправно функционировать с установленным драйвером, прежде чем wpa_supplicant запустится.
  • Wpa_supplicant запрашивает драйвер ядра сканировать доступные Basic Service Set (BSS).
  • Wpa_supplicant производит выбор BSS в соответствии с настройками.
  • Wpa_supplicant запрашивает драйвер ядра установить соединение с выбранной BSS.
  • Для WPA-EAP: аутентификацию EAP производит встроенный IEEE 802.1X Supplicant, либо же внешний Xsupplicant с сервером аутентификации.
  • Для WPA-EAP: получен мастер-ключ от IEEE 802.1X Supplicant.
  • Для WPA-PSK wpa_supplicant использует пароль PSK в качестве мастер-ключа сессии.
  • Wpa_supplicant производит с аутентификатором точки доступа 4-х этапное согласование[1] [3] и групповое согласование ключей.
  • Wpa_supplicant производит шифрование однонаправленных и широковещательных пакетов[2] [4], после чего начинается обычный обмен данными.

Главный и большой плюс wpa_supplicant — его юниксвейность, то есть соответствие принципу Unix Way, когда программа делает что-то одно, но делает это хорошо. В каком-то смысле wpa_supplicant также Gentoo Way [5]. Она требует некоторого внимания и терпения вначале, но затем о ней можно напрочь забыть. После того как программа настроена и пущена в дело, она полностью выпадает из потока событий, превращаясь в пару строк из ps -ef. Она не сверкает и не мигает в системном трее, не оповещает о разведанных, подключенных и отключенных беспроводных сетях. Ее просто нет, пока вы сами ее не поищите.

Из минусов — сложность настройки и конфигурации. Много возни по сравнению с тырк-тырк-тырк в окне Network Manager, не говоря уже о WiFi подключении с любого Андроид устройства. Если вы собираетесь в поездку с Linux ноутбуком, то наверняка предпочтете более дружественный фронтенд настройки беспроводной сети, чтобы быстро подключаться к бесплатным точкам доступа WiFi в аэропорту, гостинице или в рабочей обстановке. Для домашнего же беспроводного интернета — самое то.

Установка

Если не выбирать графический фронтенд, то программа почти не тянет за собой никаких зависимостей. Для Gentoo Linux сгодится установка с выставленными флагами как показано.

(5:562)$ equery uses wpa_supplicant
[ Legend : U - final flag setting for installation]
[        : I - package is installed with flag     ]
[ Colors : set, unset                             ]
 * Found these USE flags for net-wireless/wpa_supplicant-2.6:
 U I
 - - ap                 : Add support for access point mode
 + + dbus               : Enable dbus support for anything that needs it (gpsd, gnomemeeting, etc)
 - - eap-sim            : Add support for EAP-SIM authentication algorithm
 - - fasteap            : Add support for FAST-EAP authentication algorithm
 - - gnutls             : Add support for net-libs/gnutls (TLS 1.0 and SSL 3.0 support)
 + + hs2-0              : Add support for 802.11u and Passpoint for HotSpot 2.0
 - - p2p                : Add support for Wi-Fi Direct mode
 - - qt4                : Add support for the Qt GUI/Application Toolkit version 4.x
 - - qt5                : Add support for the Qt 5 application and UI framework
 + + readline           : Enable support for libreadline, a GNU line-editing library that almost everyone wants
 - - smartcard          : Add support for smartcards
 + + ssl                : Add support for Secure Socket Layer connections
 - - tdls               : Add support for Tunneled Direct Link Setup (802.11z)
 - - uncommon-eap-types : Add support for GPSK, SAKE, GPSK_SHA256, IKEV2 and EKE
 - - wps                : Add support for Wi-Fi Protected Setup

Устанавливаем.

  • emerge -av wpa_supplicant #Gentoo
  • aptitude install wpasupplicant #Debian
  • yum install wpa_supplicant #Redhat
  • pacman -S wpa_supplicant #Arch

Подключение без конфиг файла

Если вам нужно подключиться только один раз, то необходимости создавать файл конфигурации и вникать во все тонкости настройки, нет. Достаточно набрать несколько инструкций из командной строки.

Пример для открытой сети был показан в самом начале. Для закрытой WPA сети быстрое подключение выгладит так:

В начале надо запустить саму программу wpa_supplicant и сопутствующую wpa_cli.

[root@home ~]$ wpa_supplicant -Dnl80211 -iwlan0 -C/var/run -u &
[root@home ~]$ wpa_cli -p/var/run

Затем настройка из интерактивного интерфейса wpa_cli.

> add_network
> set_network 0 ssid "name of AP"
> set_network 0 key_mgmt WPA-PSK
> set_network 0 pairwise TKIP
> set_network 0 psk "key"
> enable_network 0

Для закрытой WPA2 сети:

> add_network
> set_network 0 ssid "name of AP"
> set_network 0 key_mgmt WPA-PSK
> set_network 0 pairwise CCMP
> set_network 0 psk "key"
> enable_network 0

В конце необходимо вручную запустить демон DHCP.

[root@home ~]$ dhcpcd wlan0

Подключение к Ad-Hoc сети

Никогда с такой не сталкивался, но готовым нужно быть ко всему. Подключение к открытой ad-hoc.

> add_network
> set_network 0 ssid "adhoc-ssid"
> set_network 0 mode 1
> set_network 0 frequency 2412
> set_network 0 key_mgmt NONE
> enable_network 0

То же самое с помощью iw.

> iw dev wlan0 del
> iw phy phy0 interface add wlan0 type ibss
> ifconfig wlan0 up
> iw dev wlan0 scan                                            
> iw dev wlan0 ibss join AdHocNetworkName 2412 

Настройка для домашней сети

Теперь самое интересное — настройка. Этот процесс задокументирован для Arch Wiki [6], Debian Wiki [7] и Gentoo Wiki [8], но всех деталей там естественно нет.

Программа обычно ставится в директорию /etc/wpa_supplicant/, и наша задача — правильно настроить конфигурационный файл wpa_supplicant.conf, и привязать его к автозапуску беспроводного сетевого интерфейса.

Начнем с wpa_supplicant.conf. Если вы подключаетесь из дома к WPA/WPA2, то скорее всего используете пароль для WiFi соединения, что соответствует режиму WPA-PSK ("WPA-Personal"). Мы не будет рассматривать варианты с WEP шифрованием, так как оно ненамного лучше открытой сети.

Возьмем типовой конфиг из документации. Например такой.

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel
#
# home network; allow all valid ciphers
    network={
    ssid="home"
    scan_ssid=1
    key_mgmt=WPA-PSK
    psk="very secret passphrase"
 }

Первая строка необходима, без ctrl_interface программа даже не запустится. GROUP=wheel нужно для того, чтобы запускать из под обычного пользователя в графическом интерфейсе wpa_gui, но это не наш путь. Поэтому меняем на рутовый GROUP=0.

ctrl_interface_group=0
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1

Каждой сети в файле настроек должен соответствовать блок network {}. Покопавшись в исходниках, обнаружил нашел годное писание переменной ap_scan в файле config.h, а в мануале и руководстве пользователя ее описание очень скудное.

ap_scan=0 #драйвер сканирует точку доступа
ap_scan=1 #wpa_supplicant сканирует точку доступа, используется по-умолчанию
ap_scan=2 #как 0, но еще учитывает политики безопасности и SSID, работает с ndiswrapper

Полное описание

ap_scan — AP scanning/selection

By default, wpa_supplicant requests driver to perform AP scanning and then uses the scan results to select a suitable AP. Another alternative is to allow the driver to take care of AP scanning and selection and use wpa_supplicant just to process EAPOL frames based on IEEE 802.11 association information from the driver.

1: wpa_supplicant initiates scanning and AP selection (default).
0: Driver takes care of scanning, AP selection, and IEEE 802.11 association parameters (e.g., WPA IE generation); this mode can also be used with non-WPA drivers when using IEEE 802.1X mode;
do not try to associate with APs (i.e., external program needs to control association). This mode must also be used when using wired Ethernet drivers.

2: like 0, but associate with APs using security policy and SSID (but not BSSID); this can be used, e.g., with ndiswrapper and NDIS drivers to enable operation with hidden SSIDs and optimized roaming;
in this mode, the network blocks in the configuration are tried one by one until the driver reports successful association; each network block should have explicit security policy (i.e., only one
option in the lists) for key_mgmt, pairwise, group, proto variables.

Note: ap_scan=2 should not be used with the nl80211 driver interface (the current Linux interface). ap_scan=1 is optimized work working with nl80211. For finding networks using hidden SSID, scan_ssid=1 in the network block can be used with nl80211.

Остальные опции взяты из руководства конфиг файла [9].

  • bssid — The Basic Service Set Identifier (BSSID), физический адрес точки доступа.
  • key_mgmt — Протоколы аутентификации.
  • pairwise — Для WPA2 укажите CCMP, а для WPA — TKIP.
  • proto — WPA/WPA2.
  • psk — Хэш пароля PreShared Key.

руководство по настройкам

group: list of accepted group (broadcast/multicast) ciphers for WPA
CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key [IEEE 802.11]
If not set, this defaults to: CCMP TKIP WEP104 WEP40

pairwise: list of accepted pairwise (unicast) ciphers for WPA
CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
NONE = Use only Group Keys (deprecated, should not be included if APs support pairwise keys)

proto: list of accepted protocols
WPA = WPA/IEEE 802.11i/D3.0
RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)
If not set, this defaults to: WPA RSN

key_mgmt: list of accepted authenticated key management protocols
WPA-PSK = WPA pre-shared key (this requires 'psk' field)
WPA-EAP = WPA using EAP authentication (this can use an external program, e.g., Xsupplicant, for IEEE 802.1X EAP Authentication
IEEE8021X = IEEE 802.1X using EAP authentication and (optionally) dynamically generated WEP keys
NONE = WPA is not used; plaintext or static WEP could be used
If not set, this defaults to: WPA-PSK WPA-EAP

Создаем хэш пароля для psk:

$ wpa_passphrase MYSSID passphrase

Все готово, чтобы создать конфиг сети. Итоговый файл должен выглядеть как-то так.

ctrl_interface_group=0
ap_scan=1
ctrl_interface=/var/run/wpa_supplicant
network={
    proto=WPA2
    pairwise=CCMP
    key_mgmt=WPA-PSK
    priority=5
    ssid="MYSSID"
    bssid=44:b0:51:dc:ba:f8
    psk=ce55977186ae1df2dffeb571acee8dacd92f49edddbdef53623132e3c24567ae
}

Верные значения для bssid, group, proto и pairwise можно определить, сканируя беспроводную сеть.

[root@home ~]$ iwlist <wlan_interface> scan

Команда iwlist из набора Wireless Tools устарела, вместо нее сейчас iw.

[root@home ~]$ iw dev <wlan_interface> scan

Настройка 802.1X для офиса

Стандарт IEEE 802.1X определяет более строгую модель подключения к WiFi сети. Вместо psk пароля необходимо предъявить серверный сертификат.

  • ca_cert — Абсолютный путь к CA-сертификату в формате PEM или DER, необходим для возможности подтверждения сертификата сервера.
  • ca_path — Абсолютный путь к директории, где хранятся файлы CA-сертификатов (в формате PEM), которые вы хотите добавить в список доверенных.
  • client_cert — Абсолютный путь к клиентскому сертификату в формате PEM или DER.
  • eap — Разделенный пробелами список поддерживаемых методов EAP: MD5, MSCHAPV2, OTP, GTC, TLS, PEAP, или TTLS.
  • identity — Идентификации EAP, например имя пользователя.
  • password — Пароль EAP.

Так может выглядеть блок, настроенный для подключения к сети в режиме WPA-Enterprise с аутентификацией 802.1X PEAP, в котором требуется ввод данных учетной записи пользователя:

network = {
ssid="Company WPA2 EAP"
key_mgmt=WPA-EAP
pairwise=TKIP
group=TKIP
eap=PEAP
identity="username@domain"
password="your_passphrase"
ca_cert="/etc/cert/ca.pem"
phase1="peapver=0"
phase2="MSCHAPV2"
}

А это пример блока, настроенного для подключения к сети в режиме WPA-Enterprise с аутентификацией 802.1X EAP-TLS, в котором требуются серверный и клиентский сертификаты:

network = {
ssid="Company WPA2 TLS"
key_mgmt=WPA-EAP
pairwise=CCMP
group=CCMP
eap=TLS
ca_cert="/etc/cert/ca.pem"
private_key="/etc/cert/privkey.p12"
private_key_passwd="your_passphrase PKCS#12"
}

Привязка wpa_supplicant к сетевой карте

Для Gentoo Linux надо добавить 2 строки в /etc/conf.d/net.

modules=( "wpa_supplicant" )
wpa_supplicant_wlan0="-Dnl80211"

Список поддерживаемых -D<driver> драйверов. Для современных чипов и версий ядра подойдет nl80211. На старом железе может взлететь wext.

  • nl80211 — New driver.
  • wext — Linux wireless extensions (generic).
  • wired — wpa_supplicant wired Ethernet driver.
  • roboswitch — wpa_supplicant Broadcom switch driver.
  • bsd — BSD 802.11 support (Atheros, etc.).
  • ndis — Windows NDIS driver.

Сетевая карта wlan0 должна быть залинкована с lo0.

lrwxrwxrwx 1 root root 6 ноя 29  2014 /etc/init.d/net.wlan0 -> net.lo

Следует также добавить wpa_supplicant в автозапуск.

 [root@home ~]$ rc-update add wpa_supplicant default

Пользователи Debian добавляют запись в файл /etc/network/interfaces.

auto wlan0
iface wlan0 inet dhcp
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

Пользователи RedHat добавляют в /etc/sysconfig/wpa_supplicant

INTERFACES="-iwlan0"

а в файл /etc/sysconfig/network-scripts/ifcfg-wlan0

ESSID="home"
NAME=wlan0
MODE=Managed
KEY_MGMT=WPA-PSK
TYPE=Wireless
BOOTPROTO=dhcp
DEFROUTE=yes
ONBOOT=yes
HWADDR=aa:bb:cc:dd:ee
IPV6INIT=yes
IPV6_AUTOCONF=yes

Отладка

После того как wpa_supplicant успешно подключилась к точке доступа, в dmesg можно увидеть протокол установки соединения.

[243960.587] cfg80211: World regulatory domain updated:
[243960.587] cfg80211: DFS Master region: unset
[243960.587] cfg80211: (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[243960.587] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
[243960.587] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz, 92000 KHz AUTO), (2000 mBm), (N/A)
[243960.587] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
[243960.587] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (2000 mBm), (N/A)
[243960.587] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (2000 mBm), (0 s)
[243960.587] cfg80211: (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
[243960.587] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), 
[243960.587] cfg80211: (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm),
[243963.070] wlan0: authenticate with aa:bb:cc:dd:ee
[243963.075] wlan0: send auth to aa:bb:cc:dd:ee (try 1/3)
[243963.077] wlan0: authenticated
[243963.084] wlan0: associate with aa:bb:cc:dd:ee (try 1/3)
[243963.088] wlan0: RX AssocResp from aa:bb:cc:dd:ee (capab=0x411 status=0 aid=3)
[243963.090] wlan0: associated

Если же вместо этого вы увидите ошибку:

Successfully initialized wpa_supplicant
nl80211: Driver does not support authentication/association or connect commands
wlan0: Failed to initialize driver interface

то скорее всего, надо использовать драйвер wext вместо nl80211. А с ошибкой:

WEXT: Driver did not support SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE

наоборот, вместо wext надо подставить nl80211.
В ситуации, когда вы не можете определить ошибку, запустите wpa_supllicant напрямую с ключем -dd.

[root@home ~]$ wpa_supplicant -Dnl80211 -iwlan0 -C/var/run/wpa_supplicant/ -c/etc/wpa_supplicant/wpa_supplicant.conf -dd

Использованные материалы


  1. [14] 4-way handshake
  2. [14] Unicast and broadcast

Автор: temujin

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/linux/213985

Ссылки в тексте:

[1] стандарта IEEE 802.11: https://en.wikipedia.org/wiki/IEEE_802.11i

[2] SME: https://wireless.wiki.kernel.org/en/developers/documentation/glossary#sme

[3] [1]: #cite_ref-1

[4] [2]: #cite_ref-2

[5] Gentoo Way: https://habrahabr.ru/post/315048/

[6] Arch Wiki: https://wiki.archlinux.org/index.php/WPA_supplicant_(Русский)

[7] Debian Wiki: https://wiki.debian.org/ru/WiFi/HowToUse#wpa_supplicant

[8] Gentoo Wiki: https://wiki.gentoo.org/wiki/Wpa_supplicant

[9] руководства конфиг файла: https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf

[10] WL18XX Linux WIreless Architecture: http://processors.wiki.ti.com/index.php/WL18xx_Linux_Wireless_Architecture

[11] Linux Kernel Wireless: https://wireless.wiki.kernel.org/

[12] wpa_supplicant and wifi in RHEL 7: http://www.ilmostro.info/2014/12/wpasupplicant-and-wifi-in-rhel-7.html

[13] Linux WPA Supplicant (IEEE 802.1X, WPA, WPA2, RSN, IEEE 802.11i): http://w1.fi/wpa_supplicant/

[14] ↑: #cite_note-2

[15] Источник: https://habrahabr.ru/post/315960/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best