Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for TLS configuration of NLK #115

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions docs/tls/CA-MTLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Mutual TLS with Certificate Authority (CA) certificates

This mode allows NLK to verify it is connecting to the correct NGINX Plus instance, allows NGINX Plus to verify it is connecting to the correct NLK, and encrypts the data between NLK and NGINX Plus.

## Overview

Mutual TLS is used to encrypt the traffic between NLK and NGINX Plus, to ensure NLK verifies the NGINX Plus server, and to ensure NGINX Plus verifies NLK.

## Certificates

To configure this mode, the following certificates are required:

- Server Certificate
- Client Certificate

See the following sections for instructions on how to create these certificates.

### Certificate Authority (CA)

Provided by the user.

### Server Certificate (NGINX Plus)

Use your own certificate authority (CA) to generate a server certificate and key.

### Client Certificate (NLK)

Use your own certificate authority (CA) to generate a client certificate and key.

## Kubernetes Secrets

NLK accesses the necessary certificates for each mode from Kubernetes Secrets. For this mode, the following Kubernetes Secret(s) are required:
- Client Certificate

To create the Kubernetes Secret containing the CA certificate, refer to the [Kubernetes Secrets](./KUBERNETES-SECRETS.md) guide;
the name and location of the certificate(s) created above should be used. The name of the Secret will be needed for the ConfigMap (discussed below).

## ConfigMap


NLK is configured via a ConfigMap. The ConfigMap is named `nlk-config` and is located in the `nlk` namespace.

Depending on which mode is chosen, certain fields will need to be updated in the NLK ConfigMap.

For this mode, the `tlsMode` and `clientCertificate` fields need to be included. The `tlsMode` field should be set to `ca-mtls`
and the `clientCertificate` field should be set to the name of the Kubernetes Secret containing the Client certificate created above.

The following is an example of a ConfigMap for this mode (be sure to update the `nginx-hosts` field with the correct NGINX Plus API endpoints):

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nlk-config
namespace: nlk
data:
nginx-hosts: "http://10.1.1.4:9000/api,http://10.1.1.5:9000/api"
tlsMode: "ca-mtls"
clientCertificate: "nlk-tls-client-secret"
```

## Deployment

Save the above ConfigMap definition to a file named `ca-mtls-configmap.yaml`, then deploy the ConfigMap using the following command:

```bash
kubectl apply -f docs/tls/ca-mtls-configmap.yaml
```

## Configuring NGINX Plus

Refer to the [NGINX Plus Configuration](./NGINX-PLUS-CONFIGURATION.md) guide for instructions on configuring NGINX Plus to use the certificates created above.

The steps in both the ["One-way TLS"](./NGINX-PLUS-CONFIGURATION.md#one-way-tls) section and the ["Mutual TLS"](./NGINX-PLUS-CONFIGURATION.md#mutual-tls) section are required for this mode.

## Verification

To verify the ConfigMap was deployed correctly, run the following command:

```bash
kubectl get configmap -n nlk nlk-config -o yaml
```

The output should match the ConfigMap above.

To verify NLK is running, follow the instructions in either the [TCP](../tcp/tcp-installation-guide.md) or [HTTP](../http/http-installation-guide.md) guides.

77 changes: 77 additions & 0 deletions docs/tls/CA-TLS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# One-way TLS with Certificate Authority (CA) certificates

This mode allows NLK to verify it is connecting to the correct NGINX Plus instance, and encrypts the data between NLK and NGINX Plus.

## Overview

One-way TLS is used to encrypt the traffic between NLK and NGINX Plus, and to ensure NLK verifies the NGINX Plus server;
however, the NGINX Plus server _does not_ validate NLK.

## Certificates

To configure this mode, the following certificates are required:

- Server Certificate

See the following sections for instructions on how to create these certificates.

### Certificate Authority (CA)

Provided by the user.

### Server Certificate (NGINX Plus)

Use your certificate authority (CA) to generate a server certificate and key.

## Kubernetes Secrets

No Kubernetes Secrets are required for this mode.

## ConfigMap

NLK is configured via a ConfigMap. The ConfigMap is named `nlk-config` and is located in the `nlk` namespace.

Depending on which mode is chosen, certain fields will need to be updated in the NLK ConfigMap.

For this mode, only the `tlsMode` fields needs to be included. The `tlsMode` field should be set to `ca-tls`.

The following is an example of a ConfigMap for this mode (be sure to update the `nginx-hosts` field with the correct NGINX Plus API endpoints):


```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nlk-config
namespace: nlk
data:
nginx-hosts: "http://10.1.1.4:9000/api,http://10.1.1.5:9000/api"
tlsMode: "ca-tls"
```

## Deployment

Save the above ConfigMap definition to a file named `ca-tls-configmap.yaml`, then deploy the ConfigMap using the following command:

```bash
kubectl apply -f docs/tls/ca-tls-configmap.yaml
```

## Configuring NGINX Plus

Refer to the [NGINX Plus Configuration](./NGINX-PLUS-CONFIGURATION.md) guide for instructions on configuring NGINX Plus to use the certificates created above.

Only the steps in the ["One-way TLS"](./NGINX-PLUS-CONFIGURATION.md#one-way-tls) section are required for this mode.
Use the certificate and key from your CA to configure NGINX Plus.

## Verification

To verify the ConfigMap was deployed correctly, run the following command:

```bash
kubectl get configmap -n nlk nlk-config -o yaml
```

The output should match the ConfigMap above.

To verify NLK is running, follow the instructions in either the [TCP](../tcp/tcp-installation-guide.md) or [HTTP](../http/http-installation-guide.md) guides.
44 changes: 44 additions & 0 deletions docs/tls/CERTIFICATE-AUTHORITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generate a Certificate Authority (CA)

When using self-signed certificates, the first step is to generate the Certificate Authority (CA).

The following commands will generate the CA certificate and key:

```bash
openssl req -newkey rsa:2048 -nodes -x509 -out ca.crt -keyout ca.key
```

You will be prompted to enter the Distinguished Name (DN) information for the CA.

Alternatively, you can provide the DN information in a file, an example is shown below:

```bash
[ req ]
distinguished_name = dn
prompt = no
req_extensions = req_ext

[ req_ext ]
basicConstraints = CA:TRUE
keyUsage = critical, keyCertSign, cRLSign

[ dn ]
C=[COUNTRY]
ST=[STATE]
L=[LOCALITY]
O=[ORGANIZATION]
OU=[ORGANIZATION_UNIT]
```

Create a file using the above as a template and update the values in the `[ dn ]` section; then use following command to generate the CA certificate and key:

```bash
openssl req -newkey rsa:2048 -nodes -x509 -config ca.cnf -out ca.crt -keyout ca.key
```

The output of the above command will be the CA certificate (`ca.crt`) and key (`ca.key`).

## References

- [Distinguished Name reference](http://certificate.fyicenter.com/2098_OpenSSL_req_-distinguished_name_Configuration_Section.html)

50 changes: 50 additions & 0 deletions docs/tls/CLIENT-CERTIFICATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generate a client certificate

When using self-signed certificates in the `ss-mtls` mode, a certificate needs to be generated for NLK.

The certificate has the same basic field as the CA certificate, with the addition of `clientAuth` in the `extendedKeyUsage` field:

```bash
[ req ]
distinguished_name = dn
prompt = no

[ dn ]
C=[COUNTRY]
ST=[STATE]
L=[LOCALITY]
O=[ORGANIZATION]
OU=[ORGANIZATION_UNIT]

[ client ]
extendedKeyUsage = clientAuth
```

Create a file using the above as a template and update the values in the `[ dn ]` section; then use following command to generate the certificate request and key:

```bash
openssl genrsa -out client.key 2048
openssl req -new -key client.key -config client.cnf -out client.csr
```

The output of the above commands will be the client certificate request (`client.csr`) and key (`client.key`).

##### Sign the client certificate

```bash
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256 -extfile client.cnf -extensions client
```

The output of the above command will be the client certificate (`client.crt`).

#### Verify the Client Certificate has the correct extendedKeyUsage

```bash
openssl x509 -in client.crt -noout -purpose | grep 'SSL client :'
```

Look for `SSL client : Yes` in the output.

## References

- [Distinguished Name reference](http://certificate.fyicenter.com/2098_OpenSSL_req_-distinguished_name_Configuration_Section.html)
51 changes: 51 additions & 0 deletions docs/tls/DOCUMENT-HIERARCHY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
```mermaid
graph LR
README[README.md]
SS-TLS[SS-TLS.md]
SS-MTLS[SS-MTLS.md]
CA-TLS[CA-TLS.md]
CA-MTLS[CA-MTLS.md]
NO-TLS[NO-TLS.md]
CERTIFICATE-AUTHORITY[CERTIFICATE-AUTHORITY.md]
CLIENT-CERTIFICATE[CLIENT-CERTIFICATE.md]
SERVER-CERTIFICATE[SERVER-CERTIFICATE.md]
KUBERNETES-SECRETS[KUBERNETES-SECRETS.md]
NGINX-PLUS-CONFIGURATION[NGINX-PLUS-CONFIGURATION.md]
KUBERNETES-SECRETS[KUBERNETES-SECRETS.md]

subgraph "README.md"
README
end

subgraph "NO-TLS links"
README --> NO-TLS
end

subgraph "SS-TLS links"
README --> SS-TLS
SS-TLS --> CERTIFICATE-AUTHORITY
SS-TLS --> SERVER-CERTIFICATE
SS-TLS --> KUBERNETES-SECRETS
SS-TLS --> NGINX-PLUS-CONFIGURATION
end

subgraph "SS-MTLS links"
README --> SS-MTLS
SS-MTLS --> CERTIFICATE-AUTHORITY
SS-MTLS --> SERVER-CERTIFICATE
SS-MTLS --> CLIENT-CERTIFICATE
SS-MTLS --> KUBERNETES-SECRETS
SS-MTLS --> NGINX-PLUS-CONFIGURATION
end

subgraph "CA-TLS links"
README --> CA-TLS
CA-TLS --> NGINX-PLUS-CONFIGURATION
end

subgraph "CA-MTLS links"
README --> CA-MTLS
CA-MTLS --> KUBERNETES-SECRETS
CA-MTLS --> NGINX-PLUS-CONFIGURATION
end
```
82 changes: 82 additions & 0 deletions docs/tls/KUBERNETES-SECRETS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Kubernetes Secrets

## Overview

Kubernetes Secrets are used to provide the required certificates to NLK. There are two ways to create the Secrets:
- Using `kubectl`
- Using yaml files

The filenames for the certificates created are required for both methods. The examples below assume the certificates were generated in `/tmp`
and follow the naming conventions in the documentation.

## Using `kubectl`

The easiest way to create the Secret(s) is by using `kubectl`:

```bash
kubectl create secret tls -n nlk nlk-tls-ca-secret --cert=/tmp/ca.crt --key=/tmp/ca.key
kubectl create secret tls -n nlk nlk-tls-server-secret --cert=/tmp/server.crt --key=/tmp/server.key
kubectl create secret tls -n nlk nlk-tls-client-secret --cert=/tmp/client.crt --key=/tmp/client.key
```

## Using yaml files

The Secrets can also be created using yaml files. The following is an example of a yaml file for the Client Secret (note that the `data` values are truncated):

```yaml
apiVersion: v1
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVCVEN...
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0l...
kind: Secret
metadata:
name: nlk-tls-ca-secret
type: kubernetes.io/tls
```

Note: While it is possible to generate the values for `tls.crt` and `tls.key` manually, the above yaml can be generated using the following command:

```bash
kubectl create secret tls -n nlk nlk-tls-ca-secret --cert=/tmp/ca.crt --key=/tmp/ca.key --dry-run=client -o yaml > ca-secret.yaml
kubectl create secret tls -n nlk nlk-tls-server-secret --cert=/tmp/server.crt --key=/tmp/server.key --dry-run=client -o yaml > server-secret.yaml
kubectl create secret tls -n nlk nlk-tls-client-secret --cert=/tmp/client.crt --key=/tmp/client.key --dry-run=client -o yaml > client-secret.yaml
```

> [!WARNING]
> It is important that these files do not make their way into a public repository or other storage location where they can be accessed by unauthorized users.


Once the yaml files are generated they can be applied using `kubectl`:

```bash
kubectl apply -f ca-secret.yaml
kubectl apply -f server-secret.yaml
kubectl apply -f client-secret.yaml
```

# Verification

The Secrets can be verified using `kubectl`:

```bash
kubectl describe secret -n nlk nlk-tls-ca-secret
kubectl describe secret -n nlk nlk-tls-server-secret
kubectl describe secret -n nlk nlk-tls-client-secret
```

The output should look similar to the example above.

To see the actual values of the certificates, the following command can be used:

```bash
kubectl get secret -n nlk nlk-tls-ca-secret -o json | jq -r '.data["tls.crt"], .data["tls.key"]' | base64 -d
kubectl get secret -n nlk nlk-tls-server-secret -o json | jq -r '.data["tls.crt"], .data["tls.key"]' | base64 -d
kubectl get secret -n nlk nlk-tls-client-secret -o json | jq -r '.data["tls.crt"], .data["tls.key"]' | base64 -d
```

Note that this requires `jq` to be installed.

## References

- [Kubernetes Secrets](https://kubernetes.io/docs/concepts/configuration/secret/)
- [kubectl dry run flags](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-dry-run-em-)
Loading