acme

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2021 License: Apache-2.0 Imports: 18 Imported by: 0

README

acme

CI Workflow

ACME

Note: If you already use CoreDNS and know how SSL and ACME works, you can go straight to the installation and configuration. You can also read the RFC.

If you have ever setup SSL certificates from Let's Encrypt, you would know that renewing them are important as certificates expire within 90 days of installation. This plugin is a solution that automates certificate management through the ACME protocol.

Table of Contents

  1. What is ACME and why do you need it?
  2. Why is ACME important?
  3. How does ACME work?
  4. Pros and Cons
  5. Getting Started

What is ACME and why do you need it?

Without Certificate With Certificate

(SSL/TLS) certificates are used to encrypt information between the client and the server. Information becomes unreadable to everyone except for you and the server you are sending the information to. This protects it from hackers and identity thieves.

Certificate management is the act of issuing, renewing and revoking certificates. There are two ways to do it: 1) Manually by yourself or 2) Automatically using the ACME protocol. ACME automates the creation and renewal of your certificates. This enables more secure communications and certificate management while saving time and manpower.

Why is ACME important?

To understand the importance of ACME, you need to know how manual certificate management works and its risks.

Manual Certificate Management

To generate a certificate, you need to do the following:

  1. Generate a Certificate Signing Request (CSR) manually Creating a CSR

  2. Cut and paste the CSR into a Certificate Authority's (CA) page Submitting a CSR

  3. Prove ownership of the domain(s) in the CSR by manually resolving the CA's challenges

  4. Download the issued certificate and install it on the server. Installing SSL Cert

Certificate Mismanagement

Certificate mismanagement can occur when you manage your certificates manually because:

  • All certificates will expire
  • Users need to be reminded to renew certificates
  • Manpower and time is needed to renew certificates manually
  • The process is tedious and cumbersome

Managing certificates manually poses a risk to systems in production because:

  • Users can forget to renew certificate until expiration Expired Certificate

  • Risk of exposure leads to gaps in ownership and hence Man-in-the-Middle attacks and data breaches. Man in the Middle Attacks

How can ACME help?

ACME automates the entire process. It enables secure certificate management and prevents these risks from happening. In a production environment, you could have hundreds of certificates to keep watch everyday and renew or revoke for many different domains. This saves a lot of manpower and time for managing these certificates manually.

How does ACME work?

In the beginning, the client needs to register an account with a CA and add the domain under it. Then it needs to prove that it owns the domain through domain validation.

Domain Validation

Domain Validation

  1. Client first generates a public and private key. Client keeps the private key.
  2. The CA issues one or more challenges (DNS/HTTPS/TLS-ALPN) to prove that the client controls the domain.
  3. CA also sends a nonce to sign with the private key. This proves that the client controls the public and private keys.
  4. Client fulfills the challenge and signs the provided nonce.
  5. LetsEncrypt verifies the nonce and checks whether the challenge is fulfilled.
  6. Server is authorised to do certificate management for the domain with the key-value pair. The key-value pair is now known as the authorised key-value pair.
ACME Challenges

These challenges are for proving to the CA that the client owns the domain. In this case, we refer to the client as the one requesting for the certificate and the server as the Certificate Authority.

  1. HTTP
  • Client constructs a key authorization from the token in the challenge and the client's account key.
  • Client then provisions it as a resource on the HTTP server for the domain and notifies the server. The key authorization will be placed at http://{domain}/.well-known/acme-challenge/{token}.
  • Server will try to retrieve the key authorization from the URL and verify its value matches.
  1. DNS
  • Client constructs a key authorization from the token in the challenge and the client's account key. It computes the SHA256 digest of it.
  • Client provisions a TXT record with the digest under _acme-challenge.{domain}, the validation domain. Client notifies the server.
  • Server will try to retrieve the TXT record under the validation domain name and verify its value matches.
  1. TLS-ALPN
  • Known as TLS with Application-Layer Protocol Negotiation (TLS ALPN). It allows clients to negotiate what protocol to use for communication (at the application level).
  • Client configures a TLS server to respond to specific connection attempts using the ALPN extension with identifying information.
  • Client builds a self-signed certificate with the required extensions. The acmeIdentifier extension must contain the SHA256 digest of the key authorization from the token in the challenge. The subjectAlternativeName extension must contain the domain name being validated.
  • Server connects to a TLS server at one of the addresses resolved for the domain name and verifies that a certificate with the specified content is presented. It must use port 443.
Certificate Issuance

Certificate Issuance

  • Server generates a Certificate Signing Request and a public key. It asks the CA to issue a certificate with this public key.
  • Server signs the public key in the CSR and the CSR with the authorised private key.
  • CA verifies both signatures and issues the certificate.
  • Server receives the certificate and installs it on the relevant domain.
Certificate Revocation

Likewise, for revocation, a revocation request is generated and signed with the authorised private key. It is then sent to the CA to revoke the certificate.

Pros and Cons

Pros

ACME enables automatic renewal, replacement and revocation of domain validated TLS/SSL certificates.

  • You no longer have to spend energy and time to keep a watch on their expiry dates and worry about certificates expiring.
  • You no longer have to dig out the instructions to renew and configure the certificates.
  • You no longer have to worry about data breaches or Man-in-the-Middle attacks that happen when your certificates expire
  • Certificates from LetsEncrypt are free!

Just set up ACME once and let it run.

Cons
  • LetsEncrypt does not offer OV (Organisation Validation) or EV (Extended Validation) certificates as stated in their FAQ.

Getting Started

Configuration
Basic
acme {
  domain <DOMAIN>
}
  • DOMAIN is the domain name the plugin should be authoritative for.
  • Under this configuration, only the DNS challenge will be used for ACME.
Advanced
acme {
  domain DOMAIN

  # optional parameters
  challenge <CHALLENGE> port <PORT>
}

You can specify one or more challenges the CA can use to verify your ownership of the domain.

  • CHALLENGE is the name of the challenge you will use for ACME. There are only two options: tlsalpn and http01.
  • PORT is the port number to use for each challenge. Make sure the ports are open and accessible.
Examples
Basic
acme {
  domain contoso.com
}

This will perform ACME for contoso.com and use the DNS01 challenge only.

Advanced
acme {
  domain example.com

  challenge http port 90
  challenge tlsalpn port 8080
}

This will perform ACME for example.com and perform the following challenges:

  1. HTTP challenge on port 90
  2. TLSALPN challenge on port 8080
  3. DNS challenge
How this plugin works with CoreDNS

ACME uses challenges to prove that you own the domain. One challenge is DNS, which requires adding DNS records on the authoritative nameserver for your domain. This plugin uses CoreDNS to create and providing the necessary records for solving this challenge. It can also resolve the other challenges separately.

Installation

This is a CoreDNS plugin so you need to set up CoreDNS first.

Basic

If you have Golang installed, you can execute the script below to build the binary.

# Clone CoreDNS
git clone https://github.com/coredns/coredns
cd coredns

# Add acme:github.com/chinzhiweiblank/coredns-acme into the plugin configuration
echo "acme:github.com/chinzhiweiblank/coredns-acme" >> plugin.cfg

# Get the modules
go get github.com/chinzhiweiblank/coredns-acme

# Generate Files
go generate

# Tidy the modules
go mod tidy

# Compile
go build
Docker

The recommended way is to use a Docker container to build the binary and output it.

docker run --rm -v "$PWD":/usr/src -w /usr/src golang:1.16 bash -c "git clone https://github.com/coredns/coredns; cd coredns; echo 'acme:github.com/chinzhiweiblank/coredns-acme' >> plugin.cfg; go get github.com/chinzhiweiblank/coredns-acme; go generate; go mod tidy; go build;"
Disclaimer

Make sure you have the following conditions:

  • You own the domain
  • Your CoreDNS server is the authoritative nameserver for the domain

See Also

  1. Challenge Types
  2. RFC for ACME
  3. ACME Protocol

Documentation

Index

Constants

View Source
const (
	HTTPChallenge     = "http"
	TLPSALPNChallenge = "tlsalpn"
	CHALLENGE         = "challenge"
	DOMAIN            = "domain"
	PORT              = "port"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ACME

type ACME struct {
	Manager *certmagic.ACMEManager
	Config  *certmagic.Config
	Zone    string
}

func NewACME

func NewACME(acmeManagerTemplate certmagic.ACMEManager, zone string) ACME

func (ACME) GetCert

func (a ACME) GetCert(zone string) error

func (ACME) IssueCert

func (a ACME) IssueCert(zones []string) error

func (ACME) OnStartup

func (a ACME) OnStartup() error

func (ACME) RevokeCert

func (a ACME) RevokeCert(zone string) error

type AcmeConfig

type AcmeConfig struct {
	Zone                    string
	Ipv4Addr                net.IP
	Ipv6Addr                net.IP
	AuthoritativeNameserver string
}

type AcmeHandler

type AcmeHandler struct {
	Next plugin.Handler

	*AcmeConfig
	// contains filtered or unexported fields
}

func (AcmeHandler) Name

func (h AcmeHandler) Name() string

func (AcmeHandler) ServeDNS

func (h AcmeHandler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error)

type Provider

type Provider struct {
	sync.Mutex
	// contains filtered or unexported fields
}

func (*Provider) AppendRecords

func (p *Provider) AppendRecords(ctx context.Context, zoneName string, recs []libdns.Record) ([]libdns.Record, error)

func (*Provider) DeleteRecords

func (p *Provider) DeleteRecords(ctx context.Context, zoneName string, recs []libdns.Record) ([]libdns.Record, error)

func (*Provider) GetRecords

func (p *Provider) GetRecords(ctx context.Context, zoneName string) ([]libdns.Record, error)

type RecordStore added in v1.0.2

type RecordStore struct {
	// contains filtered or unexported fields
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL