TLS using cert-manager

Hydrolix deployment can leverage k8s cert-manager to deploy and manage certificate on your cluster.
There are several ways to get a certificate from cert-manager, in this doc we'll use let's encrypt CA and different verification method:

Getting started

The first step to get started is to install cert-manager using kubectl

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml

Certificate using let's encrypt and HTTP challenge

🚧

Pre-requesite

  • Hydrolix cluster deployed
  • Cluster is using a public load balancer
  • DNS entry is created and pointing to the LB
  • IP filtering is disable to allow let's encrypt verification:
    ip_allowlist:
  - source: 0.0.0.0/0

Create a certificate issuer configuration

Here we'll create an issuer leveraging Let's Encrypt production certificate authority, the issuer contains several important information:

  • name - name of the issuer when we generate new certificate requests
  • ACME server - server which will be used to generate the ACME challenge
  • email - email used for the certificate information
  • solvers - how we can we are going to validate ownership of the domain

This is a configuration example to generate a certificate using Let's Encrypt validate the domain ownership using HTTP and ingress traefik which is the default for Hydrolix deployment.

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-production-http
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: $YOUREMAILMANAGINGCERTIFICATE - TO BE REPLACE
    privateKeySecretRef:
      name: letsencrypt-production-http
    solvers:
    - selector: {}
      http01:
        ingress:
          class: traefik

Once you generate the issuer configuration you can store it in the yaml file issuer-prod-lets-enc.yaml and deploy it in your cluster:

kubectl apply -f issuer-prod-lets-enc.yaml

Create a certificate request configuration

After deploying your certificate issuer you can now create a new certificate request including your domain.
An important requirement for Hydrolix is to store the certificate into the secretName: traefik-tls.
That's the default location used by Hydrolix to load the certificate.
Here's a configuration example:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: $YOURNAMESPACE - TO BE REPLACE
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  secretName: traefik-tls
  issuerRef:
    name: letsencrypt-production-http
  commonName: $YOURDOMAIN - TO BE REPLACE
  dnsNames:
  - $YOURDOMAIN - TO BE REPLACE

After generating this certificate request you can store it in the yaml file cert-req.yaml and deploy it in your cluster:

kubectl apply -f cert-req.yaml

Checking the certificate request status

Once the certificate is applied you can check its status by using the following command:

kubectl describe certificate $YOURNAMESPACE

If the certificate validation is successful you can should see the following:

Normal  Issuing    12s   cert-manager-certificates-issuing          The certificate has been successfully issued

Enable TLS on traefik

Once the certificate is deployed you can enable HTTPS in the hydrolixcluster.yaml config by changing the hydrolix_url from http to https.
Example: hydrolix_url: https://$YOURHOSTNAME

After changing the protocol traefik should restart and use the newly deployed let's encrypt certificate.

Deploy using DNS validation with route53

If your cluster is not accessible publicly you can leverage DNS validation with Let's Encrypt.
This documentation is based on the https://cert-manager.io/docs/configuration/acme/dns01/route53/

🚧

Pre-requesite

  • Hydrolix cluster is deployed on AWS
  • Route53 is used to manage DNS zone used by hydrolix hostname
  • AWS CLI

Create the policy

In this example we are creating a new policy ${HDX_KUBERNETES_NAMESPACE}-route53 which allows changing record route53.

read -r -d '' POLICY_DOC << EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "route53:GetChange",
      "Resource": "arn:aws:route53:::change/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets",
        "route53:ListResourceRecordSets"
      ],
      "Resource": "arn:aws:route53:::hostedzone/*"
    },
    {
      "Effect": "Allow",
      "Action": "route53:ListHostedZonesByName",
      "Resource": "*"
    }
  ]
}
EOF

aws iam create-policy --policy-name "${HDX_KUBERNETES_NAMESPACE}-route53" --policy-document ${POLICY_DOC}

We then attach that policy to the service account used by our Hydrolix deployment:

aws iam attach-role-policy --role-name "${HDX_KUBERNETES_NAMESPACE}-bucket" \
    --policy-arn="arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${HDX_KUBERNETES_NAMESPACE}-route53"

Create a certificate issuer using DNS validation and route53

Here we'll create an issuer leveraging Let's Encrypt production certificate authority, the issuer contains several important information:

  • name - name of the issuer when we generate new certificate requests
  • ACME server - server which will be used to generate the ACME challenge
  • email - email used for the certificate information
  • solvers - how we can we are going to validate ownership of the domain

This is a configuration example to generate a certificate using Let's Encrypt validate the domain ownership using DNS and will manage the creation of the proof via route53.

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-production-route53
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: $YOUREMAILMANAGINGCERTIFICATE - TO BE REPLACE
    privateKeySecretRef:
      name: letsencrypt-production-route53
    solvers:
    - selector:
        dnsZones:
          - "example.com" #TO_BE_REPLACE_BY_YOUR_ZONE
      dns01:
        route53:
          region: us-east-1 #TO_BE_REPLACE_BY_YOUR_REGION
          hostedZoneID: DIKER8JEXAMPLE #TO_BE_REPLACE_BY_YOUR_ZONE_ID

Once you generate the issuer configuration you can store it in the yaml file issuer-prod-lets-enc-route53.yaml and deploy it in your cluster:

kubectl apply -f issuer-prod-lets-enc-route53.yaml

Create a certificate request configuration

After deploying your certificate issuer you can now create a new certificate request including your domain.
An important requirement for Hydrolix is to store the certificate into the secretName: traefik-tls.
That's the default location used by Hydrolix to load the certificate.
Here's a configuration example:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: $YOURNAMESPACE - TO BE REPLACE
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  secretName: traefik-tls
  issuerRef:
    name: letsencrypt-production-route53
  commonName: $YOURDOMAIN - TO BE REPLACE
  dnsNames:
  - $YOURDOMAIN - TO BE REPLACE

After generating this certificate request you can store it in the yaml file cert-req.yaml and deploy it in your cluster:

kubectl apply -f cert-req.yaml

Checking the certificate request status

Once the certificate is applied you can check its status by using the following command:

kubectl describe certificate $YOURNAMESPACE

If the certificate validation is successful you can should see the following:

Normal  Issuing    12s   cert-manager-certificates-issuing          The certificate has been successfully issued

Enable TLS on traefik

Once the certificate is deployed you can enable HTTPS in the hydrolixcluster.yaml config by changing the hydrolix_url from http to https.
Example: hydrolix_url: https://$YOURHOSTNAME

After changing the protocol traefik should restart and use the newly deployed let's encrypt certificate.

Deploy using DNS validation with Cloudflare

If your cluster is not accessible publicly you can leverage DNS validation with Let's Encrypt.
This documentation is based on the https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/

🚧

Pre-requesite

  • Hydrolix cluster deployed
  • Cloudflare is used to manage DNS zone used by hydrolix hostname

Create token to alter zone

To use Cloudflare, you may use one of two types of tokens. API Tokens allow application-scoped keys bound to specific zones and permissions, while API Keys are globally-scoped keys that carry the same permissions as your account.

API Tokens are recommended for higher security, since they have more restrictive permissions and are more easily revocable.

Tokens can be created at User Profile > API Tokens > API Tokens. The following settings are recommended:

  • Permissions:
    • Zone - DNS -Edit
    • Zone - Zone - Read
  • Zone Resources:
    • Include - All Zones

Once the token is created we need to create a secret and store that information into your Kubernetes cluster:

apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token-secret
type: Opaque
stringData:
  api-token: $API_TOKEN - TO BE REPLACE

Once you generate the secret configuration you can store it in the yaml file cloudflare-secret.yaml and deploy it in your cluster:

kubectl apply -f cloudflare-secret.yaml

Create a certificate issuer using DNS validation and Cloudflare

Here we'll create an issuer leveraging Let's Encrypt production certificate authority, the issuer contains several important information:

  • name - name of the issuer when we generate new certificate requests
  • ACME server - server which will be used to generate the ACME challenge
  • email - email used for the certificate information
  • solvers - how we can we are going to validate ownership of the domain

This is a configuration example to generate a certificate using Let's Encrypt validate the domain ownership using DNS and will manage the creation of the proof via Cloudflare.

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-production-cloudflare
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: $YOUREMAILMANAGINGCERTIFICATE - TO BE REPLACE
    privateKeySecretRef:
      name: letsencrypt-production-cloudflare
    solvers:
    - dns01:
        cloudflare:
          email: $YOUR_EMAIL_ON_CLOUDFLARE_USED_TO_CREATE_THE_TOKEN - TO BE REPLACE
          apiTokenSecretRef:
            name: cloudflare-api-token-secret
            key: api-token

Once you generate the issuer configuration you can store it in the yaml file issuer-prod-lets-enc-cloudflare.yaml and deploy it in your cluster:

kubectl apply -f issuer-prod-lets-enc-cloudflare.yaml

Create a certificate request configuration

After deploying your certificate issuer you can now create a new certificate request including your domain.
An important requirement for Hydrolix is to store the certificate into the secretName: traefik-tls.
That's the default location used by Hydrolix to load the certificate.
Here's a configuration example:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: $YOURNAMESPACE - TO BE REPLACE
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  secretName: traefik-tls
  issuerRef:
    name: letsencrypt-production-cloudflare
  commonName: $YOURDOMAIN - TO BE REPLACE
  dnsNames:
  - $YOURDOMAIN - TO BE REPLACE

After generating this certificate request you can store it in the yaml file cert-req.yaml and deploy it in your cluster:

kubectl apply -f cert-req.yaml

Checking the certificate request status

Once the certificate is applied you can check its status by using the following command:

kubectl describe certificate $YOURNAMESPACE

If the certificate validation is successful you can should see the following:

Normal  Issuing    12s   cert-manager-certificates-issuing          The certificate has been successfully issued

Enable TLS on traefik

Once the certificate is deployed you can enable HTTPS in the hydrolixcluster.yaml config by changing the hydrolix_url from http to https.
Example: hydrolix_url: https://$YOURHOSTNAME

After changing the protocol traefik should restart and use the newly deployed let's encrypt certificate.

Deploy using DNS validation with Google CloudDNS

If your cluster is not accessible publicly you can leverage DNS validation with Let's Encrypt.
This documentation is based on the https://cert-manager.io/docs/configuration/acme/dns01/google/

🚧

Pre-requesite

  • Hydrolix cluster is deployed on GKE
  • Google CloudDNS is used to manage DNS zone used by hydrolix hostname
  • gcloud CLI

Add DNS role to service account

By default Hydrolix cluster are deployed leveraging a service account to connect to the different services in google cloud.
We need to update that service account so it can create DNS entries for the challenge.

Your service account name should be in your env.sh file you created when you built the cluster.

The basic format of it is export GCP_STORAGE_SA=hdx-${HDX_KUBERNETES_NAMESPACE}[email protected]${PROJECT_ID}.iam.gserviceaccount.com

gcloud projects add-iam-policy-binding ${PROJECT_ID} --member="serviceAccount:${GCP_STORAGE_SA}" --role='roles/dns.admin'

Create a certificate issuer using DNS validation and Google CloudDNS

Here we'll create an issuer leveraging Let's Encrypt production certificate authority, the issuer contains several important information:

  • name - name of the issuer when we generate new certificate requests
  • ACME server - server which will be used to generate the ACME challenge
  • email - email used for the certificate information
  • solvers - how we can we are going to validate ownership of the domain

This is a configuration example to generate a certificate using Let's Encrypt validate the domain ownership using DNS and will manage the creation of the proof via CloudDNS.

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-production-gclouddns
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: $YOUREMAILMANAGINGCERTIFICATE - TO BE REPLACE
    privateKeySecretRef:
      name: letsencrypt-production-gclouddns
        solvers:
    - dns01:
        cloudDNS:
          project: $PROJECT_ID - TO BE REPLACE

Once you generate the issuer configuration you can store it in the yaml file issuer-prod-lets-enc-gcloud.yaml and deploy it in your cluster:

kubectl apply -f issuer-prod-lets-enc-gcloud.yaml

Create a certificate request configuration

After deploying your certificate issuer you can now create a new certificate request including your domain.
An important requirement for Hydrolix is to store the certificate into the secretName: traefik-tls.
That's the default location used by Hydrolix to load the certificate.
Here's a configuration example:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: $YOURNAMESPACE - TO BE REPLACE
  namespace: $YOURNAMESPACE - TO BE REPLACE
spec:
  secretName: traefik-tls
  issuerRef:
    name: letsencrypt-production-gclouddns
  commonName: $YOURDOMAIN - TO BE REPLACE
  dnsNames:
  - $YOURDOMAIN - TO BE REPLACE

After generating this certificate request you can store it in the yaml file cert-req.yaml and deploy it in your cluster:

kubectl apply -f cert-req.yaml

Checking the certificate request status

Once the certificate is applied you can check its status by using the following command:

kubectl describe certificate $YOURNAMESPACE

If the certificate validation is successful you can should see the following:

Normal  Issuing    12s   cert-manager-certificates-issuing          The certificate has been successfully issued

Enable TLS on traefik

Once the certificate is deployed you can enable HTTPS in the hydrolixcluster.yaml config by changing the hydrolix_url from http to https.
Example: hydrolix_url: https://$YOURHOSTNAME

After changing the protocol traefik should restart and use the newly deployed let's encrypt certificate.