Security for the GRPC Server with TLS

gRPC has built-in support for TLS both for the server and client applications.

From the documentation:

gRPC has SSL/TLS integration and promotes the use of SSL/TLS to authenticate the server, and to encrypt all the data exchanged between the client and the server. Optional mechanisms are available for clients to provide certificates for mutual authentication.

Options for TLS

For the server case, the enumeration grpc_ssl_client_certificate_request_type can be used how to respond to an incoming gRPC client.

The values of this enumeration are described by the following table:

| Enumerator | Description | |——————————————|———————————————-| | GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE | Server does not request client certificate.
The certificate presented by the client is not checked by the server at all.
(A client may present a self signed or signed certificate or not present a certificate at all and any of those option would be accepted) | | GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY | Server requests client certificate but does not enforce that the client presents a certificate.
If the client presents a certificate, the client authentication is left to the application (the necessary metadata will be available to the application via authentication context properties, see grpc_auth_context).
The client’s key certificate pair must be valid for the SSL connection to be established. | | GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY | Server requests client certificate but does not enforce that the client presents a certificate.
If the client presents a certificate, the client authentication is done by the gRPC framework.
(For a successful connection the client needs to either present a certificate that can be verified against the root certificate configured by the server or not present a certificate at all)
The client’s key certificate pair must be valid for the SSL connection to be established. | | GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY | Server requests client certificate and enforces that the client presents a certificate.
If the client presents a certificate, the client authentication is left to the application (the necessary metadata will be available to the application via authentication context properties, see grpc_auth_context).
The client’s key certificate pair must be valid for the SSL connection to be established. | | GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY | Server requests client certificate and enforces that the client presents a certificate.
The certificate presented by the client is verified by the gRPC framework. (For a successful connection the client needs to present a certificate that can be verified against the root certificate configured by the server)
The client’s key certificate pair must be valid for the SSL connection to be established. |

Initialization with TLS

The desired value is passed as an argument by the init script to the openolt application.

If the TLS option is an empty string the gRPC server is insecure, otherwise the corresponding TLS level is set.

Certificate Files

TLS requires valid certificates.

The following certificate files must be present at the keystore/ directory:

  • root.crt (CA public key),

  • server.crt (public key),

  • server.key (private key)

Self-signed certificates can be used.

Self-Signed Certificates

Self-signed certificates can be generated by the ubiquitous OpenSSL.

Note that the gRPC clients may require these certificates.

First create the keystore directory, if it is not created already. A few definitions will be useful, here domain is the ma1 IP address of the OLT which is “192.168.31.251”.

## on the test OLT

# openssl version
OpenSSL 1.0.1t  3 May 2016

# mkdir -p /broadcom/keystore

# cd /broadcom/keystore

# DOMAIN=192.168.31.251
# COMMON_NAME=$DOMAIN
# SUBJECT="/C=CA/ST=None/L=NB/O=None/CN=$COMMON_NAME"
# NUM_OF_DAYS=365

Generate the root certificates:

# openssl genrsa -out root.key 2048
Generating RSA private key, 2048 bit long modulus
........................................+++
..................................+++
e is 65537 (0x10001)

# openssl req -x509 -new -nodes -key root.key -sha256 -days $NUM_OF_DAYS -out root.crt
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:Santa Clara
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Netsia
Organizational Unit Name (eg, section) []:SEBA
Common Name (e.g. server FQDN or YOUR name) []:www.netsia.com
Email Address []:contact@netsia.com

Generate the extension file:

# cat << EOF > v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = $DOMAIN
IP.1 = $COMMON_NAME
EOF

# cat v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = 192.168.31.251
IP.1 = 192.168.31.251

Generate the server certificates:

# openssl req -new -newkey rsa:2048 -sha256 -nodes -keyout server.key -subj "$SUBJECT" -out server.csr
Generating a 2048 bit RSA private key
..........................................+++
..............................................................+++
writing new private key to 'server.key'
-----

# openssl x509 -req -in server.csr -CA root.crt -CAkey root.key -CAcreateserial -out server.crt -days $NUM_OF_DAYS -sha256 -extfile v3.ext
Signature ok
subject=/C=CA/ST=None/L=NB/O=None/CN=192.168.31.251
Getting CA Private Key

Test with Browsers

Browsers are quite exacting when it comes to certificates, and gRPC is not designed for browsers. Still the certificates may be checked with a common browser.

Assuming that the generated certificates will be used by the init script with the first and least-demanding TLS option, going to the URL https://192.168.31.251:9191/ will result in security warnings. Now the certificates can be checked using the browser itself.

Both Google Chrome and Mozilla Firefox respond in a similar way, since they don’t know beforehand the Certificate Authority which issued this certificate (self-signed, unknown entitities), they give strong warnings:

  • Google Chrome: NET::ERR_CERT_AUTHORITY_INVALID

  • Mozilla Firefox: SEC_ERROR_UNKNOWN_ISSUER