This is a prototype state, short term TODO to move close to BETA:

Initial version was tested on Centos 7.

Nokia gRPC services

Nokia SROS currently supports gNMI developed by google as open-sourced project and Nokia RibApi.

Contents of this repository:

Installing

In future grpc_shell will be published on pypi. Until then, just clone or download this repository and then in its root dir (where setup.py resides):

pip install --editable .

It is highly recommended to use grpc_shell inside python virtual enviroment. There are multiple ways how to create and manage virtual enviroments, the most simple and supported both in python2 and python3 is virtualenv.

pip install virtualenv
cd /my/venv/dir
virtualenv myvenv
source myvenv/bin/activate

Grpc setup on SROS

Working with md-cli in mixed or model-driven modes assumes that you will use all the awesome md-cli features to compare, validate and commit your config - short video intro.

Server

Grpc server is available in classic, mixed and model-driven configuration modes. Limitations for specific services are documented under shell.

You can check your current configuration mode with following command in either cli engine:

show system information | match "Configuration Mode"
Configuration Mode Cfg : model-driven
Configuration Mode Oper: model-driven

Configuration Mode Oper can signal syncing state, it is recommended to wait until this field has same value as Cfg field, so all features of configured mode are available.

Grpc server connections and RPC contexts are not affected by mode switch, so both will stay alive if you decide to transition from one mode to another.

Grpc server connections and RPC context doesnt support HA (high availibilty) on systems with redundant CPMs, so after switchover you need to reconnect all clients and recreate all RPC contexts.

gNMI is the only service which is by default enabled.

Basic classic-cli configuration with unsecure connection:

/configure system grpc
        allow-unsecure-connection
        rib-api
            no shutdown
        exit
        gnmi
            no shutdown
        exit
        no shutdown

Basic md-cli configuration with unsecure connection:

/configure system grpc
    admin-state enable
    allow-unsecure-connection
    gnmi {
        admin-state enable
    }
    rib-api {
        admin-state enable
    }

User access, profile and authorization

In order to be able to use grpc services on SROS, user has to have proper access and profile with the RPCs which he wants to use. gNMI and RibApi RPCs are by deafult permitted.

For command authorization rules please consult SROS documentation for given release.

Profile and user in classic-cli:

/configure system security profile "grpc"
                grpc
                    rpc-authorization
                        gnmi-capabilities permit
                        gnmi-get permit
                        gnmi-set permit
                        gnmi-subscribe permit
                        rib-api-modify permit
                        rib-api-getversion permit
                    exit
                exit
                entry 1
                    match "configure"
                    action permit
                exit

/configure system security user "grpc"
                password baran_ovca
                access grpc
                console
                    no member "default"
                    member "grpc"
                exit

Profile and user in md-cli:

/configure system security aaa local-profiles profile "grpc"
                grpc {
                    rpc-authorization {
                        gnmi-capabilities permit
                        gnmi-get permit
                        gnmi-set permit
                        gnmi-subscribe permit
                        rib-api-getversion permit
                        rib-api-modify permit
                    }
                }
                entry 1 {
                    action permit
                    match "configure"
                }

/configure system security user-params local-user user "grpc"
                password baran_ovca
                access {
                    grpc true
                }
                console {
                    member ["grpc"]
                }

TLS support

Grpc can be used with TLS server for secure transport in both server-side and mutual authentication modes. In mutual mode, server also checks client certificates.

Certificate importing

Creating certificates is out of scope of this document, but all the information can be found in openssl documentation.

For server side authentication we will need certificate for server signed by certification authority (cert_l1.crt), and servers private key which is used to encrypt the data communication (servkey_l1.crt).

For mutual authentication we will in addtion to previous files need also certification authority certificate (CAcert_l1.crt) and certificate revocation list (CAcrl_l1.crt).

Presuming we have all certificates copied on compact flash on SROS node in directory cf1:/gmi_tls/, we can use admin commands to import them (at the time of writing these docs, only classic-cli engine supported certificate management):

# certificate signed by CA - sent to client
/admin certificate import type cert input "cf1:/gmi_tls/cert_l1.pem" output cert_l1.crt format pem

# private key
/admin certificate import type key input "cf1:/gmi_tls/servkey_l1.pem" output servkey_l1.crt format pem

# CA certificate - used to checks client certificate in mutual authentication mode
/admin certificate import type cert input "cf1:/gmi_tls/CAcert_l1.pem" output CAcert_l1.crt format pem

# certificate revocation list, also used in mutual authentication mode
/admin certificate import type crl input "cf1:/gmi_tls/CAcrl_l1.pem" output CAcrl_l1.crt format pem

cert-profile, server-cipher-list and server-tls-profile

Configuring these three is required for both server and mutual authentication.

cert-profile, server-cipher-list and server-tls-profile in classic-cli:

# you can choose which ciphers will server support in server-cipher-list
/configure system security tls server-cipher-list "grpc_cipher_list" create
                    cipher 1 name tls-rsa-with3des-ede-cbc-sha
                    cipher 2 name tls-rsa-with-aes128-cbc-sha
                    cipher 3 name tls-rsa-with-aes256-cbc-sha
                    cipher 4 name tls-rsa-with-aes128-cbc-sha256
                    cipher 5 name tls-rsa-with-aes256-cbc-sha256

# cert-profile
/configure system security tls cert-profile "grpc_cert_profile" create
                    entry 1 create
                        cert "cert_l1.crt"
                        key "servkey_l1.crt"
                    exit
                    no shutdown

# finally to glue it all together, we can create server-tls-profile
/configure system security tls server-tls-profile "grpc_tls_profile" create
                    cert-profile "grpc_cert_profile"
                    cipher-list "grpc_cipher_list"
                    no shutdown

cert-profile, server-cipher-list and server-tls-profile in md-cli:

# you can choose which ciphers will server support in server-cipher-list
/configure system security tls server-cipher-list "grpc_cipher_list"
                    cipher 1 {
                        name tls-rsa-with3des-ede-cbc-sha
                    }
                    cipher 2 {
                        name tls-rsa-with-aes128-cbc-sha
                    }
                    cipher 3 {
                        name tls-rsa-with-aes256-cbc-sha
                    }
                    cipher 4 {
                        name tls-rsa-with-aes128-cbc-sha256
                    }
                    cipher 5 {
                        name tls-rsa-with-aes256-cbc-sha256
                    }

# cert-profile
/configure system security tls cert-profile "grpc_cert_profile"
                    admin-state enable
                    entry 1 {
                        certificate-file "cert_l1.crt"
                        key-file "servkey_l1.crt"
                    }

# finally to glue it all together, we can create server-tls-profile
/configure system security tls server-tls-profile "grpc_tls_profile"
                    admin-state enable
                    cert-profile "grpc_cert_profile"
                    cipher-list "grpc_cipher_list"

pki ca-profile and trust-anchor-profile

For mutual authentication we have to two additional objects.

classic-cli:

# ca-profile contains CA cert which will tell us if client
# tls certificate is legit and mandatory certificate revocation list
/configure system security pki ca-profile "grpc_pki_ca_profile" create
                    cert-file "CAcert_l1.crt"
                    crl-file "CAcrl_l1.crt"
                    revocation-check crl-optional
                    no shutdown

# trust-anchor for client authentication as reference to ca-profile
/configure system security tls trust-anchor-profile "grpc_trust_anchor" create
                    trust-anchor "grpc_pki_ca_profile"

# lastly we must inject trust-anchor-profile into previously created
# server-tls-profile under authenticate-client
/configure system security tls server-tls-profile "grpc_tls_profile"
                    authenticate-client
                        trust-anchor-profile "grpc_trust_anchor"

md-cli:

# ca-profile contains CA cert which will tell us if client
# tls certificate is legit and mandatory certificate revocation list
/configure system security pki
                    ca-profile "grpc_pki_ca_profile" {
                        admin-state enable
                        cert-file "CAcert_l1.crt"
                        crl-file "CAcrl_l1.crt"
                        revocation-check crl-optional
                    }

# trust-anchor for client authentication as reference to ca-profile
/configure system security tls trust-anchor-profile "grpc_trust_anchor"
                    trust-anchor "grpc_pki_ca_profile" { }

# lastly we must inject trust-anchor-profile into previously created
# server-tls-profile under authenticate-client
/configure system security tls server-tls-profile "grpc_tls_profile"
                    authenticate-client {
                        trust-anchor-profile "grpc_trust_anchor"
                    }

Debugging

Once the grpc server is up and all underlying protocols are set-up correctly, the server is usually quite verbose about the reasons that the RPC calls are failing.

show system grpc

===============================================================================
gRPC Server
===============================================================================
Administrative State      : Enabled
Operational State         : Up

Supported services
-------------------------------------------------------------------------------
gNMI Version              : 0.4.0
RibApi Version            : 1.0.0
===============================================================================

Routing and http proxy

Sanity test is to preform ping or ping6 towards remote side.

Grpc library is actively using http_proxy and https_proxy enviroment variables. On linux and mac you can check those with echo $http_proxy and echo $https_proxy, on windows its set HTTP from command line. In case you need to remove or change them for client session, there is no need to mess with global settings, you can instead just edit them in shell config file.

Cipher suites

Client and server must support at least one matching cipher suite. For client side you have to pick cipher suite appropriate for your server-cipher-list. This change can be also made in shell config file.

TLS layer

This is proper working setup of mutual authentication from server side, for server side authentication you can ignore trust-anchor-profile.

cert-profile

show system security tls cert-profile "grpc_cert_profile"

===============================================================================
Certificate Profile Entry "grpc_cert_profile"
===============================================================================
Id  Certificate File Name     Key File Name             Status Flags
-------------------------------------------------------------------------------
1   cert_l1.crt               servkey_l1.crt
===============================================================================

server-tls-profile:

show system security tls server-tls-profile "grpc_tls_profile"

===============================================================================
Server Profile Entry "grpc_tls_profile"
===============================================================================
Cipher List Name             : grpc_cipher_list
Certificate Profile Name     : grpc_cert_profile
Trust Anchor Profile Name    : grpc_trust_anchor
CN-List Name                 : (Not Specified)
===============================================================================

trust-anchor-profile:

show system security tls trust-anchor-profile "grpc_trust_anchor"

===============================================================================
CA-profile List for Trust Anchor "grpc_trust_anchor"
===============================================================================
CA Profile Name                                AdminState     OperState
-------------------------------------------------------------------------------
grpc_pki_ca_profile                            up             up
===============================================================================

No data is retrieved from server

If you get into situation where you can successfully subscribe (or get) and you can actually see that the subscription is present on server, but no data is comming from server, it may mean that your authorization rules are not correct. Please contact Nokia support or consult SROS documentation for your release.

Another case might be that data that you subscribed to doesnt actually exist yet on remote side. In this situation, the grpc server doesnt fail such subscription but instead waits until the data is available. You can check your config via md-cli engine, gNMI service on SROS is working with the same schema. Only exception is openconfig, where gNMI schema works from root of each module.

eg:

md-cli:
/configure openconfig network-instances network-instance

gNMI:
/network-instances/network-instance