Сейчас как заавтоматизирую


    Итак, Вам надоело набирать пароли, писать команды, смотреть на скучные обои? А хочется завоевать вселенную и почивать на лаврах? Заставьте роботов трудиться вместо cебя!


    Собираем робота


    Для тренировки терпимости и лояльности, учитель Йода разрешил нам зайти на все 1000 серверов Имперского комитета по разведению Эвоков в условиях невесомости по SSH, вбить руками логин и пароль и проверить кто создал и размер файла /tmp/yoda_is_awesome.txt
    Пишем скрипт который будет набирать пароли и команды за нас. Из предустановленных/легко доставляемых на unix/linux присутствуют: Bash/Shell, Perl, Python.
    Для задачи с SSH в Bash/Perl/Python есть более специализированные модули/программы. А ведь завтра учитель Йода попросит сделать тоже через Telnet, потом sudo echo “Yoda is superman!”. Рассмотрим более общий Expect в связке с Bash, модуль «Expect.pm» для Perl, модуль «pexpect» для Python.
    Листинг скриптов в конце.
    Начинаем медитировать на бегущие строчки:
    
    $ ./sshauto.sh|pl|py 'ls -l /tmp/yoda_is_awesome.txt'
    

    Output:
    
    Password:
    pavlo@10.10.10.10's password:
    -rw-r--r--  1 root root 56 Jul 19  2006 /tmp/yoda_is_awesome.txt
    pavlo@20.20.20.20's password:
    -rw-r--r--  1 root root 56 Jul 19  2006 /tmp/yoda_is_awesome.txt
    pavlo@30.30.30.30's password:
    -rw-r--r--  1 root root 56 Jul 19  2006 /tmp/yoda_is_awesome.txt
    <дальше поглотила бездна>
     

    Медитация закончена. Доделываем напильником «grep» по вкусу.

    Изучаем чужих роботов


    Public key. Разложить на все 1000 серверов «SSH Public key» для своего пользователя. Это трудоемко, и при других условиях (иной пользователь, необходимость использовать sudo,.. .) может оказаться бесполезным.
    cssh (Cluster SSH). Открывает консоли по количеству серверов, и одно дополнительное окошко для выполнения команд на всех серверах одновременно. Хорошее решение для 3 серверов, но не для 1000.
    sshpass. Передача пароля для ssh в открытом виде на STDIN не поддерживается. Но есть например sshpass: `sshpass -p 'PASSWORD' ssh pavlo@10.10.10.10 'ls -l /tmp/temp_file.txt'` который решает эту проблему, но не поможет если потребуется дополнительное sudo или смена пользователя.
    Микроскопы. (CFEngine, Puppet, свой вариант). При условии что он стоит везде. Ему можно и такую задачу поручить. Но это уже не целевое использование, «Забивать гвозди микроскопом».

    Темная сторона


    Ни одно из перечисленных решений не встречалось мне работающим из коробки при обычной установке операционной системы. Для каждого из них требуется установка хотя бы одного пакета.

    Захват галактики


    Здесь приводиться примеры реализации/использования «Expect» на Bash, Perl, Python.
    Требования к скрипту:
    a. ip_addresses.txt — файл со списком всех IP адресов.
    b. пароль должен вводиться при старте скрипта в скрытом виде.

    BASH
    Требуется установка: expect
    
    $ cat ./sshauto.sh
    #!/bin/bash
    echo -n "Password:"
    read -s passw; echo
    stty echo
    while read IP
    do
    ./sshlogin.exp $passw $IP "$1" 2> /dev/null
    done < ip_addresses.txt
    
    $ cat ./sshlogin.exp
    #!/usr/bin/expect -f
    set password [lrange $argv 0 0]
    set ip_address [lrange $argv 1 1]
    set command [lindex $argv 2]
    spawn ssh -q -t -o StrictHostKeyChecking=no pavlo@$ip_address $command 
    expect "*?assword:*"
    send -- "$password\r"
    expect eof
    


    PERL
    Требуется установка модулей: Expect, Term::ReadKey
    
    $ cat ./sshauto.pl
    #!/usr/bin/perl
    use Expect;
    use Term::ReadKey;
    print "Password:";
    ReadMode 'noecho';
    $password = ReadLine(0);
    chomp($password);
    print "\n";
    ReadMode 'normal';
    $command = $ARGV[0];
    open (IP_list, 'ip_addresses.txt');
    foreach $IP (<IP_list>) {
        chomp($IP);
        $cli = "/usr/bin/ssh -q -t -o StrictHostKeyChecking=no et0362\@$IP  $command";
        $exp = new Expect;
        $exp->raw_pty(1);
        $exp->spawn($cli) or die "Cannot spawn $cli: $!\n";
        $exp->expect(5, [ qr /ssword:*/ => sub { my $exph = shift; $exph->send("$password\n"); exp_continue; }] );
    };
    close (IP_list);
    


    Python
    Требуется установка модуля: pexpect
    
    $ cat ./sshauto.py
    #!/usr/bin/python
    import pexpect
    import getpass
    import sys
    command = sys.argv[1]
    password = getpass.getpass()
    IP_list = open('ip_addresses.txt')
    IP = IP_list.readline()
    while IP:
        print IP,
        cli="ssh pavlo@%s %s" % (IP,command)
        exp = pexpect.spawn(cli)
        exp.expect('password:')
        exp.sendline(password)
        exp.expect(pexpect.EOF)
        print exp.before
        IP = IP_list.readline()
    IP_list.close()
    

    Ну вот и всё. Удачных Вам свершений на ниве автоматизации.

    *В статье использовалась картинка отсюда
    Инфопульс Украина
    Creating Value, Delivering Excellence
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 13

      0
      У меня роботы даже в игрушки за меня играют :)
        –3
        Тьфу! Нашли чем гордиться.
          0
          он не гордится, просто «он настолько суров» (с)
          +1
          — Так вы что, и конфеты за меня есть будете?!..
          — АГА!!!
          «Вовка в тридевятом царстве» 1965г.
          +1
          while read IP
          do
          ./sshlogin.exp $passw $IP "$1" 2> /dev/null
          done < ip_addresses.txt


          Ускоряем процесс в N раз.
          N=20 # для примера
          cat ip_addresses.txt | xargs -l1 -I\1 -P${N} ./sshlogin.exp $passw \1 "$1"
            +8
            Вы всегда обманываете учителя? Вам велели не умничать заниматься автоматизацией, а зайти на 1000 серверов, и вбить руками логин и пароль. Возможно, смысл смыслом задания было — извлечь пользу из авторизации по ключам? Тогда Вы обманули и учителя, и себя.
              +1
              Учителей нужно слушать и быть честным :). По поводу ключей. SSH RSA/DSA ключи хорошо когда все делается только от имени обычного пользователя и простые команды. Но если необходимо выполнить дополнительно sudo <команда> (запрос пароля) или обычная команда в ответ попросит что то ввести, ключи в этом не помогу. В статье упрощенный вариант. Пару дополнительных строк, решает вопрос с sudo:
              expect "*?assword:*"
              send -- "$password\r"
              expect "*?assword*"
              send -- "$password\r"

              Хотя можно пройти по всем серверам и отключить запрос пароля в sudo, а еще проще разрешить логинится по ssh от имени root :).
              0
              Да, вот хоть и работаю не под Линуксом, всегда уважал эту платформу за возможность легко делать такие вещи. Наверное, под другими ОС это тоже возможно, было бы интересно почитать статью и на эту тему.
                0
                Под виндой такие штуки тоже легко реализуются с помощью powershell или vbscript.
                  0
                  это не «под линуксом», это expect — специальный язык для организации диалогов с чем-то, что любит задавать вопросы. Expect можно гонять где угодно, не только под Линуксом.
                    0
                    модуль expect под питон до сих пор недоступен для windows платформ (пытался pip install expect)…
                      0
                      Лол, там же написано import pexpect. pip install pexpect.
                  +2
                  Kerberos…

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое