wpa_supplicant

wpa_supplicant is a cross-platform supplicant with support for WPA, WPA2 and WPA3 (IEEE 802.11i). It is suitable for desktops, laptops and embedded systems. It is the IEEE 802.1X/WPA component that is used in the client stations. It implements key negotiation with a WPA authenticator and it controls the roaming and IEEE 802.11 authentication/association of the wireless driver.

Installation

Install the wpa_supplicant package, which includes the main program wpa_supplicant, the passphrase tool wpa_passphrase, and the text front-end wpa_cli.

Optionally, also install the official wpa_supplicant_guiAUR which provides wpa_gui, a graphical front-end for wpa_supplicant, or wpa-cuteAUR which is a fork from an earlier version of wpa_gui with a couple of fixes and improvements.

Overview

The first step to connect to an encrypted wireless network is having wpa_supplicant obtain authentication from a WPA authenticator. In order to do this, wpa_supplicant must be configured so that it will be able to submit the correct credentials to the authenticator.

Once you are authenticated you need to assign an IP address, see Network configuration#IP addresses.

Connecting with wpa_cli

This connection method allows scanning for available networks, making use of wpa_cli, a command line tool which can be used to configure wpa_supplicant. See wpa_cli(8) for details.

In order to use wpa_cli, a control interface must be specified for wpa_supplicant, and it must be given the rights to update the configuration. Do this by creating a minimal configuration file:

/etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/run/wpa_supplicant
update_config=1

Now start wpa_supplicant with:

# wpa_supplicant -B -i interface -c /etc/wpa_supplicant/wpa_supplicant.conf
Tip: To discover your wireless network interface name, see Network configuration#Network interfaces.

At this point run:

# wpa_cli

This will present an interactive prompt (), which has tab completion and descriptions of completed commands.

Use the and commands to see the available networks:

> scan
OK
<3>CTRL-EVENT-SCAN-RESULTS
> scan_results
bssid / frequency / signal level / flags / ssid
00:00:00:00:00:00 2462 -49 [WPA2-PSK-CCMP][ESS] MYSSID
11:11:11:11:11:11 2437 -64 [WPA2-PSK-CCMP][ESS] ANOTHERSSID

To associate with MYSSID, add the network, set the credentials and enable it:

> add_network
0
> set_network 0 ssid "MYSSID"
> set_network 0 psk "passphrase"
> enable_network 0
<2>CTRL-EVENT-CONNECTED - Connection to 00:00:00:00:00:00 completed (reauth) [id=0 id_str=]

If the SSID does not have password authentication, you must explicitly configure the network as keyless by replacing the command set_network 0 psk "passphrase" with .

Finally save this network in the configuration file and quit wpa_cli:

> save_config
OK
> quit

Once association is complete, you must obtain an IP address, for example, using dhcpcd.

Connecting with wpa_passphrase

This connection method allows quickly connecting to a network whose SSID is already known, making use of wpa_passphrase, a command line tool which generates the minimal configuration needed by wpa_supplicant. For example:

This means that wpa_supplicant can be associated with wpa_passphrase and started with:

# wpa_supplicant -B -i interface -c <(wpa_passphrase MYSSID passphrase)

Finally, you should obtain an IP address, see Network configuration#IP addresses.

Advanced usage

For networks of varying complexity, possibly employing extensive use of EAP, it will be useful to maintain a customised configuration file. For an overview of the configuration with examples, refer to ; for details on all the supported configuration parameters, refer to the example file .

Configuration

As explained in #Connecting with wpa_passphrase, a basic configuration file can be generated with:

# wpa_passphrase MYSSID passphrase > /etc/wpa_supplicant/example.conf

This will only create a section. A configuration file with also the ability of #Connecting with wpa_cli and some other common options may look like:

/etc/wpa_supplicant/example.conf
# Giving configuration update rights to wpa_cli
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1

# AP scanning
ap_scan=1

# ISO/IEC alpha2 country code in which the device is operating
country=US

# network section generated by wpa_passphrase
network={
    ssid="MYSSID"
    psk=59e0d07fa4c7741797a4e394f38a5c321e3bed51d54ad5fcbd3f84bc7415d73d
}

If security is not a concern, the passphrase can also be defined in clear text in the section by enclosing it in quotes:

psk="passphrase"

If the network does not have a passphrase, e.g. a public Wi-Fi:

network={
   ssid="MYSSID"
   key_mgmt=NONE
}

To connect to a WPA-Enterprise network, see #802.1x/radius.

Further blocks may be added manually, or using wpa_cli as illustrated in #Connecting with wpa_cli. In order to use wpa_cli, a control interface must be set with the ctrl_interface option. Setting allows users belonging to such group to execute wpa_cli. This setting can be used to enable users without root access (or equivalent via sudo etc) to connect to wireless networks. Also add so that changes made with wpa_cli to can be saved. Note that any user that is a member of the group will be able to make changes to the file if this is turned on.

and  are the wpa_supplicant options active globally at the time of writing. Whether you need them, or other global options too for that matter, depends on the type of network to connect to. If you need other global options, simply copy them over to the file from . 

Alternatively, can be used to see options' status or set new ones. Multiple network blocks may be appended to this configuration: the supplicant will handle association to and roaming between all of them. The strongest signal defined with a network block usually is connected to by default, one may define to influence behaviour. For example to auto-connect to any unsecured network as a fallback with the lowest priority:

network={
   key_mgmt=NONE
   priority=-999
}

Once you have finished the configuration file, you can optionally use it as a system-wide or per-interface default configuration by naming it according to the paths listed in #At boot (systemd). This also applies if you use additional network manager tools, which may rely on the paths (for example Dhcpcd#10-wpa_supplicant).

Tip: To configure a network block to a hidden wireless SSID, which by definition will not turn up in a regular scan, the option scan_ssid=1 has to be defined in the network block.

Manual

First start wpa_supplicant command, whose most commonly used arguments are:

  • - Fork into background.
  • - Path to configuration file.
  • - Interface to listen on.
  • -D driver - Optionally specify the driver to be used. For a list of supported drivers see the output of .
    • is the current standard, but not all wireless chip's modules support it.
    • is currently deprecated, but still widely supported.

See for the full argument list. For example:

# wpa_supplicant -B -i interface -c /etc/wpa_supplicant/example.conf

followed by a method to obtain an ip address manually as indicated in the #Overview, for example:

# dhcpcd interface

At boot (systemd)

The wpa_supplicant package provides multiple systemd service files:

  • - uses D-Bus, recommended for NetworkManager users.
  • wpa_supplicant@interface.service - accepts the interface name as an argument and starts the wpa_supplicant daemon for this interface. It reads a configuration file. Useful when using systemd-networkd.
  • - also interface specific, but explicitly forces the driver (see below). The configuration file path is .
  • - also interface specific, uses the driver. The configuration file path is .

To enable wireless at boot, enable an instance of one of the above services on a particular wireless interface. For example, enable the systemd unit.

Now choose and enable an instance of a service to obtain an ip address for the particular interface as indicated in the #Overview. For example, enable the systemd unit.

Tip: dhcpcd has a hook that can launch wpa_supplicant implicitly, see dhcpcd#10-wpa_supplicant.
802.1x/radius

To connect a wired adapter using 802.1x/radius you will need to specify some configurations and enable the necessary service for the adapter. This is useful for headless servers using networkd.

Replace with the wired adapter you wish to connect, and adapt the settings to match your 802.1x/radius requirements.

/etc/wpa_supplicant/wpa_supplicant-wired-''adapter''.conf
ctrl_interface=/run/wpa_supplicant
ap_scan=0
network={
  key_mgmt=IEEE8021X
  eap=PEAP
  identity="''user_name''"
  password="''user_password''"
  phase2="autheap=MSCHAPV2"
}

Since this file is storing a plaintext password, chown it to and chmod it to .

To use the hash instead of the plaintext password, you can use the keyword:

password=hash:hash_of_plaintext_password

To hash your password:

$ iconv -t utf16le | openssl md4

After invoking the command above, provide your plain password and then press .

Before running the service, make sure to set the device down:

# ip link set adapter down

wpa_cli action script

wpa_cli can run in daemon mode and execute a specified script based on events from wpa_supplicant. Two events are supported: CONNECTED and . Some environment variables are available to the script, see wpa_cli(8) for details.

The following example will use desktop notifications to notify the user about the events:

Remember to make the script executable, then use the -a flag to pass the script path to wpa_cli:

$ wpa_cli -a /path/to/script

Roaming

When connected to a wireless network with multiple access points, wpa_supplicant is typically responsible for roaming between access points. Choosing a new access point requires wpa_supplicant to perform a scan of available networks, which causes a brief interruption in connectivity to the current access point while the wireless radio scans other frequencies. After a scan, if wpa_supplicant detects a closer access point (BSSID) in the current network (SSID), in terms of signal strength (RSSI), it will re-associate to the closer access point.

The default configuration of wpa_supplicant has relatively timid roaming: it will rescan only when the association to the current access point is lost. This means that, if a client moves far away from its current access point, but not far enough to completely lose signal, the client will keep using the weak signal instead of roaming to a closer access point.

To make wpa_supplicant more aggressive about roaming, set the parameter in the configuration file, such as:

bgscan="simple:30:-70:3600"

The above example will cause wpa_supplicant to scan every 30 seconds when the signal is weak (below -70), and every 3600 seconds otherwise. can be specified either in specific blocks or globally for all networks.

Troubleshooting

Debugging connection failures

In order to determine why you are unable to connect to an access point you can run wpa_supplicant with the flag for debug messages, wait a couple seconds then look for lines that list SSIDs and the reason they were not connected to. For example:

In this case we are trying to connect to an access point with the SSID home. The reason the connection fails is , so we need to add to our configuration file.

nl80211 driver not supported on some hardware

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

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

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

# wpa_supplicant -B -i wlan0 -D wext -c /etc/wpa_supplicant/example.conf

If the command works to connect, and the user wishes to use systemd to manage the wireless connection, it is necessary to edit the unit provided by the package and modify the line accordingly:

/etc/systemd/system/wpa_supplicant@.service.d/wext.conf
[Service]
ExecStart=
ExecStart=/usr/bin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I '''-Dnl80211,wext'''

Problem with mounted network shares (cifs) and shutdown

When you use wireless to connect to network shares you might have the problem that the shutdown takes a very long time. That is because systemd runs against a 3 minute timeout. The reason is that WPA supplicant is shut down too early, i.e. before systemd tries to unmount the share(s). A bug report suggests a work-around by editing the as follows:

wpa_supplicant may not work properly if directly passed via stdin particularly long or complex passphrases which include special characters. This may lead to errors such as failed 4-way WPA handshake, PSK may be wrong when launching wpa_supplicant.

In order to solve this try using here strings or passing a file to the flag instead:

# wpa_supplicant -i <interface> -c /etc/wpa_supplicant/example.conf

In some instances it was found that storing the passphrase cleartext in the key of the block gave positive results (see ). However, this approach is rather insecure. Using to create this file instead of manually writing it gives the best results most of the time and therefore is the recommended way to proceed.

Problems with eduroam and other MSCHAPv2 connections

Ensure that your configuration uses

phase2="auth=MSCHAPV2"

with a capital "v" (see ). You could even omit this setting entirely, since MSCHAPV2 is the default.

Connections to pure WPA3-SAE access points

Make sure to define the following within the network block of the configuration to enable connections to pure WPA3 access points:

ssid="network SSID"
key_mgmt=SAE
sae_password="the.literal.wifi.password"
ieee80211w=2

Connections to mixed WPA2-PSK/WPA3-SAE access points

Mixed WPA2-PSK/WPA3-SAE access points will require an alternative setting for key_mgmt as shown below:

ssid="network SSID"
key_mgmt=WPA-PSK-SHA256
psk=xxx
ieee80211w=2

Hardware 802.11w support

You can check for hardware support of MFP/PMF (Management Frame Protection / Protected Management Frames) on the interface client by running:

$ iw phy phy0 info | grep 00-0f-ac:6

Most WiFi devices support this standard introduced in 2009, except some limited (aka non x86_64 related) or old hardware.

gollark: Run-length encoding.
gollark: Oh, so NFT plus RLE compression?
gollark: So how does your format work?
gollark: Last week I overhauled potatOS's peripheral handling for increased performance and fewer peripheral calls.
gollark: The performance considerations of the projects I work on are mostly dominated by I/O (peripheral calls and stuff) more than CPU use so it doesn't really matter but it would be nice to know.

See also

This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.