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 <felix.buenemann@gmail.com>
This commit is contained in:
parent
f411848591
commit
4ecb17cc4c
4 changed files with 19 additions and 5 deletions
|
@ -114,6 +114,10 @@ type Configuration struct {
|
||||||
|
|
||||||
// Email is the email to use during Let's Encrypt registration
|
// Email is the email to use during Let's Encrypt registration
|
||||||
Email string `yaml:"email,omitempty"`
|
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:"letsencrypt,omitempty"`
|
||||||
} `yaml:"tls,omitempty"`
|
} `yaml:"tls,omitempty"`
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,9 @@ var configStruct = Configuration{
|
||||||
Key string `yaml:"key,omitempty"`
|
Key string `yaml:"key,omitempty"`
|
||||||
ClientCAs []string `yaml:"clientcas,omitempty"`
|
ClientCAs []string `yaml:"clientcas,omitempty"`
|
||||||
LetsEncrypt struct {
|
LetsEncrypt struct {
|
||||||
CacheFile string `yaml:"cachefile,omitempty"`
|
CacheFile string `yaml:"cachefile,omitempty"`
|
||||||
Email string `yaml:"email,omitempty"`
|
Email string `yaml:"email,omitempty"`
|
||||||
|
Hosts []string `yaml:"hosts,omitempty"`
|
||||||
} `yaml:"letsencrypt,omitempty"`
|
} `yaml:"letsencrypt,omitempty"`
|
||||||
} `yaml:"tls,omitempty"`
|
} `yaml:"tls,omitempty"`
|
||||||
Headers http.Header `yaml:"headers,omitempty"`
|
Headers http.Header `yaml:"headers,omitempty"`
|
||||||
|
@ -95,8 +96,9 @@ var configStruct = Configuration{
|
||||||
Key string `yaml:"key,omitempty"`
|
Key string `yaml:"key,omitempty"`
|
||||||
ClientCAs []string `yaml:"clientcas,omitempty"`
|
ClientCAs []string `yaml:"clientcas,omitempty"`
|
||||||
LetsEncrypt struct {
|
LetsEncrypt struct {
|
||||||
CacheFile string `yaml:"cachefile,omitempty"`
|
CacheFile string `yaml:"cachefile,omitempty"`
|
||||||
Email string `yaml:"email,omitempty"`
|
Email string `yaml:"email,omitempty"`
|
||||||
|
Hosts []string `yaml:"hosts,omitempty"`
|
||||||
} `yaml:"letsencrypt,omitempty"`
|
} `yaml:"letsencrypt,omitempty"`
|
||||||
}{
|
}{
|
||||||
ClientCAs: []string{"/path/to/ca.pem"},
|
ClientCAs: []string{"/path/to/ca.pem"},
|
||||||
|
|
|
@ -215,6 +215,7 @@ http:
|
||||||
letsencrypt:
|
letsencrypt:
|
||||||
cachefile: /path/to/cache-file
|
cachefile: /path/to/cache-file
|
||||||
email: emailused@letsencrypt.com
|
email: emailused@letsencrypt.com
|
||||||
|
hosts: [myregistryaddress.org]
|
||||||
debug:
|
debug:
|
||||||
addr: localhost:5001
|
addr: localhost:5001
|
||||||
headers:
|
headers:
|
||||||
|
@ -738,6 +739,7 @@ http:
|
||||||
letsencrypt:
|
letsencrypt:
|
||||||
cachefile: /path/to/cache-file
|
cachefile: /path/to/cache-file
|
||||||
email: emailused@letsencrypt.com
|
email: emailused@letsencrypt.com
|
||||||
|
hosts: [myregistryaddress.org]
|
||||||
debug:
|
debug:
|
||||||
addr: localhost:5001
|
addr: localhost:5001
|
||||||
headers:
|
headers:
|
||||||
|
@ -782,12 +784,15 @@ TLS certificates provided by
|
||||||
> accessible on port `443`. The registry defaults to listening on port `5000`.
|
> 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`
|
> 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
|
> 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 |
|
| Parameter | Required | Description |
|
||||||
|-----------|----------|-------------------------------------------------------|
|
|-----------|----------|-------------------------------------------------------|
|
||||||
| `cachefile` | yes | Absolute path to a file where the Let's Encrypt agent can cache data. |
|
| `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. |
|
| `email` | yes | The email address used to register with Let's Encrypt. |
|
||||||
|
| `hosts` | no | The hostnames allowed for Let's Encrypt certificates. |
|
||||||
|
|
||||||
### `debug`
|
### `debug`
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,9 @@ func (registry *Registry) ListenAndServe() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(config.HTTP.TLS.LetsEncrypt.Hosts) > 0 {
|
||||||
|
m.SetHosts(config.HTTP.TLS.LetsEncrypt.Hosts)
|
||||||
|
}
|
||||||
tlsConf.GetCertificate = m.GetCertificate
|
tlsConf.GetCertificate = m.GetCertificate
|
||||||
} else {
|
} else {
|
||||||
tlsConf.Certificates = make([]tls.Certificate, 1)
|
tlsConf.Certificates = make([]tls.Certificate, 1)
|
||||||
|
|
Loading…
Reference in a new issue