Merge pull request #780 from aaronlehmann/automatic-secret
Automatically generate a HTTP secret if none is providedmaster
						commit
						b6ec2f2b10
					
				|  | @ -30,7 +30,6 @@ storage: | ||||||
|             enabled: false |             enabled: false | ||||||
| http: | http: | ||||||
|     addr: :5000 |     addr: :5000 | ||||||
|     secret: asecretforlocaldevelopment |  | ||||||
|     debug: |     debug: | ||||||
|         addr: localhost:5001 |         addr: localhost:5001 | ||||||
| redis: | redis: | ||||||
|  |  | ||||||
|  | @ -1184,7 +1184,12 @@ should have both preceding and trailing slashes, for example <code>/path/</code> | ||||||
|     <td> |     <td> | ||||||
| A random piece of data. This is used to sign state that may be stored with the | A random piece of data. This is used to sign state that may be stored with the | ||||||
| client to protect against tampering. For production environments you should generate a | client to protect against tampering. For production environments you should generate a | ||||||
| random piece of data using a cryptographically secure random generator. | random piece of data using a cryptographically secure random generator. This | ||||||
|  | configuration parameter may be omitted, in which case the registry will automatically | ||||||
|  | generate a secret at launch. | ||||||
|  | <p /> | ||||||
|  | <b>WARNING: If you are building a cluster of registries behind a load balancer, you MUST | ||||||
|  | ensure the secret is the same for all registries.</b> | ||||||
|     </td> |     </td> | ||||||
|   </tr> |   </tr> | ||||||
| </table> | </table> | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| package handlers | package handlers | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	cryptorand "crypto/rand" | ||||||
| 	"expvar" | 	"expvar" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/rand" | 	"math/rand" | ||||||
|  | @ -30,6 +31,10 @@ import ( | ||||||
| 	"golang.org/x/net/context" | 	"golang.org/x/net/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // randomSecretSize is the number of random bytes to generate if no secret
 | ||||||
|  | // was specified.
 | ||||||
|  | const randomSecretSize = 32 | ||||||
|  | 
 | ||||||
| // App is a global registry application object. Shared resources can be placed
 | // App is a global registry application object. Shared resources can be placed
 | ||||||
| // on this object that will be accessible from all requests. Any writable
 | // on this object that will be accessible from all requests. Any writable
 | ||||||
| // fields should be protected.
 | // fields should be protected.
 | ||||||
|  | @ -102,6 +107,7 @@ func NewApp(ctx context.Context, configuration configuration.Configuration) *App | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	app.configureSecret(&configuration) | ||||||
| 	app.configureEvents(&configuration) | 	app.configureEvents(&configuration) | ||||||
| 	app.configureRedis(&configuration) | 	app.configureRedis(&configuration) | ||||||
| 	app.configureLogHook(&configuration) | 	app.configureLogHook(&configuration) | ||||||
|  | @ -337,6 +343,19 @@ func (app *App) configureLogHook(configuration *configuration.Configuration) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // configureSecret creates a random secret if a secret wasn't included in the
 | ||||||
|  | // configuration.
 | ||||||
|  | func (app *App) configureSecret(configuration *configuration.Configuration) { | ||||||
|  | 	if configuration.HTTP.Secret == "" { | ||||||
|  | 		var secretBytes [randomSecretSize]byte | ||||||
|  | 		if _, err := cryptorand.Read(secretBytes[:]); err != nil { | ||||||
|  | 			panic(fmt.Sprintf("could not generate random bytes for HTTP secret: %v", err)) | ||||||
|  | 		} | ||||||
|  | 		configuration.HTTP.Secret = string(secretBytes[:]) | ||||||
|  | 		ctxu.GetLogger(app).Warn("No HTTP secret provided - generated random secret. This may cause problems with uploads if multiple registries are behind a load-balancer. To provide a shared secret, fill in http.secret in the configuration file or set the REGISTRY_HTTP_SECRET environment variable.") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request) { | func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 	defer r.Body.Close() // ensure that request body is always closed.
 | 	defer r.Body.Close() // ensure that request body is always closed.
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue