Проверка пароля в скрипте bash
Справочная информация: мне нужно скопировать файл с одного сервера на более чем 100 серверов в тестовой среде. после того, как файл скопирован, он требует изменения / проверки прав доступа к файлу. Это все серверы Linux. большинство из них имеют один и тот же пароль для входа, но некоторые не могут.
Мне нужна помощь с созданием цикла в моем скрипте bash. Это на самом деле вызывает Expect. Область, которую я хочу сделать "лучше" или исправить, это несколько вещей
- часть, где он ожидает пароль. (раздел *), он должен выйти из сценария после 1 неудачной попытки ввода пароля и вывести ip в текстовый файл с именем "fail.txt"
- в идеале должна быть часть, которая также сбрасывает ip в файл fail.txt, если нет соединения с сервером.
Я пытался написать часть пароля, думая, что это цикл, но я не совсем уверен, что этот метод мышления имеет смысл. Я попытался просто добавить еще один "ожидаем пароль: ", думая, что если он получит подсказку во второй раз, чтобы выйти, но мне было трудно заставить его работать. Спасибо!
#!/bin/bash
while read ip; do
sleep 2
expect <<- DONE
set timeout 1
spawn scp yoman.txt root@$ip:/felixtemp
if above command fails, dump the IP to fail.txt, otherwise continue
expect yes/no { send yes\r }
expect Password: { send aaaaaa\r } #if this is good, continue the script from *****
else #exit the script
expect Password: { send 033\r }
expect # { send "echo 'password failed'\r" }
&& dump to a text file called fail.txt
***** expect # { send "exit\r\r" }
sleep 1
set timeout 1
spawn ssh root@$ip
sleep 2
expect yes/no { send yes\r }
sleep 2
expect Password: { send aaaaaa\r }
sleep 5
expect # { send "cd /felixtemp\r" }
expect # { send "chown informix:informix yoman.txt\r" }
expect # { send "chmod 775 yoman.txt\r" }
expect # { send "sum yoman.txt | grep 10350 && echo 'transfer good' || echo 'transfer bad'\r" }
expect # { send exit\r }
sleep 1
DONE
done < ip.txt
2 ответа
Если вам нужно управлять сотнями Linux-серверов, вы должны использовать инструмент управления конфигурацией для выполнения этих задач. Очень простой инструмент управления конфигурацией является доступным, единственное требование к управляемой системе - это Python 2.4 или более ( http://docs.ansible.com/intro_installation.html).
Ваша проблема решена с помощью ansible:
1) Определите список хостов, вы можете определить пароль по умолчанию для всех хостов и другой пароль для некоторых хостов
[hosts_list]
172.17.0.101 ansible_ssh_user=root ansible_ssh_pass=password
172.17.0.102 ansible_ssh_user=root ansible_ssh_pass=oldpassword
172.17.0.103
172.17.0.104
[hosts_list:vars]
ansible_ssh_user=root ansible_ssh_pass=default_password
2) Определите простую книгу воспроизведения, содержащую те задачи, которые вы хотите выполнить на управляемых узлах
root@node1:~# cat play.yoman
---
- hosts: hosts_list
tasks:
- name: "Build hosts file"
copy: src=/root/yoman.txt dest=/tmp/felixtemp owner=user group=adm mode=0755
3) Выполните сборник пьес и проверьте результат
root@node1:~# ansible-playbook -i hosts_list play.yoman
PLAY [hosts_list] *************************************************************
GATHERING FACTS ***************************************************************
fatal: [172.17.0.104] => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
fatal: [172.17.0.103] => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
ok: [172.17.0.101]
fatal: [172.17.0.102] => Authentication failure.
TASK: [Build hosts file] ******************************************************
ok: [172.17.0.101]
PLAY RECAP ********************************************************************
to retry, use: --limit @/root/play.yoman.retry
172.17.0.101 : ok=2 changed=0 unreachable=0 failed=0
172.17.0.102 : ok=0 changed=0 unreachable=1 failed=0
172.17.0.103 : ok=0 changed=0 unreachable=1 failed=0
172.17.0.104 : ok=0 changed=0 unreachable=1 failed=0
Вы получите список серверов, на которых выполнено задание, и список серверов, на которых задание не выполнено с причинами (недоступный сервер или неверный пароль). Вы также получаете подмножество сервера, на котором файл, его разрешение и содержимое не были изменены, потому что они уже обновлены
Ни один из предыдущих комментариев не ожидал внутри сценария bash, как запросил OP.
Недавно мне нужно было выполнить аналогичную задачу, поэтому вот мое решение с использованием expect:
expect <<- DONE
set timeout 1
spawn scp yoman.txt root@${ip}:/felixtemp
while 1 {
expect {
"no)?" {
send "yes\n"
}
"denied" {
log_file fail.txt
send_log "Couldn't log in to ${ip}.\n";
exit 1
}
"assword:" {
send "${password}\n"
}
"100%" {
break;
}
}
}
expect eof
DONE
Объяснение синтаксиса expect:
- while 1 {}: создает бесконечный цикл. Внутри цикла я определяю различные ожидаемые случаи.
- log_file fail.txt: создайте файл с именем fail.txt.
- send_log "текст": отправляет текст в файл журнала.
- break: вырывается из бесконечного цикла и завершает ожидаемую секцию.
Почему ты не используешь sshpass
?
Петля со столом:
tab=(
1.2.3.4
4.3.2.1
...
);
for (( i = 1; i < ${#tab[*]}; i++ )) {
echo ${tab[i]};
...
}
Вам понадобятся некоторые условия для определенных IP-адресов, чтобы установить правильный пароль.
SCP
sshpass -p $PASSWORD scp -o StrictHostKeyChecking=no $FILE $USER@$HOST:$PATH
Согласно man-странице, возвращаемые значения:
0 Успех
1 неверный аргумент командной строки
2 приведены противоречивые аргументы
3 Общая ошибка времени выполнения
4 Нераспознанный ответ от ssh (ошибка разбора)
5 Неверный / неверный пароль
6 Открытый ключ хоста неизвестен. sshpass завершает работу без подтверждения нового ключа.
Полезно, если вы хотите напечатать $HOST в файле с возвращаемым значением:
sshpass -p $PASSWORD scp -o StrictHostKeyChecking=no $FILE $USER@$HOST:$PATH
if [ $? -ne 0 ]
then
echo $HOST:$? >> file.txt;
fi
SSH
Чтобы отправить команды:
sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no $USER@$HOST $CMD