๐Ÿ“— Letโ€™s Encrypt#

Overview

letsencrypt

Letโ€™s Encrypt is a free, automated, and open certificate authority (CA), run for the publicโ€™s benefit. ๐Ÿ˜‡

Certbot DNS Gandi#

Creating a Wildcard Certificate#

Create a virtualenv, install certbot and gandi-plugin.

mkdir guisam_xyz_LE_certs && cd guisam_xyz_LE_certs
python -m venv CertbotEnv
pip list --outdated | awk 'NR>2{print $1}' | xargs pip install -U
pip install certbot certbot-plugin-gandi

Create gandi API key file : ~/guisam_xyz_LE_certs/gandi.ini.

# live dns v5 api key
dns_gandi_api_key=xxxxxxxxxxxxxxxxxxxxxxxx

Create your certificate.

certbot certonly -d "guisam.xyz" -d "*.guisam.xyz" \
--authenticator dns-gandi \
--dns-gandi-credentials /root/guisam_xyz_LE_certs/gandi.ini \
--email guisam@guisam.xyz \
--agree-tos
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for *.guisam.xyz
Unsafe permissions on credentials configuration file: /root/guisam_xyz_LE_certs/gandi.ini
Waiting 10 seconds for DNS changes to propagate

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/guisam.xyz/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/guisam.xyz/privkey.pem
This certificate expires on 2023-04-08.
These files will be updated when the certificate renews.

[...]

Check the wildcard certificate.

openssl x509 -noout -text -in /etc/letsencrypt/live/guisam.xyz/fullchain.pem | \
awk '/Validity|Not|Subject.*CN|Alternative|DNS/'
       Validity
           Not Before: Jan  9 09:52:49 2023 GMT
           Not After : Apr  9 09:52:48 2023 GMT
       Subject: CN = guisam.xyz
           X509v3 Subject Alternative Name:
               DNS:*.guisam.xyz, DNS:guisam.xyz

.. _letsencrypt_certbot_dns_ovh:

Cerbot DNS OVH#

OVH guisam.fr former ip#

แ… dig guisam.fr +noall +answer
guisam.fr.              2974    IN      A       213.186.33.5

แ… sudo resolvectl status
แ… sudo systemctl restart systemd-resolved.service

แ… dig guisam.fr +noall +answer
guisam.fr.              3600    IN      A       82.64.232.18

letโ€™s encrypt certificate OVH#

Manual Setup via Certbot (Advanced) If you prefer full control, use Certbot with the dns-ovh plugin to automate DNS challenges:

  • Create an API token in your OVHcloud account for DNS API access.

Tip

To create an OVH API token for Letโ€™s Encrypt automation, follow these steps:

  1. Access the API Token Creation Page
  2. Configure Token Permissions.
    Set the following rights for the API token:

GET

/domain/zone/*

POST

/domain/zone/*

PUT

/domain/zone/*

DELETE

/domain/zone/*

  1. Set Token Validity
    Choose Unlimited validity to avoid frequent renewals, especially for automated scripts.
  2. Generate the Token
    Click Create Token. Youโ€™ll receive:
    • Application Key

    • Application Secret

    • Consumer Key

  • Install certbot-dns-ovh plugin.

root@forge:~# mkdir certbot && pytohn3 -m venv certbot/Venv && source certbot/Venv/bin/activate
root@forge:~# pip install certbot certbot-dns-ovh
  • Configure /home/guisam/ovh.conf with your OVH API credentials.

root@forge:~# awk -F "=" '{if($2 !~ /ovh-/){$2="xxx"};printf "%-28s %s %s\n", $1, "=", $2}' /home/guisam/ovh.conf
dns_ovh_endpoint             = ovh-eu
dns_ovh_application_key      = xxx
dns_ovh_application_secret   = xxx
dns_ovh_consumer_key         = xxx
  • Use the command:

แ… sudo certbot certonly --dns-ovh --dns-ovh-credentials /home/guisam/ovh.conf \
--preferred-challenges dns --agree-tos --email guisam@free.fr -d forge.guisam.fr
  • Automate renewal using a cron job:

แ… sudo cat /etc/cron.d/cerbot_renew
30 21 * * * root /root/certbot_renew.sh
แ… sudo cat /root/certbot_renew.sh
#!/usr/bin/env bash

set -euo pipefail

typeset -r forgejo_wkd="/home/guiam/forgejo/"
typeset -r certs_dst="$forgejo_wkd/forgejo/gitea/conf/"
typeset -r certs_src="/etc/letsencrypt/live/forge.guisam.fr/"
# shellcheck source=/dev/null
source /root/certbotVenv/bin/activate
cb="$(command -v certbot)"
d="$(command -v docker)"
p="$(command -v pip)"

printf "### Upgrade Pkgs\n%s %s\n\n" "$p" install
"$p" install -U certbot-dns-ovh
printf "\n### Renew Certs\n%s %s\n\n" "$cb" renew
cbr_status=$("$cb" renew)
echo "$cbr_status"
if grep -q skipped <<< "$cbr_status";then
  echo No renewals.
else
  cp "$certs_src"[fp]*.pem "$certs_dst"
  chown guisam: "$certs_dst"[fp]*.pem
  "$d" compose -f "$forgejo_wkd"docker-compose.yaml restart server
fi

Secure traffic using Letโ€™s Encrypt and cert-manager#

  1. Deploy cert-manager.

แ… helm repo add jetstack https://charts.jetstack.io
แ… htlm repo update
แ… helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \
--set config.kind="ControllerConfiguration" \
--set config.enableGatewayAPI=true \
--set crds.enabled=true
  1. Install webhook OVH via Helm.

แ… git clone https://github.com/baarde/cert-manager-webhook-ovh.git
แ… cd cert-manager-webhook-ovh
แ… helm install cert-manager-webhook-ovh ./deploy/cert-manager-webhook-ovh \
  --set groupName=guisam.fr
  1. Create API token

  2. Create k8s secret with application_secret

แ… k create secret generic ovh-credentials \
  --namespace cert-manager \
  --from-literal=applicationSecret=xxx

แ… k get secrets -n cert-manager ovh-credentials \
  -o jsonpath='{.data.applicationSecret}' | base64 -d
  1. Create RBAC authorization (ServiceAccount cert-manager can get Secret ovh-credentials)

cert-manager-webhook-ovh-rbac.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cert-manager-webhook-ovh:secret-reader
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["ovh-credentials"]
    verbs: ["get", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cert-manager-webhook-ovh:secret-reader
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cert-manager-webhook-ovh:secret-reader
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: cert-manager-webhook-ovh
    namespace: cert-manager
แ… k apply -f cert-manager-webhook-ovh-rbac.yaml
  1. Create ClusterIssuer

  2. Create Gateway

  3. Create HTTPRoute

See Helm Charts

notes-charts .

แ… helm template notes . -n notes | \
    yq '.| select(.kind == "Gateway")'
{
  "apiVersion": "gateway.networking.k8s.io/v1",
  "kind": "Gateway",
  "metadata": {
    "name": "notes",
    "namespace": "notes",
    "annotations": {
      "cert-manager.io/cluster-issuer": "letsencrypt-dns01"
    }
  },
  "spec": {
    "gatewayClassName": "nginx",
    "listeners": [
      {
        "name": "http",
        "port": 80,
        "protocol": "HTTP"
      },
      {
        "name": "https",
        "port": 443,
        "protocol": "HTTPS",
        "hostname": "guisam.fr",
        "tls": {
          "mode": "Terminate",
          "certificateRefs": [
            {
              "kind": "Secret",
              "name": "notes-secret"
            }
          ]
        }
      }
    ]
  }
}

แ… helm template notes . -n notes | \
 yq '.| select(.kind == "Gateway" or .kind == "HTTPRoute" or .kind == "ClusterIssuer")'

แ… k get clusterissuers,gtw,httproutes -n notes
NAME                                              READY   AGE
clusterissuer.cert-manager.io/letsencrypt-dns01   True    113m

NAME                                      CLASS   ADDRESS         PROGRAMMED   AGE
gateway.gateway.networking.k8s.io/notes   nginx   10.96.222.193   True         4d17h

NAME                                        HOSTNAMES       AGE
httproute.gateway.networking.k8s.io/notes   ["guisam.fr"]   4d17h