Connecting to a Raspberry Pi on RUWireless Secure

Published on May 21, 2020

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="<Your netid>"
	password="<Your 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.