Friday, November 5, 2021

Eduroam on Raspberry Pi

I bought a Raspberry Pi Zero 2 W last week and worked out how to do something I've been wanting to do for a while - get a Raspberry Pi to connect to Eduroam. These instructions will be specific to the University of Leicester but hopefully helpful to others.

1. Eduroam

On the Pi, either go to cat.eduroam.org and then go through the process to find the appropriate Eduroam installer, or download the Linux script from wireless.le.ac.uk/setup/linux.  The link says it's to download the certificate, but that isn't what's downloaded - what you get is a Python script.

2. Generating the certificate and wpa-supplicant file

Run the script (chmod +x first) and it asks for your username and password.  You end up with a directory .cat_installer in your home directory, and this contains ca.pem and cat_installer.conf. The latter file contains your password in plain text, which is not a good thing.

3. Hash your password

echo -n your-actual-password | iconv -t utf16le | openssl md4 > pw.txt

4. Edit wpa_supplicant.conf

Edit /etc/wpa_supplicant/wpa_supplicant.conf and add the contents of ~/.cat_installer/cat_installer.conf.  Replace the line 
password="your-actual-password
with the line
password=hash:1234567
Where 1234567 is the contents of the pw.txt file you created in step 3 (which will be a considerably longer hex number).  No quotes.  Now delete that file in ~/.cat_installer which has your plaintext password in it!
I moved the ca.pem file from step 2 to /etc/ssl/certs/leicester.pem, and edited the ca_cert line to reflect the new location and name of the certificate.  I also made some other changes based on this site, and a bit of experimentation to see what worked.  See below for the final version of the file.

5. Reboot

I now found that I was automatically connected to Eduroam, but DNS lookup wasn't working so I couldn't see websites.  I checked the Eduroam settings on my phone, found the IP addresses of the DHCP servers that was using, and entered them on the Pi through the network settings (click on the wifi symbol, change the settings for the Eduroam SSID).  The result was an /etc/resolv.conf file that looked like this:
# Generated by resolvconf
domain le.ac.uk
nameserver 143.210.12.158
nameserver 143.210.12.159

I also had to set priorities for the two networks in wpa_supplicant.conf, because the Pi was sometimes connecting to the Cloud (free wifi) rather than Eduroam.  I use the Cloud sometimes, but it's no good in headless mode because you have to finish the log in process using a browser (and lynx has stopped working for that).  The final file looks like this, and the Pi is now reliably connecting to Eduroam without any further intervention (I often use a Pi Zero in serial gadget mode so a web browser is out of the question).

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=GB

network={
        ssid="_The Cloud"
        key_mgmt=NONE
        priority=10
}

network={
        ssid="eduroam"
        key_mgmt=WPA-EAP
        pairwise=CCMP
        eap=PEAP
        ca_cert="/etc/ssl/certs/leicester.pem"
        identity="nja@leicester.ac.uk"
        anonymous_identity="anonymous@le.ac.uk"
        password=hash:9911066b9816dc8dd0e82209ecc138a4
        altsubject_match="DNS:radius.le.ac.uk;DNS:radius.le.ac.uk"
        phase2="auth=MSCHAPV2"
        priority=20
}

Wednesday, May 1, 2019

A second image client

This one is quite different from the previous client. It sends the width and height of the image to the server, and reconstitutes the pickled Image object from the byte stream the server sends back. It then uses pygame to display the image in a window, and does that as fast as it can. The width and height default to 300x300, but can be altered from the command line.


A second image server

Variation on the first.  This server expects the client to send the dimensions of the image to be returned - if the aspect ratio is different to the camera's aspect ratio, the camera image is cropped (centrally) to the correct aspect ratio, resized using thumbnail(), and sent.  Also, rather than sending a byte stream of the image data, I'm using pickle.dumps() to create a byte stream from an Image object, and sending that (since I'm already creating an Image object for the cropping and resizing).


Wednesday, April 17, 2019

A terrible security camera 3 - the client software

Notes:
  • Again, I'm using argparse.  The IP address now has to be the server's address, not the client's!
  • The client receives the image data, puts it into a PIL Image object, and then crops it to a square and resizes it to the dimensions of the Unicorn Hat (16 x 16).
  • If the --debug flag was used, the original and cropped/resized image are saved to files.
  • The client keeps sending requests to the server as fast as it can (which is not very fast given the other work it's doing).
If I run the client with the command below, the current webcam image is displayed on the Unicorn Hat (updating about twice a second) until I press CTRL-C.

pi@pibow:~/Python/camclient $ ./image-client.py -i 192.168.1.106 

 

 

The code


A terrible security camera 2 - the server software

A few notes on the server software:
  • I'm using the argparse module to allow me to change key information (IP address, port, debug information) from the command line.  The default is to use port 12345 on localhost.
  • The server simply takes a photo and sends it to the client.
  • The server runs forever until the process is stopped (ideally with CTRL-C).
An example of running the server: picam's IP address is 192.168.1.106 (I have set it up to have a static address on my home wifi). To run the server:

pi@picam:~/Python/camserver $ ./image-server.py -i 192.168.1.106 --debug
Server started on 192.168.1.106:12345


Because I've used the --debug flag, the server tells me it has started and the address and port number it's using.

 

The code


A terrible security camera 1 - the hardware

Raspberry Pi 3B in a Pibow case, with a Unicorn Hat HD attached and a diffuser on top of the case (machine name "pibow"). The Unicorn Hat HD comes with a dark diffuser, I prefer the look of the lighter diffuser which covers the whole top of the case.
Raspberry Pi Zero W in the official Pi case with a camera attached (machine name "picam").  The official case comes with a cable to attach the camera to the smaller connection on the Zero.

Raspberry Pi setup

A few notes on how I set up Raspberry Pi devices.

Static IP

My home router won't allocate addresses above 100 (I have set it up not to do so), so it is safe to use static IP addresses above that.  I keep a master list of allocated static addresses in /etc/hosts on my desktop (Linux) PC to avoid conflict with other addresses (doesn't do anything to avoid conflicts apart from having a master list in one place!). For example, a new Pi Zero W which I have called "pish" (it originally had a Pimoroni LED shim attached).

192.168.1.108 pish
 
Log in to pish and edit /etc/dhcpcd.conf to add the lines below, and reboot.


interface wlan0
static ip_address=192.168.1.108/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
 
Assuming ssh is enabled on pish, on the desktop machine to allow login without password:

ssh-copy-id pi@pish

Shell

Add this line to .bashrc
 
export PATH=~/bin:$PATH
Create a ~/bin folder, and add this script to it in a file called update - allows quick system updates just by typing update at the command prompt.
#!/usr/bin/env bash

sudo apt update
sudo apt dist-upgrade
sudo apt autoremove
Create .inputrc and add this line to it (allows tab completion of file names ignoring upper and lower case variants).
set completion-ignore-case on

Editing

gvim (my preferred editor) gives a warning unless these packages are installed:

sudo apt install libcanberra-gtk*-module