aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2024-07-04 08:59:04 +0200
committerGitHub <noreply@github.com>2024-07-04 08:59:04 +0200
commit456f0fd4279ae727831a80c506a343b8a9aedd90 (patch)
treeaa18aea321f395c2c8ce217f167255d89f303278 /src/lib
parent843e4872706b07b9e78418986d35fc86bc156d60 (diff)
Improve detection of Cloudflare WARP traffic (#2491)
See: #2484
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ndpi_content_match.c.inc18
-rw-r--r--src/lib/ndpi_main.c4
-rw-r--r--src/lib/protocols/cloudflare_warp.c96
3 files changed, 118 insertions, 0 deletions
diff --git a/src/lib/ndpi_content_match.c.inc b/src/lib/ndpi_content_match.c.inc
index 2b2fa450f..438362889 100644
--- a/src/lib/ndpi_content_match.c.inc
+++ b/src/lib/ndpi_content_match.c.inc
@@ -323,6 +323,15 @@ static ndpi_network host_protocol_list[] = {
{ 0xADC70000 /* 173.199.0.0/18 */, 18, NDPI_PROTOCOL_GOTO },
{ 0x17EFE000 /* 23.239.224.0/19 */, 19, NDPI_PROTOCOL_GOTO },
+
+ /* CloudflareWarp: https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/firewall/
+ TODO: are we able to autogenerate this list?
+ */
+ { 0xA29FC100 /* 162.159.193.0/24 */, 24, NDPI_PROTOCOL_CLOUDFLARE_WARP },
+ { 0xA29FC000 /* 162.159.192.0/24 */, 24, NDPI_PROTOCOL_CLOUDFLARE_WARP },
+ { 0xA29FC500 /* 162.159.197.0/24 */, 24, NDPI_PROTOCOL_CLOUDFLARE_WARP },
+
+
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_content_match_host_protocol_list.c.inc"
#endif
@@ -331,6 +340,15 @@ static ndpi_network host_protocol_list[] = {
{ 0x0, 0, 0 }
};
+static ndpi_network6 host_protocol_list_6[] = {
+
+ /* See the ipv4 list for a description */
+ { "2606:4700:100::", 48, NDPI_PROTOCOL_CLOUDFLARE_WARP },
+ { "2606:4700:102::", 48, NDPI_PROTOCOL_CLOUDFLARE_WARP },
+
+ /* End */
+ { NULL, 0, 0 }
+};
/* ****************************************************** */
diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c
index ac1c28897..b8dc08aab 100644
--- a/src/lib/ndpi_main.c
+++ b/src/lib/ndpi_main.c
@@ -3298,6 +3298,7 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(struct ndpi_glob
}
ndpi_init_ptree_ipv4(ndpi_str->protocols->v4, host_protocol_list);
+ ndpi_init_ptree_ipv6(ndpi_str, ndpi_str->protocols->v6, host_protocol_list_6);
ndpi_str->ip_risk_mask = ndpi_ptree_create();
@@ -6181,6 +6182,9 @@ static int ndpi_callback_init(struct ndpi_detection_module_struct *ndpi_str) {
/* (Magellan) Ripe Atlas */
init_ripe_atlas_dissector(ndpi_str, &a);
+ /* Cloudflare WARP */
+ init_cloudflare_warp_dissector(ndpi_str, &a);
+
#ifdef CUSTOM_NDPI_PROTOCOLS
#include "../../../nDPI-custom/custom_ndpi_main_init.c"
#endif
diff --git a/src/lib/protocols/cloudflare_warp.c b/src/lib/protocols/cloudflare_warp.c
new file mode 100644
index 000000000..e14647084
--- /dev/null
+++ b/src/lib/protocols/cloudflare_warp.c
@@ -0,0 +1,96 @@
+/*
+ * cloudflare_warp.c
+ *
+ * Copyright (C) 2024 - ntop.org
+ *
+ * nDPI is free software: you can zmqtribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * nDPI is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with nDPI. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#include "ndpi_protocol_ids.h"
+
+#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_CLOUDFLARE_WARP
+
+#include "ndpi_api.h"
+#include "ndpi_private.h"
+
+
+static void ndpi_int_cloudflare_warp_add_connection(struct ndpi_detection_module_struct * ndpi_struct,
+ struct ndpi_flow_struct * flow)
+{
+ NDPI_LOG_INFO(ndpi_struct, "found CloudflareWarp\n");
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_CLOUDFLARE_WARP,
+ NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
+}
+
+
+static void ndpi_search_cloudflare_warp(struct ndpi_detection_module_struct *ndpi_struct,
+ struct ndpi_flow_struct *flow)
+{
+ NDPI_LOG_DBG(ndpi_struct, "search CloudflareWarp\n");
+
+ /* https://developers.cloudflare.com/cloudflare-one/connections/connect-devices/warp/deployment/firewall/ */
+
+ /* Cloudflare has been using wireguard and it is moving to MASQUE:
+ * https://blog.cloudflare.com/1111-warp-better-vpn/
+ * https://blog.cloudflare.com/zero-trust-warp-with-a-masque
+
+ Wireguard. It is not a standard wireguard traffic:
+ * message type seems to be 0xc1-0xc4 instead of 1-4
+ * handshake messages are different
+ * reserved bytes are set to 0x00 only on the very first msg, i.e 0xc1
+ However:
+ * for the "data" messages, the receiver_index and counter fields seems as the standard ones
+ * the general logic (2 handshake pkts + data) seems the same
+
+ TODO: Not yet available traffic sample with MASQUE
+
+ Overall, it should be enough to identify it via ip and port matching
+ */
+
+ if(flow->guessed_protocol_id_by_ip == NDPI_PROTOCOL_CLOUDFLARE_WARP) {
+ /* Wireguard */
+ if(flow->s_port == ntohs(2408) || flow->c_port == ntohs(2408) ||
+ flow->s_port == ntohs(500) || flow->c_port == ntohs(500) ||
+ flow->s_port == ntohs(1701) || flow->c_port == ntohs(1701) ||
+ flow->s_port == ntohs(4500) || flow->c_port == ntohs(4500)) {
+ ndpi_int_cloudflare_warp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ /* MASQUE */
+ /* TODO: we should check if the QUIC dissector already owns this flow, i.e
+ if this code path is ever triggered... */
+ if(flow->s_port == ntohs(443) || flow->c_port == ntohs(443) ||
+ flow->s_port == ntohs(4443) || flow->c_port == ntohs(4443) ||
+ flow->s_port == ntohs(8443) || flow->c_port == ntohs(8443) ||
+ flow->s_port == ntohs(8095) || flow->c_port == ntohs(8095)) {
+ ndpi_int_cloudflare_warp_add_connection(ndpi_struct, flow);
+ return;
+ }
+ }
+
+ NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
+}
+
+
+void init_cloudflare_warp_dissector(struct ndpi_detection_module_struct *ndpi_struct,
+ u_int32_t *id)
+{
+ ndpi_set_bitmask_protocol_detection("CloudflareWarp", ndpi_struct, *id,
+ NDPI_PROTOCOL_CLOUDFLARE_WARP,
+ ndpi_search_cloudflare_warp,
+ NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
+ SAVE_DETECTION_BITMASK_AS_UNKNOWN,
+ ADD_TO_DETECTION_BITMASK);
+ *id += 1;
+}