Как настроить и протестировать TLS в gRPC/gRPC-Web

Эта статья содержит примеры на Node.JS, но может быть полезна и для других языков, так что давайте начнем. Все рабочие примеры вы можете найти здесь.


Как работает TLS?

Рекомендую прочитать лучший комикс-статью о том, как работает TLS.

Типы соединений gRPC

Существует три типа соединений gRPC, которые вы можете использовать:

  1. Insecure — все данные передаются без шифрования.
  2. Server-Side TLS — шифрование как в браузере, где только сервер предоставляет TLS сертификат клиенту.
  3. Взаимный TLS — наиболее безопасный, когда и сервер, и клиент предоставляют друг другу сертификаты.

Создание самоподписанных сертификатов

Это необязательный шаг, если у вас нет сертификата от CA или вы хотите работать с TLS на localhost.

Обратите внимание, что в производственной среде для большей безопасности рекомендуется выбирать сертификат центра сертификации, например, вы можете получить бесплатный сертификат от Let’s Encrypt.


Подготовка

Давайте начнем с реализации нашего сервиса gRPC.

Во-первых, мы определим файл Protocol Buffers нашего сервиса.

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

protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt=env=node,outputServices=grpc-js --ts_proto_out=./src/generated ./proto/tls_service.proto
Вход в полноэкранный режим Выход из полноэкранного режима

Теперь мы можем реализовать наш сервер, работающий на Node.js.


gRPC

Здесь мы будем использовать официальный пакет @grpc/grpc-js как для серверной, так и для клиентской стороны.


TLS на стороне сервера

Для серверного TLS требуется только сертификат сервера и его закрытый ключ.

Сервер

Клиент

Теперь мы можем реализовать клиентскую часть.

Обратите внимание, что если ваш сертификат TLS подписан CA (не самоподписанный), вам не нужно предоставлять этот сертификат на клиенте, он должен работать автоматически.


Взаимный TLS

Взаимный TLS требует корневой сертификат, сертификат сервера и его закрытый ключ.
Корневой сертификат используется здесь для проверки того, что сертификат клиента подписан и сервер может доверять клиенту.

Сервер

Как и в разделе Server-Side, изменена только функция getServerCredentials.

Клиент

Как и в разделе Server-Side, изменена только функция getChannelCredentials.


Переопределить имя цели SSL

Пакет @grpc/grpc-js дополнительно предоставляет несколько полезных опций канала, которые вы можете установить. Вы можете прочитать о каждой из них здесь.

grpc.ssl_target_name_override — будет полезно, когда фактический сервер за прокси и CN не совпадают.

Для настройки опций канала необходимо передать их в третий аргумент конструктора клиента.


gRPC-Web

Прочитайте статью в блоге grpc.io о состоянии gRPC-Web.

TL;DR
То, что вы должны знать:

  1. Схема работы:
    Клиент ↔ Прокси [HTTP(S) gRPC-Web] ↔ Сервер (gRPC).

  2. Существует две реализации — официальная gRPC-Web и @improbable-eng/grpc-web.

  3. На данный момент gRPC-Web поддерживает только унарные и серверно-потоковые запросы через HTTP(S).

    Кроме того, @improbable-eng/grpc-web поддерживает клиентскую и двунаправленную потоковую передачу с экспериментальным транспортом websocket. Это не является частью спецификации gRPC-Web и не рекомендуется для производственного использования.

  4. Есть два прокси — Envoy с фильтром gRPC-Web от официального gRPC-Web и grpcwebproxy от @improbable-eng.

  5. Вы можете использовать любой клиент с любым прокси.

  6. Клиенты имеют разные транспорты связи.

    Официальный gRPC-web поддерживает только XMLHttpRequest.
    @improbable-eng/grpc-web дополнительно поддерживает Fetch (используя его, если он доступен) и может быть расширен пользовательским транспортом, например, Node.js.

В этом примере мы будем использовать Envoy proxy, запущенный в docker.


TLS на стороне сервера

Сервер

Как вы уже заметили, нам нужно запустить наш gRPC-сервис за прокси. Поэтому ничего менять не нужно, просто запустите службу с помощью Server-Side TLS, о котором мы говорили ранее.

После этого нам нужно настроить envoy и запустить его.

docker-compose up envoy-server
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот и все. Ваш gRPC-Web прокси с Server-Side TLS будет доступен по адресу https://0.0.0.0:8080.

Взаимный TLS

Сервер

Хак здесь заключается в том, чтобы запустить службу gRPC с Server-Side TLS, но на стороне envoy проверить сертификат клиента, подписанный доверенным CA.

docker-compose up envoy-mutual
Вход в полноэкранный режим Выход из полноэкранного режима

Отлично! Ваш gRPC-Web прокси с взаимным TLS будет доступен по адресу https://0.0.0.0:8080.


Тестирование запросов как gRPC, так и gRPC-Web

Недавно я выпустил мультиплатформенный десктопный gRPC / gRPC-Web клиент под названием ezy. Я работаю с gRPC каждый день, и нет ни одного полнофункционального, UI/UX-совершенного клиента для тестирования gRPC, поэтому я попытался создать такой клиент.

Этот клиент имеет полную поддержку gRPC / gRPC-Web. Я буду признателен, если вы попробуете его.

🙏 Если у вас есть какие-либо отзывы или идеи, не стесняйтесь, открывайте обсуждение.

Оцените статью
devanswers.ru
Добавить комментарий