aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2022-02-02 10:58:14 -0500
committerLibravatar netblue30 <netblue30@protonmail.com>2022-02-02 10:58:14 -0500
commitf5c0b6af59b4c5e4c677d8bd9703beb4d2e628c3 (patch)
treeacc78a5c8591f832c25bee1f988373540993db9e
parentBump github/codeql-action from 1.0.29 to 1.0.30 (diff)
downloadfirejail-f5c0b6af59b4c5e4c677d8bd9703beb4d2e628c3.tar.gz
firejail-f5c0b6af59b4c5e4c677d8bd9703beb4d2e628c3.tar.zst
firejail-f5c0b6af59b4c5e4c677d8bd9703beb4d2e628c3.zip
netlocker fixes
-rw-r--r--src/firejail/netfilter.c11
-rw-r--r--src/firejail/usage.c1
-rw-r--r--src/fnettrace/fnettrace.h8
-rw-r--r--src/fnettrace/main.c38
-rw-r--r--src/fnettrace/tail.c63
-rw-r--r--src/jailcheck/network.c1
-rw-r--r--src/man/firejail.txt12
7 files changed, 117 insertions, 17 deletions
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 939ab29fa..5b49fe19a 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -41,17 +41,16 @@ void netfilter_netlock(pid_t pid) {
41 41
42 // try to find a X terminal 42 // try to find a X terminal
43 char *terminal = NULL; 43 char *terminal = NULL;
44 if (access("/usr/bin/lxterminal", X_OK) == 0) 44 if (access("/usr/bin/xterm", X_OK) == 0)
45 terminal = "/usr/bin/lxterminal";
46 else if (access("/usr/bin/xterm", X_OK) == 0)
47 terminal = "/usr/bin/xterm"; 45 terminal = "/usr/bin/xterm";
46 else if (access("/usr/bin/lxterminal", X_OK) == 0)
47 terminal = "/usr/bin/lxterminal";
48 else if (access("/usr/bin/xfce4-terminal", X_OK) == 0) 48 else if (access("/usr/bin/xfce4-terminal", X_OK) == 0)
49 terminal = "/usr/bin/xfce4-terminal"; 49 terminal = "/usr/bin/xfce4-terminal";
50 else if (access("/usr/bin/konsole", X_OK) == 0) 50 else if (access("/usr/bin/konsole", X_OK) == 0)
51 terminal = "/usr/bin/konsole"; 51 terminal = "/usr/bin/konsole";
52// problem: newer gnome-terminal versions don't support -e command line option??? 52// problem: newer gnome-terminal versions don't support -e command line option???
53// else if (access("/usr/bin/gnome-terminal", X_OK) == 0) 53// same for mate-terminal
54// terminal = "/usr/bin/gnome-terminal";
55 54
56 if (isatty(STDIN_FILENO)) 55 if (isatty(STDIN_FILENO))
57 terminal = NULL; 56 terminal = NULL;
@@ -64,7 +63,7 @@ void netfilter_netlock(pid_t pid) {
64 drop_privs(0); 63 drop_privs(0);
65 64
66 char *cmd; 65 char *cmd;
67 if (asprintf(&cmd, "%s -e \"tail -f %s\"", terminal, flog) == -1) 66 if (asprintf(&cmd, "%s -e \"%s/firejail/fnettrace --tail --log=%s\"", terminal, LIBDIR, flog) == -1)
68 errExit("asprintf"); 67 errExit("asprintf");
69 int rv = system(cmd); 68 int rv = system(cmd);
70 (void) rv; 69 (void) rv;
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index c903841c5..0b24467be 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -147,6 +147,7 @@ static char *usage_str =
147 " --netfilter.print=name|pid - print the firewall.\n" 147 " --netfilter.print=name|pid - print the firewall.\n"
148 " --netfilter6=filename - enable IPv6 firewall.\n" 148 " --netfilter6=filename - enable IPv6 firewall.\n"
149 " --netfilter6.print=name|pid - print the IPv6 firewall.\n" 149 " --netfilter6.print=name|pid - print the IPv6 firewall.\n"
150 " --netlock - enable the network locking feature\n"
150 " --netmask=address - define a network mask when dealing with unconfigured\n" 151 " --netmask=address - define a network mask when dealing with unconfigured\n"
151 "\tparent interfaces.\n" 152 "\tparent interfaces.\n"
152 " --netns=name - Run the program in a named, persistent network namespace.\n" 153 " --netns=name - Run the program in a named, persistent network namespace.\n"
diff --git a/src/fnettrace/fnettrace.h b/src/fnettrace/fnettrace.h
index 66b7378da..b30a9f10d 100644
--- a/src/fnettrace/fnettrace.h
+++ b/src/fnettrace/fnettrace.h
@@ -23,10 +23,15 @@
23#include "../include/common.h" 23#include "../include/common.h"
24#include <unistd.h> 24#include <unistd.h>
25#include <sys/stat.h> 25#include <sys/stat.h>
26#include <sys/types.h>
26#include <sys/socket.h> 27#include <sys/socket.h>
27#include <netinet/in.h> 28#include <netinet/in.h>
28#include <time.h> 29#include <time.h>
29#include <stdarg.h> 30#include <stdarg.h>
31#include <fcntl.h>
32#include <sys/mman.h>
33
34
30//#define DEBUG 1 35//#define DEBUG 1
31 36
32#define NETLOCK_INTERVAL 60 // seconds 37#define NETLOCK_INTERVAL 60 // seconds
@@ -62,4 +67,7 @@ extern int geoip_calls;
62void load_hostnames(const char *fname); 67void load_hostnames(const char *fname);
63char* retrieve_hostname(uint32_t ip); 68char* retrieve_hostname(uint32_t ip);
64 69
70// tail.c
71void tail(const char *logfile);
72
65#endif \ No newline at end of file 73#endif \ No newline at end of file
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c
index e58cc79b3..31d49d839 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -23,6 +23,7 @@
23#define MAX_BUF_SIZE (64 * 1024) 23#define MAX_BUF_SIZE (64 * 1024)
24 24
25static int arg_netfilter = 0; 25static int arg_netfilter = 0;
26static int arg_tail = 0;
26static char *arg_log = NULL; 27static char *arg_log = NULL;
27 28
28typedef struct hnode_t { 29typedef struct hnode_t {
@@ -574,11 +575,16 @@ void logprintf(char* fmt, ...) {
574} 575}
575 576
576static void usage(void) { 577static void usage(void) {
577 printf("Usage: fnetlock [OPTIONS]\n"); 578 printf("Usage: fnettrace [OPTIONS]\n");
578 printf("Options:\n"); 579 printf("Options:\n");
579 printf(" --help, -? - this help screen\n"); 580 printf(" --help, -? - this help screen\n");
580 printf(" --log=filename - netlocker logfile\n"); 581 printf(" --log=filename - netlocker logfile\n");
581 printf(" --netfilter - build the firewall rules and commit them.\n"); 582 printf(" --netfilter - build the firewall rules and commit them.\n");
583 printf(" --tail - \"tail -f\" functionality\n");
584 printf("Examples:\n");
585 printf(" # fnettrace - traffic trace\n");
586 printf(" # fnettrace --netfilter --log=logfile - netlocker, dump output in logfile\n");
587 printf(" # fnettrace --tail --log=logifile - similar to \"tail -f logfile\"\n");
582 printf("\n"); 588 printf("\n");
583} 589}
584 590
@@ -599,11 +605,6 @@ int main(int argc, char **argv) {
599 printf("%s\n", name); 605 printf("%s\n", name);
600#endif 606#endif
601 607
602 if (getuid() != 0) {
603 fprintf(stderr, "Error: you need to be root to run this program\n");
604 return 1;
605 }
606
607 for (i = 1; i < argc; i++) { 608 for (i = 1; i < argc; i++) {
608 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") == 0) { 609 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") == 0) {
609 usage(); 610 usage();
@@ -611,6 +612,8 @@ int main(int argc, char **argv) {
611 } 612 }
612 else if (strcmp(argv[i], "--netfilter") == 0) 613 else if (strcmp(argv[i], "--netfilter") == 0)
613 arg_netfilter = 1; 614 arg_netfilter = 1;
615 else if (strcmp(argv[i], "--tail") == 0)
616 arg_tail = 1;
614 else if (strncmp(argv[i], "--log=", 6) == 0) 617 else if (strncmp(argv[i], "--log=", 6) == 0)
615 arg_log = argv[i] + 6; 618 arg_log = argv[i] + 6;
616 else { 619 else {
@@ -619,6 +622,24 @@ int main(int argc, char **argv) {
619 } 622 }
620 } 623 }
621 624
625 // tail
626 if (arg_tail) {
627 if (!arg_log) {
628 fprintf(stderr, "Error: no log file\n");
629 usage();
630 exit(1);
631 }
632
633 tail(arg_log);
634 sleep(5);
635 exit(0);
636 }
637
638 if (getuid() != 0) {
639 fprintf(stderr, "Error: you need to be root to run this program\n");
640 return 1;
641 }
642
622 ansi_clrscr(); 643 ansi_clrscr();
623 if (arg_netfilter) 644 if (arg_netfilter)
624 logprintf("starting network lockdown\n"); 645 logprintf("starting network lockdown\n");
@@ -629,6 +650,11 @@ int main(int argc, char **argv) {
629 650
630 run_trace(); 651 run_trace();
631 if (arg_netfilter) { 652 if (arg_netfilter) {
653 // TCP path MTU discovery will not work properly since the firewall drops all ICMP packets
654 // Instead, we use iPacketization Layer PMTUD (RFC 4821) support in Linux kernel
655 int rv = system("echo 1 > /proc/sys/net/ipv4/tcp_mtu_probing");
656 (void) rv;
657
632 deploy_netfilter(); 658 deploy_netfilter();
633 sleep(3); 659 sleep(3);
634 if (arg_log) 660 if (arg_log)
diff --git a/src/fnettrace/tail.c b/src/fnettrace/tail.c
new file mode 100644
index 000000000..a910788d6
--- /dev/null
+++ b/src/fnettrace/tail.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2014-2022 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
22void tail(const char *logfile) {
23 assert(logfile);
24
25 // wait for no more than 5 seconds for the logfile to appear in the filesystem
26 int cnt = 5;
27 while (access(logfile, R_OK) && cnt > 0)
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 }
63}
diff --git a/src/jailcheck/network.c b/src/jailcheck/network.c
index 474224fc5..8f70c6ff0 100644
--- a/src/jailcheck/network.c
+++ b/src/jailcheck/network.c
@@ -40,6 +40,7 @@ void network_test(void) {
40 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { 40 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
41 if (strcmp(ifa->ifa_name, "lo") == 0) 41 if (strcmp(ifa->ifa_name, "lo") == 0)
42 continue; 42 continue;
43
43 found = 1; 44 found = 1;
44 break; 45 break;
45 } 46 }
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 59dc5d310..4cbe7f13d 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1458,17 +1458,19 @@ $ firejail --name=browser --net=eth0 --netfilter firefox &
1458$ firejail --netfilter6.print=browser 1458$ firejail --netfilter6.print=browser
1459 1459
1460.TP 1460.TP
1461\fB\-\-netlock=name/pid 1461\fB\-\-netlock
1462Several type of programs (email clients, multiplayer games etc.) talk to a very small 1462Several type of programs (email clients, multiplayer games etc.) talk to a very small
1463number of IP addresses. But the best example is tor browser. It only talks to a guard node, 1463number of IP addresses. But the best example is tor browser. It only talks to a guard node,
1464and there are two or three more on standby in case the main one fails. 1464and there are two or three more on standby in case the main one fails.
1465During startup, the browser contacts all of them, after that it keeps talking to the main 1465During startup, the browser contacts all of them, after that it keeps talking to the main
1466one... for weeks! 1466one... for weeks!
1467 1467
1468Use the network locking feature to build and deploy a network firewall in your sandbox. 1468Use the network locking feature to build and deploy a custom network firewall in your sandbox.
1469The firewall allows only the network traffic to the IP addresses detected during the program 1469The firewall allows only the traffic to the IP addresses detected during the program
1470startup. Traffic to any other address is quietly dropped. By default the startup monitoring 1470startup. Traffic to any other address is quietly dropped. By default the network monitoring
1471time is one minute. Example: 1471time is one minute.
1472
1473A network namespace (\-\-net=eth0) is required for this feature to work. Example:
1472.br 1474.br
1473 1475
1474.br 1476.br