Persistent authorized_keys on a UDM Pro

SSH into a UDM Pro

After enabling SSH access into a UDM Pro, and adding a public SSH key via the web GUI, enabling password-less SSH is as easy as using copying the public key into the ~/.ssh/authorized_keys file.

Problems after reboot and/or upgrade

Everything works great, until you reboot or upgrade, in which case, your ~/.ssh/authorized_keys file is gone.

Thankfully, there is an easy way to make the ~/.ssh/authorized_keys file recreated after every reboot, using BoostChicken's package, udm-boot.

Install udm-boot

To survive reboots and firmware updates on the UDM, Boostchicken has a package, udm-boot, that can be installed to automatically run a shell script(s) at S95 anytime your UDM starts / reboots.

  • SSH into your UDM Pro

  • Switch to the UniFi shell

    unifi-os shell
    
  • Download the boot scripts:

    curl -L https://unifi.boostchicken.io/udm-boot_1.0.7_all.deb -o udm-boot_1.0.7_all.deb
    
  • Install and enable the boot scripts:

    dpkg -i udm-boot_1.0.7_all.deb
    systemctl enable udm-boot
    
  • Exit out of the UniFi shell (this is important!):

    exit
    

Create the permanent authorized_keys file

After SSH'ing into the UDM Pro:

If you are running firmware version 1.x, your DATA directory will be /mnt/data, otherwise firmware versions 2.x - 4.x (and above) will be /data

These instructions are for firmware versions 2.x (and above) and reflect the /data DATA directory.

mkdir -p /data/on_boot.d/settings/ssh

Copy your public SSH key into /data/on_boot.d/settings/ssh/authorized_keys.

Create the boot script to copy the authorized_keys file

Create the file /data/on_boot.d/15-add-root-ssh-keys.sh file:

#!/bin/bash
# Get DataDir location
DATA_DIR="/data"
case "$(ubnt-device-info firmware || true)" in
1*)
   DATA_DIR="/mnt/data"
   ;;
2*)
   DATA_DIR="/data"
   ;;
3*)
   DATA_DIR="/data"
   ;;
4*)
   DATA_DIR="/data"
   ;;
*)
   echo "ERROR: No persistent storage found." 1>&2
   exit 1
   ;;
esac
## Places public keys in ~/.ssh/authorized_keys

KEYS_SOURCE_FILE="${DATA_DIR}/on_boot.d/settings/ssh/authorized_keys"
KEYS_TARGET_FILE="/root/.ssh/authorized_keys"

count_added=0
count_skipped=0
while read -r key; do
   # Places public key in ~/.ssh/authorized_keys if not present
   if ! grep -Fxq "$key" "$KEYS_TARGET_FILE"; then
      let count_added++
      echo "$key" >>"$KEYS_TARGET_FILE"
   else
      let count_skipped++
   fi
done <"$KEYS_SOURCE_FILE"

echo "${count_added} keys added to ${KEYS_TARGET_FILE}"
if [ $count_skipped -gt 0 ]; then
   echo "${count_skipped} already added keys skipped"
fi

exit 0

Running the script

Either run the script to copy the desired authorized_keys file, or reboot.

References

Github.com - unifios-utilities/on-boot-script https://github.com/unifi-utilities/unifios-utilities/blob/main/on-boot-script/README.md