Also update all dependencies to the latest versions, where possible. PR: 284580 Approved by: freebsd@yapsoft.it (maintainer timeout)
143 lines
5.8 KiB
Plaintext
143 lines
5.8 KiB
Plaintext
Adapted from the https://github.com/distribution/distribution/pull/3943
|
|
|
|
-mi
|
|
|
|
From 9b4f2caaf89c63b015bbed3e710501df5cf2f75a Mon Sep 17 00:00:00 2001
|
|
From: Alex Lavallee <73203142+lavalleeale@users.noreply.github.com>
|
|
Date: Sun, 18 Jun 2023 09:52:12 -0700
|
|
Subject: [PATCH] Add support for modern ACME
|
|
|
|
Signed-off-by: Alex Lavallee <73203142+lavalleeale@users.noreply.github.com>
|
|
---
|
|
configuration/configuration.go | 4 +
|
|
configuration/configuration_test.go | 14 +-
|
|
docs/configuration.md | 12 +-
|
|
registry/registry.go | 29 +-
|
|
...
|
|
|
|
--- configuration/configuration.go
|
|
+++ configuration/configuration.go
|
|
@@ -129,6 +129,10 @@ type Configuration struct {
|
|
// Hosts specifies the hosts which are allowed to obtain Let's
|
|
// Encrypt certificates.
|
|
Hosts []string `yaml:"hosts,omitempty"`
|
|
+
|
|
+ // DirectoryURL points to the CA directory endpoint.
|
|
+ // If empty, LetsEncrypt is used.
|
|
+ DirectoryURL string `yaml:"directoryurl,omitempty"`
|
|
} `yaml:"letsencrypt,omitempty"`
|
|
} `yaml:"tls,omitempty"`
|
|
|
|
--- configuration/configuration_test.go
|
|
+++ configuration/configuration_test.go
|
|
@@ -89,9 +89,10 @@ var configStruct = Configuration{
|
|
MinimumTLS string `yaml:"minimumtls,omitempty"`
|
|
CipherSuites []string `yaml:"ciphersuites,omitempty"`
|
|
LetsEncrypt struct {
|
|
- CacheFile string `yaml:"cachefile,omitempty"`
|
|
- Email string `yaml:"email,omitempty"`
|
|
- Hosts []string `yaml:"hosts,omitempty"`
|
|
+ CacheFile string `yaml:"cachefile,omitempty"`
|
|
+ Email string `yaml:"email,omitempty"`
|
|
+ Hosts []string `yaml:"hosts,omitempty"`
|
|
+ DirectoryURL string `yaml:"directoryurl,omitempty"`
|
|
} `yaml:"letsencrypt,omitempty"`
|
|
} `yaml:"tls,omitempty"`
|
|
Headers http.Header `yaml:"headers,omitempty"`
|
|
@@ -113,9 +114,10 @@ var configStruct = Configuration{
|
|
MinimumTLS string `yaml:"minimumtls,omitempty"`
|
|
CipherSuites []string `yaml:"ciphersuites,omitempty"`
|
|
LetsEncrypt struct {
|
|
- CacheFile string `yaml:"cachefile,omitempty"`
|
|
- Email string `yaml:"email,omitempty"`
|
|
- Hosts []string `yaml:"hosts,omitempty"`
|
|
+ CacheFile string `yaml:"cachefile,omitempty"`
|
|
+ Email string `yaml:"email,omitempty"`
|
|
+ Hosts []string `yaml:"hosts,omitempty"`
|
|
+ DirectoryURL string `yaml:"directoryurl,omitempty"`
|
|
} `yaml:"letsencrypt,omitempty"`
|
|
}{
|
|
ClientCAs: []string{"/path/to/ca.pem"},
|
|
--- docs/configuration.md
|
|
+++ docs/configuration.md
|
|
@@ -229,6 +229,7 @@ http:
|
|
cachefile: /path/to/cache-file
|
|
email: emailused@letsencrypt.com
|
|
hosts: [myregistryaddress.org]
|
|
+ directoryurl: https://acme-v02.api.letsencrypt.org/directory
|
|
debug:
|
|
addr: localhost:5001
|
|
prometheus:
|
|
@@ -879,11 +880,12 @@ TLS certificates provided by
|
|
> that are valid for this registry to avoid trying to get certificates for random
|
|
> hostnames due to malicious clients connecting with bogus SNI hostnames.
|
|
|
|
-| Parameter | Required | Description |
|
|
-|-----------|----------|-------------------------------------------------------|
|
|
-| `cachefile` | yes | Absolute path to a file where the Let's Encrypt agent can cache data. |
|
|
-| `email` | yes | The email address used to register with Let's Encrypt. |
|
|
-| `hosts` | no | The hostnames allowed for Let's Encrypt certificates. |
|
|
+| Parameter | Required | Description |
|
|
+|----------------|----------|-----------------------------------------------------------------------|
|
|
+| `cachefile` | yes | Absolute path to a file where the Let's Encrypt agent can cache data. |
|
|
+| `email` | yes | The email address used to register with Let's Encrypt. |
|
|
+| `hosts` | no | The hostnames allowed for Let's Encrypt certificates. |
|
|
+| `directoryurl` | no | The url to use for the ACME server. |
|
|
|
|
### `debug`
|
|
|
|
--- registry/registry.go
|
|
+++ registry/registry.go
|
|
@@ -13,7 +13,8 @@ import (
|
|
"syscall"
|
|
"time"
|
|
|
|
- "rsc.io/letsencrypt"
|
|
+ "golang.org/x/crypto/acme"
|
|
+ "golang.org/x/crypto/acme/autocert"
|
|
|
|
logrus_bugsnag "github.com/Shopify/logrus-bugsnag"
|
|
|
|
@@ -210,6 +211,14 @@ func getCipherSuiteNames(ids []uint16) []string {
|
|
return names
|
|
}
|
|
|
|
+// set ACME-server/DirectoryURL, if provided
|
|
+func setDirectoryURL(directoryurl string) *acme.Client {
|
|
+ if len(directoryurl) > 0 {
|
|
+ return &acme.Client{DirectoryURL: directoryurl}
|
|
+ }
|
|
+ return nil
|
|
+}
|
|
+
|
|
// ListenAndServe runs the registry's HTTP server.
|
|
func (registry *Registry) ListenAndServe() error {
|
|
config := registry.config
|
|
@@ -247,19 +256,15 @@ func (registry *Registry) ListenAndServe() error {
|
|
if config.HTTP.TLS.Certificate != "" {
|
|
return fmt.Errorf("cannot specify both certificate and Let's Encrypt")
|
|
}
|
|
- var m letsencrypt.Manager
|
|
- if err := m.CacheFile(config.HTTP.TLS.LetsEncrypt.CacheFile); err != nil {
|
|
- return err
|
|
- }
|
|
- if !m.Registered() {
|
|
- if err := m.Register(config.HTTP.TLS.LetsEncrypt.Email, nil); err != nil {
|
|
- return err
|
|
- }
|
|
- }
|
|
- if len(config.HTTP.TLS.LetsEncrypt.Hosts) > 0 {
|
|
- m.SetHosts(config.HTTP.TLS.LetsEncrypt.Hosts)
|
|
+ m := &autocert.Manager{
|
|
+ HostPolicy: autocert.HostWhitelist(config.HTTP.TLS.LetsEncrypt.Hosts...),
|
|
+ Cache: autocert.DirCache(config.HTTP.TLS.LetsEncrypt.CacheFile),
|
|
+ Email: config.HTTP.TLS.LetsEncrypt.Email,
|
|
+ Prompt: autocert.AcceptTOS,
|
|
+ Client: setDirectoryURL(config.HTTP.TLS.LetsEncrypt.DirectoryURL),
|
|
}
|
|
tlsConf.GetCertificate = m.GetCertificate
|
|
+ tlsConf.NextProtos = append(tlsConf.NextProtos, acme.ALPNProto)
|
|
} else {
|
|
tlsConf.Certificates = make([]tls.Certificate, 1)
|
|
tlsConf.Certificates[0], err = tls.LoadX509KeyPair(config.HTTP.TLS.Certificate, config.HTTP.TLS.Key)
|