Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use SSL in gRPC client server communication

Tags:

ssl

grpc

I know nothing about SSL/TLS and am trying to use SSL/TLS channel in gRPC by following instructions found online. Here is the server code:

      std::string server_address("0.0.0.0:50051");
      GreeterServiceImpl service;
    
      grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp ={"a","b"};
      grpc::SslServerCredentialsOptions ssl_opts;
      ssl_opts.pem_root_certs="";
      ssl_opts.pem_key_cert_pairs.push_back(pkcp);
    
      std::shared_ptr<grpc::ServerCredentials> creds;
      creds = grpc::SslServerCredentials(ssl_opts);
    
      ServerBuilder builder;
      builder.AddListeningPort(server_address, creds);
      builder.RegisterService(&service);
      std::unique_ptr<Server> server(builder.BuildAndStart());

The server won't start and terminates with following error.

E1115 13:00:55.657846941   17129 ssl_transport_security.c:636] Invalid cert chain file.
E1115 13:00:55.657936436   17129 security_connector.c:830]   Handshaker factory creation failed with TSI_INVALID_ARGUMENT.
E1115 13:00:55.657954952   17129 server_secure_chttp2.c:344] {"created":"@1479243655.657946821","description":"Unable to create secure server with credentials of type Ssl.","file":"src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c","file_line":242,"security_status":1}
Server listening on 0.0.0.0:50051
Segmentation fault (core dumped)

All I want to do is just use SSL for server and client communication. Looks like I am missing proper certificates in the server and believe similar things needed in client. Since I don't have any background in SSL it would be great if anybody can point me to examples about how to create those certificates and use properly for gRPC communication.

like image 293
damleak Avatar asked Nov 16 '16 03:11

damleak


1 Answers

It appears to be problem with the way the certificates are created. I forgot the post in StackOverflow that had shown how to create the certificates. Used that method and plugged-in the key and certificates to make it work.

Here is how I created the key (server.key) and the certificates (server.crt).

    mypass="pass123"

    echo Generate server key:
    openssl genrsa -passout pass:$mypass -des3 -out server.key 4096

    echo Generate server signing request:
    openssl req -passin pass:$mypass -new -key server.key -out server.csr -subj  "/C=US/ST=CA/L=SanFrancisco/O=Google/OU=youtube/CN=localhost"

    echo Self-sign server certificate:
    openssl x509 -req -passin pass:$mypass -days 365 -in server.csr -signkey server.key -set_serial 01 -out server.crt

    echo Remove passphrase from server key:
    openssl rsa -passin pass:$mypass -in server.key -out server.key

    rm server.csr

Pay attention to the use of localhost here. Same should be used at the time of client channel creation. I modified the example from grpc code base to use these. The server that looked like below.

    std::string server_address("0.0.0.0:50051");
    GreeterServiceImpl service;

    std::string servercert = read_keycert("server.crt");
    std::string serverkey = read_keycert("server.key");

    grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp;
    pkcp.private_key = serverkey;
    pkcp.cert_chain = servercert;

    grpc::SslServerCredentialsOptions ssl_opts;
    ssl_opts.pem_root_certs="";
    ssl_opts.pem_key_cert_pairs.push_back(pkcp);

    std::shared_ptr<grpc::ServerCredentials> creds;
    creds = grpc::SslServerCredentials(ssl_opts);

    ServerBuilder builder;
    builder.AddListeningPort(server_address, creds);
    builder.RegisterService(&service);
    std::unique_ptr<Server> server(builder.BuildAndStart());
    server->Wait();

In client only certificate is required. Here is how it is used in my case.

    std::string cacert = read_keycert("server.crt");
    grpc::SslCredentialsOptions ssl_opts;
    ssl_opts.pem_root_certs=cacert;

    auto ssl_creds = grpc::SslCredentials(ssl_opts);
    GreeterClient greeter(grpc::CreateChannel("localhost:50051", ssl_creds));

The way the key and certificates are generated and used is different in each use case. I think if two servers communicate then these may be different. Not sure. Hope this helps some newbie to start with secure SSL/TLS in gRPC C++.

like image 127
damleak Avatar answered Sep 28 '22 16:09

damleak