Last active
June 3, 2016 08:17
-
-
Save craSH/3ac797a4371054ef9fd1 to your computer and use it in GitHub Desktop.
Script to setup multiple SSH tunnels in a reliable way for use with FoxyProxy or other SOCKS-aware clients
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
#!/usr/bin/env bash | |
# | |
# Use to setup numerous various tunnels to SSH servers, useful with ssh config blocks like those below | |
# for each host, with incrementing port numbers for each - then configure FoxyProxy etc to use the unique | |
# port for each host you want to tunnel out of. | |
# | |
# Thanks to tecknicaltom <[email protected]> for the initial idea behind tying this all together. | |
# | |
# Host host_alpha | |
# IdentityFile ~/.ssh/id_ecdsa-$USER-host_alpha-<remote_hostname>-<key_gen_year>-<key_gen_month> | |
# DynamicForward localhost:4504 | |
# | |
# Host host_bravo | |
# IdentityFile ~/.ssh/id_ecdsa-$USER-host_bravo-<remote_hostname>-<key_gen_year>-<key_gen_month> | |
# DynamicForward localhost:4505 | |
# | |
# Example FoxyProxy config XML block (import/export): | |
# | |
# <proxy name="host_alpha" id="12345" notes="localhost:4504/socks (SSH)" enabled="true" color="#AFBD31" mode="manual" autoconfMode="pac" lastresort="false"> | |
# <manualconf host="localhost" port="4504" socksversion="5" isSocks="true"/> | |
# <autoconf url="" reloadPac="false" loadNotification="true" errorNotification="true" autoReload="false" reloadFreqMins="60" disableOnBadPAC="true"/> | |
# <matches> | |
# <match enabled="true" name="*" isRegex="false" pattern="*" reload="true" autoReload="false" isBlackList="false" isMultiLine="false" fromSubscription="false" caseSensitive="false"/> | |
# </matches> | |
# </proxy> | |
# | |
# <proxy name="host_bravo" id="54321" notes="localhost:4505/socks (SSH)" enabled="true" color="#AFBD31" mode="manual" autoconfMode="pac" lastresort="false"> | |
# <manualconf host="localhost" port="4505" socksversion="5" isSocks="true"/> | |
# <autoconf url="" reloadPac="false" loadNotification="true" errorNotification="true" autoReload="false" reloadFreqMins="60" disableOnBadPAC="true"/> | |
# <matches> | |
# <match enabled="true" name="*" isRegex="false" pattern="*" reload="true" autoReload="false" isBlackList="false" isMultiLine="false" fromSubscription="false" caseSensitive="false"/> | |
# </matches> | |
# </proxy> | |
# | |
# | |
# SSH Options | |
# -N Do not execute a remote command. This is useful for just forwarding ports (protocol version 2 only). | |
# -f Requests ssh to go to background just before command execution. This is useful if ssh is going to ask | |
# for passwords or passphrases, but the user wants it in the background. This implies -n. | |
# -n (implied from -f, above) Redirects stdin from /dev/null (actually, prevents reading from stdin). | |
# This must be used when ssh is run in the background. | |
# -q Quiet mode. Causes most warning and diagnostic messages to be suppressed. | |
ssh_cli_options="-Nfq -oControlMaster=no -oControlPath=none -oControlPersist=no" | |
# AutoSSH options (see man page for autossh for all environment variable information) | |
export AUTOSSH_GATETIME=0 | |
export AUTOSSH_POLL=30 | |
# Hosts to connect to/setup tunnels for, one per line | |
hosts_list="${HOME}/.config/scripts/init-tunnels" | |
if [ ! -r "$hosts_list" ]; then | |
echo "[FATAL] Can't read $hosts_list - ensure it exists and contains one host per line." >&2 | |
exit 1 | |
fi | |
hosts=$(cat "$hosts_list") | |
# Connect to each host with the specified options | |
connection_count=0 | |
for host in $hosts; do | |
# No monitor port (needed sometimes in weird environments) | |
#ssh_cmd="autossh -M 0" | |
# Choose a monitor port off of a base and 10 away from the previous one | |
ssh_cmd="autossh -Nf -M $((48004 + (connection_count += 10))) $ssh_cli_options" | |
$ssh_cmd $host | |
if [ 0 -eq $? ]; then | |
echo -n "[INFO] Tunnel established: $host" | |
socks_port=$(grep "^Host.*${host}" ~/.ssh/config -A 5 \ | |
| grep "DynamicForward" \ | |
| head -n 1 | awk -F ':' '{print $NF}') | |
if [ -n "$socks_port" ]; then | |
echo ", SOCKS listener: $socks_port" | |
else | |
echo | |
fi | |
else | |
echo "[ERROR] Tunnel FAILED ($?): $host" >&2 | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment