Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func JA4 ¶
func JA4(hello *tls.ClientHelloInfo) string
JA4 generates a JA4 fingerprint from the given tls.ClientHelloInfo. It extracts TLS Version, Cipher Suites, Extensions, and ALPN Protocols.
Example ¶
package main import ( "crypto/tls" "fmt" "log" "net/http" "net/http/httptest" "github.com/exaring/ja4plus" ) func main() { srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) defer srv.Close() srv.TLS = &tls.Config{ GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) { fmt.Println(ja4plus.JA4(hello)) return nil, nil }, } srv.EnableHTTP2 = true srv.StartTLS() client := srv.Client() resp, err := client.Get(srv.URL) if err != nil { log.Println(err) return } defer resp.Body.Close() }
Output: t13i1310h2_f57a46bbacb6_e7c285222651
func JA4FromContext ¶
JA4FromContext extracts the JA4 fingerprint from the provided http.Request.Context. It requires a server set up with JA4Middleware to work.
Types ¶
type JA4Middleware ¶
type JA4Middleware struct {
// contains filtered or unexported fields
}
JA4Middleware is a helper to plug the JA4 fingerprinting into your HTTP server. It only exists because there is no direct way to pass information from the TLS handshake to the HTTP handler. Usage:
ja4middleware := ja4plus.JA4Middleware{} srv := http.Server{ Handler: ja4middleware.Wrap(...), TLSConfig: &tls.Config{ GetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) { ja4middleware.StoreFingerprintFromClientHello(chi) return nil, nil }, }, ConnState: ja4middleware.ConnStateCallback, } srv.ListenAndServeTLS("cert.pem", "key.pem")
Afterwards the fingerprint can be accessed via [JA4Middleware.FingerprintFromContext]
Example ¶
package main import ( "crypto/tls" "io" "net/http" "github.com/exaring/ja4plus" ) func main() { exampleHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = io.WriteString(w, ja4plus.JA4FromContext(r.Context())) }) ja4middleware := ja4plus.JA4Middleware{} /* srv */ _ = http.Server{ Addr: ":8080", Handler: ja4middleware.Wrap(exampleHandler), TLSConfig: &tls.Config{ GetConfigForClient: func(chi *tls.ClientHelloInfo) (*tls.Config, error) { ja4middleware.StoreFingerprintFromClientHello(chi) return nil, nil }, }, ConnState: ja4middleware.ConnStateCallback, } // srv.ListenAndServeTLS(...) }
Output:
func (*JA4Middleware) ConnStateCallback ¶
func (m *JA4Middleware) ConnStateCallback(conn net.Conn, state http.ConnState)
ConnStateCallback is a callback that should be set as the http.Server's ConnState to clean up the fingerprint cache.
func (*JA4Middleware) StoreFingerprintFromClientHello ¶
func (m *JA4Middleware) StoreFingerprintFromClientHello(hello *tls.ClientHelloInfo)
StoreFingerprintFromClientHello stores the JA4 fingerprint of the provided tls.ClientHelloInfo in the middleware.
func (*JA4Middleware) Wrap ¶
func (m *JA4Middleware) Wrap(next http.Handler) http.Handler
Wrap wraps the provided http.Handler and injects the JA4 fingerprint into the http.Request.Context. It requires a server set up with JA4Middleware to work.