mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 13:04:59 +01:00
feat: support setting the path to certs (#4198)
This commit is contained in:
@@ -35,7 +35,6 @@ services:
|
|||||||
> [!NOTE] Docker Socket Proxy users
|
> [!NOTE] Docker Socket Proxy users
|
||||||
> If you are using a remote agent you **CANNOT** add a socket proxy on top of the agent. Dozzle agents **REPLACE** using a proxy, see [Remote Hosts](/guide/remote-hosts.md) for more info and how to use a socket proxy instead of an agent.
|
> If you are using a remote agent you **CANNOT** add a socket proxy on top of the agent. Dozzle agents **REPLACE** using a proxy, see [Remote Hosts](/guide/remote-hosts.md) for more info and how to use a socket proxy instead of an agent.
|
||||||
|
|
||||||
|
|
||||||
The agent will start and listen on port `7007`. You can connect to the agent using the Dozzle UI by providing the agent's IP address and port. The agent will only show the containers that are available on the host where the agent is running.
|
The agent will start and listen on port `7007`. You can connect to the agent using the Dozzle UI by providing the agent's IP address and port. The agent will only show the containers that are available on the host where the agent is running.
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
@@ -153,7 +152,9 @@ This will restrict the agent to displaying only containers with the label `color
|
|||||||
|
|
||||||
By default, Dozzle uses self-signed certificates for communication between agents. This is a private certificate which is only valid to other Dozzle instances. This is secure and recommended for most use cases. However, if Dozzle is exposed externally and an attacker knows exactly which port the agent is running on, then they can set up their own Dozzle instance and connect to the agent. To prevent this, you can provide your own certificates.
|
By default, Dozzle uses self-signed certificates for communication between agents. This is a private certificate which is only valid to other Dozzle instances. This is secure and recommended for most use cases. However, if Dozzle is exposed externally and an attacker knows exactly which port the agent is running on, then they can set up their own Dozzle instance and connect to the agent. To prevent this, you can provide your own certificates.
|
||||||
|
|
||||||
To provide custom certificates, you need to mount or use secrets to provide the certificates. Here is an example:
|
To provide custom certificates, you need to mount or use secrets to provide the certificates. By default, Dozzle looks for certificates at `/dozzle_cert.pem` and `/dozzle_key.pem`, but you can customize these paths using the `--cert` and `--key` flags or the `DOZZLE_CERT` and `DOZZLE_KEY` environment variables.
|
||||||
|
|
||||||
|
Here is an example using the default paths:
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
services:
|
services:
|
||||||
@@ -176,10 +177,49 @@ secrets:
|
|||||||
file: ./key.pem
|
file: ./key.pem
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or using custom paths with environment variables:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
agent:
|
||||||
|
image: amir20/dozzle:latest
|
||||||
|
command: agent
|
||||||
|
environment:
|
||||||
|
- DOZZLE_CERT=/certs/my-cert.pem
|
||||||
|
- DOZZLE_KEY=/certs/my-key.pem
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./certs:/certs
|
||||||
|
ports:
|
||||||
|
- 7007:7007
|
||||||
|
```
|
||||||
|
|
||||||
|
Or using command-line flags:
|
||||||
|
|
||||||
|
::: code-group
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run -v /var/run/docker.sock:/var/run/docker.sock -v ./certs:/certs -p 7007:7007 amir20/dozzle:latest agent --cert /certs/my-cert.pem --key /certs/my-key.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml [docker-compose.yml]
|
||||||
|
services:
|
||||||
|
agent:
|
||||||
|
image: amir20/dozzle:latest
|
||||||
|
command: agent --cert /certs/my-cert.pem --key /certs/my-key.pem
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./certs:/certs
|
||||||
|
ports:
|
||||||
|
- 7007:7007
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Docker secrets are preferred for providing certificates. They can be created using `docker secret create` command or as the example above using `docker-compose.yml`. The same certificates should be provided to the Dozzle instance connecting to the agent.
|
> Docker secrets are preferred for providing certificates. They can be created using `docker secret create` command or as the example above using `docker-compose.yml`. The same certificates should be provided to the Dozzle instance connecting to the agent.
|
||||||
|
|
||||||
This will mount the `cert.pem` and `key.pem` files to the agent. The agent will use these certificates for communication. The same certificates should be provided to the Dozzle instance connecting to the agent.
|
This will mount the certificate and key files to the agent. The agent will use these certificates for communication. The same certificates should be provided to the Dozzle instance connecting to the agent.
|
||||||
|
|
||||||
To generate certificates, you can use the following command:
|
To generate certificates, you can use the following command:
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func (a *AgentCmd) Run(args Args, embeddedCerts embed.FS) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create docker client: %w", err)
|
return fmt.Errorf("failed to create docker client: %w", err)
|
||||||
}
|
}
|
||||||
certs, err := ReadCertificates(embeddedCerts)
|
certs, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read certificates: %w", err)
|
return fmt.Errorf("failed to read certificates: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type AgentTestCmd struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (at *AgentTestCmd) Run(args Args, embeddedCerts embed.FS) error {
|
func (at *AgentTestCmd) Run(args Args, embeddedCerts embed.FS) error {
|
||||||
certs, err := ReadCertificates(embeddedCerts)
|
certs, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error reading certificates: %w", err)
|
return fmt.Errorf("error reading certificates: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ type Args struct {
|
|||||||
TimeoutString string `arg:"--timeout,env:DOZZLE_TIMEOUT" default:"10s" help:"sets the timeout for docker client"`
|
TimeoutString string `arg:"--timeout,env:DOZZLE_TIMEOUT" default:"10s" help:"sets the timeout for docker client"`
|
||||||
Timeout time.Duration `arg:"-"`
|
Timeout time.Duration `arg:"-"`
|
||||||
Namespace []string `arg:"env:DOZZLE_NAMESPACE" help:"sets the namespace to use in k8s"`
|
Namespace []string `arg:"env:DOZZLE_NAMESPACE" help:"sets the namespace to use in k8s"`
|
||||||
|
CertPath string `arg:"--cert,env:DOZZLE_CERT" default:"dozzle_cert.pem" help:"path to custom TLS certificate"`
|
||||||
|
KeyPath string `arg:"--key,env:DOZZLE_KEY" default:"dozzle_key.pem" help:"path to custom TLS key"`
|
||||||
Healthcheck *HealthcheckCmd `arg:"subcommand:healthcheck" help:"checks if the server is running"`
|
Healthcheck *HealthcheckCmd `arg:"subcommand:healthcheck" help:"checks if the server is running"`
|
||||||
Generate *GenerateCmd `arg:"subcommand:generate" help:"generates a configuration file for simple auth"`
|
Generate *GenerateCmd `arg:"subcommand:generate" help:"generates a configuration file for simple auth"`
|
||||||
Agent *AgentCmd `arg:"subcommand:agent" help:"starts the agent"`
|
Agent *AgentCmd `arg:"subcommand:agent" help:"starts the agent"`
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ReadCertificates(certs embed.FS) (tls.Certificate, error) {
|
func ReadCertificates(certs embed.FS, certPath, keyPath string) (tls.Certificate, error) {
|
||||||
if pair, err := tls.LoadX509KeyPair("dozzle_cert.pem", "dozzle_key.pem"); err == nil {
|
if pair, err := tls.LoadX509KeyPair(certPath, keyPath); err == nil {
|
||||||
log.Info().Msg("Loaded custom dozzle certificate and key")
|
log.Info().Str("cert", certPath).Str("key", keyPath).Msg("Loaded custom dozzle certificate and key")
|
||||||
return pair, nil
|
return pair, nil
|
||||||
} else {
|
} else {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
log.Fatal().Err(err).Msg("Failed to load custom dozzle certificate and key. Stopping...")
|
log.Fatal().Err(err).Str("cert", certPath).Str("key", keyPath).Msg("Failed to load custom dozzle certificate and key. Stopping...")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func CreateMultiHostService(embeddedCerts embed.FS, args Args) *docker_support.M
|
|||||||
go StartEvent(args, "server", localClient, "")
|
go StartEvent(args, "server", localClient, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
certs, err := ReadCertificates(embeddedCerts)
|
certs, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("Could not read certificates")
|
log.Fatal().Err(err).Msg("Could not read certificates")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func (h *HealthcheckCmd) Run(args Args, embeddedCerts embed.FS) error {
|
|||||||
return fmt.Errorf("failed to read file: %w", err)
|
return fmt.Errorf("failed to read file: %w", err)
|
||||||
}
|
}
|
||||||
agentAddress := string(data)
|
agentAddress := string(data)
|
||||||
certs, err := ReadCertificates(embeddedCerts)
|
certs, err := ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read certificates: %w", err)
|
return fmt.Errorf("failed to read certificates: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -68,7 +68,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("Could not create docker client")
|
log.Fatal().Err(err).Msg("Could not create docker client")
|
||||||
}
|
}
|
||||||
certs, err := cli.ReadCertificates(certs)
|
certs, err := cli.ReadCertificates(certs, args.CertPath, args.KeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msg("Could not read certificates")
|
log.Fatal().Err(err).Msg("Could not read certificates")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user