Code Monkey home page Code Monkey logo

identitry / cert-manager-webhook-loopia Goto Github PK

View Code? Open in Web Editor NEW
4.0 1.0 6.0 139 KB

cert-manager-webhook-loopia is an ACME webhook for Cert-Manager that allows for Cert-Manager to use DNS-01 challenge against the Loopia DNS.

License: Apache License 2.0

Dockerfile 2.60% Makefile 5.26% Mustache 11.29% Go 80.85%
cert-manager-webhook cert-manager acme acme-client acme-dns kubernetes letsencrypt letsencrypt-certificates lets-encrypt tls tls-certificate loopia loopia-api

cert-manager-webhook-loopia's Introduction

Cert-Manager ACME webhook for Loopia (cert-manager-webhook-loopia)

Warning

This repository is in urgent need of some TLC but lack of time and interest makes me the wrong person to handle it. If you feel that you are the right person to give it some maintenence, please fork it and let me know and I'll add a reference to the new repository.

cert-manager-webhook-loopia is an ACME webhook for Cert-Manager that allows for Cert-Manager to use DNS-01 challenge against the Loopia DNS.

test

release

Table of Contents

  1. Overview

    1.1. Building

    1.2. Docker Image

    1.3. Compatibility

  2. Installation

    2.2. Install Cert-Manager

    2.3. Install/Uninstall Loopia Webhook

  3. Using the Loopia Webhook

    3.1. Loopia API credential Secret

    3.2. Cert-Manager Issuer configuration

    3.3. Cert-Manager Certificate configuration

    3.4. Troubleshooting

  4. Conformance Testing

1. Overview

Cert-Manager is a Kubernetes certificate management controller, it allows for issuing certifaces from a variety of sources. cert-manager-webhook-loopia that acts as an extension to cert-manager is targeted the use of certificates issued through the ACME-protocol and especially the DNS01 challenge targeting the Loopia hosting company DNS. Issued certificates are stored in Kubernetes as secrets for use within Kubernetes.

The main issuer of public certificates using the ACME-protocol is Let´s Encrypt that issues free public TLS-certificates. What´s special about Let´s Encrypt is that the lifetime of the certificates they issue are short and issuance is automated using the ACME-protocol, that means you need a way to automatically request new certificates and renew certificates when the old are about expire.

The ACME DNS-01 challenge is one of two diiferent challenges (the other is HTTP-01) that you as a user of Let´s Encrypt certificates could use to prove you´re the owner of the domain the certificate is to be issued for. ACME DNS-01 challenge has an advantage over HTTP-01 in that it allows for issuance of wildcard certificates. ACME DNS-01 challenge requires you to be able to automatically add a DNS TXT record to your public DNS zone as a proof of ownership of the domain.

The role of cert-manager-webhook-loopia is to act as a DNS-provider and create a DNS TXT-record in the '_acme-challenge' sub domain of the domain a certificate should be issued for, for example: '_acme-challenge.example.com'. The value the TXT-record should contain is supplied by the ACME issuer. When the DNS01 challenge is complete, cert-manager-webhook-loopia is responsible for cleaning up the TXT-records created. Currently cert-manager-webhook-loopia can´t delete the '_acme-challenge' sub domain due to lack of functionality in the Loopia-Go client used but TXT records are removed.

Loopia is a major hosting company based in Sweden but has subsidaries in Norway and Serbia but also offers services to companies and individuals in the rest of the world.

Loopia API that is used by cert-manager-webhook-loopia is an API based on XMLRPC that allows for reading and editing of your DNS domain(s) hosted at Loopia. This API becomes very handy when we need to request a lot of certificates automatically and also renew these when they expire. Loopia-Go client is the client library used for communicating with Loopia API.


NOTE You need to register for special Loopia API user credentials in Loopia CustomerZone, this is also required for testing.


Loopia API Logo

1.1. Building

Build the container image cert-manager-webhook-loopia:latest

make build

1.2. Docker Image

An image is hosted on Docker Hub: identitry/cert-manager-webhook-loopia

1.3. Compatibility

This webhook has been tested with cert-manager v1.2.0 and Kubernetes v1.20.x on amd64.

2. Installation

2.1. Prereqs

Before starting the installation of cert-manager-webhook-loopia the prerequisite is that you have a working Kubernetes cluster, either in the cloud or on bare metal. You could of course use Cert-Manager and cert-manager-webhook-loopia on Minikube, Microk8s, K3s or Docker Desktop with Kubernetes enabled. The installation also require that you have registered for Loopia API credentials in the Loopia CustomerZone, these special credentials are required for cert-manager-webhook-loopia to work.

2.2. Install Cert-Manager

The easiest way to install Cert-Manager is using Helm. For this Helm v3 needs to be installed already. This is how to install Cert-Manager using Helm, if you wish to install using manifests or using other options you can use this instruction.

Add the Jetstack Helm Repository:

helm repo add jetstack https://charts.jetstack.io

Update Helm chart repository cache:

helm repo update

Install Cert-Manager (with CRD´s):

helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.2.0 --create-namespace --set installCRDs=true

Verify Cert-Manager installation by getting the cert-manager running pods:

kubectl get pods --namespace cert-manager

NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-85f9bbcd97-666mx              1/1     Running   0          2m
cert-manager-cainjector-74459fcc56-r6dc8   1/1     Running   0          2m
cert-manager-webhook-57d97ccc67-jngx8      1/1     Running   0          2m

Note that it might take a minute or two before all pods are running.

2.3. Install/Uninstall Loopia Webhook

The cert-manager-webhook-loopia can be installed in multiple ways but the easiest is using helm:

helm repo add identitry https://identitry.github.io/cert-manager-webhook-loopia
helm repo update
helm install cert-manager-webhook-loopia identitry/cert-manager-webhook-loopia --namespace cert-manager

This will install a helm chart with the pre built image available in Docker Hub as identitry/cert-manager-webhook-loopia.

If you wish to uninstall cert-manager-webhook-loopia simply run this command:

helm uninstall cert-manager-webhook-loopia --namespace cert-manager

3. Using the Loopia Webhook

Ok, now you have probably installed cert-manager-webhook-loopia, it´s time to configure it for getting a certificate from Let´s Encrypt.

3.1. Loopia API credential Secret

In order to logon to the Loopia API you first need a set of credentials, as a customer with Loopia you can request these in the Loopia Customer Zone, the usual credentials we normally use to logon with Loopia wont work.


Note: Your Loopia API account requires these permissions:

  • addZoneRecord
  • getZoneRecords
  • removeZoneRecord
  • removeSubdomain

When we have the Loopia API credentials (username and password) we need to store these credentials safely within Kubernetes and Kubernetes has a special API object type, Secret that can be used for this.

The Secret needs to be created in the "cert-manager" namespace, otherwise permissions needs to be given for cert-manager to use the Secret. This is the secret configuration we need to apply to Kubernetes, you can find this file in the configuration/ folder. Replace the username and password with your Loopia API credentials:

apiVersion: v1
kind: Secret
metadata:
  name: loopia-credentials
  namespace: cert-manager
stringData:
  username: "LOOPIA API USERNAME"
  password: "LOOPIA API PASSWORD"

Then deploy the Secret to Kubernetes using this command:

kubectl apply -f configuration/loopia-credentials.yaml

You can also deploy the secret using this command, replace the username and password with your Loopia API credentials.

kubectl create secret generic loopia-credentials --namespace cert-manager --from-literal=username='LOOPIA API USERNAME' --from-literal=password='LOOPIA API PASSWORD'

To remove the Secret, run this command:

kubectl delete secret loopia-credentials --namespace cert-manager

3.2 Cert-Manager Issuer configuration

Issuers and ClusterIssuers, are Kubernetes resources that represent certificate authorities (CAs) that are able to generate signed certificates. An Issuer is limited to a single namespace whereas a ClusterIssuer can issue certificates for the whole cluster. The example yaml below is for creating a ClusterIssuer but you can just change "ClusterIssuer" to "Issuer" if you like to restrict the certificate to a single namespace.

You also need to replace the email adress to your real email adress, Let´s Encrypt needs this to identify you as a subscriber and holder of the private key. This email adress will also recieve warnings of expiring certs and notifications about changes to Let´s Encrypts privacy policy.

The ClusterIssuer example below is targeted Let´s Encrypts staging environment, this will allow you to get things right before issuing trusted certificates and reduce the chance of your running up against rate limits. When you have successfully tested your configuration you can remove the staging ClusterIssuer and replace it with a production one pointing to the Let´s Encrypt production environment, changing the name and the name of the Secret where the issued certificate should end up.

The example below is also available as configuration/le-staging-clusterissuer.yaml.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # The ACME server URL for testing.
    server: https://acme-staging-v02.api.letsencrypt.org/directory

    # The ACME server URL for production.
    # server: https://acme-v02.api.letsencrypt.org/directory

    # You must replace this email address with your own.
    # Let's Encrypt will use this to contact you about expiring
    # certificates, and issues related to your account.
    email: [email protected]

    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-staging

    solvers:
      - dns01:
          webhook:
            groupName: acme.webhook.loopia.com
            solverName: loopia
            config:
              usernameSecretKeyRef:
                name: loopia-credentials
                key: username
              passwordSecretKeyRef:
                name: loopia-credentials
                key: password

To deploy the Cluster Issuer configuration file after you have edit it you can run this command:

kubectl apply -f configuration/le-staging-clusterissuer.yaml

Afterwards, check the status of the Cluster Issuer.

kubectl describe clusterissuer letsencrypt-staging

To delete the Cluster Issuer, run this command:

kubectl delete clusterissuer letsencrypt-staging

3.3. Cert-Manager Certificate configuration

Time to wrap this up, the final Kubernetes resource we need is a Certificate. The Certificate resource represents a human readable definition of a certificate request that is to be honored by an issuer which is to be kept up-to-date.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: staging-cert-example-com
spec:
  commonName: example.com # REPLACE THIS WITH YOUR DOMAIN
  dnsNames:
  - example.com # REPLACE THIS WITH YOUR DOMAIN
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
  secretName: example-com-tls

To check the status of the certificate you can run this command:

kubectl describe certificate staging-cert-example-com

If you wish to delete the Certificate, run this command:

kubectl delete certificate staging-cert-example-com

3.4. Troubleshooting

Cert-Manager has a great page that describes how to do troubleshooting.

4. Conformance Testing

The testing of a cert-manager weebhook is a bit special and not a typical unit or integration test, instead there´s a test-fixure supplied that build up a complete Kubernetes control plane where testing is performed. This not only requires you to download a set of test binaries but also prepare some files for testing.

  • testdata/scripts/fetch-test-binaries.sh:
    Script for downloading test binaries, this script is limited to Linux/Amd64 but other OS/architecture versions are available.

  • testdata/loopia/config.json:
    This is a config file that basically informs the test fixture how to find the Kubernetes secret and keys that contains the Loopia API username and password.

  • testdata/loopia/loopia-credentials.yaml:
    A Kubernetes secret configuration that will be applied to the Kubernetes control plane during test. Real Loopia API credentials is required since the tests connects to Loopia creating a cert-manager-dns01-tests sub domain with a TXT-record.

  • testdata/bin:
    Folder location for the test-binaries.

cert-manager-webhook-loopia has been tested for conformance, not only simple create/delete TXT-record but also in Strict/Extended mode where multiple simultaneus TXT-records are tested.

cert-manager-webhook-loopia's People

Contributors

identitry avatar istyf avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

cert-manager-webhook-loopia's Issues

secrets: forbidden

Summary

I am getting the following issue which maybe related to puzzle/cert-manager-webhook-dnsimple#8 (comment).

I am quite sure secret loopia-mydomain-issuer-credentials exists on namespace cert-manager.

I1004 09:49:13.709848       1 dns.go:88] cert-manager/controller/challenges/Present "msg"="presenting DNS01 challenge for domain" "dnsName"="staging.mydomain.com" "domain"="staging.mydomain.com" "resource_kind"="Challenge" "resource_name"="staging-mydomain-com-nnw2b-1608050242-1242144700" "resource_namespace"="default" "resource_version"="v1" "type"="DNS-01"
E1004 09:49:13.969132       1 controller.go:163] cert-manager/controller/challenges "msg"="re-queuing item due to error processing" "error"="unable to get credential: failed to load secret \"cert-manager/loopia-mydomain-issuer-credentials\": secrets \"loopia-mydomain-issuer-credentials\" is forbidden: User \"system:serviceaccount:cert-manager:cert-manager-webhook-loopia\" cannot get resource \"secrets\" in API group \"\" in the namespace \"cert-manager\"" "key"="default/staging-mydomain-com-nnw2b-1608050242-1242144700"
$ kubectl get secret loopia-mydomain-issuer-credentials  --namespace=cert-manager
NAME                             TYPE     DATA   AGE
loopia-mydomain-issuer-credentials   Opaque   2      16m

Version

k3s version v1.21.5+k3s1 (acad8ef8)
go version go1.16.8

loopia-go is broken

It appears the loopia-go library is broken at the moment, see my PR at jonlil/loopia-go#14

I got it to work by building my own version with this patch applied.

This is (most likely) also the cause of issue #5

Error presenting challenge: unexpected error: txt-record was not created

Hi!

Been following the guide but seem to get stuck when the challenge is created:

Solver:
dns01:
Webhook:
Config:
Password Secret Key Ref:
Key: password
Name: loopia-credentials
Namespace: adguard
Username Secret Key Ref:
Key: username
Name: loopia-credentials
Namespace: adguard
Group Name: acme.webhook.loopia.com
Solver Name: loopia
Token: xxxx
Type: DNS-01
URL: https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/xxxx
Wildcard: false
Status:
Presented: false
Processing: true
Reason: unexpected error: txt-record was not created:
State: pending
Events:
Type Reason Age From Message


Normal Started 13m cert-manager Challenge scheduled for processing
Warning PresentError 3m24s (x8 over 13m) cert-manager Error presenting challenge: unexpected error: txt-record was not created:

I have created a "parked" sub dns called adguard.mydomain.com. Do I need to add some data to this record?

Best,
Filip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.