File: //lib/Acronis/generate_sshkey_param.sh
#!/bin/bash
#
# Generates kernel boot parameter with SSH public key for Linux boot media.
# Asks for a path to an SSH public key, generates one if needed,
# and outputs the kernel parameter in the format: sshkey=<base64-encoded-key>
# Automatically detects OpenSSH version and selects optimal key type.
#
# Detect OpenSSH version and select best key type
detect_key_type() {
local version_str major minor version
version_str=$(ssh -V 2>&1)
if [[ "$version_str" =~ OpenSSH[_[:space:]]([0-9]+)\.([0-9]+) ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
version=$((major * 10 + minor))
if [ "$version" -ge 65 ]; then
# OpenSSH 6.5+ supports Ed25519
KEY_TYPE="ed25519"
KEY_NAME="id_ed25519"
KEY_BITS=""
elif [ "$version" -ge 57 ]; then
# OpenSSH 5.7+ supports ECDSA
KEY_TYPE="ecdsa"
KEY_NAME="id_ecdsa"
KEY_BITS="256"
else
# Fallback to RSA 1024 for very old systems (shorter key for boot param)
KEY_TYPE="rsa"
KEY_NAME="id_rsa"
KEY_BITS="1024"
fi
else
# Fallback to RSA 1024 for very old systems (shorter key for boot param)
KEY_TYPE="rsa"
KEY_NAME="id_rsa"
KEY_BITS="1024"
fi
}
detect_key_type
DEFAULT_KEY_PATH="$HOME/.ssh/$KEY_NAME.pub"
echo "=== SSH Key Boot Parameter Generator ==="
echo "Detected key type: $KEY_TYPE"
echo ""
# Ask for key path
read -p "Enter path to SSH public key (default: $DEFAULT_KEY_PATH): " KEY_PATH
if [ -z "$KEY_PATH" ]; then
KEY_PATH="$DEFAULT_KEY_PATH"
fi
# Expand ~ if used
KEY_PATH="${KEY_PATH/#\~/$HOME}"
# Check if key exists
if [ ! -f "$KEY_PATH" ]; then
echo "Public key not found at: $KEY_PATH"
PRIVATE_KEY_PATH="${KEY_PATH%.pub}"
SSH_DIR=$(dirname "$PRIVATE_KEY_PATH")
if [ "$KEY_PATH" = "$DEFAULT_KEY_PATH" ] && [ ! -f "$PRIVATE_KEY_PATH" ]; then
read -p "Generate new SSH key pair? (y/n): " GENERATE
if [ "$GENERATE" = "y" ] || [ "$GENERATE" = "Y" ]; then
echo "Generating SSH key pair..."
# Create .ssh directory if needed
if [ ! -d "$SSH_DIR" ]; then
mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"
fi
# Use minimal comment to save space in boot parameter
KEYGEN_ARGS="-t $KEY_TYPE -f $PRIVATE_KEY_PATH -N \"\" -C \"\""
if [ -n "$KEY_BITS" ]; then
KEYGEN_ARGS="$KEYGEN_ARGS -b $KEY_BITS"
fi
eval ssh-keygen $KEYGEN_ARGS
if [ ! -f "$KEY_PATH" ]; then
echo "Failed to generate SSH key"
exit 1
fi
echo "SSH key pair generated successfully"
else
echo "Aborted"
exit 1
fi
else
echo "Please provide a valid path to an existing public key"
exit 1
fi
fi
# Read and encode the key
KEY_CONTENT=$(cat "$KEY_PATH" | tr -d '\n')
BASE64_KEY=$(echo -n "$KEY_CONTENT" | base64 -w0)
PARAM_STRING="sshkey=$BASE64_KEY"
PARAM_LENGTH=${#PARAM_STRING}
# Boot loader limits (sshkey parameter only, other params take ~75 chars):
# - BIOS: 255 total, ~180 for sshkey
# - EFI: 1024 total, ~950 for sshkey
# - ARM: no limit
LIMIT_BIOS=180
LIMIT_EFI=950
echo ""
echo "=== Kernel Boot Parameter ==="
echo "Parameter length: $PARAM_LENGTH characters"
echo ""
# Check compatibility with different boot loaders (only show if there are issues)
if [ $PARAM_LENGTH -gt $LIMIT_EFI ]; then
echo "WARNING: Key is TOO LONG for BIOS and EFI boot loaders!"
KEY_TYPE_DETECTED=$(echo "$KEY_CONTENT" | grep -oE '^ssh-[^ ]+' | cut -d- -f2)
echo "Your key type: ${KEY_TYPE_DETECTED:-unknown}"
echo ""
echo "Generate Ed25519 key (~100 chars) on a modern system (OpenSSH 6.5+)"
echo "and use that machine to connect to boot media."
elif [ $PARAM_LENGTH -gt $LIMIT_BIOS ]; then
echo "WARNING: Key is too long for BIOS boot loader (limit ~$LIMIT_BIOS chars)!"
KEY_TYPE_DETECTED=$(echo "$KEY_CONTENT" | grep -oE '^ssh-[^ ]+' | cut -d- -f2)
echo "Your key type: ${KEY_TYPE_DETECTED:-unknown}"
echo ""
echo "For BIOS compatibility, generate Ed25519 key (~100 chars) on a modern system"
echo "(OpenSSH 6.5+) and use that machine to connect to boot media."
fi
echo ""
echo "Add this parameter to your boot command line:"
echo ""
echo "$PARAM_STRING"
echo ""
# Copy to clipboard if xclip or xsel available
if command -v xclip &> /dev/null; then
echo -n "$PARAM_STRING" | xclip -selection clipboard
echo "(Copied to clipboard)"
elif command -v xsel &> /dev/null; then
echo -n "$PARAM_STRING" | xsel --clipboard
echo "(Copied to clipboard)"
fi