проблема
Используя последнюю стабильную сборку Ansible, у меня возникла странная проблема, когда моя playbook зависает на одном сервере во время «Gathering_Facts», но отлично работает на других подобных серверах при использовании Sudo. На сервере Ansible я работаю как мой пользователь (пользователь NIS) и использую sudo (как root) на удаленном сервере для внесения изменений. Если я удаляю Sudo из этой настройки, все работает нормально.
Настроить
Версии программного обеспечения
- ОС : RHEL 6.4
- Ansible версия : ansible 1.8.2
- Судо версия :
Судо версия 1.8.6p3 Плагин политики Sudoers версии 1.8.6p3 Судоеры файл грамматики версия 42 Плагин Sudoers I / O версии 1.8.6p3
- Версия SSH : OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 марта 2010
Карта сервера
-------- User1 @ Server1: sudo -H -S -p (зависает на Gathering_Facts) / User1 @ Ansible ---- \ -------- User1 @ Server2: sudo -H -S -p (работает нормально)
пользователей
- Пользователь1: доступный по NIS пользователь как на Сервере1, так и на Сервере2.
- root: локальный пользователь root для каждого сервера.
Ansible Configuration
Соответствующие части моего ansible.cfg .
ansible.cfg
sudo = true
sudo_user = root
ask_sudo_pass = True
ask_pass = True
...
gathering = smart
....
# change this for alternative sudo implementations
sudo_exe = sudo
# what flags to pass to sudo
#sudo_flags = -H
...
# remote_user = ansible
Вот простой тестовый playbook, чтобы коснуться пустого файла и затем удалить его. На самом деле, я просто хочу проверить, могу ли я заставить Ansible правильно использовать sudo на удаленном сервере. Если пьеса работает, я в хорошей форме.
TEST.yml
---
- hosts: Server1:Server2
vars:
- test_file: '/tmp/ansible_test_file.txt'
sudo: yes
tasks:
- name: create empty file to test connectivity and sudo access
file: dest={{ test_file }}
state=touch
owner=root group=root mode=0600
notify:
- clean
handlers:
- name: clean
file: dest={{ test_file }}
state=absent
Конфигурация Судо
/ и т.д. / sudoers
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
Эта конфигурация sudo прекрасно работает на ОБАХ серверах. Никаких проблем с самой sudo.
Как я все это запускаю
Очень просто:
$ ansible-playbook test.yml Пароль SSH: пароль sudo [по умолчанию пароль SSH]: ИГРАТЬ [Сервер1: Сервер2] ******************************************** ** ФАКТЫ СБОРА ************************************************ *************** хорошо: [Server2] fail: [Server1] => {"failed": true, "parsed": false} Извините, попробуйте еще раз. [sudo via ansible, key = mxxiqyvztlfnbctwixzmgvhwfdarumtq] пароль: sudo: 1 попытка неверного пароля ЗАДАЧА: [создать пустой файл для проверки подключения и доступа sudo] **************** изменено: [Server2] УВЕДОМЛЕНО: [чистый] ********************************************* **************** изменено: [Server2] PLAY RECAP ************************************************* ******************** чтобы повторить попытку, используйте: --limit @ / home / User1 / test.retry Сервер1: нормально = 0 изменено = 0 недоступно = 0 не удалось = 1 Сервер2: хорошо = 3 изменено = 2 недоступно = 0 не удалось = 0
Сбой независимо от того, если я явно ввожу оба пароля SSH / Sudo, а также неявно (позволяя sudo передать значение по умолчанию SSH).
Журналы удаленного сервера
Сервер1 (Сбой)
/ Вар / журнал / безопасный
31 декабря 15:21:10 Server1 sshd [27093]: принят пароль для пользователя User1 от порта xxxx 51446 ssh2 31 декабря 15:21:10 Server1 sshd [27093]: pam_unix (sshd: сеанс): сеанс открыт для пользователя User1 пользователем (uid = 0) 31 декабря 15:21:11 Server1 sshd [27095]: запрос подсистемы для sftp 31 декабря 15:21:11 Server1 sudo: pam_unix (sudo: auth): ошибка аутентификации; logname = User1 uid = 187 euid = 0 tty = / dev / pts / 1 ruser = User1 rhost = user = User1 31 декабря 15:26:13 Server1 sudo: pam_unix (sudo: auth): сбой диалога 31 декабря 15:26:13 Server1 sudo: pam_unix (sudo: auth): auth не удалось идентифицировать пароль для [User1] 31 декабря 15:26:13 Сервер1 sudo: Пользователь1: 1 попытка неверного пароля; TTY = pts / 1; PWD = / home / User1; ПОЛЬЗОВАТЕЛЬ = root; КОМАНДА = / bin / sh -c echo SUDO-SUCCESS-mxxiqyvztlfnbctwixzmgvhwfdarumtq; LANG = C LC_CTYPE = C / usr / bin / python /tmp/.ansible/tmp/ansible-tmp-1420039272.66-164754043073536/setup; rm -rf /tmp/.ansible/tmp/ansible-tmp-1420039272.66-164754043073536/> / dev / null 2> & 1 31 декабря 15:26:13 Server1 sshd [27093]: pam_unix (sshd: сеанс): сеанс закрыт для пользователя User1
Server2 (работает нормально)
/ Вар / журнал / безопасный
31 декабря 15:21:12 Server2 sshd [31447]: принят пароль для пользователя User1 от порта xxxx 60346 ssh2 31 декабря 15:21:12 Server2 sshd [31447]: pam_unix (sshd: сеанс): сеанс открыт для пользователя User1 пользователем (uid = 0) 31 декабря 15:21:12 Server2 sshd [31449]: запрос подсистемы для sftp 31 декабря 15:21:12 Сервер2 sudo: Пользователь1: TTY = pts / 2; PWD = / home / User1; ПОЛЬЗОВАТЕЛЬ = root; КОМАНДА = / bin / sh -c echo SUDO-SUCCESS-vjaypzeocvrdlqalxflgcrcoezhnbibs; LANG = C LC_CTYPE = C / usr / bin / python /tmp/.ansible/tmp/ansible-tmp-1420039272.68-243930711246149/setup; rm -rf /tmp/.ansible/tmp/ansible-tmp-1420039272.68-243930711246149/> / dev / null 2> & 1 31 декабря 15:21:14 Server2 sshd [31447]: pam_unix (sshd: сеанс): сеанс закрыт для пользователя User1
Выход STrace
Вот результат работы strace при нацеливании на команду пользователя root. Команда:
while [[ -z $(ps -fu root|grep [a]nsible|awk '{print $2}') ]]; do
continue
done
strace -vfp $(ps -fu root|grep [a]nsible|awk '{print $2}') -o /root/strace.out`
Сервер1
23650 select (0, NULL, NULL, NULL, {1, 508055}) = 0 (время ожидания) Гнездо 23650 (PF_NETLINK, SOCK_RAW, 9) = 10 23650 fcntl (10, F_SETFD, FD_CLOEXEC) = 0 23650 readlink ("/ proc / self / exe", "/ usr / bin / sudo", 4096) = 13 23650 sendto (10, "| \ 0 \ 0 \ 0L \ 4 \ 5 \ 0 \ 1 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0op = PAM: аутентичные" ..., 124, 0, {sa_family = AF_NETLINK, pid = 0, группы = 00000000}, 12) = 124 23650 опросов ([{fd = 10, события = POLLIN}], 1, 500) = 1 ([{fd = 10, revents = POLLIN}]) 23650 recvfrom (10, "$ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 1 \ 0 \ 0 \ 0b \\\ 0 \ 0 \ 0 \ 0 \ 0 \ 0 | \ 0 \ 0 \ 0L \ 4 \ 5 \ 0 \ 1 \ 0 \ 0 \ 0 "..., 8988, MSG_PEEK | MSG_DONTWAIT, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, [12]) = 36 23650 recvfrom (10, "$ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 1 \ 0 \ 0 \ 0b \\\ 0 \ 0 \ 0 \ 0 \ 0 \ 0 | \ 0 \ 0 \ 0L \ 4 \ 5 \ 0 \ 1 \ 0 \ 0 \ 0 "..., 8988, MSG_DONTWAIT, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, [12]) = 36 23650 закрыть (10) = 0 23650 write (2, «Извините, попробуйте еще раз. \ N», 18) = 18 23650 gettimeofday ({1420050850, 238344}, NULL) = 0 Гнездо 23650 (PF_FILE, SOCK_STREAM, 0) = 10 23650 connect (10, {sa_family = AF_FILE, path = "/ var / run / dbus / system_bus_socket"}, 33) = 0
Сервер2
6625 выберите (8, [5 7], [], NULL, NULL) =? ERESTARTNOHAND (будет перезапущен) 6625 --- SIGCHLD (ребенок вышел) @ 0 (0) --- 6625 записать (8, "\ 21", 1) = 1 6625 rt_sigreturn (0x8) = -1 EINTR (прерванный системный вызов) 6625 select (8, [5 7], [], NULL, NULL) = 1 (в [7]) 6625 читать (7, "\ 21", 1) = 1 6625 wait4 (6636, [{WIFEXITED (s) && WEXITSTATUS (s) == 0}], WNOHANG | WSTOPPED, NULL) = 6636 6625 rt_sigprocmask (SIG_BLOCK, NULL, [], 8) = 0 Гнездо 6625 (PF_NETLINK, SOCK_RAW, 9) = 6 6625 fcntl (6, F_SETFD, FD_CLOEXEC) = 0 6625 readlink ("/ proc / self / exe", "/ usr / bin / sudo", 4096) = 13 6625 sendto (6, "x \ 0 \ 0 \ 0R \ 4 \ 5 \ 0 \ 6 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0op = PAM: session_c" ..., 120, 0, {sa_family = AF_NETLINK, pid = 0, группы = 00000000}, 12) = 120 6625 опрос ([{fd = 6, события = POLLIN}], 1, 500) = 1 ([{fd = 6, revents = POLLIN}]) 6625 recvfrom (6, "$ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 6 \ 0 \ 0 \ 0 \ 330 \ 355 \ 377 \ 377 \ 0 \ 0 \ 0 \ 0x \ 0 \ 0 \ 0R \ 4 \ 5 \ 0 \ 6 \ 0 \ 0 \ 0 "..., 8988, MSG_PEEK | MSG_DONTWAIT, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, [12]) = 36 6625 recvfrom (6, "$ \ 0 \ 0 \ 0 \ 2 \ 0 \ 0 \ 0 \ 6 \ 0 \ 0 \ 0 \ 330 \ 355 \ 377 \ 377 \ 0 \ 0 \ 0 \ 0x \ 0 \ 0 \ 0R \ 4 \ 5 \ 0 \ 6 \ 0 \ 0 \ 0 "..., 8988, MSG_DONTWAIT, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, [12]) = 36 6625 закрыть (6) = 0 6625 open ("/ etc / security / pam_env.conf", O_RDONLY) = 6 6625 fstat (6, {st_dev = makedev (253, 1), st_ino = 521434, st_mode = S_IFREG | 0644, st_nlink = 1, st_uid = 0, st_gid = 0, st_blksize = 4096, st_blocks = 8, st_size = 2980, st_atime) = 2014/12 / 31-16: 10: 01, st_mtime = 2012/10 / 15-08: 23: 52, st_ctime = 2014/06 / 16-15: 45: 35}) = 0 6625 mmap (NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) = 0x7fbc3a59a000 6625 читать (6, "# \ n # Это конфигурация fi" ..., 4096) = 2980 6625 читать (6, "", 4096) = 0 6625 закрыть (6) = 0 6625 munmap (0x7fbc3a59a000, 4096) = 0 6625 open ("/ etc / environment", O_RDONLY) = 6
Мое предположение
Сервер1 не получает пароль правильно или неправильно запрашивает / ждет пароль. Это не похоже на проблему Sudo или Ansible (в одиночку они оба прекрасно работают), но Server1, похоже, не получает учетные данные (или придерживается их) так же, как Server2. Серверы 1 и 2 служат разным целям, поэтому возможно, что они имеют некоторые различия в аутентификации или версии пакета, но оба они были созданы из одного и того же хранилища; следовательно, они не должны быть такими разными.
PAM Auth
Я подумал, что, возможно, системы имеют разные конфигурации PAM, поэтому пароли обрабатываются немного по-разному. Я сравнил файлы /etc/pam.d/ (используя md5sum [file]
), и они одинаковы для двух систем.
тесты
Судо СТДИН
Протестировал еще одну проблему, когда sudo не считывал пароль из STDIN, но это прекрасно работало на обоих серверах.
Тест Судо Ad-Hoc
-bash-4.1 $ ansible Server1 -m файл -a "dest = / tmp / ansible_test.txt state = touch" -sK Пароль SSH: пароль sudo [по умолчанию пароль SSH]: Сервер1 | успех >> { «изменилось»: правда, "dest": "/tmp/ansible_test.txt", "gid": 0, "группа": "корень", «mode»: «0644», "владелец": "корень", «размер»: 0, "состояние": "файл", "UID": 0 }
Успех! Но почему?!
TL; DR
- Server1, похоже, ожидает запроса sudo password, а Server2 работает просто отлично.
- Запуск
ansible
ad-hoc на сервере Server1 работает нормально. Запустить его как playbook не удается.
Вопросов)
- Что может заставить мою конфигурацию Ansible Sudo нормально работать на одном сервере и быть отклоненной на другом?
- По-разному ли Ansible «передает» пароль с локального на удаленный компьютер при запуске ad-hoc и playbook? Я предполагал, что они будут такими же.
Я думаю, что это близко к тому, чтобы просто отправить отчет об ошибке на страницу GitHub исключительно на том факте, что доступ sudo имеет разные результаты, в зависимости от того, запущен ли я ad-hoc или нет.
Используя @lulian в качестве точки опоры в этом ответе, проблема
ansible_sudo_pass:
сводилась к мошеннику, определенному в group_vars, который переопределял введенный пароль--ask-sudo-pass
.Используя следующее:
Я смог найти,
write(4, "{{ password }}\n", 15)
что передается вместо введенного пароля. После некоторого быстрого поиска я действительно нашелansible_sudo_pass
определенные в моих group_vars, которые переопределяли мой введенный пароль.Для всех остальных, как
ansible_sudo_pass:
представляется, определение имеет приоритет,--ask-sudo-pass
который на первый взгляд казался нелогичным. В конце концов, это ошибка пользователя, но методология @ lulian в отладке взаимодействия SSH, а также обнаружение отношений между нимиansible_sudo_pass
и--ask-sudo-pass
должна быть очень полезной для других. (С надеждой!)источник
-e
, и вы можете обойти это, передав соответствующую опцию с-e
.