Зачем мне нужен сертификат для установки безопасного соединения gRPC в качестве клиента?
При использовании gRPC поверх обычного TCP клиент устанавливает канал с сервером следующим образом (в ruby):
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 сравнивает сертификат в корне цепочки сервера с собственным - но если это так, что произойдет, если он получит неправильный CA?
Все документы и публикации, объясняющие, как установить безопасное соединение от клиента gRPC, говорят, что читают сертификат из локального файла, но никто из них не говорит, что это за сертификат или откуда он взялся.
Что мне не хватает?
РЕДАКТИРОВАТЬ:
Я обнаружил на своем компьютере каталог с кучей корневых сертификатов CA. /etc/ssl/certs/
Один из них, по-видимому, является органом, который проверяет LetsEncrypt, который я использую на сервере, поэтому я попытался прочитать этот сертификат на клиенте следующим образом:
GRPC::Core::ChannelCredentials.new(File.read('/etc/ssl/certs/ISRG_Root_X1.pem'))
но это только привело к этой ошибке
Сбой при рукопожатии с фатальной ошибкой SSL_ERROR_SSL: ошибка:1000007d: подпрограммы SSL:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
0 ответов
G RPC в первую очередь предназначен для подключения служб путем вызова удаленных процедур, например, для микросервисов. В отличие от односторонних доверительных отношений между веб-сервером и несколькими клиентами браузера, оба вовлеченных партнера должны явно доверять друг другу, чтобы избежать атак типа "злоумышленник в середине". gRPC предусматривает это специально для подключений, защищенных TLS.
В случае небезопасного (не защищенного TLS) соединения (предназначенного только для целей тестирования) для сервера gRPC параметр
:this_port_is_insecure
передается в
(GRPC::RpcServer.new).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