Pull to refresh
140.59
ITSumma
Эксперты в производительности

Enjoy! Сервер аутентификации Isolate в Open Source

Reading time 4 min
Views 10K
isolate

В работе команды системных администраторов наступает момент, когда поддерживаемых серверов становится слишком много. А может быть еще и людей много, ну и опять же безопасность: если что-то пошло не так, нужно отовсюду ключи удалять.

У нас 300 клиентов. Кому-то это «всего», а для нас — это почти 2000 серверов на обслуживании. Чтобы хранить, обновлять и управлять базой из 2000 паролей для 60 сотрудников, управлять доступом к ней и не объяснять каждый раз клиенту, что пароли к его серверам будут одновременно знать 60 человек, мы сделали сервер аутентификации и назвали его Isolate. Под катом описание функций и ссылка на Github — мы выложили его в Open Source.

У нас есть отдельные серверы авторизации, через которые сотрудники попадают на конкретный поддерживаемый сервер. Мы сами давно и успешно пользуемся этой разработкой, а теперь решили дать ей имя и поделиться с сообществом.

Итак, Isolate — набор утилит auth сервера и ansible-playbook для быстрого его разворачивания. Он позволяет нам авторизовываться по аппаратному ключу (безопасность превыше всего!) и удобно управлять огромным количеством проектов/серверов. При этом:

  • сотрудники не знают root пароль (опять же безопасность);
  • при нештатных ситуациях аппаратный ключ сотрудника деактивируется на auth сервере, и он теряет доступ к клиентским серверам (к счастью, у нас таких ситуаций не было);
  • все SSH-сессии записываются — можно считать время, проведенное на серверах.

Принимая сервер на поддержку, мы создаем на нем sudo-пользователя и прописываем ключ auth серверов. Дальше сотрудник авторизуется на auth сервере с использованием аппаратного ключа (мы используем yubikey), командой s (search) находит нужный сервер (по имени проекта, сервера, сайта и т.п.) и командой g (go) подключается к нему по SSH.

Основные моменты Isolate:

  • у пользователей нет доступа к приватному ключу;
  • все исходящие SSH-сессии логируются;
  • используются только системные средства управления доступом (поддержка SELinux в ближайшем будущем);
  • вход на Isolate выполняется по одноразовому паролю (2FA, OTP); можно использовать либо аппаратные ключи, либо всеми любимый Google Authentificator;
  • менеджер конфигураций SSH с возможностью соединения через SSH прокси-сервер, поддержка серверов в VPN через внешний гейт;
  • устанавливается через Ansible, но требует вмешательства в системные файлы (в ручном режиме);
  • поддерживаются CentOS 7, Ubuntu 16.04, Debian 9.

Как это выглядит


Пример списка серверов:

[~]$ s .

myproject
------
10001   | 11.22.22.22   | aws-main-prod
10002   | 11.33.33.33   | aws-dev
10003   | 11.44.44.44   | vs-ci

------
Total: 3

[~]$

точка s . в данном случае — как универсальный патерн для поиска всех серверов.

Пример входа на сервер с кастомным портом и SSH-proxy:

[~]$ g myproject aws-dev
Warning: Permanently added 3.3.3.100 (RSA) to the list of known hosts.
Warning: Permanently added 10.10.10.12 (RSA) to the list of known hosts.

[root@dev ~]$

Пример входа на произвольный сервер (без конфига в ISOLATE) c произвольными параметрами:

[isolate ~]$ g 45.32.44.87 --user support --port 2232 --nosudo
Warning: Permanently added 45.32.44.87 (RSA) to the list of known hosts.

Принцип работы


Установка достаточно подробно описана в README на Github, тут же поговорим о принципах работы.

Сам доступ разграничивается системными пользователями ОС. Как прослойка для доступа используется sudo + ssh.py обертка, цель которой — не допустить попадания за sudo опасных конструкций; ssh.py верифицирует аргументы и запускает SSH-клиент, на этом его обязанности заканчиваются.

Например:

$ sudo -l
    (auth) NOPASSWD: /opt/auth/wrappers/ssh.py

$ sudo /opt/auth/wrappers/ssh.py -h

usage: ssh-wrapper [-h] [--user USER] [--port PORT] [--nosudo]
                   [--config CONFIG] [--debug] [--proxy-host PROXY_HOST]
                   [--proxy-user PROXY_USER] [--proxy-port PROXY_PORT]
                   [--proxy-id PROXY_ID]
                   hostname

positional arguments:
  hostname              server address (allowed FQDN,[a-z-],ip6,ip4)

optional arguments:
  -h, --help            show this help message and exit
  --user USER           set target username
  --port PORT           set target port
  --nosudo              run connection without sudo terminating command
  --debug
  --proxy-host PROXY_HOST
  --proxy-user PROXY_USER
  --proxy-port PROXY_PORT
  --proxy-id PROXY_ID   just for pretty logs

------

Этот скрипт также отвечает за логирование — он формирует имена лог файлов и их расположение, определяет имя пользователя, сделавшего sudo, создает каталоги для лог файлов. Рядом с каждым логом есть *.meta файл, содержащий объект текущего соединения в JSON.

Скрипт helper.py включает в себя все основные функции, изоляция с ssh.py позволит реализовать даже сложную логику без опасения ошибки с определением прав пользователя или какой либо еще небезопасной функцией.

В скрипт завернуты функции, используемые в shared/bootstrap.sh.

Например, поиск сервера:

s () {
    if [[ $# -eq 0 ]] ; then
        echo -e "\\n  Usage: s <query> \\n";
        return
    elif [[ $# -gt 0 ]] ; then
        "${ISOLATE_HELPER}" search "${@}";
    fi
}

Работать с прокси можно без установки дополнительных пакетов. Достаточно SSH-сервера и установленного на нем nc/netcat. Также можно использовать функцию проброса порта в современных SSHD/SSH, но эта методика не рекомендуется, так как еще довольно много устаревших SSHD, которые не поддерживают эту функцию.

При попытке соединиться функцией/alias g, также, вызывается helper.py, который проверяет аргументы, классифицирует адрес/IP/FQDN/project и запускает ssh.py с нужными аргументами. При попытке входа по IP/FQDN без указания project/group будет использован default конфиг для SSH.

Все настройки для сервера доступны только при точном указании, например:

$ g rogairoga nyc-prod-1

Или, если сервер находится за корпоративным прокси после имени проекта, можно указать любой адрес FQDN/IP.

$ g rogairoga 192.168.1.1

все обычные для g дополнительные аргументы также доступны:

$ g rogairoga 192.168.22.22 --port 23 --user support --nosudo

также есть возможность входа по ID сервера.

$ g 12345

Вместо заключения


Исходный код Isolate выложен на Github. Надеемся, что наше решение поможет многим DevOps-командам структурировать и упростить работу с серверами. Ждем комментариев, пожеланий и, конечно же, пул реквестов! Предложить идеи или задать вопросы можно в Телеграм-чате.

Наши дальнейшие планы:

  • разграничение прав доступа (пользователь-проект);
  • хелпер для трансфера файлов через auth сервер с/на конкретную машину;
  • интеграция с Zabbix (Tech Preview уже есть!).

И следом хотим заопенсорсить наш Телеграм-клиент — про неё можно почитать тут.
Tags:
Hubs:
+25
Comments 23
Comments Comments 23

Articles

Information

Website
www.itsumma.ru
Registered
Founded
Employees
101–200 employees
Location
Россия
Representative
ITSumma