Skip to content

Instantly share code, notes, and snippets.

@headquarters
Created January 6, 2020 18:00
Show Gist options
  • Save headquarters/d11242533ae7cf68f05a1711d3e4b5d3 to your computer and use it in GitHub Desktop.
Save headquarters/d11242533ae7cf68f05a1711d3e4b5d3 to your computer and use it in GitHub Desktop.
SSH Tunnel to MySQL via Bastion Host
#!/bin/bash
# The following environment variables are required for connecting to the DB via an SSH tunnel:
# DBHOST -> the MySQL DB endpoint
# BASTIONUSER -> username for connecting to the bastion host, associated with your SSH key
# BASTIONHOST -> the IP or hostname of the bastion host
#
# Overriding the SSH key path is optional:
# SSHKEYPATH -> if using a non-default SSH key, set this to override ~/.ssh/id_rsa
if [ -z "$DBHOST" ]; then
echo "Missing DBHOST environment variable."
exit -1
fi
if [ -z "$BASTIONUSER" ]; then
echo "Missing BASTIONUSER environment variable."
exit -1
fi
if [ -z "$BASTIONHOST" ]; then
echo "Missing BASTIONHOST environment variable."
exit -1
fi
if [ -n "$SSHKEYPATH" ]; then
PUBLICKEYPATH="$SSHKEYPATH"
else
PUBLICKEYPATH="~/.ssh/id_rsa"
fi
SERVER="$BASTIONUSER@$BASTIONHOST"
SOCKET=/tmp/dbssh
if [ -S "$SOCKET" ]; then
echo "SSH tunnel already exists so sending exit command before creating a new one."
ssh -S $SOCKET -O exit $SERVER
fi
echo "Creating new ssh tunnel."
ssh -i $PUBLICKEYPATH -f -N -M -S $SOCKET -L 3306:$DBHOST:3306 $SERVER
@headquarters
Copy link
Author

Thanks to the following Stack Overflow questions for help:
https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash
https://stackoverflow.com/questions/37618443/why-cant-bash-recognize-the-existence-of-a-socket-file
https://unix.stackexchange.com/a/164656
https://unix.stackexchange.com/a/328824

Once environment variables are set, this could be integrated with something like a Node.js project via a script like
"start-with-db": "./bastion-host.sh && npm run start"

Then running npm run start-with-db would spin up the SSH tunnel and then start the application. With this setup, the application would connect to the database as if it's local, using the hostname "localhost".

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