Expose trust key path in config
| ... | ... |
@@ -13,8 +13,6 @@ import ( |
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 | 15 |
const ( |
| 16 |
- // DefaultTrustKeyFile is the default filename for the trust key |
|
| 17 |
- DefaultTrustKeyFile = "key.json" |
|
| 18 | 16 |
// DefaultCaFile is the default filename for the CA pem file |
| 19 | 17 |
DefaultCaFile = "ca.pem" |
| 20 | 18 |
// DefaultKeyFile is the default filename for the key pem file |
| ... | ... |
@@ -38,7 +36,6 @@ type CommonOptions struct {
|
| 38 | 38 |
TLS bool |
| 39 | 39 |
TLSVerify bool |
| 40 | 40 |
TLSOptions *tlsconfig.Options |
| 41 |
- TrustKey string |
|
| 42 | 41 |
} |
| 43 | 42 |
|
| 44 | 43 |
// NewCommonOptions returns a new CommonOptions |
| ... | ... |
@@ -9,6 +9,8 @@ import ( |
| 9 | 9 |
const ( |
| 10 | 10 |
// defaultShutdownTimeout is the default shutdown timeout for the daemon |
| 11 | 11 |
defaultShutdownTimeout = 15 |
| 12 |
+ // defaultTrustKeyFile is the default filename for the trust key |
|
| 13 |
+ defaultTrustKeyFile = "key.json" |
|
| 12 | 14 |
) |
| 13 | 15 |
|
| 14 | 16 |
// installCommonConfigFlags adds flags to the pflag.FlagSet to configure the daemon |
| ... | ... |
@@ -53,6 +55,13 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) {
|
| 53 | 53 |
|
| 54 | 54 |
flags.StringVar(&conf.MetricsAddress, "metrics-addr", "", "Set default address and port to serve the metrics api on") |
| 55 | 55 |
|
| 56 |
+ // "--deprecated-key-path" is to allow configuration of the key used |
|
| 57 |
+ // for the daemon ID and the deprecated image signing. It was never |
|
| 58 |
+ // exposed as a command line option but is added here to allow |
|
| 59 |
+ // overriding the default path in configuration. |
|
| 60 |
+ flags.Var(opts.NewQuotedString(&conf.TrustKeyPath), "deprecated-key-path", "Path to key file for ID and image signing") |
|
| 61 |
+ flags.MarkHidden("deprecated-key-path")
|
|
| 62 |
+ |
|
| 56 | 63 |
conf.MaxConcurrentDownloads = &maxConcurrentDownloads |
| 57 | 64 |
conf.MaxConcurrentUploads = &maxConcurrentUploads |
| 58 | 65 |
} |
| ... | ... |
@@ -3,10 +3,8 @@ package main |
| 3 | 3 |
import ( |
| 4 | 4 |
"crypto/tls" |
| 5 | 5 |
"fmt" |
| 6 |
- "io" |
|
| 7 | 6 |
"os" |
| 8 | 7 |
"path/filepath" |
| 9 |
- "runtime" |
|
| 10 | 8 |
"strings" |
| 11 | 9 |
"time" |
| 12 | 10 |
|
| ... | ... |
@@ -27,7 +25,6 @@ import ( |
| 27 | 27 |
swarmrouter "github.com/docker/docker/api/server/router/swarm" |
| 28 | 28 |
systemrouter "github.com/docker/docker/api/server/router/system" |
| 29 | 29 |
"github.com/docker/docker/api/server/router/volume" |
| 30 |
- "github.com/docker/docker/cli" |
|
| 31 | 30 |
"github.com/docker/docker/cli/debug" |
| 32 | 31 |
cliflags "github.com/docker/docker/cli/flags" |
| 33 | 32 |
"github.com/docker/docker/daemon" |
| ... | ... |
@@ -43,7 +40,6 @@ import ( |
| 43 | 43 |
"github.com/docker/docker/pkg/pidfile" |
| 44 | 44 |
"github.com/docker/docker/pkg/plugingetter" |
| 45 | 45 |
"github.com/docker/docker/pkg/signal" |
| 46 |
- "github.com/docker/docker/pkg/system" |
|
| 47 | 46 |
"github.com/docker/docker/plugin" |
| 48 | 47 |
"github.com/docker/docker/registry" |
| 49 | 48 |
"github.com/docker/docker/runconfig" |
| ... | ... |
@@ -67,52 +63,6 @@ func NewDaemonCli() *DaemonCli {
|
| 67 | 67 |
return &DaemonCli{}
|
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 |
-func migrateKey(config *config.Config) (err error) {
|
|
| 71 |
- // No migration necessary on Windows |
|
| 72 |
- if runtime.GOOS == "windows" {
|
|
| 73 |
- return nil |
|
| 74 |
- } |
|
| 75 |
- |
|
| 76 |
- // Migrate trust key if exists at ~/.docker/key.json and owned by current user |
|
| 77 |
- oldPath := filepath.Join(cli.ConfigurationDir(), cliflags.DefaultTrustKeyFile) |
|
| 78 |
- newPath := filepath.Join(getDaemonConfDir(config.Root), cliflags.DefaultTrustKeyFile) |
|
| 79 |
- if _, statErr := os.Stat(newPath); os.IsNotExist(statErr) && currentUserIsOwner(oldPath) {
|
|
| 80 |
- defer func() {
|
|
| 81 |
- // Ensure old path is removed if no error occurred |
|
| 82 |
- if err == nil {
|
|
| 83 |
- err = os.Remove(oldPath) |
|
| 84 |
- } else {
|
|
| 85 |
- logrus.Warnf("Key migration failed, key file not removed at %s", oldPath)
|
|
| 86 |
- os.Remove(newPath) |
|
| 87 |
- } |
|
| 88 |
- }() |
|
| 89 |
- |
|
| 90 |
- if err := system.MkdirAll(getDaemonConfDir(config.Root), os.FileMode(0644)); err != nil {
|
|
| 91 |
- return fmt.Errorf("Unable to create daemon configuration directory: %s", err)
|
|
| 92 |
- } |
|
| 93 |
- |
|
| 94 |
- newFile, err := os.OpenFile(newPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) |
|
| 95 |
- if err != nil {
|
|
| 96 |
- return fmt.Errorf("error creating key file %q: %s", newPath, err)
|
|
| 97 |
- } |
|
| 98 |
- defer newFile.Close() |
|
| 99 |
- |
|
| 100 |
- oldFile, err := os.Open(oldPath) |
|
| 101 |
- if err != nil {
|
|
| 102 |
- return fmt.Errorf("error opening key file %q: %s", oldPath, err)
|
|
| 103 |
- } |
|
| 104 |
- defer oldFile.Close() |
|
| 105 |
- |
|
| 106 |
- if _, err := io.Copy(newFile, oldFile); err != nil {
|
|
| 107 |
- return fmt.Errorf("error copying key: %s", err)
|
|
| 108 |
- } |
|
| 109 |
- |
|
| 110 |
- logrus.Infof("Migrated key from %s to %s", oldPath, newPath)
|
|
| 111 |
- } |
|
| 112 |
- |
|
| 113 |
- return nil |
|
| 114 |
-} |
|
| 115 |
- |
|
| 116 | 70 |
func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
| 117 | 71 |
stopc := make(chan bool) |
| 118 | 72 |
defer close(stopc) |
| ... | ... |
@@ -128,12 +78,6 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
| 128 | 128 |
cli.configFile = &opts.configFile |
| 129 | 129 |
cli.flags = opts.flags |
| 130 | 130 |
|
| 131 |
- if opts.common.TrustKey == "" {
|
|
| 132 |
- opts.common.TrustKey = filepath.Join( |
|
| 133 |
- getDaemonConfDir(cli.Config.Root), |
|
| 134 |
- cliflags.DefaultTrustKeyFile) |
|
| 135 |
- } |
|
| 136 |
- |
|
| 137 | 131 |
if cli.Config.Debug {
|
| 138 | 132 |
debug.Enable() |
| 139 | 133 |
} |
| ... | ... |
@@ -242,13 +186,6 @@ func (cli *DaemonCli) start(opts daemonOptions) (err error) {
|
| 242 | 242 |
api.Accept(addr, ls...) |
| 243 | 243 |
} |
| 244 | 244 |
|
| 245 |
- if err := migrateKey(cli.Config); err != nil {
|
|
| 246 |
- return err |
|
| 247 |
- } |
|
| 248 |
- |
|
| 249 |
- // FIXME: why is this down here instead of with the other TrustKey logic above? |
|
| 250 |
- cli.TrustKeyPath = opts.common.TrustKey |
|
| 251 |
- |
|
| 252 | 245 |
registryService := registry.NewService(cli.Config.ServiceOptions) |
| 253 | 246 |
containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...) |
| 254 | 247 |
if err != nil {
|
| ... | ... |
@@ -424,6 +361,12 @@ func loadDaemonCliConfig(opts daemonOptions) (*config.Config, error) {
|
| 424 | 424 |
conf.CommonTLSOptions.KeyFile = opts.common.TLSOptions.KeyFile |
| 425 | 425 |
} |
| 426 | 426 |
|
| 427 |
+ if conf.TrustKeyPath == "" {
|
|
| 428 |
+ conf.TrustKeyPath = filepath.Join( |
|
| 429 |
+ getDaemonConfDir(conf.Root), |
|
| 430 |
+ defaultTrustKeyFile) |
|
| 431 |
+ } |
|
| 432 |
+ |
|
| 427 | 433 |
if flags.Changed("graph") && flags.Changed("data-root") {
|
| 428 | 434 |
return nil, fmt.Errorf(`cannot specify both "--graph" and "--data-root" option`) |
| 429 | 435 |
} |
| ... | ... |
@@ -14,23 +14,11 @@ import ( |
| 14 | 14 |
"github.com/docker/docker/cmd/dockerd/hack" |
| 15 | 15 |
"github.com/docker/docker/daemon" |
| 16 | 16 |
"github.com/docker/docker/libcontainerd" |
| 17 |
- "github.com/docker/docker/pkg/system" |
|
| 18 | 17 |
"github.com/docker/libnetwork/portallocator" |
| 19 | 18 |
) |
| 20 | 19 |
|
| 21 | 20 |
const defaultDaemonConfigFile = "/etc/docker/daemon.json" |
| 22 | 21 |
|
| 23 |
-// currentUserIsOwner checks whether the current user is the owner of the given |
|
| 24 |
-// file. |
|
| 25 |
-func currentUserIsOwner(f string) bool {
|
|
| 26 |
- if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil {
|
|
| 27 |
- if int(fileInfo.UID()) == os.Getuid() {
|
|
| 28 |
- return true |
|
| 29 |
- } |
|
| 30 |
- } |
|
| 31 |
- return false |
|
| 32 |
-} |
|
| 33 |
- |
|
| 34 | 22 |
// setDefaultUmask sets the umask to 0022 to avoid problems |
| 35 | 23 |
// caused by custom umask |
| 36 | 24 |
func setDefaultUmask() error {
|
| ... | ... |
@@ -102,10 +102,15 @@ type CommonConfig struct {
|
| 102 | 102 |
RootDeprecated string `json:"graph,omitempty"` |
| 103 | 103 |
Root string `json:"data-root,omitempty"` |
| 104 | 104 |
SocketGroup string `json:"group,omitempty"` |
| 105 |
- TrustKeyPath string `json:"-"` |
|
| 106 | 105 |
CorsHeaders string `json:"api-cors-header,omitempty"` |
| 107 | 106 |
EnableCors bool `json:"api-enable-cors,omitempty"` |
| 108 | 107 |
|
| 108 |
+ // TrustKeyPath is used to generate the daemon ID and for signing schema 1 manifests |
|
| 109 |
+ // when pushing to a registry which does not support schema 2. This field is marked as |
|
| 110 |
+ // deprecated because schema 1 manifests are deprecated in favor of schema 2 and the |
|
| 111 |
+ // daemon ID will use a dedicated identifier not shared with exported signatures. |
|
| 112 |
+ TrustKeyPath string `json:"deprecated-key-path,omitempty"` |
|
| 113 |
+ |
|
| 109 | 114 |
// LiveRestoreEnabled determines whether we should keep containers |
| 110 | 115 |
// alive upon daemon shutdown/start |
| 111 | 116 |
LiveRestoreEnabled bool `json:"live-restore,omitempty"` |
| ... | ... |
@@ -535,32 +535,6 @@ func (s *DockerDaemonSuite) TestDaemonKeyGeneration(c *check.C) {
|
| 535 | 535 |
} |
| 536 | 536 |
} |
| 537 | 537 |
|
| 538 |
-func (s *DockerDaemonSuite) TestDaemonKeyMigration(c *check.C) {
|
|
| 539 |
- // TODO: skip or update for Windows daemon |
|
| 540 |
- os.Remove("/etc/docker/key.json")
|
|
| 541 |
- k1, err := libtrust.GenerateECP256PrivateKey() |
|
| 542 |
- if err != nil {
|
|
| 543 |
- c.Fatalf("Error generating private key: %s", err)
|
|
| 544 |
- } |
|
| 545 |
- if err := os.MkdirAll(filepath.Join(os.Getenv("HOME"), ".docker"), 0755); err != nil {
|
|
| 546 |
- c.Fatalf("Error creating .docker directory: %s", err)
|
|
| 547 |
- } |
|
| 548 |
- if err := libtrust.SaveKey(filepath.Join(os.Getenv("HOME"), ".docker", "key.json"), k1); err != nil {
|
|
| 549 |
- c.Fatalf("Error saving private key: %s", err)
|
|
| 550 |
- } |
|
| 551 |
- |
|
| 552 |
- s.d.Start(c) |
|
| 553 |
- s.d.Stop(c) |
|
| 554 |
- |
|
| 555 |
- k2, err := libtrust.LoadKeyFile("/etc/docker/key.json")
|
|
| 556 |
- if err != nil {
|
|
| 557 |
- c.Fatalf("Error opening key file")
|
|
| 558 |
- } |
|
| 559 |
- if k1.KeyID() != k2.KeyID() {
|
|
| 560 |
- c.Fatalf("Key not migrated")
|
|
| 561 |
- } |
|
| 562 |
-} |
|
| 563 |
- |
|
| 564 | 538 |
// GH#11320 - verify that the daemon exits on failure properly |
| 565 | 539 |
// Note that this explicitly tests the conflict of {-b,--bridge} and {--bip} options as the means
|
| 566 | 540 |
// to get a daemon init failure; no other tests for -b/--bip conflict are therefore required |