From 4ecb17cc4cdce29c5aaecbb9b1aa6fade3e213ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Bu=CC=88nemann?= Date: Thu, 1 Feb 2018 21:16:58 +0100 Subject: [PATCH] registry: support whitelisting letsencrypt hosts This adds a configuration setting `HTTP.TLS.LetsEncrypt.Hosts` which can be set to a list of hosts that the registry will whitelist for retrieving certificates from Let's Encrypt. HTTPS connections with SNI hostnames that are not whitelisted will be closed with an "unknown host" error. It is required to avoid lots of unsuccessful registrations attempts that are triggered by malicious clients connecting with bogus SNI hostnames. NOTE: Due to a bug in the deprecated vendored rsc.io/letsencrypt library clearing the host list requires deleting or editing of the cachefile to reset the hosts list to null. Signed-off-by: Felix Buenemann --- configuration/configuration.go | 4 ++++ configuration/configuration_test.go | 10 ++++++---- docs/configuration.md | 7 ++++++- registry/registry.go | 3 +++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/configuration/configuration.go b/configuration/configuration.go index cdc996b9..4578b7bf 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -114,6 +114,10 @@ type Configuration struct { // Email is the email to use during Let's Encrypt registration Email string `yaml:"email,omitempty"` + + // Hosts specifies the hosts which are allowed to obtain Let's + // Encrypt certificates. + Hosts []string `yaml:"hosts,omitempty"` } `yaml:"letsencrypt,omitempty"` } `yaml:"tls,omitempty"` diff --git a/configuration/configuration_test.go b/configuration/configuration_test.go index 3e1583dd..010ead87 100644 --- a/configuration/configuration_test.go +++ b/configuration/configuration_test.go @@ -78,8 +78,9 @@ var configStruct = Configuration{ Key string `yaml:"key,omitempty"` ClientCAs []string `yaml:"clientcas,omitempty"` LetsEncrypt struct { - CacheFile string `yaml:"cachefile,omitempty"` - Email string `yaml:"email,omitempty"` + CacheFile string `yaml:"cachefile,omitempty"` + Email string `yaml:"email,omitempty"` + Hosts []string `yaml:"hosts,omitempty"` } `yaml:"letsencrypt,omitempty"` } `yaml:"tls,omitempty"` Headers http.Header `yaml:"headers,omitempty"` @@ -95,8 +96,9 @@ var configStruct = Configuration{ Key string `yaml:"key,omitempty"` ClientCAs []string `yaml:"clientcas,omitempty"` LetsEncrypt struct { - CacheFile string `yaml:"cachefile,omitempty"` - Email string `yaml:"email,omitempty"` + CacheFile string `yaml:"cachefile,omitempty"` + Email string `yaml:"email,omitempty"` + Hosts []string `yaml:"hosts,omitempty"` } `yaml:"letsencrypt,omitempty"` }{ ClientCAs: []string{"/path/to/ca.pem"}, diff --git a/docs/configuration.md b/docs/configuration.md index 807353cc..dd14a689 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -215,6 +215,7 @@ http: letsencrypt: cachefile: /path/to/cache-file email: emailused@letsencrypt.com + hosts: [myregistryaddress.org] debug: addr: localhost:5001 headers: @@ -738,6 +739,7 @@ http: letsencrypt: cachefile: /path/to/cache-file email: emailused@letsencrypt.com + hosts: [myregistryaddress.org] debug: addr: localhost:5001 headers: @@ -782,12 +784,15 @@ TLS certificates provided by > accessible on port `443`. The registry defaults to listening on port `5000`. > If you run the registry as a container, consider adding the flag `-p 443:5000` > to the `docker run` command or using a similar setting in a cloud -> configuration. +> configuration. You should also set the `hosts` option to the list of hostnames +> 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. | ### `debug` diff --git a/registry/registry.go b/registry/registry.go index 2e887784..93296255 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -147,6 +147,9 @@ func (registry *Registry) ListenAndServe() error { return err } } + if len(config.HTTP.TLS.LetsEncrypt.Hosts) > 0 { + m.SetHosts(config.HTTP.TLS.LetsEncrypt.Hosts) + } tlsConf.GetCertificate = m.GetCertificate } else { tlsConf.Certificates = make([]tls.Certificate, 1)