Skip to content

Commit

Permalink
update transceiver sensor path
Browse files Browse the repository at this point in the history
  • Loading branch information
dsx1123 committed Jan 8, 2024
1 parent ba8d6a8 commit 4d1c269
Show file tree
Hide file tree
Showing 51 changed files with 15,188 additions and 17 deletions.
294 changes: 294 additions & 0 deletions docs/Telemetry/gNMI/2
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
# Certificate requirements for secure connections

As per [gnmi specification](https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#31-session-security-authentication-and-rpc-authorization):
!!! quote "3.1 Session Security, Authentication and RPC Authorization"
The session between the client and server MUST be encrypted using TLS - and a target or client MUST NOT fall back to unencrypted sessions.

NX-OS only supports TLS connection on gRPC, mTLS is supported since 10.1(1). There are two certiciates used here:

- Server certificate: Used to encrypt the gRPC connection between the client and the device (in this case, the gNMI server or target)
- Client certificate: Used to authenticate a gRPC connection

To create any type of certificate, a certificate authority (CA) is required. If you don't have one (or you are looking for something free), follow the steps in this excelent guide by Jamie Nguyen: [OpenSSL Certificate Authority](https://jamielinux.com/docs/openssl-certificate-authority/introduction.html)

An acurate time is important when dealing with TLS certificates. It is recommended to setup NTP in the client and servers/devices. If you see errors related to certificate not valid yet or expired it is probably that the device or the client don't have a correct time set.

For simplicity, this tutorial uses root but other users with less priviledges can be used.

Make sure keys and certificates are protected

Tests for this tutorial are done using [gnmic](https://github.com/karimra/gnmic) and [pygnmi](https://pypi.org/project/pygnmi/)

## Server certificate

A server certificate will allow you to connect to a NX-OS device securely, without need of skipping TLS verification for TLS connections.

!!! note ""
It is assumed that you have a valid root and intermediate CA certificates installed in your workstation. Instructions can be found at the top of this article on how to set that up

#### Add the subjectAltName setting

Use the intermediate/openssl.cnf file (server_cert section):

```
[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
subjectAltName=${ENV::SAN}
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
```

The value `${ENV::SAN}` instructs openssl to look for the value of the subjectAltName in an environmental variable called _SAN_

#### Set the SAN variable.

If you don't have a DNS available, you can manually add the host entry in the /etc/hosts file if you would like to use names instead of IPs. Either one works

In this example, the device name is nx93000v-01.cisco.com and its management IP is 192.168.1.1

```bash
export SAN=DNS:nx9300v-01,DNS:nx9300v-01.cisco.com,IP:192.168.1.1
```
#### Create key and certificate

Altough the file name is trivial, it is a best practice to use the hostname of the device or other identifier that sumarizes the purpuse of the certificate.

!!! note
You can use the same certificate for multiple devices
Make sure to use server_cert extensions

```bash
openssl genrsa -out intermediate/private/nx9300v-01.cisco.com.key.pem
```
```
openssl req -config intermediate/openssl.cnf -key intermediate/private/nx9300v-01.cisco.com.key.pem -new -sha256 -out intermediate/csr/nx9300v-01.cisco.com.csr.pem
```

??? example "Output"
```
(...)
-----
Country Name (2 letter code) [GB]:US
State or Province Name [England]:CO
Locality Name []:
Organization Name [Alice Ltd]:Nexus
Organizational Unit Name []:Datacenter
Common Name []:nx9300v-01.cisco.com
Email Address []:
```

```
openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/nx9300v-01.cisco.com.csr.pem -out intermediate/certs/nx9300v-01.cisco.com.cert.pem
```
#### Verify the certificate

Check that the alternative name section is present and has the values set in the previous step

```bash
openssl x509 -noout -text -in intermediate/certs/nx9300v-01.cisco.com.cert.pem
```
#### Create the certificate chain

```bash
cat intermediate/certs/nx9300v-01.cisco.com.cert.pem > intermediate/certs/nx9300v-01.cisco.com.chain.cert.pem
cat intermediate/certs/intermediate.cert.pem >> intermediate/certs/nx9300v-01.cisco.com.chain.cert.pem
cat certs/ca.cert.pem >> intermediate/certs/nx9300v-01.cisco.com.chain.cert.pem
```
#### Export the file into the device.

!!! note
Make sure to remember the export password

```bash
openssl pkcs12 -export -out intermediate/certs/nx9300v-01.cisco.com.pfk -inkey intermediate/private/nx9300v-01.cisco.com.key.pem -in intermediate/certs/nx9300v-01.cisco.com.chain.cert.pem
scp intermediate/certs/nx9300v-01.cisco.com.pfk [email protected]:
```
#### Import the pkcs12 file

Execute the following commands on the device. For this example, "supersecret" was used as password the step before

```cli
nx9300v_01# configure
nx9300v_01(config)# crypto ca trustpoint server
nx9300v_01(config)# crypto ca import server pkcs12 bootflash:nx9300v-01.cisco.com.pfk supersecret
```

Configure grpc to use the truspoint above:
```
nx9300v_01(config)# grpc certificate server
```
#### Test with gnmic

Use the certificate chain file, not the standalone certificate file. The --skip-verify option should not be needed

```
# gnmic -a nx9300v-01.cisco.com:50051 -u admin -p YOURPASSWORD get --path /System/name --tls-cert intermediate/certs/nx9300v-01.cisco.com.chain.cert.pem --tls-key intermediate/private/nx9300v-01.cisco.com.key.pem -e json --tls-ca intermediate/certs/ca-chain.cert.pem
```

??? example "Output"

```json
[
{
"source": "nx9300v-01.cisco.com:50051",
"timestamp": 1657660857691587822,
"time": "2022-07-12T21:20:57.691587822Z",
"updates": [
{
"Path": "System/name",
"values": {
"System/name": "nx9300v-01"
}
}
]
}
]
```

#### Test with pygnmi

!!! note
For simplicity, this example includes credentials in clear text, which is not a best practice.

```python
# Modules
from pygnmi.client import gNMIclient
import json
# Variables
host = ('nx9300v-01.cisco.com', '50051')
paths = ['/System/name']

# Body
if __name__ == '__main__':
with gNMIclient(target=host, username='admin', password="YOURPASSWORD", path_cert="./ca/intermediate/certs/nx9300v-01.cisco.com.chain.cert.pem",
path_key="./ca/intermediate/private/nx9300v-01.cisco.com.key.pem", path_root="./ca/intermediate/certs/ca-chain.cert.pem") as gc:
result = gc.get(path=paths, encoding='json')
print(result)
```


```
# python get-nx.py
```
??? example "Output"
```json
{'notification': [{'timestamp': 1657660901108756130, 'update': [{'path': 'System/name', 'val': 'nx9300v-01'}]}]}

```

## Client certificate

If you prefer to use a certificate and key instead of a password, you can create a client certificate that can be used to authenticate against the NX-OS device.
It is assumed that you have a valid root and intermediate CA certificates installed in your workstation. Instructions can be found at the top of this article on how to set that up

#### Create key and certificate

Altough the file name is trivial, it is a best practice to use the username or other identifier that sumarizes the purpuse of the certificate, csr and keys.

!!! note
- Make sure to use usr_cert extensions
- Use the username as value for _Common Name_ and _Organizational Unit Name_

```
openssl genrsa -out intermediate/private/admin.key.pem 2048
```

```
openssl req -config intermediate/openssl.cnf -key intermediate/private/admin.key.pem -new -sha256 -out intermediate/csr/admin.csr.pem
```

!!! example
```
-----
Country Name (2 letter code) [GB]:US
State or Province Name [England]:CO
Locality Name []:
Organization Name [Alice Ltd]:Nexus
Organizational Unit Name []:admin
Common Name []:admin
Email Address []:
```
```
openssl ca -config intermediate/openssl.cnf -extensions usr_cert -days 375 -notext -md sha256 -in intermediate/csr/admin.csr.pem -out intermediate/certs/admin.cert.pem
```

#### Create the certificate chain

```bash
cat intermediate/certs/admin.cert.pem > intermediate/certs/admin.chain.cert.pem
cat intermediate/certs/intermediate.cert.pem >> intermediate/certs/admin.chain.cert.pem
cat certs/ca.cert.pem >> intermediate/certs/admin.chain.cert.pem
```

#### Import the CA certificate

For this example, gnmi-root is used as trustpoint name but it can have any name. Use the content of the root certificate only (certs/ca.cert.pem) - no chains or intermediate certs are required

Execute the following commands on the device:

```
nx9300v_01# configure
nx9300v_01(config)# crypto ca trustpoint gnmi-root
nx9300v_01(config)# crypto ca authenticate gnmi-root
input (cut & paste) CA certificate (chain) in PEM format;
end the input with a line containing only END OF INPUT :
-----BEGIN CERTIFICATE-----
(...)
-----END CERTIFICATE-----
END OF INPUT
(...)

Do you accept this certificate? [yes/no]:yes
```

Configure the grpc client root certificate:
```
nx9300v_01(config)# grpc client root certificate gnmi-root
```

#### Create gnmic config file

> You might need to change the tls files path to match your environment

> Password is not required anymore

```
# cat .gnmic.yaml
log-file: /tmp/gnmic.log
debug: true
tls-ca: ./intermediate/certs/ca-chain.cert.pem
targets:
192.168.1.2:50051:
username: admin
tls-cert: ./intermediate/certs/admin.chain.cert.pem
tls-key: ./intermediate/private/admin.key.pem
```

#### Test with gnmic

```
# gnmic get --path /System/name
[
{
"source": "192.168.1.2:50051",
"timestamp": 1663693091279809206,
"time": "2022-09-20T12:58:11.279809206-04:00",
"updates": [
{
"Path": "System/name",
"values": {
"System/name": "nx9300v_01"
}
}
]
}
]
#
```


Loading

0 comments on commit 4d1c269

Please sign in to comment.