My team manages many servers, and company policy dictates that the passwords on these servers must be changed every couple of weeks. Sometimes, our official database of passwords gets out of date for whatever reason (people forget to update it, usually), but we cannot identify this sometimes until months later, since we don't consistently use every server.
I want to write a script that will scrape the passwords from the database, and use those passwords to attempt an (ssh) login to each server every night, and send an email with the results to the team. I am able to scrape the database for login information, but I'm not sure how to check whether ssh login was successful or not in expect.
I cannot use public key authentication for this task. I want password authentication so I can verify the passwords.
I disable public-key authentication by specifying the following file:
PasswordAuthentication=yes
PubkeyAuthentication=no
My attempts at the expect script:
# $1 = host, $2 = user, $3 = password, $4 = config file
expect -c "spawn ssh $2@$1 -F $4
expect -re \".*?assword.*?\"
send \"$3\n\"
...
send \'^D\'"
I thought maybe exit status could indicate the success? Couldn't find anything in the man pages though.
I've been using something like the script below for a similar task.
#!/bin/sh
# Run using expect from path \
exec expect -f "$0" "$@"
# Above line is only executed by sh
set i 0; foreach n $argv {set [incr i] $n}
set pid [ spawn -noecho ssh $1@$3 $4 ]
set timeout 30
expect {
"(yes/no)" {
sleep 1
send "yes\n"
exp_continue
}
"(y/n)" {
sleep 1
send "y\n"
exp_continue
}
password {
sleep 1
send "$2\n"
exp_continue
}
Password {
sleep 1
send "$2\n"
exp_continue
}
"Last login" {
interact
}
"Permission denied" {
puts "Access not granted, aborting..."
exit 1
}
timeout {
puts "Timeout expired, aborting..."
exit 1
}
eof {
#puts "EOF reached."
}
}
set status [split [wait $pid]]
set osStatus [lindex $status 2]
set procStatus [lindex $status 3]
if { $osStatus == 0 } {
exit $procStatus
} else {
exit $procStatus
}