aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/codeql-analysis.yml6
-rw-r--r--.gitignore2
-rw-r--r--Makefile.in2
-rwxr-xr-xconfigure4
-rw-r--r--configure.ac2
-rw-r--r--etc/inc/disable-common.inc7
-rw-r--r--etc/inc/disable-programs.inc1
-rw-r--r--etc/profile-a-l/dnsmasq.profile9
-rw-r--r--etc/profile-m-z/steam.profile3
-rw-r--r--etc/profile-m-z/unbound.profile6
-rw-r--r--src/fnettrace-dns/Makefile.in17
-rw-r--r--src/fnettrace-dns/fnettrace_dns.h34
-rw-r--r--src/fnettrace-dns/main.c162
-rw-r--r--src/fnettrace-sni/Makefile.in17
-rw-r--r--src/fnettrace-sni/fnettrace_sni.h34
-rw-r--r--src/fnettrace-sni/main.c207
-rw-r--r--src/fnettrace/main.c52
-rw-r--r--src/fnettrace/static-ip-map2
18 files changed, 546 insertions, 21 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index e1d972d04..d58e0abd8 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -47,7 +47,7 @@ jobs:
47 47
48 # Initializes the CodeQL tools for scanning. 48 # Initializes the CodeQL tools for scanning.
49 - name: Initialize CodeQL 49 - name: Initialize CodeQL
50 uses: github/codeql-action/init@883476649888a9e8e219d5b2e6b789dc024f690c 50 uses: github/codeql-action/init@28eead240834b314f7def40f6fcba65d100d99b1
51 with: 51 with:
52 languages: ${{ matrix.language }} 52 languages: ${{ matrix.language }}
53 # If you wish to specify custom queries, you can do so here or in a config file. 53 # If you wish to specify custom queries, you can do so here or in a config file.
@@ -58,7 +58,7 @@ jobs:
58 # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 58 # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
59 # If this step fails, then you should remove it and run the build manually (see below) 59 # If this step fails, then you should remove it and run the build manually (see below)
60 - name: Autobuild 60 - name: Autobuild
61 uses: github/codeql-action/autobuild@883476649888a9e8e219d5b2e6b789dc024f690c 61 uses: github/codeql-action/autobuild@28eead240834b314f7def40f6fcba65d100d99b1
62 62
63 # ℹī¸ Command-line programs to run using the OS shell. 63 # ℹī¸ Command-line programs to run using the OS shell.
64 # 📚 https://git.io/JvXDl 64 # 📚 https://git.io/JvXDl
@@ -72,4 +72,4 @@ jobs:
72 # make release 72 # make release
73 73
74 - name: Perform CodeQL Analysis 74 - name: Perform CodeQL Analysis
75 uses: github/codeql-action/analyze@883476649888a9e8e219d5b2e6b789dc024f690c 75 uses: github/codeql-action/analyze@28eead240834b314f7def40f6fcba65d100d99b1
diff --git a/.gitignore b/.gitignore
index 29e0b63d6..e172d1af3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,8 @@ firemon.1
24firecfg.1 24firecfg.1
25jailcheck.1 25jailcheck.1
26mkdeb.sh 26mkdeb.sh
27src/fnettrace-dns/fnettrace-dns
28src/fnettrace-sni/fnettrace-sni
27src/firejail/firejail 29src/firejail/firejail
28src/firemon/firemon 30src/firemon/firemon
29src/firecfg/firecfg 31src/firecfg/firecfg
diff --git a/Makefile.in b/Makefile.in
index f38191880..9b1ecc4ad 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,7 @@ APPS = src/firecfg/firecfg src/firejail/firejail src/firemon/firemon src/profsta
29SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee src/fids/fids 29SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee src/fids/fids
30SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter 30SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter
31SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp 31SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp
32SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace 32SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace src/fnettrace-dns/fnettrace-dns src/fnettrace-sni/fnettrace-sni
33MYDIRS = src/lib $(MAN_SRC) $(COMPLETIONDIRS) 33MYDIRS = src/lib $(MAN_SRC) $(COMPLETIONDIRS)
34MYLIBS = src/libpostexecseccomp/libpostexecseccomp.so src/libtrace/libtrace.so src/libtracelog/libtracelog.so 34MYLIBS = src/libpostexecseccomp/libpostexecseccomp.so src/libtrace/libtrace.so src/libtracelog/libtracelog.so
35COMPLETIONS = src/zsh_completion/_firejail src/bash_completion/firejail.bash_completion 35COMPLETIONS = src/zsh_completion/_firejail src/bash_completion/firejail.bash_completion
diff --git a/configure b/configure
index 6611a8817..f0a678473 100755
--- a/configure
+++ b/configure
@@ -4288,7 +4288,7 @@ fi
4288 4288
4289ac_config_files="$ac_config_files mkdeb.sh" 4289ac_config_files="$ac_config_files mkdeb.sh"
4290 4290
4291ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile" 4291ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile src/fnettrace-dns/Makefile src/fnettrace-sni/Makefile"
4292 4292
4293cat >confcache <<\_ACEOF 4293cat >confcache <<\_ACEOF
4294# This file is a shell script that caches the results of configure 4294# This file is a shell script that caches the results of configure
@@ -5024,6 +5024,8 @@ do
5024 "src/jailcheck/Makefile") CONFIG_FILES="$CONFIG_FILES src/jailcheck/Makefile" ;; 5024 "src/jailcheck/Makefile") CONFIG_FILES="$CONFIG_FILES src/jailcheck/Makefile" ;;
5025 "src/fids/Makefile") CONFIG_FILES="$CONFIG_FILES src/fids/Makefile" ;; 5025 "src/fids/Makefile") CONFIG_FILES="$CONFIG_FILES src/fids/Makefile" ;;
5026 "src/fnettrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnettrace/Makefile" ;; 5026 "src/fnettrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnettrace/Makefile" ;;
5027 "src/fnettrace-dns/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnettrace-dns/Makefile" ;;
5028 "src/fnettrace-sni/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnettrace-sni/Makefile" ;;
5027 5029
5028 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 5030 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
5029 esac 5031 esac
diff --git a/configure.ac b/configure.ac
index 4ca30e6d7..071dea228 100644
--- a/configure.ac
+++ b/configure.ac
@@ -280,7 +280,7 @@ AC_CONFIG_FILES([Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/
280src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile \ 280src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile \
281src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile \ 281src/ftee/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile \
282src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile \ 282src/profstats/Makefile src/man/Makefile src/zsh_completion/Makefile src/bash_completion/Makefile test/Makefile \
283src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile]) 283src/jailcheck/Makefile src/fids/Makefile src/fnettrace/Makefile src/fnettrace-dns/Makefile src/fnettrace-sni/Makefile])
284AC_OUTPUT 284AC_OUTPUT
285 285
286cat <<EOF 286cat <<EOF
diff --git a/etc/inc/disable-common.inc b/etc/inc/disable-common.inc
index 2a0fec3c5..93679b472 100644
--- a/etc/inc/disable-common.inc
+++ b/etc/inc/disable-common.inc
@@ -599,7 +599,14 @@ noblacklist /var/lib/flatpak/exports
599blacklist /var/lib/flatpak/* 599blacklist /var/lib/flatpak/*
600 600
601# snap 601# snap
602blacklist ${HOME}/snap
603blacklist ${PATH}/snap
604blacklist ${PATH}/snapctl
602blacklist ${RUNUSER}/snapd-session-agent.socket 605blacklist ${RUNUSER}/snapd-session-agent.socket
606blacklist /snap
607blacklist /usr/lib/snapd
608blacklist /var/lib/snapd
609blacklist /var/snap
603 610
604# mail directories used by mutt 611# mail directories used by mutt
605blacklist ${HOME}/.Mail 612blacklist ${HOME}/.Mail
diff --git a/etc/inc/disable-programs.inc b/etc/inc/disable-programs.inc
index 558ae2446..e2e550368 100644
--- a/etc/inc/disable-programs.inc
+++ b/etc/inc/disable-programs.inc
@@ -815,6 +815,7 @@ blacklist ${HOME}/.local/share/Empathy
815blacklist ${HOME}/.local/share/Enpass 815blacklist ${HOME}/.local/share/Enpass
816blacklist ${HOME}/.local/share/FasterThanLight 816blacklist ${HOME}/.local/share/FasterThanLight
817blacklist ${HOME}/.local/share/Flavio Tordini 817blacklist ${HOME}/.local/share/Flavio Tordini
818blacklist ${HOME}/.local/share/HotlineMiami
818blacklist ${HOME}/.local/share/IntoTheBreach 819blacklist ${HOME}/.local/share/IntoTheBreach
819blacklist ${HOME}/.local/share/JetBrains 820blacklist ${HOME}/.local/share/JetBrains
820blacklist ${HOME}/.local/share/KDE/neochat 821blacklist ${HOME}/.local/share/KDE/neochat
diff --git a/etc/profile-a-l/dnsmasq.profile b/etc/profile-a-l/dnsmasq.profile
index 2db1548a4..13efd2fa8 100644
--- a/etc/profile-a-l/dnsmasq.profile
+++ b/etc/profile-a-l/dnsmasq.profile
@@ -9,9 +9,10 @@ include globals.local
9 9
10noblacklist /sbin 10noblacklist /sbin
11noblacklist /usr/sbin 11noblacklist /usr/sbin
12noblacklist /var/lib/libvirt
12 13
13blacklist /tmp/.X11-unix 14blacklist /tmp/.X11-unix
14blacklist ${RUNUSER}/wayland-* 15blacklist ${RUNUSER}
15 16
16include disable-common.inc 17include disable-common.inc
17include disable-devel.inc 18include disable-devel.inc
@@ -19,6 +20,9 @@ include disable-interpreters.inc
19include disable-programs.inc 20include disable-programs.inc
20include disable-xdg.inc 21include disable-xdg.inc
21 22
23whitelist /var/lib/libvirt/dnsmasq
24whitelist /var/run
25
22caps.keep net_admin,net_bind_service,net_raw,setgid,setuid 26caps.keep net_admin,net_bind_service,net_raw,setgid,setuid
23no3d 27no3d
24nodvd 28nodvd
@@ -33,5 +37,6 @@ seccomp
33 37
34disable-mnt 38disable-mnt
35private 39private
36private-cache
37private-dev 40private-dev
41private-tmp
42writable-var
diff --git a/etc/profile-m-z/steam.profile b/etc/profile-m-z/steam.profile
index 4137839f8..d6bc226a4 100644
--- a/etc/profile-m-z/steam.profile
+++ b/etc/profile-m-z/steam.profile
@@ -21,6 +21,7 @@ noblacklist ${HOME}/.local/share/cdprojektred
21noblacklist ${HOME}/.local/share/Dredmor 21noblacklist ${HOME}/.local/share/Dredmor
22noblacklist ${HOME}/.local/share/FasterThanLight 22noblacklist ${HOME}/.local/share/FasterThanLight
23noblacklist ${HOME}/.local/share/feral-interactive 23noblacklist ${HOME}/.local/share/feral-interactive
24noblacklist ${HOME}/.local/share/HotlineMiami
24noblacklist ${HOME}/.local/share/IntoTheBreach 25noblacklist ${HOME}/.local/share/IntoTheBreach
25noblacklist ${HOME}/.local/share/Paradox Interactive 26noblacklist ${HOME}/.local/share/Paradox Interactive
26noblacklist ${HOME}/.local/share/PillarsOfEternity 27noblacklist ${HOME}/.local/share/PillarsOfEternity
@@ -70,6 +71,7 @@ mkdir ${HOME}/.local/share/cdprojektred
70mkdir ${HOME}/.local/share/Dredmor 71mkdir ${HOME}/.local/share/Dredmor
71mkdir ${HOME}/.local/share/FasterThanLight 72mkdir ${HOME}/.local/share/FasterThanLight
72mkdir ${HOME}/.local/share/feral-interactive 73mkdir ${HOME}/.local/share/feral-interactive
74mkdir ${HOME}/.local/share/HotlineMiami
73mkdir ${HOME}/.local/share/IntoTheBreach 75mkdir ${HOME}/.local/share/IntoTheBreach
74mkdir ${HOME}/.local/share/Paradox Interactive 76mkdir ${HOME}/.local/share/Paradox Interactive
75mkdir ${HOME}/.local/share/PillarsOfEternity 77mkdir ${HOME}/.local/share/PillarsOfEternity
@@ -103,6 +105,7 @@ whitelist ${HOME}/.local/share/cdprojektred
103whitelist ${HOME}/.local/share/Dredmor 105whitelist ${HOME}/.local/share/Dredmor
104whitelist ${HOME}/.local/share/FasterThanLight 106whitelist ${HOME}/.local/share/FasterThanLight
105whitelist ${HOME}/.local/share/feral-interactive 107whitelist ${HOME}/.local/share/feral-interactive
108whitelist ${HOME}/.local/share/HotlineMiami
106whitelist ${HOME}/.local/share/IntoTheBreach 109whitelist ${HOME}/.local/share/IntoTheBreach
107whitelist ${HOME}/.local/share/Paradox Interactive 110whitelist ${HOME}/.local/share/Paradox Interactive
108whitelist ${HOME}/.local/share/PillarsOfEternity 111whitelist ${HOME}/.local/share/PillarsOfEternity
diff --git a/etc/profile-m-z/unbound.profile b/etc/profile-m-z/unbound.profile
index e8424cd7d..ef43ee822 100644
--- a/etc/profile-m-z/unbound.profile
+++ b/etc/profile-m-z/unbound.profile
@@ -10,7 +10,7 @@ noblacklist /sbin
10noblacklist /usr/sbin 10noblacklist /usr/sbin
11 11
12blacklist /tmp/.X11-unix 12blacklist /tmp/.X11-unix
13blacklist ${RUNUSER}/wayland-* 13blacklist ${RUNUSER}
14 14
15include disable-common.inc 15include disable-common.inc
16include disable-devel.inc 16include disable-devel.inc
@@ -19,8 +19,11 @@ include disable-interpreters.inc
19include disable-programs.inc 19include disable-programs.inc
20include disable-xdg.inc 20include disable-xdg.inc
21 21
22whitelist /usr/share/dns
22include whitelist-usr-share-common.inc 23include whitelist-usr-share-common.inc
23 24
25whitelist /var/lib/ca-certificates
26read-only /var/lib/ca-certificates
24whitelist /var/lib/unbound 27whitelist /var/lib/unbound
25whitelist /var/run 28whitelist /var/run
26 29
@@ -48,5 +51,4 @@ writable-var
48dbus-user none 51dbus-user none
49dbus-system none 52dbus-system none
50 53
51# mdwe can break modules/plugins
52memory-deny-write-execute 54memory-deny-write-execute
diff --git a/src/fnettrace-dns/Makefile.in b/src/fnettrace-dns/Makefile.in
new file mode 100644
index 000000000..6c11e5bc8
--- /dev/null
+++ b/src/fnettrace-dns/Makefile.in
@@ -0,0 +1,17 @@
1.PHONY: all
2all: fnettrace-dns
3
4include ../common.mk
5
6%.o : %.c $(H_FILE_LIST)
7 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
8
9fnettrace-dns: $(OBJS)
10 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
11
12.PHONY: clean
13clean:; rm -fr *.o fnettrace-dns *.gcov *.gcda *.gcno *.plist
14
15.PHONY: distclean
16distclean: clean
17 rm -fr Makefile
diff --git a/src/fnettrace-dns/fnettrace_dns.h b/src/fnettrace-dns/fnettrace_dns.h
new file mode 100644
index 000000000..db2e1a668
--- /dev/null
+++ b/src/fnettrace-dns/fnettrace_dns.h
@@ -0,0 +1,34 @@
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#ifndef FNETTRACE_DNS_H
21#define FNETTRACE_DNS_H
22
23#include "../include/common.h"
24#include <unistd.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <time.h>
30#include <stdarg.h>
31#include <fcntl.h>
32#include <sys/mman.h>
33
34#endif \ No newline at end of file
diff --git a/src/fnettrace-dns/main.c b/src/fnettrace-dns/main.c
new file mode 100644
index 000000000..0281b5157
--- /dev/null
+++ b/src/fnettrace-dns/main.c
@@ -0,0 +1,162 @@
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_dns.h"
21#include <sys/ioctl.h>
22#include <time.h>
23#include <linux/filter.h>
24#include <linux/if_ether.h>
25#define MAX_BUF_SIZE (64 * 1024)
26
27// pkt - start of DNS layer
28void print_dns(uint32_t ip_src, unsigned char *pkt) {
29 assert(pkt);
30
31 char ip[30];
32 sprintf(ip, "%d.%d.%d.%d", PRINT_IP(ip_src));
33 time_t seconds = time(NULL);
34 struct tm *t = localtime(&seconds);
35
36 // expecting a single question count
37 if (pkt[4] != 0 || pkt[5] != 1)
38 goto errout;
39
40 // check cname
41 unsigned char *ptr = pkt + 12;
42 int len = 0;
43 while (*ptr != 0 && len < 255) { // 255 is the maximum length of a domain name including multiple '.'
44 if (*ptr > 63) // the name left of a '.' is 63 length maximum
45 goto errout;
46
47 int delta = *ptr + 1;
48 *ptr = '.';
49 len += delta;;
50 ptr += delta;
51 }
52
53 printf("%02d:%02d:%02d %15s %s\n", t->tm_hour, t->tm_min, t->tm_sec, ip, pkt + 12 + 1);
54 return;
55
56errout:
57 printf("%02d:%02d:%02d %15s Error: invalid DNS packet\n", t->tm_hour, t->tm_min, t->tm_sec, ip);
58}
59
60// https://www.kernel.org/doc/html/latest/networking/filter.html
61static void custom_bpf(int sock) {
62 struct sock_filter code[] = {
63 // sudo tcpdump ip and udp and src port 53 -dd
64 { 0x28, 0, 0, 0x0000000c },
65 { 0x15, 0, 8, 0x00000800 },
66 { 0x30, 0, 0, 0x00000017 },
67 { 0x15, 0, 6, 0x00000011 },
68 { 0x28, 0, 0, 0x00000014 },
69 { 0x45, 4, 0, 0x00001fff },
70 { 0xb1, 0, 0, 0x0000000e },
71 { 0x48, 0, 0, 0x0000000e },
72 { 0x15, 0, 1, 0x00000035 },
73 { 0x6, 0, 0, 0x00040000 },
74 { 0x6, 0, 0, 0x00000000 },
75 };
76
77 struct sock_fprog bpf = {
78 .len = (unsigned short) sizeof(code) / sizeof(code[0]),
79 .filter = code,
80 };
81
82 int rv = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
83 if (rv < 0) {
84 fprintf(stderr, "Error: cannot attach BPF filter\n");
85 exit(1);
86 }
87}
88
89static void run_trace(void) {
90 // grab all Ethernet packets and use a custom BPF filter to get only UDP from source port 53
91 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
92 if (s < 0)
93 errExit("socket");
94 custom_bpf(s);
95
96 unsigned char buf[MAX_BUF_SIZE];
97 while (1) {
98 fd_set rfds;
99 FD_ZERO(&rfds);
100 FD_SET(s, &rfds);
101 struct timeval tv;
102 tv.tv_sec = 1;
103 tv.tv_usec = 0;
104 int rv = select(s + 1, &rfds, NULL, NULL, &tv);
105 if (rv < 0)
106 errExit("select");
107 else if (rv == 0)
108 continue;
109 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL);
110
111 if (bytes >= (14 + 20 + 8)) { // size of MAC + IP + UDP headers
112 uint8_t ip_hlen = (buf[14] & 0x0f) * 4;
113 uint16_t port_src;
114 memcpy(&port_src, buf + 14 + ip_hlen, 2);
115 port_src = ntohs(port_src);
116 uint8_t protocol = buf[14 + 9];
117 uint32_t ip_src;
118 memcpy(&ip_src, buf + 14 + 12, 4);
119 ip_src = ntohl(ip_src);
120
121 // if DNS packet, extract the query
122 if (port_src == 53 && protocol == 0x11) // UDP protocol
123 print_dns(ip_src, buf + 14 + ip_hlen + 8); // IP and UDP header len
124 }
125 }
126
127 close(s);
128}
129
130
131static void usage(void) {
132 printf("Usage: fnettrace-dns [OPTIONS]\n");
133 printf("Options:\n");
134 printf(" --help, -? - this help screen\n");
135 printf("\n");
136}
137
138int main(int argc, char **argv) {
139 int i;
140
141 for (i = 1; i < argc; i++) {
142 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") == 0) {
143 usage();
144 return 0;
145 }
146 else {
147 fprintf(stderr, "Error: invalid argument\n");
148 return 1;
149 }
150 }
151
152 if (getuid() != 0) {
153 fprintf(stderr, "Error: you need to be root to run this program\n");
154 return 1;
155 }
156
157 time_t now = time(NULL);
158 printf("DNS trace for %s\n", ctime(&now));
159 run_trace();
160
161 return 0;
162}
diff --git a/src/fnettrace-sni/Makefile.in b/src/fnettrace-sni/Makefile.in
new file mode 100644
index 000000000..9fe954874
--- /dev/null
+++ b/src/fnettrace-sni/Makefile.in
@@ -0,0 +1,17 @@
1.PHONY: all
2all: fnettrace-sni
3
4include ../common.mk
5
6%.o : %.c $(H_FILE_LIST)
7 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
8
9fnettrace-sni: $(OBJS)
10 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
11
12.PHONY: clean
13clean:; rm -fr *.o fnettrace-sni *.gcov *.gcda *.gcno *.plist
14
15.PHONY: distclean
16distclean: clean
17 rm -fr Makefile
diff --git a/src/fnettrace-sni/fnettrace_sni.h b/src/fnettrace-sni/fnettrace_sni.h
new file mode 100644
index 000000000..790a3ce7f
--- /dev/null
+++ b/src/fnettrace-sni/fnettrace_sni.h
@@ -0,0 +1,34 @@
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#ifndef FNETTRACE_SNI_H
21#define FNETTRACE_SNI_H
22
23#include "../include/common.h"
24#include <unistd.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <time.h>
30#include <stdarg.h>
31#include <fcntl.h>
32#include <sys/mman.h>
33
34#endif \ No newline at end of file
diff --git a/src/fnettrace-sni/main.c b/src/fnettrace-sni/main.c
new file mode 100644
index 000000000..ea7a91548
--- /dev/null
+++ b/src/fnettrace-sni/main.c
@@ -0,0 +1,207 @@
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_sni.h"
21#include <sys/ioctl.h>
22#include <time.h>
23#include <linux/filter.h>
24#include <linux/if_ether.h>
25#define MAX_BUF_SIZE (64 * 1024)
26
27// pkt - start of TLS layer
28static void print_tls(uint32_t ip_dest, unsigned char *pkt, unsigned len) {
29 assert(pkt);
30
31 char ip[30];
32 sprintf(ip, "%d.%d.%d.%d", PRINT_IP(ip_dest));
33 time_t seconds = time(NULL);
34 struct tm *t = localtime(&seconds);
35
36 // expecting a handshake packet and client hello
37 if (pkt[0] != 0x16 || pkt[5] != 0x01)
38 goto errout;
39
40
41 // look for server name indication
42 unsigned char *ptr = pkt;
43 unsigned int i = 0;
44 char *name = NULL;
45 while (i < (len - 20)) {
46 // 3 zeros and 3 matching length fields
47 if (*ptr == 0 && *(ptr + 1) == 0 && (*(ptr + 2) == 0 || *(ptr + 2) == 1) && *(ptr + 6) == 0) {
48 uint16_t len1;
49 memcpy(&len1, ptr + 2, 2);
50 len1 = ntohs(len1);
51
52 uint16_t len2;
53 memcpy(&len2, ptr + 4, 2);
54 len2 = ntohs(len2);
55
56 uint16_t len3;
57 memcpy(&len3, ptr + 7, 2);
58 len3 = ntohs(len3);
59
60 if (len1 == (len2 + 2) && len1 == (len3 + 5)) {
61 *(ptr + 9 + len3) = 0;
62 name = (char *) (ptr + 9);
63 break;
64 }
65 }
66 ptr++;
67 i++;
68 }
69
70 if (name)
71 printf("%02d:%02d:%02d %15s %s\n", t->tm_hour, t->tm_min, t->tm_sec, ip, name);
72 else
73 goto nosni;
74 return;
75
76errout:
77 printf("%02d:%02d:%02d %15s Error: invalid TLS packet\n", t->tm_hour, t->tm_min, t->tm_sec, ip);
78 return;
79
80nosni:
81 printf("%02d:%02d:%02d %15s no SNI\n", t->tm_hour, t->tm_min, t->tm_sec, ip);
82 return;
83}
84
85// https://www.kernel.org/doc/html/latest/networking/filter.html
86static void custom_bpf(int sock) {
87 struct sock_filter code[] = {
88 // sudo tcpdump "tcp port 443 and (tcp[((tcp[12] & 0xf0) >>2)] = 0x16) && (tcp[((tcp[12] & 0xf0) >>2)+5] = 0x01)" -dd
89 { 0x28, 0, 0, 0x0000000c },
90 { 0x15, 27, 0, 0x000086dd },
91 { 0x15, 0, 26, 0x00000800 },
92 { 0x30, 0, 0, 0x00000017 },
93 { 0x15, 0, 24, 0x00000006 },
94 { 0x28, 0, 0, 0x00000014 },
95 { 0x45, 22, 0, 0x00001fff },
96 { 0xb1, 0, 0, 0x0000000e },
97 { 0x48, 0, 0, 0x0000000e },
98 { 0x15, 2, 0, 0x000001bb },
99 { 0x48, 0, 0, 0x00000010 },
100 { 0x15, 0, 17, 0x000001bb },
101 { 0x50, 0, 0, 0x0000001a },
102 { 0x54, 0, 0, 0x000000f0 },
103 { 0x74, 0, 0, 0x00000002 },
104 { 0xc, 0, 0, 0x00000000 },
105 { 0x7, 0, 0, 0x00000000 },
106 { 0x50, 0, 0, 0x0000000e },
107 { 0x15, 0, 10, 0x00000016 },
108 { 0xb1, 0, 0, 0x0000000e },
109 { 0x50, 0, 0, 0x0000001a },
110 { 0x54, 0, 0, 0x000000f0 },
111 { 0x74, 0, 0, 0x00000002 },
112 { 0x4, 0, 0, 0x00000005 },
113 { 0xc, 0, 0, 0x00000000 },
114 { 0x7, 0, 0, 0x00000000 },
115 { 0x50, 0, 0, 0x0000000e },
116 { 0x15, 0, 1, 0x00000001 },
117 { 0x6, 0, 0, 0x00040000 },
118 { 0x6, 0, 0, 0x00000000 },
119 };
120
121 struct sock_fprog bpf = {
122 .len = (unsigned short) sizeof(code) / sizeof(code[0]),
123 .filter = code,
124 };
125
126 int rv = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
127 if (rv < 0) {
128 fprintf(stderr, "Error: cannot attach BPF filter\n");
129 exit(1);
130 }
131}
132
133static void run_trace(void) {
134 // grab all Ethernet packets and use a custom BPF filter to get only UDP from source port 53
135 int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
136 if (s < 0)
137 errExit("socket");
138 custom_bpf(s);
139
140 unsigned char buf[MAX_BUF_SIZE];
141 while (1) {
142 fd_set rfds;
143 FD_ZERO(&rfds);
144 FD_SET(s, &rfds);
145 struct timeval tv;
146 tv.tv_sec = 1;
147 tv.tv_usec = 0;
148 int rv = select(s + 1, &rfds, NULL, NULL, &tv);
149 if (rv < 0)
150 errExit("select");
151 else if (rv == 0)
152 continue;
153 unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL);
154
155 if (bytes >= (14 + 20 + 20)) { // size of MAC + IP + TCP headers
156 uint8_t ip_hlen = (buf[14] & 0x0f) * 4;
157 uint16_t port_dest;
158 memcpy(&port_dest, buf + 14 + ip_hlen + 2, 2);
159 port_dest = ntohs(port_dest);
160 uint8_t protocol = buf[14 + 9];
161 uint32_t ip_dest;
162 memcpy(&ip_dest, buf + 14 + 16, 4);
163 ip_dest = ntohl(ip_dest);
164 uint8_t tcp_hlen = (buf[14 + ip_hlen + 12] & 0xf0) >> 2;
165
166 // if TLS packet, extract SNI
167 if (port_dest == 443 && protocol == 6) // TCP protocol
168 print_tls(ip_dest, buf + 14 + ip_hlen + tcp_hlen, bytes - 14 - ip_hlen - tcp_hlen); // IP and TCP header len
169 }
170 }
171
172 close(s);
173}
174
175
176static void usage(void) {
177 printf("Usage: fnettrace-sni [OPTIONS]\n");
178 printf("Options:\n");
179 printf(" --help, -? - this help screen\n");
180 printf("\n");
181}
182
183int main(int argc, char **argv) {
184 int i;
185
186 for (i = 1; i < argc; i++) {
187 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") == 0) {
188 usage();
189 return 0;
190 }
191 else {
192 fprintf(stderr, "Error: invalid argument\n");
193 return 1;
194 }
195 }
196
197 if (getuid() != 0) {
198 fprintf(stderr, "Error: you need to be root to run this program\n");
199 return 1;
200 }
201
202 time_t now = time(NULL);
203 printf("SNI trace for %s\n", ctime(&now));
204 run_trace();
205
206 return 0;
207}
diff --git a/src/fnettrace/main.c b/src/fnettrace/main.c
index 31d49d839..fd3cd5016 100644
--- a/src/fnettrace/main.c
+++ b/src/fnettrace/main.c
@@ -28,7 +28,7 @@ static char *arg_log = NULL;
28 28
29typedef struct hnode_t { 29typedef struct hnode_t {
30 struct hnode_t *hnext; // used for hash table and unused linked list 30 struct hnode_t *hnext; // used for hash table and unused linked list
31 struct hnode_t *dnext; // used to display stremas on the screen 31 struct hnode_t *dnext; // used to display streams on the screen
32 uint32_t ip_src; 32 uint32_t ip_src;
33 uint32_t bytes; // number of bytes received in the last display interval 33 uint32_t bytes; // number of bytes received in the last display interval
34 uint16_t port_src; 34 uint16_t port_src;
@@ -221,6 +221,35 @@ static unsigned adjust_bandwidth(unsigned bw) {
221 return (max < (sum / 2))? sum: max; 221 return (max < (sum / 2))? sum: max;
222} 222}
223 223
224static inline const char *common_port(uint16_t port) {
225 if (port > 123)
226 return NULL;
227
228 if (port == 20 || port == 21)
229 return "(FTP)";
230 else if (port == 22)
231 return "(SSH)";
232 else if (port == 23)
233 return "(telnet)";
234 else if (port == 25)
235 return "(SMTP)";
236 else if (port == 67)
237 return "(DHCP)";
238 else if (port == 69)
239 return "(TFTP)";
240 else if (port == 80)
241 return "(HTTP)";
242 else if (port == 109)
243 return "(POP2)";
244 else if (port == 110)
245 return "(POP3)";
246 else if (port == 123)
247 return "(NTP)";
248
249 return NULL;
250}
251
252
224static void hnode_print(unsigned bw) { 253static void hnode_print(unsigned bw) {
225 assert(!arg_netfilter); 254 assert(!arg_netfilter);
226 bw = (bw < 1024 * DISPLAY_INTERVAL)? 1024 * DISPLAY_INTERVAL: bw; 255 bw = (bw < 1024 * DISPLAY_INTERVAL)? 1024 * DISPLAY_INTERVAL: bw;
@@ -285,19 +314,19 @@ static void hnode_print(unsigned bw) {
285 else 314 else
286 bwline = print_bw(ptr->bytes / bwunit); 315 bwline = print_bw(ptr->bytes / bwunit);
287 316
288 char *protocol = ""; 317 const char *protocol = NULL;
289 if (ptr->port_src == 80) 318 if (ptr->port_src == 443)
290 protocol = "(HTTP)"; 319 protocol = "(TLS)";
320 else if (ptr->port_src == 53)
321 protocol = "(DNS)";
291 else if (ptr->port_src == 853) 322 else if (ptr->port_src == 853)
292 protocol = "(DoT)"; 323 protocol = "(DoT)";
324 else if ((protocol = common_port(ptr->port_src)) != NULL)
325 ;
293 else if (ptr->protocol == 0x11) 326 else if (ptr->protocol == 0x11)
294 protocol = "(UDP)"; 327 protocol = "(UDP)";
295/* 328 if (protocol == NULL)
296 else (ptr->port_src == 443) 329 protocol = "";
297 protocol = "TLS";
298 else if (ptr->port_src == 53)
299 protocol = "DNS";
300*/
301 330
302 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s\n", 331 len = snprintf(line, LINE_MAX, "%10s %s %d.%d.%d.%d:%u%s %s\n",
303 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->hostname); 332 bytes, bwline, PRINT_IP(ptr->ip_src), ptr->port_src, protocol, ptr->hostname);
@@ -409,7 +438,8 @@ static void run_trace(void) {
409 memcpy(&port_src, buf + hlen, 2); 438 memcpy(&port_src, buf + hlen, 2);
410 port_src = ntohs(port_src); 439 port_src = ntohs(port_src);
411 440
412 hnode_add(ip_src, buf[9], port_src, bytes + 14); 441 uint8_t protocol = buf[9];
442 hnode_add(ip_src, protocol, port_src, bytes + 14);
413 } 443 }
414 } 444 }
415 } 445 }
diff --git a/src/fnettrace/static-ip-map b/src/fnettrace/static-ip-map
index e24ecf218..17ffe7f82 100644
--- a/src/fnettrace/static-ip-map
+++ b/src/fnettrace/static-ip-map
@@ -37,8 +37,10 @@
37192.168.0.0/16 local network 37192.168.0.0/16 local network
3810.0.0.0/8 local network 3810.0.0.0/8 local network
39172.16.0.0/16 local network 39172.16.0.0/16 local network
40169.254.0.0/16 local link
40 41
41# huge address ranges 42# huge address ranges
434.0.0.0/9 Level 3
426.0.0.0/8 US Army 446.0.0.0/8 US Army
437.0.0.0/8 US Army 457.0.0.0/8 US Army
449.0.0.0/8 IBM 469.0.0.0/8 IBM