Не вдалося засвідчити автентифікацію судо, навіть коли надано пропуск судо


9

Проблема

Використовуючи останню, стійку збірку Ansible, у мене виникає дивна проблема, коли моя книжка програвання висить на одному сервері під час "Gathering_Facts", але добре працює на інших подібних серверах при використанні Sudo. На сервері Ansible я запускаюсь як мій користувач (користувач NIS) і використовую sudo (як root) на віддаленому сервері для внесення змін. Якщо я вилучу Судо з цієї установки, все працює добре.

Налаштування

Версії програмного забезпечення

  • ОС : RHEL 6.4
  • Відповідна версія : ansible 1.8.2
  • Версія судо :
    Версія судо 1.8.6p3
    Версія для плагінів Sudoers версія 1.8.6p3
    Граматика файлів Судерів версії 42
    Версія плагінів для вводу / виводу Sudoers 1.8.6p3
    
  • Версія SSH : OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 березня 2010 року

Карта сервера

                   -------- User1 @ Server1: sudo -H -S -p (Висить на Gathering_Facts)
                  /
User1 @ Ansible ----
                  \
                   -------- User1 @ Server2: sudo -H -S -p (прекрасно працює)

Користувачі

  • Користувач1: Користувач, доступний NIS, і на сервері1 і на сервері2.
  • root: локальний користувач root для кожного сервера.

Відповідна конфігурація

Відповідні частини мого 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

Ось простий тестовий зошит, щоб торкнутися порожнього файлу, а потім видалити його. Дійсно, я просто хочу перевірити, чи зможу я отримати Ansible, щоб правильно використовувати sudo на віддаленому сервері. Якщо ігрова книга взагалі працює, я в хорошій формі.

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

Конфігурація судо

/ тощо / sudoers

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

Ця конфігурація sudo працює чудово на BOTH-серверах. Немає проблем із самим судо.

Як я все це запускаю

Дуже просто:

$ ansible-playbook test.yml
Пароль SSH: 
пароль sudo [за замовчуванням пароль SSH]:

ГРАТИ [Server1: Server2] ********************************************** ** 

ФАКТИ ЗБЕРІГАННЯ ************************************************** *************** 
гаразд: [Server2]
не вдалося: [Server1] => {"невдало": true, "parsed": false}

Вибачте, спробуйте ще раз.
[sudo через ansible, key = mxxiqyvztlfnbctwixzmgvhwfdarumtq] пароль: 
sudo: 1 помилкова спроба пароля


ЗАВДАННЯ: [створити порожній файл для перевірки підключення та доступу до судо] **************** 
змінено: [Server2]

ПОВІДОМЛЕНО: [чисто] *********************************************** **************** 
змінено: [Server2]

ІГРУЙТЕ РЕКАП ************************************************** ******************** 
           щоб повторити спробу, використовуйте: --limit @ / home / User1 / test.retry

Server1: ok = 0 змінено = 0 недоступно = 0 не вдалося = 1   
Сервер2: добре = 3 змінено = 2 недоступні = 0 не вдалося = 0

Не вдається незалежно від того, чи я явно ввожу і SSH / Sudo паролі, а також неявно (дозволяючи sudo перейти за замовчуванням до SSH).

Віддалені журнали сервера

Server1 (не вдається)

/ var / log / secure

31 грудня 15:21:10 Server1 sshd [27093]: Прийнятий пароль для User1 з порту xxxx 51446 ssh2
31 грудня 15:21:10 Server1 sshd [27093]: pam_unix (sshd: сесія): сеанс відкритий для користувача User1 користувачем (uid = 0)
31 грудня 15:21:11 Server1 sshd [27095]: запит підсистеми для sftp
31 грудня 15:21:11 Server1 sudo: pam_unix (sudo: auth): збій автентифікації; logname = User1 uid = 187 euid = 0 tty = / dev / pts / 1 ruser = User1 rhost = user = User1
31 грудня 15:26:13 Server1 sudo: pam_unix (sudo: auth): розмова не вдалася
31 грудня 15:26:13 Server1 sudo: pam_unix (sudo: auth): auth не зміг визначити пароль для [User1]
31 грудня 15:26:13 Server1 sudo: User1: 1 неправильна спроба пароля; TTY = очки / 1; PWD = / home / User1; USER = корінь; КОМАНДА = / 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 грудня 15:26:13 Server1 sshd [27093]: pam_unix (sshd: сесія): сеанс для користувача User1 

Server2 (працює нормально)

/ var / log / secure

31 грудня 15:21:12 Server2 sshd [31447]: Прийнятий пароль для User1 від порту xxxx 60346 ssh2
31 грудня 15:21:12 Server2 sshd [31447]: pam_unix (sshd: сесія): сеанс відкритий для користувача User1 користувачем (uid = 0)
31 грудня 15:21:12 Server2 sshd [31449]: запит підсистеми на sftp
31 грудня 15:21:12 Server2 sudo: User1: TTY = pts / 2; PWD = / home / User1; USER = корінь; КОМАНДА = / 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 грудня 15:21:14 Server2 sshd [31447]: pam_unix (sshd: сесія): сесія закрита для користувача User1 

Вихід студії

Ось вихід із strace при націленні на команду Ansible root користувача. Команда:

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`

Сервер1

23650 select (0, NULL, NULL, NULL, {1, 508055}) = 0 (таймаут)
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: справжній" ..., 124, 0, {sa_family = AF_NETLINK, pid = 0, групи = 00000000}, 12) = 124
23650 опитування ([{fd = 10, події = 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, групи = 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, групи = 00000000}, [12]) = 36
23650 закрити (10) = 0
23650 напишіть (2, "Вибачте, спробуйте ще раз. \ N", 18) = 18
23650 вихідний день ({1420050850, 238344}, NULL) = 0
23650 розетка (PF_FILE, SOCK_STREAM, 0) = 10
23650 підключення (10, {sa_family = AF_FILE, path = "/ var / run / dbus / system_bus_socket"}, 33) = 0

Сервер2

6625 select (8, [5 7], [], NULL, NULL) =? ERESTARTNOHAND (Для перезавантаження)
6625 --- SIGCHLD (Вийшов з дитини) @ 0 (0) ---
6625 запису (8, "\ 21", 1) = 1
6625 rt_sigreturn (0x8) = -1 EINTR (Перерваний системний виклик)
6625 select (8, [5 7], [], NULL, NULL) = 1 (у [7])
6625 прочитати (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 розетка (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, групи = 00000000}, 12) = 120
Опитування 6625 ([{fd = 6, події = 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, групи = 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, групи = 00000000}, [12]) = 36
6625 закрити (6) = 0
6625 відкрито ("/ 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 # Це конфігурація fi" ..., 4096) = 2980
6625 читання (6, "", 4096) = 0
6625 закрити (6) = 0
6625 munmap (0x7fbc3a59a000, 4096) = 0
6625 open ("/ etc / environment", O_RDONLY) = 6

Моя здогадка

Server1 неправильно отримує пароль або неправильно запитує / чекає пароля. Це не схоже на проблему Sudo або Ansible (поодинці вони обидва працюють нормально), але, схоже, Server1 не отримує облікові дані (або дотримуються їх) аналогічно, як Server2. Server1 і 2 служать різним цілям, тому можливо, що у них є деякі відмінності автентифікації або версії пакета, але вони були побудовані з одного сховища; отже, вони не повинні БУТИ різними.

PAM Auth

Я подумав, що, можливо, у систем були різні конфігурації PAM, що спричиняло обробку паролів дещо інакше. Я порівняв файли /etc/pam.d/ (використовуючи md5sum [file]), і вони однакові між двома системами.

Тести

Судо STDIN

Випробували ще одну проблему, коли sudo не читав пароль із STDIN, але це справно працювало на обох серверах.

Тестовий спеціальний судовий курс

-bash-4.1 $ ansible Server1 -m файл -a "dest = / tmp / ansible_test.txt state = touch" -sK
Пароль SSH: 
пароль sudo [за замовчуванням пароль SSH]: 
Сервер1 | успіх >> {
    "змінено": правда, 
    "dest": "/tmp/ansible_test.txt", 
    "gid": 0, 
    "група": "корінь", 
    "режим": "0644", 
    "власник": "корінь", 
    "розмір": 0, 
    "state": "файл", 
    "uid": 0
}

Успіху! Але чому?!

TL; DR

  1. Сервер1, схоже, чекає на підказку пароля sudo, поки Server2 працює чудово.
  2. Запуск ansible"ad-hoc" на Server1 працює чудово. Запустити його як ігрову книгу не вдасться.

Питання (и)

  • Що може спричинити нормальну роботу моєї конфігурації Ansible Sudo на одному сервері та відхилення на іншому?
  • Чи виконує Ansible "перехід" пароля від локальної до віддаленої машини по-різному, коли запускається ad-hoc проти playbook? Я припускав, що вони будуть однаковими.

Я думаю, що це наближається до простого подання звіту про помилки на сторінку GitHub виключно на тому, що доступ до sudo має різні результати залежно від того, чи я працюю ad-hoc чи ні.

Відповіді:


4

Що я б робив - це використовувати

strace -vfp `pidof sshd`

і подивіться, де воно провалюється.

Перевірте також обліковий запис, можливо, він обмежений чи щось, але я думаю, що з вашим файлом / etc / hosts щось не так, або він змінюється в процесі.


Дякую, Луліан. Я застосував декілька змін до питання, один розділ - вихід STrace. Зрозуміло, що між двома серверами є різниця в тому, як вони протікають після того, як на віддаленому сервері розпочнеться ансибільний процес. Подальші пробіги та фіксації слідів були послідовними.
BrM13

Я думаю, що вам потрібно більше від цього страйку -vfp, зробіть це вручну на верхньому процесі sshd і слідуйте за результатами. Я не думаю, що після прочитання пароля це просто закриття каналу перед тим, як пройти PAM тощо. У цей момент, будь ласка, подивіться на файл sshd_config і hosts.deny .. подивіться, чи можете ви там щось знайти.
Юліан

Я раніше пробував вашу пропозицію, але, мабуть, пропустив найважливіший елемент там (отже, чому я вирішив спостерігати за тим, як відповідав процес у початковій STrace). Після чергового переходу я знайшов порожню змінну {{password}}, передану замість реального пароля. Вирішили подати ще один "Відповідь" окремо, оскільки ваша відповідь зрештою заставила мене правильно.
BrM13

4

Використовуючи @lulian як опору у цій відповіді, проблема зійшла до шахрая, ansible_sudo_pass:визначеного у group_vars, який переосмислював пароль, введений для --ask-sudo-pass.

Використовуючи наступне:

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

Мені вдалося знайти те, write(4, "{{ password }}\n", 15)що передається замість введеного пароля. Після швидкого пошуку я дійсно виявив, що ansible_sudo_passвизначений у моїй групі_варів, який переосмислював мій введений пароль.

Як FYI для всіх інших, ansible_sudo_pass:визначення, здається, має перевагу над тим, --ask-sudo-passщо, спочатку, здавалося контрінтуїтивним. Зрештою, це помилка користувача, але методологія @ lulian при налагодженні взаємодії SSH, а також виявлення взаємозв'язку між ansible_sudo_passі --ask-sudo-passповинні бути дуже корисними для інших. (Сподіваюсь!)


1
Я можу стверджувати, що Ansible, що надає перевагу певним файлам змінних над параметрами командного рядка, є протиінтуїтивним та поганою поведінкою. Цікаво, що він визнає, що це порушено, коли ви передаєте параметри -e, і ви, можливо, зможете обійти це питання, передавши відповідний варіант -e.
Крістофер Кашелл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.