Problem
Bei Verwendung des neuesten, stabilen Ansible-Builds habe ich ein seltsames Problem, bei dem mein Playbook während "Gathering_Facts" auf einem Server hängt, bei Verwendung von Sudo jedoch auf anderen ähnlichen Servern einwandfrei funktioniert. Auf dem Ansible-Server führe ich als mein Benutzer (NIS-Benutzer) aus und verwende sudo (als root) auf dem Remote-Server, um Änderungen vorzunehmen. Wenn ich Sudo aus diesem Setup entferne, funktioniert alles einwandfrei.
Konfiguration
Softwareversionen
- Betriebssystem : RHEL 6.4
- Ansible Version : Ansible 1.8.2
- Sudo-Version :
Sudo Version 1.8.6p3 Sudoers Policy Plugin Version 1.8.6p3 Sudoers Datei Grammatik Version 42 Sudoers I / O Plugin Version 1.8.6p3
- SSH-Version : OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29. März 2010
Server Map
-------- Benutzer1 @ Server1: sudo -H -S -p (hängt an Gathering_Facts) /. User1 @ Ansible ---- \. -------- Benutzer1 @ Server2: sudo -H -S -p (Funktioniert einwandfrei)
Benutzer
- Benutzer1: NIS-zugänglicher Benutzer auf Server1 und Server2.
- root: lokaler Root-Benutzer für jeden Server.
Ansible Konfiguration
Relevante Teile meiner 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
Hier ist ein einfaches Test-Playbook, mit dem Sie eine leere Datei berühren und dann entfernen können. Eigentlich möchte ich nur testen, ob ich Ansible dazu bringen kann, sudo auf dem Remote-Server korrekt zu verwenden. Wenn das Spielbuch überhaupt läuft, bin ich in guter Verfassung.
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
Sudo-Konfiguration
/ etc / sudoers
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
Diese Sudo-Konfiguration funktioniert auf BEIDEN Servern einwandfrei. Keine Probleme mit sudo selbst.
Wie ich alles laufen lasse
Sehr einfach:
$ ansible-playbook test.yml SSH-Passwort: sudo password [standardmäßig SSH-Passwort]: PLAY [Server1: Server2] ************************************************ ** **. GATHERING FACTS ******************************************************** *************** ok: [Server2] fehlgeschlagen: [Server1] => {"fehlgeschlagen": true, "analysiert": false} Sorry, versuch es nochmal. [sudo via ansible, key = mxxiqyvztlfnbctwixzmgvhwfdarumtq] Passwort: sudo: 1 falscher Passwortversuch AUFGABE: [Leere Datei erstellen, um die Konnektivität und den Sudo-Zugriff zu testen] **************** geändert: [Server2] NOTIFIED: [clean] **************************************************** **************** geändert: [Server2] PLAY RECAP ******************************************************** ******************** Verwenden Sie zum erneuten Versuch Folgendes: --limit @ / home / User1 / test.retry Server1: ok = 0 geändert = 0 nicht erreichbar = 0 fehlgeschlagen = 1 Server2: ok = 3 geändert = 2 nicht erreichbar = 0 fehlgeschlagen = 0
Schlägt fehl, unabhängig davon, ob ich sowohl die SSH / Sudo-Passwörter als auch implizit explizit eingebe (Sudo wird standardmäßig an SSH übergeben).
Remote-Server-Protokolle
Server1 (schlägt fehl)
/ var / log / secure
31. Dezember 15:21:10 Server1 sshd [27093]: Akzeptiertes Passwort für Benutzer1 von xxxx Port 51446 ssh2 31. Dezember 15:21:10 Server1 sshd [27093]: pam_unix (sshd: session): Sitzung für Benutzer User1 geöffnet von (uid = 0) 31. Dezember 15:21:11 Server1 sshd [27095]: Subsystemanforderung für SFTP 31. Dezember 15:21:11 Server1 sudo: pam_unix (sudo: auth): Authentifizierungsfehler; logname = User1 uid = 187 euid = 0 tty = / dev / pts / 1 ruser = User1 rhost = user = User1 31. Dezember 15:26:13 Server1 sudo: pam_unix (sudo: auth): Konversation fehlgeschlagen 31. Dezember 15:26:13 Server1 sudo: pam_unix (sudo: auth): auth konnte das Passwort für [User1] nicht identifizieren 31. Dezember 15:26:13 Server1 sudo: Benutzer1: 1 falscher Passwortversuch; TTY = pts / 1; PWD = / home / User1; USER = root; BEFEHL = / 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. Dezember 15:26:13 Server1 sshd [27093]: pam_unix (sshd: session): Sitzung für Benutzer User1 geschlossen
Server2 (läuft gut)
/ var / log / secure
31. Dezember 15:21:12 Server2 sshd [31447]: Akzeptiertes Passwort für Benutzer1 von xxxx Port 60346 ssh2 31. Dezember 15:21:12 Server2 sshd [31447]: pam_unix (sshd: session): Sitzung für Benutzer User1 geöffnet von (uid = 0) 31. Dezember 15:21:12 Server2 sshd [31449]: Subsystemanforderung für SFTP 31. Dezember 15:21:12 Server2 sudo: Benutzer1: TTY = pts / 2; PWD = / home / User1; USER = root; BEFEHL = / 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. Dezember 15:21:14 Server2 sshd [31447]: pam_unix (sshd: session): Sitzung für Benutzer User1 geschlossen
STrace-Ausgabe
Hier ist die Ausgabe von strace, wenn auf den ansible-Befehl des Root-Benutzers abgezielt wird. Befehl:
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`
Server 1
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
Server2
6625 select (8, [5 7], [], NULL, NULL) =? ERESTARTNOHAND (Neustart) 6625 --- SIGCHLD (Kind verlassen) @ 0 (0) --- 6625 write (8, "\ 21", 1) = 1 6625 rt_sigreturn (0x8) = -1 EINTR (Unterbrochener Systemaufruf) 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 Umfrage ([{fd = 6, Ereignisse = 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 # Dies ist die Konfiguration fi" ..., 4096) = 2980 6625 read (6, 4096) = 0 6625 close (6) = 0 6625 Munmap (0x7fbc3a59a000, 4096) = 0 6625 open ("/ etc / environment", O_RDONLY) = 6
Meine Vermutung
Server1 erhält das Passwort nicht richtig oder fragt / wartet fälschlicherweise auf ein Passwort. Dies sieht nicht nach einem Sudo- oder Ansible-Problem aus (allein funktionieren beide einwandfrei), aber Server1 scheint die Anmeldeinformationen nicht auf ähnliche Weise wie Server2 zu erhalten (oder sie einzuhalten). Server1 und 2 dienen unterschiedlichen Zwecken, sodass es möglich ist, dass sie einige Authentifizierungs- oder Paketversionsunterschiede aufweisen, beide jedoch aus demselben Repository erstellt wurden. Daher sollten sie nicht so unterschiedlich sein.
PAM Auth
Ich dachte, vielleicht hatten die Systeme unterschiedliche PAM-Konfigurationen, wodurch die Passwörter etwas anders behandelt wurden. Ich habe die Dateien /etc/pam.d/ (mit md5sum [file]
) verglichen und sie sind zwischen den beiden Systemen gleich.
Tests
Sudo STDIN
Testete ein anderes Problem, bei dem sudo kein Passwort von STDIN lesen würde, aber das funktionierte auf beiden Servern einwandfrei.
Testen Sie Sudo Ad-Hoc
-bash-4.1 $ ansible Server1 -m Datei -a "dest = / tmp / ansible_test.txt state = touch" -sK SSH-Passwort: sudo password [standardmäßig SSH-Passwort]: Server1 | Erfolg >> { "geändert": wahr, "dest": "/tmp/ansible_test.txt", "gid": 0, "Gruppe": "Wurzel", "mode": "0644", "Besitzer": "Wurzel", "Größe": 0, "state": "file", "uid": 0 }}
Erfolg! Aber warum?!
TL; DR
- Server1 scheint auf die Eingabeaufforderung von sudo password zu warten, während Server2 einwandfrei läuft.
- Das Ausführen von
ansible
"Ad-hoc" auf Server1 funktioniert einwandfrei. Das Ausführen als Playbook schlägt fehl.
Fragen)
- Was kann dazu führen, dass meine Ansible Sudo-Konfiguration auf einem Server einwandfrei funktioniert und auf einem anderen abgelehnt wird?
- Führt Ansible das Kennwort "Weitergeben" vom lokalen zum Remote-Computer anders aus, wenn Ad-hoc oder Playbook ausgeführt wird? Ich nahm an, dass sie gleich sein würden.
Ich denke, dies kommt der einfachen Übermittlung eines Fehlerberichts an die GitHub-Seite nahe, nur weil der Sudo-Zugriff unterschiedliche Ergebnisse hat, je nachdem, ob ich ad-hoc bin oder nicht.
Mit @lulian als Grundlage in dieser Antwort kam das Problem auf einen Schurken zurück
ansible_sudo_pass:
, der in den group_vars definiert wurde und das eingegebene Passwort überschrieb--ask-sudo-pass
.Verwenden Sie Folgendes:
Ich konnte feststellen,
write(4, "{{ password }}\n", 15)
dass anstelle des eingegebenen Passworts übergeben wurde. Nach einer kurzen Suche fand ich tatsächlichansible_sudo_pass
in meinen group_vars definiert, was mein eingegebenes Passwort überschrieb.Als FYI für alle anderen
ansible_sudo_pass:
scheint die Definition Vorrang zu haben,--ask-sudo-pass
was zunächst kontraintuitiv schien. Letztendlich ist dies ein Benutzerfehler, aber die Methode von @ lulian beim Debuggen der SSH-Interaktion sowie die Beziehungserkennung zwischenansible_sudo_pass
und--ask-sudo-pass
sollte für andere da draußen sehr hilfreich sein. (Hoffnungsvoll!)quelle
-e
, und Sie können dies möglicherweise umgehen, indem Sie eine entsprechende Option mit übergeben-e
.