sshuttle/scripts/exec-sshuttle
2024-08-06 08:38:24 +10:00

160 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
export MSYS_NO_PATHCONV=1
function with_set_x() {
set -x
"$@"
{
ec=$?
set +x
return $ec
} 2>/dev/null
}
function log() {
echo "$*" >&2
}
ssh_cmd='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
ssh_copy_id=false
args=()
subnet_args=()
while [[ $# -gt 0 ]]; do
arg=$1
shift
case "$arg" in
-v|-vv*)
ssh_cmd+=" -v"
args+=("$arg")
;;
-r)
args+=("-r" "$1")
shift
;;
--copy-id)
ssh_copy_id=true
;;
--server-py=*)
server_pyenv_ver="${arg#*=}"
;;
--client-py=*)
client_pyenv_ver="${arg#*=}"
;;
-6)
ipv6_only=true
;;
--sshuttle-bin=*)
sshuttle_bin="${arg#*=}"
;;
-N|*/*)
subnet_args+=("$arg")
;;
-*)
args+=("$arg")
;;
*)
if [[ -z "$target" ]]; then
target=$arg
else
args+=("$arg")
fi
;;
esac
done
if [[ ${#subnet_args[@]} -eq 0 ]]; then
subnet_args=("-N")
fi
if [[ $target == node-* ]]; then
log "Target is a a test-bed node"
port="2222"
user_part="test:test"
host=$("$(dirname "$0")/test-bed" get-ip "$target")
index=${target#node-}
if [[ $ipv6_only == true ]]; then
args+=("2001:0DB8::/112")
else
args+=("10.55.$index.0/24")
fi
target="$user_part@$host:$port"
if ! command -v sshpass >/dev/null; then
log "sshpass is not found. You might have to manually enter ssh password: 'test'"
fi
if [[ -z $server_pyenv_ver ]]; then
log "server-py argumwnt is not specified. Setting it to 3.8"
server_pyenv_ver="3.8"
fi
fi
if [[ -n $server_pyenv_ver ]]; then
log "Would pass PYENV_VERRSION=$server_pyenv_ver to server. pyenv is required on server to make it work"
pycmd="/pyenv/shims/python"
ssh_cmd+=" -o SetEnv=PYENV_VERSION=${server_pyenv_ver:-'3'}"
args=("--python=$pycmd" "${args[@]}")
fi
if [[ $ssh_copy_id == true ]]; then
log "Trying to make it passwordless"
if [[ $target == *@* ]]; then
user_part="${target%%@*}"
host_part="${target#*@}"
else
user_part="$(whoami)"
host_part="$target"
fi
if [[ $host_part == *:* ]]; then
host="${host_part%:*}"
port="${host_part#*:}"
else
host="$host_part"
port="22"
fi
if [[ $user_part == *:* ]]; then
user="${user_part%:*}"
password="${user_part#*:}"
else
user="$user_part"
password=""
fi
cmd=(ssh-copy-id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p "$port" "$user@$host")
if [[ -n $password ]] && command -v sshpass >/dev/null; then
cmd=(sshpass -p "$password" "${cmd[@]}")
fi
with_set_x "${cmd[@]}"
fi
if [[ -z $sshuttle_bin || "$sshuttle_bin" == dev ]]; then
cd "$(dirname "$0")/.."
export PYTHONPATH="."
if [[ -n $client_pyenv_ver ]]; then
log "Using pyenv version: $client_pyenv_ver"
command -v pyenv &>/dev/null || log "You have to install pyenv to use --client-py" && exit 1
sshuttle_cmd=(/usr/bin/env PYENV_VERSION="$client_pyenv_ver" pyenv exec python -m sshuttle)
else
log "Using best python version availble"
if [ -x "$(command -v python3)" ] &&
python3 -c "import sys; sys.exit(not sys.version_info > (3, 5))"; then
sshuttle_cmd=(python3 -m sshuttle)
else
sshuttle_cmd=(python -m sshuttle)
fi
fi
else
[[ -n $client_pyenv_ver ]] && log "Can't specify --client-py when --sshuttle-bin is specified" && exit 1
sshuttle_cmd=("$sshuttle_bin")
fi
if [[ " ${args[*]} " != *" --ssh-cmd "* ]]; then
args=("--ssh-cmd" "$ssh_cmd" "${args[@]}")
fi
if [[ " ${args[*]} " != *" -r "* ]]; then
args=("-r" "$target" "${args[@]}")
fi
set -x
"${sshuttle_cmd[@]}" --version
exec "${sshuttle_cmd[@]}" "${args[@]}" "${subnet_args[@]}"