1 contributor
#!/usr/bin/env bash
set -euo pipefail
real_ssh="/usr/bin/ssh"
ssh_config="$HOME/.ssh/config"
remote_agent="/run/user/0/gnupg/S.gpg-agent.ssh"
# Access model, May 2026
# ----------------------
#
# Cheia fizica este montata pe is-jumper. Wrapper-ul local nu mai face bridge
# de agent in /tmp; in schimb ruleaza clientul SSH activ pe is-jumper:
#
# local ssh wrapper
# -> is-jumper (192.168.2.100, acces local cu id_ed25519)
# -> J1/J2/j1/j2 (autentificare cu agentul fizic de pe is-jumper)
# -> ssh final-host
#
# Custom jump flags (stripped by wrapper, not passed to real ssh):
# -J1 use J1 via VPN (default for configured hosts)
# -J2 use J2 via VPN
# -j1 use j1 via public DNS (urgente, fara ruta VPN)
# -j2 use j2 via public DNS (urgente, fara ruta VPN)
#
# Hosturi arbitrare (fara config SSH): wrapper-ul le ruteza prin jump doar daca
# unul dintre flagurile de mai sus este prezent explicit.
target_user=""
target_host=""
target_port=""
target_auth=""
found_target=0
cmd_args=()
ssh_config_args=()
jump_alias="j1"
custom_jump_set=0
host_configured=1
target_is_jump=0
want_subsystem=0
user_option=""
port_option=""
has_explicit_config() {
local arg
for arg in "$@"; do
case "$arg" in
-F|-F*)
return 0
;;
esac
done
return 1
}
quote_cmd() {
local out="" q part
for part in "$@"; do
printf -v q "%q" "$part"
out+="$q "
done
printf "%s" "$out"
}
resolve_ssh_config() {
local target=$1
local line
target_user=""
target_host=""
target_port=""
target_auth=""
while IFS= read -r line; do
case "$line" in
user\ *) target_user=${line#user } ;;
hostname\ *) target_host=${line#hostname } ;;
port\ *) target_port=${line#port } ;;
setenv\ *NG_SSH_AUTH=password-interactive*) target_auth="password_interactive" ;;
esac
done < <("$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} -G "$target" 2>/dev/null)
[[ -n "$target_user" && -n "$target_host" && -n "$target_port" ]]
}
run_real_ssh() {
exec "$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} "$@"
}
resolve_target_from_config() {
local target=$1
local default_user=${USER:-${LOGNAME:-}}
local user_override=""
local target_route=""
case "$target" in
*@*)
user_override=${target%@*}
target=${target#*@}
;;
esac
case "$target" in
is-jumper|192.168.2.100)
return 1
;;
J1|J2|j1|j2)
target_is_jump=1
;;
esac
resolve_ssh_config "$target" || return 1
# Check for SSH_ROUTE in config
while IFS= read -r line; do
case "$line" in
setenv\ SSH_ROUTE=*)
target_route=${line#setenv SSH_ROUTE=}
;;
esac
done < <("$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} -G "$target" 2>/dev/null)
# If route is "local", no jump needed
if [[ "$target_route" == "local" ]]; then
return 1
fi
if [[ -n "$user_override" ]]; then
target_user=$user_override
fi
if [[ -n "$user_option" ]]; then
target_user=$user_option
fi
if [[ -n "$port_option" ]]; then
target_port=$port_option
fi
# Unconfigured host (ssh -G returns defaults): bypass unless a custom jump
# was requested explicitly.
if [[ "$target_is_jump" -eq 0 && "$target_host" == "$target" && "$target_port" == "22" && "$target_user" == "$default_user" ]]; then
[[ $custom_jump_set -eq 0 ]] && return 1
host_configured=0
fi
[[ -n "$target_user" && -n "$target_host" && -n "$target_port" ]]
}
resolve_jump() {
local saved_user saved_host saved_port saved_auth
saved_user=$target_user
saved_host=$target_host
saved_port=$target_port
saved_auth=$target_auth
resolve_ssh_config "$jump_alias" || {
printf "ssh-wrapper: cannot resolve jump alias %s\n" "$jump_alias" >&2
exit 255
}
jump_user=$target_user
jump_host=$target_host
jump_port=$target_port
target_user=$saved_user
target_host=$saved_host
target_port=$saved_port
target_auth=$saved_auth
}
# Pre-process: extract custom jump flags and strip them from args.
filtered_args=()
for arg in "$@"; do
case "$arg" in
-J1) jump_alias="j1"; custom_jump_set=1 ;;
-J2) jump_alias="j2"; custom_jump_set=1 ;;
-j1) jump_alias="j1"; custom_jump_set=1 ;;
-j2) jump_alias="j2"; custom_jump_set=1 ;;
*) filtered_args+=("$arg") ;;
esac
done
set -- "${filtered_args[@]+"${filtered_args[@]}"}"
if [[ -f "$ssh_config" ]] && ! has_explicit_config "$@"; then
ssh_config_args=(-F "$ssh_config")
fi
skip_next=0
capture_user=0
capture_port=0
after_double_dash=0
for arg in "$@"; do
if [[ $found_target -eq 1 ]]; then
cmd_args+=("$arg")
continue
fi
if [[ $capture_user -eq 1 ]]; then
user_option=$arg
capture_user=0
continue
fi
if [[ $capture_port -eq 1 ]]; then
port_option=$arg
capture_port=0
continue
fi
if [[ $skip_next -eq 1 ]]; then
skip_next=0
continue
fi
case "$arg" in
-G|-Q|-V|-h|--help)
run_real_ssh "$@"
;;
--)
after_double_dash=1
continue
;;
esac
if [[ $after_double_dash -eq 0 ]]; then
case "$arg" in
-s)
want_subsystem=1
continue
;;
-l)
capture_user=1
continue
;;
-l*)
user_option=${arg#-l}
continue
;;
-p)
capture_port=1
continue
;;
-p*)
port_option=${arg#-p}
continue
;;
-b|-c|-D|-E|-e|-F|-I|-i|-J|-L|-m|-O|-o|-Q|-R|-S|-W|-w)
skip_next=1
continue
;;
-b*|-c*|-D*|-E*|-e*|-F*|-I*|-i*|-J*|-L*|-m*|-O*|-o*|-Q*|-R*|-S*|-W*|-w*)
continue
;;
-*)
continue
;;
esac
fi
if ! resolve_target_from_config "$arg"; then
run_real_ssh "$@"
fi
found_target=1
done
if [[ $found_target -eq 0 ]]; then
run_real_ssh "$@"
fi
tty_flag="-tt"
if [[ ${#cmd_args[@]} -gt 0 || $want_subsystem -eq 1 ]]; then
tty_flag="-T"
fi
if [[ $target_is_jump -eq 1 ]]; then
jump_cmd=(ssh "$tty_flag" -A -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -p "$target_port" "$target_user@$target_host")
jump_cmd+=(${cmd_args[@]+"${cmd_args[@]}"})
else
resolve_jump
final_cmd=(ssh "$tty_flag" -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -o ProxyJump=none -o ProxyCommand=none)
if [[ "$target_auth" == "password_interactive" ]]; then
final_cmd+=( -o BatchMode=no -o PreferredAuthentications=keyboard-interactive,password -o PubkeyAuthentication=no )
elif [[ $host_configured -eq 1 ]]; then
final_cmd+=( -o BatchMode=yes )
fi
if [[ $want_subsystem -eq 1 ]]; then
final_cmd+=( -s )
fi
final_cmd+=( -p "$target_port" "$target_user@$target_host" )
final_cmd+=(${cmd_args[@]+"${cmd_args[@]}"})
jump_cmd=(ssh "$tty_flag" -A -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -p "$jump_port" "$jump_user@$jump_host" "$(quote_cmd "${final_cmd[@]}")")
fi
is_jumper_cmd="SSH_AUTH_SOCK=$remote_agent exec $(quote_cmd "${jump_cmd[@]}")"
exec "$real_ssh" ${ssh_config_args[@]+"${ssh_config_args[@]}"} "$tty_flag" -o BatchMode=yes -o ConnectTimeout=10 is-jumper "$is_jumper_cmd"