blob: 61a45ca27d27977920d65ac122730139ae2b05dd [file] [log] [blame] [view]
Giorgi Lekveishvili0048a782023-06-20 18:32:21 +04001# ACME webhook for Gandi (cert-manager-webhook-gandi)
2`cert-manager-webhook-gandi` is an ACME webhook for [cert-manager]. It provides an ACME (read: Let's Encrypt) webhook for [cert-manager], which allows to use a `DNS-01` challenge with [Gandi]. This allows to provide Let's Encrypt certificates to [Kubernetes] for service protocols other than HTTP and furthermore to request wildcard certificates. Internally it uses the [Gandi LiveDNS API] to communicate with Gandi.
3
4Quoting the [ACME DNS-01 challenge]:
5
6> This challenge asks you to prove that you control the DNS for your domain name by putting a specific value in a TXT record under that domain name. It is harder to configure than HTTP-01, but can work in scenarios that HTTP-01 can’t. It also allows you to issue wildcard certificates. After Let’s Encrypt gives your ACME client a token, your client will create a TXT record derived from that token and your account key, and put that record at _acme-challenge.<YOUR_DOMAIN>. Then Let’s Encrypt will query the DNS system for that record. If it finds a match, you can proceed to issue a certificate!
7
8
9## Building
10Build the container image `cert-manager-webhook-gandi:latest`:
11
12 make build
13
14
15## Image
16Ready made images are hosted on Docker Hub ([image tags]). Use at your own risk:
17
18 bwolf/cert-manager-webhook-gandi
19
20
21### Release History
22Refer to the [CHANGELOG](CHANGELOG.md) file.
23
24
25## Compatibility
26This webhook has been tested with [cert-manager] v1.5.4 and Kubernetes v1.22.2 on `amd64`. In theory it should work on other hardware platforms as well but no steps have been taken to verify this. Please drop me a note if you had success.
27
28
29## Testing with Minikube
301. Build this webhook in Minikube:
31
32 minikube start --memory=4G --more-options
33 eval $(minikube docker-env)
34 make build
35 docker images | grep webhook
36
372. Install [cert-manager] with [Helm]:
38
39 helm repo add jetstack https://charts.jetstack.io
40
41 helm install cert-manager jetstack/cert-manager \
42 --namespace cert-manager \
43 --create-namespace \
44 --set installCRDs=true \
45 --version v1.5.4 \
46 --set 'extraArgs={--dns01-recursive-nameservers=8.8.8.8:53\,1.1.1.1:53}'
47
48 kubectl get pods --namespace cert-manager --watch
49
50 **Note**: refer to Name servers in the official [documentation][setting-nameservers-for-dns01-self-check] according the `extraArgs`.
51
52 **Note**: ensure that the custom CRDS of cert-manager match the major version of the cert-manager release by comparing the URL of the CRDS with the helm info of the charts app version:
53
54 helm search repo jetstack
55
56 Example output:
57
58 NAME CHART VERSION APP VERSION DESCRIPTION
59 jetstack/cert-manager v1.5.4 v1.5.4 A Helm chart for cert-manager
60
61 Check the state and ensure that all pods are running fine (watch out for any issues regarding the `cert-manager-webhook-` pod and its volume mounts):
62
63 kubectl describe pods -n cert-manager | less
64
65
663. Create the secret to keep the Gandi API key in the cert-manager namespace:
67
68 kubectl create secret generic gandi-credentials \
69 --namespace cert-manager --from-literal=api-token='<GANDI-API-KEY>'
70
71 *The `Secret` must reside in the same namespace as `cert-manager`.*
72
734. Deploy this webhook (add `--dry-run` to try it and `--debug` to inspect the rendered manifests; Set `logLevel` to 6 for verbose logs):
74
75 *The `features.apiPriorityAndFairness` argument must be removed or set to `false` for Kubernetes older than 1.20.*
76
77 helm install cert-manager-webhook-gandi \
78 --namespace cert-manager \
79 --set features.apiPriorityAndFairness=true \
80 --set image.repository=cert-manager-webhook-gandi \
81 --set image.tag=latest \
82 --set logLevel=2 \
83 ./deploy/cert-manager-webhook-gandi
84
85 To deploy using the image from Docker Hub (for example using the `0.2.0` tag):
86
87 helm install cert-manager-webhook-gandi \
88 --namespace cert-manager \
89 --set features.apiPriorityAndFairness=true \
90 --set image.tag=0.2.0 \
91 --set logLevel=2 \
92 ./deploy/cert-manager-webhook-gandi
93
94 To deploy using the Helm repository (for example using the `v0.2.0` version):
95
96 helm install cert-manager-webhook-gandi \
97 --repo https://bwolf.github.io/cert-manager-webhook-gandi \
98 --version v0.2.0 \
99 --namespace cert-manager \
100 --set features.apiPriorityAndFairness=true \
101 --set logLevel=2
102
103 Check the logs
104
105 kubectl get pods -n cert-manager --watch
106 kubectl logs -n cert-manager cert-manager-webhook-gandi-XYZ
107
1086. Create a staging issuer (email addresses with the suffix `example.com` are forbidden).
109
110 See [letsencrypt-staging-issuer.yaml](examples/issuers/letsencrypt-staging-issuer.yaml)
111
112 Don't forget to replace email `invalid@example.com`.
113
114 Check status of the Issuer:
115
116 kubectl describe issuer letsencrypt-staging
117
118 You can deploy a ClusterIssuer instead : see [letsencrypt-staging-clusterissuer.yaml](examples/issuers/letsencrypt-staging-clusterissuer.yaml)
119
120 *Note*: The production Issuer is [similar][ACME documentation].
121
1227. Issue a [Certificate] for your domain: see [certif-example-com.yaml](examples/certificates/certif-example-com.yaml)
123
124 Replace `your-domain` and `your.domain` in the [certif-example-com.yaml](examples/certificates/certif-example-com.yaml)
125
126 Create the Certificate:
127
128 kubectl apply -f ./examples/certificates/certif-example-com.yaml
129
130 Check the status of the Certificate:
131
132 kubectl describe certificate example-com
133
134 Display the details like the common name and subject alternative names:
135
136 kubectl get secret example-com-tls -o yaml
137
138 If you deployed a ClusterIssuer : use [certif-example-com-clusterissuer.yaml](examples/certificates/certif-example-com-clusterissuer.yaml)
139
1408. Issue a wildcard Certificate for your domain: see [certif-wildcard-example-com.yaml](examples/certificates/certif-wildcard-example-com.yaml)
141
142 Replace `your-domain` and `your.domain` in the [certif-wildcard-example-com.yaml](examples/certificates/certif-wildcard-example-com.yaml)
143
144 Create the Certificate:
145
146 kubectl apply -f ./examples/certificates/certif-wildcard-example-com.yaml
147
148 Check the status of the Certificate:
149
150 kubectl describe certificate wildcard-example-com
151
152 Display the details like the common name and subject alternative names:
153
154 kubectl get secret wildcard-example-com-tls -o yaml
155
156 If you deployed a ClusterIssuer : use [certif-wildcard-example-com-clusterissuer.yaml](examples/certificates/certif-wildcard-example-com-clusterissuer.yaml)
157
1589. Uninstall this webhook:
159
160 helm uninstall cert-manager-webhook-gandi --namespace cert-manager
161 kubectl delete gandi-credentials --namespace cert-manager
162
16310. Uninstalling cert-manager:
164 This is out of scope here. Refer to the official [documentation][cert-manager-uninstall].
165
166
167## Development
168**Note**: If some tool (IDE or build process) fails resolving a dependency, it may be the cause that a indirect dependency uses `bzr` for versioning. In such a case it may help to put the `bzr` binary into `$PATH` or `$GOPATH/bin`.
169
170
171## Release process (automated with [GitHub actions](.github/workflows/main.yml))
172- Changes in the Go code result in the build of a Docker image and the release of a new Helm chart
173- Changes at Helm chart level only, result in the release of a new Chart without building a new Docker image
174- All other changes are pushed to master
175- All versions are to be documented in [CHANGELOG](CHANGELOG.md)
176
177**Note**: All changes to the Go code or Helm chart must go with a version tag `vX.X.X` to trigger the GitHub workflow
178
179**Note**: Any Helm chart release results in the creation of a [GitHub release](https://github.com/bwolf/cert-manager-webhook-gandi/releases)
180
181## Conformance test
182Please note that the test is not a typical unit or integration test. Instead it invokes the web hook in a Kubernetes-like environment which asks the web hook to really call the DNS provider (.i.e. Gandi). It attempts to create an `TXT` entry like `cert-manager-dns01-tests.example.com`, verifies the presence of the entry via Google DNS. Finally it removes the entry by calling the cleanup method of web hook.
183
184As said above, the conformance test is run against the real Gandi API. Therefore you *must* have a Gandi account, a domain and an API key.
185
186``` shell
187cp testdata/gandi/api-key.yaml.sample testdata/gandi/api-key.yaml
188echo -n $YOUR_GANDI_API_KEY | base64 | pbcopy # or xclip
189$EDITOR testdata/gandi/api-key.yaml
190TEST_ZONE_NAME=example.com. make test
191make clean
192```
193
194
195[ACME DNS-01 challenge]: https://letsencrypt.org/docs/challenge-types/#dns-01-challenge
196[ACME documentation]: https://cert-manager.io/docs/configuration/acme/
197[Certificate]: https://cert-manager.io/docs/usage/certificate/
198[cert-manager]: https://cert-manager.io/
199[Gandi]: https://gandi.net/
200[Gandi LiveDNS API]: https://api.gandi.net/docs/livedns/
201[Helm]: https://helm.sh
202[image tags]: https://hub.docker.com/r/bwolf/cert-manager-webhook-gandi
203[Kubernetes]: https://kubernetes.io/
204[setting-nameservers-for-dns01-self-check]: https://cert-manager.io/docs/configuration/acme/dns01/#setting-nameservers-for-dns01-self-check
205[cert-manager-uninstall]: https://cert-manager.io/docs/installation/uninstall/kubernetes/