Skip to content

Instantly share code, notes, and snippets.

@theasp
Last active August 31, 2017 19:57
Show Gist options
  • Save theasp/c02827400c223c42edd95724a90d4925 to your computer and use it in GitHub Desktop.
Save theasp/c02827400c223c42edd95724a90d4925 to your computer and use it in GitHub Desktop.
Basic preprocessor for your ~/.ssh/config. Useful if you use various versions of ssh regularly, or you want to create a bunch of host entries dynamically.
#!/bin/bash
set -e
export SSH=${SSH:-/usr/bin/ssh}
SSH_FULL_NAME="$(${SSH} -V 2>&1)"
SSH_SHORT_NAME="${SSH_FULL_NAME%% *}"
export SSH_PROVIDER=${SSH_SHORT_NAME%%_*}
export SSH_VERSION=${SSH_SHORT_NAME##*_}
function ssh_config {
cat <<EOF
##########################################################################
# My hosts
host some some.example.com
HostName some.example.com
User theasp
Host github.com
KexAlgorithms diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1
##########################################################################
# Default
Host *
$(ver-ge 5.9)ControlMaster auto
$(ver-ge 5.9)ControlPersist 15m
$(ver-between 5.9 7.1)ControlPath ~/.ssh/cm-%r@%h:%p
$(ver-ge 7.2)ControlPath ~/.ssh/cm-%C
$(ver-ge 7.2)AddKeysToAgent yes
EOF
}
function compare_ver {
local -a version
local op=$1
local test_ver=${2//[\.p]/ }
read -ra version <<< ${SSH_VERSION//[\.p]/ }
local pos=0
for test_num in $test_ver; do
cur_num=${version[$pos]}
cur_num=${cur_num:-0}
pos=$(( pos + 1 ))
# BUG: gt and lt act like ge and le
case $op in
eq)
[[ $cur_num -lt $test_num ]] && return 1
[[ $cur_num -eq $test_num ]] && continue
[[ $cur_num -gt $test_num ]] && return 1
;;
ne)
[[ $cur_num -lt $test_num ]] && return 0
[[ $cur_num -eq $test_num ]] && continue
[[ $cur_num -ge $test_num ]] && return 0
;;
lt)
[[ $cur_num -lt $test_num ]] && return 0
[[ $cur_num -eq $test_num ]] && continue
[[ $cur_num -ge $test_num ]] && return 1
;;
le)
[[ $cur_num -lt $test_num ]] && return 0
[[ $cur_num -eq $test_num ]] && continue
[[ $cur_num -gt $test_num ]] && return 1
;;
gt)
[[ $cur_num -gt $test_num ]] && return 0
[[ $cur_num -eq $test_num ]] && continue
[[ $cur_num -le $test_num ]] && return 1
;;
ge)
[[ $cur_num -gt $test_num ]] && return 0
[[ $cur_num -eq $test_num ]] && continue
[[ $cur_num -lt $test_num ]] && return 1
;;
*)
log error "Unknown compare opration: $op"
esac
return 1
done
}
function ver-gt {
compare_ver gt $1 || echo "# Requires $SSH_VERSION > $1 # "
}
function ver-ge {
compare_ver ge $1 || echo "# Requires $SSH_VERSION >= $1 # "
}
function ver-between {
(compare_ver ge $1 && compare_ver le $2) || echo "# Requires $1 >= $SSH_VERSION >= $2 # "
}
ssh_config
#!/bin/bash
set -e
export SSH=${SSH:-/usr/bin/ssh}
export SSH_CONFIG="$HOME/.cache/ssh_config.$(hostname -f)"
export SSH_GEN="${SSH_GEN:-$HOME/.ssh/config.sh}"
if [[ -x $SSH_GEN ]]; then
if [[ ! -e $SSH_CONFIG ]] || [[ $SSH_GEN -nt $SSH_CONFIG ]]; then
$SSH_GEN > $SSH_CONFIG
fi
exec ${SSH} -F $SSH_CONFIG "$@"
else
exec $SSH "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment