ssl-fingerprint #

JA3/JA4 TLS client fingerprinting for HTTP and stream. Enable per server with "ssl_fingerprint on;" (needs the ssl-fingerprint.patch core patch + an openssl-nginx that exposes the raw ClientHello). It then populates the variables $ssl_fingerprint_ja3, $ssl_fingerprint_ja3_hash, $ssl_fingerprint_ja4, $ssl_fingerprint_ja4_r (raw), $ssl_fingerprint_ja4_o and $ssl_fingerprint_ja4_ro (original/ordered variants), plus $ssl_greased — use them in log_format or pass upstream to fingerprint clients. Full write-up: JA3/JA4 fingerprinting explained →.

Source: upstream source

Read more: deep-dive article on deb.myguard.nl

Directives

ssl_fingerprint #

syntax: ssl_fingerprint on | off;  ·  default: off  ·  context: http, stream

Enables or disables SSL fingerprint collection. When on, the JA3/JA4 variables ($ssl_fingerprint_ja3, $ssl_fingerprint_ja4 and the _r / _o / _ro variants) plus $ssl_greased are populated for every TLS connection on that server. Needs the ssl-fingerprint.patch core patch and an openssl-nginx that exposes the raw ClientHello.

Example

worker_processes  1;
daemon off;
pid nginx.pid;
error_log /dev/stderr debug;

events {
    worker_connections  1024;
}

http {
    ssl_fingerprint on;
    log_format basic '$remote_addr ja3: $ssl_fingerprint_ja3 greased: $ssl_greased';
    server {
        listen                 0.0.0.0:4433 ssl;
        access_log             /dev/stdout basic;
        ssl_certificate_key    "data:-----BEGIN EC PARAMETERS-----\nBggqhkjOPQMBBw==\n-----END EC PARAMETERS-----\n-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIL02pwZutbzkmdIM0QpvD7W3pcL2dGaeWrbQ8pNCHPFeoAoGCCqGSM49\nAwEHoUQDQgAE0Jektzpg3tJx3iPU05WwG4GweCwGWv87kkZQGB+6vG/kQQeOhnZ7\n7TCroQgY4ZVnBRZTD0lvxSyR6rwt3lWQ4A==\n-----END EC PRIVATE KEY-----\n";
        ssl_certificate        "data:-----BEGIN CERTIFICATE-----\nMIIBtjCCAV2gAwIBAgIUN/O0uv7B+18ohuf05ygsoC82liswCgYIKoZIzj0EAwIw\nMTELMAkGA1UEBhMCVVMxDDAKBgNVBAsMA1dlYjEUMBIGA1UEAwwLZXhhbXBsZS5v\ncmcwHhcNMjIwNzI4MTgzMzA2WhcNMjMwNzI5MTgzMzA2WjAxMQswCQYDVQQGEwJV\nUzEMMAoGA1UECwwDV2ViMRQwEgYDVQQDDAtleGFtcGxlLm9yZzBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABNCXpLc6YN7Scd4j1NOVsBuBsHgsBlr/O5JGUBgfurxv\n5EEHjoZ2e+0wq6EIGOGVZwUWUw9Jb8Uskeq8Ld5VkOCjUzBRMB0GA1UdDgQWBBSH\n9cc3JRcpyPh3nEa41Ux6RDGjLTAfBgNVHSMEGDAWgBSH9cc3JRcpyPh3nEa41Ux6\nRDGjLTAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIChRR5U7MMYQ\ntMK0zhNnt2SqRy30VcPIm9qoEms5cNxdAiBb273P7vSkj/PmDd1WsFVkg9NymBaT\n0nsIem2LKav60g==\n-----END CERTIFICATE-----\n";
        return                 200 "ja4: $ssl_fingerprint_ja4 ja4_r: $ssl_fingerprint_ja4_r ja4_o: $ssl_fingerprint_ja4_o ja4_ro: $ssl_fingerprint_ja4_ro ja3: $ssl_fingerprint_ja3 ja3_hash: $ssl_fingerprint_ja3_hash greased: $ssl_greased\n";
    }
}

stream {
    ssl_fingerprint on;
    log_format basic '$remote_addr ja3: $ssl_fingerprint_ja3 greased: $ssl_greased';
    server {
        listen                 0.0.0.0:4443 ssl;
        access_log             /dev/stdout basic;
        ssl_certificate_key    "data:-----BEGIN EC PARAMETERS-----\nBggqhkjOPQMBBw==\n-----END EC PARAMETERS-----\n-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIL02pwZutbzkmdIM0QpvD7W3pcL2dGaeWrbQ8pNCHPFeoAoGCCqGSM49\nAwEHoUQDQgAE0Jektzpg3tJx3iPU05WwG4GweCwGWv87kkZQGB+6vG/kQQeOhnZ7\n7TCroQgY4ZVnBRZTD0lvxSyR6rwt3lWQ4A==\n-----END EC PRIVATE KEY-----\n";
        ssl_certificate        "data:-----BEGIN CERTIFICATE-----\nMIIBtjCCAV2gAwIBAgIUN/O0uv7B+18ohuf05ygsoC82liswCgYIKoZIzj0EAwIw\nMTELMAkGA1UEBhMCVVMxDDAKBgNVBAs
…

↑ back to index