From aae358811d2df82fb744f3441e7543e0d9458136 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 9 Oct 2020 14:45:55 +0200 Subject: [PATCH] Set PROXY protocol PP2_TYPE_SSL --- go.mod | 2 +- go.sum | 4 ++-- server.go | 46 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 8024c84..87ed333 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/klauspost/cpuid v1.3.1 // 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/stretchr/testify v1.6.1 // indirect go.uber.org/multierr v1.6.0 // indirect diff --git a/go.sum b/go.sum index ed268cc..a41eaf1 100644 --- a/go.sum +++ b/go.sum @@ -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.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo= 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.0/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= +github.com/pires/go-proxyproto v0.2.1-0.20201009121050-c24efa3e2d93 h1:zJOJr+XdRZHeJ2u2M7d27G0PreBM84mXCcOSdQVC4Xc= +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.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/server.go b/server.go index 0767845..4b468cf 100644 --- a/server.go +++ b/server.go @@ -11,6 +11,7 @@ import ( "github.com/caddyserver/certmagic" "github.com/pires/go-proxyproto" + "github.com/pires/go-proxyproto/tlvparse" ) type Server struct { @@ -170,6 +171,11 @@ func (fe *Frontend) handle(downstream net.Conn, tlsState *tls.ConnectionState) e if 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 { 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 } -func authorityTLV(name string) proxyproto.TLV { +func newTLV(t proxyproto.PP2Type, v []byte) proxyproto.TLV { return proxyproto.TLV{ - Type: proxyproto.PP2_TYPE_AUTHORITY, - Length: len(name), - Value: []byte(name), + Type: t, + Length: len(v), + 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() +}