|
#!/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!" |
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.