Connecting to a Raspberry Pi on RUWireless Secure
For my recently finished Capstone project I used a Raspberry Pi 3B and did most of my work SSHed into the Pi via Rutger’s wifi network. Since that took some time to setup, I’m documenting how I did that here in case its useful to someone else.
The wpa_supplicant config
The wpa_supplicant
tool is what authenticates with the Rutgers wifi network,
which gets configured with a wpa_supplicant.conf
file.
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US
network={
ssid="RUWireless Secure"
scan_ssid=1
key_mgmt=WPA-EAP
eap=TTLS
identity=""
password=""
ca_cert="/opt/Rutgers/RUWireless_Secure.crt"
phase2="auth=PAP"
}
In general this goes in the /etc/wpa_supplicant
directory of the second (OS)
partition of your SD card after you put the Raspbien image on, but you can also
put this in the boot (first) partition as wpa_supplicant.conf
and it will
automatically get copied to the correct location on boot.
Note about the parititons: the OS partition is formatted as ext4 and won’t be recognized by Windows without special software installed. If you connect your SD card and it only recognized one filesystem, that’s probably the boot parition. The easiest way to edit this partition might be to just boot up the pi, specifically for files that can’t get automatically copied.
The RUWireless_Secure.crt
file can be downloaded and placed in the
correct location on the OS partition, or can bet set to blank if you can’t
access that partition or otherwise want to skip the certificate check.
Normally this should be the only thing necessary for Raspbien to connect, but in my own adventures I encountered an issue related to driver backends which I’ll describe below.
Driver backend problem
In the default configuration, dhcpcd will automatically start the wlan0
device and through a hook run the wpa_supplicant
command with args
-B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -D nl80211,wext
or
something similar. If you have issues like I did the problem might be in
-D nl80211,wext
which specifies the driver backends we want wpa_supplicant
to try in the order we want them to be tried. What I found is wpa_supplicant
will fail to connect if it tries to use the nl80211
backend, even though this
is the newer and recommended backend.
The solution is to get ahead of dhcpcd and start your own instance of
wpa_supplicant before dhcpcd has the chance. The dhcpcd instance won’t be
launched and you can control the -B
parameter. This will all be done on the
OS partition.
The cleanest way I’ve found is to add the following systemd service and place it
in /lib/systemd/system/wpa_supplicant-wext@.service
. This is only a few lines
changed from the already existing service
/lib/systemd/system/wpa_supplicant@.service
except we want to force it to use
the wext
backend.
[Unit]
Description=WPA supplicant daemon (interface and wext-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target
[Service]
Type=simple
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dwext -i%I
[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service
This can be enabled with systemctl or by just symlinking the service file to
etc/systemd/system/multi-user.target.wants/wpa_supplicant@wlan0.service
. Note
because this service is parameterized by the name of the interface, so wlan0
is passed in as an argument (the symlink handles this). You’ll also need to rename your wpa_supplicant.conf
to /wpa_supplicant-wlan0.conf
and place it directly in /etc/wpa_supplicant
.
Creating a headless image
It’s nice to not need to ever connect your pi to a monitor when working on it, and you can find instructions on doing that in the documentation.
Once getting SSH enabled, the other issue you’ll need to solve going headless over RUWireless
Secure is figuring out your pi’s ip address. This can be solved by editing
/etc/rc.local
on the pi’s OS partition to something like this.
#!/bin/sh -e
_IP=$(hostname -I) || true
curl "http://12.31.217.10:8000/log_pi_ip/$_IP" >/dev/null || true
exit 0
Replace 12.31.217.10
the local ip of the computer already on RUWireless Secure,
and start an HTTP server that logs requests, for instance using python.
$ python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/)
12.31.217.11 - - [08/Apr/2020 18:15:00] code 404, message File not found
12.31.217.11 - - [08/Apr/2020 18:15:00] "GET /log_pi_ip/12.31.217.11"
Since rc.local
isn’t garunteed to run after networking is setup, this might not
work the first time, but you can just reboot the pi a few times if you suspect
that’s an issue. But if it works, now you have your pi’s local ip and you know
it successfully connected.
An easier way to not need a monitor and keyboard is buy a USB to UART adaptor, which can give you a shell into the pi from your computer without a monitor, keyboard or network connection necessary. Then network setup should be a little less error prone. Unfortunately for me I didn’t know this was a possibility and spent a lot of time in awkward cable setups trying to debug things!
Afterword
I don’t maintain comments on this blog, but feel to throw me an email if you have any email. My current contact info should be in the About page linked up top.