diff options
author | Nardi Ivan <nardi.ivan@gmail.com> | 2024-07-31 18:26:13 +0200 |
---|---|---|
committer | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2024-09-05 16:36:50 +0200 |
commit | 85ebda434d44f93e656ee5d3e52dc258134495d0 (patch) | |
tree | dd94bce2fa318b1b1c043eeb8d2039f31aa4487f /src/lib | |
parent | f350379e95935448c22a387a561b57d50251f422 (diff) |
OpenVPN, Wireguard: improve sub-classification
Allow sub-classification of OpenVPN/Wireguard flows using their server IP.
That is useful to detect the specific VPN application/app used.
At the moment, the supported protocols are: Mullvad, NordVPN, ProtonVPN.
This feature is configurable.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/ndpi_main.c | 4 | ||||
-rw-r--r-- | src/lib/protocols/openvpn.c | 16 | ||||
-rw-r--r-- | src/lib/protocols/wireguard.c | 25 |
3 files changed, 37 insertions, 8 deletions
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 5f8711ca7..a234f7afe 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -11430,6 +11430,10 @@ static const struct cfg_param { { "rtp", "search_for_stun", "disable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(rtp_search_for_stun), NULL }, + { "openvpn", "subclassification_by_ip", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(openvpn_subclassification_by_ip), NULL }, + + { "wireguard", "subclassification_by_ip", "enable", NULL, NULL, CFG_PARAM_ENABLE_DISABLE, __OFF(wireguard_subclassification_by_ip), NULL }, + { "$PROTO_NAME_OR_ID", "log", "disable", NULL, NULL, CFG_PARAM_PROTOCOL_ENABLE_DISABLE, __OFF(debug_bitmask), NULL }, { "$PROTO_NAME_OR_ID", "ip_list.load", "1", NULL, NULL, CFG_PARAM_PROTOCOL_ENABLE_DISABLE, __OFF(ip_list_bitmask), NULL }, diff --git a/src/lib/protocols/openvpn.c b/src/lib/protocols/openvpn.c index 3eb30cd8a..a56af25be 100644 --- a/src/lib/protocols/openvpn.c +++ b/src/lib/protocols/openvpn.c @@ -60,6 +60,16 @@ #define P_PACKET_ID_ARRAY_LEN_OFFSET(hmac_size) (P_HARD_RESET_PACKET_ID_OFFSET(hmac_size) + 8 * (!!(hmac_size))) +static void ndpi_int_openvpn_add_connection(struct ndpi_detection_module_struct * const ndpi_struct, + struct ndpi_flow_struct * const flow) +{ + if(ndpi_struct->cfg.openvpn_subclassification_by_ip && + ndpi_struct->proto_defaults[flow->guessed_protocol_id_by_ip].protoCategory == NDPI_PROTOCOL_CATEGORY_VPN) { + ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_protocol_id_by_ip, NDPI_PROTOCOL_OPENVPN, NDPI_CONFIDENCE_DPI); + } else { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + } +} static int is_opcode_valid(u_int8_t opcode) { @@ -193,14 +203,14 @@ static void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct flow->packet_direction_counter[!dir] >= 2) { /* (2) */ NDPI_LOG_INFO(ndpi_struct,"found openvpn (session ids match on both direction)\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_openvpn_add_connection(ndpi_struct, flow); return; } if(flow->packet_direction_counter[dir] >= 4 && flow->packet_direction_counter[!dir] == 0) { /* (3) */ NDPI_LOG_INFO(ndpi_struct,"found openvpn (asymmetric)\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_openvpn_add_connection(ndpi_struct, flow); return; } } else { @@ -231,7 +241,7 @@ static void ndpi_search_openvpn(struct ndpi_detection_module_struct* ndpi_struct if(memcmp(flow->ovpn_session_id[!dir], session_remote, 8) == 0) { NDPI_LOG_INFO(ndpi_struct,"found openvpn\n"); - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_OPENVPN, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_openvpn_add_connection(ndpi_struct, flow); return; } else { NDPI_LOG_DBG2(ndpi_struct, "key mismatch 0x%lx\n", ndpi_ntohll(*(u_int64_t *)session_remote)); diff --git a/src/lib/protocols/wireguard.c b/src/lib/protocols/wireguard.c index 86e457872..f8abf31cb 100644 --- a/src/lib/protocols/wireguard.c +++ b/src/lib/protocols/wireguard.c @@ -40,6 +40,21 @@ enum wg_message_type { WG_TYPE_TRANSPORT_DATA = 4 }; +static void ndpi_int_wireguard_add_connection(struct ndpi_detection_module_struct * const ndpi_struct, + struct ndpi_flow_struct * const flow, + u_int16_t app_protocol) +{ + if(ndpi_struct->cfg.wireguard_subclassification_by_ip && + ndpi_struct->proto_defaults[flow->guessed_protocol_id_by_ip].protoCategory == NDPI_PROTOCOL_CATEGORY_VPN) { + ndpi_set_detected_protocol(ndpi_struct, flow, flow->guessed_protocol_id_by_ip, NDPI_PROTOCOL_WIREGUARD, NDPI_CONFIDENCE_DPI); + } else if(app_protocol != NDPI_PROTOCOL_UNKNOWN) { + ndpi_set_detected_protocol(ndpi_struct, flow, app_protocol, NDPI_PROTOCOL_WIREGUARD, NDPI_CONFIDENCE_DPI); + } else { + ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WIREGUARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + } +} + + static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { @@ -109,7 +124,7 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru if(flow->num_processed_pkts > 1) { /* This looks like a retransmission and probably this communication is blocked hence let's stop here */ - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WIREGUARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); return; } /* need more packets before deciding */ @@ -125,9 +140,9 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru if (receiver_index == flow->l4.udp.wireguard_peer_index[1 - packet->packet_direction]) { if(packet->payload_packet_len == 100) - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TUNNELBEAR, NDPI_PROTOCOL_WIREGUARD, NDPI_CONFIDENCE_DPI); + ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_TUNNELBEAR); else - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WIREGUARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); } else { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } @@ -143,7 +158,7 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru if (flow->l4.udp.wireguard_stage == 2 - packet->packet_direction) { u_int32_t receiver_index = get_u_int32_t(payload, 4); if (receiver_index == flow->l4.udp.wireguard_peer_index[1 - packet->packet_direction]) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WIREGUARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); } else { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } @@ -171,7 +186,7 @@ static void ndpi_search_wireguard(struct ndpi_detection_module_struct *ndpi_stru /* need more packets before deciding */ } else if (flow->l4.udp.wireguard_stage == 5) { if (receiver_index == flow->l4.udp.wireguard_peer_index[packet->packet_direction]) { - ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_WIREGUARD, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); + ndpi_int_wireguard_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_UNKNOWN); } else { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); } |