From 1738cbdaa3938281f386f7914f0003ab553b8e12 Mon Sep 17 00:00:00 2001 From: Ricardo Pchevuzinske Katz Date: Thu, 9 Feb 2017 09:45:11 -0200 Subject: [PATCH] Improve the tls-auth documentation --- examples/PREREQUISITES.md | 99 +++++++++++++++++++ examples/tls-authentication/nginx/README.md | 25 ++++- .../nginx/nginx-tls-auth.yaml | 1 + 3 files changed, 121 insertions(+), 4 deletions(-) diff --git a/examples/PREREQUISITES.md b/examples/PREREQUISITES.md index 1def0910d..9ecb10ea4 100644 --- a/examples/PREREQUISITES.md +++ b/examples/PREREQUISITES.md @@ -36,6 +36,105 @@ $ kubectl create secret tls tls-secret --key tls.key --cert tls.crt 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 All examples that require a test HTTP Service use the standard echoheaders pod, diff --git a/examples/tls-authentication/nginx/README.md b/examples/tls-authentication/nginx/README.md index 7b9160401..ed11acbfc 100644 --- a/examples/tls-authentication/nginx/README.md +++ b/examples/tls-authentication/nginx/README.md @@ -2,15 +2,30 @@ 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 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 -The following command instructs the controller to enable the TLS Authentication using -the secret containing the valid CA chains. +The following command instructs the controller to enalbe TLS authentication using the secret from the ``ingress.kubernetes.io/auth-tls-secret`` +annotation on the Ingress. Clients must present this cert to the loadbalancer, or they will receive a HTTP 400 response ```console $ kubectl create -f nginx-tls-auth.yaml @@ -18,7 +33,7 @@ $ kubectl create -f nginx-tls-auth.yaml ## Validation -You can confirm that the Ingress works. +You can confirm that the Ingress works. ```console $ kubectl describe ing nginx-test @@ -54,3 +69,5 @@ HTTP/1.1 200 OK 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. diff --git a/examples/tls-authentication/nginx/nginx-tls-auth.yaml b/examples/tls-authentication/nginx/nginx-tls-auth.yaml index ae313eaa4..c10461549 100644 --- a/examples/tls-authentication/nginx/nginx-tls-auth.yaml +++ b/examples/tls-authentication/nginx/nginx-tls-auth.yaml @@ -4,6 +4,7 @@ metadata: annotations: # Create this with kubectl create secret generic caingress --from-file=ca.crt --namespace=default ingress.kubernetes.io/auth-tls-secret: default/caingress + kubernetes.io/ingress.class: "nginx" name: nginx-test namespace: default spec: