Skip to content

Instantly share code, notes, and snippets.

@devanlai
Last active April 9, 2020 20:27
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 devanlai/bbc2d781150b5efb5b13f88fd844a83e to your computer and use it in GitHub Desktop.
Save devanlai/bbc2d781150b5efb5b13f88fd844a83e to your computer and use it in GitHub Desktop.
Script to resolve a target host via secondary SSH host, then ssh to the target IP directly
#!/bin/bash
# Utility script to first resolve the IP address of the target host to SSH into
# by SSHing into a secondary proxy host. For example, this can be used when
# the origin host does not support resolving names via mDNS, but the jump host
# does, while avoiding the overhead of routing the SSH connection through the
# jump host when the origin and target are already both in the same network.
set -e
set -o pipefail
function show_usage() {
cat <<-END
Resolve a hostname via a proxy host, then SSH to it.
Usage: $0 [OPTION]... HOST [-- TARGET SSH ARGS]
-P, --proxy-host [user@]host[:port] SSH to this host to resolve the hostname
-i identify_file Provide an identity file to connect to the
proxy host
-d, --debug Print debugging information
The proxy host can also be set via the SSH_DNS_PROXY_HOST env var
END
}
# Parse arguments
NUM_PARAMS=0
MAX_PARAMS=1
while (( "$#" )); do
case "$1" in
-P|--proxy-host)
SSH_DNS_PROXY_HOST=$2
shift 2
;;
-i)
IDENTITY_FILE=$2
shift 2
;;
-d|--debug)
DEBUG=true
shift 1
;;
-h|--help)
show_usage
exit 0
;;
--) # end argument parsing
shift
break
;;
-*|--*=) # unsupported flags
echo "Error: Unsupported flag $1" >&2
show_usage
exit 1
;;
*) # preserve positional arguments
if (($NUM_PARAMS < $MAX_PARAMS)); then
if (($NUM_PARAMS == 0)); then
TARGET_HOST=$1
fi
NUM_PARAMS=$NUM_PARAMS+1
shift
else
echo "Error: too many parameters ($NUM_PARAMS)" >&2
show_usage
exit 1
fi
;;
esac
done
if [[ -z "$TARGET_HOST" ]]; then
echo "Error: missing required parameter: HOST" >&2
show_usage
exit 1
fi
if [[ -z "$SSH_DNS_PROXY_HOST" ]]; then
echo "Error: missing required option: --proxy-host" >&2
show_usage
exit 1
fi
if [[ "$DEBUG" = true ]]; then
echo "Resolving $TARGET_HOST via $SSH_DNS_PROXY_HOST" >&2
fi
PROXY_SSH_ARGS=
if [[ ! -z "$IDENTITY_FILE" ]]; then
PROXY_SSH_ARGS="-i $IDENTITY_FILE"
fi
TARGET_IP=`ssh $PROXY_SSH_ARGS $SSH_DNS_PROXY_HOST "getent hosts $TARGET_HOST | cut -d ' ' -f 1"`
if [[ -z "$TARGET_IP" ]]; then
echo "Failed to resolve hostname for $TARGET_HOST on $SSH_DNS_PROXY_HOST" >&2
exit 2
fi
if [[ "$DEBUG" = true ]]; then
echo "Resolved $TARGET_HOST to $TARGET_IP" >&2
fi
if [[ "$DEBUG" = true ]]; then
echo "Executing SSH command: ssh $TARGET_IP $*" >&2
fi
exec ssh $TARGET_IP $*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment