Skip to content

Commit

Permalink
Fix add_variable, since it called at postconfiguration, and also over…
Browse files Browse the repository at this point in the history
…write v; make possibe working with map ''{} and other nginx.conf releated features by adding no_found; small refactoring of the code to make it more close to official nginx's style and logic
  • Loading branch information
dedok authored and phuslu committed Feb 2, 2025
1 parent b0cbf96 commit ccfe8f1
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 126 deletions.
11 changes: 10 additions & 1 deletion config
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@

#
# JA3 module conf
#

ngx_addon_name=ngx_ssl_fingerprint_module

CORE_LIBS="$CORE_LIBS"
Expand All @@ -8,9 +13,13 @@ STREAM_MODULES="ngx_stream_ssl_fingerprint_preread_module $STREAM_MODULES"

HTTP_MODULES="$HTTP_MODULES ngx_http_ssl_fingerprint_module"

NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/src/nginx_ssl_fingerprint.c \
$ngx_addon_dir/src/ngx_stream_ssl_fingerprint_preread_module.c \
$ngx_addon_dir/src/ngx_http_ssl_fingerprint_module.c
"

CFLAGS="$CFLAGS -I$ngx_addon_dir"

have=NGX_JA3_FINGERPRING_MODULE . auto/have

33 changes: 13 additions & 20 deletions src/nginx_ssl_fingerprint.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <ngx_http_v2.h>
#include <ngx_md5.h>

#include <nginx_ssl_fingerprint.h>

#define IS_GREASE_CODE(code) (((code)&0x0f0f) == 0x0a0a && ((code)&0xff) == ((code)>>8))

static inline
Expand Down Expand Up @@ -192,20 +194,16 @@ int ngx_ssl_ja3(ngx_connection_t *c)
size_t num = 0, i;
uint16_t n, greased = 0;

if (c == NULL) {
return NGX_DECLINED;
}

if (c->ssl == NULL) {
if (c == NULL || c->ssl == NULL) {
return NGX_DECLINED;
}

data = c->ssl->fp_ja3_data.data;
if (!data) {
if (data == NULL) {
return NGX_DECLINED;
}

if (c->ssl->fp_ja3_str.len > 0) {
if (c->ssl->fp_ja3_str.data != NULL) {
return NGX_OK;
}

Expand All @@ -214,7 +212,7 @@ int ngx_ssl_ja3(ngx_connection_t *c)
if (c->ssl->fp_ja3_str.data == NULL) {
/** Else we break a data stream */
c->ssl->fp_ja3_str.len = 0;
return NGX_DECLINED;
return NGX_DECLINED /** NGX_ERROR? */;
}

ngx_log_debug(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_ssl_ja3: alloc bytes: [%d]\n", c->ssl->fp_ja3_str.len);
Expand Down Expand Up @@ -300,18 +298,16 @@ int ngx_ssl_ja3(ngx_connection_t *c)

int ngx_ssl_ja3_hash(ngx_connection_t *c)
{
if (c == NULL) {
return NGX_DECLINED;
}
ngx_md5_t ctx;
u_char hash_buf[16];

if (c->ssl == NULL) {
if (c == NULL
|| c->ssl == NULL
|| c->ssl->fp_ja3_hash.len > 0)
{
return NGX_DECLINED;
}

if (c->ssl->fp_ja3_hash.len > 0) {
return NGX_OK;
}

if (ngx_ssl_ja3(c) == NGX_DECLINED) {
return NGX_DECLINED;
}
Expand All @@ -326,9 +322,6 @@ int ngx_ssl_ja3_hash(ngx_connection_t *c)

ngx_log_debug(NGX_LOG_DEBUG_EVENT, c->log, 0, "ngx_ssl_ja3_hash: alloc bytes: [%d]\n", c->ssl->fp_ja3_hash.len);

ngx_md5_t ctx;
u_char hash_buf[16];

ngx_md5_init(&ctx);
ngx_md5_update(&ctx, c->ssl->fp_ja3_str.data, c->ssl->fp_ja3_str.len);
ngx_md5_final(hash_buf, &ctx);
Expand All @@ -343,7 +336,7 @@ int ngx_http2_fingerprint(ngx_connection_t *c, ngx_http_v2_connection_t *h2c)
unsigned short n = 0;
size_t i;

if (!h2c) {
if (c == NULL || h2c == NULL) {
return NGX_DECLINED;
}

Expand Down
19 changes: 19 additions & 0 deletions src/nginx_ssl_fingerprint.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

/*
* Obj: nginx_ssl_fingerprint.c
*/

#ifndef NGINX_SSL_FINGERPRINT_H_
#define NGINX_SSL_FINGERPRINT_H_ 1


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

int ngx_ssl_ja3(ngx_connection_t *c);
int ngx_ssl_ja3_hash(ngx_connection_t *c);
int ngx_http2_fingerprint(ngx_connection_t *c, ngx_http_v2_connection_t *h2c);

#endif /** NGINX_SSL_FINGERPRINT_H_ */

174 changes: 69 additions & 105 deletions src/ngx_http_ssl_fingerprint_module.c
Original file line number Diff line number Diff line change
@@ -1,61 +1,71 @@

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

extern int ngx_ssl_ja3(ngx_connection_t *c);
extern int ngx_ssl_ja3_hash(ngx_connection_t *c);
extern int ngx_http2_fingerprint(ngx_connection_t *c, ngx_http_v2_connection_t *h2c);
#include <nginx_ssl_fingerprint.h>

static ngx_int_t ngx_http_ssl_fingerprint_init(ngx_conf_t *cf);
static ngx_int_t ngx_http_ssl_greased(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_ssl_fingerprint(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_ssl_fingerprint_hash(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_http2_fingerprint(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);

static ngx_http_module_t ngx_http_ssl_fingerprint_module_ctx = {
NULL, /* preconfiguration */
ngx_http_ssl_fingerprint_init, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
NULL, /* create location configuration */
NULL /* merge location configuration */
ngx_http_ssl_fingerprint_init, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
NULL, /* create location configuration */
NULL /* merge location configuration */
};

ngx_module_t ngx_http_ssl_fingerprint_module = {
NGX_MODULE_V1,
&ngx_http_ssl_fingerprint_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING};

static ngx_http_variable_t ngx_http_ssl_fingerprint_variables_list[] = {
{ngx_string("http_ssl_greased"), NULL, ngx_http_ssl_greased,
0, NGX_HTTP_VAR_NOCACHEABLE, 0},
{ngx_string("http_ssl_ja3"), NULL, ngx_http_ssl_fingerprint,
0, NGX_HTTP_VAR_NOCACHEABLE, 0},
{ngx_string("http_ssl_ja3_hash"), NULL, ngx_http_ssl_fingerprint_hash,
0, NGX_HTTP_VAR_NOCACHEABLE, 0},
{ngx_string("http2_fingerprint"), NULL, ngx_http_http2_fingerprint,
0, NGX_HTTP_VAR_NOCACHEABLE, 0},
ngx_http_null_variable
};

static ngx_int_t
ngx_http_ssl_greased(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
if (r->connection == NULL)
{
return NGX_OK;
}
/* For access.log's map $http2_fingerpring {}:
* if it's not found, then user could add a defined string */
v->not_found = 1;

if (r->connection->ssl == NULL)
{
if (ngx_ssl_ja3(r->connection) != NGX_OK) {
return NGX_OK;
}

if (ngx_ssl_ja3(r->connection) == NGX_DECLINED)
{
return NGX_ERROR;
}

v->len = 1;
v->data = (u_char*)(r->connection->ssl->fp_tls_greased ? "1" : "0");

v->data = (u_char*) (r->connection->ssl->fp_tls_greased ? "1" : "0");
v->valid = 1;
v->no_cacheable = 1;
v->not_found = 0;
Expand All @@ -67,26 +77,19 @@ static ngx_int_t
ngx_http_ssl_fingerprint(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
if (r->connection == NULL)
{
return NGX_OK;
}
/* For access.log's map $http2_fingerpring {}:
* if it's not found, then user could add a defined string */
v->not_found = 1;

if (r->connection->ssl == NULL)
{
if (ngx_ssl_ja3(r->connection) != NGX_OK) {
return NGX_OK;
}

if (ngx_ssl_ja3(r->connection) == NGX_DECLINED)
{
return NGX_ERROR;
}

v->data = r->connection->ssl->fp_ja3_str.data;
v->len = r->connection->ssl->fp_ja3_str.len;
v->valid = 1;
v->no_cacheable = 1;
v->not_found = 0;
v->valid = 1;

return NGX_OK;
}
Expand All @@ -95,26 +98,19 @@ static ngx_int_t
ngx_http_ssl_fingerprint_hash(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
if (r->connection == NULL)
{
return NGX_OK;
}
/* For access.log's map $http2_fingerpring {}:
* if it's not found, then user could add a defined string */
v->not_found = 1;

if (r->connection->ssl == NULL)
{
if (ngx_ssl_ja3_hash(r->connection) != NGX_OK) {
return NGX_OK;
}

if (ngx_ssl_ja3_hash(r->connection) == NGX_DECLINED)
{
return NGX_ERROR;
}

v->data = r->connection->ssl->fp_ja3_hash.data;
v->len = r->connection->ssl->fp_ja3_hash.len;
v->valid = 1;
v->no_cacheable = 1;
v->not_found = 0;
v->valid = 1;

return NGX_OK;
}
Expand All @@ -123,77 +119,45 @@ static ngx_int_t
ngx_http_http2_fingerprint(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
if (r->connection == NULL)
{
return NGX_OK;
}
/* For access.log's map $http2_fingerpring {}:
* if it's not found, then user could add a defined string */
v->not_found = 1;

if (r->stream == NULL)
{
if (r->stream == NULL) {
return NGX_OK;
}

if (r->stream->connection == NULL)
if (ngx_http2_fingerprint(r->connection, r->stream->connection)
!= NGX_OK)
{
return NGX_OK;
}

if (ngx_http2_fingerprint(r->connection, r->stream->connection) == NGX_DECLINED)
{
return NGX_ERROR;
}

v->data = r->stream->connection->fp_str.data;
v->len = r->stream->connection->fp_str.len;
v->valid = 1;
v->no_cacheable = 1;
v->not_found = 0;
v->no_cacheable = 1;

return NGX_OK;
}

static ngx_http_variable_t ngx_http_ssl_fingerprint_variables_list[] = {
{ngx_string("http_ssl_greased"),
NULL,
ngx_http_ssl_greased,
0, 0, 0},
{ngx_string("http_ssl_ja3"),
NULL,
ngx_http_ssl_fingerprint,
0, 0, 0},
{ngx_string("http_ssl_ja3_hash"),
NULL,
ngx_http_ssl_fingerprint_hash,
0, 0, 0},
{ngx_string("http2_fingerprint"),
NULL,
ngx_http_http2_fingerprint,
0, 0, 0},
};

static ngx_int_t
ngx_http_ssl_fingerprint_init(ngx_conf_t *cf)
{
ngx_http_variable_t *var, *v;

ngx_http_variable_t *v;
size_t l = 0;
size_t vars_len;

vars_len = (sizeof(ngx_http_ssl_fingerprint_variables_list) /
sizeof(ngx_http_ssl_fingerprint_variables_list[0]));
for (v = ngx_http_ssl_fingerprint_variables_list; v->name.len; v++) {

/* Register variables */
for (l = 0; l < vars_len; ++l)
{
v = ngx_http_add_variable(cf,
&ngx_http_ssl_fingerprint_variables_list[l].name,
ngx_http_ssl_fingerprint_variables_list[l].flags);
if (v == NULL)
{
continue;
var = ngx_http_add_variable(cf, &v->name, v->flags);
if (var == NULL) {
return NGX_ERROR;
}
*v = ngx_http_ssl_fingerprint_variables_list[l];
/** NOTE: update it, if set_handler will be needed */
var->get_handler = v->get_handler;
var->data = v->data;
}

return NGX_OK;
}

0 comments on commit ccfe8f1

Please # to comment.