#!/bin/bash # This script will configure a pair of DreamHost uses to be used as 'web/user' users # as described by the Best Practice documents here: http://toddgee.com/node/5 # and here: http://toddgee.com/node/23 # # This script is only intended for setting up two brand new users and should # be run by the 'master' user. The "master" user is the user that owns the bin directory. # This script is not intended to be used when the "user" user is the "master" user. # # NOTE: this script was originally intended to create and THEN setup the users; but the # DreamHost API does not provide for the creation of users. Users will have to be created # as noted here first and then the script run to configure them. # # NOTE: This script requires that 'expect' be installed. If this script is not available on # your machine, contact DH support and they'll install it for you. # # NOTE: This script cannot be run more than once for a pair of users. # # This script performs the operations performed by the 'fixSlave.sh' script on both users. # # Users are managed from the DH Panel page: https://panel.dreamhost.com/index.cgi?tree=users.users # Two users have to be created, their names should take the form "foo_user" and "foo_web" for the # 'user' user and the 'web' user respectively. "foo" should be replaced with some token that is # appropriate for the conext. # # The two users should be created with the following properties (as entered on the DreamHost panel page): # # Type of User Account: Shell # Shell Type: bash # Username: (as above) # Enhanced security?: No/unchecked # Full Name: " <'web' or 'user'>" # Pick a password for me: No/unchecked # Password: "wordpass" (without quotes) # Password Again: "wordpass" (again) # # Submit this information. Once created, edit the user again and make the following changes: # Disallow FTP?: Yes/checked # and submit again. (This option not available on first screen.) # USER_STARTING_PASSWORD="wordpass" printUsage() { echo -e " " echo -e "Usage:" echo -e "$0 <'user' user> <'web' user> " echo -e " " echo -e "Script should be run by the 'master' user." echo -e "For more info, see script header." echo -e " " echo -e "<'user' user>" echo -e "\tThe 'user' user of the _user/_web pair. Ends in '_user'" echo -e "<'web' user>" echo -e "\tThe 'web' user of the _user/_web pair. Ends in '_web'" echo -e "" echo -e "\tThe public key file of the master user." echo -e "\tWill be installed in the authorized_keys file for the 'user' user." echo -e "\tE.g. '~/.ssh/id_rsa.localhost.pub'" echo -e " " } # Calls runSSHOutput() but pipes all output to /dev/null # Same parameters, same usage. runSSH() { user="${1}" script="${2}" nopassword="${3}" runSSHOutput "${user}" "${script}" "${nopassword}" > /dev/null } # A function to run a script as another user on a remote machine using expect. # Assumes the password is USER_STARTING_PASSWORD, above # Outputs only the last line of the output. # $1 - User to run as # $2 - Script # $3 - If supplied/non-empty, will use just a ssh call rather than using expect. # This should be used after keys are installed. runSSHOutput() { user="${1}" script="${2}" nopassword="${3}" if [ -z "${nopassword}" ]; then expect -c "spawn ssh ${user}@localhost \"${script}\"" -c "expect password:" -c "send ${USER_STARTING_PASSWORD}\n" -c "expect eof" | tail -1 else ssh ${user}@localhost "${script}" fi } ######### # Param handling if [ $# -eq 0 ]; then printUsage exit 0 fi echo " " # Save and validate user names userUser="${1}" webUser="${2}" if [ -z "${userUser}" -o -z "${webUser}" ]; then echo -e "** user/web users must be specified. Aborting.\n" printUsage exit 1 fi if [ -z "`id -u "${userUser}" 2>/dev/null`" ]; then echo -e "** 'user' user does not exist. Aborting.\n" printUsage exit 1 fi if [ -z "`id -u "${webUser}" 2>/dev/null`" ]; then echo -e "** 'web' user does not exist. Aborting.\n" printUsage exit 1 fi # Validate master user's ssh public key masterPublicKeyFile="${3}" if [ ! -f "${masterPublicKeyFile}" ]; then echo -e "** Specified public key file '${masterPublicKeyFile}' does not exist. Aborting.\n" printUsage exit 1 fi # Ensure 'expect' exists if [ -z "`which expect`" ]; then echo -e "** 'expect' binary not found in PATH. (See script header.) Aborting.\n" exit 1 fi ######### echo "Setting up user/web pair users: '${userUser}'/'${webUser}'." echo "This will clobber the .ssh directories of both users and munge their 'bin' directories." echo "Press to continue, or ^C to quit..." read ## Set up webroot directory echo -n "Adding group write permission to web user home dir.... " runSSH "${webUser}" "chmod g+w ~" echo "done." echo -n "Creating webroot directory.... " runSSH "${userUser}" "cd ~${webUser}; mkdir -p webroot/drupal; chmod 0751 webroot; chmod 0751 webroot/drupal; cd; ln -s ~${webUser}/webroot ." echo "done." echo -n "Resetting web user home dir permissions.... " runSSH "${webUser}" "chmod g-w ~" echo "done." ## Set up ssh keys echo -n "Creating public key pair for 'user' user.... " runSSH "${userUser}" "rm -rf .ssh; mkdir -p .ssh; chmod 0700 .ssh; cd .ssh; ssh-keygen -f 'id_rsa.localhost' -N '' -C 'user ${userUser} key for localhost usage'" echo "done." echo -n "Creating ssh 'config' file for 'user' user.... " runSSH "${userUser}" "cd .ssh; echo -e 'Host localhost' >> config; echo -e '\tIdentityFile ~/.ssh/id_rsa.localhost' >> config; echo '' >> config; echo -e 'Host backup.dreamhost.com' >> config; echo -e '\tIdentityFile ~/.ssh/id_rsa.localhost' >> config; echo '' >> config; chmod 0600 config" echo "done." echo -n "Creating authorized_keys file for 'user' user.... " masterPublicKey="`cat "${masterPublicKeyFile}"`" runSSH "${userUser}" "cd .ssh; echo -e '${masterPublicKey}' > authorized_keys; chmod 0600 authorized_keys" echo "done." echo -n "Retriving 'user' user public key file.... " userUserPublicKey="`runSSHOutput "${userUser}" "cat ~/.ssh/id_rsa.localhost.pub" "foo"`" echo "done." echo -n "Creating authorized_keys file for 'web' user.... " runSSH "${webUser}" "rm -rf .ssh; mkdir -p .ssh; chmod 0700 .ssh; cd .ssh; echo -e '${userUserPublicKey}' > authorized_keys; chmod 0600 authorized_keys" echo "done." ## Do fixSlave.sh stuff masterUser="${USER}" cmd="/bin/rm -f ~/.bashrc ~/.bash_profile ~/.bash_logout; cd; ln -s /home/${USER}/.bashrc .; ln -s /home/${USER}/.bash_profile .; ln -s /home/${USER}/.bash_logout .; mkdir -p ~/bin; cd ~/bin; /bin/rm -f ./master; ln -s /home/${USER}/bin ./master" echo -n "Creating links to master account for 'user' user.... " runSSH "${userUser}" "${cmd}" "foo" echo "done." echo -n "Creating links to master account for 'web' user.... " runSSH "${webUser}" "${cmd}" echo "done." echo -n "Creating 'sshweb' script for 'user' user.... " runSSH "${userUser}" "cd bin; echo 'ssh ${webUser}@localhost' > sshweb; chmod 0700 sshweb" "foo" echo "done." ## Create backup directory for the user user echo -n "Creating backup directory for 'user' user.... " runSSH "${userUser}" "mkdir -p ${userUser}.backups; chmod 0700 ${userUser}.backups" "foo" echo "done." echo -e "\n** At this point, you should set the passwords for users '${userUser}' and '${webUser}'" echo -e "to long, random, un-usable strings of characters." echo -e "\n** Done."