aboutsummaryrefslogtreecommitdiffstats
path: root/src/fnettrace
diff options
context:
space:
mode:
Diffstat (limited to 'src/fnettrace')
-rw-r--r--src/fnettrace/fnettrace.h3
-rw-r--r--src/fnettrace/main.c486
-rw-r--r--src/fnettrace/runprog.c (renamed from src/fnettrace/tail.c)48
-rw-r--r--src/fnettrace/static-ip-map.txt94
4 files changed, 309 insertions, 322 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 932afff61..3bafd9090 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -25,15 +25,63 @@
25#include <signal.h> 25#include <signal.h>
26#define MAX_BUF_SIZE (64 * 1024) 26#define MAX_BUF_SIZE (64 * 1024)
27 27
28static int arg_netfilter = 0;
29static int arg_tail = 0;
30static char *arg_log = NULL; 28static char *arg_log = NULL;
31 29
30//*****************************************************************
31// packet stats
32//*****************************************************************
32uint32_t stats_pkts = 0; 33uint32_t stats_pkts = 0;
33uint32_t stats_icmp = 0; 34uint32_t stats_icmp_echo = 0;
34uint32_t stats_dns = 0; 35uint32_t stats_dns = 0;
36uint32_t stats_dns_dot = 0;
37uint32_t stats_dns_doh = 0;
38uint32_t stats_dns_doq = 0;
39uint32_t stats_tls = 0;
40uint32_t stats_quic = 0;
41uint32_t stats_tor = 0;
42uint32_t stats_http = 0;
43uint32_t stats_ssh = 0;
44
45//*****************************************************************
46// sni/dns log storage
47//*****************************************************************
48typedef struct lognode_t {
49#define LOG_RECORD_LEN 255
50 char record[LOG_RECORD_LEN + 1];
51} LogNode;
52// circular list of SNI log records
53#define SNIMAX 64
54LogNode sni_table[SNIMAX] = {0};
55int sni_index = 0;
56
57// circular list of SNI log records
58#define DNSMAX 64
59LogNode dns_table[SNIMAX] = {0};
60int dns_index = 0;
61
62static void print_sni(void) {
63 int i;
64 for (i = sni_index; i < SNIMAX; i++)
65 if (*sni_table[i].record)
66 printf(" %s", sni_table[i].record);
67 for (i = 0; i < sni_index; i++)
68 if (*sni_table[i].record)
69 printf(" %s", sni_table[i].record);
70}
35 71
72static void print_dns(void) {
73 int i;
74 for (i = dns_index; i < DNSMAX; i++)
75 if (*dns_table[i].record)
76 printf(" %s", dns_table[i].record);
77 for (i = 0; i < dns_index; i++)
78 if (*dns_table[i].record)
79 printf(" %s", dns_table[i].record);
80}
36 81
82//*****************************************************************
83// traffic trace storage - hash table for fast access + linked list for display purposes
84//*****************************************************************
37typedef struct hnode_t { 85typedef struct hnode_t {
38 struct hnode_t *hnext; // used for hash table and unused linked list 86 struct hnode_t *hnext; // used for hash table and unused linked list
39 struct hnode_t *dnext; // used to display streams on the screen 87 struct hnode_t *dnext; // used to display streams on the screen
@@ -42,6 +90,7 @@ typedef struct hnode_t {
42 90
43 // stats 91 // stats
44 uint32_t bytes; // number of bytes received in the last display interval 92 uint32_t bytes; // number of bytes received in the last display interval
93 uint32_t pkts; // number of packets received in the last display interval
45 uint16_t port_src; 94 uint16_t port_src;
46 uint8_t protocol; 95 uint8_t protocol;
47 96
@@ -97,6 +146,7 @@ static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint
97 ip_instance++; 146 ip_instance++;
98 if (ptr->port_src == port_src && ptr->protocol == protocol) { 147 if (ptr->port_src == port_src && ptr->protocol == protocol) {
99 ptr->bytes += bytes; 148 ptr->bytes += bytes;
149 ptr->pkts++;
100 assert(ptr->rnode); 150 assert(ptr->rnode);
101 ptr->rnode->pkts++; 151 ptr->rnode->pkts++;
102 return; 152 return;
@@ -115,6 +165,7 @@ static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint
115 hnew->protocol = protocol; 165 hnew->protocol = protocol;
116 hnew->hnext = NULL; 166 hnew->hnext = NULL;
117 hnew->bytes = bytes; 167 hnew->bytes = bytes;
168 hnew->pkts = 1;
118 hnew->ip_instance = ip_instance + 1; 169 hnew->ip_instance = ip_instance + 1;
119 hnew->ttl = DISPLAY_TTL; 170 hnew->ttl = DISPLAY_TTL;
120 if (htable[h] == NULL) 171 if (htable[h] == NULL)
@@ -139,9 +190,6 @@ static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src, uint
139 if (!hnew->rnode) 190 if (!hnew->rnode)
140 hnew->rnode = radix_add(hnew->ip_src, 0xffffffff, NULL); 191 hnew->rnode = radix_add(hnew->ip_src, 0xffffffff, NULL);
141 hnew->rnode->pkts++; 192 hnew->rnode->pkts++;
142
143 if (arg_netfilter)
144 logprintf(" %d.%d.%d.%d ", PRINT_IP(hnew->ip_src));
145} 193}
146 194
147static void hnode_free(HNode *elem) { 195static void hnode_free(HNode *elem) {
@@ -242,23 +290,23 @@ typedef struct port_type_t {
242 char *service; 290 char *service;
243} PortType; 291} PortType;
244static PortType ports[] = { 292static PortType ports[] = {
245 {20, "(FTP)"}, 293 {20, "FTP"},
246 {21, "(FTP)"}, 294 {21, "FTP"},
247 {22, "(SSH)"}, 295 {22, "SSH"},
248 {23, "(telnet)"}, 296 {23, "telnet"},
249 {25, "(SMTP)"}, 297 {25, "SMTP"},
250 {43, "(WHOIS)"}, 298 {43, "WHOIS"},
251 {67, "(DHCP)"}, 299 {67, "DHCP"},
252 {68, "(DHCP)"}, 300 {68, "DHCP"},
253 {69, "(TFTP)"}, 301 {69, "TFTP"},
254 {80, "(HTTP)"}, 302 {80, "HTTP"},
255 {109, "(POP2)"}, 303 {109, "POP2"},
256 {110, "(POP3)"}, 304 {110, "POP3"},
257 {113, "(IRC)"}, 305 {113, "IRC"},
258 {123, "(NTP)"}, 306 {123, "NTP"},
259 {161, "(SNMP)"}, 307 {161, "SNMP"},
260 {162, "(SNMP)"}, 308 {162, "SNMP"},
261 {194, "(IRC)"}, 309 {194, "IRC"},
262 {0, NULL}, 310 {0, NULL},
263}; 311};
264 312
@@ -266,32 +314,32 @@ static PortType ports[] = {
266static inline const char *common_port(uint16_t port) { 314static inline const char *common_port(uint16_t port) {
267 if (port >= 6660 && port <= 10162) { 315 if (port >= 6660 && port <= 10162) {
268 if (port >= 6660 && port <= 6669) 316 if (port >= 6660 && port <= 6669)
269 return "(IRC)"; 317 return "IRC";
270 else if (port == 6679) 318 else if (port == 6679)
271 return "(IRC)"; 319 return "IRC";
272 else if (port == 6771) 320 else if (port == 6771)
273 return "(BitTorrent)"; 321 return "BitTorrent";
274 else if (port >= 6881 && port <= 6999) 322 else if (port >= 6881 && port <= 6999)
275 return "(BitTorrent)"; 323 return "BitTorrent";
276 else if (port == 9001) 324 else if (port == 9001)
277 return "(Tor)"; 325 return "Tor";
278 else if (port == 9030) 326 else if (port == 9030)
279 return "(Tor)"; 327 return "Tor";
280 else if (port == 9050) 328 else if (port == 9050)
281 return "(Tor)"; 329 return "Tor";
282 else if (port == 9051) 330 else if (port == 9051)
283 return "(Tor)"; 331 return "Tor";
284 else if (port == 9150) 332 else if (port == 9150)
285 return "(Tor)"; 333 return "Tor";
286 else if (port == 10161) 334 else if (port == 10161)
287 return "(secure SNMP)"; 335 return "secure SNMP";
288 else if (port == 10162) 336 else if (port == 10162)
289 return "(secure SNMP)"; 337 return "secure SNMP";
290 return NULL; 338 return NULL;
291 } 339 }
292 340
293 if (port <= 194) { 341 if (port <= 194) {
294 PortType *ptr =&ports[0]; 342 PortType *ptr = &ports[0];
295 while(ptr->service != NULL) { 343 while(ptr->service != NULL) {
296 if (ptr->port == port) 344 if (ptr->port == port)
297 return ptr->service; 345 return ptr->service;
@@ -305,7 +353,6 @@ static inline const char *common_port(uint16_t port) {
305 353
306 354
307static void hnode_print(unsigned bw) { 355static void hnode_print(unsigned bw) {
308 assert(!arg_netfilter);
309 bw = (bw < 1024 * DISPLAY_INTERVAL) ? 1024 * DISPLAY_INTERVAL : bw; 356 bw = (bw < 1024 * DISPLAY_INTERVAL) ? 1024 * DISPLAY_INTERVAL : bw;
310#ifdef DEBUG 357#ifdef DEBUG
311 printf("*********************\n"); 358 printf("*********************\n");
@@ -336,7 +383,7 @@ static void hnode_print(unsigned bw) {
336 else 383 else
337 sprintf(stats, "%u KB/s ", bw / (1024 * DISPLAY_INTERVAL)); 384 sprintf(stats, "%u KB/s ", bw / (1024 * DISPLAY_INTERVAL));
338// int len = snprintf(line, LINE_MAX, "%32s geoip %d, IP database %d\n", stats, geoip_calls, radix_nodes); 385// int len = snprintf(line, LINE_MAX, "%32s geoip %d, IP database %d\n", stats, geoip_calls, radix_nodes);
339 int len = snprintf(line, LINE_MAX, "%32s address:port (protocol) network (packets)\n", stats); 386 int len = snprintf(line, LINE_MAX, "%32s address:port (protocol) network\n", stats);
340 adjust_line(line, len, cols); 387 adjust_line(line, len, cols);
341 printf("%s", line); 388 printf("%s", line);
342 389
@@ -369,47 +416,67 @@ static void hnode_print(unsigned bw) {
369 bwline = print_bw(ptr->bytes / bwunit); 416 bwline = print_bw(ptr->bytes / bwunit);
370 417
371 const char *protocol = NULL; 418 const char *protocol = NULL;
372 if (ptr->port_src == 443 && ptr->protocol == 0x06) // TCP 419 if (ptr->port_src == 443 && ptr->protocol == 0x06) { // TCP
373 protocol = "(TLS)"; 420 protocol = "TLS";
374 else if (ptr->port_src == 443 && ptr->protocol == 0x11) // UDP 421 stats_tls += ptr->pkts;
375 protocol = "(QUIC)"; 422 if (strstr(ptr->rnode->name, "DNS")) {
376 else if (ptr->port_src == 53) 423 protocol = "DoH";
377 protocol = "(DNS)"; 424 stats_dns_doh += ptr->pkts;
425 }
426
427 }
428 else if (ptr->port_src == 443 && ptr->protocol == 0x11) { // UDP
429 protocol = "QUIC";
430 stats_quic += ptr->pkts;
431 if (strstr(ptr->rnode->name, "DNS")) {
432 protocol = "DoQ";
433 stats_dns_doq += ptr->pkts;
434 }
435 }
436 else if (ptr->port_src == 53) {
437 protocol = "DNS";
438 stats_dns += ptr->pkts;
439 }
378 else if (ptr->port_src == 853) { 440 else if (ptr->port_src == 853) {
379 if (ptr->protocol == 0x06) 441 if (ptr->protocol == 0x06) {
380 protocol = "(DoT)"; 442 protocol = "DoT";
381 else if (ptr->protocol == 0x11) 443 stats_dns_dot += ptr->pkts;
382 protocol = "(DoQ)"; 444 }
445 else if (ptr->protocol == 0x11) {
446 protocol = "DoQ";
447 stats_dns_doq += ptr->pkts;
448 }
383 else 449 else
384 protocol = NULL; 450 protocol = NULL;
385 } 451 }
386 else if ((protocol = common_port(ptr->port_src)) != NULL) 452 else if ((protocol = common_port(ptr->port_src)) != NULL) {
387 ; 453 if (strcmp(protocol, "HTTP") == 0)
454 stats_http += ptr->pkts;
455 else if (strcmp(protocol, "Tor") == 0)
456 stats_tor += ptr->pkts;
457 else if (strcmp(protocol, "SSH") == 0)
458 stats_ssh += ptr->pkts;
459 }
388 else if (ptr->protocol == 0x11) 460 else if (ptr->protocol == 0x11)
389 protocol = "(UDP)"; 461 protocol = "UDP";
390 else if (ptr->protocol == 0x06) 462 else if (ptr->protocol == 0x06)
391 protocol = "(TCP)"; 463 protocol = "TCP";
392 464
393 if (protocol == NULL) 465 if (protocol == NULL)
394 protocol = ""; 466 protocol = "";
395 if (ptr->port_src == 0) 467 if (ptr->port_src == 0)
396 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d (ICMP) %s\n", 468 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d (ICMP) %s\n",
397 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->rnode->name); 469 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->rnode->name);
398 else if (ptr->rnode->pkts > 1000000)
399 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s (%.01fM)\n",
400 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->rnode->name, ((double) ptr->rnode->pkts) / 1000000);
401 else if (ptr->rnode->pkts > 1000)
402 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s (%.01fK)\n",
403 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->rnode->name, ((double) ptr->rnode->pkts) / 1000);
404 else 470 else
405 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s (%u)\n", 471 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u (%s) %s\n",
406 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->rnode->name, ptr->rnode->pkts); 472 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->rnode->name);
407 adjust_line(line, len, cols); 473 adjust_line(line, len, cols);
408 printf("%s", line); 474 printf("%s", line);
409 475
410 if (ptr->bytes) 476 if (ptr->bytes)
411 ptr->ttl = DISPLAY_TTL; 477 ptr->ttl = DISPLAY_TTL;
412 ptr->bytes = 0; 478 ptr->bytes = 0;
479 ptr->pkts = 0;
413 prev = ptr; 480 prev = ptr;
414 } 481 }
415 else { 482 else {
@@ -440,17 +507,10 @@ static void hnode_print(unsigned bw) {
440 507
441 508
442void print_stats(void) { 509void print_stats(void) {
443 printf("\nIP table: %d entries, %d unknown\n", radix_nodes, geoip_calls);
444 printf(" address network (packets)\n");
445 radix_print(1);
446 printf("Packets: %u total, ICMP %u, DNS %u\n", stats_pkts, stats_icmp, stats_dns);
447} 510}
448 511
449// trace rx traffic coming in 512// trace rx traffic coming in
450static void run_trace(void) { 513static void run_trace(void) {
451 if (arg_netfilter)
452 logprintf("accumulating traffic for %d seconds\n", NETLOCK_INTERVAL);
453
454 // trace only rx ipv4 tcp and upd 514 // trace only rx ipv4 tcp and upd
455 int s1 = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); 515 int s1 = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
456 int s2 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); 516 int s2 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
@@ -458,37 +518,45 @@ static void run_trace(void) {
458 if (s1 < 0 || s2 < 0 || s3 < 0) 518 if (s1 < 0 || s2 < 0 || s3 < 0)
459 errExit("socket"); 519 errExit("socket");
460 520
461 unsigned start = time(NULL); 521
522 int p1 = runprog(LIBDIR "/firejail/fnettrace-sni");
523 if (p1 != -1)
524 printf("loading snitrace...");
525
526 int p2 = runprog(LIBDIR "/firejail/fnettrace-dns --nolocal");
527 if (p2 != -1)
528 printf("loading dnstrace...");
462 unsigned last_print_traces = 0; 529 unsigned last_print_traces = 0;
463 unsigned last_print_remaining = 0;
464 unsigned char buf[MAX_BUF_SIZE]; 530 unsigned char buf[MAX_BUF_SIZE];
465 unsigned bw = 0; // bandwidth calculations 531 unsigned bw = 0; // bandwidth calculations
466 532
467 while (1) { 533 while (1) {
468 unsigned end = time(NULL); 534 unsigned end = time(NULL);
469 if (arg_netfilter && end - start >= NETLOCK_INTERVAL)
470 break;
471 if (end % DISPLAY_INTERVAL == 1 && last_print_traces != end) { // first print after 1 second 535 if (end % DISPLAY_INTERVAL == 1 && last_print_traces != end) { // first print after 1 second
472 if (!arg_netfilter) 536 hnode_print(bw);
473 hnode_print(bw);
474 last_print_traces = end; 537 last_print_traces = end;
475 bw = 0; 538 bw = 0;
476 } 539 }
477 if (arg_netfilter && last_print_remaining != end) {
478 logprintf(".");
479 fflush(0);
480 last_print_remaining = end;
481 }
482 540
483 fd_set rfds; 541 fd_set rfds;
484 FD_ZERO(&rfds); 542 FD_ZERO(&rfds);
543 FD_SET(0, &rfds);
544
485 FD_SET(s1, &rfds); 545 FD_SET(s1, &rfds);
486 FD_SET(s2, &rfds); 546 FD_SET(s2, &rfds);
487 FD_SET(s3, &rfds); 547 FD_SET(s3, &rfds);
488 if (!arg_netfilter)
489 FD_SET(0, &rfds);
490 int maxfd = (s1 > s2) ? s1 : s2; 548 int maxfd = (s1 > s2) ? s1 : s2;
491 maxfd = (s3 > maxfd) ? s3 : maxfd; 549 maxfd = (s3 > maxfd) ? s3 : maxfd;
550
551 if (p1 != -1) {
552 FD_SET(p1, &rfds);
553 maxfd = (p1 > maxfd) ? p1 : maxfd;
554 }
555
556 if (p2 != -1) {
557 FD_SET(p2, &rfds);
558 maxfd = (p2 > maxfd) ? p2 : maxfd;
559 }
492 maxfd++; 560 maxfd++;
493 561
494 struct timeval tv; 562 struct timeval tv;
@@ -508,10 +576,78 @@ static void run_trace(void) {
508 576
509 if (FD_ISSET(0, &rfds)) { 577 if (FD_ISSET(0, &rfds)) {
510 getchar(); 578 getchar();
511 print_stats(); 579 printf("\n\nStats: %u packets\n", stats_pkts);
580 printf(" encrypted: TLS %u, QUIC %u, SSH %u, Tor %u\n",
581 stats_tls, stats_quic, stats_ssh, stats_tor);
582 printf(" unencrypted: HTTP %u\n", stats_http);
583 printf(" C&C backchannel: PING %u, DNS %u, DoH %u, DoT %u, DoQ %u\n",
584 stats_icmp_echo, stats_dns, stats_dns_doh, stats_dns_dot, stats_dns_doq);
585 printf("press any key to continue...");
586 fflush(0);
587
588 getchar();
589 printf("\n\nSNI log - time server-address SNI\n");
590 print_sni();
512 printf("press any key to continue..."); 591 printf("press any key to continue...");
513 fflush(0); 592 fflush(0);
593
594 getchar();
595 printf("\n\nDNS log - time server-address domain\n");
596 print_dns();
597 printf("press any key to continue...");
598 fflush(0);
599
514 getchar(); 600 getchar();
601 printf("\n\nIP table: %d addresses - server-address network (packets)\n", radix_nodes);
602 radix_print(1);
603 printf("press any key to continue...");
604 fflush(0);
605
606 getchar();
607 continue;
608 }
609 else if (FD_ISSET(p1, &rfds)) {
610 char buf[1024];
611 ssize_t sz = read(p1, buf, 1024 - 1);
612 if (sz == -1)
613 errExit("error reading snitrace");
614 if (sz == 0) {
615 fprintf(stderr, "Error: snitrace EOF!!!\n");
616 p1 = -1;
617 }
618 if (strncmp(buf, "SNI trace", 9) == 0)
619 continue;
620
621 if (sz > LOG_RECORD_LEN)
622 sz = LOG_RECORD_LEN;
623 buf[sz] = '\0';
624 strcpy(sni_table[sni_index].record, buf);
625 if (++sni_index >= SNIMAX) {
626 sni_index = 0;
627 *sni_table[sni_index].record = '\0';
628 }
629 continue;
630 }
631 else if (FD_ISSET(p2, &rfds)) {
632 char buf[1024];
633 ssize_t sz = read(p2, buf, 1024 - 1);
634 if (sz == -1)
635 errExit("error reading dnstrace");
636 if (sz == 0) {
637 fprintf(stderr, "Error: dnstrace EOF!!!\n");
638 p2 = -1;
639 }
640 if (strncmp(buf, "DNS trace", 9) == 0)
641 continue;
642
643 if (sz > LOG_RECORD_LEN)
644 sz = LOG_RECORD_LEN;
645 buf[sz] = '\0';
646 strcpy(dns_table[dns_index].record, buf);
647 if (++dns_index >= DNSMAX) {
648 dns_index = 0;
649 *dns_table[dns_index].record = '\0';
650 }
515 continue; 651 continue;
516 } 652 }
517 else if (FD_ISSET(s2, &rfds)) 653 else if (FD_ISSET(s2, &rfds))
@@ -557,10 +693,10 @@ static void run_trace(void) {
557 693
558 // stats 694 // stats
559 stats_pkts++; 695 stats_pkts++;
560 if (icmp) 696 if (icmp) {
561 stats_icmp++; 697 if (*(buf + hlen) == 0 || *(buf + hlen) == 8)
562 if (port_src == 53) 698 stats_icmp_echo++;
563 stats_dns++; 699 }
564 700
565 } 701 }
566 } 702 }
@@ -572,142 +708,6 @@ static void run_trace(void) {
572 print_stats(); 708 print_stats();
573} 709}
574 710
575static char *filter_start =
576 "*filter\n"
577 ":INPUT DROP [0:0]\n"
578 ":FORWARD DROP [0:0]\n"
579 ":OUTPUT DROP [0:0]\n";
580
581// return 1 if error
582static int print_filter(FILE *fp) {
583 if (dlist == NULL)
584 return 1;
585 fprintf(fp, "%s\n", filter_start);
586 fprintf(fp, "-A INPUT -s 127.0.0.0/8 -j ACCEPT\n");
587 fprintf(fp, "-A OUTPUT -d 127.0.0.0/8 -j ACCEPT\n");
588 fprintf(fp, "\n");
589
590 int i;
591 for (i = 0; i < HMAX; i++) {
592 HNode *ptr = htable[i];
593 while (ptr) {
594 // filter rules are targeting ip address, the port number is disregarded,
595 // so we look only at the first instance of an address
596 if (ptr->ip_instance == 1) {
597 char *protocol = (ptr->protocol == 6) ? "tcp" : "udp";
598 fprintf(fp, "-A INPUT -s %d.%d.%d.%d -p %s -j ACCEPT\n",
599 PRINT_IP(ptr->ip_src),
600 protocol);
601 fprintf(fp, "-A OUTPUT -d %d.%d.%d.%d -p %s -j ACCEPT\n",
602 PRINT_IP(ptr->ip_src),
603 protocol);
604 fprintf(fp, "\n");
605 }
606 ptr = ptr->hnext;
607 }
608 }
609 fprintf(fp, "COMMIT\n");
610
611 return 0;
612}
613
614static char *flush_rules[] = {
615 "-P INPUT ACCEPT",
616// "-P FORWARD DENY",
617 "-P OUTPUT ACCEPT",
618 "-F",
619 "-X",
620// "-t nat -F",
621// "-t nat -X",
622// "-t mangle -F",
623// "-t mangle -X",
624// "iptables -t raw -F",
625// "-t raw -X",
626 NULL
627};
628
629static void deploy_netfilter(void) {
630 int rv;
631 char *cmd;
632 int i;
633
634 if (dlist == NULL) {
635 logprintf("Sorry, no network traffic was detected. The firewall was not configured.\n");
636 return;
637 }
638 // find iptables command
639 char *iptables = NULL;
640 char *iptables_restore = NULL;
641 if (access("/sbin/iptables", X_OK) == 0) {
642 iptables = "/sbin/iptables";
643 iptables_restore = "/sbin/iptables-restore";
644 }
645 else if (access("/usr/sbin/iptables", X_OK) == 0) {
646 iptables = "/usr/sbin/iptables";
647 iptables_restore = "/usr/sbin/iptables-restore";
648 }
649 if (iptables == NULL || iptables_restore == NULL) {
650 fprintf(stderr, "Error: iptables command not found, netfilter not configured\n");
651 exit(1);
652 }
653
654 // flush all netfilter rules
655 i = 0;
656 while (flush_rules[i]) {
657 char *cmd;
658 if (asprintf(&cmd, "%s %s", iptables, flush_rules[i]) == -1)
659 errExit("asprintf");
660 int rv = system(cmd);
661 (void) rv;
662 free(cmd);
663 i++;
664 }
665
666 // create temporary file
667 char fname[] = "/tmp/firejail-XXXXXX";
668 int fd = mkstemp(fname);
669 if (fd == -1) {
670 fprintf(stderr, "Error: cannot create temporary configuration file\n");
671 exit(1);
672 }
673
674 FILE *fp = fdopen(fd, "w");
675 if (!fp) {
676 rv = unlink(fname);
677 (void) rv;
678 fprintf(stderr, "Error: cannot create temporary configuration file\n");
679 exit(1);
680 }
681 print_filter(fp);
682 fclose(fp);
683
684 logprintf("\n\n");
685 logprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
686 if (asprintf(&cmd, "cat %s >> %s", fname, arg_log) == -1)
687 errExit("asprintf");
688 rv = system(cmd);
689 (void) rv;
690 free(cmd);
691
692 if (asprintf(&cmd, "cat %s", fname) == -1)
693 errExit("asprintf");
694 rv = system(cmd);
695 (void) rv;
696 free(cmd);
697 logprintf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
698
699 // configuring
700 if (asprintf(&cmd, "%s %s", iptables_restore, fname) == -1)
701 errExit("asprintf");
702 rv = system(cmd);
703 if (rv)
704 fprintf(stdout, "Warning: possible netfilter problem!");
705 free(cmd);
706
707 rv = unlink(fname);
708 (void) rv;
709 logprintf("\nfirewall deployed\n");
710}
711 711
712void logprintf(char *fmt, ...) { 712void logprintf(char *fmt, ...) {
713 if (!arg_log) 713 if (!arg_log)
@@ -733,14 +733,8 @@ static const char *const usage_str =
733 "Options:\n" 733 "Options:\n"
734 " --help, -? - this help screen\n" 734 " --help, -? - this help screen\n"
735 " --log=filename - netlocker logfile\n" 735 " --log=filename - netlocker logfile\n"
736 " --netfilter - build the firewall rules and commit them\n"
737 " --print-map - print IP map\n" 736 " --print-map - print IP map\n"
738 " --squash-map - compress IP map\n" 737 " --squash-map - compress IP map\n";
739 " --tail - \"tail -f\" functionality\n"
740 "Examples:\n"
741 " # fnettrace - traffic trace\n"
742 " # fnettrace --netfilter --log=logfile - netlocker, dump output in logfile\n"
743 " # fnettrace --tail --log=logifile - similar to \"tail -f logfile\"\n";
744 738
745static void usage(void) { 739static void usage(void) {
746 puts(usage_str); 740 puts(usage_str);
@@ -775,7 +769,7 @@ int main(int argc, char **argv) {
775 return 0; 769 return 0;
776 } 770 }
777 else if (strncmp(argv[i], "--squash-map=", 13) == 0) { 771 else if (strncmp(argv[i], "--squash-map=", 13) == 0) {
778 if (i !=(argc - 1)) { 772 if (i != (argc - 1)) {
779 fprintf(stderr, "Error: please provide a map file\n"); 773 fprintf(stderr, "Error: please provide a map file\n");
780 return 1; 774 return 1;
781 } 775 }
@@ -798,10 +792,6 @@ int main(int argc, char **argv) {
798 fprintf(stderr, "static ip map: input %d, output %d\n", in, radix_nodes); 792 fprintf(stderr, "static ip map: input %d, output %d\n", in, radix_nodes);
799 return 0; 793 return 0;
800 } 794 }
801 else if (strcmp(argv[i], "--netfilter") == 0)
802 arg_netfilter = 1;
803 else if (strcmp(argv[i], "--tail") == 0)
804 arg_tail = 1;
805 else if (strncmp(argv[i], "--log=", 6) == 0) 795 else if (strncmp(argv[i], "--log=", 6) == 0)
806 arg_log = argv[i] + 6; 796 arg_log = argv[i] + 6;
807 else { 797 else {
@@ -810,19 +800,6 @@ int main(int argc, char **argv) {
810 } 800 }
811 } 801 }
812 802
813 // tail
814 if (arg_tail) {
815 if (!arg_log) {
816 fprintf(stderr, "Error: no log file\n");
817 usage();
818 exit(1);
819 }
820
821 tail(arg_log);
822 sleep(5);
823 exit(0);
824 }
825
826 if (getuid() != 0) { 803 if (getuid() != 0) {
827 fprintf(stderr, "Error: you need to be root to run this program\n"); 804 fprintf(stderr, "Error: you need to be root to run this program\n");
828 return 1; 805 return 1;
@@ -838,25 +815,10 @@ int main(int argc, char **argv) {
838 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 815 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
839 816
840 ansi_clrscr(); 817 ansi_clrscr();
841 if (arg_netfilter) 818 char *fname = LIBDIR "/firejail/static-ip-map";
842 logprintf("starting network lockdown\n"); 819 load_hostnames(fname);
843 else {
844 char *fname = LIBDIR "/firejail/static-ip-map";
845 load_hostnames(fname);
846 }
847 820
848 run_trace(); 821 run_trace();
849 if (arg_netfilter) {
850 // TCP path MTU discovery will not work properly since the firewall drops all ICMP packets
851 // Instead, we use iPacketization Layer PMTUD (RFC 4821) support in Linux kernel
852 int rv = system("echo 1 > /proc/sys/net/ipv4/tcp_mtu_probing");
853 (void) rv;
854
855 deploy_netfilter();
856 sleep(3);
857 if (arg_log)
858 unlink(arg_log);
859 }
860 822
861 return 0; 823 return 0;
862} 824}
diff --git a/src/fnettrace/tail.c b/src/fnettrace/runprog.c
index 3b1b274f8..e30d8a16c 100644
--- a/src/fnettrace/tail.c
+++ b/src/fnettrace/runprog.c
@@ -19,45 +19,13 @@
19*/ 19*/
20#include "fnettrace.h" 20#include "fnettrace.h"
21 21
22void tail(const char *logfile) { 22int runprog(const char *program) {
23 assert(logfile); 23 assert(program);
24 24 FILE *fp = popen(program, "r");
25 // wait for no more than 5 seconds for the logfile to appear in the filesystem 25 if (!fp) {
26 int cnt = 5; 26 fprintf(stderr, "Error: cannot run %s\n", program);
27 while (access(logfile, R_OK) && cnt > 0) 27 return -1;
28 cnt--;
29 if (cnt == 0)
30 exit(1);
31
32 off_t last_size = 0;
33
34 while (1) {
35 int fd = open(logfile, O_RDONLY);
36 if (fd == -1)
37 return;
38
39 off_t size = lseek(fd, 0, SEEK_END);
40 if (size < 0) {
41 close(fd);
42 return;
43 }
44
45 char *content = NULL;
46 int mmapped = 0;
47 if (size && size != last_size) {
48 content = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
49 close(fd);
50 if (content != MAP_FAILED)
51 mmapped = 1;
52 }
53
54 if (mmapped) {
55 printf("%.*s", (int) (size - last_size), content + last_size);
56 fflush(0);
57 munmap(content, size);
58 last_size = size;
59 }
60
61 sleep(1);
62 } 28 }
29
30 return fileno(fp);
63} 31}
diff --git a/src/fnettrace/static-ip-map.txt b/src/fnettrace/static-ip-map.txt
index 756658562..59ec79f8f 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,15 +91,40 @@
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
948.20.247.20/32 Comodo DNS
958.26.56.26/32 Comodo DNS
899.9.9.0/24 Quad9 DNS 969.9.9.0/24 Quad9 DNS
9045.90.28.0/22 NextDNS 9745.90.28.0/22 NextDNS
9845.11.45.0/24 DNS-SB
9964.6.64.6/32 Neustar DNS
10064.6.65.6/32 Neustar DNS
10174.82.42.42/32 Hurricane Electric DNS
10276.76.2.0/24 ControlD DNS
10376.76.10.0/24 ControlD DNS
10476.76.19.0/24 Alternate DNS
10576.223.122.150/32 Alternate DNS
10677.88.8.8/32 Yandex DNS
10777.88.8.1/32 Yandex DNS
10880.80.80.0/24 Freenom DNS Cloud
10980.80.81.0/24 Freenom DNS Cloud
11084.200.69.80/32 DSN Watch
11184.200.70.40/32 DNS Watch
9194.140.14.0/23 Adguard DNS 11294.140.14.0/23 Adguard DNS
92149.112.112.0/24 Quad9 DNS 113149.112.112.0/24 Quad9 DNS
93149.112.120.0/21 CIRA DNS Canada 114149.112.120.0/21 CIRA DNS Canada
94146.255.56.96/29 Applied Privacy 115146.255.56.96/29 Applied Privacy DNS
95176.103.128.0/19 Adguard DNS 116176.103.128.0/19 Adguard DNS
117185.222.222.0/24 DNS-SB
96185.228.168.0/24 Cleanbrowsing DNS 118185.228.168.0/24 Cleanbrowsing DNS
119185.236.104.0/24 FlashStart DNS
120185.236.105.0/24 FlashStart DNS
121185.253.5.0/24 NextDNS
122193.110.81.0/24 NextDNS
123205.171.3.66/32 CentyrLink DNS
124205.171.202.166/32 CentyrLink DNS
97208.67.216.0/21 OpenDNS 125208.67.216.0/21 OpenDNS
126216.146.35.35/32 Dyn DNS
127216.146.36.36/32 Dyn DNS
98 128
99# whois 129# whois
100192.0.32.0/20 ICANN 130192.0.32.0/20 ICANN
@@ -106,13 +136,15 @@
106199.212.0.0/24 whois.arin.net US 136199.212.0.0/24 whois.arin.net US
107200.3.12.0/22 whois.lacnic.net Uruguay 137200.3.12.0/22 whois.lacnic.net Uruguay
108201.159.220.0/22 whois.lacnic.net Ecuador 138201.159.220.0/22 whois.lacnic.net Ecuador
139203.119.100.0/22 apnic.net Australia
109 140
110# some popular websites 141# some popular websites
1115.255.255.0/24 Yandex 1425.255.255.0/24 Yandex
11223.160.0.0/24 Twitch 14323.160.0.0/24 Twitch
14423.229.128.0/17 GoDaddy
11323.246.0.0/18 Netflix 14523.246.0.0/18 Netflix
11431.13.24.0/21 Facebook 14631.13.24.0/21 Facebook
11531.13.64.0/18 Facebook 14731.13.64.0/17 Facebook
11637.77.184.0/21 Netflix 14837.77.184.0/21 Netflix
11745.57.0.0/17 Netflix 14945.57.0.0/17 Netflix
11845.58.64.0/20 Dropbox 15045.58.64.0/20 Dropbox
@@ -132,9 +164,14 @@
13266.211.168.0/22 PayPal 16466.211.168.0/22 PayPal
13366.211.172.0/22 eBay 16566.211.172.0/22 eBay
13466.211.176.0/20 eBay 16666.211.176.0/20 eBay
16766.218.64.0/19 Yahoo
13566.220.144.0/20 Facebook 16866.220.144.0/20 Facebook
16969.30.200.200/29 BitChute
13669.53.224.0/19 Netflix 17069.53.224.0/19 Netflix
13769.171.224.0/19 Facebook 17169.171.224.0/19 Facebook
17269.197.182.184/29 BitChute
17374.6.0.0/16 Yahoo
17474.91.29.208/29 BitChute
13887.250.254.0/24 Yandex 17587.250.254.0/24 Yandex
13991.105.192.0/23 Telegram 17691.105.192.0/23 Telegram
14091.108.4.0/22 Telegram 17791.108.4.0/22 Telegram
@@ -147,14 +184,21 @@
14791.189.94.0/24 Ubuntu One 18491.189.94.0/24 Ubuntu One
14895.161.64.0/20 Telegram 18595.161.64.0/20 Telegram
14999.181.64.0/18 Twitch 18699.181.64.0/18 Twitch
150103.53.48.0/23 Twitch 18769.197.138.24/29 BitChute
151104.244.40.0/21 Twitter
152103.10.124.0/23 Steam 188103.10.124.0/23 Steam
153103.28.54.0/24 Steam 189103.28.54.0/24 Steam
190103.53.48.0/23 Twitch
191104.244.40.0/21 Twitter
192107.150.32.0/19 BitChute
193107.150.35.192/29 BitChute
194107.150.45.120/29 BitChute
154108.160.160.0/20 Dropbox 195108.160.160.0/20 Dropbox
155108.175.32.0/20 Netflix 196108.175.32.0/20 Netflix
156129.134.0.0/16 Facebook 197129.134.0.0/16 Facebook
157140.82.112.0/20 GitHub 198140.82.112.0/20 GitHub
199142.54.180.104/29 BitChute
200142.54.181.184/29 BitChute
201142.54.189.192/29 BitChute
158143.55.64.0/20 Github 202143.55.64.0/20 Github
159146.66.152.0/24 Steam 203146.66.152.0/24 Steam
160146.66.155.0/24 Steam 204146.66.155.0/24 Steam
@@ -174,6 +218,10 @@
174162.213.32.0/22 Ubuntu One 218162.213.32.0/22 Ubuntu One
175162.254.192.0/21 Steam 219162.254.192.0/21 Steam
176172.98.56.0/22 Rumble 220172.98.56.0/22 Rumble
221173.208.154.8/29 BitChute
222173.208.154.160/29 BitChute
223173.208.185.200/29 BitChute
224173.208.219.112/29 BitChute
177178.154.131.0/24 Yandex 225178.154.131.0/24 Yandex
178185.2.220.0/22 Netflix 226185.2.220.0/22 Netflix
179185.9.188.0/22 Netflix 227185.9.188.0/22 Netflix
@@ -194,23 +242,33 @@
194192.30.252.0/22 GitHub 242192.30.252.0/22 GitHub
195192.69.96.0/22 Steam 243192.69.96.0/22 Steam
196192.108.239.0/24 Twitch 244192.108.239.0/24 Twitch
245192.151.158.136/29 BitChute
197192.173.64.0/18 Netflix 246192.173.64.0/18 Netflix
247192.187.97.88/29 BitChute
248192.187.114.96/29 BitChute
249192.187.123.112/29 BitChute
198192.189.200.0/23 Dropbox 250192.189.200.0/23 Dropbox
199194.169.254.0/24 Ubuntu One 251194.169.254.0/24 Ubuntu One
200198.38.96.0/19 Netflix 252198.38.96.0/19 Netflix
201198.45.48.0/20 Netflix 253198.45.48.0/20 Netflix
254198.204.226.120/29 BitChute
255198.204.245.88/29 BitChute
256198.252.206.0/24 Stack Exchange
202199.9.248.0/21 Twitch 257199.9.248.0/21 Twitch
203199.16.156.0/22 Twitter 258199.16.156.0/22 Twitter
204199.59.148.0/22 Twitter 259199.59.148.0/22 Twitter
205199.168.96.24/29 BitChute 260199.168.96.24/29 BitChute
261204.12.194.176/29 BitChute
206205.185.194.0/24 Steam 262205.185.194.0/24 Steam
207205.196.6.0/24 Steam 263205.196.6.0/24 Steam
208207.45.72.0/22 Netflix 264207.45.72.0/22 Netflix
209207.241.224.0/20 Internet Archive 265207.241.224.0/20 Internet Archive
266208.82.236.0/22 Creiglist
210208.64.200.0/22 Steam 267208.64.200.0/22 Steam
211208.75.76.0/22 Netflix 268208.75.76.0/22 Netflix
212208.78.164.0/22 Steam 269208.78.164.0/22 Steam
213208.80.152.0/22 Wikipedia 270208.80.152.0/22 Wikipedia
271208.110.68.56/29 BitChute
214209.140.128.0/18 eBay 272209.140.128.0/18 eBay
215 273
216# Imperva 274# Imperva
@@ -261,15 +319,6 @@
261205.224.0.0/14 Level 3 319205.224.0.0/14 Level 3
262209.244.0.0/14 Level 3 320209.244.0.0/14 Level 3
263 321
264# WholeSale Internet
26569.30.192.0/18 WholeSale Internet
26669.197.128.0/18 WholeSale Internet
267173.208.128.0/17 WholeSale Internet
268204.12.192.0/18 WholeSale Internet
269208.67.0.0/21 WholeSale Internet
270208.110.64.0/19 WholeSale Internet
271208.110.91.0/24 WholeSale Internet
272
273# StackPath 322# StackPath
27469.16.173.0/24 StackPath 32369.16.173.0/24 StackPath
27569.16.174.0/23 StackPath 32469.16.174.0/23 StackPath
@@ -279,6 +328,7 @@
279205.185.196.0/23 StackPath 328205.185.196.0/23 StackPath
280205.185.198.0/24 StackPath 329205.185.198.0/24 StackPath
281205.185.200.0/21 StackPath 330205.185.200.0/21 StackPath
331205.185.208.0/24 StackPath
282205.185.212.0/23 StackPath 332205.185.212.0/23 StackPath
283205.185.215.0/24 StackPath 333205.185.215.0/24 StackPath
284205.185.216.0/23 StackPath 334205.185.216.0/23 StackPath
@@ -299,6 +349,8 @@
299205.185.220.0/24 StackPath 349205.185.220.0/24 StackPath
300 350
301# Linode 351# Linode
35245.79.0.0/16 Linode
35350.116.0.0/18 Linode
30266.175.208.0/20 Linode 35466.175.208.0/20 Linode
303103.29.68.0/22 Linode 355103.29.68.0/22 Linode
304104.200.16.0/21 Linode 356104.200.16.0/21 Linode
@@ -397,6 +449,7 @@
397172.105.0.0/19 Linode 449172.105.0.0/19 Linode
398172.105.112.0/20 Linode 450172.105.112.0/20 Linode
399172.105.128.0/23 Linode 451172.105.128.0/23 Linode
452173.255.192.0/18 Linode
400 453
401# Akamai 454# Akamai
4022.16.0.0/13 Akamai 4552.16.0.0/13 Akamai
@@ -576,7 +629,7 @@
576103.21.244.0/22 Cloudflare 629103.21.244.0/22 Cloudflare
577103.22.200.0/22 Cloudflare 630103.22.200.0/22 Cloudflare
578103.31.4.0/22 Cloudflare 631103.31.4.0/22 Cloudflare
579104.16.0.0/13 Cloudflare 632104.16.0.0/12 Cloudflare
580104.24.0.0/14 Cloudflare 633104.24.0.0/14 Cloudflare
581108.162.192.0/18 Cloudflare 634108.162.192.0/18 Cloudflare
582131.0.72.0/22 Cloudflare 635131.0.72.0/22 Cloudflare
@@ -684,6 +737,7 @@
6843.136.0.0/13 Amazon 7373.136.0.0/13 Amazon
6853.144.0.0/13 Amazon 7383.144.0.0/13 Amazon
6863.152.0.0/13 Amazon 7393.152.0.0/13 Amazon
7403.160.0.0/14 Amazon
6873.208.0.0/12 Amazon 7413.208.0.0/12 Amazon
6883.224.0.0/12 Amazon 7423.224.0.0/12 Amazon
6893.240.0.0/13 Amazon 7433.240.0.0/13 Amazon