3

I have started a new contract, and need to have an active account on almost 200 servers. Security has accounts lock after 30 days of inactivity, as well as if you do not log in within 1 hour of having the account unlocked.

To keep everything from locking up, I would like to create a script that runs through the list of servers, logs in with my username and password, and then logs out.

We are running RHEL 5 on most machines, with a few OEL 6's as well (mostly RHEL5 though).

Googling for the topic keeps bringing me to the SSH keygen topic (which we have/use), but I want my generic account to not get locked out all the time on the other servers, in case of network problems where I have to physically go and log in.

Valadil
  • 131

3 Answers3

4

Instead of scripting your own, I'd recommend using pssh. It's got built-in features for passing the password to ssh, parallellizing the process, error handling and so on. It's a good wheel, no need to invent another one.

Jenny D
  • 13,172
0

RSA keys would be the best solution, however if you cannot use them, you'll need to make some ugly hacks with expect like this:

#!/usr/bin/expect

set timeout 60
#set maxSpawn 20

if { $argc >= 2 } { 
    set user [lindex $argv 0]
    set pass [lindex $argv 1]
    set cmd ""
    for {set i 2} {$i < $argc} {incr i 1} {
        append cmd "[lindex $argv $i] "
    }
    #puts $cmd
} else {
    exit
}

log_user 0 
spawn sh -c "$cmd"
log_user 1

expect {
    "$user:" {
        send "$pass\n"; 
        #exp_continue; 
        expect { 
            "Sorry" { exit }
            "assword:" { send "$pass\n"; exp_continue; }
            "$user: " { send "$pass\n"; exp_continue; }
            timeout { exit }
            eof { exit }
            default { exp_continue; }
        } 
    }
    "assword:" { 
        send "$pass\n"; 
        #exp_continue; 
        expect { 
            "Sorry" { exit }
            "assword:" { send "$pass\n"; exp_continue; }
            "$user: " { send "$pass\n"; exp_continue; }
            timeout { exit }
            eof { exit }
            default { exp_continue; }
        } 
    }
    "(yes/no)?" { 
        send "yes\n"; 
        exp_continue 
    }
    "\[Y/n\]\?" { 
        send "y\n"; 
        exp_continue 
    }
    eof { exit }
    timeout { exit }
    default { exp_continue; }
}

Save it as ssh.exp and run as:

ssh.exp your_username your_password ssh server exit
JJD
  • 577
fazie
  • 2,417
0

I assume you have an user with username as user1 in all the 200 machines.

First, create a public ssh key on your machine, (say machine 1)

ssh-keygen -t rsa

You will be asked for a passphrase which you will be asked to enter the first time you run any ssh command after each login. This means that for multiple ssh or scp commands, you will only have to enter it once. Nevertheless, you can leave it empty to have completely passwordless access.

If you are in a network, all your IP addresses would be available in /etc/hosts.

You can get the list of IP addresses or host names and save it in a file with just the hostnames alone.

My IPlistfile.txt is as below.

192.168.1.11
192.168.1.12

Once you have generated your public key, copy it over (as user1) to each computer in your network.

while read ip; do 
 ssh-copy-id -i ~/.ssh/id_rsa.pub user1@$ip 
done < IPlistfile.txt

You will have to manually enter the password for each IP (unless you use one of the solutions below for this step as well) but once you've done that, you will be able to run the script without using passwords in all those machines.

Now, you can have a script to ssh to all the machines and logging out periodically.

while read ip; do 
 ssh user1@$ip
 exit 
done < IPlistfile.txt

The above script could be placed in a cronjob and could be run periodically to login and logout of servers as you wish without locking the user account.

Please refer to the answer to my question titled script to automate scp in a network and it will give you more ideas.

Ramesh
  • 39,297