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 >= **1.13** (API >= **1.25**)
|
||||||
- Docker-Compose >= **1.23.2** (optional)
|
- 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
|
## Installation
|
||||||
|
|
||||||
### Homebrew
|
### Homebrew
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,13 @@ logs:
|
||||||
timestamps: false
|
timestamps: false
|
||||||
since: '60m' # set to '' to show all logs
|
since: '60m' # set to '' to show all logs
|
||||||
tail: '' # set to 200 to show last 200 lines of 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:
|
commandTemplates:
|
||||||
dockerCompose: docker compose # Determines the Docker Compose command to run, referred to as .DockerCompose in commandTemplates
|
dockerCompose: docker compose # Determines the Docker Compose command to run, referred to as .DockerCompose in commandTemplates
|
||||||
restartService: '{{ .DockerCompose }} restart {{ .Service.Name }}'
|
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)
|
## 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:
|
## Color Attributes:
|
||||||
|
|
||||||
For color attributes you can choose an array of attributes (with max one color attribute)
|
For color attributes you can choose an array of attributes (with max one color attribute)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
ogLog "log"
|
ogLog "log"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -18,6 +19,7 @@ import (
|
||||||
ctxstore "github.com/docker/cli/cli/context/store"
|
ctxstore "github.com/docker/cli/cli/context/store"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/docker/go-connections/tlsconfig"
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/commands/ssh"
|
"github.com/jesseduffield/lazydocker/pkg/commands/ssh"
|
||||||
"github.com/jesseduffield/lazydocker/pkg/config"
|
"github.com/jesseduffield/lazydocker/pkg/config"
|
||||||
|
|
@ -97,7 +99,38 @@ func NewDockerCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
|
||||||
dockerHost = dockerHostFromEnv
|
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 {
|
if err != nil {
|
||||||
ogLog.Fatal(err)
|
ogLog.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ type UserConfig struct {
|
||||||
// hit esc or q when no confirmation panels are open
|
// hit esc or q when no confirmation panels are open
|
||||||
ConfirmOnQuit bool `yaml:"confirmOnQuit,omitempty"`
|
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 determines how we render/filter a container's logs
|
||||||
Logs LogsConfig `yaml:"logs,omitempty"`
|
Logs LogsConfig `yaml:"logs,omitempty"`
|
||||||
|
|
||||||
|
|
@ -346,6 +349,35 @@ type LogsConfig struct {
|
||||||
Tail string `yaml:"tail,omitempty"`
|
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
|
// GetDefaultConfig returns the application default configuration NOTE (to
|
||||||
// contributors, not users): do not default a boolean to true, because false is
|
// 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
|
// the boolean zero value and this will be ignored when parsing the user's
|
||||||
|
|
@ -474,6 +506,14 @@ func GetDefaultConfig() UserConfig {
|
||||||
Replacements: Replacements{
|
Replacements: Replacements{
|
||||||
ImageNamePrefixes: map[string]string{},
|
ImageNamePrefixes: map[string]string{},
|
||||||
},
|
},
|
||||||
|
TLS: TLSConfig{
|
||||||
|
Enable: false,
|
||||||
|
CACertPath: "",
|
||||||
|
CertPath: "",
|
||||||
|
KeyPath: "",
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
Host: "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue