Featured image of post WPA Supplicant - A Practical Guide

WPA Supplicant - A Practical Guide

WPA Supplicant - A practical guide

Esta es una de mis publicaciones viejas, escrita alrededor de 2022.

Index

  1. Preface
  2. Installation
  3. Using the correct configuration file
  4. Editing the configuration file
  5. Setting up the service
  6. See also

Preface

This guide is meant to be a quick setup guide for wpa_supplicant, designed primarily with Arch (SystemD) and Artix (runit) in mind. If you have no idea how to set up wpa_supplicant, you should follow it thoroughly. If you have a very specific doubt, just skip to the section which will hopefully help you solve your problems; the sections are written independently from each other unless stated otherwise.

Installation

Note: Of course, installing these programs will require an active internet connection, which you probably do not have at this point. The installation should be done in the live ISO in which you also installed your operating system.

wpa_supplicant is sure to be found in your distribution's official repositories. You should also install dhcpcd to get an IP address and complete the connection process. For default Arch-based, SystemD distributions, a simple

# pacman -S wpa_supplicant dhcpcd

should do.

However, in distributions like Artix and Parabola, specific service scripts need to be installed for your init system. For example, using runit as an init system for Artix, the following packages would also need to be installed:

# pacman -S wpa_supplicant-runit dhcpcd-runit

Using the correct configuration file

Note: WPA Supplicant is flexible enough to use any file as a configuration file, so none of these steps are technically necessary, but they are convention and will spare you a lot of confusion and file editting.

Before connecting to the internet, you should know through which wireless interface you can do this with. Most often this will be wlp2s0 or wlan0, but you can quickly verify this by doing:

$ ip a

Entries starting with "wlp" or "wlan" are the interfaces capable of wireless connection. You may have multiple of these if you have multiple wireless adapters, in which case you should choose one.

Configuration files are conventionally placed under /etc/wpa_supplicant/, but their name changes according to the interface you wish to use. They follow the format wpa_supplicant-[interface].conf, so if your interface is wlan0, your complete file path would be /etc/wpa_supplicant/wpa_supplicant-wlan0.conf.

Editing the configuration file

Connecting to a network you know the credentials to

Adding a standard WPA2 network is most commonly done through wpa_passphrase. This program takes in two simple arguments: the network's SSID (name) and its passphrase. Take a look at this intuitive example:

$ wpa_passphrase MyNetwork password123
network={
ssid="MyNetwork"
#psk="password123"
psk=1f1503df6a9182b5936a027973a426df3954bb0ff5d4add55753fe37b02a55f1
}

This output can then be redirected into your configuration file in the following way:

# wpa_passphrase MyNetwork password123 >> /etc/wpa_supplicant/wpa_supplicant-[interface].conf

or if you prefer to use sudo over a root shell:

$ wpa_passphrase MyNetwork password123 | sudo tee -a /etc/wpa_supplicant/wpa_supplicant-[interface].conf

Protecting your passphrases presents more options for those concerned with security, but as a bare minimum manually deleting the plaintext versions of your passphrases should do.

At this point restarting the service will load in the edited configuration file and, if the credentials are valid, will connect you to the internet. If you do not know how to do this, read Setting up the service.

Connecting to an enterprise network

Enterprise networks do not have a program like wpa_passphrase to fill in entries, but they follow a similar format. Still, if you need to connect to a network of this kind, you will have to manually add the entry. These networks utilize the following format:

/etc/wpa_supplicant/wpa_supplicant-[interface].conf
network={
ssid="AnEnterpriseNetwork"
key_mgmt=WPA-EAP
eap=PEAP
identity="user_name"
password="user_password"
phase2="autheap=MSCHAPV2"
}

Considering that you are utilizing a plain-text password and are unable to get around it, it is advisable that you follow the strictest protocols dictated in Protecting your passphrases.

Scanning for and connecting to open networks

To enable network scanning, the following line must be added in the configuration file, preferably at the beginning:

/etc/wpa_supplicant/wpa_supplicant-[interface].conf
ctrl_interface=/run/wpa_supplicant

To actually scan for networks, a separate program must be used, in a similar vein to wpa_passphrase. This program is wpa_cli, and does require root privileges. The program will start interactively with a simple:

# wpa_cli

You should be greeted by some text and a simple >, indicating you are in interactive mode. To begin a scan, all that is necessary is to execute the command:

> scan

which, after some time, should yield the output:

> scan
OK
<3>CTRL-EVENT-SCAN-STARTED
<3>CTRL-EVENT-SCAN-RESULTS

point at which you can see the scan's results by doing:

> scan_results

Networks detected withing your range should be presented, and from them, open networks should look something like the following (notice the lack of flags when compared to a normal entry):

> scan_results
bssid / frequency / signal level / flags / ssid
XX:XX:XX:XX:XX:XX   XXXX-XX     [WPA2-PSK-CCMP][WPS][ESS]       AClosedAndProtectedNetwork
XX:XX:XX:XX:XX:XX   XXXX-XX     [ESS]       AnOpenAndInsecureNetwork

You should know that there is a way to interactively connect to networks and save their credentials (or lack thereof) to the configuration file automatically, but frankly since I only ever use wpa_cli to connect to open networks I choose to just manually add the short entry for this kind of network, like so:

/etc/wpa_supplicant/wpa_supplicant-[interface].conf
network={
   ssid="AnOpenAndInsecureNetwork"
   key_mgmt=NONE
}

Managing multiple networks

Sometimes multiple networks are available in the same area, in which case you might prefer using one over the other. This can be easily done through the use of prioritization. In wpa_supplicant's configuration file, this is done with the priority parameter inside the network entries. The networks with the highest priority will actually be those with the highest value, so the highest priority a network can have is 999.

To illustrate its usage, all previous examples are gathered here, organized with the home network always having the highest priority, the enterprise network having the second highest and the open network having the lowest priority possible.

/etc/wpa_supplicant/wpa_supplicant-[interface].conf
ctrl_interface=/run/wpa_supplicant

# Home network network={ ssid=“MyNetwork” psk=1f1503df6a9182b5936a027973a426df3954bb0ff5d4add55753fe37b02a55f1 priority=999 }

# Enterprise network network={ ssid=“AnEnterpriseNetwork” key_mgmt=WPA-EAP eap=PEAP identity=“user_name” password=“user_password” phase2=“autheap=MSCHAPV2” priority=998 }

# Open network network={ ssid=“AnOpenAndInsecureNetwork” key_mgmt=NONE priority=-999 }

Protecting your passphrases

Your configuration file will hold the credentials to multiple networks, and considering how much sensitive information can go through these, it is important you protect them.

The most basic form of protection would be to delete plaintext password from your configuration file, since they are already made redundant by the ciphered passphrases. This step already goes a long way in protecting your credentials, and if you do not share your computer with other people, is as far as you would have to go. Anything else is just for reinforcement's sake.

If you wish to keep your plaintext passphrases and still want to prevent other users from seeing them, you can change your configuration file's permissions so that only privileged users can see them. Assuming that the file and directory already belong to root (which they will if you haven not explicitly changed it), all you need to do is to change permissions on the file so that other users do not have read or execute permissions.

# chmod 600 /etc/wpa_supplicant/wpa_supplicant-[interface].conf

Finally, if you insist on protecting your passphrases, you should also consider clearing your shell's history file so that it is not readable there.

Setting up the service

Starting the wpa_supplicant service is highly dependent on the init system you are running. This particular guide covers enabling the services under SystemD and runit, but enabling it under other init systems should not be too dissimilar.

SystemD

If you have organized your configuration file as detailed in the previous section, enabling the service should be as simple as:

# systemctl enable dhcpcd wpa_supplicant@[interface] --now

Runit

Unlike with SystemD, you do not want to just initialize the service. You have to first explicitly configure the script to point to the configuration file and interface you wish to use. This script is located in /etc/runit/sv/wpa_supplicant/run. The "official" way of doing this is by creating a conf file in the same directory and populating with the variables run calls for, like this:

/etc/runit/sv/wpa_supplicant/conf
#!/bin/sh
CONF_FILE=/etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf
WPA_INTERFACE=wlp2s0

Honestly, I find this a bit too redundant, which is why I prefer to edit the run file directly, like so:

/etc/runit/sv/wpa_supplicant/run
#!/bin/sh
#[ -r ./conf ] && . ./conf
exec 2>&1
#exec wpa_supplicant -c ${CONF_FILE:=/etc/wpa_supplicant/wpa_supplicant.conf} -i ${WPA_INTERFACE:=wlan0} ${OPTS:=-s}
exec wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant-wlp2s0.conf -i wlp2s0 ${OPTS:=-s}

Either way will work just fine. Now you can proceed to actually enabling the services, which in runit is done by doing:

# ln -s /etc/runit/sv/dhcpcd /run/runit/dhcpcd
# ln -s /etc/runit/sv/wpa_supplicant /run/runit/wpa_supplicant

Finally, to start the services:

# sv start dhcpcd wpa_supplicant

OpenRC

Edit /etc/init.d/wpa_supplicant to include the desired interface and configuration file.

/etc/init.d/wpa_supplicant
#!/usr/bin/openrc-run
# Copyright (c) 2009 Roy Marples 
# All rights reserved. Released under the 2-clause BSD license.

command=/usr/bin/wpa_supplicant : ${wpa_supplicant_conf:=/etc/wpa_supplicant/wpa_supplicant.conf} wpa_supplicant_if=${wpa_supplicant_if:+-i}$wpa_supplicant_if #command_args="$wpa_supplicant_args -B -c$wpa_supplicant_conf $wpa_supplicant_if" command_args="$wpa_supplicant_args -B -c/etc/wpa_supplicant/wpa_supplicant-wlan0.conf wlan0" name=“WPA Supplicant Daemon”

[…]

Now just enable the service:

# rc-update add dhcpcd default
# rc-update add wpa_supplicant default

See also

El león del norte