NIST BRSKI demo setup
The server device for the NIST BRSKI demo has the following requirements:
- Capability for two independent WiFi APs
The client devices must have the following requirements:
- Capability for WiFi STA that can connect to the WiFi APs
- USB Ethernet Gadget mode connectivity
For the BRSKI demo, we're setting up a Raspberry Pi 4B running Ubuntu 22.04
server edition called nqm-britannic-brski
. For the two WiFi APs, we're using
two Ralink RT5370 USB adapters. That then connects to two Ubuntu 22.04 clients
using a USB-C hub, which are both acting a USB Ethernet devices.
Physical setup
Parts
- 1x Powered USB-C hub
- 1x Powered USB-C hub Power Supply + IEC C13 cable.
- Todo, buy an IEC C13 US cable, or get a UK to US power adapter.
- 1x Powered USB-C hub Power Supply + IEC C13 cable.
- 3x Raspberry Pi 4Bs:
nqm-brittanic-brski
(server)nqm-benign-brski
(client)nqm-biddable-brski
(client)
- 1x Raspberry Pi Power supply unit
- Maybe bring one with a US plug?
- 2x USB-C to USB-C cables (ideally capable of 5V 3A)
- 1x USB-C to USB-A cable (ideally USB-3.0 for higher speed, and capable of 5V 3A)
- 1x RJ45 Ethernet cable
- 2x USB-A WiFi AP adapters
Connections
SSH Connection through brittanic brski
Only nqm-britannic-brski
is directly connected to the network.
If you want to SSH into nqm-benign-brski
or nqm-biddable-brski
, you must
use ssh 192.168.48.1 -J nqm-britannic-brski.local
(use the IP address, since
mDNS does not work for some reason).
Setup
Configuring USB-C connection
The Raspberry Pi Model 4B supports USB Gadget mode, which can be used to communicate from one Pi to another Pi without the usage of a router and switch.
Some of this guide is adapted from the steps in https://lozworld.com/lozwords/raspberry-pi-4b-as-an-ubuntu-2110-usb-gadget-tethered-to-an-ipad-pro.
Host
The Raspberry Pi 4B's USB-C connector does NOT support DRD (Dual-Role-Data). This means that if you use a USB-C to USB-C cable, the Raspberry Pi 4B can only be peripheral/UFP (upstream-facing port).
There is support for USB 2.0 OTG (USB On-The-Go) in host-mode, but it requires that you use a USB-C to USB-A/USB-B adapter.
USB-C to USB-C only works as a periperal.
Because of this, to connect the Raspberry Pi 4B to a USB-C hub as a host, you must plug the hub into one of the Raspberry Pi 4B's USB-A ports.
See RPi 4 USB-C socket as host - Raspberry Pi Forums and Texas Instruments. Transition Existing Products from USB 2.0 OTG to USB Type-CTM for more info.
Client USB-C Ethernet
The Raspberry Pi 4B's USB-C connector can be used in peripheral/UFP (upstream-facing port) mode.
Enabling USB peripheral mode in /boot/firmware/config.txt
In /boot/firmware/config.txt
, add the following line, to turn the Raspberry
Pi 4B into a USB gadget:
[cm4]
# Enable the USB2 outputs on the IO board (assuming your CM4 is plugged into
# such a board)
dtoverlay=dwc2,dr_mode=peripheral
Place it in the [cm4]
section if it exists.
Make the Raspberry Pi a USB Gadget Ethernet using /boot/firmware/cmdline.txt
In /boot/firmware/cmdline.txt
, add
modules-load=dwc2,g_ether g_ether.dev_addr=e6:5f:01:00:48:01 g_ether.host_addr=e6:5f:01:00:48:02
between rootwait
and fixrtc
, in order to enable the g_ether
Linux kernel
module.
This makes a new interface called usb0
on the Raspberry Pi, and makes
the Raspberry Pi 4B act like a USB Ethernet adapter. On the device side, the MAC
address is given by g_ether.dev_addr
, while on the host side, it will be
g_ether.host_addr
.
Important, make sure that the second character of your MAC address is one of
2
/6
/a
/e
(e.g. x6:00:00:00:00:00
), as this is the
Local bit in RFC5342 § 2.1.
Give usb0
a static IP address
Make a new file called /etc/netplan/51-usb0.yaml
with contents:
# Setup a static IP address for the USB ethernet gadget mode
# See https://github.com/nqminds/nist-brski
network:
# only set static IP addresses here
# The DHCP server we create manually using dnsmasq
ethernets: # treat these as ethernet devices
usb0:
dhcp4: false # we use a static IP
optional: true
addresses: [192.168.48.1/29]
Make sure that the static IP address is unique.
Setup dnsmasq
on usb0
only using /etc/default/dnsmasq.usb0
Install dnsmasq
, then disable it using:
sudo apt install dnsmasq
sudo systemctl disable dnsmasq.service
Then, make a /etc/default/dnsmasq.usb0
file with the following contents
(change the IP address)
DNSMASQ_EXCEPT="lo"
DNSMASQ_INTERFACE='usb0'
DNSMASQ_OPTS='--bind-interfaces --dhcp-option=3 --dhcp-range=192.168.48.2,192.168.48.6,255.255.255.248,1h'
Finally, you can start dnsmasq
using:
systemctl start dnsmasq@usb0.service
and do enable the service (so that it runs automatically on boot) using:
systemctl enable dnsmasq@usb0.service
Blacklisting cdc_subset
Add blacklist cdc_subset
to /etc/modprobe.d/blacklist.conf
on the host.
For some reason, the cdc_subset
kernel module sometimes takes precendence over
cdc_ether
. However, cdc_subset
ignores the MAC address of our USB Ethernet
device, which breaks our network config,
see https://github.com/raspberrypi/firmware/issues/843#issuecomment-1597841959.
# unlike cdc_ether, cdc_subset seems to be ignoring the really nice MAC
# addresses we setup. blacklist it so the kernel always uses cdc_ether instead.
blacklist cdc_subset
Configuring APs
On Ubuntu 22.04:
- Install hostapd and dnsmasq with
sudo apt install hostapd dnsmasq
- Disable the automatically enabled
dnsmasq.service
with:sudo systemctl disable dnsmasq.service
- Disable the automatically enabled
- If using the
Ralink Technology, Corp. RT5370 Wireless Adapter
, on Ubuntu, you must install the following package to get the binary blobs for the module:linux-modules-extra-raspi
Configuring static IPs
Ubuntu 22.04 Server uses netplan to setup network options.
Since netplan
v0.105's wifis
access-points.mode
property only supports ap
if using NetworkManager,
we cannot use netplan
to control our HostAP access points.
However, it's still the easiest way to setup a static IP address for our AP interfaces.
To do this, make a new file called /etc/netplan/51-brski.yaml
,
with the contents like:
network:
# only set static IP addresses here
# The access point we create manually using hostapd
# The DHCP server we create manually using dnsmasq
ethernets: # treat these as ethernet devices
wlx1cbfce699b7f:
addresses:
- "192.168.16.1/24"
wlx1cbfce651dc4:
addresses:
- "192.168.17.1/24"
# USB Ethernet Gadget mode
# (aka client Raspberry Pi 4)
enxe45f01053833:
dhcp4: true # find IP address automatically
optional: true
enxe45f0105389e:
dhcp4: true # find IP address automatically
optional: true
version: 2
Configuring hostapd
For each interface (%i
), make a file called /etc/hostapd/%i.conf
:
For the secure AP, /etc/hostapd/wlx1cbfce651dc4.conf
use:
# AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for
# management frames); ath0 for madwifi
interface=%i # replace the interface with the proper interface name
##### IEEE 802.11 related configuration #######################################
# SSID to be used in IEEE 802.11 management frames
ssid2="nqm-britannic-brski"
# Enable IEEE 802.11n 2.4 GHz
hw_mode=g
ieee80211n=1
# Ralink RT5370 supports 40 MHz bandwidth, see datasheet
ht_capab=[SHORT-GI-40][HT40+][HT40-]
# Ralink RT5370 doesn't seem to support ACS, so we need to manually pick channel
channel=11
auth_algs=3
wmm_enabled=1
##### WPA/IEEE 802.11i configuration ##########################################
wpa=2
# wpa_psk=000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
wpa_passphase=raspiwlan
# WPA-PSK = WPA-Personal / WPA2-Personal
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
For the unsecure/open AP, you can use a config like /etc/hostapd/wlx1cbfce699b7f.conf
:
# AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for
# management frames); ath0 for madwifi
interface=wlx1cbfce699b7f
##### IEEE 802.11 related configuration #######################################
# SSID to be used in IEEE 802.11 management frames
ssid2="nqm-britannic-brski-open"
# Enable IEEE 802.11n 2.4 GHz
hw_mode=g
ieee80211n=1
# Ralink RT5370 supports 40 MHz bandwidth, see datasheet
ht_capab=[SHORT-GI-40][HT40+][HT40-]
channel=6
Then, you can start/restart hostapd with:
systemctl restart hostapd@wlx1cbfce651dc4.service hostapd@wlx1cbfce699b7f.service
You can enable hostapd, so that it starts automatically on boot, by using:
systemctl enable hostapd@wlx1cbfce651dc4.service hostapd@wlx1cbfce699b7f.service
Configuring dnsmasq
Make two new SYSV init files called /etc/default/dnsmasq.%i
(replacing %i
with your instance name).
E.g. /etc/default/dnsmasq.wlx1cbfce699b7f
:
DNSMASQ_EXCEPT="lo"
DNSMASQ_INTERFACE='wlx1cbfce699b7f'
DNSMASQ_OPTS='--bind-interfaces --dhcp-range=192.168.16.100,192.168.16.199,4h'
E.g. /etc/default/dnsmasq.wlx1cbfce651dc4
:
DNSMASQ_EXCEPT="lo"
DNSMASQ_INTERFACE='wlx1cbfce651dc4'
DNSMASQ_OPTS='--bind-interfaces --dhcp-range=192.168.17.100,192.168.17.199,4h'
Then, you can start/restart the dnsmasq services by doing:
systemctl restart dnsmasq@wlx1cbfce651dc4.service dnsmasq@wlx1cbfce699b7f.service
Configuring dnsmasq to only start after hostapd
Unfortunately, since hostapd temporarily disables the wifi interface on startup, we cannot start dnsmasq at the same time as hostpad, we need to start it a few seconds afterwards.
To do this automatically, we can create a systemd unit override to make dnsmasq only start after hostapd starts up.
This can easily be done by using the sudo systemctl edit dnsmasq@.service
command, and entering in the following:
[Unit]
# We can only start dnsmasq after hostapd starts, because starting them both
# at the same time fails
BindsTo=hostapd%i.service
After=hostapd%i.service
[Service]
ExecStartPre=/bin/sleep 5
(or manually creating a /etc/systemd/system/dnsmasq@.service.d/override.conf
)
After we make this override, we can do a systemctl daemon-reload
, then
enable dnsmasq to start on boot (make sure you enable hostapd@
too!):
systemctl enable dnsmasq@wlx1cbfce651dc4.service dnsmasq@wlx1cbfce699b7f.service