Securing the Wedge 100BF BMC

Ronald van der Pol
Fri, Apr 23, 2021 - 396 Words - 2 minutes

The BMC of the Edgecore Wedge 100BF has a default password. You can change it with passwd(1), but after a reboot it returns to the default password because the root filesystem of the BMC runs in memory. This article describes how you can change the default passwords such that they survive a reboot or power cycle.

Edgecore offers a solution by using an rc.local script. When openbmc starts up, /etc/init.d/rc.local checks for the existence of /mnt/data/etc/rc.local.

if [ -x /mnt/data/etc/rc.local ]; then
   /mnt/data/etc/rc.local
fi

/mnt/data is on permanent storage:

# mount 
rootfs on / type rootfs (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
/dev/mtdblock4 on /mnt/data type jffs2 (rw)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /var/volatile type tmpfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
# cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00060000 00010000 "u-boot"
mtd1: 00020000 00010000 "env"
mtd2: 00400000 00010000 "kernel"
mtd3: 01780000 00010000 "rootfs"
mtd4: 00400000 00010000 "data0"
mtd5: 02000000 00010000 "flash0"

In /mnt/data/etc/rc.local, you can add a sed(1) command that changes /etc/shadow.

I wanted to use this, but also have a recovery mode when something went wrong or I forgot the password. I found a solution by using a u-boot environment variable. The BMC ARM chip boots with u-boot and openbmc is loaded by u-boot.

This is what I did. Connect to the Wedge serial port, reboot and interrupt u-boot. Then set the environment variable run_rc_local to yes.

autoboot in 3 seconds (stop with 'Delete' key)...
boot# setenv run_rc_local yes
boot# printenv run_rc_local
run_rc_local=yes
boot# saveenv

Create the file /mnt/data/etc/rc.local in openbmc. This is an example of what you could put in there:

# mechanism to disable running of this script
fw_printenv | grep -q run_rc_local=yes || exit

echo "server your.ntp.server" >> /etc/ntp.conf
/etc/init.d/ntpd reload

HOSTNAME=Foobar
echo $HOSTNAME > /etc/hostname
hostname $HOSTNAME

PROFILE=/home/root/.profile
echo "export TZ=Europe/Paris" >> $PROFILE
echo "PS1='\u@\h:\w# '" >> $PROFILE

# remember to escape special characters !!!
OLD_ROOT='\$1\$XXXXXXXXX\/XXXXXXXXXXXXXXXXXXXXXX'
NEW_ROOT='\$1\$YYYYYYYYYYYYYYYYY\/YYYYYYYYYYYYYY'
sed -i 's/'$OLD_ROOT'/'$NEW_ROOT'/' /etc/shadow

# remember to escape special characters !!!
OLD_ADMIN='\$1\$XXXXXXXXX\/XXXXXXXXXXXXXXXXXXXXXX'
NEW_ADMIN='\$1\$YYYYYYYYYYYYYYYYY\/YYYYYYYYYYYYYY'
sed -i 's/'$OLD_ADMIN'/'$NEW_ADMIN'/' /etc/shadow

You can get the password hashes by first saving the hashes that are in /etc/shadow. The change the root and admin passwords with passwd(1). Then get the new hashes from /etc/shadow.

If something goes wrong, you can disable the rc.local script by setting the u-boot variable to no:

boot# setenv run_rc_local no
boot# saveenv