From 762b1c370943f8e60840ca23a9d384d8ff55d7fd Mon Sep 17 00:00:00 2001 From: "kebler.net" Date: Mon, 2 May 2022 10:40:07 -0700 Subject: [PATCH] fix: disable host reachable check in sshfs feat: add ssh_config_get function to allow getting configuration settings feat: added list keys to sshpubkey feat: allow key removable from comment string (don't need access to public key) fix: ssh - key option does not append .pub fix: remove ssh session file and add readme to recommend putting that in host repo --- env/ssh-agent-socket.env | 2 - modules/ssh-config.func | 69 +++++++++++++++++++++++-- modules/ssh-pubkey.mod | 106 +++++++++++++++++++++++++++------------ modules/ssh.func | 3 +- modules/sshfs.mod | 4 +- ssh/session/interactive | 6 ++- ssh/session/readme.md | 1 + 7 files changed, 148 insertions(+), 43 deletions(-) delete mode 100644 env/ssh-agent-socket.env diff --git a/env/ssh-agent-socket.env b/env/ssh-agent-socket.env deleted file mode 100644 index f81d33d..0000000 --- a/env/ssh-agent-socket.env +++ /dev/null @@ -1,2 +0,0 @@ -# set ssh agent socket for each session if it exists -export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" diff --git a/modules/ssh-config.func b/modules/ssh-config.func index b10b502..33ce2e8 100644 --- a/modules/ssh-config.func +++ b/modules/ssh-config.func @@ -37,7 +37,7 @@ function ssh_config() { cnt=${#DIRS[@]} for ((i = 0; i < cnt; i++)); do # echo $i of $cnt - # looks in ssh/config subdirectory of each DIRS is not passed + # looks in ssh/config subdirectory of each DIRS if not passed DIR="${DIRS[i]}$([[ ! $PDIRS ]] && echo /ssh/config)" # echo ----- trying $DIR [ -d $DIR ] && CDIRS[j]=$DIR @@ -53,8 +53,8 @@ function ssh_config() { # It is used by the ssh function which then calls ssh binary # ##############################################################" -module_load debug -module_load file + module_load debug + module_load file debug ssh config file at: $SSH_CONFIG mkdir -p "$(dirname "$SSH_CONFIG")" @@ -72,5 +72,66 @@ module_load file done done # append any tradtional home config - build_file "$HOME/.ssh/config" $SSH_CONFIG + [[ -f "$HOME/.ssh/config" ]] && build_file "$HOME/.ssh/config" $SSH_CONFIG } + + +ssh_config_get () { + + local ssh; + local cfg; + local prop; + local all; + + if [[ $SSH_CONFIG ]]; then + [[ ! -f "$SSH_CONFIG" ]] && ssh_config "$SSH_CONFIG" + cfg="-F $SSH_CONFIG" + fi + + ssh="$(which ssh) $cfg -G" + # echo ssh cmd: "$ssh" + + local OPTION; local OPTARG; local OPTIND + while getopts 'uhpai' OPTION; do + # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} + case "$OPTION" in + u) + prop=user + ;; + h) + prop=hostname + ;; + i) + prop=identityfile + ;; + p) + prop=port + ;; + a) + all=true + ;; + *) echo unknown run option -$OPTARG + return 3 + ;; + esac + done + + shift $((OPTIND - 1)) + + [[ ! $1 ]] && { echo must pass a config host; return 1; } + + [[ ! $(cat "$SSH_CONFIG" | grep "[Hh]ost $1") ]] && return 2 + + props=$($ssh $1) + [[ $all ]] && { echo "$props"; return 0; } + [[ $prop ]] && { echo "$props" | grep -m1 -oP "(?<=$prop ).*"; return 0; } + [[ $2 ]] && { echo "$props" | grep $2; return 0; } + + echo host $1 + echo user $(echo "$props" | grep -m1 -oP "(?<=user ).*") + echo hostname $(echo "$props" | grep -m1 -oP "(?<=hostname ).*") + echo port $(echo "$props" | grep -m1 -oP "(?<=port ).*") + echo identityfile $(echo "$props" | grep -m1 -oP "(?<=identityfile ).*") + +} + diff --git a/modules/ssh-pubkey.mod b/modules/ssh-pubkey.mod index 291e68b..2ec4b1e 100644 --- a/modules/ssh-pubkey.mod +++ b/modules/ssh-pubkey.mod @@ -12,18 +12,18 @@ module_load ssh sshpubkey () { - echo pub key dir: $SSH_PUB_KEYS + # echo default pub key dir: $SSH_PUB_KEYS local key=$SSH_PUB_KEYS/id_rsa.pub - local user=${DEFAULT_USER:-ubuntu} + local user local opts;local dr="true";local rm; local ropts;local kname local vkey; local kuser; local host; local supass; local replace - local scmd; local _sudo + local scmd; local _sudo; local list local OPTION local OPTARG local OPTIND - while getopts 'u:a:rek:o:s:' OPTION; do + while getopts 'u:a:r:ek:o:s:l' OPTION; do # echo OPTION $OPTION ARG $OPTARG case "$OPTION" in a) @@ -37,14 +37,24 @@ sshpubkey () { s) supass=$OPTARG ;; + l) + list=true + ;; r) - # remove key - rm=true + # remove key, must be "comment identifier in public key" + rm=$OPTARG ;; k) kname=$OPTARG - [[ $(isAbsPath $OPTARG) ]] && key=$OPTARG || key=${SSH_PUB_KEYS:-$HOME/.ssh}/$OPTARG.pub - ;; + if [[ $(isAbsPath $OPTARG) ]]; then + key=$OPTARG + else + key=${OPTARG}.pub + if [[ ! -f $key ]]; then key=${SSH_PUB_KEYS:-$HOME/.ssh}/$OPTARG.pub; fi + fi + if [[ ! -f $key ]]; then echo "no file $key"; return 4; fi + echo key $key found, continuing + ;; o) opts=$OPTARG ;; @@ -94,20 +104,16 @@ sshpubkey () { scmd="$sshpass $(which ssh) $opts $host" - [[ $host =~ "@" ]] && user=$(sed 's/\(.*\)@.*/\1/' <<< "$host") - echo remote user: $user - - vkey=$(cat $key) # get actaul content of key file - ## Alternate remote user? - if [[ $kuser ]]; then - [[ ! $supass ]] && { echo remote user, $user, password must be supplied for sudo. use -s;return 7; } + if [[ ! $user ]]; then + if [[ $host =~ "@" ]]; then + user=$(sed 's/\(.*\)@.*/\1/' <<< "$host") + else + user=$(ssh_config_get -u $host) + [[ ! $user ]] && user=${DEFAULT_USER:-ubuntu} + fi fi - if [[ $kuser ]]; then - _sudo="echo '${supass}' | sudo -u ${kuser} --stdin" - fi - - rfcmd () ( + rfcmd () ( local fn fn=$1 shift 1 @@ -120,17 +126,40 @@ sshpubkey () { $scmd "$_sudo" "$(rfcmd "$*")" ) + # echo remote user: $user + + if [[ $kuser ]]; then + _sudo="echo '${supass}' | sudo -u ${kuser} --stdin" + fi + + if [[ $list ]]; then + run list_keys + return $? + fi + if [[ $rm ]]; then ############# REMOVE PUBLIC KEY ################# - echo ">>>>> removing public key $kname from ${kuser:-user}" - [[ $dr ]] && echo dry run by default add -e to execute || replace=" -i" - run rm_key $replace $vkey - else + # todo allow removeall without access to public key + echo ">>>>> removing public key: \"$rm\" from ${kuser:-$user}" + [[ ! $dr ]] && replace=" -i" + run rm_key $replace $rm + return $? + fi + + vkey=$(cat $key) # get actaul content of key file + ## Alternate remote user? + if [[ $kuser ]]; then + [[ ! $supass ]] && { echo remote user, $user, password must be supplied for sudo. use -s;return 7; } + fi + + if [[ $key ]] ; then ############## ADD PUBLIC KEY ######################## echo ">>>>>> sending key $key to remote user ${kuser:-$user}" echo run command run cpy_key $vkey + return $? fi + } @@ -166,27 +195,40 @@ function cpy_key () { } function rm_key () { - local vkey; local replace - echo in rm_key + local kname; local replace; local found [[ $1 = "-i" ]] && { replace=$1; shift 1; } - vkey=$* - + kname=$* + echo "" if [[ ! -f $HOME/.ssh/authorized_keys ]]; then echo no $HOME/authorized_keys file nothing to remove - else - if [[ $(cat $HOME/.ssh/authorized_keys | grep "$vkey") ]]; then + else + # found=$(sed "\,$kname$,p" $HOME/.ssh/authorized_keys) + found=$(cat $HOME/.ssh/authorized_keys | grep "${kname}$") + if [[ $found ]]; then echo key found in authorized_keys, removing... - sed $replace "\,$vkey,d" $HOME/.ssh/authorized_keys + echo "$found" if [[ $replace ]]; then echo "********updated authorized_keys file for $USER *******************" + sed $replace "\,$kname$,d" $HOME/.ssh/authorized_keys cat $HOME/.ssh/authorized_keys echo "******************************************************" + else + echo "--- this is a dry run by default ---" + echo "--- if you are SURE this is the key you want removed" + echo "--- run again with -e to actaully remove this key ---" + echo "!!! REMOVING THE WRONG KEY MAY RESULT IN LOOSING ACCESS TO THE MACHINE !!!" fi else - echo no key $key found in the authorized_keys, nothing to remove + echo no key $kname found in the authorized_keys, nothing to remove fi fi } +function list_keys () { + echo "********authorized_keys file for user: $USER at host: $HOSTNAME *******************" + cat $HOME/.ssh/authorized_keys + echo "******************************************************" +} + diff --git a/modules/ssh.func b/modules/ssh.func index 0ef3413..1026ff2 100644 --- a/modules/ssh.func +++ b/modules/ssh.func @@ -18,6 +18,7 @@ # > host=${ret[0]}; opts=${ret[1]};sshpass=${ret[2]} module_load net-utils +module_load ssh-config ssh() { @@ -48,7 +49,7 @@ ssh() { user=$OPTARG ;; k) - [[ $(isAbsPath $OPTARG) ]] && key=$OPTARG || key=${SSH_PUB_KEYS:-$HOME/.ssh}/$OPTARG.pub + [[ $(isAbsPath $OPTARG) ]] && key=$OPTARG || key=${SSH_PUB_KEYS:-$HOME/.ssh}/$OPTARG opts+=" -o IdentitiesOnly=yes -o IdentityFile=$key" ;; o) diff --git a/modules/sshfs.mod b/modules/sshfs.mod index d148ea0..b22589f 100755 --- a/modules/sshfs.mod +++ b/modules/sshfs.mod @@ -71,8 +71,8 @@ function smount() { # return opts+=" -o ssh_command=$(remove_end_spaces "'$sshpass /usr/bin/ssh $sshopts'")" - [[ ! $(host_reachable $host $(parse_option $sshopts -p)) ]] \ - && echo host $host not reachable, aborting mount && return 1 + # [[ ! $(host_reachable $host $(parse_option $sshopts -p)) ]] \ + # && echo host $host not reachable, aborting mount && return 1 if [[ $(mounted $MNT) ]]; then echo "some remote already mounted at $MNT. Umount with: $ umount $MNT" diff --git a/ssh/session/interactive b/ssh/session/interactive index fc790db..96b7d15 100644 --- a/ssh/session/interactive +++ b/ssh/session/interactive @@ -1,3 +1,5 @@ if [[ $- == *i* ]]; then -echo ssh interactive session -fi +# anything here will be executed, changing to a directory +# note anything to stdout here may make rsync and other network commands fail +#cd /opt +fi \ No newline at end of file diff --git a/ssh/session/readme.md b/ssh/session/readme.md index 223d2e1..c1b9cea 100644 --- a/ssh/session/readme.md +++ b/ssh/session/readme.md @@ -1 +1,2 @@ *anything in /session will be sourced if this is a remote ssh login session* +you may edit this in place but it's recommended to create an ssh folder in the host name repo instead