Военная архитектура SSH. Узел-бастион и принцип нулевого доверия

jc6ub3npquujkjxz4tpzq7w5vza.jpeg


В инфраструктуре организации есть такое понятие, как узел-бастион — специальный компьютер в сети, обычно на внешней стороне демилитаризованной зоны (ДМЗ) организации. Узел назван по военной терминологии. Если кто видел средневековые крепости, там есть специфические выступы — бастионы, как на КДПВ.

То же самое в компьютерных сетях. Например, перед защищённой компьютерной сетью ставится специальный сервер, через который пробрасывается SSH-туннель в свою частную сеть. Данный «бастион» организуется в соответствии с концепцией нулевого доверия, которая предполагает абсолютное недоверие ко всем объектам и пользователям как снаружи организации, так и внутри неё.
Есть несколько вариантов, как технически организовать такую схему. Можно всё сделать самому, а можно использовать готовые сервисы SaaS, которые решают эту задачу.

Узлы-бастионы используются для разных целей, в том числе:

  • как веб-сервер,
  • DNS-сервер,
  • почтовый сервер (например, SMTP),
  • FTP-сервер,
  • прокси,
  • NNTP-сервер,
  • ловушка (honeypot),
  • VPN-сервер,
  • и др.


Если узел используется для доступа к частной сети, его также называют джамп-сервером.

▍ Что такое джамп-сервер


Джамп-сервер (jump server) предоставляет доступ к сервисам внутренней инфраструктуры. Соответственно, для всех внешних (а то и внутренних) пользователей доступ к этим внутренним сервисам осуществляется только через бастион. В принципе, тут нет ничего сложного, а типичные решения для организации SSH-туннелей хорошо описаны на Хабре. Более конкретную инструкцию см. в статье «Помощь друзьям с использованием OSS для удалённого администрирования при наличии публичного IP-адреса».

4a80a3911a55ace19d36bf9b164c7cd8.png


Проблемы начинаются при масштабировании. Если мы организуем постоянный доступ для множества пользователей (например, для сотрудников организации), то такой сервер требует обслуживания и специальной настройки. Нам необходимы:

  • особая конфигурация для доступа к конкретной среде (например, RDP и Windows);
  • обязательное обновление последними патчами безопасности;
  • ротация SSH-ключей и обновление, когда приходят/уходят сотрудники (ротация ключей SSH в любом случае необходима даже без изменения штатного списка — часто для этого применяют специальные модули или службы, то есть это ещё одна отдельная задача);
  • управление ролями через sudo, проверка правильности настроек разрешений файловой системы и принадлежности пользователей к соответствующим группам. Нужно строго ограничивать возможности пользователей, чтобы они не навредили себе и другим, а именно:
  • специальный инструментарий;
  • список актуальных сервисов, доступных для взаимодействия (это может быть статический файл, известное имя DNS или документация, как взаимодействовать с этими серверами).


Для управления подобными серверами используют инструменты автоматизации, такие как Terraform, Packer и Ansible.

Поддержка этой инфраструктуры становится дополнительной нагрузкой, которая ложится на плечи штатных инженеров и сисадминов. Никто не будет нанимать отдельный персонал для такой роли, хотя сама задача становится всё более сложной: растёт и нагрузка на сервер, и количество пользователей, и количество инструментов.

Взаимодействие с джамп-сервером осуществляется с помощью SSH-клиента. Это тоже представляет определённую проблему, потому что не всегда легко через SSH-клиент получить все нужные данные из службы внутри VPN. Необходимо сначала установить SSH-соединение с джамп-сервером, потом с другим сервером, затем скопировать искомое содержимое в файл (например, при помощи scp). Вот нативный подход такого взаимодействия:

$ ssh -A bob@jump-server
$ ssh bob@internal-server '/usr/local/bin/myscript.sh > output.csv'
$ scp bob@internal-server:output.csv . && exit
$ scp bob@jump-server:output.csv .


Локальный проброс портов:

$ ssh -N bob@jump-server -L 8080:internal-web-server:3000


Работу с джамп-сервером облегчает ssh-agent. Это специфический клиент SSH, который хранит данные аутентификации за пределами одной сессии, способен хранить в памяти расшифрованные ключи и устанавливать соединение с SSH-клиентами через IPC-сокет (сокет межпроцессного взаимодействия. Подробнее об SSH-агентах см. здесь.

▍ Менеджмент джамп-сервера


Для управления инфраструктурой джамп-серверов созданы даже специальные (коммерческие) сервисы, такие как Hoop. В данном случае вместо управления джамп-сервером и всеми инструментами на нём мы управляем агентами, где изначально заложены необходимые инструменты и примитивы. Это замена одной плоскости менеджмента на другую (теоретически, более удобную).

ueokl64i8yntgf8cwb35ze4xlni.png


Здесь реализована собственная платформа идентификации, автоматическая ротация ключей SSH, назначение ролей пользователей. Все настройки для sudoers, серверов DNS и прочего делаются автоматически через SSH-агента (hoop).

rupnxn_milaw0wzkpzqvmlebbqs.png


Некоторые примеры из официальной документации.

Подключение к инстансу postgres на локальном порту:

$ hoop connect postgres-prod


Проброс порта внутреннего API:

$ hoop connect my-internal-api -p 8000


Создать интерактивную консоль Rails или сессию Django:

$ hoop connect rails-console-homolog
$ hoop connect django-prod


Выполнить скрипт непосредственно в приложении Rails:

$ hoop exec rails-exec-prod <


В общем, неплохой инструмент для джамп-сервера в дополнение к стандартным клиентам SSH, RDP и VPN.

▍ Zrok: P2P-туннели на OpenZiti


Ещё одна новая опенсорсная разработка — система Zrok на базе OpenZiti, создающая безопасный туннель между разными средами, сетями, VPN и т. д.

Вот как выглядит туннель Shares — Public между приватной сетью и открытым интернетом для публичной раздачи (шаринга) ресурсов:

ma1nspv5kleroib7ufhnq5e6f3s.png


При этом на «публичной» стороне туннеля не требуется установка какого-то специализированного программного обеспечения, клиента zrok и др. То есть система ориентирована на максимально быстрое и простое использование, в том числе неподготовленными людьми.

Другой вариант — пиринговый туннель Shares — Private между двумя приватными сетями (или персональными компьютерами):

wvxnvtg4ncti1b5mnvm5h8etuuu.png


В данном случае безопасный зашифрованный туннель устанавливается между клиентами zrok (доступны в виде бинарников).

Типичные варианты использования публичного гейта:

  • предоставление доступа к своему серверу разработки для друзей и коллег;
  • быстрый хук на свой сервер в облаке (например, AWS) для доступа извне;
  • публикация в открытом доступе файлов или других ресурсов со своего сервера (например, порт);
  • децентрализованный хостинг файлов, репозиториев, видео (в будущем).


couelg8xj-b5x0rps0dleknyefg.png


Все генерируемые URL по умолчанию эфемерны, то есть прекращают существование сразу после того, как останавливается раздача ресурсов с сервера (в отличие от опции Shares — Reserved, которая генерирует долговременные, постоянные URL).

Примеры команд из документации.

Установка нового контроллера zrok.mydomain.com вместо адреса по умолчанию api.zrok.io:

$ zrok config set apiEndpoint https://zrok.mydomain.com


Теперь установка соединения между серверами и клиентами будет происходить через новый контроллер.

Раздача файлов с сервера:

$ zrok share public . --backend-mode web


После этой команды файлы на сервере становятся доступны по публичным URL такого типа:

ox0tjk6oucvgq2kozotbaanx6qu.png


Платформа Zrok доступна как облачный сервис SaaS или в варианте self-hosted для установки на своём сервере бесплатно (репозиторий Github). В обоих случаях Zrok работает как отдельный узел (контроллер), связывающий серверы и клиентов. Такой же «бастион» перед частной сетью, как в военной архитектуре. Несмотря на интеллектуальный статус информационной безопасности, в ней на удивление часто используется военная терминология.
Примечание. OpenZiti (и Zork) — одна из технологий для удобного шаринга ресурсов между компьютерами, устройствами и приложениями (приватный VPN или zero trust network). В качестве альтернативных инструментов можно использовать Tailscale, ZeroTier, Cloudflare Tunnels, Yggdrasil и др.

© Habrahabr.ru