Set PROXY protocol PP2_TYPE_SSL

This commit is contained in:
Simon Ser 2020-10-09 14:45:55 +02:00
parent 1f16053334
commit aae358811d
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 45 additions and 7 deletions

2
go.mod
View File

@ -7,7 +7,7 @@ require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/klauspost/cpuid v1.3.1 // indirect github.com/klauspost/cpuid v1.3.1 // indirect
github.com/miekg/dns v1.1.31 // indirect github.com/miekg/dns v1.1.31 // indirect
github.com/pires/go-proxyproto v0.2.0 github.com/pires/go-proxyproto v0.2.1-0.20201009121050-c24efa3e2d93
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/stretchr/testify v1.6.1 // indirect github.com/stretchr/testify v1.6.1 // indirect
go.uber.org/multierr v1.6.0 // indirect go.uber.org/multierr v1.6.0 // indirect

4
go.sum
View File

@ -24,8 +24,8 @@ github.com/mholt/acmez v0.1.1/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ce
github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo= github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/pires/go-proxyproto v0.2.0 h1:WyYKlv9pkt77b+LjMvPfwrsAxviaGCFhG4KDIy1ofLY= github.com/pires/go-proxyproto v0.2.1-0.20201009121050-c24efa3e2d93 h1:zJOJr+XdRZHeJ2u2M7d27G0PreBM84mXCcOSdQVC4Xc=
github.com/pires/go-proxyproto v0.2.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pires/go-proxyproto v0.2.1-0.20201009121050-c24efa3e2d93/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=

View File

@ -11,6 +11,7 @@ import (
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
"github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto"
"github.com/pires/go-proxyproto/tlvparse"
) )
type Server struct { type Server struct {
@ -170,6 +171,11 @@ func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) e
if tlsState.ServerName != "" { if tlsState.ServerName != "" {
tlvs = append(tlvs, authorityTLV(tlsState.ServerName)) tlvs = append(tlvs, authorityTLV(tlsState.ServerName))
} }
if tlv, err := sslTLV(tlsState); err != nil {
return fmt.Errorf("failed to set PROXY protocol header SSL TLV: %v", err)
} else {
tlvs = append(tlvs, tlv)
}
if err := h.SetTLVs(tlvs); err != nil { if err := h.SetTLVs(tlvs); err != nil {
return fmt.Errorf("failed to set PROXY protocol header TLVs: %v", err) return fmt.Errorf("failed to set PROXY protocol header TLVs: %v", err)
} }
@ -201,10 +207,42 @@ func duplexCopy(a, b io.ReadWriter) error {
return <-done return <-done
} }
func authorityTLV(name string) proxyproto.TLV { func newTLV(t proxyproto.PP2Type, v []byte) proxyproto.TLV {
return proxyproto.TLV{ return proxyproto.TLV{
Type: proxyproto.PP2_TYPE_AUTHORITY, Type: t,
Length: len(name), Length: len(v),
Value: []byte(name), Value: v,
} }
} }
func authorityTLV(name string) proxyproto.TLV {
return newTLV(proxyproto.PP2_TYPE_AUTHORITY, []byte(name))
}
func sslTLV(state *tls.ConnectionState) (proxyproto.TLV, error) {
pp2ssl := tlvparse.PP2SSL{
Client: tlvparse.PP2_BITFIELD_CLIENT_SSL, // all of our connections are TLS
Verify: 1, // we haven't checked the client cert
}
var version string
switch state.Version {
case tls.VersionTLS10:
version = "TLSv1.0"
case tls.VersionTLS11:
version = "TLSv1.1"
case tls.VersionTLS12:
version = "TLSv1.2"
case tls.VersionTLS13:
version = "TLSv1.3"
}
if version != "" {
versionTLV := newTLV(proxyproto.PP2_SUBTYPE_SSL_VERSION, []byte(version))
pp2ssl.TLV = append(pp2ssl.TLV, versionTLV)
}
// TODO: add PP2_SUBTYPE_SSL_CIPHER, PP2_SUBTYPE_SSL_SIG_ALG, PP2_SUBTYPE_SSL_KEY_ALG
// TODO: check client-provided cert, if any
return pp2ssl.Marshal()
}