Micronaut Acme

Extensions to integrate Micronaut and Acme

Version:

1 Introduction

Micronaut supports ACME via the micronaut-acme module.

Release History

1.0.0

  • Initial Release.

    • Support for ordering, renewing and automatically installing certificates.

    • Validating challenges using http, tls and dns (limited) challenges.

    • Acme cli tooling to assist in setup

2 Configuration

Micronaut 1.3.0 or above is required and you must have the micronaut-acme dependency on your classpath:

implementation("io.micronaut.acme:micronaut-acme:1.0.0.RC1")
<dependency>
    <groupId>io.micronaut.acme</groupId>
    <artifactId>micronaut-acme</artifactId>
    <version>1.0.0.RC1</version>
</dependency>

The micronaut-acme module transitively includes the org.shredzone.acme4j:acme4j-client and org.shredzone.acme4j:acme4j-utils dependency.

src/main/resources/application.yml
micronaut:
    server:
        port : 80 (1)
        dual-protocol: true (2)
        ssl:
            enabled: true (3)
acme:
    enabled: true (4)
    tos-agree: true (5)
    cert-location: /path/to/store/certificates (6)
    domain: domain.com (7)
    refresh:
        delay: 1m (8)
        frequency: 24h (9)
    domain-key: | (10)
        -----BEGIN RSA PRIVATE KEY-----
        MIIEowIBAAKCAQEAi32GgrNvt5sYonmvFRs1lYMdUTsoFHz33knzsTvBRb+S1JCc
        al86zAx3dRdFiLyWw4/lXmS6oS5B/NT1w9R7nW3vd0oi4ump/QjWjOd8SxCBqMcR
        ....
        MIIEowIBAAKCAQEAi32GgrNvt5sYonmvFRs1lYMdUTsoFHz33knzsTvBRb+S1JCc
        al86zAx3dRdFiLyWw4/lXmS6oS5B/NT1w9R7nW3vd0oi4ump/QjWjOd8SxCBqMcR
        -----END RSA PRIVATE KEY-----
    account-key: | (11)
        -----BEGIN RSA PRIVATE KEY-----
        MIIEowIBAAKCAQEAi32GgrNvt5sYonmvFRs1lYMdUTsoFHz33knzsTvBRb+S1JCc
        al86zAx3dRdFiLyWw4/lXmS6oS5B/NT1w9R7nW3vd0oi4ump/QjWjOd8SxCBqMcR
        ....
        MIIEowIBAAKCAQEAi32GgrNvt5sYonmvFRs1lYMdUTsoFHz33knzsTvBRb+S1JCc
        al86zAx3dRdFiLyWw4/lXmS6oS5B/NT1w9R7nW3vd0oi4ump/QjWjOd8SxCBqMcR
        -----END RSA PRIVATE KEY-----
    acme-server: acme://server.com (12)
    order:
        pause: 3s (13)
        refresh-attempts: 10 (14)
    auth:
        pause: 1m (15)
        refresh-attempts: 10 (16)
    renew-within: 30 (17)
    challenge-type: tls (18)
1 Set the http port for micronaut. If using http challenge-type this must be set to port 80, unless using a load balancer or some other proxy as Let’s Encrypt for example only sends request to port 80.
2 Enables dual port mode that allows for both http and https to be bound. Default is false
3 Enables ssl for micronaut. Default is false
4 Enables ACME integration for micronaut. Default is false
5 Agrees to the Terms of Service of the ACME provider. Default is false
6 Location to store the certificate on the server.
7 Domain name for the certificate. Can with be a singular domain name (ex. domain.com) or a wildcard domain name (*.domain.com)
8 How long to wait until the server starts up the ACME background process. Default is 1 minute
9 How often the server will check for a new ACME cert and refresh it if needed. Default is 24 hours
10 Private key used to encrypt the certificate. Other options you can use here are classpath:/path/to/key.pem or file:/path/to/key.pem. It is advisable to not check this into source control as this is the secret to handle the domain encryption.
11 Private key used to when setting up your account with the ACME provider. Other options you can use here are classpath:/path/to/key.pem or file:/path/to/key.pem. It is advisable to not check this into source control as this is your account identifier.
12 Url of the ACME server (ex. acme://letsencrypt.org/staging)
13 Time to wait in between polling order status of the ACME server. Default is 3 seconds
14 Number of times to poll an order status of the ACME server. Default is 10
15 Time to wait in between polling authorization status of the ACME server. Default is 3 seconds
16 Number of times to poll an authorization status of the ACME server. Default is 10
17 Number of days before the process will start to try to refresh the certificate from the ACME provider. Default is 30 days
18 The challenge type you would like to use. Default is tls. Possible options : http, tls, dns

3 Challenge Types

ACME supports 3 different challenge types which will be used to validate that you in fact own the domain before a certificate is issued.

3.1 HTTP-01

Utilizing http challenge type you will need to do one of the following two things :

  1. enable dual protocol support

  2. setup redirect from http → https in any load balancer/proxy server you have in front of your application.

The reason for this is that Let’s Encrypt for example will only call out to the http challenge type over http and nothing else but will follow redirects.

src/main/resources/application.yml
acme:
  challenge-type: 'http'

micronaut:
  server:
    dual-protocol: true

3.2 TLS-APLN-01

Utilizing tls challenge type is the simpliest to configure and thus the default because you will only be required to open up the default secure port for the server to allow the challenge server to validate it.

src/main/resources/application.yml
acme:
  challenge-type: 'tls'

3.3 DNS-01

Utilizing dns challenge type allows validation to be done via entry of a DNS TXT record. Currently the application will log out a message that looks as follows.

DNS output
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
							CREATE DNS `TXT` ENTRY AS FOLLOWS
				_acme-challenge.example.com with value 79ZNJaxlcLYIFootHL6Rrbh2VUCfFGgPeurVyjoRrS8
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Once this is output you will need to log into your DNS provider and create a TXT entry with the following key and value.

  • key: _acme-challenge.example.com

  • value: 79ZNJaxlcLYIFootHL6Rrbh2VUCfFGgPeurVyjoRrS8

Since this is a manual process you will also want to bump out your acme.auth.pause duration so that there is enough time between retries and time take for the manual entry/DNS propagation.

src/main/resources/application.yml
acme:
  challenge-type: 'dns'
  auth:
    # Due to the current manual nature in which the dns validation has to be done currently
    # we change the amount of time we wait before trying to authorize again to make sure there
    # is time for us logging into the dns interface, setting a TXT record and waiting for it
    # to propagate.
    pause: 2m

4 CLI

To be able to secure your application using ACME there will be a few setup steps necessary before you can start using the new certificates. A cli application can be found to assist in those steps, such as creating key pairs and creating accounts.

4.1 Installation

Installation of the cli

4.1.1 Download

A zip containing the cli is uploaded to maven central for release artifacts or jfrog oss repository for snapshot artifacts.

Select the version you want to install and download the artifact with the name. micronaut-acme-cli-<version>.zip

4.1.2 Build from source

Clone the repository found below

$ git clone git@github.com:micronaut-projects/micronaut-acme.git

cd into the micronaut-acme directory and run the following command:

In a terminal, execute the following task Unix

$ ./gradlew acme-cli:shadowDistZip

Windows

$ ./gradlew.bat acme-cli:shadowDistZip

The built cli application zip can be found under micronaut-acme/acme-cli/build/distributions.

4.1.3 Install through Binary on Windows

Once you have downloaded or built from source you now need to setup your PATH

  • Extract the binary to appropriate location (For example: C:\micronaut-acme-cli)

  • Create an environment variable MICRONAUT_ACME_HOME which points to the installation directory i.e. C:\micronaut-acme-cli

  • Update the PATH environment variable, append %MICRONAUT_ACME_HOME%\bin.

You should now be able to run the Micronaut CLI from the command prompt as follows:

$ acme-cli --help

4.1.4 Install through Binary on Linux/MacOSx

Once you have downloaded or built from source you now need to setup your PATH

In your shell profile (~/.bash_profile if you are using the Bash shell), export the MICRONAUT_ACME_HOME directory and add the CLI path to your PATH:

bash_profile/.bashrc
export MICRONAUT_ACME_HOME=~/path/to/micronaut-acme-cli
export PATH="$PATH:$MICRONAUT_ACME_HOME/bin"

Reload your terminal or source your shell profile with source:

> source ~/.bash_profile

You should now be able to run the Micronaut CLI from the command prompt as follows:

$ acme-cli --help

4.2 Usage

Creating keypairs

A utility to help with creating keypairs. This is akin to doing something like so with openssl

$ openssl genrsa -out /tmp/mydomain.com-key.pem 4096

These keypairs will be used for both ACME accounts as well as each domain will also need its own keypair defined.

Usage:

Usage: acme-cli create-key [-h] [-k=<keyDir>] [-n=<keyName>] [-s=<keySize>]
Creates an keypair for use with account creation
  -h, --help                 Show usage of this command
  -k, --key-dir=<keyDir>     Custom location on disk to put the key to be used
                               with this account.
                               Default: /tmp
  -n, --key-name=<keyName>   Name of the key to be created
                               Default: acme.pem
  -s, --key-size=<keySize>   Size of the key to be generated
                               Default: 4096

Creating an Account

Creates a new account for a given ACME provider. This command will either create a new account keypair for you or you can pass the account keypair that you have generated using the acme-cli create-key or via openssl or other means in as a parameter.

Certbot or many of the other tools out there can also accomplish this step if you dont want to use this tool.

Usage:

Usage: create-account (-u=<serverUrl> | --lets-encrypt-prod | --lets-encrypt-staging) [-h]
                      -e=<email> [-k=<keyDir>] [-n=<keyName>]
Creates a new account on the given ACME server
  -e, --email=<email>        Email address to create account with.
  -h, --help                 Show usage of this command
  -k, --key-dir=<keyDir>     Directory to create/find the key to be used for this account.
                               Default: /tmp
  -n, --key-name=<keyName>   Name of the key to be created/used
                               Default: acme.pem
ACME server URL
      --lets-encrypt-prod    Use the Let's Encrypt prod URL.
      --lets-encrypt-staging Use the Let's Encrypt staging URL
  -u, --url=<serverUrl>      URL of ACME server to use

Deactivating an Account

Deactivates a given account based on the account key that was used to create the account.

Usage:

Usage: deactivate-account (-u=<serverUrl> | --lets-encrypt-prod | --lets-encrypt-staging) [-h]
                          [-k=<keyDir>] [-n=<keyName>]
Deactivates an existing ACME account
  -h, --help                 Show usage of this command
  -k, --key-dir=<keyDir>     Directory to find the key to be used for this account.
                               Default: /tmp
  -n, --key-name=<keyName>   Name of the key to be used
                               Default: acme.pem
ACME server URL
      --lets-encrypt-prod    Use the Let's Encrypt prod URL.
      --lets-encrypt-staging Use the Let's Encrypt staging URL
  -u, --url=<serverUrl>      URL of ACME server to use