Skip to content

Instantly share code, notes, and snippets.

@emabrey
Last active December 28, 2025 21:45
Show Gist options
  • Select an option

  • Save emabrey/6f82f7ab4eeb84ae6d9af8ad7e2b735e to your computer and use it in GitHub Desktop.

Select an option

Save emabrey/6f82f7ab4eeb84ae6d9af8ad7e2b735e to your computer and use it in GitHub Desktop.
A shell script for converting dropbear related key information to openSSH format on openWRT devices
#! /bin/sh
# SPDX-License-Identifier: GPL-2.0-only
# License available at https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# Script written by emabrey
#### Configuration ####
DROPBEAR_DIR="/etc/dropbear"; # Path for locating existing dropbear keys
OPENSSH_DIR="/etc/ssh"; # Path for placement of converted openSSH keys
FORCE_ENABLED=false; # Key overwrite enabled (see -f or --force)
CONVERT_PROG="dropbearconvert" # The name of the dropbearconvert package/program
BACKUP_UUID="bfe22494-8bea-43c3-908c-59e412b89cce" #The filename UUID to use when making backup files
#### Script ####
if [ "$#" -gt 1 ]; then
echo "Too many arguments, please consult --help option helptext; aborting";
exit 1;
fi
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo "Usage: $0 [option...] ";
echo " ";
echo " -f, --force Overwrite the existing openSSH keys";
echo " -h, --help Display this help message ";
echo " ";
exit 0;
elif [ "$1" = "-f" ] || [ "$1" = "--force" ]; then
FORCE_ENABLED=true;
elif [ -n "$1" ]; then
echo "Unrecognized option; aborting";
exit 1;
fi
if ! [ -e "$DROPBEAR_DIR" ] || ! [ -d "$DROPBEAR_DIR" ]; then
echo "Configured dropbear directory is not a valid directory; aborting";
exit 1;
fi;
if ! [ -e "$OPENSSH_DIR" ] || ! [ -d "$OPENSSH_DIR" ]; then
echo "Configured openSSH directory is not a valid directory; aborting";
exit 1;
fi;
for program in "echo" "cp" "rm"; do
if ! command -v $program >/dev/null 2>&1; then
printf "%s\n" "Missing $program, which is required; aborting;"
exit 1;
fi;
done;
echo "The dropbear to openSSH key conversion is about to start...";
if [ "$FORCE_ENABLED" = "true" ]; then
echo "WARNING: SSH key overwriting is enabled; press Ctrl-C if unintentional";
fi;
# Give user time to abort if they accidentally ran the program
# overwriting SSH keys accidentally could be a catastrophic issue
# so the script is trying to give you one last chance to change your mind
# if you've made a mistake
echo "5.." && sleep 1;
echo "4.." && sleep 1;
echo "3.." && sleep 1;
echo "2.." && sleep 1;
echo "1.." && sleep 1;
echo "---"
# Detect existing dropbear key converter, or temporarily install it
if ! command -v "$CONVERT_PROG" >/dev/null 2>&1; then
# Check for entware installer
if ! command -v "opkg" >/dev/null 2>&1; then
echo "Unable to proceed; $CONVERT_PROG utility is not available";
echo "Try manually installing the $CONVERT_PROG program to PATH first";
exit 1;
fi
echo "Updating entware repository database" && opkg update >/dev/null 2>&1;
echo "Temporarily installing $CONVERT_PROG utility..." && opkg install "$CONVERT_PROG" >/dev/null 2>&1;
hash -r;
REMOVEDC=true;
# Verify that the installation succeeded
if ! command -v "$CONVERT_PROG" >/dev/null 2>&1; then
echo "The temporary installation failed; aborting"
exit 1;
fi
else
echo "Pre-existing $CONVERT_PROG installation detected"
REMOVEDC=false
fi;
echo "---"
KEYCOUNT=0 # Counts up for each conversion
for keytype in "rsa" "ed25519"; do
DROPBEAR_KEY="${DROPBEAR_DIR}/dropbear_${keytype}_host_key" # dropbear input
OPENSSH_KEY="${OPENSSH_DIR}/ssh_host_${keytype}_key" # openSSH output
KEY_PRIVATE="$OPENSSH_KEY"
KEY_PUBLIC="${OPENSSH_KEY}.pub"
echo "Attempting to convert dropbear $keytype keys to openSSH format...";
# If there are existing keys, check if force is enabled and backup and remove
# the existing files if that option is enabled
for existing_keyfile in "$KEY_PRIVATE" "$KEY_PUBLIC"; do
if [ -e "$existing_keyfile" ] && [ -f "$existing_keyfile" ]; then
if [ "$FORCE_ENABLED" = "true" ]; then
echo " - openSSH $keytype keys have been detected; making backup and overwriting"
# Make a backup and remove original private key
cp "$existing_keyfile" "${existing_keyfile}.${BACKUP_UUID}.bak";
rm "$existing_keyfile";
fi;
fi;
done;
if [ -e "$KEY_PRIVATE" ] || [ -e "$KEY_PUBLIC" ]; then
echo " - Existing openSSH $keytype keys have been detected; key type skipped"
echo " - To forcibly overwrite the keys, run using the -f (--force) option"
elif [ -e "$DROPBEAR_KEY" ] && [ -f "$DROPBEAR_KEY" ]; then
# generate converted private key
echo "Converting dropbear $keytype private key into private openSSH key..."
"$CONVERT_PROG" dropbear openssh "$DROPBEAR_KEY" "$KEY_PRIVATE" >/dev/null 2>&1;
KEYCOUNT=$((KEYCOUNT+1))
# Now try to generate converted public key
if command -v "ssh-keygen" >/dev/null 2>&1; then
echo "Converting openssh $keytype private key into public openSSH key..."
ssh-keygen -y -f "$KEY_PRIVATE" -y > "$KEY_PUBLIC";
else
echo "Skipping public key conversion because ssh-keygen is not available";
fi;
else
echo "Unable to find dropbear $keytype key; skipping conversion"
fi;
done;
echo "---"
# If we temporarily installed the converter, remove it
if command -v "$CONVERT_PROG" >/dev/null 2>&1 && [ "$REMOVEDC" ]; then
echo "Removing $CONVERT_PROG utility..." && opkg remove "$CONVERT_PROG" >/dev/null 2>&1;
hash -r
# Make sure the removal was completed
if command -v "$CONVERT_PROG" >/dev/null 2>&1; then
echo "Removal of the $CONVERT_PROG utility may have experienced an error"
echo "A manual execution of \`opkg remove $CONVERT_PROG\` may be required"
fi;
else
echo "Pre-existing $CONVERT_PROG installation detected; skipping uninstall"
fi
echo "---"
if [ -e "$DROPBEAR_DIR/authorized_keys" ] && command -v "sort" >/dev/null 2>&1; then
echo "Copying dropbear authorized keys to openSSH authorized keys file...";
AUTH_KEY_FILE="${OPENSSH_DIR}/authorized_keys"
if ! [ -d "$AUTH_KEY_FILE" ]; then
if ! [ -e "$AUTH_KEY_FILE" ]; then
touch "$AUTH_KEY_FILE";
else
# Make a backup of the original authorized keys file just in case
# Uses a UUID to eliminate chance of collision in POSIX compliant way
cp "$AUTH_KEY_FILE" "${OPENSSH_DIR}/authorized_keys.${BACKUP_UUID}.bak"
fi;
sort -u "$DROPBEAR_DIR/authorized_keys" "$AUTH_KEY_FILE" -o "$AUTH_KEY_FILE";
fi
fi;
echo "---"
echo "There were $KEYCOUNT private keys converted during this script execution";
echo "The dropbear to openSSH key conversion is now complete!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment