-
-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
b8eab7c
commit 37e5217
Showing
2 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#!/usr/bin/env bash | ||
# Usage: | ||
# ssh-et [ssh_options] <remote> | ||
# | ||
# See also https://github.com/infokiller/ssh-et | ||
|
||
# See https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/ | ||
set -o errexit -o errtrace -o nounset -o pipefail | ||
|
||
_command_exists() { | ||
command -v -- "$1" &> /dev/null | ||
} | ||
|
||
_log_info() { | ||
printf 'ssh-et: %s\n' "$*" | ||
} | ||
|
||
_error() { | ||
local error normal | ||
# Red color | ||
error="$(tput setaf 1 2> /dev/null)" || true | ||
normal="$(tput sgr0 2> /dev/null)" || true | ||
printf >&2 '%s\n' "${error}${*}${normal}" | ||
} | ||
|
||
_log_error() { | ||
_error "$(printf 'ssh-et: %s' "$*")" | ||
} | ||
|
||
_print_usage_and_die() { | ||
printf >&2 'Usage: ssh-et [ssh_options] <remote>\n' | ||
exit 1 | ||
} | ||
|
||
_check_deps() { | ||
local s=0 | ||
if ((BASH_VERSINFO[0] < 4)); then | ||
_log_error 'Bash version must be at least 4.0' | ||
s=1 | ||
fi | ||
for cmd in et ssh; do | ||
if ! _command_exists "${cmd}"; then | ||
_log_error "Missing dependency: ${cmd}" | ||
s=1 | ||
fi | ||
done | ||
return $s | ||
} | ||
|
||
_check_args() { | ||
if (($# < 1)); then | ||
_print_usage_and_die | ||
fi | ||
if [[ "${*: -1}" == -* ]]; then | ||
_log_error 'Last arg must be a remote, not an SSH option' | ||
_print_usage_and_die | ||
fi | ||
} | ||
|
||
# The range 49152–65535 contains ephemeral/dynamic ports. We scan 200 ports | ||
# that start with the prefixes "522" or "622" (the 22 part of the prefix is | ||
# useful to remember it's used for SSH). | ||
_find_ephemeral_port() { | ||
for port in {52200..52299} {62200..62299}; do | ||
# Check if port is open. See: https://stackoverflow.com/a/6943581 | ||
if ! { printf '' > /dev/tcp/127.0.0.1/"${port}"; } &> /dev/null; then | ||
echo "${port}" | ||
return 0 | ||
fi | ||
done | ||
return 1 | ||
} | ||
|
||
main() { | ||
_check_deps || return 1 | ||
_check_args "$@" || return 1 | ||
local remote="${*: -1}" | ||
local ssh_args=("${@:1:(($# - 1))}") | ||
local tmpdir | ||
tmpdir="$(mktemp -d -t "ssh-et-fifo-$$_XXX")" | ||
# NOTE: The path variable in trap must be expanded here because it may not be | ||
# defined when the trap is ran. | ||
# shellcheck disable=SC2064 | ||
trap "rm -rf -- '${tmpdir}' &> /dev/null || true" EXIT ERR INT HUP TERM | ||
local port | ||
if ! port="$(_find_ephemeral_port)"; then | ||
_log_error 'Could not find an ephemeral port' | ||
return 2 | ||
fi | ||
_log_info "Found open port: ${port}" | ||
local et_fifo="${tmpdir}/et_fifo" | ||
mkfifo "${et_fifo}" || return $? | ||
local et_cmd=(et -t "${port}":22 -N "${remote}") | ||
_log_info "Running: ${et_cmd[*]}" | ||
"${et_cmd[@]}" > "${et_fifo}" & | ||
et_pid=$! | ||
found=0 | ||
while IFS='' read -r line; do | ||
printf 'et: %s\n' "${line}" | ||
if [[ $line == *"feel free to background"* ]]; then | ||
found=1 | ||
break | ||
fi | ||
done < "${et_fifo}" | ||
((found)) || return 3 | ||
# We use the localhost loopback address for all remote hosts, so we don't want | ||
# to register it in the known hosts file or do any host auth against it (which | ||
# will lead to errors since SSH will think the host key changed). et does its | ||
# own host auth so this is hopefully safe. | ||
local ssh_cmd=( | ||
ssh -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking=no' | ||
'127.0.0.1' -p "${port}" "${ssh_args[@]}" | ||
) | ||
_log_info "Running: ${ssh_cmd[*]}" | ||
"${ssh_cmd[@]}" | ||
kill "${et_pid}" | ||
# wait "${et_pid}" | ||
rm -rf -- "${tmpdir}" | ||
} | ||
|
||
main "$@" |
This file contains 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