Skip to content

Commit 81dd5d5

Browse files
symstusymstu-tempesta
authored andcommitted
Renamed JA5 hashes to TF hashes
1 parent 70cd8ee commit 81dd5d5

29 files changed

+345
-352
lines changed

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Tempesta WebShield
22

3-
Block users by JA5T, JA5H, or IP based on Tempesta FW access
3+
Block users by TFT, TFH, or IP based on Tempesta FW access
44
logs stored in the ClickHouse database.
55

66
[**WIKI**](https://tempesta-tech.com/knowledge-base/Bot-Protection/)
@@ -59,19 +59,19 @@ isort .
5959
# How to block
6060

6161
### Prepare Tempesta FW config
62-
It's useful to define separate directories for different groups of JA5 hashes
62+
It's useful to define separate directories for different groups of TF hashes
6363
in the Tempesta FW configuration file (/etc/tempesta/tempesta_fw.conf).
6464
```nginx
65-
ja5t {
66-
!include /etc/tempesta/ja5t/
65+
tft {
66+
!include /etc/tempesta/tft/
6767
}
68-
ja5h {
69-
!include /etc/tempesta/ja5h/
68+
tfh {
69+
!include /etc/tempesta/tfh/
7070
}
7171
```
7272
Then add 2 files
73-
- /etc/tempesta/ja5t/blocked.conf
74-
- /etc/tempesta/ja5h/blocked.conf
73+
- /etc/tempesta/tft/blocked.conf
74+
- /etc/tempesta/tfh/blocked.conf
7575

7676
These files should be used by default by the WebShield
7777
to add new blocking hashes.

app.py

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@
1313
IPErrorRequestDetector,
1414
IPRPSDetector,
1515
)
16-
from detectors.ja5t import (
17-
Ja5tAccumulativeTimeDetector,
18-
Ja5tErrorRequestDetector,
19-
Ja5tRPSDetector,
16+
from detectors.tft import (
17+
TFtAccumulativeTimeDetector,
18+
TFtErrorRequestDetector,
19+
TFtRPSDetector,
2020
)
21-
from detectors.ja5h import (
22-
Ja5hAccumulativeTimeDetector,
23-
Ja5hErrorRequestDetector,
24-
Ja5hRPSDetector,
21+
from detectors.tfh import (
22+
TFhAccumulativeTimeDetector,
23+
TFhErrorRequestDetector,
24+
TFhRPSDetector,
2525
)
2626
from utils.access_log import ClickhouseAccessLog
27-
from utils.ja5_config import Ja5Config
27+
from utils.tf_config import TFConfig
2828
from utils.logger import logger
2929
from utils.user_agents import UserAgentsManager
3030

@@ -50,13 +50,13 @@
5050
)
5151
context = AppContext(
5252
blockers={
53-
blockers.Ja5tBlocker.name(): blockers.Ja5tBlocker(
54-
config=Ja5Config(file_path=app_config.path_to_ja5t_config),
53+
blockers.TFtBlocker.name(): blockers.TFtBlocker(
54+
config=TFConfig(file_path=app_config.path_to_tft_config),
5555
tempesta_executable_path=app_config.tempesta_executable_path,
5656
tempesta_config_path=app_config.tempesta_config_path,
5757
),
58-
blockers.Ja5hBlocker.name(): blockers.Ja5hBlocker(
59-
config=Ja5Config(file_path=app_config.path_to_ja5h_config),
58+
blockers.TFhBlocker.name(): blockers.TFhBlocker(
59+
config=TFConfig(file_path=app_config.path_to_tfh_config),
6060
tempesta_executable_path=app_config.tempesta_executable_path,
6161
tempesta_config_path=app_config.tempesta_config_path,
6262
),
@@ -87,43 +87,43 @@
8787
block_users_per_iteration=app_config.detector_ip_errors_block_users_per_iteration,
8888
allowed_statues=app_config.detector_ip_errors_allowed_statuses,
8989
),
90-
Ja5tRPSDetector.name(): Ja5tRPSDetector(
90+
TFtRPSDetector.name(): TFtRPSDetector(
9191
access_log=clickhouse_client,
92-
default_threshold=app_config.detector_ja5t_rps_default_threshold,
93-
intersection_percent=app_config.detector_ja5t_rps_intersection_percent,
94-
block_users_per_iteration=app_config.detector_ja5t_rps_block_users_per_iteration,
92+
default_threshold=app_config.detector_tft_rps_default_threshold,
93+
intersection_percent=app_config.detector_tft_rps_intersection_percent,
94+
block_users_per_iteration=app_config.detector_tft_rps_block_users_per_iteration,
9595
),
96-
Ja5tAccumulativeTimeDetector.name(): Ja5tAccumulativeTimeDetector(
96+
TFtAccumulativeTimeDetector.name(): TFtAccumulativeTimeDetector(
9797
access_log=clickhouse_client,
98-
default_threshold=app_config.detector_ja5t_time_default_threshold,
99-
intersection_percent=app_config.detector_ja5t_time_intersection_percent,
100-
block_users_per_iteration=app_config.detector_ja5t_time_block_users_per_iteration,
98+
default_threshold=app_config.detector_tft_time_default_threshold,
99+
intersection_percent=app_config.detector_tft_time_intersection_percent,
100+
block_users_per_iteration=app_config.detector_tft_time_block_users_per_iteration,
101101
),
102-
Ja5tErrorRequestDetector.name(): Ja5tErrorRequestDetector(
102+
TFtErrorRequestDetector.name(): TFtErrorRequestDetector(
103103
access_log=clickhouse_client,
104-
default_threshold=app_config.detector_ja5t_errors_default_threshold,
105-
intersection_percent=app_config.detector_ja5t_errors_intersection_percent,
106-
block_users_per_iteration=app_config.detector_ja5t_errors_block_users_per_iteration,
107-
allowed_statues=app_config.detector_ja5t_errors_allowed_statuses,
104+
default_threshold=app_config.detector_tft_errors_default_threshold,
105+
intersection_percent=app_config.detector_tft_errors_intersection_percent,
106+
block_users_per_iteration=app_config.detector_tft_errors_block_users_per_iteration,
107+
allowed_statues=app_config.detector_tft_errors_allowed_statuses,
108108
),
109-
Ja5hRPSDetector.name(): Ja5hRPSDetector(
109+
TFhRPSDetector.name(): TFhRPSDetector(
110110
access_log=clickhouse_client,
111-
default_threshold=app_config.detector_ja5h_rps_default_threshold,
112-
intersection_percent=app_config.detector_ja5h_rps_intersection_percent,
113-
block_users_per_iteration=app_config.detector_ja5h_rps_block_users_per_iteration,
111+
default_threshold=app_config.detector_tfh_rps_default_threshold,
112+
intersection_percent=app_config.detector_tfh_rps_intersection_percent,
113+
block_users_per_iteration=app_config.detector_tfh_rps_block_users_per_iteration,
114114
),
115-
Ja5hAccumulativeTimeDetector.name(): Ja5hAccumulativeTimeDetector(
115+
TFhAccumulativeTimeDetector.name(): TFhAccumulativeTimeDetector(
116116
access_log=clickhouse_client,
117-
default_threshold=app_config.detector_ja5h_time_default_threshold,
118-
intersection_percent=app_config.detector_ja5h_time_intersection_percent,
119-
block_users_per_iteration=app_config.detector_ja5h_time_block_users_per_iteration,
117+
default_threshold=app_config.detector_tfh_time_default_threshold,
118+
intersection_percent=app_config.detector_tfh_time_intersection_percent,
119+
block_users_per_iteration=app_config.detector_tfh_time_block_users_per_iteration,
120120
),
121-
Ja5hErrorRequestDetector.name(): Ja5tErrorRequestDetector(
121+
TFhErrorRequestDetector.name(): TFtErrorRequestDetector(
122122
access_log=clickhouse_client,
123-
default_threshold=app_config.detector_ja5h_errors_default_threshold,
124-
intersection_percent=app_config.detector_ja5h_errors_intersection_percent,
125-
block_users_per_iteration=app_config.detector_ja5h_errors_block_users_per_iteration,
126-
allowed_statues=app_config.detector_ja5h_errors_allowed_statuses,
123+
default_threshold=app_config.detector_tfh_errors_default_threshold,
124+
intersection_percent=app_config.detector_tfh_errors_intersection_percent,
125+
block_users_per_iteration=app_config.detector_tfh_errors_block_users_per_iteration,
126+
allowed_statues=app_config.detector_tfh_errors_allowed_statuses,
127127
),
128128
GeoIPDetector.name(): GeoIPDetector(
129129
access_log=clickhouse_client,

blockers/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .ipset import IpSetBlocker
2-
from .ja5h import Ja5hBlocker
3-
from .ja5t import Ja5tBlocker
2+
from .tfh import TFhBlocker
3+
from .tft import TFtBlocker
44
from .nft import NFTBlocker
55

66
__author__ = "Tempesta Technologies, Inc."

blockers/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def release(self, user: User):
5353
def apply(self):
5454
"""
5555
Apply blocking rules. Some blockers may block immediately
56-
without calling this method, but others — like ja5t — apply
56+
without calling this method, but others — like tft — apply
5757
rules only after multiple config changes.
5858
"""
5959

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
11
import time
22

3-
from blockers.ja5t import Ja5tBlocker
3+
from blockers.tft import TFtBlocker
44
from utils.datatypes import User
5-
from utils.ja5_config import Ja5Hash
5+
from utils.tf_config import TFHash
66
from utils.logger import logger
77

88
__author__ = "Tempesta Technologies, Inc."
99
__copyright__ = "Copyright (C) 2023-2025 Tempesta Technologies, Inc."
1010
__license__ = "GPL2"
1111

1212

13-
class Ja5hBlocker(Ja5tBlocker):
13+
class TFhBlocker(TFtBlocker):
1414

1515
@staticmethod
1616
def name() -> str:
17-
return "ja5h"
17+
return "tfh"
1818

1919
def load(self) -> dict[int, User]:
2020
self.config.load()
2121
current_time = int(time.time())
2222
result = dict()
2323

2424
for hash_value in self.config.hashes:
25-
user = User(ja5h=[hash_value], blocked_at=current_time)
25+
user = User(tfh=[hash_value], blocked_at=current_time)
2626
result[hash(user)] = user
2727

2828
return result
2929

3030
def block(self, user: User):
31-
if self.config.exists(user.ja5h[0]):
31+
if self.config.exists(user.tfh[0]):
3232
return None
3333

34-
self.config.add(Ja5Hash(value=user.ja5h[0], packets=0, connections=0))
35-
logger.warning(f"Blocked user {user} by ja5h")
34+
self.config.add(TFHash(value=user.tfh[0], packets=0, connections=0))
35+
logger.warning(f"Blocked user {user} by tfh")
3636

3737
def release(self, user: User):
38-
if not self.config.exists(user.ja5h[0]):
38+
if not self.config.exists(user.tfh[0]):
3939
return None
4040

41-
self.config.remove(user.ja5h[0])
41+
self.config.remove(user.tfh[0])
4242

4343
def info(self) -> list[User]:
44-
return [User(ja5h=[ja5_hash.value]) for ja5_hash in self.config.hashes.values()]
44+
return [User(tfh=[tf_hash.value]) for tf_hash in self.config.hashes.values()]

blockers/ja5t.py renamed to blockers/tft.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from blockers.base import BaseBlocker, PreparationError
55
from utils.datatypes import User
6-
from utils.ja5_config import Ja5Config, Ja5Hash
6+
from utils.tf_config import TFConfig, TFHash
77
from utils.logger import logger
88
from utils.shell import run_in_shell
99

@@ -12,10 +12,10 @@
1212
__license__ = "GPL2"
1313

1414

15-
class Ja5tBlocker(BaseBlocker):
15+
class TFtBlocker(BaseBlocker):
1616
def __init__(
1717
self,
18-
config: Ja5Config,
18+
config: TFConfig,
1919
tempesta_executable_path: str = None,
2020
tempesta_config_path: str = None,
2121
):
@@ -25,7 +25,7 @@ def __init__(
2525

2626
@staticmethod
2727
def name() -> str:
28-
return "ja5t"
28+
return "tft"
2929

3030
def __tempesta_app_exists(self) -> bool:
3131
if self.tempesta_executable_path and os.path.isfile(
@@ -53,21 +53,21 @@ def load(self) -> dict[int, User]:
5353
result = dict()
5454

5555
for hash_value in self.config.hashes:
56-
user = User(ja5t=[hash_value], blocked_at=current_time)
56+
user = User(tft=[hash_value], blocked_at=current_time)
5757
result[hash(user)] = user
5858

5959
return result
6060

6161
def block(self, user: User):
62-
for hash_value in user.ja5t:
62+
for hash_value in user.tft:
6363
if self.config.exists(hash_value):
6464
continue
6565

66-
self.config.add(Ja5Hash(value=hash_value, packets=0, connections=0))
67-
logger.warning(f"Blocked user {user} by ja5t")
66+
self.config.add(TFHash(value=hash_value, packets=0, connections=0))
67+
logger.warning(f"Blocked user {user} by tft")
6868

6969
def release(self, user: User):
70-
for hash_value in user.ja5t:
70+
for hash_value in user.tft:
7171
if not self.config.exists(hash_value):
7272
continue
7373

@@ -93,4 +93,4 @@ def apply(self):
9393
)
9494

9595
def info(self) -> list[User]:
96-
return [User(ja5t=[ja5_hash.value]) for ja5_hash in self.config.hashes.values()]
96+
return [User(tft=[tf_hash.value]) for tf_hash in self.config.hashes.values()]

config.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010

1111
class AppConfig(BaseSettings):
12-
path_to_ja5t_config: str = "/etc/tempesta/ja5t/blocked.conf"
13-
path_to_ja5h_config: str = "/etc/tempesta/ja5h/blocked.conf"
12+
path_to_tft_config: str = "/etc/tempesta/tft/blocked.conf"
13+
path_to_tfh_config: str = "/etc/tempesta/tfh/blocked.conf"
1414

1515
clickhouse_host: str = "192.168.0.104"
1616
clickhouse_port: int = 8123
@@ -28,17 +28,17 @@ class AppConfig(BaseSettings):
2828
"ip_rps",
2929
"ip_time",
3030
"ip_errors",
31-
"ja5t_rps",
32-
"ja5t_time",
33-
"ja5t_errors",
34-
"ja5h_rps",
35-
"ja5h_time",
36-
"ja5h_errors",
31+
"tft_rps",
32+
"tft_time",
33+
"tft_errors",
34+
"tfh_rps",
35+
"tfh_time",
36+
"tfh_errors",
3737
"geoip",
3838
]
39-
] = {"ja5t_rps", "ja5t_time", "ja5t_errors"}
39+
] = {"tft_rps", "tft_time", "tft_errors"}
4040

41-
blocking_types: set[Literal["ja5t", "ja5h", "ipset", "nftables"]] = {"ja5t"}
41+
blocking_types: set[Literal["tft", "tfh", "ipset", "nftables"]] = {"tft"}
4242
blocking_window_duration_sec: int = 10
4343
blocking_ipset_name: str = "tempesta_blocked_ips"
4444
blocking_time_min: int = 60
@@ -77,18 +77,18 @@ class AppConfig(BaseSettings):
7777
403,
7878
]
7979

80-
detector_ja5t_rps_default_threshold: Decimal = Decimal(10)
81-
detector_ja5t_rps_intersection_percent: Decimal = Decimal(10)
82-
detector_ja5t_rps_block_users_per_iteration: Decimal = Decimal(10)
80+
detector_tft_rps_default_threshold: Decimal = Decimal(10)
81+
detector_tft_rps_intersection_percent: Decimal = Decimal(10)
82+
detector_tft_rps_block_users_per_iteration: Decimal = Decimal(10)
8383

84-
detector_ja5t_time_default_threshold: Decimal = Decimal(10)
85-
detector_ja5t_time_intersection_percent: Decimal = Decimal(10)
86-
detector_ja5t_time_block_users_per_iteration: Decimal = Decimal(10)
84+
detector_tft_time_default_threshold: Decimal = Decimal(10)
85+
detector_tft_time_intersection_percent: Decimal = Decimal(10)
86+
detector_tft_time_block_users_per_iteration: Decimal = Decimal(10)
8787

88-
detector_ja5t_errors_default_threshold: Decimal = Decimal(10)
89-
detector_ja5t_errors_intersection_percent: Decimal = Decimal(10)
90-
detector_ja5t_errors_block_users_per_iteration: Decimal = Decimal(10)
91-
detector_ja5t_errors_allowed_statuses: list[int] = [
88+
detector_tft_errors_default_threshold: Decimal = Decimal(10)
89+
detector_tft_errors_intersection_percent: Decimal = Decimal(10)
90+
detector_tft_errors_block_users_per_iteration: Decimal = Decimal(10)
91+
detector_tft_errors_allowed_statuses: list[int] = [
9292
100,
9393
101,
9494
200,
@@ -107,18 +107,18 @@ class AppConfig(BaseSettings):
107107
403,
108108
]
109109

110-
detector_ja5h_rps_default_threshold: Decimal = Decimal(10)
111-
detector_ja5h_rps_intersection_percent: Decimal = Decimal(10)
112-
detector_ja5h_rps_block_users_per_iteration: Decimal = Decimal(10)
110+
detector_tfh_rps_default_threshold: Decimal = Decimal(10)
111+
detector_tfh_rps_intersection_percent: Decimal = Decimal(10)
112+
detector_tfh_rps_block_users_per_iteration: Decimal = Decimal(10)
113113

114-
detector_ja5h_time_default_threshold: Decimal = Decimal(10)
115-
detector_ja5h_time_intersection_percent: Decimal = Decimal(10)
116-
detector_ja5h_time_block_users_per_iteration: Decimal = Decimal(10)
114+
detector_tfh_time_default_threshold: Decimal = Decimal(10)
115+
detector_tfh_time_intersection_percent: Decimal = Decimal(10)
116+
detector_tfh_time_block_users_per_iteration: Decimal = Decimal(10)
117117

118-
detector_ja5h_errors_default_threshold: Decimal = Decimal(10)
119-
detector_ja5h_errors_intersection_percent: Decimal = Decimal(10)
120-
detector_ja5h_errors_block_users_per_iteration: Decimal = Decimal(10)
121-
detector_ja5h_errors_allowed_statuses: list[int] = [
118+
detector_tfh_errors_default_threshold: Decimal = Decimal(10)
119+
detector_tfh_errors_intersection_percent: Decimal = Decimal(10)
120+
detector_tfh_errors_block_users_per_iteration: Decimal = Decimal(10)
121+
detector_tfh_errors_allowed_statuses: list[int] = [
122122
100,
123123
101,
124124
200,

0 commit comments

Comments
 (0)