Skip to content

Instantly share code, notes, and snippets.

@GuyPaddock
Created May 2, 2023 03:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GuyPaddock/bd80c42f7a471c07963424aafe5eff3d to your computer and use it in GitHub Desktop.
Save GuyPaddock/bd80c42f7a471c07963424aafe5eff3d to your computer and use it in GitHub Desktop.
Mount encrypted Synology volumes using key files over SSH
#!/usr/bin/env bash
##
# @file
# Mount encrypted Synology shared folders on their NAS over SSH.
#
# As long as key files are being stored securely on the system from which this
# command is being run, this approach offers more security than the
# "Key Manager" functionality native to Synology NASes since it does not store
# the encryption keys for volumes on the NAS device itself. This is because
# Synology uses the same cypher/passphrase on all NASes to decrypt keys stored
# in Key Manager. An alternative is to move keys to a separate USB thumb drive
# that has to be inserted to mount volumes, but that thumb drive could be stolen
# and/or represent an obstacle for teams working remotely.
#
# Requirements:
# - SSH must be enabled on the target Synology server.
# - The SSH user must be in the local "administrators" group on the Synology
# server.
# - The SSH user must not be subject to entering a password to use `sudo`.
# - Each encryption key must be stored in a file with the same name as its
# corresponding shared folder, suffixed with ".key" (e.g., "My Share.key").
#
# Usage: mount_encrypted_shares.sh <SSH_HOST> <KEY_FILE_FOLDER> <SSH_USERNAME>
#
function print_usage {
{
echo "Usage: '$0' <SSH_HOST> <KEY_FILE_FOLDER> <SSH_USERNAME>"
echo "Mount encrypted Synology shared folders over SSH."
echo ""
echo "Options:"
echo " SSH_HOST The hostname or IP address of the Synology NAS."
echo " KEY_FILE_FOLDER The path to the folder that contains keys for the shares."
echo " SSH_USERNAME The username to use when connecting to the Synology NAS."
echo ""
} >&2
exit 1
}
# Parse arguments
if [[ $# -ne 3 ]]; then
print_usage
fi
ssh_host="${1:-}"
key_file_directory="${2:-}"
ssh_username="${3:-}"
# Yes, Synology uses a hardcoded passphrase for this. Yes, it's the same in all
# NASes. See:
# https://blog.elcomsoft.com/2019/11/synology-nas-encryption-forensic-analysis-of-synology-nas-devices/
# shellcheck disable=SC2016
synology_passphrase='$1$5YN01o9y'
for arg in "$@"; do
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
print_usage
fi
done
if [[ ! -d "${key_file_directory}" ]]; then
print_usage
fi
find "${key_file_directory}" -maxdepth 1 -name '*.key' -type f | sort | while read -r filename; do
share_name=$(basename "${filename}" ".key")
echo -n " - ${share_name}: "
base64 --wrap=0 "${filename}" |
ssh "${ssh_username}@${ssh_host}" \
"base64 --decode >/tmp/share.key;"`
`"sudo /usr/syno/sbin/synoshare --enc_mount \"${share_name}\" \$("`
`"echo '$synology_passphrase' | "`
`"ecryptfs-unwrap-passphrase /tmp/share.key -;"`
`") && echo \"Mounted successfully.\""
ssh -n "${ssh_username}@${ssh_host}" "rm /tmp/share.key"
done
echo
echo "Done!"
@GuyPaddock
Copy link
Author

GuyPaddock commented Mar 30, 2024

NOTE: Something I did not realize until months after my initial proof of concept is that Synology NASes record all commands that are run from CLI, so if a password is included in any command it will appear in a log. This means that sending the encryption key as part of a command being run via SSH is less secure than storing the passwords in Key Manage since they’ll be saved in clear-text.

A better approach would be to echo the password over standard in to the SSH process, have the remote command write the password to a file, and then send a command to decrypt the file, so that the password never appears in the command line that gets logged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment