Remote Access Console using Raspberry Pi 3b+ and FreeBSD
Introduction
I have a small homelab and I was looking into some sort of KVM console to be able to access them both locally and remotely instead of moving around VGA cables/serial cables.
Those are rather expensive so I opted to build my own remote access system. Since all my servers and switch(es) have a serial console that should not be to hard.
I ended up using:
- Raspberry Pi 3+
- NavoLabs micro POE Hat
- FT4232H based USB-to-RS232 (4x) adapter
- Official Raspberry Pi case (optional)
- Heat-sink kit (optional)
- USB-to-TTL adaptor (optional)
- Sandisk 16Gb microSD
For the software I ended up using conserver. Below is a very brief tutorial on how to set everything up. I assume you have basic unix skills.
Tutorial
Preparing the microSD
At the time of writing there were no Raspberry Pi 3+ images…
- download and extract the Raspberry Pi 3 image from http://www.raspbsd.org/
- copy the image to a microSD card using either dd or pv.
- grab bcm2710-rpi-3-b-plus.dtb, bootcode.bin, fixup.dat, fixup_cd.dat, fixup_cd.dat fixup_cd.dat, start.elf, start_cd.elf, start_db.elf, start_x.elf, and u-boot.bin from github
- mount the msdos partition from the microSD card and copy over the new dtb, bin, and elf files.
Preparing the hardware
If you have a head-sink kit only install the larger one that goes on the SoC, the smaller one for the chip near the USB ports will prevent the micro POE HAT from being seated properly.
- install the micro POE HAT
- (Optionally) install a heat-sink kit, I ended up adding the smaller one to the chip on the micro POE HAT as it get rather hot.
- place the Raspberry Pi + HAT inside the case and assemble it
Configuring FreeBSD
Because I did not want to mess with HDMI and a keyboard I used a USB-to-TTL adaptor to configure the rPI. Both a monitor and keyboard should work equally well.
- set a root password
- create one or more accounts (and add ssh public keys to them)
- configure your network and firewall
- install conserver-com there is another one with -com and that is the wrong one for this tutorial.
- install additional software e.g. ipmitool, minicom, …
- update /boot/loader.conf to load the required drivers
## Raspberry Pi 3+ USB Ethernet
muge_load="YES"
## Load USB Serial support
ucom_load="YES"
## Load FTDI driver
uftdi_load="YES"
- enable both sshd and conserver
sysrc sshd_enable="YES"
sysrc conserver_enable="YES"
- create /usr/local/etc/conserver.passwd so that our users we created earlier can use conserver
usera:*passwd*
userb:*passwd*
- create /usr/local/etc/conserver.cf (use the correct cuaU and ipmitool settings)
### access
config * {
defaultaccess allowed;
}
access localhost {
admin usera;
trusted localhost;
}
### consoles
## defaults
default * {
# master server
master localhost;
# timestamps
# NOTE: every hour with activity and break logging
timestamp 1hab;
# enable writing
rw *;
# enable logging
logfile /var/log/console_&.log;
}
## switch
console switch {
motd "Ubiquiti ES-48-500W (serial)";
type device;
device /dev/cuaU0; parity none; baud 115200;
}
## computenode 1
console cn1 {
motd "SmartOS Node 1 (serial)";
type device;
device /dev/cuaU1; parity none; baud 115200;
}
console cn1_ipmi {
motd "Compute Node 1 (IPMI)";
logfile "";
type exec;
exec /usr/local/bin/ipmitool -I lanplus -C 3 -L OPERATOR -H 10.42.0.50 -U consoleuser -P consolepassword shell;
}
## computenode 2
console cn2 {
motd "SmartOS Node 2 (serial)";
type device;
device /dev/cuaU2; parity none; baud 115200;
}
console cn2_ipmi {
motd "Compute Node 2 (IPMI)";
logfile "";
type exec;
exec /usr/local/bin/ipmitool -I lanplus -C 3 -L OPERATOR -H 10.42.0.60 -U consoleuser -P consolepassword shell;
}
- drop in a newsyslog configuration file to rotate the logs console session logs
# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
/var/log/console_*.log 644 4 * $W0D23 GZ /var/run/conserver.pid
- restart conserver and test if consoles work
usera@hydra:~ # console -u
usera@hydra:~ # console c
Bonus
A small bonus script I wrote to turn on the 2nd LED on the rPI once the system is booted, it will then blink the LED if someone is connected to any of the consoles.
#!/bin/sh
## variables
LED=/dev/led/led0
CON=/usr/local/bin/console
## functions
# NOTE: turn on/off led
led_on() {
LED_STATE=1
echo "$LED_STATE" > "$LED"
}
led_off() {
LED_STATE=0
echo "$LED_STATE" > "$LED"
}
led_swap() {
case "$LED_STATE" in
1) led_off ;;
*) led_on ;;
esac
}
led_state() {
case "$LED_STATE" in
1) echo "on" ;;
*) echo "off" ;;
esac
}
# NOTE: check if conserver has active connections
has_conns() {
local num_act_conns="$("$CON" -u | grep -v -c "")"
if [ "$num_act_conns" -gt "0" ]; then
return 0
fi
return 1
}
## main
main() {
echo "Enabling conserver status indicator ..."
while true; do
if has_conns; then
led_swap
sleep 2
else
if [ "$(led_state)" != "on" ]; then
led_on
fi
sleep 1
fi
done
}
main