MTG ACME Server

MTG Certificate Lifecycle Manager Server includes an implementation of the ACME protocol according to RFC 8555.

Compatibility

An ACME Client compatibility list can be found here.

Usage

ACME can be used by all clients that are compliant to the RFC 8555 protocol. For the ACME service to be used, an ACME client needs the URL of the ACME directory endpoint, where it can obtain all ACME endpoints specified by the RFC. The URL follows the following pattern:

https://[ACME_URL_PREFIX]/[API_VERSION]/directory

ACME_URL_PREFIX

This part specifies the location of the application. It consists of the domain the ACME server is hosted and a URL prefix which offsets the root of the server application. For example, the URL prefix could be "example.com/acme".

API_VERSION

The API version the ACME endpoint has to use. Since currently only the latest version 2 is supported, the value of API_VERSION has to be "v2".

Listing 1 shows a certificate application using the certbot ACME client. The first command shows the creation of an ACME account which authenticates the subsequent communication with the ACME server. The second command executes the actual certificate application for the example domain mydomain.example.com.

Listing 1. Request certificate via certbot
certbot --server https://example.com/acme/v2/directory register \
        --no-eff-email -m test@example.com --agree-tos

certbot --server https://example.com/acme/v2/directory certonly \
        -d mydomain.example.com --standalone

Cert-manager

If you use Kubernetes and OpenShift and do not want to experience expired certificates, the cert-manager tool makes up for the solution since it is compatible with MTG ERS and particularly the MTG ACME Server.

Cert-manager has built-in mechanisms to use and deploy X.509 certificates, with management functions like requesting and renewing certificates. Certificates can be covertly renewed before they expire, which means that outages of services are avoided. This allows you to provision your resources in Kubernetes using TLS, while not worrying about certificate management. Setting up cert-manager with MTG ERS provides an easy and seamless certificate management experience.

Configuring cert-manager with MTG ERS and ACME

To configure cert-manager on Kubernetes or OpenShift with MTG ERS, you must have ERS installed and functioning with an ACME server.

ERS does not need to be deployed on the same Kubernetes cluster where cert-manager is running.

cert-manager is using ACME Issuer, which implements the ACME protocol (RFC 8555) to automate certificate management.

Step 1: Create an ACME Issuer or ClusterIssuer

To connect cert-manager to your ACME server, you’ll need to create either a ClusterIssuer or an Issuer resource.

Assuming your ACME server is hosted at pki.example.com, configure your ClusterIssuer like this:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: mtg
spec:
  acme:
    email: john@example.com
    server: https://pki.example.com/acme/v2/directory
    caBundle: <base64-encoded root CA in PEM format>  # When ACME server is not publicly trusted
    privateKeySecretRef:
      name: mtg
    solvers:
      - http01:
          ingress:
            class: nginx
ACME Challenges: HTTP-01 vs DNS-01

cert-manager supports both HTTP-01 and DNS-01 challenges to validate domain ownership.

  • HTTP-01 Challenge

    • A temporary web server is spun up during the certificate issuance process.

    • A challenge token is served at: <yourdomain>/.well-known/acme-challenge/<token>;

    • An Ingress resource is created dynamically to route this request.

    • The Ingress must match the domain defined in the certificate’s Common Name or SANs.

    • Important: Define the correct ingress.class in the solver section.

  • DNS-01 Challenge

    • The ACME server asks cert-manager to create a TXT record: _acme-challenge.<yourdomain>

    • The server queries this record to verify ownership.

    • DNS provider configuration varies—check the DNS-01 documentation for supported providers and examples.

Step 2: Issuing a Certificate

There are two main approaches:

Option 1: Annotate an Ingress Resource

You can request a certificate automatically by annotating an Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app
  namespace: demos
  annotations:
    cert-manager.io/cluster-issuer: "mtg"
    cert-manager.io/common-name: "app.example.com"
    cert-manager.io/duration: "24h"
    cert-manager.io/usages: "digital signature,key encipherment"
    cert-manager.io/private-key-algorithm: "RSA"
    cert-manager.io/private-key-size: "4096"
    cert-manager.io/private-key-rotation-policy: "Always"
spec:
  ingressClassName: nginx
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app
                port:
                  number: 80
  tls:
    - hosts:
        - app.example.com
      secretName: app.cert

Once created, cert-manager will:

  • Request the certificate,

  • Perform the challenge,

  • Store the resulting certificate in the specified secret (app.cert).

Option 2: Create a Certificate Resource Directly

This method gives you more control, including the ability to generate JKS or PKCS12 keystores.

kind: Secret
apiVersion: v1
metadata:
  name: keystore-password
  namespace: demos
stringData:
  password: "my-password"
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: second-app.cert
  namespace: demos
spec:
  duration: "24h"
  isCA: false
  subject:
    organizations: ["MTG AG"]
    countries: ["DE"]
    organizationalUnits: ["DevOps"]
    localities: ["Darmstadt"]
    provinces: ["Hessen"]
    streetAddresses: ["Dolivostraße 11"]
    postalCodes: ["64293"]
    serialNumber: "00000000"
  commonName: second-app.example.com
  dnsNames:
    - second-app.example.com
    - more-apps.example.com
  secretName: second-app.cert
  keystores:
    pkcs12:
      create: true
      passwordSecretRef:
        name: keystore-password
        key: password
    jks:
      create: true
      passwordSecretRef:
        name: keystore-password
        key: password
  privateKey:
    algorithm: ECDSA
    size: 256
  issuerRef:
    name: mtg
    kind: ClusterIssuer
    group: cert-manager.io

Endpoints for other policies

By default, the ACME server provides the following endpoint:

https://[ACME_URL_PREFIX]/[API_VERSION]/directory

Client requests to this endpoint use the default policy.

The ACME server provides additional endpoints to support requests that require a different policy. Requests to these endpoints specify a different policy, instead of the default policy of the associated API client. These are the endpoints for the different policy endpoints:

https://[ACME_URL_PREFIX]/[API_VERSION]/[POLICY_ID]/directory

The POLICY_ID must be replaced with a valid policy ID.

For example, to create a certificate under the policy 2ef92632-aaff-4d13-b3cb-6b27f2dac399, use the following URL:

https://[ACME_URL_PREFIX]/[API_VERSION]/2ef92632-aaff-4d13-b3cb-6b27f2dac399/directory.

Using win-acme with ERS ACME

Get the latest version from the official website of win-acme. Create directory c:\ers and place the zip file in this directory.

Open a PowerShell window with administration rights. Run the commands:

Listing 2. Work with win-acme
cd c:\ers
Copy-Item -Path "win-acme.v*.x64.trimmed.zip" -Destination "winacme.zip"
Expand-Archive .\winacme.zip -Destination win-acme
cd .\win-acme\
.\wacs.exe --register --accepttos --emailaddress acme@ers.example.com --baseuri "https://acme.example.com/acme/v2/directory"
.\wacs.exe --target manual --host demo.example.com --accepttos --baseuri "https://acme.example.com/acme/v2/directory"

In Listing 2 exchange domain acme.example.com in the URL acme.example.com/acme/v2/directory with the domain where your ERS ACME runs. win-acme stores data under C:\ProgramData\win-acme. win-acme offers lots of possibilities to configure properties, for example to use an HTTP proxy. See www.win-acme.com/reference/settings and www.win-acme.com/reference/cli for more information.