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>master
							parent
							
								
									f411848591
								
							
						
					
					
						commit
						4ecb17cc4c
					
				|  | @ -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 New Issue