mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2: autohostlist incoming failure triggers change
This commit is contained in:
@@ -85,3 +85,5 @@ v0.7
|
||||
|
||||
* nfqws2, zapret-lib : fix non-working % and # arg substitution under orchestrator
|
||||
* nfqws2, zapret-lib : structure conntrack in/out positions. pass in desync.track.pos.{client,server,direct,reverse} position tables
|
||||
* nfqws2: autohostlist: trigger RST and http redirect failures only within specified relative sequence
|
||||
* nfqws2: autohostlist: trigger http redirect failure if payload is http_req without connection proto check
|
||||
|
||||
@@ -140,7 +140,7 @@ static void ConntrackApplyPos(const struct tcphdr *tcp, t_ctrack *t, bool bRever
|
||||
scale = tcp_find_scale_factor(tcp);
|
||||
mss = ntohs(tcp_find_mss(tcp));
|
||||
|
||||
direct->seq_last = ntohl(tcp->th_seq);
|
||||
direct->seq_last = ntohl(tcp->th_seq);
|
||||
direct->pos = direct->seq_last + len_payload;
|
||||
reverse->pos = reverse->seq_last = ntohl(tcp->th_ack);
|
||||
if (t->pos.state == SYN)
|
||||
|
||||
@@ -63,7 +63,7 @@ typedef struct
|
||||
bool dp_search_complete;
|
||||
|
||||
uint8_t req_retrans_counter; // number of request retransmissions
|
||||
bool retrans_detect_finalized;
|
||||
bool failure_detect_finalized;
|
||||
|
||||
uint8_t incoming_ttl;
|
||||
|
||||
|
||||
@@ -252,12 +252,12 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho
|
||||
{
|
||||
if (l4proto == IPPROTO_TCP)
|
||||
{
|
||||
if (ctrack->retrans_detect_finalized)
|
||||
if (ctrack->failure_detect_finalized)
|
||||
return false;
|
||||
if (!seq_within(ctrack->pos.client.seq_last, ctrack->pos.client.seq0, ctrack->pos.client.seq0 + ctrack->dp->hostlist_auto_retrans_maxseq))
|
||||
{
|
||||
ctrack->retrans_detect_finalized = true;
|
||||
DLOG("retrans : tcp seq %u not within the req range %u-%u. stop tracking.\n", ctrack->pos.client.seq_last, ctrack->pos.client.seq0, ctrack->pos.client.seq0 + ctrack->dp->hostlist_auto_retrans_maxseq);
|
||||
ctrack->failure_detect_finalized = true;
|
||||
DLOG("retrans : tcp seq %u not within range %u-%u. stop tracking.\n", ctrack->pos.client.seq_last, ctrack->pos.client.seq0, ctrack->pos.client.seq0 + ctrack->dp->hostlist_auto_retrans_maxseq);
|
||||
ctrack_stop_retrans_counter(ctrack);
|
||||
auto_hostlist_reset_fail_counter(ctrack->dp, ctrack->hostname, client_ip_port, l7proto);
|
||||
return false;
|
||||
@@ -270,7 +270,7 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho
|
||||
{
|
||||
DLOG("retrans threshold reached : %u/%u\n", ctrack->req_retrans_counter, threshold);
|
||||
ctrack_stop_retrans_counter(ctrack);
|
||||
ctrack->retrans_detect_finalized = true;
|
||||
ctrack->failure_detect_finalized = true;
|
||||
return true;
|
||||
}
|
||||
DLOG("retrans counter : %u/%u\n", ctrack->req_retrans_counter, threshold);
|
||||
@@ -1097,49 +1097,48 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
// process reply packets for auto hostlist mode
|
||||
// by looking at RSTs or HTTP replies we decide whether original request looks like DPI blocked
|
||||
// we only process first-sequence replies. do not react to subsequent redirects or RSTs
|
||||
if (!params.server && ctrack && ctrack->hostname && ctrack->hostname_ah_check && (ctrack->pos.server.seq_last - ctrack->pos.server.seq0) == 1)
|
||||
if (!params.server && ctrack && ctrack->hostname_ah_check && !ctrack->failure_detect_finalized)
|
||||
{
|
||||
bool bFail = false;
|
||||
|
||||
char client_ip_port[48];
|
||||
if (*params.hostlist_auto_debuglog)
|
||||
ntop46_port((struct sockaddr*)&dst, client_ip_port, sizeof(client_ip_port));
|
||||
else
|
||||
*client_ip_port = 0;
|
||||
if (seq_within(ctrack->pos.server.seq_last, ctrack->pos.server.seq0, ctrack->pos.server.seq0 + dp->hostlist_auto_incoming_maxseq))
|
||||
{
|
||||
bool bFail = false;
|
||||
uint32_t rseq = ctrack->pos.server.seq_last - ctrack->pos.server.seq0;
|
||||
|
||||
if (dis->tcp->th_flags & TH_RST)
|
||||
{
|
||||
DLOG("incoming RST detected for hostname %s\n", ctrack->hostname);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : incoming RST", ctrack->hostname, ctrack->dp->n, PROFILE_NAME(dp), client_ip_port, l7proto_str(l7proto));
|
||||
bFail = true;
|
||||
}
|
||||
else if (dis->len_payload && l7proto == L7_HTTP)
|
||||
{
|
||||
if (l7payload == L7P_HTTP_REPLY)
|
||||
if (dis->tcp->th_flags & TH_RST)
|
||||
{
|
||||
DLOG("incoming HTTP reply detected for hostname %s\n", ctrack->hostname);
|
||||
DLOG("incoming RST detected for hostname %s rseq %u\n", ctrack->hostname, rseq);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : rseq %u : incoming RST", ctrack->hostname, ctrack->dp->n, PROFILE_NAME(dp), client_ip_port, l7proto_str(l7proto), rseq);
|
||||
bFail = true;
|
||||
}
|
||||
else if (dis->len_payload && l7payload == L7P_HTTP_REPLY)
|
||||
{
|
||||
DLOG("incoming HTTP reply detected for hostname %s rseq\n", ctrack->hostname, rseq);
|
||||
bFail = HttpReplyLooksLikeDPIRedirect(dis->data_payload, dis->len_payload, ctrack->hostname);
|
||||
if (bFail)
|
||||
{
|
||||
DLOG("redirect to another domain detected. possibly DPI redirect.\n");
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : redirect to another domain", ctrack->hostname, ctrack->dp->n, PROFILE_NAME(dp), client_ip_port, l7proto_str(l7proto));
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : rseq %u : redirect to another domain", ctrack->hostname, ctrack->dp->n, PROFILE_NAME(dp), client_ip_port, l7proto_str(l7proto), rseq);
|
||||
}
|
||||
else
|
||||
DLOG("local or in-domain redirect detected. it's not a DPI redirect.\n");
|
||||
}
|
||||
else
|
||||
if (bFail)
|
||||
{
|
||||
// received not http reply. do not monitor this connection anymore
|
||||
DLOG("incoming unknown HTTP data detected for hostname %s\n", ctrack->hostname);
|
||||
auto_hostlist_failed(dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, l7proto);
|
||||
ctrack->failure_detect_finalized = true;
|
||||
}
|
||||
}
|
||||
if (bFail)
|
||||
auto_hostlist_failed(dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, l7proto);
|
||||
else
|
||||
if (dis->len_payload)
|
||||
auto_hostlist_reset_fail_counter(dp, ctrack->hostname, client_ip_port, l7proto);
|
||||
if (dis->tcp->th_flags & TH_RST)
|
||||
ctrack->hostname_ah_check = false; // do not react to further dup RSTs
|
||||
{
|
||||
// incoming_maxseq exceeded. treat connection as successful
|
||||
auto_hostlist_reset_fail_counter(dp, ctrack->hostname, client_ip_port, l7proto);
|
||||
ctrack->failure_detect_finalized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// not reverse
|
||||
|
||||
@@ -1435,6 +1435,7 @@ static void exithelp(void)
|
||||
" --hostlist-auto-fail-time=<int>\t\t\t; all failed attemps must be within these seconds (default : %d)\n"
|
||||
" --hostlist-auto-retrans-threshold=<int>\t\t; how many request retransmissions cause attempt to fail (default : %d)\n"
|
||||
" --hostlist-auto-retrans-maxseq=<int>\t\t\t; count retransmissions only within this relative sequence (default : %u)\n"
|
||||
" --hostlist-auto-incoming-maxseq=<int>\t\t\t; treat tcp connection as successful if incoming relative sequence exceedes this threshold (default : %u)\n"
|
||||
" --hostlist-auto-debug=<logfile>\t\t\t; debug auto hostlist positives (global parameter)\n"
|
||||
"\nLUA PACKET PASS MODE:\n"
|
||||
" --payload=type[,type]\t\t\t\t\t; set payload types following LUA functions should process : %s\n"
|
||||
@@ -1450,7 +1451,8 @@ static void exithelp(void)
|
||||
LUA_GC_INTERVAL,
|
||||
all_protos,
|
||||
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT,
|
||||
HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT, HOSTLIST_AUTO_RETRANS_MAXSEQ,
|
||||
HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT,
|
||||
HOSTLIST_AUTO_RETRANS_MAXSEQ, HOSTLIST_AUTO_INCOMING_MAXSEQ,
|
||||
all_payloads
|
||||
);
|
||||
exit(1);
|
||||
@@ -1548,6 +1550,7 @@ enum opt_indices {
|
||||
IDX_HOSTLIST_AUTO_FAIL_TIME,
|
||||
IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD,
|
||||
IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ,
|
||||
IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ,
|
||||
IDX_HOSTLIST_AUTO_DEBUG,
|
||||
IDX_NEW,
|
||||
IDX_SKIP,
|
||||
@@ -1633,6 +1636,7 @@ static const struct option long_options[] = {
|
||||
[IDX_HOSTLIST_AUTO_FAIL_TIME] = {"hostlist-auto-fail-time", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD] = {"hostlist-auto-retrans-threshold", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ] = {"hostlist-auto-retrans-maxseq", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ] = {"hostlist-auto-incoming-maxseq", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_DEBUG] = {"hostlist-auto-debug", required_argument, 0, 0},
|
||||
[IDX_NEW] = {"new", no_argument, 0, 0},
|
||||
[IDX_SKIP] = {"skip", no_argument, 0, 0},
|
||||
@@ -2100,6 +2104,9 @@ int main(int argc, char **argv)
|
||||
case IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ:
|
||||
dp->hostlist_auto_retrans_maxseq = (uint32_t)atoi(optarg);
|
||||
break;
|
||||
case IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ:
|
||||
dp->hostlist_auto_incoming_maxseq = (uint32_t)atoi(optarg);
|
||||
break;
|
||||
case IDX_HOSTLIST_AUTO_DEBUG:
|
||||
{
|
||||
FILE *F = fopen(optarg, "a+t");
|
||||
|
||||
@@ -343,6 +343,7 @@ void dp_init(struct desync_profile *dp)
|
||||
dp->hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
||||
dp->hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
|
||||
dp->hostlist_auto_retrans_maxseq = HOSTLIST_AUTO_RETRANS_MAXSEQ;
|
||||
dp->hostlist_auto_incoming_maxseq = HOSTLIST_AUTO_INCOMING_MAXSEQ;
|
||||
dp->filter_ipv4 = dp->filter_ipv6 = true;
|
||||
}
|
||||
static void dp_clear_dynamic(struct desync_profile *dp)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||
#define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3
|
||||
#define HOSTLIST_AUTO_RETRANS_MAXSEQ 65536
|
||||
#define HOSTLIST_AUTO_INCOMING_MAXSEQ 4096
|
||||
|
||||
#define IPCACHE_LIFETIME 7200
|
||||
|
||||
@@ -79,7 +80,7 @@ struct desync_profile
|
||||
// pointer to autohostlist. NULL if no autohostlist for the profile.
|
||||
struct hostlist_file *hostlist_auto;
|
||||
int hostlist_auto_fail_threshold, hostlist_auto_fail_time, hostlist_auto_retrans_threshold;
|
||||
uint32_t hostlist_auto_retrans_maxseq;
|
||||
uint32_t hostlist_auto_retrans_maxseq, hostlist_auto_incoming_maxseq;
|
||||
|
||||
hostfail_pool *hostlist_auto_fail_counters;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user