-
Notifications
You must be signed in to change notification settings - Fork 851
Add boringssl support to the ja4_fingerprint plugin #12790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jasmine-nahrain
wants to merge
18
commits into
apache:master
Choose a base branch
from
jasmine-nahrain:bssl_ja4
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+672
−51
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
786fbaa
got client hello routed to plugins
jasmine-nahrain 3f4e5c4
Creates ja4 fingerprint with boringssl
jasmine-nahrain 5c8c8ed
cleanup a bit
jasmine-nahrain 0efeade
make ssl_client_hello const
jasmine-nahrain 9765eb8
spaces cleanup
jasmine-nahrain 2bc38d0
cleanup code
jasmine-nahrain fd03806
more cleanup
jasmine-nahrain 9b76bd0
Update plugin.cc
jasmine-nahrain 51ebe55
Update plugin.cc
jasmine-nahrain b57f338
Update ts.h
jasmine-nahrain 162af78
Update apidefs.h.in
jasmine-nahrain a42ae48
Update to make more clean
jasmine-nahrain 19bbc06
Update data
jasmine-nahrain 4dc5af8
address comments
jasmine-nahrain 4a51fac
Update ja4_fingerprint.en.rst
jasmine-nahrain b2868d9
Add docs
jasmine-nahrain b9e1351
Update TSVConnClientHelloGet.en.rst
jasmine-nahrain 3019dd7
Update TSVConnClientHelloGet.en.rst
jasmine-nahrain File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,209 @@ | ||
| .. Licensed to the Apache Software Foundation (ASF) under one | ||
| or more contributor license agreements. See the NOTICE file | ||
| distributed with this work for additional information | ||
| regarding copyright ownership. The ASF licenses this file | ||
| to you under the Apache License, Version 2.0 (the | ||
| "License"); you may not use this file except in compliance | ||
| with the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, | ||
| software distributed under the License is distributed on an | ||
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| KIND, either express or implied. See the License for the | ||
| specific language governing permissions and limitations | ||
| under the License. | ||
|
|
||
| .. include:: ../../common.defs | ||
|
|
||
| .. _admin-plugins-ja4-fingerprint: | ||
|
|
||
| JA4 Fingerprint Plugin | ||
| ********************** | ||
|
|
||
| Description | ||
| =========== | ||
|
|
||
| The JA4 Fingerprint plugin generates TLS client fingerprints based on the JA4 | ||
| algorithm designed by John Althouse. JA4 is the successor to the JA3 | ||
| fingerprinting algorithm and provides improved client identification for TLS | ||
| connections. | ||
|
|
||
| A JA4 fingerprint uniquely identifies TLS clients based on characteristics of | ||
| their TLS ClientHello messages, including: | ||
|
|
||
| * TLS version | ||
| * ALPN (Application-Layer Protocol Negotiation) preferences | ||
| * Cipher suites offered | ||
| * TLS extensions present | ||
|
|
||
| This information can be used for: | ||
|
|
||
| * Client identification and tracking | ||
| * Bot detection and mitigation | ||
| * Security analytics and threat intelligence | ||
| * Understanding client TLS implementation patterns | ||
|
|
||
| How It Works | ||
| ============ | ||
|
|
||
| The plugin intercepts TLS ClientHello messages during the TLS handshake and | ||
| generates a JA4 fingerprint consisting of three sections separated by underscores: | ||
|
|
||
| **Section a (unhashed)**: Basic information about the client including: | ||
|
|
||
| * Protocol (``t`` for TCP, ``q`` for QUIC) | ||
| * TLS version | ||
| * SNI (Server Name Indication) status | ||
| * Number of cipher suites | ||
| * Number of extensions | ||
| * First ALPN value | ||
|
|
||
| **Section b (hashed)**: A SHA-256 hash of the sorted cipher suite list | ||
|
|
||
| **Section c (hashed)**: A SHA-256 hash of the sorted extension list | ||
|
|
||
| Example fingerprint:: | ||
|
|
||
| t13d1516h2_8daaf6152771_b186095e22b6 | ||
|
|
||
| Key Differences from JA3 | ||
| ------------------------- | ||
|
|
||
| * Cipher suites and extensions are sorted before hashing for consistency | ||
| * SNI and ALPN information is included in the fingerprint | ||
| * More resistant to fingerprint randomization | ||
|
|
||
| Plugin Configuration | ||
| ==================== | ||
|
|
||
| The plugin operates as a global plugin and has no configuration options. | ||
|
|
||
| To enable the plugin, add the following line to :file:`plugin.config`:: | ||
|
|
||
| ja4_fingerprint.so | ||
|
|
||
| No additional parameters are required or supported. | ||
|
|
||
| Plugin Behavior | ||
| =============== | ||
|
|
||
| When loaded, the plugin will: | ||
|
|
||
| 1. **Capture TLS ClientHello**: Intercepts all incoming TLS connections during | ||
| the ClientHello phase | ||
|
|
||
| 2. **Generate Fingerprint**: Calculates the JA4 fingerprint from the | ||
| ClientHello data | ||
|
|
||
| 3. **Log to File**: Writes the fingerprint and client IP address to | ||
| ``ja4_fingerprint.log`` | ||
|
|
||
| 4. **Add HTTP Headers**: Injects the following headers into subsequent HTTP | ||
| requests on the same connection: | ||
|
|
||
| * ``ja4``: Contains the JA4 fingerprint | ||
| * ``x-ja4-via``: Contains the proxy name (from ``proxy.config.proxy_name``) | ||
|
|
||
| Log Output | ||
| ========== | ||
|
|
||
| The plugin writes to ``ja4_fingerprint.log`` in the Traffic Server log | ||
| directory (typically ``/var/log/trafficserver/``). | ||
|
|
||
| **Log Format**:: | ||
|
|
||
| [timestamp] Client IP: <ip_address> JA4: <fingerprint> | ||
|
|
||
| **Example**:: | ||
|
|
||
| [Jan 29 10:15:23.456] Client IP: 192.168.1.100 JA4: t13d1516h2_8daaf6152771_b186095e22b6 | ||
| [Jan 29 10:15:24.123] Client IP: 10.0.0.50 JA4: t13d1715h2_8daaf6152771_02713d6af862 | ||
|
|
||
| Using JA4 Headers in Origin Requests | ||
| ===================================== | ||
|
|
||
| Origin servers can access the JA4 fingerprint through the injected HTTP header. | ||
| This allows the origin to: | ||
|
|
||
| * Make access control decisions based on client fingerprints | ||
| * Log fingerprints for security analysis | ||
| * Track client populations and TLS implementation patterns | ||
|
|
||
| The ``x-ja4-via`` header allows origin servers to track which Traffic Server | ||
| proxy handled the request when multiple proxies are deployed. | ||
|
|
||
| Debugging | ||
| ========= | ||
|
|
||
| To enable debug logging for the plugin, set the following in :file:`records.yaml`:: | ||
|
|
||
| records: | ||
| diags: | ||
| debug: | ||
| enabled: 1 | ||
| tags: ja4_fingerprint | ||
|
|
||
| Debug output will appear in :file:`diags.log` and includes: | ||
|
|
||
| * ClientHello processing events | ||
| * Fingerprint generation details | ||
| * Header injection operations | ||
|
|
||
| Requirements | ||
| ============ | ||
|
|
||
| * Traffic Server must be built with TLS support (OpenSSL or BoringSSL) | ||
| * The plugin operates on all TLS connections | ||
|
|
||
| Configuration Settings | ||
| ====================== | ||
|
|
||
| The plugin requires the ``proxy.config.proxy_name`` setting to be configured | ||
| for the ``x-ja4-via`` header. If not set, the plugin will log an error and use | ||
| "unknown" as the proxy name. | ||
|
|
||
| To set the proxy name in :file:`records.yaml`:: | ||
|
|
||
| records: | ||
| proxy: | ||
| config: | ||
| proxy_name: proxy01 | ||
|
|
||
| Limitations | ||
| =========== | ||
|
|
||
| * The plugin only operates in global mode (no per-remap configuration) | ||
| * Logging cannot be disabled | ||
| * Raw (unhashed) cipher and extension lists are not logged | ||
| * Non-TLS connections do not generate fingerprints | ||
|
|
||
| See Also | ||
| ======== | ||
|
|
||
| * JA4 Technical Specification: https://github.com/FoxIO-LLC/ja4/blob/main/technical_details/JA4.md | ||
| * JA4 is licensed under the BSD 3-Clause license | ||
|
|
||
| Example Configuration | ||
| ===================== | ||
|
|
||
| Complete example configuration for enabling JA4 fingerprinting: | ||
|
|
||
| **plugin.config**:: | ||
|
|
||
| ja4_fingerprint.so | ||
|
|
||
| **records.yaml**:: | ||
|
|
||
| records: | ||
| proxy: | ||
| config: | ||
| proxy_name: proxy-01 | ||
| diags: | ||
| debug: | ||
| enabled: 1 | ||
| tags: ja4_fingerprint | ||
|
|
||
| After restarting Traffic Server, the plugin will begin fingerprinting TLS | ||
| connections and logging to ``ja4_fingerprint.log``. |
50 changes: 50 additions & 0 deletions
50
doc/developer-guide/api/functions/TSVConnClientHelloGet.en.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| .. Licensed to the Apache Software Foundation (ASF) under one or more | ||
| contributor license agreements. See the NOTICE file distributed | ||
| with this work for additional information regarding copyright | ||
| ownership. The ASF licenses this file to you under the Apache | ||
| License, Version 2.0 (the "License"); you may not use this file | ||
| except in compliance with the License. You may obtain a copy of | ||
| the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
| implied. See the License for the specific language governing | ||
| permissions and limitations under the License. | ||
|
|
||
| .. include:: ../../../common.defs | ||
|
|
||
| .. default-domain:: cpp | ||
|
|
||
| TSVConnClientHelloGet | ||
| ********************* | ||
|
|
||
| Synopsis | ||
| ======== | ||
|
|
||
| .. code-block:: cpp | ||
|
|
||
| #include <ts/ts.h> | ||
|
|
||
| .. function:: TSClientHello TSVConnClientHelloGet(TSVConn sslp) | ||
| .. function:: void TSClientHelloDestroy(TSClientHello ch) | ||
| .. function:: TSReturnCode TSClientHelloExtensionGet(TSClientHello ch, unsigned int type, const unsigned char **out, size_t *outlen) | ||
|
|
||
| Description | ||
| =========== | ||
|
|
||
| :func:`TSVConnClientHelloGet` retrieves ClientHello message data from the TLS | ||
| virtual connection :arg:`sslp`. This function is typically called from the | ||
| ``TS_EVENT_SSL_CLIENT_HELLO`` hook. Returns ``nullptr`` if | ||
| :arg:`sslp` is invalid or not a TLS connection. | ||
|
|
||
| The caller must call :func:`TSClientHelloDestroy` to free the returned object. | ||
|
|
||
| :func:`TSClientHelloDestroy` frees the :type:`TSClientHello` object :arg:`ch`. | ||
|
|
||
| :func:`TSClientHelloExtensionGet` retrieves extension data for the specified | ||
| :arg:`type` (e.g., ``0x10`` for ALPN). Returns :enumerator:`TS_SUCCESS` if | ||
| found, :enumerator:`TS_ERROR` otherwise. The returned pointer in :arg:`out` is | ||
| valid only while :arg:`ch` exists. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| .. Licensed to the Apache Software Foundation (ASF) under one or more | ||
| contributor license agreements. See the NOTICE file distributed | ||
| with this work for additional information regarding copyright | ||
| ownership. The ASF licenses this file to you under the Apache | ||
| License, Version 2.0 (the "License"); you may not use this file | ||
| except in compliance with the License. You may obtain a copy of | ||
| the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
| implied. See the License for the specific language governing | ||
| permissions and limitations under the License. | ||
|
|
||
| .. include:: ../../../common.defs | ||
|
|
||
| .. default-domain:: cpp | ||
|
|
||
| TSClientHello | ||
| ************* | ||
|
|
||
| Synopsis | ||
| ======== | ||
|
|
||
| .. code-block:: cpp | ||
|
|
||
| #include <ts/apidefs.h> | ||
|
|
||
| .. type:: TSClientHello | ||
|
|
||
|
|
||
| Description | ||
| =========== | ||
|
|
||
| :type:`TSClientHello` is an opaque handle to a TLS ClientHello message sent by | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not just a handle. I think the accessors need to be listed. Otherwise reading the header file would be the only way to know how to use it. |
||
| a client during the TLS handshake. It provides access to the client's TLS | ||
| version, cipher suites, and extensions. | ||
|
|
||
| Objects of this type are obtained via :func:`TSVConnClientHelloGet` and must | ||
| be freed using :func:`TSClientHelloDestroy`. The implementation abstracts | ||
| differences between OpenSSL and BoringSSL to provide a consistent interface. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we don't deep copy the information, we can use this function only on limited hooks. I'm sure we can use
TS_EVENT_SSL_CLIENT_HELLO, but I'm not sure if it's the only hook or there are other hooks.The documentation should list up all the hooks, or tell that
TS_EVENT_SSL_CLIENT_HELLOis the only hook supported (maybe for now, until somebody confirms another hook work as well).