Mikhail Teterin 83aae5b5d3 sysutils/docker-registry: upgrade from 2.7.1 to 2.8.3
Also update all dependencies to the latest versions, where possible.

PR:		284580
Approved by:	freebsd@yapsoft.it (maintainer timeout)
2025-02-21 00:27:23 +01:00

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)