Setting up SSL using cert-manager through HTTP-01 challenge
In this page we will see how can we create SSL certificate using cert-manager through HTTP-01 challenge
What are HTTP-01 and DNS-01 challenge ?
The DNS-01 and HTTP-01 challenges are two methods used in the ACME (Automated Certificate Management Environment) protocol for validating domain ownership when requesting SSL/TLS certificates, typically for securing websites.
DNS-01 challenge involves creating a DNS TXT record with a specific value provided by the certificate authority (CA) to prove domain ownership. This method is usually preferred when automating certificate issuance because it doesn't require a publicly accessible web server but does require control over the domain's DNS records.
On the other hand, HTTP-01 challenge requires hosting a specific file with a token provided by the CA on the web server associated with the domain. The CA performs an HTTP request to verify that the token exists at a specific URL, confirming domain ownership. This method is suitable for domains with web servers that are publicly accessible.
Why HTTP-01 ?
It is sometimes not possible to pass the authentication keys of the DNS server to cert-manager to perform DNS-01 challenge. For cases like these a web server can be hosted in the kubernetes cluster through which HTTP-01 challenge can be completed and certificate can be generated.
Generating Certificate Cert-manager and Istio.
-
Make sure cert-manager is installed in the cluster. For this head over to the Integrations tab, click on the three dots on your cluster card.
-
Click Manage Applications and install cert-manager.
-
Export these variables
export DOMAIN="" # enter your domain name here, can't we wildcard as it is not supported for HTTP-01 challenge export EMAIL=""
-
Create the
Issuer
withhttp01
challenge. Issuer should be created inistio-system
namespace only.k apply -f -<<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: letsencrypt-prod-cluster namespace: istio-system spec: acme: email: $EMAIL server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod-cluster solvers: - http01: ingress: class: istio EOF
-
Create the certificate. Certificate should be created in
istio-system
namespace only.k apply -f -<<EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: letsencrypt-prod-cert namespace: istio-system spec: secretName: letsencrypt-prod-secret duration: 2160h # 90d renewBefore: 360h # 15d isCA: false privateKey: algorithm: RSA encoding: PKCS1 size: 2048 usages: - server auth - client auth dnsNames: - "$DOMAIN" issuerRef: name: letsencrypt-prod-cluster EOF
-
The certificate will be in
False
statekubectl get certificates.cert-manager.io -n istio-system NAME READY SECRET AGE letsencrypt-prod-cert False letsencrypt-prod-secret 12m
-
This will create a pod, service and an ingress in
istio-system
namespace.kubectl get pods,svc,ing -n istio-system -l acme.cert-manager.io/http01-solver=true
-
We need to copy the service name and the port number from this ingress
SERVICE_NAME=$(kubectl get ing -n istio-system -l acme.cert-manager.io/http01-solver=true -ojsonpath='{.items[0].spec.rules[0].http.paths[0].backend.service.name}') PORT_NUMBER=$(kubectl get ing -n istio-system -l acme.cert-manager.io/http01-solver=true -ojsonpath='{.items[0].spec.rules[0].http.paths[0].backend.service.port.number}')
-
We need to create a
VirtualService
object with the ingress detailsk apply -f -<<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: letsencrypt-prod-vs namespace: istio-system spec: hosts: - "$DOMAIN" gateways: - istio-system/tfy-wildcard http: - match: - uri: prefix: / rewrite: uri: / route: - destination: host: SERVICE_NAME port: number: $PORT_NUMBER EOF
-
Now we will edit tfy-istio-ingress in Deployments tab under Helm section.
-
Make suretfy-istio-ingress is running.
-
Edit tfy-istio-ingress to check if
httpsRedirect
is set tofalse
-
Edit the
HTTPS
section of the gateway tocredentialName
to have the value ofspec.secretName
of the certificate we created above. Keep the protocol fortls[1]
toHTTPS
tfyGateway: name: tfy-wildcard spec: servers: - tls: httpsRedirect: false port: name: http-tfy-wildcard number: 80 protocol: HTTP hosts: - $DOMAIN - tls: mode: SIMPLE credentialName: letsencrypt-prod-secret port: name: https-tfy-wildcard number: 443 protocol: HTTPS hosts: - $DOMAIN selector: istio: tfy-istio-ingress
-
-
Once this is done we need to create a DNS record in the DNS server to allow
$DOMAIN
to point to the load balancer created by the cloud provider. To get the IP or the hostname, run the below commandkubectl get svc tfy-istio-ingress -n istio-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE tfy-istio-ingress LoadBalancer 10.0.58.231 <YOUR-IP-HERE> 15021:30547/TCP,80:32123/TCP,443:30997/TCP 11h
-
Once this is done we will wait for the certificate to get in the ready state.
-
Once the certificate gets in the ready state, we can edit the
httpsRedirect: true
Updated 8 months ago