Refactor TLS code with a new tlsconfig
package
This patch creates a new `tlsconfig` package to handle creation of secure-enough TLS configurations for clients and servers. The package was created by refactoring TLS code in the client and the daemon. After this patch, it is expected that all code creating TLS configurations use this `tlsconfig` package for greater security, consistency and readability. On the server side, this fixes a bug where --tlsverify was not taken into account. Now, if specified, it will require the client to authenticate. Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
parent
afecf24bf7
commit
6c2626b90e
2 changed files with 111 additions and 53 deletions
|
@ -2,68 +2,19 @@ package sockets
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/pkg/listenbuffer"
|
||||
)
|
||||
|
||||
type TlsConfig struct {
|
||||
CA string
|
||||
Certificate string
|
||||
Key string
|
||||
Verify bool
|
||||
}
|
||||
|
||||
func NewTlsConfig(tlsCert, tlsKey, tlsCA string, verify bool) *TlsConfig {
|
||||
return &TlsConfig{
|
||||
Verify: verify,
|
||||
Certificate: tlsCert,
|
||||
Key: tlsKey,
|
||||
CA: tlsCA,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTcpSocket(addr string, config *TlsConfig, activate <-chan struct{}) (net.Listener, error) {
|
||||
func NewTcpSocket(addr string, tlsConfig *tls.Config, activate <-chan struct{}) (net.Listener, error) {
|
||||
l, err := listenbuffer.NewListenBuffer("tcp", addr, activate)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if config != nil {
|
||||
if l, err = setupTls(l, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tlsConfig != nil {
|
||||
tlsConfig.NextProtos = []string{"http/1.1"}
|
||||
l = tls.NewListener(l, tlsConfig)
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func setupTls(l net.Listener, config *TlsConfig) (net.Listener, error) {
|
||||
tlsCert, err := tls.LoadX509KeyPair(config.Certificate, config.Key)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("Could not load X509 key pair (%s, %s): %v", config.Certificate, config.Key, err)
|
||||
}
|
||||
return nil, fmt.Errorf("Error reading X509 key pair (%s, %s): %q. Make sure the key is encrypted.",
|
||||
config.Certificate, config.Key, err)
|
||||
}
|
||||
tlsConfig := &tls.Config{
|
||||
NextProtos: []string{"http/1.1"},
|
||||
Certificates: []tls.Certificate{tlsCert},
|
||||
// Avoid fallback on insecure SSL protocols
|
||||
MinVersion: tls.VersionTLS10,
|
||||
}
|
||||
if config.CA != "" {
|
||||
certPool := x509.NewCertPool()
|
||||
file, err := ioutil.ReadFile(config.CA)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not read CA certificate: %v", err)
|
||||
}
|
||||
certPool.AppendCertsFromPEM(file)
|
||||
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
tlsConfig.ClientCAs = certPool
|
||||
}
|
||||
return tls.NewListener(l, tlsConfig), nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue