mirror of
https://github.com/traefik/traefik.git
synced 2025-05-05 15:33:01 +00:00
Error level log for configuration-related TLS errors with backends
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
This commit is contained in:
parent
b02946147d
commit
8ba99adc50
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@ -91,8 +92,9 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
|
||||
BufferPool: bufferPool,
|
||||
ErrorLog: errorLogger,
|
||||
ErrorHandler: func(w http.ResponseWriter, request *http.Request, err error) {
|
||||
statusCode := http.StatusInternalServerError
|
||||
logger := log.FromContext(request.Context())
|
||||
|
||||
statusCode := http.StatusInternalServerError
|
||||
switch {
|
||||
case errors.Is(err, io.EOF):
|
||||
statusCode = http.StatusBadGateway
|
||||
@ -109,7 +111,13 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("'%d %s' caused by: %v", statusCode, statusText(statusCode), err)
|
||||
// Log the error with error level if it is a TLS error related to configuration.
|
||||
if isTLSConfigError(err) {
|
||||
logger.Errorf("'%d %s' caused by: %v", statusCode, statusText(statusCode), err)
|
||||
} else {
|
||||
logger.Debugf("'%d %s' caused by: %v", statusCode, statusText(statusCode), err)
|
||||
}
|
||||
|
||||
w.WriteHeader(statusCode)
|
||||
_, werr := w.Write([]byte(statusText(statusCode)))
|
||||
if werr != nil {
|
||||
@ -121,6 +129,22 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
|
||||
return proxy, nil
|
||||
}
|
||||
|
||||
// isTLSError returns true if the error is a TLS error which is related to configuration.
|
||||
// We assume that if the error is a tls.RecordHeaderError or a tls.CertificateVerificationError,
|
||||
// it is related to configuration, because the client should not send a TLS request to a non-TLS server,
|
||||
// and the client configuration should allow to verify the server certificate.
|
||||
func isTLSConfigError(err error) bool {
|
||||
// tls.RecordHeaderError is returned when the client sends a TLS request to a non-TLS server.
|
||||
var recordHeaderErr tls.RecordHeaderError
|
||||
if errors.As(err, &recordHeaderErr) {
|
||||
return true
|
||||
}
|
||||
|
||||
// tls.CertificateVerificationError is returned when the server certificate cannot be verified.
|
||||
var certVerificationErr *tls.CertificateVerificationError
|
||||
return errors.As(err, &certVerificationErr)
|
||||
}
|
||||
|
||||
func isWebSocketUpgrade(req *http.Request) bool {
|
||||
if !httpguts.HeaderValuesContainsToken(req.Header["Connection"], "Upgrade") {
|
||||
return false
|
||||
|
@ -1,12 +1,15 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/traefik/traefik/v2/pkg/testhelpers"
|
||||
)
|
||||
|
||||
@ -35,3 +38,46 @@ func BenchmarkProxy(b *testing.B) {
|
||||
handler.ServeHTTP(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsTLSConfigError(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
err error
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
desc: "nil",
|
||||
},
|
||||
{
|
||||
desc: "TLS ECHRejectionError",
|
||||
err: &tls.ECHRejectionError{},
|
||||
},
|
||||
{
|
||||
desc: "TLS AlertError",
|
||||
err: tls.AlertError(0),
|
||||
},
|
||||
{
|
||||
desc: "Random error",
|
||||
err: errors.New("random error"),
|
||||
},
|
||||
{
|
||||
desc: "TLS RecordHeaderError",
|
||||
err: tls.RecordHeaderError{},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
desc: "TLS CertificateVerificationError",
|
||||
err: &tls.CertificateVerificationError{},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
actual := isTLSConfigError(test.err)
|
||||
require.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user