Last active
December 28, 2025 21:45
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /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