# Security for the GRPC Server with TLS [gRPC](https://grpc.io/) has built-in support for [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) both for the server and client applications. From the [documentation](https://www.grpc.io/docs/guides/auth/): > 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](https://grpc.github.io/grpc/cpp/grpc__security__constants_8h.html) 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](./agent/scripts/init.d/openolt) 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](https://en.wikipedia.org/wiki/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