Problem
Korzystając z najnowszej, stabilnej wersji Ansible, mam dziwny problem polegający na tym, że mój playbook zawiesza się na jednym serwerze podczas „Gathering_Facts”, ale działa dobrze na innych podobnych serwerach podczas korzystania z Sudo. Na serwerze Ansible uruchamiam się jako mój użytkownik (użytkownik NIS) i używam sudo (jako root) na serwerze zdalnym, aby wprowadzać zmiany. Jeśli usunę Sudo z tej konfiguracji, wszystko działa dobrze.
Ustawiać
Wersje oprogramowania
- System operacyjny : RHEL 6.4
- Wersja Ansible : ansible 1.8.2
- Wersja Sudo :
Wersja Sudo 1.8.6p3 Sudoers policy plugin wersja 1.8.6p3 Gramatyka pliku Sudoers wersja 42 Sudoers I / O plugin version 1.8.6p3
- Wersja SSH : OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 marca 2010
Mapa serwera
-------- Użytkownik1 @ Serwer1: sudo -H -S -p (zawiesza się na Gathering_Facts) / Użytkownik1 @ Ansible ---- \ -------- Użytkownik1 @ Serwer2: sudo -H -S -p (działa dobrze)
Użytkownicy
- Użytkownik 1: użytkownik dostępny w systemie NIS zarówno na serwerze 1, jak i na serwerze 2.
- root: lokalny użytkownik root dla każdego serwera.
Konfiguracja Ansible
Odpowiednie części mojego 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
Oto prosty testowy podręcznik, aby dotknąć pustego pliku, a następnie go usunąć. Naprawdę, chcę tylko przetestować, czy mogę uzyskać Ansible, aby poprawnie używać sudo na zdalnym serwerze. Jeśli w ogóle działa podręcznik, jestem w dobrej formie.
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
Konfiguracja Sudo
/ etc / sudoers
Host_Alias SRV = Server1, Server2
User_Alias SUPPORT = User1, User2, User3
SUPPORT SRV=(root) ALL
Ta konfiguracja sudo działa dobrze na OBU serwerach. Żadnych problemów z samym sudo.
Jak to wszystko uruchomić
Bardzo prosta:
$ ansible-playbook test.yml Hasło SSH: hasło sudo [domyślnie hasło SSH]: ZAGRAJ [Server1: Server2] ******************************************** ** ZGODNE FAKTY ************************************************ *************** ok: [Server2] failed: [Server1] => {„failed”: true, „parsowany”: false} Przepraszamy, spróbuj jeszcze raz. [sudo przez ansible, key = mxxiqyvztlfnbctwixzmgvhwfdarumtq] hasło: sudo: 1 niepoprawna próba hasła ZADANIE: [utwórz pusty plik, aby przetestować łączność i dostęp do sudo] **************** zmieniono: [Server2] ZGŁOSZONE: [czyste] ********************************************* **************** zmieniono: [Server2] ZAGRAJ RECAP ************************************************ ********************** aby spróbować ponownie, użyj: --limit @ / home / User1 / test.retry Serwer 1: ok = 0 zmieniony = 0 nieosiągalny = 0 nieudany = 1 Serwer2: ok = 3 zmienione = 2 nieosiągalne = 0 nieudane = 0
Nie działa niezależnie od tego, czy jawnie wprowadzę zarówno hasło SSH / Sudo, jak i niejawnie (pozwalając sudo przejść domyślnie na SSH).
Dzienniki zdalnego serwera
Serwer1 (nie działa)
/ var / log / secure
31 grudnia 15:21:10 Serwer1 sshd [27093]: Akceptowane hasło dla użytkownika 1 z portu xxxx 51446 ssh2 31 grudnia 15:21:10 Serwer1 sshd [27093]: pam_unix (sshd: session): sesja otwarta dla użytkownika User1 przez (uid = 0) 31 grudnia 15:21:11 Serwer1 sshd [27095]: żądanie podsystemu dla sftp 31 grudnia 15:21:11 Serwer1 sudo: pam_unix (sudo: auth): błąd uwierzytelnienia; logname = identyfikator użytkownika 1 = 187 identyfikator użytkownika = 0 tty = / dev / pts / 1 ruser = użytkownik 1 rhost = użytkownik = użytkownik 1 31 grudnia 15:26:13 Serwer1 sudo: pam_unix (sudo: auth): konwersacja nie powiodła się 31 grudnia 15:26:13 Serwer1 sudo: pam_unix (sudo: auth): auth nie mógł zidentyfikować hasła dla [Użytkownik1] 31 grudnia 15:26:13 Serwer1 sudo: Użytkownik1: 1 próba niepoprawnego hasła; 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 31 grudnia 15:26:13 Serwer1 sshd [27093]: pam_unix (sshd: session): sesja zamknięta dla użytkownika User1
Serwer2 (działa dobrze)
/ var / log / secure
31 grudnia 15:21:12 Serwer2 sshd [31447]: Akceptowane hasło użytkownika 1 z portu xxxx 60346 ssh2 31 grudnia 15:21:12 Serwer2 sshd [31447]: pam_unix (sshd: session): sesja otwarta dla użytkownika User1 przez (uid = 0) 31 grudnia 15:21:12 Serwer2 sshd [31449]: żądanie podsystemu dla sftp 31 grudnia 15:21:12 Serwer2 sudo: Użytkownik1: TTY = pts / 2; PWD = / home / User1; USER = root; POLECENIE = / 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 grudnia 15:21:14 Serwer2 sshd [31447]: pam_unix (sshd: session): sesja zamknięta dla użytkownika User1
Wyjście STrace
Oto dane wyjściowe strace podczas celowania w komendę użytkownika root. Komenda:
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`
Serwer 1
23650 wybierz (0, NULL, NULL, NULL, {1, 508055}) = 0 (Limit czasu) Gniazdo 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: autentyczne" ..., 124, 0, {sa_family = AF_NETLINK, pid = 0, grupy = 00000000}, 12) = 124 23650 ankieta ([{fd = 10, events = POLLIN}], 1, 500) = 1 ([{fd = 10, revents = POLLIN}]) Odwołanie 23650 (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, grupy = 00000000}, [12]) = 36 Odwołanie 23650 (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, grupy = 00000000}, [12]) = 36 23650 zamknij (10) = 0 23650 zapisu (2, „Przepraszamy, spróbuj ponownie. \ N”, 18) = 18 23650 gettimeofday ({1420050850, 238344}, NULL) = 0 Gniazdo 23650 (PF_FILE, SOCK_STREAM, 0) = 10 23650 connect (10, {sa_family = AF_FILE, path = "/ var / run / dbus / system_bus_socket"}, 33) = 0
Serwer 2
6625 wybierz (8, [5 7], [], NULL, NULL) =? ERESTARTNOHAND (do ponownego uruchomienia) 6625 --- SIGCHLD (dziecko zakończone) @ 0 (0) --- 6625 zapis (8, „\ 21”, 1) = 1 6625 rt_sigreturn (0x8) = -1 EINTR (przerwane wywołanie systemowe) 6625 wybierz (8, [5 7], [], NULL, NULL) = 1 (w [7]) 6625 przeczytane (7, „\ 21”, 1) = 1 6625 wait4 (6636, [{WIFEXITED (s) && WEXITSTATUS (s) == 0}], WNOHANG | WSTOPPED, NULL) = 6636 6625 rt_sigprocmask (SIG_BLOCK, NULL, [], 8) = 0 Gniazdo 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, grupy = 00000000}, 12) = 120 6625 ankieta ([{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, grupy = 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, grupy = 00000000}, [12]) = 36 6625 zamknij (6) = 0 6625 otwarty („/ 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 przeczytane (6, „# \ n # To jest konfiguracja fi” ..., 4096) = 2980 6625 odczytany (6, „”, 4096) = 0 6625 zamknij (6) = 0 6625 Munmap (0x7fbc3a59a000, 4096) = 0 6625 otwarty („/ etc / environment”, O_RDONLY) = 6
Zgaduję że
Serwer 1 nie otrzymuje poprawnie hasła lub niepoprawnie pyta / czeka na hasło. Nie wygląda to na problem Sudo lub Ansible (same, oba działają dobrze), ale Serwer1 nie wydaje się otrzymywać poświadczeń (ani się do nich stosować) w podobny sposób jak Serwer2. Serwer 1 i 2 służą różnym celom, więc możliwe jest, że mają pewne różnice w uwierzytelnianiu lub wersjach pakietów, ale oba zostały zbudowane z tego samego repozytorium; dlatego nie powinny być TAKIE różne.
PAM Auth
Pomyślałem, że może systemy mają różne konfiguracje PAM, co powoduje, że hasła są traktowane nieco inaczej. Porównałem pliki /etc/pam.d/ (za pomocą md5sum [file]
) i są one takie same między dwoma systemami.
Testy
Sudo STDIN
Przetestowano inny problem, w którym sudo nie czytało hasła ze STDIN, ale działało dobrze na obu serwerach.
Test Sudo Ad-Hoc
-bash-4.1 $ ansible Serwer1 -m plik -a "dest = / tmp / ansible_test.txt state = touch" -sK Hasło SSH: hasło sudo [domyślnie hasło SSH]: Serwer1 | sukces >> { „zmieniono”: prawda, „dest”: „/tmp/ansible_test.txt”, „gid”: 0, „group”: „root”, „mode”: „0644”, „owner”: „root”, „rozmiar”: 0, „state”: „file”, „uid”: 0 }
Sukces! Ale dlaczego?!
TL; DR
- Serwer 1 wydaje się czekać na monit sudo o hasło, a Serwer 2 działa dobrze.
- Uruchamianie
ansible
„ad-hoc” na serwerze Server1 działa dobrze. Uruchomienie go jako playbooka kończy się niepowodzeniem.
Pytania)
- Co może spowodować, że moja konfiguracja Ansible Sudo będzie działać poprawnie na jednym serwerze i zostać odrzucona na innym?
- Czy Ansible wykonuje hasło „przekazuj” z komputera lokalnego do zdalnego w inny sposób, gdy działa ad-hoc w porównaniu do podręcznika? Zakładałem, że będą takie same.
Myślę, że zbliża się to do wysłania raportu o błędzie na stronie GitHub wyłącznie z tego powodu, że dostęp do sudo ma różne wyniki, w zależności od tego, czy korzystam z ad-hoc, czy nie.
Wykorzystując @lulian jako podstawę w tej odpowiedzi, problem sprowadził się do nieuczciwego
ansible_sudo_pass:
zdefiniowanego w group_vars, który przesłaniał wprowadzone hasło--ask-sudo-pass
.Wykorzystując następujące:
Udało mi się znaleźć,
write(4, "{{ password }}\n", 15)
że przekazywano zamiast wprowadzonego hasła. Po szybkim wyszukiwaniu rzeczywiście znalazłemansible_sudo_pass
zdefiniowane w moich group_vars, które przesłaniały moje wprowadzone hasło.ansible_sudo_pass:
Definicja wydaje się mieć pierwszeństwo dla wszystkich innych,--ask-sudo-pass
dlatego wydaje się , że z początku wydawała się sprzeczna z intuicją. W końcu jest to błąd użytkownika, ale metodologia @ lulian w debugowaniu interakcji SSH, a także odkrywanie relacji międzyansible_sudo_pass
i--ask-sudo-pass
powinna być bardzo pomocna dla innych. (Ufnie!)źródło
-e
, i możesz być w stanie obejść ten problem, przekazując odpowiednią opcję za pomocą-e
.