66
66
* created HTTP/1.1-message.
67
67
*
68
68
* Copyright (C) 2014 NatSys Lab. (info@natsys-lab.com).
69
- * Copyright (C) 2015-2024 Tempesta Technologies, Inc.
69
+ * Copyright (C) 2015-2025 Tempesta Technologies, Inc.
70
70
*
71
71
* This program is free software; you can redistribute it and/or modify it
72
72
* under the terms of the GNU General Public License as published by
114
114
#include "access_log.h"
115
115
#include "vhost.h"
116
116
#include "websocket.h"
117
+ #include "ja5_filter.h"
118
+ #include "ja5_conf.h"
117
119
118
120
#include "sync_socket.h"
119
121
#include "lib/common.h"
@@ -5997,6 +5999,15 @@ __check_authority_correctness(TfwHttpReq *req)
5997
5999
return true;
5998
6000
}
5999
6001
6002
+ static bool
6003
+ tfw_http_check_ja5h_req_limit (TfwHttpReq * req )
6004
+ {
6005
+ u64 limit = http_get_ja5_recs_limit (req -> ja5h );
6006
+ u64 rate = ja5h_get_records_rate (req -> ja5h );
6007
+
6008
+ return rate > limit ;
6009
+ }
6010
+
6000
6011
/**
6001
6012
* @return zero on success and negative value otherwise.
6002
6013
* TODO enter the function depending on current GFSM state.
@@ -6158,6 +6169,14 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
6158
6169
6159
6170
req -> ja5h .method = req -> method ;
6160
6171
6172
+ if (tfw_http_check_ja5h_req_limit (req )) {
6173
+ TFW_INC_STAT_BH (clnt .msgs_filtout );
6174
+ return tfw_http_req_parse_block (req , 403 ,
6175
+ "parsed request exceeded ja5h limit" ,
6176
+ HTTP2_ECODE_PROTO );
6177
+ }
6178
+
6179
+
6161
6180
/*
6162
6181
* The message is fully parsed, the rest of the data in the
6163
6182
* stream may represent another request or its part.
@@ -7303,6 +7322,7 @@ tfw_http_start(void)
7303
7322
{
7304
7323
TfwVhost * dflt_vh = tfw_vhost_lookup_default ();
7305
7324
bool misconfiguration ;
7325
+ u64 storage_size = http_get_ja5_storage_size ();
7306
7326
7307
7327
if (WARN_ON_ONCE (!dflt_vh ))
7308
7328
return -1 ;
@@ -7319,9 +7339,18 @@ tfw_http_start(void)
7319
7339
return -1 ;
7320
7340
}
7321
7341
7342
+ if (storage_size && !ja5h_init_filter (storage_size ))
7343
+ return - ENOMEM ;
7344
+
7322
7345
return 0 ;
7323
7346
}
7324
7347
7348
+ static void
7349
+ tfw_http_stop (void )
7350
+ {
7351
+ ja5h_close_filter ();
7352
+ }
7353
+
7325
7354
/*
7326
7355
* ------------------------------------------------------------------------
7327
7356
* configuration handling
@@ -7957,12 +7986,27 @@ static TfwCfgSpec tfw_http_specs[] = {
7957
7986
.allow_none = true,
7958
7987
.cleanup = tfw_cfgop_cleanup_max_header_list_size ,
7959
7988
},
7989
+ {
7990
+ .name = "ja5h" ,
7991
+ .deflt = NULL ,
7992
+ .handler = tfw_cfg_handle_children ,
7993
+ .cleanup = http_ja5_cfgop_cleanup ,
7994
+ .dest = ja5_hash_specs ,
7995
+ .spec_ext = & (TfwCfgSpecChild ) {
7996
+ .begin_hook = ja5_cfgop_begin ,
7997
+ .finish_hook = http_ja5_cfgop_finish
7998
+ },
7999
+ .allow_none = true,
8000
+ .allow_repeat = false,
8001
+ .allow_reconfig = true,
8002
+ },
7960
8003
{ 0 }
7961
8004
};
7962
8005
7963
8006
TfwMod tfw_http_mod = {
7964
8007
.name = "http" ,
7965
8008
.start = tfw_http_start ,
8009
+ .stop = tfw_http_stop ,
7966
8010
.specs = tfw_http_specs ,
7967
8011
};
7968
8012
0 commit comments