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:

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…

  1. download and extract the Raspberry Pi 3 image from http://www.raspbsd.org/
  2. copy the image to a microSD card using either dd or pv.
  3. 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
  4. 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.

  1. install the micro POE HAT
  2. (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.
  3. place the Raspberry Pi + HAT inside the case and assemble it

Novalabs micro POE HAT Raspberry Pi 3+ with micro POE HAT and heat-sink kit Fully assembled case

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.

  1. set a root password
  2. create one or more accounts (and add ssh public keys to them)
  3. configure your network and firewall
  4. install conserver-com there is another one with -com and that is the wrong one for this tutorial.
  5. install additional software e.g. ipmitool, minicom, …
  6. 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"
  1. enable both sshd and conserver
sysrc sshd_enable="YES"
sysrc conserver_enable="YES"
  1. create /usr/local/etc/conserver.passwd so that our users we created earlier can use conserver
usera:*passwd*
userb:*passwd*
  1. 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;
}
  1. 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
  1. restart conserver and test if consoles work
usera@hydra:~ # console -u
usera@hydra:~ # console c

Screenshot showing a terminal running conserver

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