Created
June 26, 2012 01:56
-
-
Save dmytro/2992692 to your computer and use it in GitHub Desktop.
Various scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
:<<"=cut" | |
=head1 NAME | |
C<run_root_remotely> - use expect and sudo to deploy SSH key to remote | |
server root account and execute script on the remote via SSH as root | |
=head1 DESCRIPTION | |
Assumed that remote user account exists on remote machine and added to | |
sudoers file. | |
Single use SSH keys are generated on each run in /tmp directory. Keys | |
are copied to root account on remote server using expect and sudo. | |
After remote commands completed, stored locally in /tmp private and | |
public keys are removed. On remote machine authorized_keys file | |
restored to pre-run state. | |
=head1 USAGE | |
./run_root_remotely <options> | |
Without options prints this help. | |
=head2 COMMAND LINE OPTIONS | |
--host | -h <hostname> | |
Hostname of the remote server to run command (REQUIRED) | |
--user | -u <name> | |
Login name of remote user. If it is not provided, then | |
it is assumed to be the same as login name of user | |
running script. | |
--password | -p <password> | |
Password of the remote user. If password is not | |
provided, script will ask for it. | |
--local | -l <PATH> | |
PATH on the local host to the script. Script copied to | |
remote server and executed there via SSH with root privileges. | |
--remote | -r <PATH> | |
PATH on the remote host to the script to run. Script | |
executed on remote host with root privileges. | |
Both local and remote commands can be specified. In this case both | |
commands are executed on the remote machine. | |
=head1 TO-DO | |
- How to avoid typing password on each run and also do not use as command line option? | |
=head1 AUTHOR | |
Dmytro Kovalov, 2012, June 4. | |
=cut | |
usage () { | |
perldoc $0; exit | |
} | |
while test $# -gt 0; do | |
case "$1" in | |
-h|--host ) | |
HOST=$2; shift 2 ;; | |
-p|--password ) | |
PASS=$2; shift 2 ;; | |
-l|--local ) | |
LOCAL_COMMAND=$2; shift 2 | |
# Check existence of local script | |
[ -f ${LOCAL_COMMAND} ] || { echo "Local command script does not exist."; exit 1; } | |
;; | |
-r|--remote ) | |
REMOTE_COMMAND=$2; shift 2;; | |
--) shift;; | |
* ) usage ;; | |
esac | |
done | |
[ -z "${HOST}" ] && usage | |
# Create keys | |
# ---------------------------------------- | |
SSHDIR=$(mktemp -d /tmp/deploy_keys.XXXX) | |
ssh-keygen -N "" -t dsa -f ${SSHDIR}/identity 2>&1 > /dev/null | |
# | |
# Remote user's password | |
# ---------------------------------------- | |
[ -z "$PASS" ] && { builtin read -p "Remote server password: " -s PASS; echo; } | |
KEY=$(cat ${SSHDIR}/identity.pub) | |
# | |
# Actual authorized_keys file on remote server | |
# | |
A_KEYS=/root/.ssh/authorized_keys | |
# | |
# Backup copy of the file, to restore key after completion | |
# | |
B_KEYS=/root/.ssh/authorized_keys.${USER}.$(uname -n).$$.bak | |
# | |
# Need echo to send result to user's terminal | |
# | |
echo $(expect -c " | |
spawn -noecho ssh -t ${USER}@${HOST} \"sudo -v \; sudo mkdir -p /root/.ssh \; sudo chmod 700 /root/.ssh\; sudo touch ${A_KEYS}\; sudo chown root ${A_KEYS}\; sudo chmod 600 ${A_KEYS}\; sudo cp --force ${A_KEYS} ${B_KEYS}\; echo '${KEY}' | sudo tee -a ${A_KEYS} \; \" | |
log_user 0 | |
expect { | |
\"try again\" { send_user \"Wrong server or sudo password\"; exit } | |
-re \".*Are.*.*yes.*no.\" { send \"yes\r\n\"; exp_continue } | |
\"${USER}@${HOST}*assword:\" { send \"$PASS\r\" ; exp_continue} | |
\"sudo*assword for*:\" { send \"$PASS\r\" ; exp_continue } | |
eof exit | |
}") | |
if [ ! -z "${REMOTE_COMMAND}" ]; then | |
ssh root@${HOST} -i ${SSHDIR}/identity "${REMOTE_COMMAND}" | |
fi | |
if [ ! -z "${LOCAL_COMMAND}" ]; then | |
REMOTE_NAME=/tmp/$(basename ${LOCAL_COMMAND}).${USER}.$$ | |
scp -i ${SSHDIR}/identity "${LOCAL_COMMAND}" root@${HOST}:${REMOTE_NAME} 1> /dev/null | |
ssh root@${HOST} -i ${SSHDIR}/identity "chmod +x ${REMOTE_NAME}; ${REMOTE_NAME}; rm -f ${REMOTE_NAME}" | |
fi | |
# | |
# Cleanup keys on completion | |
# ---------------------------------------- | |
ssh -i ${SSHDIR}/identity root@${HOST} "/bin/mv --force ${B_KEYS} ${A_KEYS}" | |
rm -rf ${SSHDIR} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Use perldoc functions to see documentation for this file. | |
:<<"=cut" | |
=head1 NAME | |
functions - Common functions for bash scripts | |
=head1 DESCRIPTIONS | |
Define some common bash scripts often used in Moria environment. To | |
use it simply source this file in your script. | |
=head2 SIDE EFFECTS | |
Re-sets PATH to /bin:/usr/bin:/sbin:/usr/sbin. If you need more PATHs | |
add them after sourcing this file. | |
=head2 VARIABLES | |
To exit cleanly from parent script functions rely on $PARENT | |
variable. It must be set in caller script as PARENT=$$ | |
=head1 FUNCTIONS | |
=head2 osbreed | |
Returns OS name on STDOUT and sets variable $osbreed | |
=cut | |
osbreed () { | |
export osbreed=$(awk 'NR==1 {print $1; exit}' < /etc/issue 2> /dev/null ) | |
echo $osbreed | |
} | |
:<<"=cut" | |
=head2 am_i_root | |
Usage: | |
am_i_root | |
Kills parent script if it is not run under root. | |
=cut | |
am_i_root () { | |
test $(id -u) -eq 0 || { echo "Must be run as root"; exit 2; } | |
} | |
:<<"=cut" | |
=head2 primary_ip | |
Detects IP address for the interface which have default route on it. | |
Returns IP on STDOUT and sets variable $primary_ip. | |
=cut | |
primary_ip () { | |
local IF=$(netstat -r | awk '$0 ~ /^default/ {print $8}') | |
export primary_ip=$(ifconfig ${IF} | awk '$0 ~ /inet addr:/ { print $2}' | cut -d: -f2) | |
echo $primary_ip | |
} | |
:<<"=cut" | |
=head2 check_dir | |
Check that directory exists. Return expanded PATH of the directory on | |
STDOUT. If not exit with a message and error. | |
Can be used like: | |
# dir=\`check_dir PATH\` | |
=cut | |
check_dir () { | |
test -z "$1" && { echo >&2 "Directory name must be provided"; kill $PARENT; exit 2; } | |
test -d $1 || { echo >&2 "Directory $1 does not exist"; kill $PARENT; exit 1; } | |
(cd $1 && pwd) | |
} | |
:<<"=cut" | |
=head2 check_file | |
Check that file exists. Return expanded PATH of the file on | |
STDOUT. If not exit with a message and error. | |
Can be used like: | |
file=\$(check_file PATH) | |
=cut | |
check_file () { | |
test -z "$1" && { echo >&2 "File name must be provided"; kill $PARENT; exit 2; } | |
test -f $1 || { echo >&2 "File $1 does not exist"; kill $PARENT; exit 1; } | |
echo $1 | |
} | |
# END OF FUNCTIONS | |
export PATH=/bin:/usr/bin:/sbin:/usr/sbin | |
set -e | |
osbreed > /dev/null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment