Используя последнюю стабильную сборку Ansible, у меня возникает странная проблема, когда моя playbook зависает на одном сервере во время "Gathering_Facts", но отлично работает на других подобных серверах при использовании Sudo. На сервере Ansible я запускаю как свой пользователь (пользователь NIS) и использую судо (как root) на удаленном сервере, чтобы внести изменения. Если я удалю Sudo из этой настройки, все будет работать нормально.
Sudo version 1.8.6p3 Sudoers policy plugin version 1.8.6p3 Sudoers file grammar version 42 Sudoers I/O plugin version 1.8.6p3
-------- User1@Server1: sudo -H -S -p (Hangs on Gathering_Facts) / User1@Ansible ---- \ -------- User1@Server2: sudo -H -S -p (Works fine)
Соответствующие части моего 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
Вот простой тестовый сценарий, позволяющий прикоснуться к пустому файлу и затем удалить его. На самом деле, я просто хочу проверить, могу ли я заставить 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 password: sudo password [defaults to SSH password]: PLAY [Server1:Server2] ********************************************** GATHERING FACTS *************************************************************** ok: [Server2] failed: [Server1] => {"failed": true, "parsed": false} Sorry, try again. [sudo via ansible, key=mxxiqyvztlfnbctwixzmgvhwfdarumtq] password: sudo: 1 incorrect password attempt TASK: [create empty file to test connectivity and sudo access] **************** changed: [Server2] NOTIFIED: [clean] ************************************************************* changed: [Server2] PLAY RECAP ******************************************************************** to retry, use: --limit @/home/User1/test.retry Server1 : ok=0 changed=0 unreachable=0 failed=1 Server2 : ok=3 changed=2 unreachable=0 failed=0
Не работает независимо от того, ввожу ли я оба пароля SSH / Sudo явно или неявно (позволяя sudo передавать SSH по умолчанию).
/ var / журнал / безопасный
Dec 31 15:21:10 Server1 sshd[27093]: Accepted password for User1 from x.x.x.x port 51446 ssh2 Dec 31 15:21:10 Server1 sshd[27093]: pam_unix(sshd:session): session opened for user User1 by (uid=0) Dec 31 15:21:11 Server1 sshd[27095]: subsystem request for sftp Dec 31 15:21:11 Server1 sudo: pam_unix(sudo:auth): authentication failure; logname=User1 uid=187 euid=0 tty=/dev/pts/1 ruser=User1 rhost= user=User1 Dec 31 15:26:13 Server1 sudo: pam_unix(sudo:auth): conversation failed Dec 31 15:26:13 Server1 sudo: pam_unix(sudo:auth): auth could not identify password for [User1] Dec 31 15:26:13 Server1 sudo: User1 : 1 incorrect password attempt ; TTY=pts/1 ; PWD=/home/User1 ; USER=root ; COMMAND=/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 Dec 31 15:26:13 Server1 sshd[27093]: pam_unix(sshd:session): session closed for user User1
/ var / журнал / безопасный
Dec 31 15:21:12 Server2 sshd[31447]: Accepted password for User1 from x.x.x.x port 60346 ssh2 Dec 31 15:21:12 Server2 sshd[31447]: pam_unix(sshd:session): session opened for user User1 by (uid=0) Dec 31 15:21:12 Server2 sshd[31449]: subsystem request for sftp Dec 31 15:21:12 Server2 sudo: User1 : TTY=pts/2 ; PWD=/home/User1 ; USER=root ; COMMAND=/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 Dec 31 15:21:14 Server2 sshd[31447]: pam_unix(sshd:session): session closed for user User1
Вот результат работы strace при выборе команды ansible пользователя 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`
23650 select(0, NULL, NULL, NULL, {1, 508055}) = 0 (Timeout) 23650 socket(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:authentic"..., 124, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 124 23650 poll([{fd=10, events=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 close(10) = 0 23650 write(2, "Sorry, try again.\n", 18) = 18 23650 gettimeofday({1420050850, 238344}, NULL) = 0 23650 socket(PF_FILE, SOCK_STREAM, 0) = 10 23650 connect(10, {sa_family=AF_FILE, path="/var/run/dbus/system_bus_socket"}, 33) = 0
6625 select(8, [5 7], [], NULL, NULL) = ? ERESTARTNOHAND (To be restarted) 6625 --- SIGCHLD (Child exited) @ 0 (0) --- 6625 write(8, "\21", 1) = 1 6625 rt_sigreturn(0x8) = -1 EINTR (Interrupted system call) 6625 select(8, [5 7], [], NULL, NULL) = 1 (in [7]) 6625 read(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 socket(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, groups=00000000}, 12) = 120 6625 poll([{fd=6, events=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 close(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 read(6, "#\n# This is the configuration fi"..., 4096) = 2980 6625 read(6, "", 4096) = 0 6625 close(6) = 0 6625 munmap(0x7fbc3a59a000, 4096) = 0 6625 open("/etc/environment", O_RDONLY) = 6
Сервер1 не получает пароль должным образом или неправильно запрашивает / ждет пароль. Это не похоже на проблему Sudo или Ansible (по отдельности они оба работают нормально), но Server1, похоже, не получает учетные данные (или не придерживается их) таким же образом, как Server2. Серверы 1 и 2 служат разным целям, поэтому возможно, что у них есть некоторые различия в аутентификации или версиях пакетов, но они оба были созданы из одного и того же репозитория; следовательно, они не должны ТАК отличаться.
Я подумал, что, возможно, в системах были разные конфигурации PAM, из-за чего пароли обрабатывались немного по-другому. Я сравнил файлы /etc/pam.d/ (используя md5sum [file]
), и они одинаковы для двух систем.
Проверено другая проблема где sudo не считывал пароль из STDIN, но это нормально работало на обоих серверах.
-bash-4.1$ ansible Server1 -m file -a "dest=/tmp/ansible_test.txt state=touch" -sK SSH password: sudo password [defaults to SSH password]: Server1 | success >> { "changed": true, "dest": "/tmp/ansible_test.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "size": 0, "state": "file", "uid": 0 }
Успех! Но почему?!
ansible
"ad-hoc" на Server1 работает нормально. Запускать его как playbook не удается.Я думаю, это приближается к тому, чтобы просто отправить отчет об ошибке на страницу GitHub исключительно потому, что доступ sudo дает разные результаты в зависимости от того, работаю ли я ad-hoc или нет.
Используя @lulian в качестве точки опоры в этом ответе, проблема сводилась к мошенничеству ansible_sudo_pass:
определенный в group_vars, который переопределял пароль, введенный для --ask-sudo-pass
.
Используя следующее:
while [[ -z $(ps -eaf|grep 'sshd: [U]ser1@pts/1') ]]; do
continue
done
strace -ff -vfp $(ps -eaf|grep 'sshd: [U]ser1@pts/1'|awk '{print $2}') -o /root/strace_sshd1_2.out
Я смог найти это write(4, "{{ password }}\n", 15)
передавался вместо введенного пароля. После быстрого поиска я действительно нашел ansible_sudo_pass
определен в моем group_vars, который переопределил введенный мной пароль.
К сведению всех остальных, ansible_sudo_pass:
определение, кажется, имеет приоритет над --ask-sudo-pass
что сначала казалось нелогичным. В конце концов, это ошибка пользователя, но методология @lulian в отладке взаимодействия SSH, а также в обнаружении отношений между ansible_sudo_pass
и --ask-sudo-pass
должен быть очень полезным для других. (С надеждой!)
Что бы я сделал, так это использовать
strace -vfp `pidof sshd`
и посмотрите, где он терпит неудачу.
Также проверьте учетную запись, возможно, она ограничена или что-то в этом роде, но я уверен, что что-то не так с вашим файлом / etc / hosts или он действительно изменился в процессе.