Automatically Rotating Guest WiFi Passwords With hostapd
enI like to have control over who gets on my networks and who doesn't.
To obtain this level of control in my home network, I'm running a separate WiFi for guests, which among other things separates guest devices from my private infrastructure.
Authorization in hostapd
The most simple way of configuring WPA2-PSK authorization in hostapd is a static passphrase:
# /etc/hostapd/hostapd.conf
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_passphrase=Nobody expects the Spanish Inquisition!
So far, so good - but once a person knows this passphrase, they can get on my WiFi all the time, and they could share the passphrase with other people. This way, I lose control over who gets on my networks.
hostapd also supports device-specific passphrases, configured in a separate file:
# /etc/hostapd/hostapd.conf
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_psk_file=/etc/hostapd/hostapd.wpa_psk
Now, how should this file look like? The hostapd "documentation" is a bit shady in this
regard, and only mentions (PSK,MAC address) pairs
; the exact format
is not mentioned. However, multiple sources on the internet seem to
agree on this format:
# /etc/hostapd/hostapd.wpa_psk
ma:ca:dd:re:ss:00 The Passphrase For Device A
ma:ca:dd:re:ss:01 The Passphrase For Device B
And, most important, some sources also mention that the MAC address
00:00:00:00:00:00
can be used as a wildcard, so the associated
passphrase works for all devices. This alone does not give us any
advantage over the hardcoded passphrase. However, having the
passphrase in a separate file makes automated rotation extremely easy.
By doing this, I have a fairly good control over who can access my
guest WiFi when the passphrase is rotated frequently through a
cronjob.
To take things a step further, we can decouple the passphrases rotation rate from how long a passphrase remains valid. As it turns out, the wildcard MAC address can be used multiple times, and all wildcard passphrases are accepted. This allows us to do the following:
- Generate a new passphrase once a day
- Add the new passphrase as a wildcard entry to the wpa_psk file
- Remove all but the seven newest entries from the file
- Reload hostapd
So, this gives us a new passphrase every day, and each passphrase remains valid for a week.
Giving the Passphrase to Guests
I'm using qrencode
to generate a QR code with the latest passphrase,
and display the result, together with its plaintext form, in a Grafana
HTML panel:
qrencode \
-t PNG --size=6 --output=/var/www/html/wifi-guest.png \
"WIFI:S:${SSID};T:WPA2;P:${PASSPHRASE};;"
cat > /var/www/html/wifi-guest.html <<EOF
<!-- Timestamp for browser cache circumvention -->
<img src="/wifi-guest.png?$(date +%s)" />
<br/><br/><br/>
<h3><tt>${SSID}</tt></h3>
<h1><tt>${PASSPHRASE}</tt></h1>
EOF
And the result looks like this: