pomerium/internal/log/access.go
Joe Kralicky 554e77bc7c
envoy: log mtls failures (#5210)
envoy: log mtls failures

This implements limited listener-based access logging for downstream
transport failures, only enabled when downstream_mtls.enforcement is
set to 'reject_connection'. Client certificate details and the error
message will be logged.

Additionally, the new key 'client-certificate' can be set in the
access_log_fields list in the configuration, which will add peer
certificate properties (issuer, subject, SANs) to the existing
per-request http logs.

---------

Co-authored-by: Kenneth Jenkins <51246568+kenjenkins@users.noreply.github.com>
2024-08-09 14:05:10 -04:00

83 lines
2.7 KiB
Go

package log
import (
"errors"
"fmt"
)
// An AccessLogField is a field in the access logs.
type AccessLogField string
// known access log fields
const (
AccessLogFieldAuthority AccessLogField = "authority"
AccessLogFieldDuration AccessLogField = "duration"
AccessLogFieldForwardedFor AccessLogField = "forwarded-for"
AccessLogFieldIP AccessLogField = "ip"
AccessLogFieldMethod AccessLogField = "method"
AccessLogFieldPath AccessLogField = "path"
AccessLogFieldQuery AccessLogField = "query"
AccessLogFieldReferer AccessLogField = "referer"
AccessLogFieldRequestID AccessLogField = "request-id"
AccessLogFieldResponseCode AccessLogField = "response-code"
AccessLogFieldResponseCodeDetails AccessLogField = "response-code-details"
AccessLogFieldSize AccessLogField = "size"
AccessLogFieldUpstreamCluster AccessLogField = "upstream-cluster"
AccessLogFieldUserAgent AccessLogField = "user-agent"
AccessLogFieldClientCertificate AccessLogField = "client-certificate"
)
var defaultAccessLogFields = []AccessLogField{
AccessLogFieldUpstreamCluster,
AccessLogFieldMethod,
AccessLogFieldAuthority,
AccessLogFieldPath,
AccessLogFieldUserAgent,
AccessLogFieldReferer,
AccessLogFieldForwardedFor,
AccessLogFieldRequestID,
AccessLogFieldDuration,
AccessLogFieldSize,
AccessLogFieldResponseCode,
AccessLogFieldResponseCodeDetails,
}
// DefaultAccessLogFields returns the default access log fields.
func DefaultAccessLogFields() []AccessLogField {
return defaultAccessLogFields
}
// ErrUnknownAccessLogField indicates that an access log field is unknown.
var ErrUnknownAccessLogField = errors.New("unknown access log field")
var accessLogFieldLookup = map[AccessLogField]struct{}{
AccessLogFieldAuthority: {},
AccessLogFieldDuration: {},
AccessLogFieldForwardedFor: {},
AccessLogFieldIP: {},
AccessLogFieldMethod: {},
AccessLogFieldPath: {},
AccessLogFieldQuery: {},
AccessLogFieldReferer: {},
AccessLogFieldRequestID: {},
AccessLogFieldResponseCode: {},
AccessLogFieldResponseCodeDetails: {},
AccessLogFieldSize: {},
AccessLogFieldUpstreamCluster: {},
AccessLogFieldUserAgent: {},
AccessLogFieldClientCertificate: {},
}
// Validate returns an error if the access log field is invalid.
func (field AccessLogField) Validate() error {
if _, ok := GetHeaderField(field); ok {
return nil
}
_, ok := accessLogFieldLookup[field]
if !ok {
return fmt.Errorf("%w: %s", ErrUnknownAccessLogField, field)
}
return nil
}