Problema
Usando a versão mais recente e estável do Ansible, tenho um problema estranho em que o meu manual fica travado em um servidor durante o "Gathering_Facts", mas funciona bem em outros servidores semelhantes ao usar o Sudo. No servidor Ansible, eu corro como meu usuário (usuário NIS) e uso sudo (como root) no servidor remoto para fazer alterações. Se eu remover o Sudo dessa configuração, tudo funcionará bem.
Configuração
Versões de software
Mapa do servidor
-------- User1@Server1: sudo -H -S -p (Hangs on Gathering_Facts)
/
User1@Ansible ----
\
-------- User1@Server2: sudo -H -S -p (Works fine)
Usuários
- Usuário1: usuário acessível por NIS no Server1 & Server2.
- root: usuário raiz local para cada servidor.
Configuração Ansible
Partes relevantes do meu 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
Aqui está um manual de teste simples para tocar em um arquivo vazio e depois removê-lo. Realmente, estou apenas querendo testar se posso conseguir Ansible para usar corretamente o sudo no servidor remoto. Se a cartilha for executada, estou em boa forma.
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
Configuração do Sudo
/ etc / sudoers
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
Esta configuração do sudo funciona muito bem em ambos os servidores. Nenhum problema com o próprio sudo.
Como eu corro tudo
Muito simples:
$ 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
Falha, independentemente de eu inserir explicitamente ambas as senhas SSH / Sudo e implicitamente (permitindo que o sudo passe o padrão para SSH).
Logs do servidor remoto
Servidor1 (falha)
/ var / log / secure
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
Server2 (funciona bem)
/ var / log / secure
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
Saída do Strrace
Aqui está a saída do strace ao direcionar o comando ansible do usuário root.
Comando:
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'
Server1
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, "|
6625 select(8, [5 7], [], NULL, NULL) = ? ERESTARTNOHAND (To be restarted)
6625 --- SIGCHLD (Child exited) @ 0 (0) ---
6625 write(8, "", 1) = 1
6625 rt_sigreturn(0x8) = -1 EINTR (Interrupted system call)
6625 select(8, [5 7], [], NULL, NULL) = 1 (in [7])
6625 read(7, "", 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
-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
}
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)
Rsudo = 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
---
- 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
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
$ 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
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
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
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, "|
6625 select(8, [5 7], [], NULL, NULL) = ? ERESTARTNOHAND (To be restarted)
6625 --- SIGCHLD (Child exited) @ 0 (0) ---
6625 write(8, "", 1) = 1
6625 rt_sigreturn(0x8) = -1 EINTR (Interrupted system call)
6625 select(8, [5 7], [], NULL, NULL) = 1 (in [7])
6625 read(7, "", 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
-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
}
%pre%%pre%R%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%op=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, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0577%pre%%pre%%pre%%pre%x%pre%%pre%%pre%R%pre%%pre%%pre%%pre%"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
6625 recvfrom(6, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0577%pre%%pre%%pre%%pre%x%pre%%pre%%pre%R%pre%%pre%%pre%%pre%"..., 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
%pre%%pre%L%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%op=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, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%b\%pre%%pre%%pre%%pre%%pre%%pre%|%pre%%pre%%pre%L%pre%%pre%%pre%%pre%"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
23650 recvfrom(10, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%b\%pre%%pre%%pre%%pre%%pre%%pre%|%pre%%pre%%pre%L%pre%%pre%%pre%%pre%"..., 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
op=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, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0577%pre%%pre%%pre%%pre%x%pre%%pre%%pre%R%pre%%pre%%pre%%pre%"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
6625 recvfrom(6, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%0577%pre%%pre%%pre%%pre%x%pre%%pre%%pre%R%pre%%pre%%pre%%pre%"..., 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
%pre%%pre%L%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%op=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, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%b\%pre%%pre%%pre%%pre%%pre%%pre%|%pre%%pre%%pre%L%pre%%pre%%pre%%pre%"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 36
23650 recvfrom(10, "$%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%b\%pre%%pre%%pre%%pre%%pre%%pre%|%pre%%pre%%pre%L%pre%%pre%%pre%%pre%"..., 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
Server2
%pre%
Meu palpite
O servidor1 não está obtendo a senha corretamente ou está solicitando / aguardando uma senha incorretamente. Isso não parece um problema Sudo ou Ansible (sozinhos, ambos funcionam bem), mas o Server1 não parece receber as credenciais (ou aderir a elas) de maneira similar ao Server2. Server1 & 2 servem a propósitos diferentes, então é possível que eles tenham alguma autenticação ou diferenças de versão de pacote, mas ambos foram construídos a partir do mesmo repositório; portanto, eles não deveriam ser diferentes.
Autenticação do PAM
Pensei que talvez os sistemas tivessem configurações PAM diferentes, fazendo com que as senhas fossem tratadas de maneira um pouco diferente. Eu comparei os arquivos /etc/pam.d/ (usando md5sum [file]
), e eles são os mesmos entre os dois sistemas.
Testes
Sudo STDIN
Testado outro problema onde o sudo não lia uma senha de STDIN, mas funcionou bem em ambos os servidores.
Teste Sudo Ad-Hoc
%pre%
Sucesso! Mas por quê?
TL; DR
- O servidor1 parece estar aguardando o prompt de senha sudo enquanto o Servidor2 está funcionando bem.
- A execução de
ansible
"ad-hoc" no Server1 funciona bem. Executá-lo como um manual de jogo falha.
Pergunta (s)
- O que poderia fazer com que minha configuração do Ansible Sudo funcione bem em um servidor e seja rejeitada em outro?
- O Ansible executa a senha "pass" da máquina local para a remota de maneira diferente quando executado ad-hoc versus playbook? Eu assumi que eles seriam os mesmos.
Eu estou pensando que isso está chegando perto de simplesmente enviar um relatório de bug para a página do GitHub puramente sobre o fato de que o acesso do sudo tem resultados diferentes dependendo se eu estou executando ad-hoc ou não.