Automatically generate a HTTP secret if none is provided
Log a warning if the registry generates its own secret. Update configuration doc, and remove the default secret from the development config file. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
01e6dde2fd
commit
70d9a9d543
3 changed files with 25 additions and 2 deletions
|
@ -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 a new issue