Skip to content

Commit

Permalink
ProtonVPN: split the ip list (#2060)
Browse files Browse the repository at this point in the history
Use two separate lists:
* one for the ingress nodes, which triggers a ProtonVPN classification
* one for the egress nodes, which triggers the
`NDPI_ANONYMOUS_SUBSCRIBER` risk

Add a command line option (to `ndpiReader`) to easily test IP/port
matching.

Add another example of custom rule.
  • Loading branch information
IvanNardi authored Jul 27, 2023
1 parent 3326fa2 commit bc91192
Show file tree
Hide file tree
Showing 16 changed files with 2,581 additions and 1,912 deletions.
63 changes: 61 additions & 2 deletions example/ndpiReader.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static FILE *csv_fp = NULL; /**< for CSV export */
static FILE *serialization_fp = NULL; /**< for TLV,CSV,JSON export */
static ndpi_serialization_format serialization_format = ndpi_serialization_format_unknown;
static char* domain_to_check = NULL;
static char* ip_port_to_check = NULL;
static u_int8_t ignore_vlanid = 0;
/** User preferences **/
u_int8_t enable_protocol_guess = 1, enable_payload_analyzer = 0, num_bin_clusters = 0, extcap_exit = 0;
Expand Down Expand Up @@ -352,6 +353,56 @@ void ndpiCheckHostStringMatch(char *testChar) {
ndpi_exit_detection_module(ndpi_str);
}

/* *********************************************** */

static void ndpiCheckIPMatch(char *testChar) {
struct ndpi_detection_module_struct *ndpi_str;
u_int16_t ret = NDPI_PROTOCOL_UNKNOWN;
u_int16_t port = 0;
char *saveptr, *ip_str, *port_str;
struct in_addr addr;
char appBufStr[64];
ndpi_protocol detected_protocol;
NDPI_PROTOCOL_BITMASK all;

if(!testChar)
return;

ndpi_str = ndpi_init_detection_module(init_prefs);
NDPI_BITMASK_SET_ALL(all);
ndpi_set_protocol_detection_bitmask2(ndpi_str, &all);

if(_protoFilePath != NULL)
ndpi_load_protocols_file(ndpi_str, _protoFilePath);

ndpi_finalize_initialization(ndpi_str);

ip_str = strtok_r(testChar, ":", &saveptr);
if(!ip_str)
return;

addr.s_addr = inet_addr(ip_str);
port_str = strtok_r(NULL, "\n", &saveptr);
if(port_str)
port = atoi(port_str);
ret = ndpi_network_port_ptree_match(ndpi_str, &addr, htons(port));

if(ret != NDPI_PROTOCOL_UNKNOWN) {
memset(&detected_protocol, 0, sizeof(ndpi_protocol));
detected_protocol.app_protocol = ndpi_map_ndpi_id_to_user_proto_id(ndpi_str, ret);

ndpi_protocol2name(ndpi_str, detected_protocol, appBufStr,
sizeof(appBufStr));

printf("Match Found for IP %s, port %d -> %s (%d)\n",
ip_str, port, appBufStr, detected_protocol.app_protocol);
} else {
printf("Match NOT Found for IP: %s\n", testChar);
}

ndpi_exit_detection_module(ndpi_str);
}

/********************** FUNCTIONS ********************* */

/**
Expand Down Expand Up @@ -914,7 +965,7 @@ static void parseOptions(int argc, char **argv) {
lru_cache_ttls[i] = -1; /* Use the default value */
}

while((opt = getopt_long(argc, argv, "a:Ab:B:e:Ec:C:dDFf:g:i:Ij:k:K:S:hHp:pP:l:r:s:tu:v:V:n:rp:x:w:zZ:q0123:456:7:89:m:MT:U:",
while((opt = getopt_long(argc, argv, "a:Ab:B:e:Ec:C:dDFf:g:i:Ij:k:K:S:hHp:pP:l:r:s:tu:v:V:n:rp:x:X:w:zZ:q0123:456:7:89:m:MT:U:",
longopts, &option_idx)) != EOF) {
#ifdef DEBUG_TRACE
if(trace) fprintf(trace, " #### Handling option -%c [%s] #### \n", opt, optarg ? optarg : "");
Expand Down Expand Up @@ -1198,6 +1249,10 @@ static void parseOptions(int argc, char **argv) {
domain_to_check = optarg;
break;

case 'X':
ip_port_to_check = optarg;
break;

case 'U':
max_num_udp_dissected_pkts = atoi(optarg);
if(max_num_udp_dissected_pkts < 3) max_num_udp_dissected_pkts = 3;
Expand Down Expand Up @@ -1264,7 +1319,7 @@ static void parseOptions(int argc, char **argv) {
extcap_capture();
}

if(!domain_to_check) {
if(!domain_to_check && !ip_port_to_check) {
if(_pcap_file[0] == NULL)
help(0);

Expand Down Expand Up @@ -5421,6 +5476,10 @@ int main(int argc, char **argv) {
ndpiCheckHostStringMatch(domain_to_check);
exit(0);
}
if(ip_port_to_check) {
ndpiCheckIPMatch(ip_port_to_check);
exit(0);
}

if(enable_doh_dot_detection) {
init_doh_bins();
Expand Down
1 change: 1 addition & 0 deletions example/protos.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ip:54.80.47.130@AmazonPrime

ip:3.3.3.3:443@CustomProtocolA
ip:3.3.3.3:444@CustomProtocolB
ip:3.3.3.3:446@CustomProtocolC=400

#
# Risk Exceptions
Expand Down
1 change: 1 addition & 0 deletions src/include/ndpi_typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,7 @@ typedef enum {
This heuristic only analyzes the first packet of the flow.
See: https://www.usenix.org/system/files/sec23fall-prepub-234-wu-mingshi.pdf */
ndpi_disable_fully_encrypted_heuristic = (1 << 21),
ndpi_dont_load_protonvpn_exit_nodes_list = (1 << 22),
} ndpi_prefs;

typedef struct {
Expand Down
374 changes: 325 additions & 49 deletions src/lib/inc_generated/ndpi_icloud_private_relay_match.c.inc

Large diffs are not rendered by default.

498 changes: 498 additions & 0 deletions src/lib/inc_generated/ndpi_protonvpn_in_match.c.inc

Large diffs are not rendered by default.

1,611 changes: 0 additions & 1,611 deletions src/lib/inc_generated/ndpi_protonvpn_match.c.inc

This file was deleted.

1,429 changes: 1,429 additions & 0 deletions src/lib/inc_generated/ndpi_protonvpn_out_match.c.inc

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
#include "inc_generated/ndpi_google_cloud_match.c.inc"
#include "inc_generated/ndpi_crawlers_match.c.inc"
#include "inc_generated/ndpi_icloud_private_relay_match.c.inc"
#include "inc_generated/ndpi_protonvpn_match.c.inc"
#include "inc_generated/ndpi_protonvpn_in_match.c.inc"
#include "inc_generated/ndpi_protonvpn_out_match.c.inc"
#include "inc_generated/ndpi_asn_telegram.c.inc"
#include "inc_generated/ndpi_asn_apple.c.inc"
#include "inc_generated/ndpi_asn_twitter.c.inc"
Expand Down Expand Up @@ -2923,11 +2924,12 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs

if(!(prefs & ndpi_dont_init_risk_ptree)) {
if((ndpi_str->ip_risk_ptree = ndpi_patricia_new(32 /* IPv4 */)) != NULL) {
if(!(prefs & ndpi_dont_load_icloud_private_relay_list)) {
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_protocol_list);
if(!(prefs & ndpi_dont_load_icloud_private_relay_list))
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_icloud_private_relay_protocol_list);
if(!(prefs & ndpi_dont_load_protonvpn_exit_nodes_list))
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_anonymous_subscriber_protonvpn_protocol_list);
if(!(prefs & ndpi_dont_load_crawlers_list))
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->ip_risk_ptree, ndpi_http_crawler_bot_protocol_list);
}
}
}

Expand Down
Binary file modified tests/cfgs/default/pcap/custom_rules_same-ip_multiple_ports.pcapng
Binary file not shown.
Binary file modified tests/cfgs/default/pcap/protonvpn.pcap
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Guessed flow protos: 0

DPI Packets (TCP): 2 (1.00 pkts/flow)
Confidence Unknown : 2 (flows)
DPI Packets (TCP): 3 (1.00 pkts/flow)
Confidence Unknown : 3 (flows)
Num dissector calls: 0 (0.00 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
Expand All @@ -18,10 +18,12 @@ Automa risk mask: 0/0 (search/found)
Automa common alpns: 0/0 (search/found)
Patricia risk mask: 0/0 (search/found)
Patricia risk: 0/0 (search/found)
Patricia protocols: 2/2 (search/found)
Patricia protocols: 3/3 (search/found)

CustomProtocolA 3 222 1
CustomProtocolB 2 148 1
Unknown 3 222 1

1 TCP 192.168.1.245:56866 -> 3.3.3.3:443 [proto: 91.353/TLS.CustomProtocolA][IP: 353/CustomProtocolA][Encrypted][Confidence: Unknown][DPI packets: 1][cat: Web/5][3 pkts/222 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][3.05 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 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,0,0]
2 TCP 192.168.1.245:59682 -> 3.3.3.3:444 [proto: 354/CustomProtocolB][IP: 354/CustomProtocolB][ClearText][Confidence: Unknown][DPI packets: 1][2 pkts/148 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][1.02 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 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,0,0]
2 TCP 192.168.1.245:58288 -> 3.3.3.3:446 [proto: 400/CustomProtocolC][IP: 355/Unknown][Encrypted][Confidence: Unknown][DPI packets: 1][3 pkts/222 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][3.04 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 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,0,0]
3 TCP 192.168.1.245:59682 -> 3.3.3.3:444 [proto: 354/CustomProtocolB][IP: 354/CustomProtocolB][ClearText][Confidence: Unknown][DPI packets: 1][2 pkts/148 bytes -> 0 pkts/0 bytes][Goodput ratio: 0/0][1.02 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][Plen Bins: 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,0,0]
Loading

0 comments on commit bc91192

Please sign in to comment.