@@ 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
@@ 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=
@@ 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()
+}