aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2025-04-21 16:36:13 -0400
committerXe Iaso <me@xeiaso.net>2025-04-21 16:36:13 -0400
commit8ecbe6f42e0eed79e899178570690aab1ce67c3f (patch)
tree1df34b6f2f656065fa63718127d27a87e4566adb
parentc56a114a91656d7a8a644f3e606b422d28ab10bb (diff)
downloadx-8ecbe6f42e0eed79e899178570690aab1ce67c3f.tar.xz
x-8ecbe6f42e0eed79e899178570690aab1ce67c3f.zip
feat(relayd): ja4t fingerprinting
Signed-off-by: Xe Iaso <me@xeiaso.net>
-rw-r--r--cmd/relayd/fingerprint.go14
-rw-r--r--cmd/relayd/tcpfingerprint.go26
2 files changed, 29 insertions, 11 deletions
diff --git a/cmd/relayd/fingerprint.go b/cmd/relayd/fingerprint.go
index 7ef2d13..1a30a57 100644
--- a/cmd/relayd/fingerprint.go
+++ b/cmd/relayd/fingerprint.go
@@ -41,12 +41,16 @@ func applyTLSFingerprinter(server *http.Server) {
}
server.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
ctx = context.WithValue(ctx, tlsFingerprintKey{}, &TLSFingerprint{})
- tcpFP, err := assignTCPFingerprint(c)
- 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/tcpfingerprint.go b/cmd/relayd/tcpfingerprint.go
index a5f611a..d88115b 100644
--- a/cmd/relayd/tcpfingerprint.go
+++ b/cmd/relayd/tcpfingerprint.go
@@ -1,9 +1,11 @@
package main
import (
+ "encoding/json"
"fmt"
"net"
"net/http"
+ "os"
"strings"
"github.com/mikioh/tcp"
@@ -25,15 +27,27 @@ func assignTCPFingerprint(c net.Conn) (*JA4T, error) {
ci, ok := i.(*tcpinfo.Info)
if !ok {
- return nil, fmt.Errorf("can't make %T into *tcpinfo.Info")
+ return nil, fmt.Errorf("can't make %T into *tcpinfo.Info", i)
}
+ json.NewEncoder(os.Stdout).Encode(ci)
+
result := &JA4T{
- Window: uint32(ci.Sys.SenderWindow),
- MSS: uint16(ci.SenderMSS),
- WindowScale: 0,
+ 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)
+ }
}
- fmt.Println(result.String())
return result, nil
}
@@ -61,7 +75,7 @@ func (j JA4T) String() string {
for i, opt := range j.Options {
fmt.Fprint(&sb, opt)
- if i-1 != len(j.Options) {
+ if i != len(j.Options)-1 {
fmt.Fprint(&sb, "-")
}
}