mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
Merge cb368e758d into f023b42c89
This commit is contained in:
commit
456f4f885f
4 changed files with 235 additions and 1 deletions
73
README.md
73
README.md
|
|
@ -89,6 +89,79 @@ Memorising docker commands is hard. Memorising aliases is slightly less hard. Ke
|
|||
- Docker >= **1.13** (API >= **1.25**)
|
||||
- Docker-Compose >= **1.23.2** (optional)
|
||||
|
||||
## TLS Configuration
|
||||
|
||||
Lazydocker supports secure connections to Docker daemon using TLS. To enable TLS, you can configure it in your config.yml:
|
||||
|
||||
### Basic TLS Configuration
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
enable: true
|
||||
caCertPath: "/path/to/ca.pem"
|
||||
certPath: "/path/to/cert.pem"
|
||||
keyPath: "/path/to/key.pem"
|
||||
```
|
||||
|
||||
### Complete TLS Configuration
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
enable: true # Enable TLS connections to Docker daemon
|
||||
caCertPath: "/path/to/ca.pem" # Path to Certificate Authority (CA) certificate
|
||||
certPath: "/path/to/cert.pem" # Path to client certificate
|
||||
keyPath: "/path/to/key.pem" # Path to client private key
|
||||
host: "docker.example.com" # Hostname or IP for certificate validation (ServerName)
|
||||
insecureSkipVerify: false # Skip TLS certificate verification (NOT recommended for production)
|
||||
```
|
||||
|
||||
### TLS Configuration Options
|
||||
|
||||
- **`enable`**: Set to `true` to enable TLS connections to the Docker daemon
|
||||
- **`caCertPath`**: Path to the Certificate Authority (CA) certificate file used to verify the Docker daemon's certificate
|
||||
- **`certPath`**: Path to the client certificate file for mutual TLS authentication
|
||||
- **`keyPath`**: Path to the client private key file corresponding to the client certificate
|
||||
- **`host`**: The hostname or IP address expected on the Docker daemon's certificate. This must match the Common Name (CN) or a Subject Alternative Name (SAN) in the server's certificate
|
||||
- **`insecureSkipVerify`**: When set to `true`, skips certificate verification (useful for testing, but insecure for production use)
|
||||
|
||||
### Important Notes
|
||||
|
||||
1. **Two Different "Hosts"**: Don't confuse the `tls.host` config field with the `DOCKER_HOST` environment variable:
|
||||
- `DOCKER_HOST` environment variable: Tells Lazydocker **where to connect** (e.g., `tcp://192.168.1.100:2376`)
|
||||
- `tls.host` in config.yml: Tells Lazydocker **what name to expect on the certificate** (e.g., `docker.example.com` or `192.168.1.100`)
|
||||
|
||||
2. **Certificate Validation**: The `host` field must match a name in your Docker daemon's certificate:
|
||||
- Common Name (CN) in the certificate's Subject field
|
||||
- Or one of the Subject Alternative Names (SANs) in the certificate
|
||||
|
||||
3. **Security**: Always use `insecureSkipVerify: false` in production environments. Only set it to `true` for testing purposes.
|
||||
|
||||
### Example for Remote Docker Daemon
|
||||
|
||||
When connecting to a Docker daemon running on a remote machine with TLS:
|
||||
|
||||
1. Set the connection endpoint:
|
||||
```bash
|
||||
export DOCKER_HOST=tcp://docker.example.com:2376
|
||||
```
|
||||
|
||||
2. Configure TLS in `config.yml`:
|
||||
```yaml
|
||||
tls:
|
||||
enable: true
|
||||
caCertPath: "/home/user/.docker/ca.pem"
|
||||
certPath: "/home/user/.docker/cert.pem"
|
||||
keyPath: "/home/user/.docker/key.pem"
|
||||
host: "docker.example.com" # Must match the name on the server's certificate
|
||||
insecureSkipVerify: false
|
||||
```
|
||||
|
||||
### Troubleshooting TLS Issues
|
||||
|
||||
- **"x509: certificate is valid for ..., not ..."**: The `host` field doesn't match any name on the server's certificate. Check your server certificate's CN and SANs.
|
||||
- **"certificate signed by unknown authority"**: The CA certificate path is incorrect or the server's certificate wasn't signed by the specified CA.
|
||||
- **"no such host"**: This is a network connectivity issue with `DOCKER_HOST`, not a TLS configuration problem.
|
||||
|
||||
## Installation
|
||||
|
||||
### Homebrew
|
||||
|
|
|
|||
|
|
@ -64,6 +64,13 @@ logs:
|
|||
timestamps: false
|
||||
since: '60m' # set to '' to show all logs
|
||||
tail: '' # set to 200 to show last 200 lines of logs
|
||||
tls:
|
||||
enable: false # Set to true to enable TLS connections to Docker daemon
|
||||
caCertPath: "" # Path to Certificate Authority (CA) certificate file
|
||||
certPath: "" # Path to client certificate file for mutual TLS authentication
|
||||
keyPath: "" # Path to client private key file
|
||||
host: "" # Hostname or IP for certificate validation (must match server certificate)
|
||||
insecureSkipVerify: false # Skip certificate verification (NOT recommended for production)
|
||||
commandTemplates:
|
||||
dockerCompose: docker compose # Determines the Docker Compose command to run, referred to as .DockerCompose in commandTemplates
|
||||
restartService: '{{ .DockerCompose }} restart {{ .Service.Name }}'
|
||||
|
|
@ -97,6 +104,87 @@ stats:
|
|||
|
||||
## To see what all of the config options mean, and what other options you can set, see [here](https://godoc.org/github.com/jesseduffield/lazydocker/pkg/config)
|
||||
|
||||
## TLS Configuration
|
||||
|
||||
Lazydocker supports secure connections to Docker daemon using TLS (Transport Layer Security). This is essential when connecting to remote Docker daemons or when your Docker daemon requires client certificate authentication.
|
||||
|
||||
### Configuration Options
|
||||
|
||||
The `tls` section in your config supports the following options:
|
||||
|
||||
- **`enable`**: Boolean flag to enable/disable TLS connections
|
||||
- **`caCertPath`**: Path to the Certificate Authority (CA) certificate file used to verify the Docker daemon's certificate
|
||||
- **`certPath`**: Path to the client certificate file for mutual TLS authentication
|
||||
- **`keyPath`**: Path to the client private key file corresponding to the client certificate
|
||||
- **`host`**: The hostname or IP address expected on the Docker daemon's certificate. This must match the Common Name (CN) or a Subject Alternative Name (SAN) in the server's certificate
|
||||
- **`insecureSkipVerify`**: When set to `true`, skips certificate verification. **Only use this for testing - it's insecure for production!**
|
||||
|
||||
### Basic Example
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
enable: true
|
||||
caCertPath: "/home/user/.docker/ca.pem"
|
||||
certPath: "/home/user/.docker/cert.pem"
|
||||
keyPath: "/home/user/.docker/key.pem"
|
||||
host: "docker.example.com"
|
||||
insecureSkipVerify: false
|
||||
```
|
||||
|
||||
### Remote Docker Daemon Setup
|
||||
|
||||
When connecting to a remote Docker daemon with TLS:
|
||||
|
||||
1. **Set the Docker Host**: Use the `DOCKER_HOST` environment variable to specify where to connect:
|
||||
```bash
|
||||
export DOCKER_HOST=tcp://docker.example.com:2376
|
||||
```
|
||||
|
||||
2. **Configure TLS**: Update your `config.yml`:
|
||||
```yaml
|
||||
tls:
|
||||
enable: true
|
||||
caCertPath: "/path/to/ca.pem"
|
||||
certPath: "/path/to/cert.pem"
|
||||
keyPath: "/path/to/key.pem"
|
||||
host: "docker.example.com" # Must match certificate
|
||||
insecureSkipVerify: false
|
||||
```
|
||||
|
||||
### Important Notes
|
||||
|
||||
1. **Don't confuse two different "hosts"**:
|
||||
- `DOCKER_HOST` environment variable: **WHERE** to connect (e.g., `tcp://192.168.1.100:2376`)
|
||||
- `tls.host` config field: **WHAT NAME** to expect on the certificate (e.g., `docker.example.com`)
|
||||
|
||||
2. **Certificate Validation**: The `host` field must match a name in your Docker daemon's certificate. You can check your certificate's valid names with:
|
||||
```bash
|
||||
openssl x509 -in server-cert.pem -noout -text
|
||||
```
|
||||
|
||||
3. **Certificate Paths**: Ensure all certificate files are readable by the user running Lazydocker
|
||||
|
||||
### Testing TLS Configuration
|
||||
|
||||
For testing purposes only, you can skip certificate verification:
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
enable: true
|
||||
caCertPath: "/path/to/ca.pem"
|
||||
certPath: "/path/to/cert.pem"
|
||||
keyPath: "/path/to/key.pem"
|
||||
host: "any-name-here" # Ignored when insecureSkipVerify is true
|
||||
insecureSkipVerify: true # INSECURE - only for testing!
|
||||
```
|
||||
|
||||
### Common TLS Errors
|
||||
|
||||
- **"x509: certificate is valid for X, not Y"**: The `host` field doesn't match any name on the server's certificate
|
||||
- **"certificate signed by unknown authority"**: The `caCertPath` is incorrect or the server's certificate wasn't signed by the specified CA
|
||||
- **"no such host"**: Network connectivity issue with `DOCKER_HOST` (not a TLS config problem)
|
||||
- **"tls: failed to verify certificate"**: General certificate validation failure - check all certificate paths and the `host` field
|
||||
|
||||
## Color Attributes:
|
||||
|
||||
For color attributes you can choose an array of attributes (with max one color attribute)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -97,7 +99,38 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
|
|||
dockerHost = dockerHostFromEnv
|
||||
}
|
||||
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion(APIVersion), client.WithHost(dockerHost))
|
||||
opts := []client.Opt{
|
||||
client.FromEnv,
|
||||
client.WithVersion(APIVersion),
|
||||
client.WithHost(dockerHost),
|
||||
}
|
||||
|
||||
if config.UserConfig.TLS.Enable {
|
||||
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...)
|
||||
if err != nil {
|
||||
ogLog.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ type UserConfig struct {
|
|||
// hit esc or q when no confirmation panels are open
|
||||
ConfirmOnQuit bool `yaml:"confirmOnQuit,omitempty"`
|
||||
|
||||
// TLS configuration for connecting to Docker daemon
|
||||
TLS TLSConfig `yaml:"tls,omitempty"`
|
||||
|
||||
// Logs determines how we render/filter a container's logs
|
||||
Logs LogsConfig `yaml:"logs,omitempty"`
|
||||
|
||||
|
|
@ -346,6 +349,35 @@ type LogsConfig struct {
|
|||
Tail string `yaml:"tail,omitempty"`
|
||||
}
|
||||
|
||||
// TLSConfig holds TLS configuration for connecting to Docker daemon
|
||||
type TLSConfig struct {
|
||||
// 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 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
|
||||
// contributors, not users): do not default a boolean to true, because false is
|
||||
// the boolean zero value and this will be ignored when parsing the user's
|
||||
|
|
@ -474,6 +506,14 @@ func GetDefaultConfig() UserConfig {
|
|||
Replacements: Replacements{
|
||||
ImageNamePrefixes: map[string]string{},
|
||||
},
|
||||
TLS: TLSConfig{
|
||||
Enable: false,
|
||||
CACertPath: "",
|
||||
CertPath: "",
|
||||
KeyPath: "",
|
||||
InsecureSkipVerify: false,
|
||||
Host: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue