diff --git a/modules/net-utils.mod b/modules/net-utils.mod index 0291eef..29d9870 100644 --- a/modules/net-utils.mod +++ b/modules/net-utils.mod @@ -5,23 +5,68 @@ # or # host_reachable &> /dev/null && echo sure || echo nope # or + host_reachable () { -if [[ $(command -v nmap) ]] && [[ $2 ]]; then - [[ $(nmap $1 -PN -p $2 | grep open) ]] && echo yes && return 0 || return 1 -fi -if [[ $(command -v nc) ]] && [[ $2 ]]; then -[[ $(nc -w 2 $1 $2) ]] && echo yes && return 0 || return 1 -fi -if [[ $(command -v ping) ]]; then -ping -c1 -W1 $1 &> /dev/null && echo yes && return 0 || return 1 -fi -return 2 # return 2 to indicate no method was available +# usage: host_reachable < -F configfile > host < port > +# reachable returns yes and return 0 +# return 1 - not reachable +# return 2 no method available to try + +local host; local config + +function try( ) ( + if [[ $(command -v nmap) ]] && [[ $2 ]]; then + [[ $(nmap $1 -PN -p $2 | grep open) ]] && echo yes && return 0 || return 1 + fi + if [[ $(command -v nc) ]] && [[ $2 ]]; then + [[ $(nc -w 2 $1 $2) ]] && echo yes && return 0 || return 1 + fi + if [[ $(command -v ping) ]]; then + ping -c1 -W1 $1 &> /dev/null && echo yes && return 0 || return 1 + fi + return 2 # return 2 to indicate no method was available +) + +[[ $1 = "-F " ]] && { config=$2;shift 2; } +host=$(lookup_host $1 $config) +try $host $2 +return $? } +lookup_host () { +# usage: lookup_host hostname < configfile > +local config; local host; local lhost +config=$([[ $2 ]] && echo $2 || echo ${SSH_CONFIG:-$HOME/.ssh/config}) +host=$(parse_host $1) +lhost=$(ssh -F $config -G $host | grep -w hostname | cut -d' ' -f2) +[[ $lhost ]] && echo $lhost || echo $host +} + +parse_host () { + # usage: parse_host + # returns extracted host if passed user@host + # otherwise return value passed + [[ $1 =~ "@" ]] && { echo $(sed 's/.*@\(.*\)/\1/' <<< "$1");return 0; } + echo $1 + return 1 +} + +parse_user () { + # usage: parse_user + # returns extracted user if passed user@host + # otherwise returns nothing + # return 1 no user in string + [[ $1 =~ "@" ]] && { echo $(sed 's/\(.*\)@.*/\1/' <<< "$1"); return 0; } || return 1 + } + + valid_ip() { + # usage: valid_ip ip + # check so see if basic format is correct and all subs or numbers, no returns 2 + # then checks if they are 0 to 254, no returns 1 + # otherwise if good returns "true" and 0 local ip=$1 - local stat=1 local res if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then @@ -31,15 +76,20 @@ valid_ip() IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] - res=$([ $? == 0 ] && echo true || echo false) - else - res=false - fi - echo $res + res=$([ $? == 0 ] && echo true) + [[ $res ]] && { echo $res;return 0; } + return 1 + fi + return 2 } get_domain() { + # usage: get_domain fulldomain + # returns domain.tld + # exampe: get_domain discuss.mydomain.com => returns mydomain.com local domain domain=$(echo $1 | awk -F\. '{print $(NF-1) FS $NF}') echo "$domain" } + + diff --git a/modules/new-host/remote-host.mod b/modules/new-host/remote-host.mod new file mode 100644 index 0000000..81fdf04 --- /dev/null +++ b/modules/new-host/remote-host.mod @@ -0,0 +1,176 @@ +#!/bin/bash + +module_load confirm +module_load net-utils +module_load ssh +module_load ssh-pubkey +module_load minimize +module_load_path + +# echo sourcing functions + + +_v_ () { + # used internally to module for getting value from environment variable + var=${REMOTE_HOST_PREFIX:-"_"}_$1 +echo ${!var} +} + +remote_host_env () { + [[ $1 = "--set" || $1 = "-s" ]] && { local set; set=true; shift; } + local prefix=${REMOTE_HOST_PREFIX:-"_"} # double __ is default prefix + [[ $1 = "--prefix" || $1 = "-p" ]] && { local prefix; prefix=$2; export REMOTE_HOST_PREFIX=$prefix; shift 2; } + local envfile + envfile=${1:-$REMOTE_HOST_ENV_FILE} + # echo passed $1 + # echo set $set + # echo REMOTE_HOST_ENV_FILE $REMOTE_HOST_ENV_FILE + # echo envfile $envfile + [[ ! $envfile ]] && { echo "must pass remote host environment file or set REMOTE_HOST_ENV"; return 1; } + [[ ! -f $envfile ]] && { echo ERROR environment file, $1, does not exist; return 2; } + + if [[ $set || ! $REMOTE_HOST_ENV_FILE ]]; then + + # curr="$(env | grep ^${prefix}_)" + # curr= $(sed 's/=.*//' <<<"$curr") + curr=$(sed 's/=.*//' <<< "$(env | grep ^${prefix}_)") + if [[ $curr ]]; then + echo "****** removing current values ************" + echo "$curr" + echo "--------------------" + while IFS= read -r var; do + # echo adding prefix: $prefix + # echo removing environment variable: $var + unset "$var" + done <<< "$curr" + fi + + if [[ $1 ]]; then + echo exporting $1.env to REMOTE_HOST_ENV_FILE + export REMOTE_HOST_ENV_FILE=$(abs_path $1) + fi + + while IFS= read -r var; do + # echo adding prefix: $prefix + # echo environment variable: ${prefix}_$var + export ${prefix}_$var + done <<< "$(minimize "$envfile")" + echo "****** Now Using Remote Host Environment ************" + env | grep ^${prefix}_ + env | grep REMOTE + echo "************************************" + + fi + + [[ ! $(env | grep ^${prefix}_) ]] && { echo ERROR: no remote host environment has been set; return 4; } + + return 0 +} + +remote_host_sshoptions () { +local key; local pw; local user; + +[[ $1 = "-k" ]] && { shift; [[ $(_v_ KEY) ]] && key="-k $(_v_ KEY)"; } +[[ $1 = "-p" ]] && { shift; [[ $(_v_ USER_PW) ]] && pw="-p $(_v_ USER_PW)"; } +# echo key: $key +# echo pw: $pw +# echo envfile: $1 +if ! remote_host_env; then + return $? + fi +[[ (! $pw) && $(_v_ KEY) ]] && key="-k $(_v_ KEY)" +[[ (! $key) && $(_v_ USER_PW) ]] && pw="-p $(_v_ USER_PW)" + +echo $pw $(_v_ MP) $key "$@" +# ssh $pw $(_v_ MP) $key $user$(_v_ HOST_NAME) +} + +remote_host_user () { +local host=$(_v_ HOST_NAME) +[[ ! $host ]] && { echo ERROR: environment file MUST include a HOST_NAME value; return 1; } +if ! remote_host_env; then + return $? + fi +[[ $(_v_ USER) ]] && user=$(_v_ USER)@ +[[ $(_v_ USE_ROOT) ]] && user=root@ +echo $user$host + +} + +remote_host_login () { + local sopts; local cmd + if [[ ! $* =~ "--" ]]; then + sopts=$* + else + sopts=$(sed 's/\(.*\)--.*/\1/' <<< "$*") + cmd=$(sed 's/.*--\(.*\)/\1/' <<< "$*") + fi +local options=$(remote_host_sshoptions "$sopts") +[[ $? -gt 0 ]] && return $? +local userhost=$(remote_host_user) +[[ $? -gt 0 ]] && return $? +echo ssh $options $userhost +ssh $options $userhost $cmd +} + +remote_host_pubkey () { +# usage pubkey options -- ssh options, +local add=$(_v_ ADD_KEY) +local sudo=$(_v_ USER_PW) +[[ ! $add ]] && { echo no value given for ADD_KEY, aborting; return 2; } +local kopts; local sopts + if [[ ! $* =~ "--" ]]; then + kopts=$* + else + kopts=$(sed 's/\(.*\)--.*/\1/' <<< "$*") + sopts=$(sed 's/.*--\(.*\)/\1/' <<< "$*") + fi +echo adding public key: $add +kopts="$kopts -k $add" +module_load ssh-pubkey +echo sshpubkey $kopts $(remote_host_user) $(remote_host_sshoptions $sopts) +sshpubkey $kopts $(remote_host_user) $(remote_host_sshoptions $sopts) +echo sudo pw $sudo +sshpubkey -a root -s $sudo $kopts $(remote_host_user) $(remote_host_sshoptions $sopts) + +} + +# remote_host_shell () { + + +# } + +remote_host_mount () { + module_load sshfs + local base=$(_v_ BASE_MOUNT_POINT) + if [[ $1 = "-u" ]]; then + umount $base/home + umount $base/root + return 0 + fi + + local mopts; local sopts + if [[ ! $* =~ "--" ]]; then + mopts=$* + else + mopts=$(sed 's/\(.*\)--.*/\1/' <<< "$*") + sopts=$(sed 's/.*--\(.*\)/\1/' <<< "$*") + fi + + + mkdir -p $base > /dev/null + base=${base:-"/mnt/_temp_"} + local user=$(_v_ USER) + # echo smount $mopts $(remote_host_user):/home/${user:-ubuntu} $base/home $(remote_host_sshoptions $sopts) + smount $mopts $user@$(_v_ HOST_NAME):/home/${user:-ubuntu} $base/$user $(remote_host_sshoptions $sopts) + smount $mopts root@$(_v_ HOST_NAME):/ $base/fs $(remote_host_sshoptions $sopts) +} + +# below is run at module load +echo done loading module,functions available are +flist | grep remote_host + + +alias rhl="remote_host_login" +alias rhe="remote_host_env" +alias rhm="remote_host_mount" \ No newline at end of file diff --git a/modules/remote.func b/modules/remote.func new file mode 100644 index 0000000..c5a6844 --- /dev/null +++ b/modules/remote.func @@ -0,0 +1,96 @@ +#!/bin/bash +module_load ssh +remote_script () { + # usage: remote_script script -- host + # see ssh function + # +local sshargs;local user;local supass;local fn; + +local OPTION + local OPTARG + local OPTIND + while getopts 'u:s:f:' OPTION; do + # echo OPTION $OPTION ARG $OPTARG + case "$OPTION" in + f) + # run a function within the script + fn=$OPTARG + ;; + + u) + # run command as another user + user=$OPTARG + ;; + s) + # password of sudo account for running as root or other user + supass=$OPTARG + ;; + *) + echo unknown remote script option -$OPTARG + return 1 + ;; + esac + done + + shift $((OPTIND - 1)) + +local script=$1 +[[ ! -f $script ]] && { echo cannot find script $script to run; return 1; } + +[[ "$*" =~ "--" ]] && sshargs=$(sed 's/.*--\(.*\)/\1/' <<< "$@") +[[ ! $sshargs ]] && { echo must provide at least a hostname; return 3; } + +# escape arguments with spaces +local i=2 +local count=0 +declare -a args +while [[ ! ${!i} = "--" ]] +do + #echo "${!i}" + args[count]=$(printf '%q' "${!i}") + count=$((count+1)) + i=$((i+1)) +done + +# if script loads a module then use bundler +if [[ $(cat $script | grep module_load) ]]; then +echo bundling modules with script +local temp +module_load bundle +script=$( mktemp -t TEMP_FILE_script.XXXXXXXX ) +bundle $1 $script +temp=true +fi + +local _sudo +if [[ $user ]]; then +[[ ! $supass ]] && { echo password must be supplied for connecting sudo account. use -s;return 7; } +# echo running script remotely as user $user +_sudo="echo '${supass}' | sudo --stdin -u ${user} 2>/dev/null" +else +if [[ $supass ]]; then + _sudo="echo '${supass}' | sudo --stdin 2>/dev/null" + # echo running script remotely as root + fi +fi + +src=$(cat $script) +if [[ $fn ]]; then + # echo running function + cmd="bash -c '$src; $fn ${args[*]}'" + else + # echo running as script + local sargs + [[ ${args[*]} ]] && sargs=$(printf '%s\n' "set -- ${args[*]}") + cmd="bash -c '$sargs; $(cat $script)'" +fi + +ssh $sshargs "$_sudo" "$cmd" + +[[ $temp ]]&& rm -f $script + +} + +# # if script was executed then call the function +(return 0 2>/dev/null) ||remote_script $@ + diff --git a/modules/ssh.sh b/modules/ssh-config.func similarity index 63% rename from modules/ssh.sh rename to modules/ssh-config.func index c46a1af..b10b502 100644 --- a/modules/ssh.sh +++ b/modules/ssh-config.func @@ -53,6 +53,9 @@ function ssh_config() { # It is used by the ssh function which then calls ssh binary # ##############################################################" +module_load debug +module_load file + debug ssh config file at: $SSH_CONFIG mkdir -p "$(dirname "$SSH_CONFIG")" echo -e "$HEADER" >$SSH_CONFIG @@ -71,68 +74,3 @@ function ssh_config() { # append any tradtional home config build_file "$HOME/.ssh/config" $SSH_CONFIG } - -ssh() { - if [[ $SSH_CONFIG ]]; then - [[ ! -f "$SSH_CONFIG" ]] && ssh_config "$SSH_CONFIG" - command ssh -F $SSH_CONFIG "$@" - else - command ssh "$@" - fi -} - -sshp() { - local opts="-o PreferredAuthentications=password -o PubkeyAuthentication=no" - if [[ $SSH_CONFIG ]]; then - [[ ! -f "$SSH_CONFIG" ]] && ssh_config "$SSH_CONFIG" - command ssh $opts -F $SSH_CONFIG "$@" - else - command ssh $opts "$@" - fi -} - - ssh_test() { - echo running non-interactive ssh test on $2 with user $1 - ssh $1@$2 "cat .bashrc" - # env | grep -E 'SHELL|BASH|SSH';type module_load;module_load helpers;adirname . - } - -function rrem() { - ssh -X -t "$@" -} - -ssh_script () { - - local SUDO="" - - declare OPTION - declare OPTARG - declare OPTIND - while getopts 'ps:' OPTION; do - # echo $OPTION $OPTARG - case "$OPTION" in - p) - PASS=true - # echo option password login only: $PASS - ;; - s) - SUDO="sudo" - # echo option s: $SUDO - ;; - *) - echo unknown option $OPTION - ;; - esac - done - - shift $((OPTIND - 1)) - - HOST=$1@$2 - SCRIPT=$3 - - # ssh < 'bash -s' << local_script.sh - - scp $PATHtoSCRIPT$SCRIPTname $HOSTtoCONTROL:/tmp/ - ssh -t $HOSTtoCONTROL "sudo -s bash /tmp/$SCRIPTname" - ssh root@MachineB 'bash -s' < local_script.sh -} diff --git a/modules/ssh-copy.func b/modules/ssh-copy.func new file mode 100644 index 0000000..cc3f646 --- /dev/null +++ b/modules/ssh-copy.func @@ -0,0 +1,71 @@ +#!/bin/bash + + # usage: + # sshcp src dest -- + + sshcp () { + + local SRC=$1 + local DEST=$2 + local SHOST; local DHOST + local OPTS; local SOPTS + # echo remaining options: $* + shift 2 + echo $SRC to $DEST + if [[ $SRC =~ ":" ]]; then + # echo source is remote + SHOST=$(sed 's/\(.*\):.*/\1/' <<< "$SRC") + SDIR=$(sed 's/.*:\(.*\)/\1/' <<< "$SRC") + else + # echo source is local + SDIR=$SRC + fi + # echo SHOST $SHOST SDIR $SDIR + if [[ $DEST =~ ":" ]]; then + # echo destination is remote + DHOST=$(sed 's/\(.*\):.*/\1/' <<< "$DEST") + DDIR=$(sed 's/.*:\(.*\)/\1/' <<< "$DEST") + else + # echo destination is local + DDIR=$DEST + fi + # echo DHOST $DHOST DDIR $DDIR + + [[ $DHOST && $SHOST && (! $DHOST = "$SHOST") ]] && { echo full remote copy must be same hosts; return 2; } + + # echo parse: $* + if [[ ! $* =~ "--" ]]; then + SOPTS=$* + else + SOPTS=$(sed 's/\(.*\)--.*/\1/' <<< "$*") + OPTS=$(sed 's/.*--\(.*\)/\1/' <<< "$*") + fi + + # echo SOPTS $SOPTS + # echo OPTS $OPTS + + module_load array + declare -a ret + # echo ssh -r "$SOPTS" "${DHOST:-$SHOST}" + # return + module_load ssh + cmd=$(ssh -r ${SOPTS} ${DHOST:-$SHOST}) + # echo $cmd + String::split ret "$(ssh -r ${SOPTS} ${DHOST:-$SHOST})" , + local host=${ret[0]}; local opts=${ret[1]}; local sshpass=${ret[2]} + + [[ -d $SDIR && ! $SHOST ]] && OPTS+=" -r" + if [[ $SHOST ]]; then + [[ $(ssh $SOPTS $SHOST test -d $SDIR ) ]] && OPTS+=" -r" + fi + + local cmd="$sshpass scp $opts $OPTS $([[ $SHOST ]] && echo "${host}:")$SDIR $([[ $DHOST ]] && echo "${host}:")$DDIR" + echo $cmd + $cmd + return 0 + + } + + + + \ No newline at end of file diff --git a/modules/ssh-copy.sh b/modules/ssh-copy.sh deleted file mode 100644 index 129ae25..0000000 --- a/modules/ssh-copy.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - - SSH_PUB_KEYS=${SSH_PUB_KEYS:-$HOME/.ssh} - export SSH_PUB_KEYS - - sshcp () { - echo args: $@ -# todo add a use password only flag -# local opts="-o PreferredAuthentications=password -o PubkeyAuthentication=no" - local dir="" - echo options $opts - [[ $1 = "-u" ]] && user=$2 && shift 2 || user=ubuntu - local host=$1 - [[ ! $(host_reachable $host) ]] && echo host $host not reachable, aborting mount && return 1 - local src=${2:-$(pwd)} - echo source: $src - [[ -d $src ]] && dir="-r" - echo scp $opts $dir "$src" $user@$host:$3 - scp $opts $dir "$src" $user@$host:$3 - } - - sshcpid () { - local opts="-o PreferredAuthentications=password -o PubkeyAuthentication=no" - local PUB_KEY=${SSH_PUB_KEYS:-$HOME/.ssh}/$3.pub - [[ $1 = "-u" ]] && user=$2 && shift 2 || user=ubuntu - dr="-n" - [[ $4 = "yes" ]] && dr="" || echo add "yes" as last argment to invoke - ssh-copy-id $opts $dr -f -i $PUB_KEY $1@$2 - } - - - sshd_disable_pw () { - module_load config_edit - local cnf=$(declare -f confirm) - local cc=$(declare -f config_change) - declare -A settings - local settings=( ["PasswordAuthentication"]=no ["PubkeyAuthentication"]=yes ["ChallengeResponseAuthentication"]=no) - #file=/etc/ssh/sshd_config - file=test.config - for setting in ${!settings[@]}; do - sudo bash -c "$cnf;$cc;config_change $setting ${settings[${setting}]} $file" - done - } \ No newline at end of file diff --git a/modules/ssh-pubkey.mod b/modules/ssh-pubkey.mod new file mode 100644 index 0000000..291e68b --- /dev/null +++ b/modules/ssh-pubkey.mod @@ -0,0 +1,192 @@ +#!/bin/bash + +#example: +# initial xfer of pubkey with a password +# sshpubkey host -- + + +SSH_PUB_KEYS=${SSH_PUB_KEYS:-$HOME/.ssh} +export SSH_PUB_KEYS +module_load path +module_load ssh + +sshpubkey () { + + echo pub key dir: $SSH_PUB_KEYS + + local key=$SSH_PUB_KEYS/id_rsa.pub + local user=${DEFAULT_USER:-ubuntu} + 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 OPTION + local OPTARG + local OPTIND + while getopts 'u:a:rek:o:s:' OPTION; do + # echo OPTION $OPTION ARG $OPTARG + case "$OPTION" in + a) + # to put the key at another user on remote. will require sudo on remote + kuser=$OPTARG + ;; + u) + # user if not explicit from host + user=$OPTARG + ;; + s) + supass=$OPTARG + ;; + r) + # remove key + rm=true + ;; + k) + kname=$OPTARG + [[ $(isAbsPath $OPTARG) ]] && key=$OPTARG || key=${SSH_PUB_KEYS:-$HOME/.ssh}/$OPTARG.pub + ;; + o) + opts=$OPTARG + ;; + e) + dr="" + ;; + *) + echo unknown option -$OPTARG + # opts="$opts ${@:$OPTIND:1}" + # # ((OPTIND+=1)) + # #echo remaining ${@:$OPTIND} + return 1 + ;; + esac + done + + shift $((OPTIND - 1)) + + host=$1 + if [[ ! $host ]]; then + echo "no host supplied, aborting" + echo "usage: sshpubkey host -- " + return 2 + fi + + shift 1 + if [[ ! $* =~ "--" ]]; then + ropts=$* + else + ropts=$(sed 's/\(.*\)--.*/\1/' <<< "$*") + opts=$(sed 's/.*--\(.*\)/\1/' <<< "$*") + fi + + # echo KEY $key + # echo HOST $host + # echo ROPTS $ropts + # echo OPTS $opts + + # TODO add run remote function to ssh and this won't be required + module_load array + declare -a ret + scmd="ssh -r ${ropts} ${host}" + # echo "$cmd" + String::split ret "$($scmd)" , + host=${ret[0]}; opts+=${ret[1]}; local sshpass=${ret[2]} + # echo "$host;$opts;$sshpass" + 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; } + fi + + if [[ $kuser ]]; then + _sudo="echo '${supass}' | sudo -u ${kuser} --stdin" + fi + + rfcmd () ( + local fn + fn=$1 + shift 1 + echo "bash -c '$(declare -f $fn); $fn $*'" + ) + + run () ( + # echo "$scmd" "$_sudo" + # echo "$(rfcmd "$*")" + $scmd "$_sudo" "$(rfcmd "$*")" + ) + + 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 + ############## ADD PUBLIC KEY ######################## + echo ">>>>>> sending key $key to remote user ${kuser:-$user}" + echo run command + run cpy_key $vkey + fi +} + + +function cpy_key () { + + vkey=$* + if [[ $(cat $HOME/.ssh/authorized_keys | grep "$vkey") ]]; then + echo key $key already in authorized_keys for remote user $USER + else + echo -e "\nInstalling key for $USER" + echo -e "\n############ appending key to -s$HOME/.ssh/authorized_keys ############" + cat $HOME/.ssh/authorized_keys + echo "###########################" + # echo "#################### adding ####################" + # echo $vkey + # echo "#################################################" + + if [[ ! -f $HOME/.ssh/authorized_keys ]]; then + mkdir $HOME/.ssh >/dev/null 2>&1 + touch $HOME/.ssh/authorized_keys >/dev/null 2>&1 + chmod 600 $HOME/.ssh/authorized_keys >/dev/null 2>&1 + ls -la $HOME/.ssh/authorized_keys + fi + + echo "$vkey" >> $HOME/.ssh/authorized_keys + ls -la $HOME/.ssh/authorized_keys + echo "******** updated authorized_keys for $USER *******************" + cat $HOME/.ssh/authorized_keys + echo "******************************************************" + + fi + +} + +function rm_key () { + local vkey; local replace + echo in rm_key + [[ $1 = "-i" ]] && { replace=$1; shift 1; } + vkey=$* + + 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 + echo key found in authorized_keys, removing... + sed $replace "\,$vkey,d" $HOME/.ssh/authorized_keys + if [[ $replace ]]; then + echo "********updated authorized_keys file for $USER *******************" + cat $HOME/.ssh/authorized_keys + echo "******************************************************" + fi + else + echo no key $key found in the authorized_keys, nothing to remove + fi + fi + +} + + diff --git a/modules/ssh-utils.mod b/modules/ssh-utils.mod new file mode 100644 index 0000000..07809b5 --- /dev/null +++ b/modules/ssh-utils.mod @@ -0,0 +1,27 @@ +#!/bin/bash + +# TODO. instead write files in sshd_config.d +# sshd_disable_pw () { +# module_load config_edit +# local cnf=$(declare -f confirm) +# local cc=$(declare -f config_change) +# declare -A settings +# local settings=( ["PasswordAuthentication"]=no ["PubkeyAuthentication"]=yes ["ChallengeResponseAuthentication"]=no) +# #file=/etc/ssh/sshd_config +# file=test.config +# for setting in ${!settings[@]}; do +# sudo bash -c "$cnf;$cc;config_change $setting ${settings[${setting}]} $file" +# done +# } + + +ssh_dir_permissions() { + sudo chmod -R g-w $HOME + echo warning turned off group write for $HOME as this can cause ssh failure + sudo chown -R $USER:$USER $HOME/.ssh + sudo chmod 00700 $HOME/.ssh + sudo chmod 600 $HOME/.ssh/authorized_keys + sudo chmod 400 $HOME/.ssh/id_rsa + sudo chmod 644 $HOME/.ssh/id_rsa.pub + sudo chmod 600 $HOME/.ssh/known_hosts +} \ No newline at end of file diff --git a/modules/ssh.func b/modules/ssh.func new file mode 100644 index 0000000..0ef3413 --- /dev/null +++ b/modules/ssh.func @@ -0,0 +1,138 @@ +#!/bin/bash + +# this will superceed the ssh binary in order to source all the config files +# "USAGE: ssh host " +# put any additional SSH (man ssh) options after the host, aborting"# + +# if using ssh in another command use -r flag +# this returns a string that can be parsed into an array +# the array has three elements +# 0 - host (mayb include user) +# 1 - all ssh options +# 2 - an sshpass command if -p flag was used +# to user the arary do this. +# +# > module_load array +# > declare -a ret +# > String::split ret "$(ssh -p f filename -m -r test -p 32)" +# > host=${ret[0]}; opts=${ret[1]};sshpass=${ret[2]} + +module_load net-utils + +ssh() { + + local pw;local cfg;local opts;local mp; local sshpass; local dr + local host; local user; local script; local ret ; local key + + if [[ $SSH_CONFIG ]]; then + [[ ! -f "$SSH_CONFIG" ]] && ssh_config "$SSH_CONFIG" + cfg="-F $SSH_CONFIG" + fi + + # echo passed: $* + + local OPTION; local OPTARG; local OPTIND + while getopts ':h:u:mdF:p:ro:k:' OPTION; do + # echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND} + case "$OPTION" in + h) + host=$OPTARG + ;; + d) + dr=true + ;; + r) + ret=true + ;; + u) + user=$OPTARG + ;; + k) + [[ $(isAbsPath $OPTARG) ]] && key=$OPTARG || key=${SSH_PUB_KEYS:-$HOME/.ssh}/$OPTARG.pub + opts+=" -o IdentitiesOnly=yes -o IdentityFile=$key" + ;; + o) + opts+=" -o $OPTARG" + ;; + p) + # pw=$OPTARG + #e, f, d + case "$OPTARG" in + e) + sshpass="sshpass -e " + ;; + f) ;& + d) + # echo ${@[$OPTIND]} + sshpass="sshpass -$OPTARG ${@:$OPTIND:1}" + ((OPTIND+=1)) + ;; + *) + [[ ! ( $OPTARG = "yes" || $OPTARG = "y" ) ]] && sshpass="sshpass -p $OPTARG" + ;; + esac + pw=true + opts+=" -o PreferredAuthentications=password -o PubkeyAuthentication=no -o StrictHostKeyChecking=no" + ;; + F) + echo "using SSH Config file at: $OPTARG" + [[ -f $OPTARG ]] && cfg="-F $OPTARG" || echo no config file at $OPTARG, ignored + ;; + m) + # echo setting multipass + mp=true + ;; + *) echo unknown run option -$OPTARG + echo "USAGE: ssh host " + echo "put any additional SSH (man ssh) options after the host, aborting" + return 3 + # opts="$opts ${@:$OPTIND:1}" + # ((OPTIND+=1)) + #echo remaining ${@:$OPTIND} + ;; + esac + done + + shift $((OPTIND - 1)) + + [[ (! $host) && $1 ]] && { host=$1;shift; } + + # echo extra ssh options and the command: $@ + # echo host $host + # return + + [[ ! $host ]] && echo host/ip required, aborting && return 2 + [[ ! $user ]] && user=$(parse_user $host) + + if [[ $mp ]]; then + user=${user:-ubuntu} + [[ ! $host ]] && echo multipass host/ip required, aborting && return 2 + # echo multipass host:$host user:$user + module_load multipass + ip="$(multipass_get_ip $(parse_host $host))" + [[ ! $ip ]] && echo could not resolve ip for multipass instance $1 && return 5 + [[ ! $pw && ! $key ]] && opts+=" $(multipass_ssh_options)" + host="$user@$ip" + else # not an mp vm + [[ $user && (! $host =~ "@") ]] && host=$user@$host + if [[ $user && $host =~ "@" ]]; then + host=$(sed 's/.*@\(.*\)/\1/' <<<"$host") + # option takes precedence + host=$user@$host + fi + opts+=" $cfg" + fi + +if [[ $ret ]]; then + # return arguments so a command can be composed elsewhere + { echo "$host,$opts $* ,$sshpass"; return 0; } + else + # run remote commands right here + sshcmd="$sshpass $(which ssh) $opts $host" + # echo extra args: "$@" + # echo running command: $ "$sshcmd" + [[ ! $dr ]] && $sshcmd "$@" || echo $sshcmd "$@" +fi + +} # end ssh + diff --git a/modules/sshfs.mod b/modules/sshfs.mod new file mode 100755 index 0000000..d148ea0 --- /dev/null +++ b/modules/sshfs.mod @@ -0,0 +1,122 @@ +#!/bin/bash +# depends on sshfs fuse for ssh +# smount host:dir mountpoint -- < more sshoptions > +# example: smount +module_load filesystem # mounted +module_load net-utils # host_reachable +module_load helpers +module_load ssh + +function smount() { + + local user=${DEFAULT_USER:-ubuntu} + local opts; local ropts; local sshopts + local host; local sshcmd; local cmd + + local dir; local MNT; local SRC + local MNTUSER; + + local OPTION; local OPTARG; local OPTIND + + while getopts ':uno:' OPTION; do + # echo $OPTION $OPTARG + case "$OPTION" in + + u) + MNTUSER=$OPTARG + ;; + n) + MNTUSER=_NONE_ + ;; + o) + echo "adding sshfs option: $OPTARG" + opts+=" -o $OPTARG" + ;; + *) + echo unknown sshfs option $OPTION + ;; + esac + done + + shift $((OPTIND - 1)) + + SRC=$1 + MNT=$2 + shift 2 + + if [[ ! $* =~ "--" ]]; then + ropts=$* + else + ropts=$(sed 's/\(.*\)--.*/\1/' <<< "$*") + sshopts=$(sed 's/.*--\(.*\)/\1/' <<< "$*") + fi + + host=$(sed 's/\(.*\):.*/\1/' <<<"$SRC") + dir=$(sed 's/.*:\(.*\)/\1/' <<<"$SRC") + + [[ ! $host ]] && { echo no remote host given, aborting; return 4; } + [[ ! $dir ]] && { echo no remote directory given, aborting; return 5; } + + module_load array + declare -a ret + echo $ropts + scmd="ssh -r ${ropts} ${host}" + String::split ret "$($scmd)" , + host=${ret[0]}; sshopts+=" ${ret[1]}"; local sshpass=${ret[2]} + # echo "$host;$sshopts;$sshpass" + # scmd="'$sshpass /usr/bin/ssh $sshopts'" + # echo ssh command: "$scmd" + # opts+=" $scmd" + # remove_end_spaces "$scmd" + # 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 + + if [[ $(mounted $MNT) ]]; then + echo "some remote already mounted at $MNT. Umount with: $ umount $MNT" + else + mkdir -p $MNT + if [[ ! $MNTUSER == "_NONE_" ]]; then + MNTUSER=${MNTUSER:-$USER} + id=$(id -u ${MNTUSER}) + if [[ $id ]]; then + opts+=" -o uid=$id -o allow_other -o idmap=user" + else + echo no user ${MNTUSER} on this machine, aborting mount + return 1 + fi + else + MNTUSER="" + fi + + cmd="sshfs $host:$dir $MNT $opts" + echo $cmd + eval $cmd + if [[ $? -gt 0 ]]; then + echo "ERROR: unable to mount remote directory" + echo "CMD=> $cmd" + else + [[ ! $MNTUSER == "_NONE_" ]] && MNTUSER=" as user $MNTUSER " || MNTUSER="" + echo "mounted directory $dir from $(parse_host $host)${MNTUSER}at $MNT" + fi + fi +} + +function usmount() { + if [[ $(mounted $1) ]]; then + echo "unmounting remote file system at $1" + fusermount -u $1 + else + echo "nothing mounted at $1, aborting unmount" + fi +} + +function mntBackup() { + smount root@$1:/backup /backup/remote +} + +function umntBackup() { + usmount /backup/remote +}