зачем мне нужен сертификат для установления безопасного соединения gRPC в качестве клиента?

При использовании gRPC поверх обычного TCP, клиент устанавливает канал с сервером следующим образом (в рубине):

stub = Helloworld::Greeter::Stub.new(service_url, :this_channel_is_insecure)

но затем, когда я реализовать TLS на сервере и вставить мой сертификат LetsEncrypt на сервер, клиент должен установить такое безопасное соединение (в ruby):

creds = GRPC::Core::Credentials.new(load_certs)  # load_certs typically loads a CA roots file
stub = Helloworld::Greeter::Stub.new(service_url, creds)

Этот код с комментарием взят из официальных документов gRPC.

У меня вопрос, зачем клиенту здесь сертификат? Я думал, что сертификат нужен серверу, а клиент проверяет его действительность. Когда мой браузер подключается к защищенным веб-сайтам, приносит ли он собственный сертификат в таблицу? Если нет, то зачем он нужен gRPC-клиенту?

Насколько я знаю, клиент знает о некоторых доверенных центрах, с одним из которых связана цепочка сертификатов сервера. И комментарий в приведенном выше коде относится к «корневому файлу CA», который может быть сертификатом органа в верхней части цепочки. Так что, возможно, клиент gRPC сравнивает сертификат в корне цепочки сервера со своим собственным - но если это так, что произойдет, если он получит неправильный ЦС?

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

Что мне не хватает?

РЕДАКТИРОВАТЬ:

Я обнаружил на своем компьютере каталог с кучей того, что похоже на корневые сертификаты ЦС. / etc / ssl / certs / Один из них, похоже, является органом, который проверяет LetsEncrypt, который я использую на сервере, поэтому я попытался прочитать этот сертификат в клиенте следующим образом:

GRPC::Core::ChannelCredentials.new(File.read('/etc/ssl/certs/ISRG_Root_X1.pem'))

, но это только привело к этой ошибке

Не удалось выполнить рукопожатие с фатальной ошибкой SSL_ERROR_SSL: error: 1000007d: SSL подпрограммы: OPENSSL_internal: CERTIFICATE_VERIFY_FAILED.

0
задан 22 May 2019 в 10:12
1 ответ

gRPC в первую очередь предназначен для подключения служб путем вызова удаленных процедур, например для микросервисов. В отличие от односторонних доверительных отношений между веб-сервером и несколькими клиентами браузера, оба партнера должны явно доверять друг другу, чтобы избежать атак типа «злоумышленник в середине». gRPC предусматривает это специально для соединений, защищенных TLS.

В случае небезопасного (не защищенного TLS) соединения (предназначенного только для целей тестирования) для сервера gRPC параметр : this_port_is_insecure передается на (GRPC :: RpcServer. новый).add_http2_port и для каждого задействованного клиента gRPC параметр channel_args:: this_channel_is_insecure передается методу Core :: Stub.new .

Напротив, в случае защищенного соединения через TLS, GRPC :: Core :: ServerCredentials.new client_ca_pem, [{private_key: server_key_pem, cert_chain: server_cert_pem}], true должно быть передано для Сервер gRPC и GRPC :: Core :: ChannelCredentials.new server_ca_pem, client_key_pem, client_cert_pem должны быть переданы для каждого клиента.

Для всех переменных * _pem загружайте контент через File.read из соответствующих файлов PEM, предоставленных вашим центром доверия или, возможно, самостоятельно созданных ранее:

  • server_ca_pem - это центр сертификации, который подписал server_cert_pem
  • server_cert_pem - это цепочка сертификатов сервера, подтвержденная клиентом через server_ca_pem
  • server_key_pem - закрытый ключ сервера
  • client_ca_pem - центр сертификации, который подписал client_cert_pem
  • client_cert_pem - цепочка сертификатов клиента , подтвержденный сервером через client_ca_pem
  • client_key_pem - это закрытый ключ клиента

server_ca_pem и client_ca_pem могут быть или не совпадать. Используйте дополнительный GRPC :: Core :: CallCredentials , если вам нужно защитить отношения между сервисом и клиентом на уровне вызовов.

Руководство по аутентификации gRPC:

https://grpc.io/docs/guides/auth/

Примеры кода Ruby:

https://github.com/grpc/grpc/blob/master/ src / ruby ​​/ spec / channel_credentials_spec.rb

2
ответ дан 24 December 2019 в 16:09

Теги

Похожие вопросы