automatizare ssh cu parole via expect

Titlu alternativ: ce limbaj antic sa mai invat in noaptea asta? :-)

Ma rog, nu e chiar asa, pe de o parte ca Tcl si Expect nu-s chiar atat de antice (ca awk, de exemplu), nici nu m-am jucat prima oara cu Expect aseara si nici nu pot sa zic ca am invatat suficient de bine, daaar...

Reputatia lui Expect e ca se comporta foarte fain pentru automatizarea a diverse chestii interactive, asa ca am scris aseara scriptanul de mai jos care face ssh pe un numar de masini date in linia de comanda si ruleaza o comanda data. Partea simpatica este ca daca nu stie parola intreaba una noua, facand o lista de parole stiute pe care le va incerca pe hosturile urmatoare inainte sa intrebe din nou. Motivul pentru care l-am scris e ca am cateva (multe) zeci de servere pe care trebuie sa verific anumite lucruri si folosesc cateva parole standard daca n-am cheie. Ma rog, are o gramada de buguri pe care le stiu si probabil inca cateva care-mi scapa, dar mi s-a parut o experienta fun de a invata Tcl si Expect (cu ochii pe http://wiki.tcl.tk), asa ca il public si aici, ca exemplu. Probabil ca daca vreau sa-l extind o sa refac parti din el in perl, folosind Expect.pm pentru partea de interactivitate, asa ca mai mult de atat nu ma mai joc cu el.

#!/usr/bin/expect -f
# apt-get install expect if you don't have it
if {![llength $argv]} {
    send_user "please provide space-separated hostlist as argv\n"
    exit
}
#you can preseed the password list like:
#set pwdlist { "mypass" "otherpass" }
set pwdlist { }
send_error "Please provide command to be run on specified hosts:\n  "
expect_user -re "(.*)\n"
set cmd $expect_out(1,string)
#remove first two if you want hostkey checking
set sshopts {
    UserKnownHostsFile=/dev/null
    StrictHostKeyChecking=no
    PubkeyAuthentication=no
    ForwardX11=no
    ForwardAgent=no
}

#add non -o options to ssh
#set ssh_extraopts { -x -a }
set ssh_extraopts {}

foreach opt $sshopts { lappend ssh_extraopts "-o" $opt }

foreach host $argv {
set idx -1
send_user "Trying $host...\n"
eval "spawn -noecho ssh $ssh_extraopts $host \"$cmd\" "
expect "password: " {
  incr idx
  if { $idx == [llength $pwdlist] } {
    stty -echo
    send_error "\n\[LOCAL\] Enter new password or empty to skip:"
    expect_user -re "(.*)\n"
    #this doesn't seem to be needed
    #send_error "\n"
    stty echo
    set newpass $expect_out(1,string)
    if { $newpass == "" } {
        send_error "tried all passwords, giving up.\n"
        continue
    }
    lappend pwdlist $newpass
  }
  send [lindex $pwdlist $idx]
  send "\r"
  exp_continue
} timeout {
  send_error "Error connecting\n"
}

#uncomment in case $cmd is empty to get an interactive command prompt
#interact
}

2 Responses to “automatizare ssh cu parole via expect”

  1. sin Says:

    http://web.taranis.org/shmux/ nu te coafa ?

  2. admin Says:

    Nu.