LINUX.ORG.RU
ФорумAdmin

SSH команда на несколько серверов


0

1

Прошу помочь

Исходные данные:
- есть локальная линукс машина
- есть много удаленных серверов на которые есть доступ по SSH
- на все удаленные сервера можно ходить только по паролю
- на всех серверах невозможно внести изменения в sudoers так что бы sudo команды выполнять можно было выполнять без пароля

Задача:
- Выполнить на всех удаленных серверах одну и ту же команду с под рута не вводя при этом пароля ни на подключения ни на sudo (что бы каждый сервер не спрашивал пароли)

Наработки:
Ну как всем известно если бы не пароли и судо можно было бы выполнить через «for i in 10.10.48.{101..104}; do ssh " » Но это нам не подходит. Есть возможность использовать следующую конструкцию.

########
#!/usr/bin/expect

set password 123456
set first_command sudo\ \su
set root_command uname
set servers 10.10.48.20

spawn ssh $servers

expect «yes/no» {
send «yes\r»
expect «*?assword» { send «$password\r» }
} «*?assword» { send «$password\r» }

expect «$ » { send «$first_command\r» }
expect ": " { send «$password\r» }
expect «# » { send «$root_command\r» }
interact

########

Но так как в синтаксисе интерпритатора Expect нет for i in .... а как я понял нормально переменой диапазон апишек не присвоишь то соответственно упираемся в тупик.
Как решить задачу ?

Но так как в синтаксисе интерпритатора Expect

Это TCL, учи его

sdio ★★★★★ ()

Я вот не понимаю, почему все так стремятся именно выполнить команду на куче удалённых серверов? Ведь в конце концов требуется только что бы она была выполнена. А каким образом не важно.

При этом все почему-то старательно игнорируют опыт многомилионных ботнетов.

А что если ты заведёшь в кроне (на каждой машине) скрипт, который будет раз в минуту ломиться на некоторый адрес и выкачивать список команд. Там же в кроне указывается почтовый адрес, на который отправится результат.

У себя поднимаешь web серверок, который будет отдавать команды и почтового робота, который будет парсить ответы. Можно это всё завязать на какую-нибудь БД.

Все команды/ответы естественно в машиночтаемом формате (csv, например).

Соответственно цикл такой:

  • машинка получает список команд. Находит по времени (поле в файле) ещё не исполненную;
  • выполняет по-очереди от имени юзера (поле в файле), выводя результаты;
  • крон сам отсылает вывод (или ошибку, если всё пошло не так);
  • робот парсит отчёт и предоставляет тебе некоторые результаты;
  • ...
  • PROFIT!
ziemin ★★ ()

Как вариант for i in можно прописать в sh скрипте, из которого вызывать потом скрипт expect. Например:
Sh script:

#!/bin/sh
for i in 10.10.48.{101..104}; 
do 
ssh.exp $i;
done
Expect script:

#!/usr/bin/expect 

set password 123456 
set first_command sudo\ \su 
set root_command uname 
set servers [lindex $argv 0] 

spawn ssh $servers 

expect «yes/no» { 
send «yes\r» 
expect «*?assword» { send «$password\r» } 
} «*?assword» { send «$password\r» } 

expect «$ » { send «$first_command\r» } 
expect ": " { send «$password\r» } 
expect «# » { send «$root_command\r» } 
interact 

menzoberronzan ()

Ну и ziemin дело говорит, лично я конструкцию из expect + ssh использовал один раз для того чтобы поставить puppet на все машины. А затем все прекрасно рулится через puppet.

menzoberronzan ()
$ aptitude show mussh
..............
Description: MUltihost SSH Wrapper
 Mussh is a shell script that allows you to execute a command or script over ssh
 on multiple hosts with one command.  When possible mussh will use ssh-agent and
 RSA/DSA keys to minimize the need to enter your password more than once. 
 
 Unlike clusterssh or mssh, mussh is just a shell script wrapper for ssh with
 concurrency support.  It is intended to make running identical commands or
 scripts on almost any number of hosts possible with minimal overhead.  There is
 no GUI and the only language used is bash.
Homepage: http://mussh.sourceforge.net/

$ aptitude show pssh
...........
Description: Parallel versions of SSH-based tools
 pssh provides a number of commands for executing against a group of computers,
 using SSH. It's most useful for operating on clusters of
 homogenously-configured hosts. 
 
 The package contains: 
 
 * Parallel ssh (parallel-ssh, upstream calls it pssh), executes commands on
   multiple hosts in parallel 
 * Parallel scp (parallel-scp, upstream calls it pscp), copies files to multiple
   remote hosts in parallel 
 * Parallel rsync (parallel-rsync, upstream calls it prsync), efficiently copies
   files to multiple hosts in parallel 
 * Parallel nuke (parallel-nuke, upstream calls it pnuke), kills processes on
   multiple remote hosts in parallel 
 * Parallel slurp (parallel-slurp, upstream calls it pslurp), copies files from
   multiple remote hosts to a central host in parallel 
   
 These tools are good for controlling large collections of nodes, where faster
 alternatives such as gexec and pcp are not available.
Homepage: http://code.google.com/p/parallel-ssh/
imb ★★ ()

Ansible

Имхо лучше сразу привыкать к хорошему. Используй ansible, мало того что эта штука может работать как выполнялка задач на куче серверов, она ещё умеет сценарии, роли и т.п.

Как установить гугл подскажет, я подскажу как сделать то что тебе надо:

создаём файл hosts со списком хостов (оф. доки):

[myservers]
10.10.48.101 ansible_sudo_pass=blabla ansible_ssh_user=masterserg
10.10.48.102 ansible_sudo_pass=blabla ansible_ssh_user=masterserg
10.10.48.103 ansible_sudo_pass=blabla ansible_ssh_user=masterserg
10.10.48.104 ansible_sudo_pass=blabla ansible_ssh_user=masterserg

Желательно на узлы раскидать публичный ключ и ходить через него, а не каждый раз ходить по паролю. Если и по ключам нельзя, то в hosts нужно добавить ещё параметр ansible_ssh_pass. Если нужно именно несолько задач выполнить, то лучше сразу использовать ansible-playbook, по-русски на хабре. Теперь делаем всё что нужно от рута:

$ ansible myservers -i hosts -s -m shell -a "whoami"
$ ansible myservers -i hosts -s -m shell -a "dig +trace ya.ru >> /tmp/dig_output.txt"

Где

  • myservers - группа хостов в файле hosts
  • -i hosts - говорим где брать файл со списком хостов
  • -s - для выполнения команд/задач используем sudo (по умолчанию от рута, но можно и другого пользователя задать)
  • -m shell - используем модуль shell, в аргументах принимает команду, которую нужно выполнить

Есть дёгтя ложка - на удалённых узлах должен присутствовать хоть какой-то интерпретатор python'а, если нет, то можно попробовать использовать модуль raw вместо shell

Если освоить ansible (буквально потратить вечер), то потом не будет возникать вопросов как сделать что-нибудь на куче узлов с логированием и получением статуса выполненых задач. Использование ansible не является «пушкой по воробьям», это очень хороший инструмент для работы с серверами если их больше одного.

technoid ()
Ответ на: комментарий от ziemin

Я вот не понимаю, почему все так стремятся именно выполнить команду на куче удалённых серверов? Ведь в конце концов требуется только что бы она была выполнена. А каким образом не важно.

Потому что ты мыслишь примитивными понятиями. Серверы могут быть за файерволами (DMZ) и доступ к ним есть только однонаправленный с системы мониторинга, например. Кроме того если письмо не пришло, что это значит? команда не была выполнена или письмо не дошло? Надо идти проверять, потеряно время.

И "бот" должен под рутом быть запущен, да?

sdio ★★★★★ ()
Последнее исправление: sdio (всего исправлений: 1)
Ответ на: комментарий от sdio

Потому что ты мыслишь примитивными понятиями.

И где ты это вычитал в первом параграфе? Дальше я один из возможных вариантов привожу.

ziemin ★★ ()
Ответ на: комментарий от ziemin

Потому что ваши фантазии никак не коррелируют с вопросом. Если бы он мог, уже сделал бы авторизацию по ключу и sudo без запроса пароля.

sdio ★★★★★ ()

Если вас не смущает GUI, то используйте pacmanager. Его и скриптовать можно, и просто из гуя в кластер несколько коннектов объединить и комманды выполнять.

ValdikSS ★★★★★ ()

masterserg О юный падаван, о подтверждении исполнения задачи забываешь ты. Ибо команду отправить несложно будет. А вот анализ исполнения провести важнее будет.

MikeDM ★★★★★ ()
Ответ на: комментарий от ziemin

UUCP изобрели гораздо раньше интернета, но по IP оно хуже работать не стало.

ABW ★★★★★ ()
Ответ на: комментарий от menzoberronzan

Спасибо действительно помогло

Получилась вот такая конструкция

Стартовый скрипт запускается ./run > log (это на вопрос как логи писать) Но может у кого то есть более толковые идеи как возможно сразу в скрипте забит так что он в файлик писал логи ?

#!/bin/sh 

password=12345678 
root_command=uname 

echo; 
for servers in 10.10.10.{96..97}; 
do 
./main $servers $password $root_command; 
echo;  
done 


 Обращается к второму скрипту 
#!/usr/bin/expect 

set servers [lindex $argv 0] 
set password [lindex $argv 1] 
set first_command sudo\ \su 
set root_command [lindex $argv 2] 


spawn  ssh  $servers 
 
expect "yes/no" { 
    send "yes\r" 
    expect "*?assword" { send "$password\r" } 
    } "*?assword" { send "$password\r" } 

expect "$ " { send "echo '###########' && hostname && echo  '###########' &&  $first_command\r" }
expect ": " { send "$password\r" }  
expect "# " { send "$root_command && sleep 1 && exit\r" } 
expect "$ " { send "exit\r" } 
interact 


Небольшие пояснения к тем возгласам что надо было использовать всякие плюшки фирменные и давно написанные , если коротко то нет такой возможности, использовать надо только базовый функционал.
masterserg ()
Ответ на: комментарий от masterserg

Нет возможность установить на машину ничего.

На целевые машины ничего не надо ставить, ставь с которой работаешь.

tazhate ★★★★★ ()
Ответ на: комментарий от tazhate

зайти по ssh легко как минимум есть sshpass, а как без expect дать пароль sudo если ничего нельзя менять?

sdio ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.