Created
January 20, 2025 15:16
-
-
Save mankins/dd085823dd5e7aa717ecf9ba3e65a01f to your computer and use it in GitHub Desktop.
jump box ssh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#set -x | |
# If there's a proxy host set in the environment, pull it in | |
[ -n $FTAWS_PROXY_HOST ] && PROXYHOST=$FTAWS_PROXY_HOST | |
# Private is the 'usual' way, subject to override in a few places below. If any code below selects public, then we go with the public address. | |
PROXYTOIPTYPE="-r" | |
while getopts "hi:n:R:k:fp:q1vV:x" flag | |
do | |
case "$flag" in | |
h) | |
echo "SSH to an instance using instance name or ID rather than the IP address" | |
echo "Usage: $(basename $0) [-h] [-v] [-f] [-i <instance_id_pattern> | -n <instance_name_pattern> ] [-R <region>] [-k <keyfile>] [-p <proxyhost>] [-q] [-x] [\"command\"]" | |
echo " [-h] display this help" | |
echo " [-i] <instance_id_pattern> ssh to the instance(s) with this ID or matching this pattern. Do not use with -n." | |
echo " [-n] <instance_name_pattern> ssh to the instance(s) with this name or matching this pattern. Do not use with -i." | |
echo " [-R] <region> work on instance(s) in <region>. If omitted, use the default region. Region is, e.g. 'us-east-1'" | |
echo " [-v] verbose - print instance info when connecting" | |
echo " [-V <n>] really verbose - <n> may be '1', '2', or '3'. Calls ssh with -v, -vv, or -vvv based on <n>" | |
echo " [-k] </path/to/privatekey> use this key to login (same as -i in ssh)" | |
echo " [-f] Forward Agent - use my credentials transitively for subsequent authentication from the host" | |
echo " [-p] <proxy-through-this-host> (dns hostname, not instance name) to a host in the same region" | |
echo " [-q] if proxying (FTAWS_PROXY_HOST set, or -p) proxy to the PUBLIC address of the target, not the private address" | |
echo " [-x] connect directly, even if ia proxy host is set in my environment" | |
echo " [-1] if instance_name_pattern matches more than one host, operate only on the first in the list" | |
echo " Useful for connecting to 'any' instance whose name matches a pattern:" | |
echo " $ ftaws-ssh -1 -n prod-web-402-* connects to the first instance matching the pattern" | |
echo " If -1 is not used and instance_name_pattern matches more than one instance, then each will be connected in turn." | |
echo " [\"command\"] run remote command" | |
echo | |
echo "If you always use one proxy host, export FTAWS_PROXY_HOST and this script will automatically use it (no need for -p)" | |
echo "Add to your login script:" | |
echo " export FTAWS_PROXY_HOST=<hostname> where <hostname> is the DNS name of the proxy" | |
echo "If FTAWS_PROXY_HOST is set and '-p <hostname>' appears on the command line, -p takes precedence" | |
echo | |
exit 1 | |
;; | |
i) | |
INST="-i ${OPTARG}" | |
;; | |
n) | |
INST="-n ${OPTARG}" | |
;; | |
R) | |
REGION="${OPTARG}" | |
;; | |
f) | |
FORWARDAGENT="-o ForwardAgent=yes" | |
;; | |
k) | |
KEYFILE="-i ${OPTARG}" | |
;; | |
p) | |
PROXYHOST="${OPTARG}" | |
;; | |
q) | |
PROXYTOIPTYPE="-u" | |
;; | |
1) | |
FIRSTONLY="-1" | |
;; | |
v) | |
VERBOSE="1" | |
;; | |
V) | |
VERBOSE_SSH="${OPTARG}" | |
;; | |
x) | |
NOPROXY="1" | |
;; | |
esac | |
done | |
# non-labeled args slide over to $1... | |
shift $(($OPTIND - 1)) | |
if [ -z "$INST" ] | |
then | |
echo "Must specify either -n <instance_name_pattern> or -i <instance_id_pattern>" | |
exit 1 | |
fi | |
# Set up the verbose-call string for ssh if -V was set | |
if [ -n "$VERBOSE_SSH" ] | |
then | |
VERBOSE_SSH_STRING="-" | |
while [ $VERBOSE_SSH -gt 0 ] | |
do | |
VERBOSE_SSH_STRING+="v" | |
((VERBOSE_SSH--)) | |
done | |
fi | |
# Auto-detect a need to use the target's public IP address (proxy gateway and target are in different regions) | |
if [ -n "$FTAWS_PROXY_HOST_REGION" ] | |
then | |
if [ -n "$REGION" ] | |
then | |
# An explicitly-set region (-R <region>) overrides any region settings from the environment | |
# If an explicitly-set region is not the same as that of the proxy host, use the target's public address | |
[ "$REGION" == "$FTAWS_PROXY_HOST_REGION" ] || PROXYTOIPTYPE="-u" | |
# and prefix a -R to make REGION easy to pass to ftaws-get-ip below | |
REGION="-R $REGION" | |
else | |
# Region was not explicitly set. Check the region we're working in by default -- if not the smae | |
# as the proxy host, use the target's public address | |
echo "$EC2_URL" | grep "$FTAWS_PROXY_HOST_REGION" > /dev/null | |
[ $? -eq 0 ] || PROXYTOIPTYPE="-u" | |
fi | |
fi | |
# if no proxy host is set, we are connecting directly. get the public IP | |
if [ -z "$PROXYHOST" -o -n "$NOPROXY" ] | |
then | |
IP_LIST=$(ftaws-get-ip $FIRSTONLY $REGION -u ${INST}) | |
if [ -z "$IP_LIST" ] | |
then | |
echo "Instance not found: $INST" | |
exit 1 | |
fi | |
for IP in $IP_LIST | |
do | |
[ -z "$VERBOSE" ] || echo "$(ftaws-get-name $REGION $IP)" | |
ssh $VERBOSE_SSH_STRING -t -o CheckHostIP=no -o StrictHostKeyChecking=no -o ConnectTimeout=30 $FORWARDAGENT ec2-user@${IP} ${KEYFILE} "${@}" | |
done | |
# otherwise if a proxy host is set, connect to the proxy host's public ip, then to either the public or private IP of the true target | |
# depending on whether it is in the same region as the proxy host (see the Auto-Detect section above for enlightenment) | |
else | |
# OpenSSH pre-version 5.4: ssh ec2-user@INTERNALIP -o "ProxyCommand ssh ec2-user@$PROXYHOST nc %h %p" | |
# OpenSSH 5.4 and later: ssh ec2-user@INTERNALIP -o "ProxyCommand ssh -W %h:%p ec2-user@$PROXYHOST" | |
# Versions 5.4 and later have netcat built in - so it's not necessary to call it separately | |
# That's preferred, but even OS/X 10.6 has a pre-5.4 OpenSSH, so for compatibility we still use the old way | |
IP_LIST=$(ftaws-get-ip $FIRSTONLY $REGION $PROXYTOIPTYPE ${INST}) | |
if [ -z "$IP_LIST" ] | |
then | |
echo "Instance not found: $INST" | |
exit 1 | |
fi | |
for IP in $IP_LIST | |
do | |
[ -z "$VERBOSE" ] || echo "$(ftaws-get-name $REGION $IP)" | |
ssh $VERBOSE_SSH_STRING -t -t ec2-user@${IP} ${KEYFILE} -o CheckHostIP=no -o StrictHostKeyChecking=no -o ConnectTimeout=30 $FORWARDAGENT -o "ProxyCommand ssh ec2-user@$PROXYHOST nc %h %p" "${@}" | |
done | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment