Ansible non riesce ad autenticare il Sudo anche quando viene concesso il Sudo Pass


9

Problema

Utilizzando l'ultimo, stabile Ansible build, ho un problema strano in cui il mio playbook si blocca su un server durante "Gathering_Facts" ma funziona bene su altri server simili quando si utilizza Sudo. Sul server Ansible, corro come il mio utente (utente NIS) e utilizzo sudo (come root) sul server remoto per apportare modifiche. Se rimuovo Sudo da questa configurazione, tutto funziona bene.

Impostare

Versioni del software

  • Sistema operativo : RHEL 6.4
  • Versione ansible: ansible 1.8.2
  • Versione Sudo :
    Versione Sudo 1.8.6p3
    Plugin per le policy dei sudatori versione 1.8.6p3
    Grammatica dei file dei sudatori versione 42
    Plugin I / O Sudoers versione 1.8.6p3
    
  • Versione SSH : OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 mar 2010

Mappa del server

                   -------- User1 @ Server1: sudo -H -S -p (si blocca su Gathering_Facts)
                  /
Utente1 @ Ansible ----
                  \
                   -------- User1 @ Server2: sudo -H -S -p (funziona bene)

utenti

  • Utente1: utente accessibile NIS su Server1 e Server2.
  • root: utente root locale per ciascun server.

Configurazione sensibile

Parti rilevanti del mio 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

Ecco un semplice playbook di prova per toccare un file vuoto e quindi rimuoverlo. Davvero, voglio solo provare se riesco a ottenere Ansible per usare correttamente sudo sul server remoto. Se il playbook funziona, sono in buona 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

Configurazione Sudo

/ etc / sudoers

Host_Alias SRV     = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL

Questa configurazione sudo funziona perfettamente su ENTRAMBI i server. Nessun problema con lo stesso sudo.

Come eseguo tutto

Molto semplice:

$ ansible-playbook test.yml
Password SSH: 
sudo password [impostazione predefinita password SSH]:

PLAY [Server1: Server2] ********************************************** ** 

FATTI DI RIUNIONE ************************************************** *************** 
ok: [Server2]
failed: [Server1] => {"failed": true, "parsed": false}

Mi dispiace riprova.
[sudo via ansible, key = mxxiqyvztlfnbctwixzmgvhwfdarumtq] password: 
sudo: 1 tentativo di password errato


COMPITO: [crea un file vuoto per testare la connettività e l'accesso sudo] **************** 
modificato: [Server2]

NOTIFICATO: [pulito] *********************************************** **************** 
modificato: [Server2]

RIPRODUCI GIOCO ************************************************** ******************** 
           per riprovare, utilizzare: --limit @ / home / User1 / test.retry

Server1: ok = 0 modificato = 0 non raggiungibile = 0 non riuscito = 1   
Server2: ok = 3 modificato = 2 non raggiungibile = 0 non riuscito = 0

Non riesce a prescindere se inserisco esplicitamente sia le password SSH / Sudo che implicitamente (lasciando sudo passare automaticamente a SSH).

Registri del server remoto

Server1 (errore)

/ Var / log / secure

31 dic 15:21:10 Server1 sshd [27093]: password accettata per User1 dalla porta xxxx 51446 ssh2
31 dic 15:21:10 Server1 sshd [27093]: pam_unix (sshd: session): sessione aperta per l'utente User1 da (uid = 0)
31 dic 15:21:11 Server1 sshd [27095]: richiesta del sottosistema per sftp
31 dic 15:21:11 Server1 sudo: pam_unix (sudo: auth): errore di autenticazione; logname = User1 uid = 187 euid = 0 tty = / dev / pts / 1 ruser = User1 rhost = user = User1
31 dic 15:26:13 Server1 sudo: pam_unix (sudo: auth): conversazione fallita
31 dic 15:26:13 Server1 sudo: pam_unix (sudo: auth): auth non è riuscito a identificare la password per [Utente1]
31 dic 15:26:13 Server1 sudo: User1: 1 tentativo di password errato; TTY = pts / 1; PWD = / home / Utente1; USER = root; COMANDO = / 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 dic 15:26:13 Server1 sshd [27093]: pam_unix (sshd: session): sessione chiusa per l'utente User1 

Server2 (funziona bene)

/ Var / log / secure

31 dic 15:21:12 Server2 sshd [31447]: password accettata per User1 dalla porta xxxx 60346 ssh2
31 dic 15:21:12 Server2 sshd [31447]: pam_unix (sshd: session): sessione aperta per l'utente User1 da (uid = 0)
31 dic 15:21:12 Server2 sshd [31449]: richiesta del sottosistema per sftp
31 dic 15:21:12 Server2 sudo: User1: TTY = pts / 2; PWD = / home / Utente1; USER = root; COMANDO = / 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 dic 15:21:14 Server2 sshd [31447]: pam_unix (sshd: session): sessione chiusa per l'utente User1 

Uscita STrace

Ecco l'output di strace quando si sceglie come target il comando ansible dell'utente 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 seleziona (0, NULL, NULL, NULL, {1, 508055}) = 0 (Timeout)
Presa 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: autentico" ..., 124, 0, {sa_family = AF_NETLINK, pid = 0, gruppi = 00000000}, 12) = 124
23650 sondaggio ([{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, gruppi = 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, gruppi = 00000000}, [12]) = 36
23650 chiuso (10) = 0
23650 scrivi (2, "Siamo spiacenti, riprova. \ N", 18) = 18
23650 gettimeofday ({1420050850, 238344}, NULL) = 0
Presa 23650 (PF_FILE, SOCK_STREAM, 0) = 10
23650 connect (10, {sa_family = AF_FILE, path = "/ var / run / dbus / system_bus_socket"}, 33) = 0

Server2

6625 seleziona (8, [5 7], [], NULL, NULL) =? ERESTARTNOHAND (da riavviare)
6625 --- SIGCHLD (Bambino uscito) @ 0 (0) ---
6625 write (8, "\ 21", 1) = 1
6625 rt_sigreturn (0x8) = -1 EINTR (chiamata di sistema interrotta)
6625 seleziona (8, [5 7], [], NULL, NULL) = 1 (in [7])
6625 letto (7, "\ 21", 1) = 1
6625 wait4 (6636, [{WIFEXITED (s) && WEXITSTATUS (s) == 0}], WNOHANG | WSTOPPED, NULL) = 6636
6625 rt_sigprocmask (SIG_BLOCK, NULL, [], 8) = 0
Presa 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, gruppi = 00000000}, 12) = 120
6625 sondaggio ([{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, gruppi = 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, gruppi = 00000000}, [12]) = 36
6625 chiuso (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 letto (6, "", 4096) = 0
6625 chiuso (6) = 0
6625 munmap (0x7fbc3a59a000, 4096) = 0
6625 aperto ("/ etc / environment", O_RDONLY) = 6

La mia ipotesi

Server1 non riceve correttamente la password o chiede / attende erroneamente una password. Questo non sembra un problema di Sudo o Ansible (da soli, funzionano entrambi bene), ma Server1 non sembra ricevere le credenziali (o aderire ad esse) in modo simile a Server2. Server1 e 2 hanno scopi diversi, quindi è possibile che presentino alcune differenze di autenticazione o versione del pacchetto, ma entrambi sono stati creati dallo stesso repository; pertanto, non dovrebbero essere così diversi.

PAM Auth

Ho pensato che forse i sistemi avevano diverse configurazioni PAM che causavano una gestione un po 'diversa delle password. Ho confrontato i file /etc/pam.d/ (usando md5sum [file]), e sono gli stessi tra i due sistemi.

test

Sudo STDIN

Testato un altro problema in cui sudo non leggeva una password da STDIN, ma funzionava bene su entrambi i server.

Prova il Sudo Ad-Hoc

-bash-4.1 $ ansible Server1 -m file -a "dest = / tmp / ansible_test.txt state = touch" -sK
Password SSH: 
sudo password [impostazione predefinita password SSH]: 
Server1 | successo >> {
    "cambiato": vero, 
    "dest": "/tmp/ansible_test.txt", 
    "gid": 0, 
    "group": "root", 
    "mode": "0644", 
    "proprietario": "root", 
    "dimensione": 0, 
    "state": "file", 
    "uid": 0
}

Successo! Ma perché?!

TL; DR

  1. Server1 sembra essere in attesa al prompt della password sudo mentre Server2 funziona correttamente.
  2. L'esecuzione ansible"ad-hoc" su Server1 funziona correttamente. L'esecuzione come un playbook non riesce.

Domande)

  • Cosa potrebbe causare il corretto funzionamento della mia configurazione di Ansible Sudo su un server e il rifiuto su un altro?
  • Ansible esegue la password "passa" dal computer locale al computer remoto in modo diverso quando viene eseguito ad-hoc rispetto al playbook? Ho pensato che sarebbero stati gli stessi.

Sto pensando che questo si sta avvicinando semplicemente all'invio di una segnalazione di bug alla pagina GitHub semplicemente sul fatto che l'accesso sudo ha risultati diversi a seconda che io stia eseguendo ad-hoc o meno.

Risposte:


4

Quello che vorrei fare è usare

strace -vfp `pidof sshd`

e vedere dove sta fallendo.

Controlla anche l'account, forse è limitato o qualcosa del genere, ma la mia scommessa è che qualcosa non va nel tuo file / etc / hosts o viene modificato nel processo.


Grazie, Lulian. Ho applicato alcune modifiche alla domanda, una sezione è l'output di STrace. È chiaro che c'è una differenza tra i due server nel modo in cui procedono dopo che il processo ansible inizia sul server remoto. Le esecuzioni successive e le acquisizioni di traccia erano coerenti.
BrM13

Penso che tu abbia bisogno di più da quella strace -vfp, fallo manualmente sul processo sshd in alto e segui l'output. Non credo che dopo aver letto la password stia chiudendo il canale in quel modo prima di passare attraverso PAM ecc. A quel punto, dai un'occhiata al file sshd_config e hosts.deny .. vedi se riesci a trovare qualcosa lì.
Iulian,

Avevo già provato il tuo suggerimento prima, ma devo essermi perso l'elemento cruciale (quindi perché ho scelto di seguire il processo di risposta nella STrace iniziale). Dopo un altro tentativo, ho trovato una variabile {{password}} vuota invece della vera password. Ho scelto di inviare un'altra "risposta" separatamente poiché la tua risposta alla fine mi ha portato sulla strada giusta.
BrM13,

4

Usando @lulian come punto d'appoggio in questa risposta, il problema è ansible_sudo_pass:ricaduto in una canaglia definita in group_vars che stava scavalcando la password inserita --ask-sudo-pass.

Utilizzando quanto segue:

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

Sono stato in grado di scoprire che write(4, "{{ password }}\n", 15)veniva passato invece della password inserita. Dopo alcune ricerche rapide, ho effettivamente trovato ansible_sudo_passdefinito nei miei group_vars che stava sovrascrivendo la mia password inserita.

In quanto FYI per tutti gli altri, la ansible_sudo_pass:definizione sembra avere la precedenza su ciò --ask-sudo-passche, inizialmente, sembrava controintuitivo. Alla fine, questo è un errore dell'utente, ma la metodologia di @lulian nel debug dell'interazione SSH e la scoperta della relazione tra ansible_sudo_passe --ask-sudo-passdovrebbero essere molto utili per gli altri là fuori. (Fiduciosamente!)


1
Direi che Ansible dare la precedenza alle variabili definite dal file rispetto alle opzioni della riga di comando è controintuitivo e comportamento scorretto. Curiosamente, riconosce che questo si interrompe quando si passano le opzioni -ee si può essere in grado di aggirare questo passaggio passando un'opzione appropriata con -e.
Christopher Cashell,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.