added support for tcp proxyProtocol v1&v2 to backend
This commit is contained in:
parent
520fcf82ae
commit
84b125bdde
28 changed files with 388 additions and 83 deletions
|
@ -11,7 +11,7 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
proxyprotocol "github.com/c0va23/go-proxyprotocol"
|
||||
"github.com/pires/go-proxyproto"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/traefik/traefik/v2/pkg/config/static"
|
||||
"github.com/traefik/traefik/v2/pkg/ip"
|
||||
|
@ -316,10 +316,10 @@ func (c *writeCloserWrapper) CloseWrite() error {
|
|||
// implementation, if any was found within the underlying conn.
|
||||
func writeCloser(conn net.Conn) (tcp.WriteCloser, error) {
|
||||
switch typedConn := conn.(type) {
|
||||
case *proxyprotocol.Conn:
|
||||
underlying, err := writeCloser(typedConn.Conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
case *proxyproto.Conn:
|
||||
underlying, ok := typedConn.TCPConn()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("underlying connection is not a tcp connection")
|
||||
}
|
||||
return &writeCloserWrapper{writeCloser: underlying, Conn: typedConn}, nil
|
||||
case *net.TCPConn:
|
||||
|
@ -356,42 +356,35 @@ func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
|
|||
return tc, nil
|
||||
}
|
||||
|
||||
type proxyProtocolLogger struct {
|
||||
log.Logger
|
||||
}
|
||||
|
||||
// Printf force log level to debug.
|
||||
func (p proxyProtocolLogger) Printf(format string, v ...interface{}) {
|
||||
p.Debugf(format, v...)
|
||||
}
|
||||
|
||||
func buildProxyProtocolListener(ctx context.Context, entryPoint *static.EntryPoint, listener net.Listener) (net.Listener, error) {
|
||||
var sourceCheck func(addr net.Addr) (bool, error)
|
||||
proxyListener := &proxyproto.Listener{Listener: listener}
|
||||
|
||||
if entryPoint.ProxyProtocol.Insecure {
|
||||
sourceCheck = func(_ net.Addr) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
} else {
|
||||
checker, err := ip.NewChecker(entryPoint.ProxyProtocol.TrustedIPs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
log.FromContext(ctx).Infof("Enabling ProxyProtocol without trusted IPs: Insecure")
|
||||
return proxyListener, nil
|
||||
}
|
||||
|
||||
checker, err := ip.NewChecker(entryPoint.ProxyProtocol.TrustedIPs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
proxyListener.Policy = func(upstream net.Addr) (proxyproto.Policy, error) {
|
||||
ipAddr, ok := upstream.(*net.TCPAddr)
|
||||
if !ok {
|
||||
return proxyproto.REJECT, fmt.Errorf("type error %v", upstream)
|
||||
}
|
||||
|
||||
sourceCheck = func(addr net.Addr) (bool, error) {
|
||||
ipAddr, ok := addr.(*net.TCPAddr)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("type error %v", addr)
|
||||
}
|
||||
|
||||
return checker.ContainsIP(ipAddr.IP), nil
|
||||
if !checker.ContainsIP(ipAddr.IP) {
|
||||
log.FromContext(ctx).Debugf("IP %s is not in trusted IPs list, ignoring ProxyProtocol Headers and bypass connection", ipAddr.IP)
|
||||
return proxyproto.IGNORE, nil
|
||||
}
|
||||
return proxyproto.USE, nil
|
||||
}
|
||||
|
||||
log.FromContext(ctx).Infof("Enabling ProxyProtocol for trusted IPs %v", entryPoint.ProxyProtocol.TrustedIPs)
|
||||
|
||||
return proxyprotocol.NewDefaultListener(listener).
|
||||
WithSourceChecker(sourceCheck).
|
||||
WithLogger(proxyProtocolLogger{Logger: log.FromContext(ctx)}), nil
|
||||
return proxyListener, nil
|
||||
}
|
||||
|
||||
func buildListener(ctx context.Context, entryPoint *static.EntryPoint) (net.Listener, error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue