Description ----------- The script seeks to automate administrative tasks on a large number of hosts securely via SSH/SCP. I wrote this because I do not like the large and complex packages like PIKT that do this and much more. This script was simply born out of a need to update security-related RPMs on a large amount of Redhat Linux machines. I did not want to install daemons on all machines for this. The design is simple: The script is given a set of non-root and/or root passwords, a list of remote hosts, a collection of files to copy over (such as RPMs), and a set of scripts to run on the remote hosts. It will attempt to copy all of the needed files and scripts to the remote machine via SCP as a non-root user, SSH in as the non-root user, su to root on the remote machine if applicable, and then execute the scripts you provided. This process is cycled for every host given. su'ing to root can be turned off, and also the tasks can be parallelized in multiple processes. Disclaimer ---------- Because of the nature of this program and that it executes scripts as root, there is the possibility that it may damage your system irreparably. I take no responsibility whatsoever for damage caused by this script. I will say that I have tried to take care of any problem areas in the code I could find, and I use this script without problems in a production environment. My suggestion to you is to test it on unimportant machines first, and ultimately look at and understand the code. Requirements ------------ Expect Perl Module - Get it from CPAN, and any dependencies it needs. I have tested with the following version: http://www.cpan.org/authors/id/R/RG/RGIERSIG/Expect-1.11.tar.gz I found that it required the following modules, and these are the versions I used: http://www.cpan.org/authors/id/GBARR/IO-Tty-0.04.tar.gz http://www.cpan.org/authors/id/AUSCHUTZ/IO-Stty-.02.tar.gz You will of course need the Expect/TCL/TK libraries on your system, which are usually bundled with most Linux distributions. Local and remote hosts must be using OpenSSH. It may work with other SSH's if the prompts are the same but I have not tested. I've tested this on Redhat Linux 6.2, with the same type of remote machines as well as a Solaris 2.7 machine as remote. As long as the remote shell prompts are somewhat standard, it should work with any UNIX platform. Setup ----- This script does NOT support remotely logging in (via SSH) as root. If you do this, stop. There should be a standard account (say admin), which will be used to copy files and su to root. 1. Edit configuration section of script. You may need to modify paths to certain programs (like SSH/SCP). 2. Setup a passwd file This file contains all password information for your hosts. The script must know, or be able to guess, the root password as well as at least 1 working non-root account for each host. See example_passwd.txt for the format of this file. 3. Setup a directory structure DIR that looks like the following: DIR/hosts Plain file containing all hostnames that will be processed. See example_hosts.txt for the format of this file. DIR/files Directory that contains files that are copied to remote host as non-root user. You would put RPMs here for example. DIR/scripts Directory that contains scripts that are copied to remote host as non-root user, and then executed as root. You would put scripts that install RPMs here for example. They can be named anything but should not begin with '.' (hidden files). From your scripts, the files from above will be accessible as: ./files/filename An example script: #!/bin/sh rpm -Fvh ./files/millionth_security_fix.rpm Note that if your scripts create any temporary directories in the current directory tree, for example untarring packages, you need to REMOVE these directories when finished. Otherwise there will be directories owned by root which can't be removed when cleanup is done (which, for safety is done as the non-root user). 4. Run the script: ./remote_update.pl -p PASSWD -d DIR It may be also useful to run the program so you have the script output to a file also: ./remote_update.pl -p PASSWD -d DIR 2>&1 | tee DIR/output.txt 5. Logs for each host are stored as HOSTNAME.log in DIR. This script will not check for errors in your scripts or if they failed to run, so you need to look at the logs. Options ------- -f This will only process a previously failed host. The determination of a failed host is the existence of a hostname.log filename in DIR that contains a line beginning with 'FAILED:'. This is useful if you want to redo an update on just the hosts that failed a previous update. If a .log file doesn't exist for a host, it is considered failed, and it will be processed. -i This will turn on interactive mode. Before each host is processed, you will be prompted. -j # This will set parallel mode with # of processes to use. This will speed up updates quite a bit by splitting the task in multiple processes. The standard output is changed in this case and new files DIR/output.1.txt through DIR/output.#.txt are created with the output of each process sent to those files. It is a little trickier to debug but much faster. -s This will cause the script to not attempt to 'su' on the remote machines. This may be useful if you want to instead call 'sudo' from your scripts. With this option, you do not need to have the root passwords in the password file. -v This will turn on verbose mode. Host output will be sent to standard output. -D This will turn on debug mode. NOTE passwords will be shown on standard output. -P This will turn off sending passwords to SSH/SCP. This is useful if you are using no-passphrase keys. This option applies to all hosts. For specific hosts, use the 'np' flag in the hosts file. Troubleshooting --------------- The script relies heavily on expect/send sequences which are prone to problems. Look at the host logfiles created for clues. Also try using -D to get some more info. NOTE that this will dump passwords to the screen and if using the '-j' option will dump them to the output files! Security Considerations ----------------------- You must secure the passwd file. Having the passwd file in cleartext is a bad idea. I suggest keeping this file encrypted (via GPG for example). Then, when you need to run this script, use your encryption software to provide the decrypted passwd file as standard input via the '-p -' option so you never store the decrypted file on the filesystem. For example, I use a script similar to the following: #!/bin/sh gpg -o - passwd.gpg | ./remote_update.pl -p - -d $1 2>&1 | tee $1/output.txt Bugs and Suggestions -------------------- Send them to valankar@bigfoot.com