Як я можу надійно реалізувати ansible за допомогою паролів хоста?


108

Я хотів би використовувати ansible для управління групою існуючих серверів. Я створив ansible_hostsфайл і успішно протестував (з -Kопцією) з командами, націленими лише на одного хоста

ansible -i ansible_hosts host1 --sudo -K # + commands ...

Моя проблема зараз полягає в тому, що паролі користувачів на кожному хості різні, але я не можу знайти спосіб обробки цього в Ansible.

Використовуючи -K, мені пропонується ввести лише один пароль sudo на передній панелі, який потім, здається, буде випробувано для всіх наступних хостів, не вимагаючи:

host1 | ...
host2 | FAILED => Incorrect sudo password
host3 | FAILED => Incorrect sudo password
host4 | FAILED => Incorrect sudo password
host5 | FAILED => Incorrect sudo password

Дослідження поки що:

  • StackOverflow питання одним неправильної відповіді ( «використання -K») і одна відповідь автор кажучи "Дізнався я потребував в беспарольному Sudo"

  • Документи Ansible , в яких сказано: "Використання судового пароля без проблем робить речі легшими для автоматизації, але це не потрібно ". (наголос мій)

  • це питання StackExchange безпеки, яке сприймає його як прочитане, що NOPASSWDпотрібно

  • стаття "Масштабоване та зрозуміле забезпечення ...", де сказано:

    "для запуску sudo може знадобитися введення пароля, що є вірним способом блокування Ansible назавжди. Просте виправлення - запустити visudo на цільовому хості та переконатися, що користувач Ansible використовуватиме для входу не потрібно вводити пароль"

  • стаття "Основні відповідні ігрові книги" , в якій сказано

    "Ansible міг би увійти на цільовий сервер як root та уникнути потреби в sudo, або дозволити користувачеві Ansible мати sudo без пароля. не "

    Мої думки точно, але як потім вийти за межі одного сервера?

  • Ansible issue # 1227 , "Ansible повинен запитати пароль для sudo для всіх користувачів у програмі", яка була закрита рік тому mpdehaan з коментарем "Я не бачив великого попиту на це, я думаю, що більшість людей погоджуються лише з одним обліковий запис користувача або використовуючи ключі більшість часу. "

Отже ... як люди використовують Ansible у таких ситуаціях? Установка NOPASSWDв /etc/sudoers, повторне використання пароля по хостам або дозволяючи кореневої SSH логін все , здається , досить різке скорочення безпеки.


2
Чи є причина, що ви не використовуєте SSH-ключі?
Тронд

22
Я вже використовую SSH ключі; вони не впливають sudo(для чого все-таки потрібен пароль).
supervacuo

1
Це може бути не саме те, що ви шукаєте, але в ящиках Ubuntu я все-таки використовую ключі, тобто вводя свій відкритий ключ у / root / санкціонований_кейс, щоб безпосередньо входити як root. Очевидний недолік дозволяє дозволити вхід у систему через ssh ... Я також заборонити вхід паролів через ssh та запускати fail2ban для додаткової безпеки.
senorsmile

27
@senorsmile дякую за відповідь! Ви б проти цього зробити відповідь натомість, щоб я міг вас порушити за те, що ви не читали питання?
supervacuo

4
тобтоansible_ssh_password параметр застосовується тільки до паролю SSH (розгадка в ім'я ...). & Я вже використовую ключ на основі SSH.
supervacuo

Відповіді:


53

Ви неодмінно зробили свої дослідження ...

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

Отже, я не можу запропонувати точне рішення, яке ви шукаєте, але ви запитали ...

"Отже ... як люди, які використовують Ansible в таких ситуаціях? Встановлення NOPASSWD в / etc / sudoers, повторне використання пароля через хости або включення root-SSH входу все здається досить різким зниженням безпеки".

Я можу дати вам один погляд на це. Мій випадок використання - це 1k вузлів у декількох центрах обробки даних, що підтримують глобальну фірму SaaS, в якій я маю розробити / впровадити деякі шалено жорсткі засоби контролю за безпекою через характер нашого бізнесу. Безпека - це завжди балансуючий акт, більша зручність використання, менше безпека, цей процес не відрізняється, якщо ви працюєте з 10 серверами або 1000 або 100 000.

Ви абсолютно правильні, що не користуєтеся кореневими логінами ні через пароль, ні на ключ ssh. Насправді кореневий вхід повинен бути повністю відключений, якщо до серверів підключений мережевий кабель.

Давайте поговоримо про повторне використання паролів на великому підприємстві, чи розумно просити системних адміністраторів мати різні паролі на кожному вузлі? можливо, для декількох вузлів, але мої адміністратори / інженери б збурилися, якби вони мали різні паролі на 1000 вузлів. Здійснюючи це, що також буде майже неможливим, кожен користувач повинен буде десь зберігати свої власні паролі, сподіваємось, що це ключ, а не електронна таблиця. І кожного разу, коли ви ставите пароль у місці, де його можна витягнути простим текстом, ви значно знизили рівень безпеки. Я хотів би скоріше, щоб вони знали напам’ять один-два дійсно міцні паролі, ніж доводиться звертатися до файлу клавіатури кожного разу, коли їм потрібно було увійти або викликати sudo на машині.

Тож використання та стандартизація паролів - це те, що є цілком прийнятним та стандартним навіть у безпечному середовищі. Інакше ldap, keystone та інші служби каталогів не потребують існування.

Коли ми переходимо до автоматизованих користувачів, клавіші ssh чудово працюють, щоб вас увійти, але вам все одно потрібно пройти через sudo. Ваш вибір - це стандартизований пароль для автоматизованого користувача (який у багатьох випадках прийнятний) або включення NOPASSWD, як ви вказали. Більшість автоматизованих користувачів виконують лише кілька команд, тому цілком можливо і, звичайно, бажано включити NOPASSWD, але тільки для попередньо затверджених команд. Я б запропонував використовувати ваше управління конфігурацією (відповідальне в цьому випадку) для управління файлом sudoers, щоб ви могли легко оновити список команд без пароля.

Тепер є кілька кроків, які ви можете зробити, як тільки ви почнете масштабування для подальшого виділення ризику. Хоча у нас є 1000 або більше вузлів, не всі вони є "виробничими" серверами, деякі - тестовими середовищами і т. Д. Не всі адміністратори можуть отримати доступ до виробничих серверів, тим, хто може використовувати свій той самий користувач SSO / ключ | як і в іншому місці . Але автоматизовані користувачі трохи захищеніші, наприклад, автоматизований інструмент, до якого адміністратори невиробничого доступу можуть отримати доступ, має користувачеві та облікові дані, які неможливо використовувати у виробництві. Якщо ви хочете запустити ansible на всіх вузлах, вам доведеться зробити це в дві партії, один раз для невиробництва і один раз для виробництва.

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

Очевидно, якщо той запит на функцію, який ви цитували, буде повторно відкритий / виконаний, все, що ви хочете зробити, буде повністю підтримуватися. Навіть тоді, безпека - це процес оцінки ризику та компромісу. Якщо у вас є лише кілька вузлів, для яких ви можете запам'ятати паролі, не вдаючись до примітки після неї, окремі паролі будуть дещо безпечнішими. Але для більшості з нас це не здійсненний варіант.


Дякую, @Zeb - я уявляв, що користувачі з десятками до тисяч серверів все одно використовуватимуть NOPASSWDз розумних причин (можливо, це підтримується більш жорсткими правилами брандмауера тощо ), але добре ознайомитись із вашим випадком використання та думками про загрозу модель.
supervacuo

16
Хоча один коментар до вашої пропозиції щодо обмеження на "попередньо затверджені" sudoкоманди (що у мене траплялося, коли я виявив, що NOPASSWDце дуже потрібно). На жаль, це здається абсолютно непідтримуваним, оскільки відповідальний не дає жодних обіцянок щодо виклику напр., chown Або mkdirбінарних файлів безпосередньо, і sudo /bin/shдля більшості модулів потрібно працювати.
супервакуо

Здається, я згадую одного з моїх інженерів, який скаржився на те, що деякий час повертався, це дратує.
Зеб

36

Починаючи з відповіді 1.5, можна використовувати зашифрований сейф для host_vars та інших змінних. Це принаймні дає змогу ansible_sudo_passнадійно зберігати змінну на хост (або на групу) . На жаль, --ask-vault-passбуде запропоновано лише один сейф-пароль на кожну виклик, що відповідає, тому ви все ще обмежуєтесь одним паролем сховища для всіх хостів, які ви будете використовувати разом.

Тим не менш, для деяких застосувань це може бути вдосконаленням щодо наявності одного пароля sudo для кількох хостів, оскільки зловмиснику без доступу до ваших зашифрованих host_vars все одно знадобиться окремий пароль sudo для кожної машини (або групи машин), на яку він атакує.


3
Цей ansible_sudo_passваріант теж здається новим - і, здається, виконує те, про що я просив. Єдиний пароль сховища ідеально підходить і для моїх цілей. Дякую!
supervacuo

Чи є спосіб уникнути шифрування всіх, host_vars використовуючи цей метод? (потенційне обмеження, відмічене Алексом
Дюпюєм

1
@supervacuo - Щоб уникнути шифрування всіх варіантів хостів, просто використовуйте каталог var хост, що містить main.yml (незашифрований) та secret.yml (зашифрований) - див. останню частину цього розділу документа, де йдеться про групу "raleigh" - та сама техніка працює для хостів vars та групових vars. Я дуже часто використовую це, єдиною варіацією є те, що якщо секрет потрібен лише для деяких ігрових книжок, це може бути корисно повністю зберігати його в іншому дереві та включати через шлях, що включає ім'я хоста чи var.
RichVel

1
Якщо я зашифрував значення "ansible_ssh_pass" у сховищі, то мені також потрібно дублювати значення "ansible_sudo_pass"? Чи існує спосіб для другого значення sudo_pass відбити перше значення 'ssh_pass'?
emeraldjava

Гарне освітлення на склепінчастому використанні пароля можна знайти тут: stackoverflow.com/a/37300030/5025060
КОД читаного

22

За допомогою Ansible 1.5 можна встановити змінну ansible_sudo_pass, використовуючи lookup('password', …):

ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

Мені це зручніше, ніж використання файлів host_vars/з кількох причин:

  • Я фактично використовую with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt" для надання паролів віддаленому користувачеві розгортання (який тоді потрібен для sudo ), тому вони вже присутні у файлах (хоча при виконанні цих простого тексту пошуку втрачається значення солі, збережене у файлі, коли генерується хешоване значення) .

  • Це зберігає лише паролі у файлі ( ansible_sudo_pass:невідомий простий текст) для деякого підвищення криптографічної безпеки. Більш суттєво, це означає, що ви не шифруєте всі інші змінні, що стосуються хоста, тому їх можна читати без пароля Vault.

  • Якщо розмістити паролі в окремому каталозі, це полегшить збереження файлів поза контролем джерела або використовувати такий інструмент, як git-crypt, щоб зберігати їх у зашифрованому вигляді (ви можете використовувати це з попереднім Ansible, у якому відсутня функція сейфу). Я використовую git-crypt, і оскільки я лише перевіряю сховище в розшифрованому вигляді в зашифрованих файлових системах, я не турбуюсь із сховищем і, таким чином, не потрібно вводити пароль. (Використання обох, звичайно, буде більш безпечним.)

Ви також можете використовувати функцію пошуку з ansible_ssh_pass ; це можливо навіть у більш ранніх версіях Ansible, які не мають ansible_sudo_pass .


2
Нарешті я спробував це (спасибі!), Але не можу зрозуміти, як це буде працювати без git-crypt; наскільки я бачу. Схоже, Ansible ще не підтримує використання lookupв зашифрованому сховищі. Документи passwordмодулів кажуть, що існує якась ще незадокументована підтримка зашифрованого сховища, але я ще не можу знайти подробиці. Будь-які підказки?
supervacuo

19

Використання пропуску - це простий спосіб забезпечити відповідальність паролями sudo. pass зберігає один пароль на файл, що дозволяє легко обмінюватися паролями за допомогою git або інших методів. Це також безпечно (використовуючи GnuPG), і якщо ви використовуєте gpg-агент, він дозволяє використовувати ansible без введення пароля при кожному використанні.

Щоб забезпечити пароль, який зберігається як servers/fooдля сервера, fooдо відповідальності, використовуйте його у інвентарному файлі, як це:

[servers]
foo ansible_sudo=True \
    ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

Зважаючи на те, що ви раніше розблокували ключ для gpg-агента, він буде працювати без відповіді без необхідності введення пароля.


3

Це дуже стара тема, проте:

  • Ми використовуємо дві різні системи аутентифікації вдома, управління машинами здійснюється на місцевих робочих станціях моєї команди.
  • Я написав vars_pluginдля Ansible (досить повну реалізацію можна знайти за адресою https://gist.github.com/mfriedenhagen/e488235d732b7becda81 ), яка розрізняє декілька систем аутентифікації:
  • Назва системи аутентифікації є специфічною для групи.
  • Використовуваний користувач login / sudo має специфіку для групи та адміністратора.
  • Тому я витягаю користувача із середовища адміністратора та відповідного пароля через бібліотеку клавіш python із безпечного пароля (ми використовуємо брелок Mac OS X, але також підтримуються kwallet Gnome та _win_crypto документації).
  • Я встановлюю дозволи на паролі в брелоку Mac OS X, щоб повідомляти мене про те, що безпека програми командного рядка вимагає доступу до пароля для кожної системи аутентифікації, що використовується хостами, тому я запускаю "ansible -s all -m ping" і отримаю два підказки (по одному для кожної системи аутентифікації), де я натискаю пробіл і ansible підбирає паролі.

Це виглядає дуже акуратно, дякую - мені подобається ідея не зберігати паролі у двох місцях. На даний момент я застряг у використанні KeepassX (оскільки брелок GNOME здається не дуже портативним), але, можливо, я можу зробити python-keepassроботу?
supervacuo

Наскільки я розумію, python-keyring - це абстракція цього, тому ваші колеги можуть використовувати інші ОС. Або ви зберігаєте dd Keepassx db на USB-накопичувачі та маєте адмініструвати з робочих станцій з різними ОС?
Mirko Friedenhagen

зрозумів; Я мав на увазі, що я вже повинен використовувати KeepassX, щоб мати доступ до паролів у системах, що не належать до GNOME, тому зберігання в них gnome-keyringозначатиме збереження дублікатів записів. І все-таки набагато приємніше, ніж використовувати NOPASSWD, хоча…
supervacuo

0

Один з можливих способів зробити це - використання змінних довкілля.

напр

pass1=foo pass2=bar ansible-playbook -i production servers.xml

Потім у п’єсах ви можете знайти пароль sudo, використовуючи:

lookup('env', 'pass1') 
lookup('env', 'pass2') 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.