Skip to content

Instantly share code, notes, and snippets.

@callumgare
Last active February 12, 2024 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save callumgare/9be6af91534ca26d101c3161fd953619 to your computer and use it in GitHub Desktop.
Save callumgare/9be6af91534ca26d101c3161fd953619 to your computer and use it in GitHub Desktop.
A script to mount EFS volumes via an ssh bastion host
#!/bin/bash
SSH_PROXY_HOSTHAME=$1
EFS_ID=$2
AWS_REGION=$3
LOCAL_MOUNT_PATH=$4
usage () {
cat <<EOF
Usage: $(basename "$0") [user@]hostname-for-ssh-proxy efs-id aws-region [local-path-to-mount-to]
Example usage: $(basename "$0") username@proxy-host.com fs-0423ab789 us-east-1 /tmp/efs-dev-static
Description: Mounts an EFS volume that is in a non-publicly accessible VPC
by proxying the connection with ssh though a host that has been setup to
provide ingress to that VPC.
If "local-path-to-mount-to" is not given then a temparary path will be
created.
When run with sudo this script will attempt to identify the username of the
actual user running the script start the ssh process that that user so that
ssh uses the ssh key of the real user and not root.
EOF
}
usage_as_additional_info () {
echo ""
echo "--------------------------------------------------------------------------------"
usage
}
if [[ "$1" == "--help" ]]; then
usage
exit 0;
fi
# Get the name of the actual user running the script if run via sudo so as to run ssh proxy
# as the user and therefore connect using their ssh keys rather than the root user's keys.
run_as_actual_user () {
USERNAME=${SUDO_USER:-$(whoami)}
sudo -u "$USERNAME" "$@"
}
if [[ -z "$SSH_PROXY_HOSTHAME" ]]; then
echo "Error: Missing first argument." >&2
usage_as_additional_info
exit 1
fi
if [[ -z "$EFS_ID" ]]; then
echo "Error: Missing second argument." >&2
usage_as_additional_info
exit 1
fi
if [[ -z "$LOCAL_MOUNT_PATH" ]]; then
LOCAL_MOUNT_PATH="$(run_as_actual_user mktemp -d -t "$EFS_ID")"
fi
if [ "$EUID" -ne 0 ]
then echo "Please run as root (use sudo if you still want ssh to use your user account's ssh creds)"
exit
fi
get_free_port () {
for port in {10000..20000}; do
if ! (exec 2>&-; echo > "/dev/tcp/localhost/$port"); then
echo "$port"
return 0
fi
done
}
PROXY_PORT=$(get_free_port)
SSH_CONTROL_FILE=$(run_as_actual_user mktemp -t ssh-pid -u)
if [ -e "$LOCAL_MOUNT_PATH" ] && ! [ -d "$LOCAL_MOUNT_PATH" ]; then
echo "Mount point must be a directory" >&2
exit 1
elif ! [ -e "$LOCAL_MOUNT_PATH" ]; then
LOCAL_MOUNT_PATH_CREATION_REQUIRED=true
run_as_actual_user mkdir "$LOCAL_MOUNT_PATH"
fi
function cleanup {
umount "$LOCAL_MOUNT_PATH" || echo "Could not unmount $LOCAL_MOUNT_PATH"
if [ -n "$LOCAL_MOUNT_PATH_CREATION_REQUIRED" ]; then
rmdir "$LOCAL_MOUNT_PATH" || echo "Could not remove $LOCAL_MOUNT_PATH"
fi
ssh -S "$SSH_CONTROL_FILE" -O exit -q "$SSH_PROXY_HOSTHAME"
echo ""
echo "Volume unmounted"
}
trap cleanup EXIT
# Setup proxy for NFS connection
run_as_actual_user ssh -f -N -S "$SSH_CONTROL_FILE" -M -L "$PROXY_PORT:$EFS_ID.efs.$AWS_REGION.amazonaws.com:2049" "$SSH_PROXY_HOSTHAME"
# Mount EFS volume via NFS
mount -t nfs -o vers=4 -o tcp -o "port=$PROXY_PORT" -w localhost:/ "$LOCAL_MOUNT_PATH"
echo "$EFS_ID is mounted at $LOCAL_MOUNT_PATH"
# Infinite loop so mount can be cleaned up by exiting script
while true; do sleep 10000; done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment