Major refactor upgrades for remote scripting and access via ssh

ssh-copy now uses options and has help and uses new helpers to prepare the scp command
remote module totally redone.  now uses sshcp (scp) to copy the file
   makes use of the much improved bundle function for bundling script
now that remote_script is refactored can use for
ssh-pub-key
and for the uci remote install function
cleaned up ssh function a bit
add parsing functions to net-utils for parsing host
master
David Kebler 2024-02-21 11:33:37 -08:00
parent c45418d313
commit a67d54e9dc
20 changed files with 653 additions and 290 deletions

View File

@ -1,39 +0,0 @@
#!/bin/bash
# assumes that bash is installed
#!/bin/bash
# must! be run as sudo
install_shell_base () {
# TODO have a cross distro package install
[[ ! $(which git) ]] && echo git must be installed first && return 1
[[ ! $EUID -eq 0 ]] && { echo ERROR script must be run as root; return 2; }
mkdir -p /shell/base
git clone https://git.kebler.net/bash/shell-base.git /shell/base
chown -R ${1:-$1000}:${1:-1000} /shell
chmod -R +r /shell
/bin/bash /shell/base/install/install.sh ${1:-$1000}
}
# remote_install_shell_base -r <remote host> <sudo pass if host not root> <user to install, default is $USER>
# module_load install-shell-base && remote_install_shell_base -r newboxr
remote_install_shell_base () {
module_load remote
local supass;local user
if [[ $1 == "-r" ]]; then
shift 1;
user=$2;
else
[[ ! $2 ]] && { echo sudo password for remote user required; return 2; }
supass="-p $2"
user=$3
fi
remote_script $supass install-shell-base $user -- $1
}
# # if script was executed then call the function
(return 0 2>/dev/null) || install_shell_base $@
# example
# $ module_load install-shell-base
# $ remote_install_shell_base -r portabler david

View File

@ -0,0 +1,30 @@
#!/bin/bash
# assumes that bash is installed
#!/bin/bash
# must! be run as sudo
install_shell_base () {
# TODO have a cross distro package install
module_load distro
set_distro
[[ ! $(command -v git) ]] && echo git must be installed first && $INSTALL_PKGS git
# TODO, avoid which in all scripts. or put which in environment if not on machine
[[ ! $(command -v which) ]] && echo 'which' must be installed first && $INSTALL_PKGS which
echo $USER, $EUID
[[ ! $EUID -eq 0 ]] && { echo ERROR script must be run as root; return 2; }
echo I am ROOT, now running script
echo UCI user: $1
# TODO make the repo and clone values dynamic or bundle current base on sending machine a archive
mkdir -p /shell/base
git clone https://git.kebler.net/bash/shell-base.git /shell/base
chown -R ${1:-$1000}:${1:-1000} /shell
chmod -R +r /shell
/bin/bash /shell/base/install/install.sh ${1:-1000}
}
# # if script was executed then call the function
( return 0 2>/dev/null ) || install_shell_base $@

View File

@ -37,26 +37,36 @@ 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)
host=$(get_hostname_host $1)return
lhost=$(ssh -F $config -G $host | grep -w hostname | cut -d' ' -f2)
[[ $lhost ]] && echo $lhost || echo $host
}
parse_host () {
# usage: parse_host <user/host>
get_hostname_host () {
# usage: get_hostname_host <user/host>
# returns extracted host if passed user@host
# otherwise return value passed
[[ $1 =~ "@" ]] && { echo $(sed 's/.*@\(.*\)/\1/' <<< "$1");return 0; }
echo $1
return 1
# [[ $1 =~ "@" ]] && { echo $(sed 's/.*@\(.*\)/\1/' <<< "$1");return 0; }
local hostname
hostname=$(cut -s -d@ -f2 <<< "$1")
if [[ ! $hostname ]] && type ssh_config_get &>/dev/null ; then
hostname=$(ssh_config_get -h $1)
fi
[[ $hostname ]] && echo $hostname || return 1
}
parse_user () {
# usage: parse_user <user/host>
get_user_host () {
# [[ $1 =~ "@" ]] && { echo $(sed 's/\(.*\)@.*/\1/' <<< "$1"); return 0; } || return 1
# usage: get_user_host <user/host>
# 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
local user
user=$(cut -s -d@ -f1 <<< "$1")
if [[ ! $user ]] && type ssh_config_get &>/dev/null ; then
user=$(ssh_config_get -u $1)
fi
[[ $user ]] && echo $user || return 1
}

13
modules/nomachine.lib Normal file
View File

@ -0,0 +1,13 @@
/usr/NX/etc/server.cfg
sed
#AcceptedAuthenticationMethods all
to
AcceptedAuthenticationMethods NX-private-key
restrat the server
sdr nxserver
copy a public key to ~/.nx/config/authorized.crt

View File

@ -1,97 +1,172 @@
#!/bin/bash
module_load ssh
module_load bundle
module_load helpers
module_load ssh-copy
remote_function () {
[[ $2 ]] && module_load $2
if declare -f $1; then
local file
file=$(mkrfilename function)
$(declare -f $1) > $file
echo $file
else
>&2 echo fatal: unable to source funtion $1, aborting
return 1
fi
}
remote_script () {
# usage: remote_script script -- <ssh setup options> host <ssh options>
# see ssh function
#
local sshargs;local user;local supass;local fn;local args;local file
[[ "$*" =~ "--" ]] && sshargs=$(sed 's/.*--\(.*\)/\1/' <<< "$@")
[[ ! $sshargs ]] && { echo missing remote machine, must provide at least a hostname, -- hostname; return 3; }
# reset arguments to just those before --
set -- $(sed 's/\(.*\)--.*/\1/' <<< "$@")
local sshargs;local user;local supass;local cfn; local rfn; local args;
local script; local host; local dr; local supass
local hostname; local bscript; local ruser; local usesudo
local OPTION
local OPTARG
local OPTIND
while getopts 'u:s:f:p:' OPTION; do
# echo OPTION $OPTION ARG $OPTARG INDX $OPTIND
case "$OPTION" in
s)
# script filename to run
file=$OPTARG
;;
help() {
cat <<EOF
usage: remote_script <remote_script options> host script <script args> -- <ssh script options>
host and script are required, script can be either path to a file containing a script to a UCI module
-s, execute remote script using sudo
-f, run a function in the passed script, otherwise script is assumed to be bash executed.
-d, dry run. don't run the rscript just output the command that will be run
-u, remote user to run script as. default is ssh host user or root if using sudo
-p, password for ssh login, will also be used for sudo assuming remote user is in sudo group
-x, create script from available function instead of module or file
-h, this help text
EOF
}
# parse ssh arguments from the rest
debug $( ( IFS=$','; echo all arguments: "$*" ) )
for ((d=1; d<$#; ++d)); do
[[ ${!d} == "--" ]] && break
done
if [[ $d -lt $# ]]; then # if there are extra ssh arguments
debug found -- at $d
sshargs=("${@:$d+1:$#}")
debug $( ( IFS=$','; echo "ssh arguments: ${sshargs[*]}" ) )
# [[ ! ${sshargs[0]} ]] && { echo missing remote machine, must provide at least a hostname, -- hostname; return 3; }
args=("${@:1:$d-1}")
# reset script arguments to just those before --
set -- "${args[@]}"
debug $( ( IFS=$','; echo remaining arguments to parse: "$*" ) )
fi
# parse remote_script options
local OPTION
local OPTARG
local OPTIND
while getopts 'hdu:sf:p:x:' OPTION; do
# echo OPTION $OPTION ARG $OPTARG INDX $OPTIND
case "$OPTION" in
s)
# using sudo, password will come from ssh user password or if you supply it with -p
usesudo=true
;;
f)
# run a function within the script
fn=$OPTARG
;;
# run a function within the script
# any function arguments appear after script
cfn="-f $OPTARG"
;;
d)
# dry run
dr=true
;;
u)
# run command as another user
user=$OPTARG
# run remote command as another user
ruser=$OPTARG
# usesudo=true
;;
x)
rfn=$OPTARG
;;
p)
# password of sudo account for running as root or other user
supass=$OPTARG
;;
# password of sudo account for running as root or other user
# will force running as root on remote if ruser is not specified
supass=$OPTARG
;;
h)
help
return 0
;;
*)
echo unknown remote script option -$OPTARG
>&2 echo fatal: unknown remote script option $OPTION, aborting
help
return 1
;;
esac
done
done
shift $((OPTIND - 1))
shift $((OPTIND - 1))
[[ ! $file ]] && { file=$1;shift 1; }
if [[ ! -f $file ]]; then
file=$(module_find $file)
[[ ! $file ]] && { echo no module or script at $file to run; return 1; }
fi
[[ $# -lt 1 ]] && echo fatal: remote_script requires a 'host' && help && return 1
# remaining script arguments
args=$*
# echo arguments for script: $args
script=$file
# 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 $file $script
temp=true
fi
host=$1;
[[ ! $host ]] && echo fatal: no host was passed unable to excute a remote script && return 3
user=$(get_user_host $host)
[[ ! $user ]] && echo fatal: unable to determine user at host $host, aborting remote script && return 4
hostname=$(get_hostname_host $host)
shift 1
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
# script can come from
if [[ $rfn ]]; then
if ! declare -f $rfn >/dev/null; then
if ! module_load $2; then
[[ -f $2 ]] && source $2
fi
if ! declare -f $rfn >/dev/null; then echo fatal: remote-script, unable to source funtion $rfn, aborting; return 1; fi
shift
fi
fi
local file
script=$(mkrfilename temp_function)
declare -f $rfn > $script
cfn="-f $rfn"
else
script=$2
shift 1
fi
[[ ! -f $script ]] && echo fatal: must pass a script to remote run && help && return 1
src="$(cat $script);"
if [[ $fn ]]; then
# echo running function
cmd="bash -c '$src $fn ${args[*]}'"
debug echo host: $host user: $user hostname:$hostname script:$script function to run: $cfn
bscript=$(mkrfilename bundle_script )
if ! bundle -c $cfn $script $bscript; then
>&2 echo fatal: remote_script unable to bundle script for sending, aborting; return 1;
fi
[[ $usesudo ]] && supass=$(parse_option "${sshargs[*]}" -p)
if [[ $supass ]]; then
usesudo="echo '${supass}' | sudo -u ${ruser:-root} --stdin 2>/dev/null"
echo remote script to be run as ${ruser:-root} using sudo
fi
debug remote script arguments $(remote_args "$@")
debug ssh arguments $(remote_args "${sshargs[@]}")
rscript=${save:-$(mkrfilename REMOTE_SCRIPT)}
if sshcp -d $host $bscript $rscript -- "${sshargs[@]}"; then
# make remote script excuteable
ssh "${sshargs[@]}" "$host" "chmod +x $rscript"
# run the script
ssh "${sshargs[@]}" "$host" "$usesudo" "$rscript" "$(remote_args "$@")"
# now delete it, save script if passed an explicit name
if ! ssh "${sshargs[@]}" $host rm -f $rscript; then echo unable to delete temporary remote file at $host:$rscript; fi
# ssh "${sshargs[@]}" "$host" "cat $rscript"
else
# echo running as script
local sargs
[[ ${args} ]] && sargs="$(printf '%s\n' "set -- ${args}"); "
cmd="bash -c '$sargs $src'"
fi
>&2 echo fatal: remote_script failed because script could not be copied; return 1;
fi
# echo ssh $sshargs "$_sudo" "$cmd"
ssh $sshargs "$_sudo" "$cmd"
[[ $temp ]]&& rm -f $script
rm -f $bscript
[[ $rfn ]] && [[ "${script}" =~ "temp_function" ]] && rm -f $script
}
# END REMOTE SCRIPT
# can be used with a file or HEREDOC
@ -99,12 +174,10 @@ ssh $sshargs "$_sudo" "$cmd"
remote_stdin () {
local file
# echo args $@
file=$( mktemp -t TEMP_FILE_script.XXXXXXXX )
file=$( mkrfilename remote_script )
cat > $file
echo remote_script -s "$file" "$@"
#remote_script -s "$file" "$@"
rm $file
remote_script $1 "$file" "$@"
rm -f $file &> /dev/null
}
# # if script was executed then call the function
@ -112,10 +185,41 @@ rm $file
# sudo rsync --exclude *[C]ache* -e '/usr/bin/ssh -F /home/david/.ssh/_config' --progress -aAru /opt/chromium seldon:/opt
# remote_install_shell_base <script options> script command <sudo pass if host not root> <user to install, default is $USER>
remote_install_shell_base () {
module_load remote
remote_copy () {
local supass;local user; local host
sudo rsync --exclude *[C]ache* -e '/usr/bin/ssh -F /home/david/.ssh/_config' --progress -aAru /opt/chromium seldon:/opt
declare OPTION; declare OPTARG; declare OPTIND
while getopts 's:p:cf:x:' OPTION; do
case "$OPTION" in
p)
#both for login and sudo
upass="-p $OPTARG"
;;
u) user="$OPTARG"
;;
s)
# only for running sudo command for non-root use logged in via sshkey
supass="-p $OPTARG"
;;
*)
echo unknown bundle option $OPTION
;;
esac
done
}
shift $(( OPTIND - 1 ))
host=$1
[[ ! $host ]] && >&2 echo remote_install_shell_base requires specifying a host
shift 1
user=${user:-$(get_user_host $host)}
[[ $user == "root" ]] && user="" && >&2 echo warning, will not set up any user than root for UCI shell
[[ ! $user ]] && >&2 echo unable to determin remote user for host $host, aborting && return 1
if [[ $supass ]] && [[ $upass ]]; then >&2 echo specify either -s or -p or neither but not both; return 1; fi
[[ $upass ]] && remote_script -s -f install_shell_base $host install-shell-base $user -- $upass "$@" && return $?
[[ $supass ]] && remote_script $supass -f install_shell_base $host install-shell-base $user -- $upass "$@" && return $?
remote_script -f install_shell_base $host install-shell-base $user -- "$@"
}

View File

@ -183,9 +183,9 @@ ssh_config_get () {
shift $((OPTIND - 1))
[[ ! $1 ]] && { echo must pass a config host; return 1; }
[[ ! $1 ]] && { >&2 echo must pass a config host; return 1; }
[[ ! $(cat "$SSH_CONFIG" | grep "[Hh]ost" | grep $1) ]] && echo "no host alias $1" && return 2
[[ ! $(cat "$SSH_CONFIG" | grep "[Hh]ost" | grep $1) ]] && >&2 echo "no host alias $1" && return 2
props=$($ssh $1)
[[ $all ]] && { echo "$props"; return 0; }

View File

@ -1,45 +1,114 @@
#!/bin/bash
# usage:
# sshcp src dest <ssh run opts> -- <ssh opts>
module_load ssh
module_load debug
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
sshcp () {
local SHOST; local DHOST; local dr; local sshargs; local args
local OPTS; local SOPTS; local SRC; local DEST;
local SPATH; local SPATH
help() {
cat <<EOF
usage:
sshcp <script options> src dest <scp options> -- <ssh options>
-d, destination host
-s, source host
-y, dry run. don't run the rscript just output the command that will be run
-h, this help text
EOF
}
# parse sshcp options
local OPTION
local OPTARG
local OPTIND
while getopts 'd:ys:h' OPTION; do
# echo OPTION $OPTION ARG $OPTARG INDX $OPTIND
case "$OPTION" in
s)
# script filename to run
SHOST=$OPTARG
;;
y)
# dry run
dr=true
;;
d)
# run remote command as another user
DHOST=$OPTARG
;;
h)
help
return 0
;;
*)
>&2 echo fatal: unknown remote script option $OPTION, aborting
help
return 1
;;
esac
done
shift $((OPTIND - 1))
[[ ! $1 ]] && >&2 echo fatal: scp requires a source path to send && return 1
SRC=$1; shift
if [[ $SRC =~ ":" ]]; then
# echo source is remote
SHOST=$(sed 's/\(.*\):.*/\1/' <<< "$SRC")
SDIR=$(sed 's/.*:\(.*\)/\1/' <<< "$SRC")
SHOST=${SHOST:-$(sed 's/\(.*\):.*/\1/' <<< "$SRC")}
SPATH=$(sed 's/.*:\(.*\)/\1/' <<< "$SRC")
else
# echo source is local
SDIR=$SRC
SPATH=$SRC
fi
# echo SHOST $SHOST SDIR $SDIR
DEST=$1;shift
if [[ $DEST =~ ":" ]]; then
# echo destination is remote
DHOST=$(sed 's/\(.*\):.*/\1/' <<< "$DEST")
DDIR=$(sed 's/.*:\(.*\)/\1/' <<< "$DEST")
destination is remote
DHOST=${DHOST:-$(sed 's/\(.*\):.*/\1/' <<< "$DEST")}
DPATH=$(sed 's/.*:\(.*\)/\1/' <<< "$DEST")
else
# echo destination is local
DDIR=$DEST
DPATH=$DEST
fi
# echo DHOST $DHOST DDIR $DDIR
[[ ! $DPATH ]] && >&2 echo fatal: scp requires a destination file path && return 1
[[ $DHOST && $SHOST && (! $DHOST = "$SHOST") ]] && { echo full remote copy must be same hosts; return 2; }
if [[ ! $(get_user_host $DHOST) ]] && [[ ! $(get_user_host $SHOST ) ]]; then
>&2 echo fatal: need at least a valid remote source host $SHOST or remote destination host $DHOST, aborting remote copy
return 1
fi
[[ $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
# parse ssh arguments from the rest
debug $( ( IFS=$','; echo all arguments: "$*" ) )
for ((d=1; d<$#; ++d)); do
[[ ${!d} == "--" ]] && break
done
if [[ $d -lt $# ]]; then # if there are extra ssh arguments
debug found -- at $d
sshargs=("${@:$d+1:$#}")
debug $( ( IFS=$','; echo "ssh arguments: ${sshargs[*]}" ) )
# [[ ! ${sshargs[0]} ]] && { echo missing remote machine, must provide at least a hostname, -- hostname; return 3; }
args=("${@:1:$d-1}")
# reset script arguments to just those before --
# set -- "${args[@]}"
debug $( ( IFS=$','; echo remaining arguments to parse: "$*" ) )
fi
# # echo parse: $*
# if [[ ! $* =~ "--" ]]; then
# SOPTS=$*
# else
# SOPTS=$(sed 's/\(.*\)--.*/\1/' <<< "$*")
# OPTS=$(sed 's/.*--\(.*\)/\1/' <<< "$*")
# fi
# echo SOPTS $SOPTS
# echo OPTS $OPTS
@ -48,22 +117,25 @@
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
cmd="ssh -r ${sshargs[*]} ${DHOST:-$SHOST}"
String::split ret "$($cmd)" ,
local host=${ret[0]}; local sshopts=${ret[1]}; local sshpass=${ret[2]}
[[ -d $SPATH && ! $SHOST ]] && args+=(" -r")
# todo test remote to local copy
local cmd="$sshpass scp $opts $OPTS $([[ $SHOST ]] && echo "${host}:")$SDIR $([[ $DHOST ]] && echo "${host}:")$DDIR"
echo $cmd
$cmd
return 0
local cmd="$sshpass scp ${args[*]} $sshopts $([[ $SHOST ]] && echo "${host}:")$SPATH $([[ $DHOST ]] && echo "${host}:")$DPATH"
# echo $cmd
if $([[ $dr ]] && echo "echo ") $cmd; then
debug copy success
debug $(ssh ${sshargs[*]} ${DHOST:-$SHOST} ls -la $DPATH)
else
>&2 echo remote copy failed
>&2 echo $cmd
return 1
fi
}

View File

@ -60,7 +60,8 @@ catpubkey () {
export SSH_PUB_KEYS
module_load path
module_load ssh
module_load net-utils
module_load remote
sshpubkey () {
@ -69,113 +70,146 @@ sshpubkey () {
local kname=id_rsa
local user
local opts;local dr="true";local rm; local ropts
local vkey; local kuser; local host; local supass; local replace
local scmd; local _sudo; local list
local vkey; local kuser; local host; local upass; local replace
local _sudo; local list;
local OPTION
local OPTARG
local OPTIND
while getopts 'u:a:r:ek:o:s:l' 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
;;
l)
list=true
;;
r)
# remove key, must be "comment identifier in public key"
rm=$OPTARG
;;
k)
kpath=$OPTARG
key=$(getkeyname $kpath)
;;
o)
opts=$OPTARG
;;
e)
dr=""
;;
*)
echo unknown option -$OPTARG
# opts="$opts ${@:$OPTIND:1}"
# # ((OPTIND+=1))
# #echo remaining ${@:$OPTIND}
return 1
;;
esac
done
help() {
cat <<EOF
usage: sshpubkey <pubkey opts> host <ssh run options> -- <more ssh options>
-a, <alternate user> put the key at another user on remote. if you want to put it to root use 'root' will require remote sudo
-u, <user> remote user if not available in host
-s, <paswd> sudo password for remote if needed
-k, <key> can be either the path to a public key file or the name of the key currently loaded in an ssh agent
-l, list the keys for the remote user
-r, remove the key from the user, use the comment identifier of the public key
-o, <options> additional ssh options
-e, required to actually make the remote changes, otherwise it's a dry run. This to avoid making a mistake and locking out of remote
-h, this help text
EOF
}
local OPTION;local OPTARG;local OPTIND
while getopts 'sp:hu:a:r:ek:o:s:l' 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="-u $OPTARG"
;;
u)
# user if not explicit from host
user=$OPTARG
;;
p)
upass="-p $OPTARG"
;;
l)
list=true
;;
r)
# remove key, must be "comment identifier in public key"
rm=$OPTARG
;;
k)
kpath=$OPTARG
key=$(getkeyname $kpath)
;;
o)
opts=$OPTARG
;;
e)
dr=""
;;
h)
help
;;
*)
echo unknown option -$OPTARG
help
# opts="$opts ${@:$OPTIND:1}"
# # ((OPTIND+=1))
# #echo remaining ${@:$OPTIND}
return 1
;;
esac
done
shift $((OPTIND - 1))
host=$1
shift 1
if [[ ! $host ]]; then
echo "no host supplied, aborting"
echo "usage: sshpubkey <pubkey opts> host <ssh run options> -- <more ssh options>"
>&2 echo "no host supplied, aborting"
help
return 2
fi
shift 1
if [[ ! $* =~ "--" ]]; then
ropts=$*
else
ropts=$(sed 's/\(.*\)--.*/\1/' <<< "$*")
opts=$(sed 's/.*--\(.*\)/\1/' <<< "$*")
# parse ssh arguments from the rest
# TODO change to a function to do this
if [[ ! $* =~ "--" ]]; then
debug $( ( IFS=$','; echo all arguments: "$*" ) )
for ((d=1; d<$#; ++d)); do
[[ ${!d} == "--" ]] && break
done
if [[ $d -lt $# ]]; then # if there are extra ssh arguments
debug found -- at $d
opts=("${@:$d+1:$#}")
debug $( ( IFS=$','; echo "ssh arguments: ${opts[*]}" ) )
# [[ ! ${sshargs[0]} ]] && { echo missing remote machine, must provide at least a hostname, -- hostname; return 3; }
ropts=("${@:1:$d-1}")
debug $( ( IFS=$','; echo "remaining arguments to parse: ${ropts[*]}" ) )
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"
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
rfcmd () (
local fn
fn=$1
shift 1
echo "bash -c '$(declare -f $fn); $fn $*'"
)
# if [[ ! $* =~ "--" ]]; then
# ropts=$*
# else
# ropts=$(sed 's/\(.*\)--.*/\1/' <<< "$*")
# opts=$(sed 's/.*--\(.*\)/\1/' <<< "$*")
# fi
debug KEY $key, HOST $host
debug ssh run opts ${ropts[*]}
debug additional ssh 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"
user=${user:-$(get_user_host $host)}
[[ ! $user ]] && >&2 echo "unable to determine remote user, aborting" && return 2
# rfcmd () (
# local fn
# fn=$1
# shift 1
# echo "bash -c '$(declare -f $fn); $fn $*'"
# )
run () (
# echo "$scmd" "$_sudo"
# echo "$(rfcmd "$*")"
$scmd "$_sudo" "$(rfcmd "$*")"
local func; local _sudo
func=$1; shift
if [[ "${kuser}" =~ "root" ]]; then
kuser=""
_sudo=-s
fi
remote_script $_sudo $kuser -x $func $host "$@" -- $upass
)
# echo remote user: $user
if [[ $kuser ]]; then
_sudo="echo '${supass}' | sudo -u ${kuser} --stdin"
fi
# if [[ $kuser ]]; then
# _sudo="echo '${supass}' | sudo -u ${kuser} --stdin"
# fi
if [[ $list ]]; then
run list_keys
@ -194,15 +228,14 @@ sshpubkey () {
vkey=$(catpubkey $kpath) # get actaul content of public key
[[ $? -gt 0 ]] && echo no valid public key for $key at $kpath found && return 4
## Alternate remote user?
if [[ $kuser ]]; then
[[ ! $supass ]] && { echo remote user, $user, password must be supplied for sudo. use -s;return 7; }
fi
# ## 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

View File

@ -1,8 +1,8 @@
#!/bin/bash
# this will superceed the ssh binary in order to source all the config files
# "USAGE: ssh <run/setup options> host <SSH options> <commands to run on remote>"
# put any additional SSH (man ssh) options after the host, aborting"#
# "USAGE: ssh <ssh script options> <host,can set via -h> <SSH options> <commands to run on remote>"
# put any additional SSH (man ssh) options after the host
# if using ssh in another command use -r flag
# this returns a string that can be parsed into an array
@ -23,7 +23,7 @@ module_load ssh-config
ssh() {
local pw;local cfg;local opts;local mp; local sshpass; local dr; local sshcmd
local pw;local cfg;local opts;local mp; local sshpass; local dr; local sshcmd; local term
local host; local user; local script; local ret ; local key; local efile; local tfile
if [[ $SSH_CONFIG ]]; then
@ -34,12 +34,15 @@ ssh() {
# echo passed: $*
local OPTION; local OPTARG; local OPTIND
while getopts ':h:u:mdF:p:ro:k:' OPTION; do
while getopts 'th:u:mdF:p:ro:k:' OPTION; do
# echo processing: option:$OPTION argument:$OPTARG index:$OPTIND remaining:${@:$OPTIND}
case "$OPTION" in
h)
host=$OPTARG
;;
t)
term=" -t "
;;
d)
dr=true
;;
@ -99,19 +102,17 @@ ssh() {
[[ (! $host) && $1 ]] && { host=$1;shift; }
# echo extra ssh options and the command: $@
# echo host $host
# return
debug extra ssh options and the remote commands: $@
[[ ! $host ]] && echo host/ip required, aborting && return 2
[[ ! $user ]] && user=$(parse_user $host)
[[ ! $user ]] && user=$(get_user_host $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="$(multipass_get_ip $(get_hostname_host $host))"
[[ ! $ip ]] && echo could not resolve ip for multipass instance $1 && return 5
[[ ! $pw && ! $key ]] && opts+=" $(multipass_ssh_options)"
host="$user@$ip"
@ -130,10 +131,14 @@ if [[ $ret ]]; then
{ echo "$host,$opts $* ,$sshpass"; return 0; }
else
# run remote commands right here
sshcmd="$sshpass $(which ssh) $opts $host"
sshcmd="$sshpass $(which ssh) $term $opts $host"
# echo extra args: "$@"
# echo running command: "$sshcmd"
[[ ! $dr ]] && $sshcmd "$@" || echo SSH Command Failed: $sshcmd "$@"
if [[ $dr ]]; then
echo $sshcmd
else
$sshcmd "$@" || echo SSH Command Failed: $sshcmd "$@"
fi
fi
} # end ssh

View File

@ -101,7 +101,7 @@ function smount() {
echo "CMD=> $cmd"
else
[[ ! $MNTUSER == "_NONE_" ]] && MNTUSER=" as user $MNTUSER " || MNTUSER=""
echo "mounted directory $dir from $(parse_host $host)${MNTUSER}at $MNT"
echo "mounted directory $dir from $(get_hostname_host $host)${MNTUSER}at $MNT"
fi
fi
}

1
ssh/etc/sshd_config Normal file
View File

@ -0,0 +1 @@
Include /etc/ssh/sshd_config.d/*.conf

View File

@ -0,0 +1,7 @@
PermitRootLogin no
UsePAM yes
KbdInteractiveAuthentication no
PubkeyAuthentication no
KbdInteractiveAuthentication no
PasswordAuthentication no

View File

@ -0,0 +1,3 @@
Match user rsk
X11Forwarding yes

View File

@ -0,0 +1,5 @@
#ubuntu/debian
# Subsystem sftp /usr/lib/openssh/sftp-server
# arch
Subsystem sftp /usr/lib/ssh/sftp-server

View File

@ -0,0 +1,2 @@
DenyUsers <put users here no spaces comma>

View File

@ -0,0 +1,5 @@
# allow only some users from some addresses
Match User <user>,,user> Address 10.10.0.2
PubkeyAuthentication yes
PermitRootLogin prohibit-password

116
ssh/etc/sshd_config.sample Normal file
View File

@ -0,0 +1,116 @@
# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
KbdInteractiveAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
UsePAM yes
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
#Banner none
# override default of no subsystems
Subsystem sftp /usr/lib/ssh/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server

View File

@ -1,5 +0,0 @@
# if [[ $- == *i* ]]; then
# 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

View File

@ -1,2 +0,0 @@
*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

3
ssh/ssh.inst Normal file
View File

@ -0,0 +1,3 @@
TODO write a command to copy these to etc/ssh
should save a backup of that directory first
need to run as sudo