aboutsummaryrefslogtreecommitdiffstats
path: root/src/fnettrace
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2023-07-24 17:55:16 -0400
committerLibravatar netblue30 <netblue30@protonmail.com>2023-07-24 17:55:16 -0400
commitc4b6af8f1c48e9727eea6d91f9aae3476bae762e (patch)
tree0f18aa6851df5a6761b6991e284584642e657cae /src/fnettrace
parentfnettrace: trace ICPM ECHO (ping) traffic (diff)
downloadfirejail-c4b6af8f1c48e9727eea6d91f9aae3476bae762e.tar.gz
firejail-c4b6af8f1c48e9727eea6d91f9aae3476bae762e.tar.zst
firejail-c4b6af8f1c48e9727eea6d91f9aae3476bae762e.zip
integrating nettrace dnstrace and snitrace
Diffstat (limited to 'src/fnettrace')
-rw-r--r--src/fnettrace/fnettrace.h3
-rw-r--r--src/fnettrace/main.c193
-rw-r--r--src/fnettrace/runprog.c31
-rw-r--r--src/fnettrace/static-ip-map.txt24
4 files changed, 225 insertions, 26 deletions
diff --git a/src/fnettrace/fnettrace.h b/src/fnettrace/fnettrace.h
index b1a2f5b6c..b4a8f26c7 100644
--- a/src/fnettrace/fnettrace.h
+++ b/src/fnettrace/fnettrace.h
@@ -75,4 +75,7 @@ void terminal_handler(int s);
75void terminal_set(void); 75void terminal_set(void);
76void terminal_restore(void); 76void terminal_restore(void);
77 77
78// runprog.c
79int runprog(const char *program);
80
78#endif 81#endif
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c
index c996adb19..54ef54314 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -29,11 +29,60 @@ static int arg_netfilter = 0;
29static int arg_tail = 0; 29static int arg_tail = 0;
30static char *arg_log = NULL; 30static char *arg_log = NULL;
31 31
32//*****************************************************************
33// packet stats
34//*****************************************************************
32uint32_t stats_pkts = 0; 35uint32_t stats_pkts = 0;
33uint32_t stats_icmp_echo = 0; 36uint32_t stats_icmp_echo = 0;
34uint32_t stats_dns = 0; 37uint32_t stats_dns = 0;
38uint32_t stats_dns_dot = 0;
39uint32_t stats_dns_doh = 0;
40uint32_t stats_dns_doq = 0;
41uint32_t stats_tls = 0;
42uint32_t stats_quic = 0;
43uint32_t stats_tor = 0;
44uint32_t stats_http = 0;
45
46//*****************************************************************
47// sni/dns log storage
48//*****************************************************************
49typedef struct lognode_t {
50#define LOG_RECORD_LEN 255
51 char record[LOG_RECORD_LEN + 1];
52} LogNode;
53// circular list of SNI log records
54#define SNIMAX 64
55LogNode sni_table[SNIMAX] = {0};
56int sni_index = 0;
57
58// circular list of SNI log records
59#define DNSMAX 64
60LogNode dns_table[SNIMAX] = {0};
61int dns_index = 0;
62
63static void print_sni(void) {
64 int i;
65 for (i = sni_index; i < SNIMAX; i++)
66 if (*sni_table[i].record)
67 printf(" %s", sni_table[i].record);
68 for (i = 0; i < sni_index; i++)
69 if (*sni_table[i].record)
70 printf(" %s", sni_table[i].record);
71}
35 72
73static void print_dns(void) {
74 int i;
75 for (i = dns_index; i < DNSMAX; i++)
76 if (*dns_table[i].record)
77 printf(" %s", dns_table[i].record);
78 for (i = 0; i < dns_index; i++)
79 if (*dns_table[i].record)
80 printf(" %s", dns_table[i].record);
81}
36 82
83//*****************************************************************
84// traffic trace storage - hash table for fast access + linked list for display purposes
85//*****************************************************************
37typedef struct hnode_t { 86typedef struct hnode_t {
38 struct hnode_t *hnext; // used for hash table and unused linked list 87 struct hnode_t *hnext; // used for hash table and unused linked list
39 struct hnode_t *dnext; // used to display streams on the screen 88 struct hnode_t *dnext; // used to display streams on the screen
@@ -42,6 +91,7 @@ typedef struct hnode_t {
42 91
43 // stats 92 // stats
44 uint32_t bytes; // number of bytes received in the last display interval 93 uint32_t bytes; // number of bytes received in the last display interval
94 uint32_t pkts; // number of packets received in the last display interval
45 uint16_t port_src; 95 uint16_t port_src;
46 uint8_t protocol; 96 uint8_t protocol;
47 97
@@ -97,6 +147,7 @@ static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint
97 ip_instance++; 147 ip_instance++;
98 if (ptr->port_src == port_src && ptr->protocol == protocol) { 148 if (ptr->port_src == port_src && ptr->protocol == protocol) {
99 ptr->bytes += bytes; 149 ptr->bytes += bytes;
150 ptr->pkts++;
100 assert(ptr->rnode); 151 assert(ptr->rnode);
101 ptr->rnode->pkts++; 152 ptr->rnode->pkts++;
102 return; 153 return;
@@ -115,6 +166,7 @@ static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint
115 hnew->protocol = protocol; 166 hnew->protocol = protocol;
116 hnew->hnext = NULL; 167 hnew->hnext = NULL;
117 hnew->bytes = bytes; 168 hnew->bytes = bytes;
169 hnew->pkts = 1;
118 hnew->ip_instance = ip_instance + 1; 170 hnew->ip_instance = ip_instance + 1;
119 hnew->ttl = DISPLAY_TTL; 171 hnew->ttl = DISPLAY_TTL;
120 if (htable[h] == NULL) 172 if (htable[h] == NULL)
@@ -369,22 +421,41 @@ static void hnode_print(unsigned bw) {
369 bwline = print_bw(ptr->bytes / bwunit); 421 bwline = print_bw(ptr->bytes / bwunit);
370 422
371 const char *protocol = NULL; 423 const char *protocol = NULL;
372 if (ptr->port_src == 443 && ptr->protocol == 0x06) // TCP 424 if (ptr->port_src == 443 && ptr->protocol == 0x06) { // TCP
373 protocol = "(TLS)"; 425 protocol = "(TLS)";
374 else if (ptr->port_src == 443 && ptr->protocol == 0x11) // UDP 426 stats_tls += ptr->pkts;
427 }
428 else if (ptr->port_src == 443 && ptr->protocol == 0x11) { // UDP
375 protocol = "(QUIC)"; 429 protocol = "(QUIC)";
376 else if (ptr->port_src == 53) 430 stats_quic += ptr->pkts;
377 protocol = "(DNS)"; 431 }
378 else if (ptr->port_src == 853) { 432 else if (ptr->port_src == 53) {
433 stats_dns += ptr->pkts;
379 if (ptr->protocol == 0x06) 434 if (ptr->protocol == 0x06)
380 protocol = "(DoT)"; 435 protocol = "(TCP/DNS)";
381 else if (ptr->protocol == 0x11) 436 else if (ptr->protocol == 0x11)
437 protocol = "(UDP/DNS)";
438 else
439 protocol = NULL;
440 }
441 else if (ptr->port_src == 853) {
442 if (ptr->protocol == 0x06) {
443 protocol = "(DoT)";
444 stats_dns_dot += ptr->pkts;
445 }
446 else if (ptr->protocol == 0x11) {
382 protocol = "(DoQ)"; 447 protocol = "(DoQ)";
448 stats_dns_doq += ptr->pkts;
449 }
383 else 450 else
384 protocol = NULL; 451 protocol = NULL;
385 } 452 }
386 else if ((protocol = common_port(ptr->port_src)) != NULL) 453 else if ((protocol = common_port(ptr->port_src)) != NULL) {
387 ; 454 if (strcmp(protocol, "(HTTP)") == 0)
455 stats_http += ptr->pkts;
456 else if (strcmp(protocol, "(Tor)") == 0)
457 stats_tor += ptr->pkts;
458 }
388 else if (ptr->protocol == 0x11) 459 else if (ptr->protocol == 0x11)
389 protocol = "(UDP)"; 460 protocol = "(UDP)";
390 else if (ptr->protocol == 0x06) 461 else if (ptr->protocol == 0x06)
@@ -410,6 +481,7 @@ static void hnode_print(unsigned bw) {
410 if (ptr->bytes) 481 if (ptr->bytes)
411 ptr->ttl = DISPLAY_TTL; 482 ptr->ttl = DISPLAY_TTL;
412 ptr->bytes = 0; 483 ptr->bytes = 0;
484 ptr->pkts = 0;
413 prev = ptr; 485 prev = ptr;
414 } 486 }
415 else { 487 else {
@@ -440,9 +512,6 @@ static void hnode_print(unsigned bw) {
440 512
441 513
442void print_stats(void) { 514void print_stats(void) {
443 printf("\nIP table: %d entries - address network (packets)\n", radix_nodes);
444 radix_print(1);
445 printf("Packets: %u total, PING %u, DNS %u\n", stats_pkts, stats_icmp_echo, stats_dns);
446} 515}
447 516
448// trace rx traffic coming in 517// trace rx traffic coming in
@@ -457,6 +526,18 @@ static void run_trace(void) {
457 if (s1 < 0 || s2 < 0 || s3 < 0) 526 if (s1 < 0 || s2 < 0 || s3 < 0)
458 errExit("socket"); 527 errExit("socket");
459 528
529
530 int p1 = -1;
531 if (!arg_netfilter)
532 p1 = runprog(LIBDIR "/firejail/fnettrace-sni");
533 if (p1 != -1)
534 printf("loading snitrace...");
535
536 int p2 = -1;
537 if (!arg_netfilter)
538 p2 = runprog(LIBDIR "/firejail/fnettrace-dns --nolocal");
539 if (p2 != -1)
540 printf("loading dnstrace...");
460 unsigned start = time(NULL); 541 unsigned start = time(NULL);
461 unsigned last_print_traces = 0; 542 unsigned last_print_traces = 0;
462 unsigned last_print_remaining = 0; 543 unsigned last_print_remaining = 0;
@@ -480,14 +561,26 @@ static void run_trace(void) {
480 } 561 }
481 562
482 fd_set rfds; 563 fd_set rfds;
564
483 FD_ZERO(&rfds); 565 FD_ZERO(&rfds);
566 if (!arg_netfilter)
567 FD_SET(0, &rfds);
568
484 FD_SET(s1, &rfds); 569 FD_SET(s1, &rfds);
485 FD_SET(s2, &rfds); 570 FD_SET(s2, &rfds);
486 FD_SET(s3, &rfds); 571 FD_SET(s3, &rfds);
487 if (!arg_netfilter)
488 FD_SET(0, &rfds);
489 int maxfd = (s1 > s2) ? s1 : s2; 572 int maxfd = (s1 > s2) ? s1 : s2;
490 maxfd = (s3 > maxfd) ? s3 : maxfd; 573 maxfd = (s3 > maxfd) ? s3 : maxfd;
574
575 if (p1 != -1) {
576 FD_SET(p1, &rfds);
577 maxfd = (p1 > maxfd) ? p1 : maxfd;
578 }
579
580 if (p2 != -1) {
581 FD_SET(p2, &rfds);
582 maxfd = (p2 > maxfd) ? p2 : maxfd;
583 }
491 maxfd++; 584 maxfd++;
492 585
493 struct timeval tv; 586 struct timeval tv;
@@ -505,14 +598,82 @@ static void run_trace(void) {
505 int sock = s1; 598 int sock = s1;
506 int icmp = 0; 599 int icmp = 0;
507 600
508 if (FD_ISSET(0, &rfds)) { 601 if (!arg_netfilter && FD_ISSET(0, &rfds)) {
602 getchar();
603 printf("\n\nStats: %u packets\n", stats_pkts);
604 printf(" encrypted: TLS %u, QUIC %u, Tor %u\n",
605 stats_tls, stats_quic, stats_tor);
606 printf(" unencrypted: HTTP %u\n", stats_http);
607 printf(" C&C backchannel: PING %u, DNS %u, DoH %u, DoT %u, DoQ %u\n",
608 stats_icmp_echo, stats_dns, stats_dns_doh, stats_dns_dot, stats_dns_doq);
609 printf("press any key to continue...");
610 fflush(0);
611
612 getchar();
613 printf("\n\nSNI log - time server-address SNI\n");
614 print_sni();
615 printf("press any key to continue...");
616 fflush(0);
617
618 getchar();
619 printf("\n\nDNS log - time server-address domain\n");
620 print_dns();
621 printf("press any key to continue...");
622 fflush(0);
623
509 getchar(); 624 getchar();
510 print_stats(); 625 printf("\n\nIP table: %d addresses - server-address network (packets)\n", radix_nodes);
626 radix_print(1);
511 printf("press any key to continue..."); 627 printf("press any key to continue...");
512 fflush(0); 628 fflush(0);
629
513 getchar(); 630 getchar();
514 continue; 631 continue;
515 } 632 }
633 else if (!arg_netfilter && FD_ISSET(p1, &rfds)) {
634 char buf[1024];
635 ssize_t sz = read(p1, buf, 1024 - 1);
636 if (sz == -1)
637 errExit("error reading snitrace");
638 if (sz == 0) {
639 fprintf(stderr, "Error: snitrace EOF!!!\n");
640 p1 = -1;
641 }
642 if (strncmp(buf, "SNI trace", 9) == 0)
643 continue;
644
645 if (sz > LOG_RECORD_LEN)
646 sz = LOG_RECORD_LEN;
647 buf[sz] = '\0';
648 strcpy(sni_table[sni_index].record, buf);
649 if (++sni_index >= SNIMAX) {
650 sni_index = 0;
651 *sni_table[sni_index].record = '\0';
652 }
653 continue;
654 }
655 else if (!arg_netfilter && FD_ISSET(p2, &rfds)) {
656 char buf[1024];
657 ssize_t sz = read(p2, buf, 1024 - 1);
658 if (sz == -1)
659 errExit("error reading dnstrace");
660 if (sz == 0) {
661 fprintf(stderr, "Error: dnstrace EOF!!!\n");
662 p2 = -1;
663 }
664 if (strncmp(buf, "DNS trace", 9) == 0)
665 continue;
666
667 if (sz > LOG_RECORD_LEN)
668 sz = LOG_RECORD_LEN;
669 buf[sz] = '\0';
670 strcpy(dns_table[dns_index].record, buf);
671 if (++dns_index >= DNSMAX) {
672 dns_index = 0;
673 *dns_table[dns_index].record = '\0';
674 }
675 continue;
676 }
516 else if (FD_ISSET(s2, &rfds)) 677 else if (FD_ISSET(s2, &rfds))
517 sock = s2; 678 sock = s2;
518 else if (FD_ISSET(s3, &rfds)) { 679 else if (FD_ISSET(s3, &rfds)) {
@@ -560,8 +721,6 @@ static void run_trace(void) {
560 if (*(buf + hlen) == 0 || *(buf + hlen) == 8) 721 if (*(buf + hlen) == 0 || *(buf + hlen) == 8)
561 stats_icmp_echo++; 722 stats_icmp_echo++;
562 } 723 }
563 else if (port_src == 53)
564 stats_dns++;
565 724
566 } 725 }
567 } 726 }
diff --git a/src/fnettrace/runprog.c b/src/fnettrace/runprog.c
new file mode 100644
index 000000000..e30d8a16c
--- /dev/null
+++ b/src/fnettrace/runprog.c
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2014-2023 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fnettrace.h"
21
22int runprog(const char *program) {
23 assert(program);
24 FILE *fp = popen(program, "r");
25 if (!fp) {
26 fprintf(stderr, "Error: cannot run %s\n", program);
27 return -1;
28 }
29
30 return fileno(fp);
31}
diff --git a/src/fnettrace/static-ip-map.txt b/src/fnettrace/static-ip-map.txt
index 1f799fd2c..10b3a0ffb 100644
--- a/src/fnettrace/static-ip-map.txt
+++ b/src/fnettrace/static-ip-map.txt
@@ -38,14 +38,19 @@
38# 38#
39 39
40 40
41# local network addresses 41# local network addresses (based on https://en.wikipedia.org/wiki/Reserved_IP_addresses)
42192.168.0.0/16 local network 4210.0.0.0/8 Local network
4310.0.0.0/8 local network 43100.64.0.0/10 Carrier-grade NAT
44172.16.0.0/16 local network 44127.0.0.0/8 Local host
45169.254.0.0/16 local link 45169.254.0.0/16 Local link
46172.16.0.0/12 Local network
47192.0.2.0/24 Documentation
48192.168.0.0/16 Local network
49198.51.100.0/24 Documentation
50203.0.113.0/24 Documentation
46 51
47# multicast 52# multicast
48224.0.0.0/4 multicast 53224.0.0.0/4 Multicast
49224.0.0.9/32 RIPv2 54224.0.0.9/32 RIPv2
50224.0.0.5/32 OSPF 55224.0.0.5/32 OSPF
51224.0.0.6/32 OSPF 56224.0.0.6/32 OSPF
@@ -86,8 +91,8 @@
864.2.2.4/32 Level3 DNS 914.2.2.4/32 Level3 DNS
878.8.4.0/24 Google DNS 928.8.4.0/24 Google DNS
888.8.8.0/24 Google DNS 938.8.8.0/24 Google DNS
898.20.247.20 Comodo DNS 948.20.247.20/32 Comodo DNS
908.26.56.26 Comodo DNS 958.26.56.26/32 Comodo DNS
919.9.9.0/24 Quad9 DNS 969.9.9.0/24 Quad9 DNS
9245.90.28.0/22 NextDNS 9745.90.28.0/22 NextDNS
9345.11.45.0/24 DNS-SB 9845.11.45.0/24 DNS-SB
@@ -139,7 +144,7 @@
13923.160.0.0/24 Twitch 14423.160.0.0/24 Twitch
14023.246.0.0/18 Netflix 14523.246.0.0/18 Netflix
14131.13.24.0/21 Facebook 14631.13.24.0/21 Facebook
14231.13.64.0/18 Facebook 14731.13.64.0/17 Facebook
14337.77.184.0/21 Netflix 14837.77.184.0/21 Netflix
14445.57.0.0/17 Netflix 14945.57.0.0/17 Netflix
14545.58.64.0/20 Dropbox 15045.58.64.0/20 Dropbox
@@ -235,6 +240,7 @@
235192.30.252.0/22 GitHub 240192.30.252.0/22 GitHub
236192.69.96.0/22 Steam 241192.69.96.0/22 Steam
237192.108.239.0/24 Twitch 242192.108.239.0/24 Twitch
243192.151.158.136/29 BitChute
238192.173.64.0/18 Netflix 244192.173.64.0/18 Netflix
239192.187.97.88/29 BitChute 245192.187.97.88/29 BitChute
240192.187.123.112/29 BitChute 246192.187.123.112/29 BitChute