Improve the tls-auth documentation

This commit is contained in:
Ricardo Pchevuzinske Katz 2017-02-09 09:45:11 -02:00
parent ef7be11c6b
commit 1738cbdaa3
3 changed files with 121 additions and 4 deletions

View file

@ -36,6 +36,105 @@ $ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret "tls-secret" created secret "tls-secret" created
``` ```
## CA Authentication
You can act as your very own CA, or use an existing one. As an exercise / learning, we're going to generate our
own CA, and also generate a client certificate.
These instructions are based in CoreOS OpenSSL instructions: https://coreos.com/kubernetes/docs/latest/openssl.html
### Generating a CA
First of all, you've to generate a CA. This is going to be the one who will sign your client certificates.
In real production world, you may face CAs with intermediate certificates, as the following:
```console
$ openssl s_client -connect www.google.com:443
[...]
---
Certificate chain
0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
i:/C=US/O=Google Inc/CN=Google Internet Authority G2
1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
```
To generate our CA Certificate, we've to run the following commands:
```console
$ openssl genrsa -out ca.key 2048
$ openssl req -x509 -new -nodes -key ca.key -days 10000 -out ca.crt -subj "/CN=example-ca"
```
This will generate two files: A private key (ca.key) and a public key (ca.crt). This CA is valid for 10000 days.
The ca.crt can be used later in the step of creation of CA authentication secret.
### Generating the client certificate
The following steps generates a client certificate signed by the CA generated above. This client can be
used to authenticate in a tls-auth configured ingress.
First, we need to generate an 'openssl.cnf' file that will be used while signing the keys:
```
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
```
Then, a user generates his very own private key (that he needs to keep secret)
and a CSR (Certificate Signing Request) that will be sent to the CA to sign and generate a certificate.
```console
$ openssl genrsa -out client1.key 2048
$ openssl req -new -key client1.key -out client1.csr -subj "/CN=client1" -config openssl.cnf
```
As the CA receives the generated 'client1.csr' file, it signs it and generates a client.crt certificate:
```console
$ openssl x509 -req -in client1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client1.crt -days 365 -extensions v3_req -extfile openssl.cnf
```
Then, you'll have 3 files: the client.key (user's private key), client.crt (user's public key) and client.csr (disposable CSR).
### Creating the CA Authentication secret
If you're using the CA Authentication feature, you need to generate a secret containing
all the authorized CAs. You must download them from your CA site in PEM format (like the following):
```
-----BEGIN CERTIFICATE-----
[....]
-----END CERTIFICATE-----
```
You can have as many certificates as you wan't. If they're in the binary DER format,
you can convert them as the following:
```console
$ openssl x509 -in certificate.der -inform der -out certificate.crt -outform pem
```
Then, you've to concatenate them all in only one file, named 'ca.crt' as the following:
```console
$ cat certificate1.crt certificate2.crt certificate3.crt >> ca.crt
```
The final step is to create a secret with the content of this file. This secret is going to be used in
the TLS Auth directive:
```console
$ kubectl create secret generic caingress --namespace=default --from-file=ca.crt
```
## Test HTTP Service ## Test HTTP Service
All examples that require a test HTTP Service use the standard echoheaders pod, All examples that require a test HTTP Service use the standard echoheaders pod,

View file

@ -2,15 +2,30 @@
This example demonstrates how to enable the TLS Authentication through the nginx Ingress controller. This example demonstrates how to enable the TLS Authentication through the nginx Ingress controller.
## Terminology
* CA Certificate(s) - Certificate Authority public key. Client certs must chain back to this cert,
meaning the Issuer field of some certificate in the chain leading up to the client cert must contain
the name of this CA. For purposes of this example, this is a self signed certificate.
* Client Cert: Certificate used by the clients to authenticate themselves with the loadbalancer/backends.
* CA: Certificate authority signing the client cert, in this example we will play the role of a CA.
You can generate a CA cert as show in this doc.
* CA chains: A chain of certificates where the parent has a Subject field matching the Issuer field of
the child, except for the root, which has Issuer == Subject.
## Prerequisites ## Prerequisites
You need a valid CA File, composed of a group of valid enabled CAs. This MUST be in PEM Format. You need a valid CA File, composed of a group of valid enabled CAs. This MUST be in PEM Format.
Also the Ingress must terminate TLS, otherwise this makes no sense ;) The instructions are described here: https://github.com/kubernetes/ingress/blob/master/examples/PREREQUISITES.md#ca-authentication
Also your ingress must be configured as a HTTPs/TLS Ingress.
## Deployment ## Deployment
The following command instructs the controller to enable the TLS Authentication using The following command instructs the controller to enalbe TLS authentication using the secret from the ``ingress.kubernetes.io/auth-tls-secret``
the secret containing the valid CA chains. annotation on the Ingress. Clients must present this cert to the loadbalancer, or they will receive a HTTP 400 response
```console ```console
$ kubectl create -f nginx-tls-auth.yaml $ kubectl create -f nginx-tls-auth.yaml
@ -54,3 +69,5 @@ HTTP/1.1 200 OK
Server: nginx/1.11.9 Server: nginx/1.11.9
``` ```
You must use the full DNS name while testing, as NGINX relies on the Server Name (SNI) to select the correct Ingress to be used.

View file

@ -4,6 +4,7 @@ metadata:
annotations: annotations:
# Create this with kubectl create secret generic caingress --from-file=ca.crt --namespace=default # Create this with kubectl create secret generic caingress --from-file=ca.crt --namespace=default
ingress.kubernetes.io/auth-tls-secret: default/caingress ingress.kubernetes.io/auth-tls-secret: default/caingress
kubernetes.io/ingress.class: "nginx"
name: nginx-test name: nginx-test
namespace: default namespace: default
spec: spec: