tcp_socket.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package server
  2. import (
  3. "crypto/tls"
  4. "crypto/x509"
  5. "fmt"
  6. "io/ioutil"
  7. "net"
  8. "os"
  9. "github.com/docker/docker/pkg/listenbuffer"
  10. )
  11. type tlsConfig struct {
  12. CA string
  13. Certificate string
  14. Key string
  15. Verify bool
  16. }
  17. func tlsConfigFromServerConfig(conf *ServerConfig) *tlsConfig {
  18. verify := conf.TlsVerify
  19. if !conf.Tls && !conf.TlsVerify {
  20. return nil
  21. }
  22. return &tlsConfig{
  23. Verify: verify,
  24. Certificate: conf.TlsCert,
  25. Key: conf.TlsKey,
  26. CA: conf.TlsCa,
  27. }
  28. }
  29. func NewTcpSocket(addr string, config *tlsConfig, activate <-chan struct{}) (net.Listener, error) {
  30. l, err := listenbuffer.NewListenBuffer("tcp", addr, activate)
  31. if err != nil {
  32. return nil, err
  33. }
  34. if config != nil {
  35. if l, err = setupTls(l, config); err != nil {
  36. return nil, err
  37. }
  38. }
  39. return l, nil
  40. }
  41. func setupTls(l net.Listener, config *tlsConfig) (net.Listener, error) {
  42. tlsCert, err := tls.LoadX509KeyPair(config.Certificate, config.Key)
  43. if err != nil {
  44. if os.IsNotExist(err) {
  45. return nil, fmt.Errorf("Could not load X509 key pair (%s, %s): %v", config.Certificate, config.Key, err)
  46. }
  47. return nil, fmt.Errorf("Error reading X509 key pair (%s, %s): %q. Make sure the key is encrypted.",
  48. config.Certificate, config.Key, err)
  49. }
  50. tlsConfig := &tls.Config{
  51. NextProtos: []string{"http/1.1"},
  52. Certificates: []tls.Certificate{tlsCert},
  53. // Avoid fallback on insecure SSL protocols
  54. MinVersion: tls.VersionTLS10,
  55. }
  56. if config.CA != "" {
  57. certPool := x509.NewCertPool()
  58. file, err := ioutil.ReadFile(config.CA)
  59. if err != nil {
  60. return nil, fmt.Errorf("Could not read CA certificate: %v", err)
  61. }
  62. certPool.AppendCertsFromPEM(file)
  63. tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
  64. tlsConfig.ClientCAs = certPool
  65. }
  66. return tls.NewListener(l, tlsConfig), nil
  67. }