Kemungkinan Gagal untuk Mengotentikasi Sudo Bahkan Ketika Sudo Pass Diberikan

9

Masalah

Menggunakan build Ansible yang terbaru dan stabil, saya memiliki masalah aneh ketika playbook saya hang pada satu server selama "Gathering_Facts" tetapi bekerja dengan baik pada server lain yang serupa saat menggunakan Sudo. Di server Ansible, saya menjalankan sebagai pengguna saya (pengguna NIS) dan menggunakan sudo (sebagai root) pada server jauh untuk membuat perubahan. Jika saya menghapus Sudo dari pengaturan ini, semuanya berfungsi dengan baik.

Mendirikan

Versi Perangkat Lunak

  • OS : RHEL 6.4
  • Versi yang memungkinkan : mungkin 1.8.2
  • Versi sudo :
    Sudo versi 1.8.6p3
    Plugin Sudoers policy plugin versi 1.8.6p3
    File tata bahasa Sudoers versi 42
    Sudoers I / O plugin versi 1.8.6p3
    
  • Versi SSH : OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010

Peta Server

                   -------- User1 @ Server1: sudo -H -S -p (Hang di Gathering_Facts)
                  /
User1 @ Ansible ----
                  \
                   -------- User1 @ Server2: sudo -H -S -p (Bekerja dengan baik)

Pengguna

  • User1: pengguna yang dapat diakses NIS di Server1 & Server2.
  • root: pengguna root lokal untuk setiap server.

Konfigurasi yang Mungkin

Bagian yang relevan dari ansible.cfg saya .

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

Berikut ini adalah buku pedoman uji sederhana untuk menyentuh file kosong dan kemudian menghapusnya. Sungguh, saya hanya ingin menguji apakah saya bisa mendapatkan Kemungkinan untuk menggunakan sudo dengan benar di server jarak jauh. Jika playbook berjalan sama sekali, saya dalam kondisi baik.

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

Konfigurasi Sudo

/ etc / sudoers

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

Konfigurasi sudo ini berfungsi dengan baik pada KEDUA server. Tidak ada masalah dengan sudo itu sendiri.

Bagaimana Saya Menjalankan Semuanya

Sangat sederhana:

$ ansible-playbook test.yml
Kata sandi SSH: 
kata sandi sudo [standar untuk kata sandi SSH]:

MAIN [Server1: Server2] ****************************************** ** 

FAKTA MENGUMPULKAN ********************************************** ***************** 
ok: [Server2]
gagal: [Server1] => {"gagal": benar, "diurai": false}

Maaf coba lagi.
[sudo via ansible, key = mxxiqyvztlfnbctwixzmgvhwfdarumtq] kata sandi: 
sudo: 1 upaya kata sandi salah


TUGAS: [buat file kosong untuk menguji konektivitas dan akses sudo] **************** 
berubah: [Server2]

Diberitahu: [bersih] ******************************************* **************** 
berubah: [Server2]

MAINKAN KEMBALI ********************************************** ******************** 
           untuk mencoba lagi, gunakan: --limit @ / home / User1 / test.retry

Server1: ok = 0 diubah = 0 tidak terjangkau = 0 gagal = 1   
Server2: ok = 3 berubah = 2 tidak dapat dijangkau = 0 gagal = 0

Gagal terlepas dari apakah saya secara eksplisit memasukkan SSH / Sudo passwords dan juga secara implisit (membiarkan sudo meneruskan default ke SSH).

Log Server Jarak Jauh

Server1 (Gagal)

/ var / log / secure

31 Des 15:21:10 Server1 sshd [27093]: Kata sandi yang diterima untuk User1 dari xxxx port 51446 ssh2
31 Des 15:21:10 Server1 sshd [27093]: pam_unix (sshd: session): sesi dibuka untuk pengguna User1 oleh (uid = 0)
31 Des 15:21:11 Server1 sshd [27095]: permintaan subsistem untuk sftp
31 Des 15:21:11 Server1 sudo: pam_unix (sudo: auth): kegagalan otentikasi; logname = User1 uid = 187 euid = 0 tty = / dev / pts / 1 ruser = User1 rhost = user = User1
31 Des 15:26:13 Server1 sudo: pam_unix (sudo: auth): percakapan gagal
31 Des 15:26:13 Server1 sudo: pam_unix (sudo: auth): auth tidak dapat mengidentifikasi kata sandi untuk [User1]
31 Des 15:26:13 Server1 sudo: User1: 1 upaya kata sandi salah; TTY = Poin / 1; PWD = / home / User1; USER = root; PERINTAH = / 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 Des 15:26:13 Server1 sshd [27093]: pam_unix (sshd: session): sesi ditutup untuk pengguna User1 

Server2 (berjalan dengan baik)

/ var / log / secure

31 Des 15:21:12 Server2 sshd [31447]: Kata sandi yang diterima untuk User1 dari xxxx port 60346 ssh2
31 Des 15:21:12 Server2 sshd [31447]: pam_unix (sshd: session): sesi dibuka untuk pengguna User1 oleh (uid = 0)
31 Des 15:21:12 Server2 sshd [31449]: permintaan subsistem untuk sftp
31 Des 15:21:12 Server2 sudo: User1: TTY = pts / 2; PWD = / home / User1; USER = root; PERINTAH = / 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 Des 15:21:14 Server2 sshd [31447]: pam_unix (sshd: session): sesi ditutup untuk pengguna User1 

STrace Output

Ini adalah output dari strace ketika menargetkan perintah yang dimungkinkan oleh pengguna root. Perintah:

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 pilih (0, NULL, NULL, NULL, {1, 508055}) = 0 (Batas waktu)
23650 soket (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 \ 0op = PAM: authentic" ..., 124, 0, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, 12) = 124
23650 jajak pendapat ([{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, grup = 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, grup = 00000000}, [12]) = 36
23650 tutup (10) = 0
23650 tulis (2, "Maaf, coba lagi. \ N", 18) = 18
23650 gettimeofday ({1420050850, 238344}, NULL) = 0
23650 soket (PF_FILE, SOCK_STREAM, 0) = 10
23650 terhubung (10, {sa_family = AF_FILE, path = "/ var / run / dbus / system_bus_socket"}, 33) = 0

Server2

6625 pilih (8, [5 7], [], NULL, NULL) =? ERESTARTNOHAND (Akan dimulai kembali)
6625 --- SIGCHLD (Anak keluar) @ 0 (0) ---
6625 write (8, "\ 21", 1) = 1
6625 rt_sigreturn (0x8) = -1 EINTR (Panggilan sistem terputus)
6625 pilih (8, [5 7], [], NULL, NULL) = 1 (dalam [7])
6625 baca (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 \ 0op = PAM: session_c" ..., 120, 0, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, 12) = 120
6625 jajak pendapat ([{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, grup = 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, grup = 00000000}, [12]) = 36
6625 close (6) = 0
6625 terbuka ("/ 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_blocks = 8, st_size = 2980, st_atize = 2980, st_atize = 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 baca (6, "# \ n # Ini adalah konfigurasi fi" ..., 4096) = 2980
6625 baca (6, "", 4096) = 0
6625 close (6) = 0
6625 munmap (0x7fbc3a59a000, 4096) = 0
6625 terbuka ("/ etc / environment", O_RDONLY) = 6

Tebakanku

Server1 tidak mendapatkan kata sandi dengan benar atau salah meminta / menunggu kata sandi. Ini tidak terlihat seperti masalah Sudo atau Ansible (sendirian, mereka berdua bekerja dengan baik), tetapi Server1 tampaknya tidak menerima kredensial (atau mematuhi mereka) dengan cara yang mirip dengan Server2. Server1 & 2 melayani tujuan yang berbeda, jadi ada kemungkinan bahwa mereka memiliki beberapa otentikasi atau perbedaan versi paket, tetapi keduanya dibangun dari repositori yang sama; oleh karena itu, mereka seharusnya tidak berbeda.

PAM Auth

Saya pikir mungkin sistem memiliki konfigurasi PAM berbeda yang menyebabkan kata sandi ditangani sedikit berbeda. Saya membandingkan file /etc/pam.d/ (menggunakan md5sum [file]), dan keduanya sama antara kedua sistem.

Tes

Sudo STDIN

Menguji masalah lain di mana sudo tidak akan membaca kata sandi dari STDIN, tetapi itu berfungsi dengan baik di kedua server.

Uji Sudo Ad-Hoc

-bash-4.1 $ Serversible1 file -m -m "dest = / tmp / ansible_test.txt state = touch" -sK
Kata sandi SSH: 
kata sandi sudo [standar untuk kata sandi SSH]: 
Server1 | sukses >> {
    "diubah": benar, 
    "dest": "/tmp/ansible_test.txt", 
    "gid": 0, 
    "grup": "root", 
    "mode": "0644", 
    "pemilik": "root", 
    "size": 0, 
    "state": "file", 
    "uid": 0
}

Keberhasilan! Tapi kenapa?!

TL; DR

  1. Server1 tampaknya menunggu prompt kata sandi sudo sementara Server2 berjalan dengan baik.
  2. Menjalankan ansible"ad-hoc" di Server1 berfungsi dengan baik. Menjalankannya sebagai buku pedoman gagal.

Pertanyaan

  • Apa yang dapat menyebabkan konfigurasi Ansible Sudo saya berfungsi dengan baik di satu server dan ditolak di server lain?
  • Apakah Ansible melakukan kata sandi "lulus" dari mesin lokal ke remote secara berbeda ketika menjalankan ad-hoc versus playbook? Saya berasumsi mereka akan sama.

Saya pikir ini semakin dekat dengan hanya mengirimkan laporan bug ke halaman GitHub murni pada kenyataan bahwa akses sudo memiliki hasil yang berbeda tergantung apakah saya menjalankan ad-hoc atau tidak.

BrM13
sumber

Jawaban:

4

Apa yang akan saya lakukan adalah menggunakan

strace -vfp `pidof sshd`

dan lihat di mana itu gagal.

Periksa akun juga, mungkin itu dibatasi atau sesuatu tetapi taruhan saya adalah ada sesuatu yang salah dengan file / etc / hosts Anda atau itu bisa berubah dalam proses.

Iulian
sumber
Terima kasih, lulian. Saya telah menerapkan beberapa pengeditan untuk pertanyaan, satu bagian menjadi keluaran STrace. Jelas bahwa ada perbedaan antara dua server dalam cara mereka melanjutkan setelah proses yang mungkin dimulai pada server jauh. Lari berikutnya dan jejak tangkapan konsisten.
BrM13
Saya pikir Anda membutuhkan lebih dari strace -vfp, lakukan secara manual pada proses sshd atas dan ikuti outputnya. Saya tidak berpikir setelah membaca kata sandi itu hanya menutup saluran seperti itu sebelum melalui PAM dll. Pada saat itu silakan lihat file sshd_config dan hosts.deny .. lihat apakah Anda dapat menemukan sesuatu di sana.
Iulian
Saya telah mencoba saran Anda sebelumnya, tetapi saya pasti telah melewatkan elemen penting di sana (karenanya mengapa saya memilih untuk menonton proses yang mungkin dalam STrace awal). Setelah mencoba lagi, saya menemukan variabel {{password}} kosong yang diteruskan alih-alih kata sandi asli. Memilih untuk mengirim "Jawaban" lain secara terpisah karena jawaban Anda akhirnya membuat saya di jalur yang benar.
BrM13
4

Menggunakan @lulian sebagai pijakan dalam jawaban ini, masalahnya menjadi masalah yang ansible_sudo_pass:didefinisikan dalam group_vars yang mengesampingkan kata sandi yang dimasukkan --ask-sudo-pass.

Menggunakan yang berikut ini:

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

Saya dapat menemukan yang write(4, "{{ password }}\n", 15)dilewatkan sebagai ganti kata sandi yang dimasukkan. Setelah beberapa pencarian cepat, saya memang menemukan ansible_sudo_passdidefinisikan dalam group_vars saya yang menimpa kata sandi saya yang dimasukkan.

Sebagai FYI bagi semua orang, ansible_sudo_pass:definisi tersebut tampaknya lebih diutamakan daripada --ask-sudo-passyang awalnya terlihat kontra-intuitif. Pada akhirnya, ini adalah kesalahan pengguna, tetapi metodologi @ lulian dalam men-debug interaksi SSH serta penemuan hubungan antara ansible_sudo_passdan --ask-sudo-passharus sangat membantu bagi orang lain di luar sana. (Semoga!)

BrM13
sumber
1
Saya berpendapat bahwa Ansible memberikan prioritas pada variabel yang ditentukan file daripada opsi baris perintah adalah kontra-intuitif, dan perilaku buruk. Anehnya, ia mengakui bahwa ini rusak ketika Anda melewati opsi dengan -e, dan Anda mungkin dapat mengatasi ini dengan melewati opsi yang sesuai dengannya -e.
Christopher Cashell