mirror of
https://github.com/caddyserver/caddy.git
synced 2025-06-01 20:54:26 -04:00
caddyhttp: Support TLS key logging for debugging (#4808)
* Add SSL key logging. * Resolve merge conflict with master * Add Caddyfile support; various fixes * Also commit go.mod and go.sum, oops * Appease linter * Minor tweaks * Add doc comment Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
parent
74547f5bed
commit
616418281b
@ -54,7 +54,6 @@ func init() {
|
|||||||
// parseBind parses the bind directive. Syntax:
|
// parseBind parses the bind directive. Syntax:
|
||||||
//
|
//
|
||||||
// bind <addresses...>
|
// bind <addresses...>
|
||||||
//
|
|
||||||
func parseBind(h Helper) ([]ConfigValue, error) {
|
func parseBind(h Helper) ([]ConfigValue, error) {
|
||||||
var lnHosts []string
|
var lnHosts []string
|
||||||
for h.Next() {
|
for h.Next() {
|
||||||
@ -85,8 +84,8 @@ func parseBind(h Helper) ([]ConfigValue, error) {
|
|||||||
// eab <key_id> <mac_key>
|
// eab <key_id> <mac_key>
|
||||||
// issuer <module_name> [...]
|
// issuer <module_name> [...]
|
||||||
// get_certificate <module_name> [...]
|
// get_certificate <module_name> [...]
|
||||||
|
// insecure_secrets_log <log_file>
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
func parseTLS(h Helper) ([]ConfigValue, error) {
|
func parseTLS(h Helper) ([]ConfigValue, error) {
|
||||||
cp := new(caddytls.ConnectionPolicy)
|
cp := new(caddytls.ConnectionPolicy)
|
||||||
var fileLoader caddytls.FileLoader
|
var fileLoader caddytls.FileLoader
|
||||||
@ -396,6 +395,12 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
|
|||||||
}
|
}
|
||||||
onDemand = true
|
onDemand = true
|
||||||
|
|
||||||
|
case "insecure_secrets_log":
|
||||||
|
if !h.NextArg() {
|
||||||
|
return nil, h.ArgErr()
|
||||||
|
}
|
||||||
|
cp.InsecureSecretsLog = h.Val()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, h.Errf("unknown subdirective: %s", h.Val())
|
return nil, h.Errf("unknown subdirective: %s", h.Val())
|
||||||
}
|
}
|
||||||
@ -517,7 +522,6 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
|
|||||||
// parseRoot parses the root directive. Syntax:
|
// parseRoot parses the root directive. Syntax:
|
||||||
//
|
//
|
||||||
// root [<matcher>] <path>
|
// root [<matcher>] <path>
|
||||||
//
|
|
||||||
func parseRoot(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
func parseRoot(h Helper) (caddyhttp.MiddlewareHandler, error) {
|
||||||
var root string
|
var root string
|
||||||
for h.Next() {
|
for h.Next() {
|
||||||
@ -700,7 +704,6 @@ func parseHandleErrors(h Helper) ([]ConfigValue, error) {
|
|||||||
// format <encoder_module> ...
|
// format <encoder_module> ...
|
||||||
// level <level>
|
// level <level>
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
func parseLog(h Helper) ([]ConfigValue, error) {
|
func parseLog(h Helper) ([]ConfigValue, error) {
|
||||||
return parseLogHelper(h, nil)
|
return parseLogHelper(h, nil)
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,14 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
"github.com/mholt/acmez"
|
"github.com/mholt/acmez"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -156,6 +159,16 @@ type ConnectionPolicy struct {
|
|||||||
// is no policy configured for the empty SNI value.
|
// is no policy configured for the empty SNI value.
|
||||||
DefaultSNI string `json:"default_sni,omitempty"`
|
DefaultSNI string `json:"default_sni,omitempty"`
|
||||||
|
|
||||||
|
// Also known as "SSLKEYLOGFILE", TLS secrets will be written to
|
||||||
|
// this file in NSS key log format which can then be parsed by
|
||||||
|
// Wireshark and other tools. This is INSECURE as it allows other
|
||||||
|
// programs or tools to decrypt TLS connections. However, this
|
||||||
|
// capability can be useful for debugging and troubleshooting.
|
||||||
|
// **ENABLING THIS LOG COMPROMISES SECURITY!**
|
||||||
|
//
|
||||||
|
// This feature is EXPERIMENTAL and subject to change or removal.
|
||||||
|
InsecureSecretsLog string `json:"insecure_secrets_log,omitempty"`
|
||||||
|
|
||||||
// TLSConfig is the fully-formed, standard lib TLS config
|
// TLSConfig is the fully-formed, standard lib TLS config
|
||||||
// used to serve TLS connections. Provision all
|
// used to serve TLS connections. Provision all
|
||||||
// ConnectionPolicies to populate this. It is exported only
|
// ConnectionPolicies to populate this. It is exported only
|
||||||
@ -280,6 +293,30 @@ func (p *ConnectionPolicy) buildStandardTLSConfig(ctx caddy.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.InsecureSecretsLog != "" {
|
||||||
|
filename, err := caddy.NewReplacer().ReplaceOrErr(p.InsecureSecretsLog, true, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
filename, err = filepath.Abs(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logFile, _, err := secretsLogPool.LoadOrNew(filename, func() (caddy.Destructor, error) {
|
||||||
|
w, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
|
||||||
|
return destructableWriter{w}, err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ctx.OnCancel(func() { _, _ = secretsLogPool.Delete(filename) })
|
||||||
|
|
||||||
|
cfg.KeyLogWriter = logFile.(io.Writer)
|
||||||
|
|
||||||
|
tlsApp.logger.Warn("TLS SECURITY COMPROMISED: secrets logging is enabled!",
|
||||||
|
zap.String("log_filename", filename))
|
||||||
|
}
|
||||||
|
|
||||||
setDefaultTLSParams(cfg)
|
setDefaultTLSParams(cfg)
|
||||||
|
|
||||||
p.TLSConfig = cfg
|
p.TLSConfig = cfg
|
||||||
@ -297,7 +334,8 @@ func (p ConnectionPolicy) SettingsEmpty() bool {
|
|||||||
p.ProtocolMin == "" &&
|
p.ProtocolMin == "" &&
|
||||||
p.ProtocolMax == "" &&
|
p.ProtocolMax == "" &&
|
||||||
p.ClientAuthentication == nil &&
|
p.ClientAuthentication == nil &&
|
||||||
p.DefaultSNI == ""
|
p.DefaultSNI == "" &&
|
||||||
|
p.InsecureSecretsLog == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientAuthentication configures TLS client auth.
|
// ClientAuthentication configures TLS client auth.
|
||||||
@ -542,3 +580,9 @@ type ClientCertificateVerifier interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var defaultALPN = []string{"h2", "http/1.1"}
|
var defaultALPN = []string{"h2", "http/1.1"}
|
||||||
|
|
||||||
|
type destructableWriter struct{ *os.File }
|
||||||
|
|
||||||
|
func (d destructableWriter) Destruct() error { return d.Close() }
|
||||||
|
|
||||||
|
var secretsLogPool = caddy.NewUsagePool()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user