From 4104e1fa76a2530e4f5eaf77e90798de3f5e31d6 Mon Sep 17 00:00:00 2001 From: volodymyr Date: Tue, 3 Jun 2025 14:51:34 +0300 Subject: [PATCH] Use advance TLS conn establishment using host, verify, CheckRedirect & ExclusiveRootPools --- pkg/commands/docker.go | 30 ++++++++++++++++++++++++------ pkg/config/app_config.go | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/pkg/commands/docker.go b/pkg/commands/docker.go index d99143ca..0bb2bb21 100644 --- a/pkg/commands/docker.go +++ b/pkg/commands/docker.go @@ -7,6 +7,7 @@ import ( "fmt" "io" ogLog "log" + "net/http" "os" "os/exec" "strings" @@ -18,6 +19,7 @@ import ( ctxstore "github.com/docker/cli/cli/context/store" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" + "github.com/docker/go-connections/tlsconfig" "github.com/imdario/mergo" "github.com/jesseduffield/lazydocker/pkg/commands/ssh" "github.com/jesseduffield/lazydocker/pkg/config" @@ -104,12 +106,28 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat } if config.UserConfig.TLS.Enable { - tlsOpts := client.WithTLSClientConfig( - config.UserConfig.TLS.CACertPath, - config.UserConfig.TLS.CertPath, - config.UserConfig.TLS.KeyPath, - ) - opts = append(opts, tlsOpts) + tlsConfigOpts := tlsconfig.Options{ + CAFile: config.UserConfig.TLS.CACertPath, + CertFile: config.UserConfig.TLS.CertPath, + KeyFile: config.UserConfig.TLS.KeyPath, + InsecureSkipVerify: config.UserConfig.TLS.InsecureSkipVerify, + ExclusiveRootPools: true, + } + customTLSConfig, err := tlsconfig.Client(tlsConfigOpts) + if err != nil { + ogLog.Fatalf("Failed to create custom TLS config: %v", err) + } + + if config.UserConfig.TLS.Host != "" { + customTLSConfig.ServerName = config.UserConfig.TLS.Host + } + httpClient := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: customTLSConfig, + }, + CheckRedirect: client.CheckRedirect, + } + opts = append(opts, client.WithHTTPClient(httpClient)) } cli, err := client.NewClientWithOpts(opts...) diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index b0754116..79284231 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -351,10 +351,31 @@ type LogsConfig struct { // TLSConfig holds TLS configuration for connecting to Docker daemon type TLSConfig struct { - Enable bool `yaml:"enable,omitempty"` + // Enable TLS connections to Docker daemon + Enable bool `yaml:"enable,omitempty"` + + // CACertPath is the path to the Certificate Authority (CA) certificate file + // used to verify the Docker daemon's server certificate CACertPath string `yaml:"caCertPath,omitempty"` - CertPath string `yaml:"certPath,omitempty"` - KeyPath string `yaml:"keyPath,omitempty"` + + // CertPath is the path to the client certificate file for mutual TLS authentication + CertPath string `yaml:"certPath,omitempty"` + + // KeyPath is the path to the client private key file corresponding to the client certificate + KeyPath string `yaml:"keyPath,omitempty"` + + // InsecureSkipVerify controls whether a client verifies the server's certificate chain + // and host name. If InsecureSkipVerify is true, TLS accepts any certificate presented + // by the server and any host name in that certificate. This should only be used for + // testing purposes as it makes TLS susceptible to man-in-the-middle attacks. + InsecureSkipVerify bool `yaml:"insecureSkipVerify,omitempty"` + + // Host specifies the hostname or IP address expected on the Docker daemon's certificate. + // This value is used for Server Name Indication (SNI) and certificate validation. + // It must match either the Common Name (CN) or one of the Subject Alternative Names (SANs) + // in the server's certificate. Do not include protocol (tcp://) or port - just the hostname/IP. + // Example: "docker.example.com" or "192.168.1.100" + Host string `yaml:"host,omitempty"` } // GetDefaultConfig returns the application default configuration NOTE (to @@ -486,10 +507,12 @@ func GetDefaultConfig() UserConfig { ImageNamePrefixes: map[string]string{}, }, TLS: TLSConfig{ - Enable: false, - CACertPath: "", - CertPath: "", - KeyPath: "", + Enable: false, + CACertPath: "", + CertPath: "", + KeyPath: "", + InsecureSkipVerify: false, + Host: "", }, } }