From 6aa26b7defa02515fcc8473b8c8603e5fbe45f3f Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Sat, 26 Apr 2025 20:42:21 -0400 Subject: fix(relayd): disable TCP fingerprinting on Linux for now Signed-off-by: Xe Iaso --- cmd/relayd/_tcpfingerprint.go | 84 +++++++++++++++++++++++++++++++++++++++++++ cmd/relayd/fingerprint.go | 17 +++++---- cmd/relayd/main.go | 6 ++-- cmd/relayd/tcpfingerprint.go | 82 ------------------------------------------ 4 files changed, 95 insertions(+), 94 deletions(-) create mode 100644 cmd/relayd/_tcpfingerprint.go delete mode 100644 cmd/relayd/tcpfingerprint.go (limited to 'cmd') diff --git a/cmd/relayd/_tcpfingerprint.go b/cmd/relayd/_tcpfingerprint.go new file mode 100644 index 0000000..201a9b6 --- /dev/null +++ b/cmd/relayd/_tcpfingerprint.go @@ -0,0 +1,84 @@ +//go:build ignore + +package main + +import ( + "fmt" + "net" + "net/http" + "strings" + + "github.com/mikioh/tcp" + "github.com/mikioh/tcpinfo" +) + +func assignTCPFingerprint(c net.Conn) (*JA4T, error) { + tc, err := tcp.NewConn(c) + if err != nil { + return nil, err + } + + var o tcpinfo.Info + var b [256]byte + i, err := tc.Option(o.Level(), o.Name(), b[:]) + if err != nil { + return nil, err + } + + ci, ok := i.(*tcpinfo.Info) + if !ok { + return nil, fmt.Errorf("can't make %T into *tcpinfo.Info", i) + } + + result := &JA4T{ + Window: uint32(ci.Sys.SenderWindow), + MSS: uint16(ci.SenderMSS), + } + + for _, opt := range ci.PeerOptions { + switch opt.(type) { + case tcpinfo.WindowScale: + result.Options = append(result.Options, 3, uint8(opt.(tcpinfo.WindowScale))) + result.WindowScale = uint8(opt.(tcpinfo.WindowScale)) + case tcpinfo.SACKPermitted: + result.Options = append(result.Options, 4, 1) + case tcpinfo.Timestamps: + result.Options = append(result.Options, 8, 1) + } + } + + return result, nil +} + +type tcpFingerprintKey struct{} + +func GetTCPFingerprint(r *http.Request) *JA4T { + ptr := r.Context().Value(tcpFingerprintKey{}) + if fpPtr, ok := ptr.(*JA4T); ok && ptr != nil && fpPtr != nil { + return fpPtr + } + return nil +} + +type JA4T struct { + Window uint32 + Options []uint8 + MSS uint16 + WindowScale uint8 +} + +func (j JA4T) String() string { + var sb strings.Builder + fmt.Fprintf(&sb, "%d_", j.Window) + + for i, opt := range j.Options { + fmt.Fprint(&sb, opt) + if i != len(j.Options)-1 { + fmt.Fprint(&sb, "-") + } + } + fmt.Fprint(&sb, "_") + fmt.Fprintf(&sb, "%d_%d", j.MSS, j.WindowScale) + + return sb.String() +} diff --git a/cmd/relayd/fingerprint.go b/cmd/relayd/fingerprint.go index 1a30a57..67d55de 100644 --- a/cmd/relayd/fingerprint.go +++ b/cmd/relayd/fingerprint.go @@ -7,7 +7,6 @@ import ( "crypto/tls" "encoding/hex" "fmt" - "log/slog" "net" "net/http" "slices" @@ -42,14 +41,14 @@ func applyTLSFingerprinter(server *http.Server) { server.ConnContext = func(ctx context.Context, c net.Conn) context.Context { ctx = context.WithValue(ctx, tlsFingerprintKey{}, &TLSFingerprint{}) - if tc, ok := c.(*tls.Conn); ok { - tcpFP, err := assignTCPFingerprint(tc.NetConn()) - if err == nil { - ctx = context.WithValue(ctx, tcpFingerprintKey{}, tcpFP) - } else { - slog.Debug("ja4t error", "err", err) - } - } + // if tc, ok := c.(*tls.Conn); ok { + // tcpFP, err := assignTCPFingerprint(tc.NetConn()) + // if err == nil { + // ctx = context.WithValue(ctx, tcpFingerprintKey{}, tcpFP) + // } else { + // slog.Debug("ja4t error", "err", err) + // } + // } return ctx } diff --git a/cmd/relayd/main.go b/cmd/relayd/main.go index 9580fb2..3185b37 100644 --- a/cmd/relayd/main.go +++ b/cmd/relayd/main.go @@ -113,9 +113,9 @@ func main() { } } - if tcpFP := GetTCPFingerprint(req); tcpFP != nil { - req.Header.Set("X-TCP-Fingerprint-JA4T", tcpFP.String()) - } + // if tcpFP := GetTCPFingerprint(req); tcpFP != nil { + // req.Header.Set("X-TCP-Fingerprint-JA4T", tcpFP.String()) + // } req.Header.Set("X-Forwarded-Host", req.URL.Host) req.Header.Set("X-Forwarded-Proto", "https") diff --git a/cmd/relayd/tcpfingerprint.go b/cmd/relayd/tcpfingerprint.go deleted file mode 100644 index e420354..0000000 --- a/cmd/relayd/tcpfingerprint.go +++ /dev/null @@ -1,82 +0,0 @@ -package main - -import ( - "fmt" - "net" - "net/http" - "strings" - - "github.com/mikioh/tcp" - "github.com/mikioh/tcpinfo" -) - -func assignTCPFingerprint(c net.Conn) (*JA4T, error) { - tc, err := tcp.NewConn(c) - if err != nil { - return nil, err - } - - var o tcpinfo.Info - var b [256]byte - i, err := tc.Option(o.Level(), o.Name(), b[:]) - if err != nil { - return nil, err - } - - ci, ok := i.(*tcpinfo.Info) - if !ok { - return nil, fmt.Errorf("can't make %T into *tcpinfo.Info", i) - } - - result := &JA4T{ - Window: uint32(ci.Sys.SenderWindow), - MSS: uint16(ci.SenderMSS), - } - - for _, opt := range ci.PeerOptions { - switch opt.(type) { - case tcpinfo.WindowScale: - result.Options = append(result.Options, 3, uint8(opt.(tcpinfo.WindowScale))) - result.WindowScale = uint8(opt.(tcpinfo.WindowScale)) - case tcpinfo.SACKPermitted: - result.Options = append(result.Options, 4, 1) - case tcpinfo.Timestamps: - result.Options = append(result.Options, 8, 1) - } - } - - return result, nil -} - -type tcpFingerprintKey struct{} - -func GetTCPFingerprint(r *http.Request) *JA4T { - ptr := r.Context().Value(tcpFingerprintKey{}) - if fpPtr, ok := ptr.(*JA4T); ok && ptr != nil && fpPtr != nil { - return fpPtr - } - return nil -} - -type JA4T struct { - Window uint32 - Options []uint8 - MSS uint16 - WindowScale uint8 -} - -func (j JA4T) String() string { - var sb strings.Builder - fmt.Fprintf(&sb, "%d_", j.Window) - - for i, opt := range j.Options { - fmt.Fprint(&sb, opt) - if i != len(j.Options)-1 { - fmt.Fprint(&sb, "-") - } - } - fmt.Fprint(&sb, "_") - fmt.Fprintf(&sb, "%d_%d", j.MSS, j.WindowScale) - - return sb.String() -} -- cgit v1.2.3