DNS: evaluate all flow risks even if sub-classification is disabled (#2714)

This commit is contained in:
Ivan Nardi 2025-02-11 13:16:03 +01:00 committed by GitHub
parent 65c224e19c
commit d738b60cac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 76 additions and 48 deletions

View file

@ -67,7 +67,7 @@ List of the supported configuration options:
| "stun" | "metadata.attribute.relayed_address" | enable | NULL | NULL | Enable/disable extraction of (xor-)relayed-address attribute for STUN flows. If it is disabled, STUN classification might be significant faster |
| "stun" | "metadata.attribute.peer_address" | enable | NULL | NULL | Enable/disable extraction of (xor-)peer-address attribute for STUN flows. If it is disabled, STUN classification might be significant faster; however sub-classification capability might be negatively impacted |
| "bittorrent" | "metadata.hash" | enable | NULL | NULL | Enable/disable extraction of hash metadata for Bittorrent flows. |
| "dns" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of DNS flows (via query/response domain name). If disabled, some flow risks are not checked |
| "dns" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of DNS flows (via query/response domain name). |
| "dns" | "process_response" | enable | NULL | NULL | Enable/disable processing of DNS responses. By default, DNS flows are fully classified after the first request/response pair (or after the first response, if the request is missing). If this parameter is disabled, the flows are fully classified after the first packet, i.e. usually after the first request; in that case, some flow risks are not checked and some metadata are not exported |
| "http" | "process_response" | enable | NULL | NULL | Enable/disable processing of HTTP responses. By default, HTTP flows are usually fully classified after the first request/response pair. If this parameter is disabled, the flows are fully classified after the first request (or after the first response, if the request is missing); in that case, some flow risks are not checked and some metadata are not exported |
| "http" | "subclassification" | enable | NULL | NULL | Enable/disable sub-classification of HTTP flows |

View file

@ -488,6 +488,7 @@ extern "C" {
* @par string_to_match_len = the length of the string
* @par ret_match = completed returned match information
* @par master_protocol_id = value of the ID associated to the master protocol detected
* @par update_flow_classification = update or not protocol (sub)classification
* @return the ID of the matched subprotocol
*
*/
@ -496,7 +497,8 @@ extern "C" {
char *string_to_match,
u_int string_to_match_len,
ndpi_protocol_match_result *ret_match,
u_int16_t master_protocol_id);
u_int16_t master_protocol_id,
int update_flow_classification);
/**
* Check if the string content passed match with a protocol

View file

@ -10413,7 +10413,8 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_
struct ndpi_flow_struct *flow,
char *string_to_match, u_int string_to_match_len,
ndpi_protocol_match_result *ret_match,
u_int16_t master_protocol_id) {
u_int16_t master_protocol_id,
int update_flow_classification) {
u_int16_t rc;
ndpi_protocol_category_t id;
@ -10421,7 +10422,7 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_
memset(ret_match, 0, sizeof(*ret_match));
rc = ndpi_automa_match_string_subprotocol(ndpi_str, flow,
rc = ndpi_automa_match_string_subprotocol(ndpi_str, update_flow_classification ? flow : NULL,
string_to_match, string_to_match_len,
master_protocol_id, ret_match);
id = ret_match->protocol_category;
@ -10430,13 +10431,12 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_
string_to_match_len, &id) != -1) {
/* if(id != -1) */ {
ret_match->protocol_category = id;
if(flow)
flow->category = id;
flow->category = id;
rc = master_protocol_id;
}
}
if(flow && ndpi_str->risky_domain_automa.ac_automa != NULL) {
if(ndpi_str->risky_domain_automa.ac_automa != NULL) {
u_int32_t proto_id;
u_int16_t rc1 = ndpi_match_string_common(ndpi_str->risky_domain_automa.ac_automa,
string_to_match, string_to_match_len,
@ -10450,7 +10450,7 @@ u_int16_t ndpi_match_host_subprotocol(struct ndpi_detection_module_struct *ndpi_
}
/* Add punycode check */
if(flow && ndpi_check_punycode_string(string_to_match, string_to_match_len)) {
if(ndpi_check_punycode_string(string_to_match, string_to_match_len)) {
char str[64] = { '\0' };
strncpy(str, string_to_match, ndpi_min(string_to_match_len, sizeof(str)-1));
@ -10477,7 +10477,7 @@ int ndpi_match_hostname_protocol(struct ndpi_detection_module_struct *ndpi_struc
what = name, what_len = name_len;
subproto = ndpi_match_host_subprotocol(ndpi_struct, flow, what, what_len,
&ret_match, master_protocol);
&ret_match, master_protocol, 1);
if(subproto != NDPI_PROTOCOL_UNKNOWN) {
ndpi_set_detected_protocol(ndpi_struct, flow, subproto, master_protocol, NDPI_CONFIDENCE_DPI);

View file

@ -801,44 +801,39 @@ static void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, st
}
}
if(len > 0) {
if(ndpi_struct->cfg.dns_subclassification_enabled || ndpi_struct->cfg.fpc_enabled) {
ndpi_protocol_match_result ret_match;
if(strlen(flow->host_server_name) > 0) {
ndpi_protocol_match_result ret_match;
/* Avoid writing on flow (i.e. updating classification) if subclassification is disabled */
ret.proto.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, ndpi_struct->cfg.dns_subclassification_enabled ? flow : NULL,
flow->host_server_name,
strlen(flow->host_server_name),
&ret_match,
NDPI_PROTOCOL_DNS);
/* Add to FPC DNS cache */
if(ndpi_struct->cfg.fpc_enabled &&
ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN &&
ret.proto.app_protocol != NDPI_PROTOCOL_DNS &&
(flow->protos.dns.rsp_type == 0x1 || flow->protos.dns.rsp_type == 0x1c) && /* A, AAAA */
ndpi_struct->fpc_dns_cache) {
ndpi_lru_add_to_cache(ndpi_struct->fpc_dns_cache,
fpc_dns_cache_key_from_dns_info(flow), ret.proto.app_protocol,
ndpi_get_current_time(flow));
}
if(!ndpi_struct->cfg.dns_subclassification_enabled)
ret.proto.app_protocol = NDPI_PROTOCOL_UNKNOWN;
if(ret.proto.app_protocol == NDPI_PROTOCOL_UNKNOWN)
ret.proto.master_protocol = checkDNSSubprotocol(s_port, d_port);
else
ret.proto.master_protocol = NDPI_PROTOCOL_DNS;
ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0);
} else {
ret.proto.master_protocol = checkDNSSubprotocol(s_port, d_port);
ret.proto.app_protocol = NDPI_PROTOCOL_UNKNOWN;
/* Avoid updating classification if subclassification is disabled */
ret.proto.app_protocol = ndpi_match_host_subprotocol(ndpi_struct, flow,
flow->host_server_name,
strlen(flow->host_server_name),
&ret_match,
NDPI_PROTOCOL_DNS,
ndpi_struct->cfg.dns_subclassification_enabled ? 1 : 0);
/* Add to FPC DNS cache */
if(ndpi_struct->cfg.fpc_enabled &&
ret.proto.app_protocol != NDPI_PROTOCOL_UNKNOWN &&
ret.proto.app_protocol != NDPI_PROTOCOL_DNS &&
(flow->protos.dns.rsp_type == 0x1 || flow->protos.dns.rsp_type == 0x1c) && /* A, AAAA */
ndpi_struct->fpc_dns_cache) {
ndpi_lru_add_to_cache(ndpi_struct->fpc_dns_cache,
fpc_dns_cache_key_from_dns_info(flow), ret.proto.app_protocol,
ndpi_get_current_time(flow));
}
if(!ndpi_struct->cfg.dns_subclassification_enabled)
ret.proto.app_protocol = NDPI_PROTOCOL_UNKNOWN;
if(ret.proto.app_protocol == NDPI_PROTOCOL_UNKNOWN)
ret.proto.master_protocol = checkDNSSubprotocol(s_port, d_port);
else
ret.proto.master_protocol = NDPI_PROTOCOL_DNS;
ndpi_check_dga_name(ndpi_struct, flow, flow->host_server_name, 1, 0);
/* Category is always NDPI_PROTOCOL_CATEGORY_NETWORK, regardless of the subprotocol */
flow->category = NDPI_PROTOCOL_CATEGORY_NETWORK;
}
/* Report if this is a DNS query or reply */

View file

@ -210,7 +210,7 @@ static void ndpi_search_fastcgi(struct ndpi_detection_module_struct *ndpi_struct
ndpi_match_host_subprotocol(ndpi_struct, flow,
flow->host_server_name,
strlen(flow->host_server_name),
&ret_match, NDPI_PROTOCOL_FASTCGI);
&ret_match, NDPI_PROTOCOL_FASTCGI, 1);
ndpi_check_dga_name(ndpi_struct, flow,
flow->host_server_name, 1, 0);
if(ndpi_is_valid_hostname((char *)packet->host_line.ptr,

View file

@ -571,7 +571,7 @@ static void ndpi_http_parse_subprotocol(struct ndpi_detection_module_struct *ndp
origin_hostname,
origin_hostname_len,
&ret_match,
master_protocol);
master_protocol, 1);
}
}
}

View file

@ -1460,7 +1460,7 @@ void process_chlo(struct ndpi_detection_module_struct *ndpi_struct,
ndpi_match_host_subprotocol(ndpi_struct, flow,
flow->host_server_name,
strlen(flow->host_server_name),
&ret_match, NDPI_PROTOCOL_QUIC);
&ret_match, NDPI_PROTOCOL_QUIC, 1);
flow->protos.tls_quic.client_hello_processed = 1; /* Allow matching of custom categories */
ndpi_check_dga_name(ndpi_struct, flow,

View file

@ -9,7 +9,7 @@ LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
LRU cache fpc_dns: 0/0/0 (insert/search/found)
Automa host: 2/2 (search/found)
Automa domain: 0/0 (search/found)
Automa domain: 2/0 (search/found)
Automa tls cert: 0/0 (search/found)
Automa risk mask: 2/0 (search/found)
Automa common alpns: 0/0 (search/found)

View file

@ -0,0 +1 @@
--cfg=dns,subclassification,1

View file

@ -0,0 +1 @@
../../default/pcap/dns.pcap

View file

@ -0,0 +1,29 @@
DPI Packets (UDP): 3 (1.50 pkts/flow)
Confidence DPI : 2 (flows)
Num dissector calls: 2 (1.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache stun: 0/0/0 (insert/search/found)
LRU cache tls_cert: 0/0/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
LRU cache fpc_dns: 1/0/0 (insert/search/found)
Automa host: 3/3 (search/found)
Automa domain: 3/0 (search/found)
Automa tls cert: 0/0 (search/found)
Automa risk mask: 1/0 (search/found)
Automa common alpns: 0/0 (search/found)
Patricia risk mask: 2/0 (search/found)
Patricia risk mask IPv6: 0/0 (search/found)
Patricia risk: 1/0 (search/found)
Patricia risk IPv6: 0/0 (search/found)
Patricia protocols: 4/0 (search/found)
Patricia protocols IPv6: 0/0 (search/found)
Google 3 226 1
WhatsApp 2 310 1
Acceptable 5 536 2
1 UDP 82.178.113.245:47255 <-> 82.178.158.181:53 [VLAN: 785][proto: 5.142/DNS.WhatsApp][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5.142/DNS.WhatsApp, Confidence: DPI][DPI packets: 2][cat: Network/14][1 pkts/91 bytes <-> 1 pkts/219 bytes][Goodput ratio: 36/73][0.00 sec][Hostname/SNI: e7.whatsapp.net][169.45.219.235][PLAIN TEXT (whatsapp)][Plen Bins: 0,50,0,0,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
2 UDP 192.168.170.20:53 <-> 192.168.170.8:32795 [proto: 5.126/DNS.Google][IP: 0/Unknown][ClearText][Confidence: DPI][FPC: 5.126/DNS.Google, Confidence: DPI][DPI packets: 1][cat: Network/14][2 pkts/151 bytes <-> 1 pkts/75 bytes][Goodput ratio: 44/43][41.07 sec][Hostname/SNI: www.l.google.com][0.0.0.0][PLAIN TEXT (google)][Plen Bins: 0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

View file

@ -10,7 +10,7 @@ LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
LRU cache fpc_dns: 2/4/0 (insert/search/found)
Automa host: 4/4 (search/found)
Automa domain: 0/0 (search/found)
Automa domain: 4/0 (search/found)
Automa tls cert: 0/0 (search/found)
Automa risk mask: 2/0 (search/found)
Automa common alpns: 1/0 (search/found)

View file

@ -9,7 +9,7 @@ LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
LRU cache fpc_dns: 1/0/0 (insert/search/found)
Automa host: 3/3 (search/found)
Automa domain: 0/0 (search/found)
Automa domain: 3/0 (search/found)
Automa tls cert: 0/0 (search/found)
Automa risk mask: 2/0 (search/found)
Automa common alpns: 0/0 (search/found)