Как стать автором
Обновить
238.3
KTS
Создаем цифровые продукты для бизнеса

Firezone, или как спрятать свою инфраструктуру от посторонних глаз

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров6.1K

Привет! Меня зовут Даниил Донецков, я DevOps-инженер в KTS.

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

Мы решили проблему с помощью сервиса Firezone, и в этой статье я хочу поделиться нашим опытом. Сегодня я расскажу о том, как DevOps-юнит KTS:

  • внедрил виртуальную сеть в существующую инфраструктуру, состоящую из двух k8s-кластеров и нескольких ВМ в разных облаках;

  • обеспечил бесперебойный доступ для более чем 150 сотрудников к веб-сервисам.

Оглавление

Почему Firezone

Наш выбор пал на Firezone по нескольким причинам.

  • Сервис имеет открытый исходный код. Он активно поддерживается, регулярно обновляется и улучшается.

  • Изначально Firezone спроектирован для горизонтального масштабирования. Следовательно, при работе с ним можно просто поднять новый сервер и запустить на нем дополнительный компонент частной сети.

  • Основан на протоколе WireGuard, что гарантирует скорость и безопасность.

  • Управляется и настраивается из веб-интерфейса, поэтому для настройки не приходится вручную менять конфиги на серверах.

  • Можно закрыть сеть от сторонних пользователей через интеграцию с сервисом Keycloak.

  • Можно включать по доменам. Если домен переедет, Firezone сам позаботится о том, что вы получите доступ к ресурсу.

Примечание: в документации Yandex Cloud есть инструкция по установке Firezone, но относится она к версиям Firezone 0.7.*. Мы же поговорим о том, как развернуть версии 1.*.*, у которых есть заметные преимущества (о них ниже).

Сборка

Сборку мы использовали из репозитория разработчиков на GitHub, но немного переделали ее под свои нужды.

По сути, мы допиливали только «голову» — API, Domain и Web. В Web мы исправляли скрипты для деплоя сетевых компонентов (Relay и Gateway, о них поговорим отдельно), фиксировали версию и игрались с параметрами.

Для самих сетевых компонентов мы решили не переделывать Docker-образы, поскольку для наших целей хватает и общедоступных.

Подготовка Helm Chart

В своем репозитории разработчики для тестирования запустили голову через Docker-Compose. Так же они форкнули репозиторий с чартом, но не поддерживают и не актуализируют его.

Мы же форкнули оригинальный репозиторий и добавили в него:

  • CronJob для вытягивания пользователей из Kecyloak: голова Firezone не умеет самостоятельно синхронизировать пользователей с сервисами аутентификации, и для решения этой проблемы мы добавили в наш Helm chart кронджобу, которая каждый час синхронизирует пользователей, добавляя их в основную группу;

  • джобу для инициализации организации, поскольку по умолчанию в Firezone подразумевается подключение внутрь контейнера и выполнение всех команд вручную на языке Elixir.

Запуск в Kubernetes

Мы запускаем Firezone в k8s через Terraform. Весь процесс инициализации занимает меньше часа, после чего Firezone уже готов к работе.

Вся прелесть версий 1.*.* в том, что голова (в документации называемая «Portal») не обязана быть развернута на сервере, через который будет выполняться подключение к сервисам. Таким образом, обслуживать голову становится заметно легче.

Инициализация организации

Для инициализации организации нужно выполнить следующие действия:

  1. Подключиться к поду firezone-web:
    kubectl exec -n firezone -it deployment/firezone-web -- bash

  1. Запустить окружения Elixir:
    bin/web remote

  1. Создать аккаунт:
    {:ok, account} = Domain.Accounts.create_account(%{name: "<ACCOUNT_NAME>", slug: "<ACCOUNT_SLUG>"})

  1. Создать провайдера Keycloak:
    {:ok, openid_connect} = Domain.Auth.create_provider(account, %{name: "<PROVIDER_NAME>", adapter: :openid_connect, adapter_config: %{"auto_create_users" => true, "client_id" => "firezone", "client_secret" => "<CLIENT_SECRET>,"response_type" => "code","scope" => "openid email profile offline_access","discovery_document_uri" => "<KEYCLOAK_DOCUMENT_URI>","redirect_uri" => "https://<FIREZONE_HOST>/auth/oidc/<PROVIDER_NAME>/callback/"}})

  2. Создать первого админ-пользователя:
    {:ok, actor} = Domain.Actors.create_actor(account, %{type: :account_admin_user, name: "<ADMIN NAME>"})

  3. Создать идентификатор для первого админ-пользователя:
    {:ok, identity} = Domain.Auth.upsert_identity(actor, openid_connect, %{provider_identifier: "<ADMIN_EMAIL>", provider_identifier_confirmation: "<ADMIN_EMAIL>"})

  4. Разблокировать расширенную функциональность:
    account |> Ecto.Changeset.change(features: %{flow_activities: true,policy_conditions: true,multi_site_resources: true,traffic_filters: true,self_hosted_relays: true,idp_sync: true,rest_api: true})|> Domain.Repo.update!()

После этого вы сможете войти в ваш аккаунт:

Авторизация через Keycloak будет выглядеть следующим образом:

Добавление ресурсов

Для начала надо создать ресурс Site. Это группа сервисов (сайтов, виртуальных машин, подсетей), в которые будет открыт доступ из конкретных шлюзов.

После создания сайта в интерфейсе откроется его вкладка. В нем можно добавить новые шлюзы и ресурсы (ip-адреса, подсети и домены).

Деплой Gateway-сервисов

Gateway-сервисы, или шлюзы — это двоичные файлы Linux, которые работают в вашей инфраструктуре. Их можно развернуть и в виде контейнеров Docker, и в виде служб systemd через дефолтный скрипт, или же взять минимально рекомендуемые настройки системы для запуска шлюза и сделать свой вариант запуска.

Шлюзы были разработаны как переносимые, чрезвычайно легкие и не требующие внешних зависимостей. Это упрощает их развертывание и управление ими в больших масштабах.

Работают шлюзы без необходимости в постоянном хранилище; вместо этого для их правильного функционирования требуется настроить лишь несколько переменных среды. Дополнительную информацию об их деплое см. в руководстве по развертыванию шлюзов.

Firezone предоставляет 4 готовых варианта развертывания шлюзов — через systemd, Docker, Terraform и кастомный. По сути это вкладки с готовым кодом, который можно просто скопировать и выполнить на нужной машине. Этот готовый код пришлось немного допилить, чтобы команды работали сразу, и любой сотрудник с необходимым доступом смог бы создать или масштабировать систему. В результате получилось довольно удобно.

Чаще всего мы пользуемся systemd. Надо признать, что это не самый удобный способ, поскольку при ошибке в запуске приходится вытаскивать скрипт, дебажить его и запускать корректно. Однако основная масса шлюзов у нас развернута именно через systemd, и работают они стабильно и без перебоев.

При этом помимо перечисленных способов есть еще один, неочевидный — деплой через Helm chart. В стандартных вариантах деплоя его нет, но Helm chart для Gateway можно найти на GitHub. Gateway-сервис, развернутый в k8s-кластере, позволяет обращаться к сервисам внутри Kubernetes по DNS кластера (к примеру, postgres.database.svc.cluster.local).

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

  • пользователям группы DataScience доступны ресурсы  **.database.svc.cluster.local (все сервисы в неймспейсе Database);

  • пользователям группы KubernetesAdmins доступны ресурсы  **.svc.cluster.local (все сервисы в Kubernetes).

Деплой Relay-сервисов (отдельные STUN-серверы)

Relay (ретрансляторы) помогают клиентам устанавливать прямые соединения со шлюзами, используя метод обхода NAT, стандартизированный как STUN. Это хорошо работает в подавляющем большинстве случаев.

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

  • клиент или шлюз находятся за особенно строгим брандмауэром, который иногда называют симметричным NAT. Такие брандмауэры чаще встречаются в корпоративных средах, но в последние годы их использование сокращается;

  • сетевая среда клиента или шлюза блокирует трафик WireGuard. Это случается редко, но может произойти в некоторых общедоступных сетях Wi-Fi и даже в некоторых странах.

В этих случаях Relay выступает в качестве посредника, реализуя протокол TURN для надежной передачи трафика между клиентом и шлюзом независимо от любых сетевых ограничений. Весь трафик в Firezone полностью зашифрован с помощью WireGuard.

Ретрансляторы не имеют возможности расшифровывать или иным образом изменять передаваемые данные. Они распределены в нескольких регионах, чтобы обеспечить низкую задержку и надежную связь, где бы ни находились сотрудники. К сожалению, и здесь не обошлось без ложки дегтя — поддержка systemd в оригинальном репозитории не выполняется уже давно, и скрипты в нем не работают. 

Однако коммьюнити не дремлет: к примеру, тут можно найти инструкцию для поднятия Relay через systemd. Сразу оговорюсь: запуск двух ретрансляторов на одном сервере — подход сомнительный и нестабильный, они валятся с ошибкой занятого адреса. Лучший вариант — запускать по одному Relay-сервису на одной машине, и машин должно быть как минимум две.

Мы же запустили ретрансляторы в YC с помощью Terraform.

Закрытие ресурсов от Ethernet

Посмотрим на примерах, как закрыть ресурсы наших сервисов от общего доступа.

  • В k8s — отдельный ingress для админской консоли поднимается со следующей анотацией:
    nginx.ingress.kubernetes.io/whitelist-source-range: "{gateway_ip}"

  • Для сервисов на ВМ с доступом через nginx:
    Location /admin {
    allow {gateway_ip};
    deny all;
    }

Заключение

Несмотря на некоторые пляски с бубном в процессе, в итоге мы получили рабочее решение и смогли обеспечить нашим сотрудникам стабильный доступ к защищенным ресурсам под одними кредами. Отдельно Firezone радует удобным управлением доступами и простым деплоем новых сетевых компонентов.

Кстати, у коммьюнити Firezone есть активный Discord-канал. Сам я неоднократно писал туда при возникновении проблем с деплоем, поддержкой и обслуживанием сервиса. В канале можно задать любой вопрос. Особенно приятно, что быстро отвечают не только активные пользователи, но и разработчики сервиса.

Надеюсь, наш опыт будет вам полезен. Если у вас возникнут вопросы — задавайте их в комментариях, буду рад обсудить.

Также рекомендую почитать статьи моих коллег для DevOps-инженеров:

И, наконец, напоминаю о том, что мы регулярно проводим DevOps-челленджи и награждаем победителей крутым мерчом. Доступ к архивным челленджам всегда открыт, так что вы можете начать готовиться к будущим испытаниям уже сейчас. Переходите в бота по ссылке, и он расскажет вам подробности.

Удачи!

Теги:
Хабы:
Всего голосов 52: ↑52 и ↓0+55
Комментарии3

Публикации

Информация

Сайт
kts.tech
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия