diff --git a/docs/content/observability/access-logs.md b/docs/content/observability/access-logs.md index 829be2a4f..51859c4e1 100644 --- a/docs/content/observability/access-logs.md +++ b/docs/content/observability/access-logs.md @@ -209,7 +209,7 @@ accessLog: | `RequestScheme` | The HTTP scheme requested `http` or `https`. | | `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` | | `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. | - | `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. | + | `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. | | `OriginContentSize` | The content length specified by the origin server, or 0 if unspecified. | | `OriginStatus` | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent. | | `OriginStatusLine` | `OriginStatus` + Status code explanation | @@ -218,8 +218,10 @@ accessLog: | `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. | | `RequestCount` | The number of requests received since the Traefik instance started. | | `GzipRatio` | The response body compression ratio achieved. | - | `Overhead` | The processing time overhead (in nanoseconds) caused by Traefik. | + | `Overhead` | The processing time overhead (in nanoseconds) caused by Traefik. | | `RetryAttempts` | The amount of attempts the request was retried. | + | `TLSVersion` | The TLS version used by the connection (e.g. `1.2`) (if connection is TLS). | + | `TLSCipher` | The TLS cipher used by the connection (e.g. `TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA`) (if connection is TLS) | ## Log Rotation diff --git a/pkg/middlewares/accesslog/logdata.go b/pkg/middlewares/accesslog/logdata.go index 37f415ed5..1db168446 100644 --- a/pkg/middlewares/accesslog/logdata.go +++ b/pkg/middlewares/accesslog/logdata.go @@ -70,6 +70,11 @@ const ( Overhead = "Overhead" // RetryAttempts is the map key used for the amount of attempts the request was retried. RetryAttempts = "RetryAttempts" + + // TLSVersion is the version of TLS used in the request. + TLSVersion = "TLSVersion" + // TLSCipher is the cipher used in the request. + TLSCipher = "TLSCipher" ) // These are written out in the default case when no config is provided to specify keys of interest. @@ -111,6 +116,8 @@ func init() { allCoreKeys[StartLocal] = struct{}{} allCoreKeys[Overhead] = struct{}{} allCoreKeys[RetryAttempts] = struct{}{} + allCoreKeys[TLSVersion] = struct{}{} + allCoreKeys[TLSCipher] = struct{}{} } // CoreLogData holds the fields computed from the request/response. diff --git a/pkg/middlewares/accesslog/logger.go b/pkg/middlewares/accesslog/logger.go index b0e273a1f..8698852dd 100644 --- a/pkg/middlewares/accesslog/logger.go +++ b/pkg/middlewares/accesslog/logger.go @@ -18,6 +18,7 @@ import ( "github.com/sirupsen/logrus" ptypes "github.com/traefik/paerser/types" "github.com/traefik/traefik/v2/pkg/log" + traefiktls "github.com/traefik/traefik/v2/pkg/tls" "github.com/traefik/traefik/v2/pkg/types" ) @@ -209,6 +210,8 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request, next http core[RequestScheme] = "http" if req.TLS != nil { core[RequestScheme] = "https" + core[TLSVersion] = getRequestTLSVersion(req) + core[TLSCipher] = getRequestTLSCipher(req) } core[ClientAddr] = req.RemoteAddr @@ -382,3 +385,19 @@ var requestCounter uint64 // Request ID func nextRequestCount() uint64 { return atomic.AddUint64(&requestCounter, 1) } + +func getRequestTLSVersion(req *http.Request) string { + if version, ok := traefiktls.VersionsReversed[req.TLS.Version]; ok { + return version + } + + return "unknown" +} + +func getRequestTLSCipher(req *http.Request) string { + if cypher, ok := traefiktls.CipherSuitesReversed[req.TLS.CipherSuite]; ok { + return cypher + } + + return "unknown" +} diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index aaa145e5b..d3d680d8f 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -355,9 +355,11 @@ func TestLoggerJSON(t *testing.T) { Duration: assertFloat64NotZero(), Overhead: assertFloat64NotZero(), RetryAttempts: assertFloat64(float64(testRetryAttempts)), + TLSVersion: assertString("1.3"), + TLSCipher: assertString("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), "time": assertNotEmpty(), - "StartLocal": assertNotEmpty(), - "StartUTC": assertNotEmpty(), + StartLocal: assertNotEmpty(), + StartUTC: assertNotEmpty(), }, }, { @@ -772,7 +774,10 @@ func doLoggingTLSOpt(t *testing.T, config *types.AccessLog, enableTLS bool) { }, } if enableTLS { - req.TLS = &tls.ConnectionState{} + req.TLS = &tls.ConnectionState{ + Version: tls.VersionTLS13, + CipherSuite: tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + } } logger.ServeHTTP(httptest.NewRecorder(), req, http.HandlerFunc(logWriterTestHandlerFunc)) diff --git a/pkg/middlewares/metrics/metrics.go b/pkg/middlewares/metrics/metrics.go index c824b5749..6d9bd2966 100644 --- a/pkg/middlewares/metrics/metrics.go +++ b/pkg/middlewares/metrics/metrics.go @@ -2,7 +2,6 @@ package metrics import ( "context" - "crypto/tls" "net/http" "strconv" "strings" @@ -148,18 +147,11 @@ func getMethod(r *http.Request) string { } func getRequestTLSVersion(req *http.Request) string { - switch req.TLS.Version { - case tls.VersionTLS10: - return "1.0" - case tls.VersionTLS11: - return "1.1" - case tls.VersionTLS12: - return "1.2" - case tls.VersionTLS13: - return "1.3" - default: - return "unknown" + if version, ok := traefiktls.VersionsReversed[req.TLS.Version]; ok { + return version } + + return "unknown" } func getRequestTLSCipher(req *http.Request) string { diff --git a/pkg/tls/version.go b/pkg/tls/version.go new file mode 100644 index 000000000..5ff14cff3 --- /dev/null +++ b/pkg/tls/version.go @@ -0,0 +1,12 @@ +package tls + +import "crypto/tls" + +// VersionsReversed Map of TLS versions from crypto/tls +// Available TLS versions defined at https://golang.org/pkg/crypto/tls/#pkg-constants +var VersionsReversed = map[uint16]string{ + tls.VersionTLS10: "1.0", + tls.VersionTLS11: "1.1", + tls.VersionTLS12: "1.2", + tls.VersionTLS13: "1.3", +}