mirror of https://github.com/docker/docs.git
only create ca and client cert once; create server keys each time; add serverAuth to ext usage
Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
parent
97e164e7a2
commit
74f9bcebc7
10
commands.go
10
commands.go
|
@ -27,6 +27,7 @@ import (
|
|||
_ "github.com/docker/machine/drivers/vmwarevcloudair"
|
||||
_ "github.com/docker/machine/drivers/vmwarevsphere"
|
||||
"github.com/docker/machine/state"
|
||||
"github.com/docker/machine/utils"
|
||||
)
|
||||
|
||||
type hostListItem struct {
|
||||
|
@ -156,7 +157,7 @@ var Commands = []cli.Command{
|
|||
|
||||
func cmdActive(c *cli.Context) {
|
||||
name := c.Args().First()
|
||||
store := NewStore(c.GlobalString("storage-path"), c.GlobalString("auth-ca"), c.GlobalString("auth-key"))
|
||||
store := NewStore(c.GlobalString("storage-path"), c.GlobalString("tls-ca-cert"), c.GlobalString("tls-ca-key"))
|
||||
|
||||
if name == "" {
|
||||
host, err := store.GetActive()
|
||||
|
@ -221,10 +222,9 @@ func cmdConfig(c *cli.Context) {
|
|||
log.Fatalf("Error loading machine config: %s", err)
|
||||
}
|
||||
|
||||
storeDir := store.Path
|
||||
caCert := filepath.Join(storeDir, name, "ca.pem")
|
||||
clientCert := filepath.Join(storeDir, name, "cert.pem")
|
||||
clientKey := filepath.Join(storeDir, name, "key.pem")
|
||||
caCert := filepath.Join(utils.GetMachineDir(), "ca.pem")
|
||||
clientCert := filepath.Join(utils.GetMachineDir(), "client.pem")
|
||||
clientKey := filepath.Join(utils.GetMachineDir(), "client-key.pem")
|
||||
machineUrl, err := host.GetURL()
|
||||
if err != nil {
|
||||
log.Fatalf("Error getting machine url: %s", err)
|
||||
|
|
|
@ -4,22 +4,12 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/docker/machine/utils"
|
||||
)
|
||||
|
||||
func GetHomeDir() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return os.Getenv("USERPROFILE")
|
||||
}
|
||||
return os.Getenv("HOME")
|
||||
}
|
||||
|
||||
func GetDockerDir() string {
|
||||
return fmt.Sprintf(filepath.Join(GetHomeDir(), ".docker"))
|
||||
}
|
||||
|
||||
func PublicKeyPath() string {
|
||||
return filepath.Join(GetHomeDir(), ".docker", "public-key.json")
|
||||
return filepath.Join(utils.GetHomeDir(), ".docker", "public-key.json")
|
||||
}
|
||||
|
||||
func AddPublicKeyToAuthorizedHosts(d Driver, authorizedKeysPath string) error {
|
||||
|
|
|
@ -143,7 +143,7 @@ func (d *Driver) Create() error {
|
|||
}
|
||||
|
||||
// todo: use real constant for .docker
|
||||
rootPath := filepath.Join(drivers.GetHomeDir(), ".docker")
|
||||
rootPath := filepath.Join(utils.GetHomeDir(), ".docker")
|
||||
imgPath := filepath.Join(rootPath, "images")
|
||||
commonIsoPath := filepath.Join(imgPath, "boot2docker.iso")
|
||||
if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) {
|
||||
|
|
|
@ -151,7 +151,7 @@ func (d *Driver) Create() error {
|
|||
}
|
||||
|
||||
// todo: use real constant for .docker
|
||||
rootPath := filepath.Join(drivers.GetHomeDir(), ".docker")
|
||||
rootPath := filepath.Join(utils.GetHomeDir(), ".docker")
|
||||
imgPath := filepath.Join(rootPath, "images")
|
||||
commonIsoPath := filepath.Join(imgPath, "boot2docker.iso")
|
||||
if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) {
|
||||
|
|
|
@ -244,8 +244,7 @@ func (d *Driver) Create() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// todo: use real constant for .docker
|
||||
rootPath := filepath.Join(drivers.GetHomeDir(), ".docker")
|
||||
rootPath := utils.GetDockerDir()
|
||||
imgPath := filepath.Join(rootPath, "images")
|
||||
commonIsoPath := filepath.Join(imgPath, "boot2docker.iso")
|
||||
if _, err := os.Stat(commonIsoPath); os.IsNotExist(err) {
|
||||
|
|
76
host.go
76
host.go
|
@ -6,6 +6,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"time"
|
||||
|
@ -83,59 +84,15 @@ func ValidateHostName(name string) (string, error) {
|
|||
return name, nil
|
||||
}
|
||||
|
||||
func (h *Host) GenerateCertificates() error {
|
||||
func GenerateClientCertificate(caCertPath, privateKeyPath string) error {
|
||||
var (
|
||||
caPathExists bool
|
||||
privateKeyExists bool
|
||||
org = "docker-machine"
|
||||
bits = 2048
|
||||
org = "docker-machine"
|
||||
bits = 2048
|
||||
)
|
||||
|
||||
ip, err := h.Driver.GetIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientCertPath := filepath.Join(utils.GetMachineDir(), "cert.pem")
|
||||
clientKeyPath := filepath.Join(utils.GetMachineDir(), "key.pem")
|
||||
|
||||
caCertPath := filepath.Join(h.storePath, "ca.pem")
|
||||
privateKeyPath := filepath.Join(h.storePath, "private.pem")
|
||||
|
||||
if _, err := os.Stat(h.CaCertPath); os.IsNotExist(err) {
|
||||
caPathExists = false
|
||||
} else {
|
||||
caPathExists = true
|
||||
}
|
||||
|
||||
if _, err := os.Stat(h.PrivateKeyPath); os.IsNotExist(err) {
|
||||
privateKeyExists = false
|
||||
} else {
|
||||
privateKeyExists = true
|
||||
}
|
||||
|
||||
if !caPathExists && !privateKeyExists {
|
||||
log.Debugf("generating self-signed CA cert: %s", caCertPath)
|
||||
if err := utils.GenerateCACert(caCertPath, privateKeyPath, org, bits); err != nil {
|
||||
return fmt.Errorf("error generating self-signed CA cert: %s", err)
|
||||
}
|
||||
} else {
|
||||
if err := utils.CopyFile(h.CaCertPath, caCertPath); err != nil {
|
||||
return fmt.Errorf("unable to copy CA cert: %s", err)
|
||||
}
|
||||
if err := utils.CopyFile(h.PrivateKeyPath, privateKeyPath); err != nil {
|
||||
return fmt.Errorf("unable to copy private key: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
serverCertPath := filepath.Join(h.storePath, "server.pem")
|
||||
serverKeyPath := filepath.Join(h.storePath, "server-key.pem")
|
||||
|
||||
log.Debugf("generating server cert: %s", serverCertPath)
|
||||
|
||||
if err := utils.GenerateCert([]string{ip}, serverCertPath, serverKeyPath, caCertPath, privateKeyPath, org, bits); err != nil {
|
||||
return fmt.Errorf("error generating server cert: %s", err)
|
||||
}
|
||||
|
||||
clientCertPath := filepath.Join(h.storePath, "cert.pem")
|
||||
clientKeyPath := filepath.Join(h.storePath, "key.pem")
|
||||
log.Debugf("generating client cert: %s", clientCertPath)
|
||||
if err := utils.GenerateCert([]string{""}, clientCertPath, clientKeyPath, caCertPath, privateKeyPath, org, bits); err != nil {
|
||||
return fmt.Errorf("error generating client cert: %s", err)
|
||||
|
@ -151,14 +108,23 @@ func (h *Host) ConfigureAuth() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("generating certificates for %s", h.Name)
|
||||
if err := h.GenerateCertificates(); err != nil {
|
||||
ip, err := h.Driver.GetIP()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
caCertPath := filepath.Join(utils.GetMachineDir(), "ca.pem")
|
||||
caKeyPath := filepath.Join(utils.GetMachineDir(), "key.pem")
|
||||
serverCertPath := filepath.Join(h.storePath, "server.pem")
|
||||
caCertPath := filepath.Join(h.storePath, "ca.pem")
|
||||
serverKeyPath := filepath.Join(h.storePath, "server-key.pem")
|
||||
org := "docker"
|
||||
bits := 2048
|
||||
|
||||
log.Debugf("generating server cert: %s", serverCertPath)
|
||||
|
||||
if err := utils.GenerateCert([]string{ip}, serverCertPath, serverKeyPath, caCertPath, caKeyPath, org, bits); err != nil {
|
||||
return fmt.Errorf("error generating server cert: %s", err)
|
||||
}
|
||||
|
||||
if err := d.StopDocker(); err != nil {
|
||||
return err
|
||||
|
@ -180,19 +146,19 @@ func (h *Host) ConfigureAuth() error {
|
|||
|
||||
// due to windows clients, we cannot use filepath.Join as the paths
|
||||
// will be mucked on the linux hosts
|
||||
machineCaCertPath := fmt.Sprintf("%s/ca.pem", d.GetDockerConfigDir())
|
||||
machineCaCertPath := path.Join(d.GetDockerConfigDir(), "ca.pem")
|
||||
|
||||
serverCert, err := ioutil.ReadFile(serverCertPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
machineServerCertPath := fmt.Sprintf("%s/server.pem", d.GetDockerConfigDir())
|
||||
machineServerCertPath := path.Join(d.GetDockerConfigDir(), "server.pem")
|
||||
|
||||
serverKey, err := ioutil.ReadFile(serverKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
machineServerKeyPath := fmt.Sprintf("%s/server-key.pem", d.GetDockerConfigDir())
|
||||
machineServerKeyPath := path.Join(d.GetDockerConfigDir(), "server-key.pem")
|
||||
|
||||
cmd, err = d.GetSSHCommand(fmt.Sprintf("echo \"%s\" | sudo tee -a %s", string(caCert), machineCaCertPath))
|
||||
if err != nil {
|
||||
|
|
63
main.go
63
main.go
|
@ -3,11 +3,51 @@ package main
|
|||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/docker/machine/utils"
|
||||
)
|
||||
|
||||
func before(c *cli.Context) error {
|
||||
|
||||
caCertPath := c.GlobalString("tls-ca-cert")
|
||||
caKeyPath := c.GlobalString("tls-ca-key")
|
||||
clientCertPath := c.GlobalString("tls-client-cert")
|
||||
clientKeyPath := c.GlobalString("tls-client-key")
|
||||
org := "docker"
|
||||
bits := 2048
|
||||
|
||||
if _, err := os.Stat(caCertPath); os.IsNotExist(err) {
|
||||
log.Debugf("Creating CA: %s", caCertPath)
|
||||
|
||||
// check if the key path exists; if so, error
|
||||
if _, err := os.Stat(caKeyPath); err == nil {
|
||||
log.Fatalf("The CA key already exists. Please remove it or specify a different key/cert.")
|
||||
}
|
||||
|
||||
if err := utils.GenerateCACertificate(caCertPath, caKeyPath, org, bits); err != nil {
|
||||
log.Fatalf("Error generating CA certificate: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(clientCertPath); os.IsNotExist(err) {
|
||||
log.Debugf("Creating client certificate: %s", clientCertPath)
|
||||
|
||||
// check if the key path exists; if so, error
|
||||
if _, err := os.Stat(clientKeyPath); err == nil {
|
||||
log.Fatalf("The client key already exists. Please remove it or specify a different key/cert.")
|
||||
}
|
||||
|
||||
if err := utils.GenerateCert([]string{""}, clientCertPath, clientKeyPath, caCertPath, caKeyPath, org, bits); err != nil {
|
||||
log.Fatalf("Error generating client certificate: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
for _, f := range os.Args {
|
||||
if f == "-D" || f == "--debug" || f == "-debug" {
|
||||
|
@ -21,6 +61,7 @@ func main() {
|
|||
app.Commands = Commands
|
||||
app.CommandNotFound = cmdNotFound
|
||||
app.Usage = "Create and manage machines running Docker."
|
||||
app.Before = before
|
||||
app.Version = VERSION
|
||||
|
||||
app.Flags = []cli.Flag{
|
||||
|
@ -34,14 +75,28 @@ func main() {
|
|||
Usage: "Configures storage path",
|
||||
},
|
||||
cli.StringFlag{
|
||||
EnvVar: "MACHINE_AUTH_CA",
|
||||
Name: "auth-ca",
|
||||
EnvVar: "MACHINE_TLS_CA_CERT",
|
||||
Name: "tls-ca-cert",
|
||||
Usage: "CA to verify remotes against",
|
||||
Value: filepath.Join(utils.GetMachineDir(), "ca.pem"),
|
||||
},
|
||||
cli.StringFlag{
|
||||
EnvVar: "MACHINE_AUTH_PRIVATE_KEY",
|
||||
Name: "auth-key",
|
||||
EnvVar: "MACHINE_TLS_CA_KEY",
|
||||
Name: "tls-ca-key",
|
||||
Usage: "Private key to generate certificates",
|
||||
Value: filepath.Join(utils.GetMachineDir(), "key.pem"),
|
||||
},
|
||||
cli.StringFlag{
|
||||
EnvVar: "MACHINE_TLS_CLIENT_CERT",
|
||||
Name: "tls-client-cert",
|
||||
Usage: "Client cert to use for TLS",
|
||||
Value: filepath.Join(utils.GetMachineDir(), "client.pem"),
|
||||
},
|
||||
cli.StringFlag{
|
||||
EnvVar: "MACHINE_TLS_CLIENT_KEY",
|
||||
Name: "tls-client-key",
|
||||
Usage: "Private key used in client TLS auth",
|
||||
Value: filepath.Join(utils.GetMachineDir(), "client-key.pem"),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
3
store.go
3
store.go
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/machine/drivers"
|
||||
"github.com/docker/machine/utils"
|
||||
)
|
||||
|
||||
// Store persists hosts on the filesystem
|
||||
|
@ -19,7 +20,7 @@ type Store struct {
|
|||
|
||||
func NewStore(rootPath string, caCert string, privateKey string) *Store {
|
||||
if rootPath == "" {
|
||||
rootPath = filepath.Join(drivers.GetHomeDir(), ".docker", "machines")
|
||||
rootPath = utils.GetMachineDir()
|
||||
}
|
||||
|
||||
return &Store{Path: rootPath, CaCertPath: caCert, PrivateKeyPath: privateKey}
|
||||
|
|
|
@ -40,10 +40,10 @@ func newCertificate(org string) (*x509.Certificate, error) {
|
|||
|
||||
}
|
||||
|
||||
// GenerateCACert generates a new certificate authority from the specified org
|
||||
// GenerateCACertificate generates a new certificate authority from the specified org
|
||||
// and bit size and stores the resulting certificate and key file
|
||||
// in the arguments.
|
||||
func GenerateCACert(certFile, keyFile, org string, bits int) error {
|
||||
func GenerateCACertificate(certFile, keyFile, org string, bits int) error {
|
||||
template, err := newCertificate(org)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -1,10 +1,28 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func GetHomeDir() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return os.Getenv("USERPROFILE")
|
||||
}
|
||||
return os.Getenv("HOME")
|
||||
}
|
||||
|
||||
func GetDockerDir() string {
|
||||
return fmt.Sprintf(filepath.Join(GetHomeDir(), ".docker"))
|
||||
}
|
||||
|
||||
func GetMachineDir() string {
|
||||
return fmt.Sprintf(filepath.Join(GetDockerDir(), "machines"))
|
||||
}
|
||||
|
||||
func CopyFile(src, dst string) error {
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue