diff --git a/doc/admin-guide/plugins/ja4_fingerprint.en.rst b/doc/admin-guide/plugins/ja4_fingerprint.en.rst index b8e5e5e37ad..a976f53b12d 100644 --- a/doc/admin-guide/plugins/ja4_fingerprint.en.rst +++ b/doc/admin-guide/plugins/ja4_fingerprint.en.rst @@ -78,13 +78,22 @@ Key Differences from JA3 Plugin Configuration ==================== -The plugin operates as a global plugin and has no configuration options. +The plugin operates as a global plugin. To enable the plugin, add the following line to :file:`plugin.config`:: ja4_fingerprint.so -No additional parameters are required or supported. + +.. option:: --preserve + +This option controls whether the plugin preserves any existing JA4 header. If the option is specified the plugin keep the header +intact. If the option is not speficied, the plugins appends a generated fingerprint to the existing header value. + +.. option:: --nologging + +This option disables log output. + Plugin Behavior =============== @@ -110,7 +119,7 @@ Log Output ========== The plugin writes to ``ja4_fingerprint.log`` in the Traffic Server log -directory (typically ``/var/log/trafficserver/``). +directory (typically ``/var/log/trafficserver/``) if the feature is not disabled. **Log Format**:: @@ -175,7 +184,6 @@ 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 diff --git a/plugins/experimental/ja4_fingerprint/plugin.cc b/plugins/experimental/ja4_fingerprint/plugin.cc index 216171280fa..a8bfe033671 100644 --- a/plugins/experimental/ja4_fingerprint/plugin.cc +++ b/plugins/experimental/ja4_fingerprint/plugin.cc @@ -81,15 +81,17 @@ constexpr unsigned int EXT_SUPPORTED_VERSIONS{0x2b}; DbgCtl dbg_ctl{PLUGIN_NAME}; int global_preserve_enabled{0}; +int global_nologging_enabled{0}; } // end anonymous namespace static bool -read_config_option(int argc, char const *argv[], int &preserve) +read_config_option(int argc, char const *argv[], int &preserve, int &no_logging) { const struct option longopts[] = { - {"preserve", no_argument, &preserve, 1}, - {nullptr, 0, nullptr, 0} + {"preserve", no_argument, &preserve, 1}, + {"nologging", no_argument, &no_logging, 1}, + {nullptr, 0, nullptr, 0} }; optind = 0; @@ -108,6 +110,7 @@ read_config_option(int argc, char const *argv[], int &preserve) } Dbg(dbg_ctl, "JA4 preserve is %s", (preserve == 1) ? "enabled" : "disabled"); + Dbg(dbg_ctl, "JA4 nologging is %s", (no_logging == 1) ? "enabled" : "disabled"); return true; } @@ -148,16 +151,18 @@ TSPluginInit(int argc, char const **argv) TSError("[%s] Failed to register.", PLUGIN_NAME); return; } - if (!read_config_option(argc, argv, global_preserve_enabled)) { + if (!read_config_option(argc, argv, global_preserve_enabled, global_nologging_enabled)) { TSError("[%s] Failed to parse options.", PLUGIN_NAME); return; } reserve_user_arg(); - if (!create_log_file()) { - TSError("[%s] Failed to create log.", PLUGIN_NAME); - return; - } else { - Dbg(dbg_ctl, "Created log file."); + if (!global_nologging_enabled) { + if (!create_log_file()) { + TSError("[%s] Failed to create log.", PLUGIN_NAME); + return; + } else { + Dbg(dbg_ctl, "Created log file."); + } } register_hooks(); } @@ -207,8 +212,11 @@ handle_client_hello(TSCont /* cont ATS_UNUSED */, TSEvent event, void *edata) } else { auto data{std::make_unique()}; data->fingerprint = get_fingerprint(ch); + Dbg(dbg_ctl, "JA4 fingerprint: %s", data->fingerprint.c_str()); get_IP(TSNetVConnRemoteAddrGet(ssl_vc), data->IP_addr); - log_fingerprint(data.get()); + if (!global_nologging_enabled) { + log_fingerprint(data.get()); + } // The VCONN_CLOSE handler is now responsible for freeing the resource. TSUserArgSet(ssl_vc, *get_user_arg_index(), static_cast(data.release())); } @@ -259,7 +267,6 @@ get_IP(sockaddr const *s_sockaddr, char res[INET6_ADDRSTRLEN]) void log_fingerprint(JA4_data const *data) { - Dbg(dbg_ctl, "JA4 fingerprint: %s", data->fingerprint.c_str()); if (TS_ERROR == TSTextLogObjectWrite(*get_log_handle(), "Client IP: %s\tJA4: %s", data->IP_addr, data->fingerprint.c_str())) { Dbg(dbg_ctl, "Failed to write to log!"); }