Skip to content

Commit

Permalink
kic: adjust the guide to support BackendTLSPolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalek committed Dec 13, 2024
1 parent 8283d58 commit ac0800f
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 60 deletions.
19 changes: 19 additions & 0 deletions app/_includes/md/kic/verify-upstream-tls-backendtlspolicy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```shell
echo 'apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: goecho-tls-policy
spec:
options:
tls-verify-depth: "1"
targetRefs:
- group: core
kind: Service
name: echo
validation:
caCertificateRefs:
- group: core
kind: {{ include.ref_kind }}
name: root-ca
hostname: kong.example' | kubectl apply -f -
```
41 changes: 41 additions & 0 deletions app/_includes/md/kic/verify-upstream-tls-ca.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% assign kind = include.ca_source_type | capitalize %}
{% assign id = "bf6e0f14-78cd-45ad-9325-87ec7ef7b891" %}
{% if include.ca_source_type == "secret" %}
{% assign id = "bf6e0f14-78cd-45ad-9325-87ec7ef7b892" %}
{% endif %}

First, create a secret with the root CA certificate.

```shell
kubectl create {{ include.ca_source_type }} {% if include.ca_source_type == "secret" %}generic {%endif%}root-ca \
--from-file=ca.crt=./certs/root.crt \
--from-literal=id={{ id }} # An arbitrary ID for the certificate
kubectl label {{ include.ca_source_type }} root-ca konghq.com/ca-cert=true # This label is required for the CA certificate to be recognized by Kong
kubectl annotate {{ include.ca_source_type }} root-ca kubernetes.io/ingress.class=kong
```
The results should look like this.
```text
{{ include.ca_source_type }}/root-ca created
{{ include.ca_source_type }}/root-ca labeled
{{ include.ca_source_type }}/root-ca annotated
```
{% if include.associate_with_service %}
Now, associate the root CA certificate with the `Service` passing its name to `konghq.com/ca-certificates-{{ include.ca_source_type }}` annotation.
{:.note}
> The `konghq.com/ca-certificates-{{ include.ca_source_type }}` annotation is a comma-separated list of `{{ kind }}`s holding CA certificates.
> You can add multiple `{{ kind }}`s to the list.
```shell
kubectl annotate service echo konghq.com/ca-certificates-{{ include.ca_source_type }}='root-ca'
```
The result should look like this.
```text
service/echo annotated
```
{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,28 @@ verification_.

### Enable TLS verification

{% navtabs certificate %}
{% navtab Gateway API %}

To configure {{ site.base_gateway }} to verify the certificate of the upstream service,
we need to create a `BackendTLSPolicy` resource:

{% navtabs ca_source %}
<!-- NOTE: Add Secret when https://github.com/Kong/kubernetes-ingress-controller/issues/6834 gets implemented -->
{% navtab ConfigMap %}
{% include /md/kic/verify-upstream-tls-backendtlspolicy.md ref_kind="ConfigMap" %}
{% endnavtab %}
{% endnavtabs %}

The results should look like this.

```text
backendtlspolicy.gateway.networking.k8s.io/goecho-tls-policy created
```

{% endnavtab %}
{% navtab Ingress %}

To configure {{ site.base_gateway }} to verify the certificate of the upstream service, we need to annotate the
service accordingly.

Expand All @@ -205,6 +227,8 @@ The results should look like this.
```text
service/echo annotated
```
{% endnavtab %}
{% endnavtabs %}

Now, when you issue the same request as before, you should see an error similar to this.

Expand All @@ -222,7 +246,7 @@ curl -H Host:kong.example $PROXY_IP/echo
If you inspect {{ site.base_gateway }}'s container logs, you should see an error indicating an issue with TLS handshake.

```shell
kubectl logs -n kong deploy/kong-gateway | grep "GET /echo"
kubectl logs -n kong deploy/kong-gateway | grep "GET /echo"
```

```text
Expand All @@ -238,71 +262,32 @@ the certificate is not trusted.
That can be fixed by adding the root CA certificate to the {{ site.base_gateway }}'s CA certificates and associating
it with the service.

First, create a secret with the root CA certificate.

{% navtabs certificate %}
{% navtab Secret %}
```shell
kubectl create secret generic root-ca \
--from-file=ca.crt=./certs/root.crt \
--from-literal=id=bf6e0f14-78cd-45ad-9325-87ec7ef7b891 # An arbitrary ID for the certificate
kubectl label secret root-ca konghq.com/ca-cert=true # This label is required for the CA certificate to be recognized by Kong
kubectl annotate secret root-ca kubernetes.io/ingress.class=kong
```

The results should look like this.
{% navtab Gateway API %}

```text
secret/root-ca created
configmap/root-ca labeled
configmap/root-ca annotated
```
{% navtabs ca_source %}
<!-- NOTE: Add Secret when https://github.com/Kong/kubernetes-ingress-controller/issues/6834 gets implemented -->
{% navtab ConfigMap %}
{% include /md/kic/verify-upstream-tls-ca.md ca_source_type="configmap" %}
{% endnavtab %}
{% endnavtabs %}

Now, associate the root CA certificate with the service passing its name to `konghq.com/ca-certificates-secret` annotation.
The CA is already associated with the `Service` through `BackendTLSPolicy`'s `spec.validation.caCertificateRefs`.

{:.note}
> The `konghq.com/ca-certificates-secret` annotation is a comma-separated list of `Secret`s holding CA certificates.
> You can add multiple `Secret`s to the list.
{% endnavtab %}
{% navtab Ingress %}

```shell
kubectl annotate service echo konghq.com/ca-certificates-secret='root-ca'
```
{% navtabs ca_source %}
{% navtab Secret %}
{% include /md/kic/verify-upstream-tls-ca.md ca_source_type="secret" associate_with_service=true %}
{% endnavtab %}
{% navtab ConfigMap %}

```shell
kubectl create configmap root-ca \
--from-file=ca.crt=./certs/root.crt \
--from-literal=id=bf6e0f14-78cd-45ad-9325-87ec7ef7b891 # An arbitrary ID for the certificate
kubectl label configmap root-ca konghq.com/ca-cert=true # This label is required for the CA certificate to be recognized by Kong
kubectl annotate configmap root-ca kubernetes.io/ingress.class=kong
```

The results should look like this.

```text
configmap/root-ca created
configmap/root-ca labeled
configmap/root-ca annotated
```

Now, associate the root CA certificate with the service passing its name to `konghq.com/ca-certificates-configmap` annotation.

{:.note}
> The `konghq.com/ca-certificates-configmap` annotation is a comma-separated list of `ConfigMap`s holding CA certificates.
> You can add multiple `ConfigMap`s to the list.
```shell
kubectl annotate service echo konghq.com/ca-certificates-configmap='root-ca'
```
{% include /md/kic/verify-upstream-tls-ca.md ca_source_type="configmap" associate_with_service=true %}
{% endnavtab %}
{% endnavtabs %}

The results should look like this.

```text
service/echo annotated
```
{% endnavtab %}
{% endnavtabs %}

Now, when you issue the same request as before, you should see a successful response.

Expand All @@ -318,6 +303,10 @@ With IP address 192.168.194.18.
Through HTTPS connection.
```

{:.note}
> It may take a moment for {{ site.base_gateway }} to pick up the changes and start verifying the certificate.
> If you want to speed up the process, you can restart the {{ site.base_gateway }} pod.
{{ site.base_gateway }} is now verifying the certificate of the upstream service and accepting the connection because
the certificate is trusted.

Expand All @@ -326,8 +315,30 @@ the certificate is trusted.
By default, {{ site.base_gateway }} verifies the certificate chain up to the root CA certificate with no depth limit.
You can configure the verification depth by annotating the service with the `konghq.com/tls-verify-depth` annotation.

For example, to limit the verification depth to 1 (i.e., only verify one intermediate certificate), you can annotate the
service like this:
{% navtabs certificate %}
{% navtab Gateway API %}
For example, to limit the verification depth to 1 (i.e., only verify one intermediate certificate),
you can set the `tls-verify-depth` option in the `BackendTLSPolicy` resource like this:

```shell
kubectl patch backendtlspolicies.gateway.networking.k8s.io goecho-tls-policy --type merge -p='{
"spec": {
"options" : {
"tls-verify-depth": "1"
}
}
}'
```

The results should look like this.

```text
backendtlspolicy.gateway.networking.k8s.io/goecho-tls-policy patched
```
{% endnavtab %}
{% navtab Ingress %}
For example, to limit the verification depth to 1 (i.e., only verify one intermediate certificate),
you can annotate the service like this:

```shell
kubectl annotate service echo konghq.com/tls-verify-depth=1
Expand All @@ -338,6 +349,8 @@ The results should look like this.
```text
service/echo annotated
```
{% endnavtab %}
{% endnavtabs %}

Now, when you issue the same request as before, you should still see a successful response.

Expand All @@ -355,6 +368,25 @@ Through HTTPS connection.

You can also set the verification depth to 0 to not allow any intermediate certificates.

{% navtabs certificate %}
{% navtab Gateway API %}
```shell
kubectl patch backendtlspolicies.gateway.networking.k8s.io goecho-tls-policy --type merge -p='{
"spec": {
"options" : {
"tls-verify-depth": "0"
}
}
}'
```

The results should look like this.

```text
backendtlspolicy.gateway.networking.k8s.io/goecho-tls-policy patched
```
{% endnavtab %}
{% navtab Ingress %}
```shell
kubectl annotate --overwrite service echo konghq.com/tls-verify-depth=0
```
Expand All @@ -364,6 +396,8 @@ The results should look like this.
```text
service/echo annotated
```
{% endnavtab %}
{% endnavtabs %}

Now, when you issue the same request as before, you should see an error similar to this.

Expand All @@ -389,8 +423,30 @@ kubectl logs -n kong deploy/kong-gateway | grep "GET /echo"
192.168.194.1 - - [29/Nov/2024:11:41:46 +0000] "GET /echo HTTP/1.1" 502 126 "-" "curl/8.7.1" kong_request_id: "678281372fb8907ed06d517cf515de78"
```

{{ site.base_gateway }} is now rejecting the connection because the certificate chain is too long. Changing the
verification depth to 1 should allow the connection to succeed again.
{{ site.base_gateway }} is now rejecting the connection because the certificate chain is too long.
Changing the verification depth to 1 should allow the connection to succeed again.

{% navtabs certificate %}
{% navtab Gateway API %}
```shell
kubectl patch backendtlspolicies.gateway.networking.k8s.io goecho-tls-policy --type merge -p='{
"spec": {
"options" : {
"tls-verify-depth": "1"
}
}
}'
```

The results should look like this.

```text
backendtlspolicy.gateway.networking.k8s.io/goecho-tls-policy patched
```
{% endnavtab %}
{% navtab Ingress %}
For example, to limit the verification depth to 1 (i.e., only verify one intermediate certificate),
you can annotate the service like this:

```shell
kubectl annotate --overwrite service echo konghq.com/tls-verify-depth=1
Expand All @@ -401,6 +457,8 @@ The results should look like this.
```text
service/echo annotated
```
{% endnavtab %}
{% endnavtabs %}

Now, when you issue the same request as before, you should see a successful response.

Expand Down

0 comments on commit ac0800f

Please sign in to comment.