github.com/projectcontour/contour@v1.28.2/site/content/docs/v1.17.2/grpc-tls-howto.md (about)

     1  # Enabling TLS between Envoy and Contour
     2  
     3  This document describes the steps required to secure communication between Envoy and Contour.
     4  The outcome of this is that we will have two Secrets available in the `projectcontour` namespace:
     5  
     6  - **contourcert:** contains Contour's keypair which is used for serving TLS secured gRPC, and the CA's public certificate bundle which is used for validating Envoy's client certificate.
     7  Contour's certificate must be a valid certificate for the name `contour` in order for this to work.
     8  This is currently hardcoded by Contour.
     9  - **envoycert:** contains Envoy's keypair which used as a client for connecting to Contour, and the CA's public certificate bundle which is used for validating Contour's server certificate.
    10  
    11  Note that both Secrets contain a copy of the CA certificate bundle under the `ca.crt` data key.
    12  
    13  ## Ways you can get the certificates into your cluster
    14  
    15  - Deploy the Job from [certgen.yaml][1].
    16  This will run `contour certgen --kube --secrets-format=compact` for you.
    17  - Run `contour certgen --kube` locally.
    18  - Run the manual procedure below.
    19  
    20  ## Caveats and warnings
    21  
    22  **Be very careful with your production certificates!**
    23  
    24  This is intended as an example to help you get started.
    25  For any real deployment, you should **carefully** manage all the certificates and control who has access to them.
    26  Make sure you don't commit them to any git repositories either.
    27  
    28  ## Manual TLS certificate generation process
    29  
    30  ### Generating a CA keypair
    31  
    32  First, we need to generate a keypair:
    33  
    34  ```
    35  $ openssl req -x509 -new -nodes \
    36      -keyout certs/cakey.pem -sha256 \
    37      -days 1825 -out certs/cacert.pem \
    38      -subj "/O=Project Contour/CN=Contour CA"
    39  ```
    40  
    41  Then, the new CA key will be stored in `certs/cakey.pem` and the cert in `certs/cacert.pem`.
    42  
    43  ### Generating Contour's keypair
    44  
    45  Next, we need to generate a keypair for Contour.
    46  First, we make a new private key:
    47  
    48  ```
    49  $ openssl genrsa -out certs/contourkey.pem 2048
    50  ```
    51  
    52  Then, we create a CSR and have our CA sign the CSR and issue a certificate.
    53  This uses the file [certs/cert-contour.ext][2], which ensures that at least one of the valid names of the certificate is the bareword `contour`.
    54  This is required for the handshake to succeed, as `contour bootstrap` configures Envoy to pass this as the SNI server name for the connection.
    55  
    56  ```
    57  $ openssl req -new -key certs/contourkey.pem \
    58  	-out certs/contour.csr \
    59  	-subj "/O=Project Contour/CN=contour"
    60  
    61  $ openssl x509 -req -in certs/contour.csr \
    62      -CA certs/cacert.pem \
    63      -CAkey certs/cakey.pem \
    64      -CAcreateserial \
    65      -out certs/contourcert.pem \
    66      -days 1825 -sha256 \
    67      -extfile certs/cert-contour.ext
    68  ```
    69  
    70  At this point, the contour certificate and key are in the files `certs/contourcert.pem` and `certs/contourkey.pem` respectively.
    71  
    72  ### Generating Envoy's keypair
    73  
    74  Next, we generate a keypair for Envoy:
    75  
    76  ```
    77  $ openssl genrsa -out certs/envoykey.pem 2048
    78  ```
    79  
    80  Then, we generate a CSR and have the CA sign it:
    81  
    82  ```
    83  $ openssl req -new -key certs/envoykey.pem \
    84  	-out certs/envoy.csr \
    85  	-subj "/O=Project Contour/CN=envoy"
    86  
    87  $ openssl x509 -req -in certs/envoy.csr \
    88      -CA certs/cacert.pem \
    89      -CAkey certs/cakey.pem \
    90      -CAcreateserial \
    91      -out certs/envoycert.pem \
    92      -days 1825 -sha256 \
    93      -extfile certs/cert-envoy.ext
    94  ```
    95  
    96  Like the Contour certificate, this CSR uses the file [certs/cert-envoy.ext][3].
    97  However, in this case, there are no special names required.
    98  
    99  ### Putting the certificates in the cluster
   100  
   101  Next, we create the required Secrets in the target Kubernetes cluster:
   102  
   103  ```bash
   104  $ kubectl create secret -n projectcontour generic contourcert \
   105          --from-file=tls.key=./certs/contourkey.pem \
   106          --from-file=tls.crt=./certs/contourcert.pem \
   107          --from-file=ca.crt=./certs/cacert.pem \
   108          --save-config
   109  
   110  $ kubectl create secret -n projectcontour generic envoycert \
   111          --from-file=tls.key=./certs/envoykey.pem \
   112          --from-file=tls.crt=./certs/envoycert.pem \
   113          --from-file=ca.crt=./certs/cacert.pem \
   114          --save-config
   115  ```
   116  
   117  Note that we don't put the CA **key** into the cluster, there's no reason for that to be there, and that would create a security problem.
   118  
   119  ## Rotating Certificates
   120  
   121  Eventually the certificates that Contour and Envoy use will need to be rotated.
   122  The following steps can be taken to replace the certificates that Contour and Envoy are using:
   123  
   124  1. Generate a new keypair for both Contour and Envoy (optionally also for the CA)
   125  2. Update the Secrets that hold the gRPC TLS keypairs
   126  3. Contour and Envoy will automatically rotate their certificates after mounted secrets have been updated by the kubelet
   127  
   128  The secrets can be updated in-place by running:
   129  
   130  ```bash
   131  $ kubectl create secret -n projectcontour generic contourcert \
   132          --from-file=tls.key=./certs/contourkey.pem \
   133          --from-file=tls.crt=./certs/contourcert.pem \
   134          --from-file=ca.crt=./certs/cacert.pem \
   135          --dry-run -o json \
   136          | kubectl apply -f -
   137  
   138  $ kubectl create secret -n projectcontour generic envoycert \
   139          --from-file=tls.key=./certs/envoykey.pem \
   140          --from-file=tls.crt=./certs/envoycert.pem \
   141          --from-file=ca.crt=./certs/cacert.pem \
   142          --dry-run -o json \
   143          | kubectl apply -f -
   144  ```
   145  
   146  There are few preconditions that need to be met before Envoy can automatically reload certificate and key files:
   147  
   148  - Envoy must be version v1.14.1 or later
   149  - The bootstrap configuration must be generated with `contour bootstrap` using the `--resources-dir` argument, see [examples/contour/03-envoy.yaml][4]
   150  
   151  ### Rotate using the contour-certgen job
   152  
   153  When using the built-in Contour certificate generation, the following steps can be used:
   154  
   155  1. Delete the contour-certgen job
   156   - `kubectl delete job contour-certgen -n projectcontour`
   157  2. Reapply the contour-certgen job from [certgen.yaml][1]
   158  
   159  ## Conclusion
   160  
   161  Once this process is done, the certificates will be present as Secrets in the `projectcontour` namespace, as required by
   162  [examples/contour][5].
   163  
   164  [1]: {{< param github_url >}}/tree/{{< param version >}}/examples/contour/02-job-certgen.yaml
   165  [2]: {{< param github_url >}}/tree/{{< param version >}}/certs/cert-contour.ext
   166  [3]: {{< param github_url >}}/tree/{{< param version >}}/certs/cert-envoy.ext
   167  [4]: {{< param github_url >}}/tree/{{< param version >}}/examples/contour/03-envoy.yaml
   168  [5]: {{< param github_url >}}/tree/{{< param version >}}/examples/contour
   169