В работе команды системных администраторов наступает момент, когда поддерживаемых серверов становится слишком много. А может быть еще и людей много, ну и опять же безопасность: если что-то пошло не так, нужно отовсюду ключи удалять.
У нас 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 уже есть!).
Автор: ITSumma