aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--etc/firejail.config4
-rw-r--r--etc/inc/disable-interpreters.inc3
-rw-r--r--etc/inc/disable-programs.inc2
-rw-r--r--etc/profile-a-l/1password.profile2
-rw-r--r--etc/profile-a-l/abrowser.profile1
-rw-r--r--etc/profile-a-l/audacious.profile13
-rw-r--r--etc/profile-a-l/basilisk.profile1
-rw-r--r--etc/profile-a-l/brave.profile4
-rw-r--r--etc/profile-a-l/cachy-browser.profile11
-rw-r--r--etc/profile-a-l/cliqz.profile1
-rw-r--r--etc/profile-a-l/cyberfox.profile2
-rw-r--r--etc/profile-a-l/discord-ptb.profile14
-rw-r--r--etc/profile-a-l/firedragon.profile1
-rw-r--r--etc/profile-a-l/firefox-common-addons.profile1
-rw-r--r--etc/profile-a-l/firefox-common.profile5
-rw-r--r--etc/profile-a-l/firefox.profile9
-rw-r--r--etc/profile-a-l/gnome-calendar.profile2
-rw-r--r--etc/profile-a-l/icecat.profile1
-rw-r--r--etc/profile-a-l/krunner.profile6
-rw-r--r--etc/profile-a-l/kube.profile19
-rw-r--r--etc/profile-a-l/librewolf.profile9
-rw-r--r--etc/profile-m-z/minetest.profile5
-rw-r--r--etc/profile-m-z/mov-cli.profile4
-rw-r--r--etc/profile-m-z/mpv.profile2
-rw-r--r--etc/profile-m-z/nodejs-common.profile2
-rw-r--r--etc/profile-m-z/noprofile.profile15
-rw-r--r--etc/profile-m-z/palemoon.profile2
-rw-r--r--etc/profile-m-z/pingus.profile3
-rw-r--r--etc/profile-m-z/rtin.profile2
-rw-r--r--etc/profile-m-z/signal-desktop.profile8
-rw-r--r--etc/profile-m-z/sniffnet.profile49
-rw-r--r--etc/profile-m-z/spotify.profile11
-rw-r--r--etc/profile-m-z/steam.profile4
-rw-r--r--etc/profile-m-z/thunderbird.profile3
-rw-r--r--etc/profile-m-z/tin.profile4
-rw-r--r--etc/profile-m-z/trojita.profile11
-rw-r--r--etc/profile-m-z/waterfox.profile1
-rw-r--r--src/firecfg/firecfg.config1
-rw-r--r--src/firejail/netfilter.c4
-rw-r--r--src/fnetlock/Makefile9
-rw-r--r--src/fnetlock/fnetlock.h51
-rw-r--r--src/fnetlock/main.c394
-rw-r--r--src/fnetlock/tail.c (renamed from src/fnettrace/tail.c)2
-rw-r--r--src/fnettrace-dns/main.c16
-rw-r--r--src/fnettrace-sni/main.c2
-rw-r--r--src/fnettrace/fnettrace.h3
-rw-r--r--src/fnettrace/main.c486
-rw-r--r--src/fnettrace/runprog.c31
-rw-r--r--src/fnettrace/static-ip-map.txt94
50 files changed, 961 insertions, 371 deletions
diff --git a/Makefile b/Makefile
index 6e3593d20..03ae71026 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ SBOX_APPS = src/fbuilder/fbuilder src/ftee/ftee src/fids/fids
17SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter src/fzenity/fzenity 17SBOX_APPS_NON_DUMPABLE = src/fcopy/fcopy src/fldd/fldd src/fnet/fnet src/fnetfilter/fnetfilter src/fzenity/fzenity
18SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp 18SBOX_APPS_NON_DUMPABLE += src/fsec-optimize/fsec-optimize src/fsec-print/fsec-print src/fseccomp/fseccomp
19SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace src/fnettrace-dns/fnettrace-dns src/fnettrace-sni/fnettrace-sni 19SBOX_APPS_NON_DUMPABLE += src/fnettrace/fnettrace src/fnettrace-dns/fnettrace-dns src/fnettrace-sni/fnettrace-sni
20SBOX_APPS_NON_DUMPABLE += src/fnettrace-icmp/fnettrace-icmp 20SBOX_APPS_NON_DUMPABLE += src/fnettrace-icmp/fnettrace-icmp src/fnetlock/fnetlock
21MYDIRS = src/lib $(COMPLETIONDIRS) 21MYDIRS = src/lib $(COMPLETIONDIRS)
22MYLIBS = src/libpostexecseccomp/libpostexecseccomp.so src/libtrace/libtrace.so src/libtracelog/libtracelog.so 22MYLIBS = src/libpostexecseccomp/libpostexecseccomp.so src/libtrace/libtrace.so src/libtracelog/libtracelog.so
23COMPLETIONS = src/zsh_completion/_firejail src/bash_completion/firejail.bash_completion 23COMPLETIONS = src/zsh_completion/_firejail src/bash_completion/firejail.bash_completion
diff --git a/etc/firejail.config b/etc/firejail.config
index e8bf45751..c3c355e3d 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -163,12 +163,12 @@
163# Xpra server command extra parameters. None by default; this is an example. 163# Xpra server command extra parameters. None by default; this is an example.
164# xpra-extra-params --dpi 96 164# xpra-extra-params --dpi 96
165 165
166# Screen size for --x11=xvfb, default 800x600x24. The third dimension is 166# Screen size for --x11=xvfb, default 800x600x24. The third dimension is
167# color depth; use 24 unless you know exactly what you're doing. 167# color depth; use 24 unless you know exactly what you're doing.
168# xvfb-screen 640x480x24 168# xvfb-screen 640x480x24
169# xvfb-screen 800x600x24 169# xvfb-screen 800x600x24
170# xvfb-screen 1024x768x24 170# xvfb-screen 1024x768x24
171# xvfb-screen 1280x1024x24 171# xvfb-screen 1280x1024x24
172 172
173# Xvfb command extra parameters. None by default; this is an example. 173# Xvfb command extra parameters. None by default; this is an example.
174# xvfb-extra-params -pixdepths 8 24 32 174# xvfb-extra-params -pixdepths 8 24 32
diff --git a/etc/inc/disable-interpreters.inc b/etc/inc/disable-interpreters.inc
index 4e3590fed..e4497f832 100644
--- a/etc/inc/disable-interpreters.inc
+++ b/etc/inc/disable-interpreters.inc
@@ -44,8 +44,7 @@ blacklist /usr/share/perl*
44# it is needed so that Firefox can run applications with Terminal=true in 44# it is needed so that Firefox can run applications with Terminal=true in
45# their .desktop file (depending on what is installed). The reason is that 45# their .desktop file (depending on what is installed). The reason is that
46# this is done via glib, which currently uses a hardcoded list of terminal 46# this is done via glib, which currently uses a hardcoded list of terminal
47# emulators: 47# emulators: https://gitlab.gnome.org/GNOME/glib/-/issues/338.
48# https://gitlab.gnome.org/GNOME/glib/-/issues/338
49# And in this list, rxvt comes before xterm. 48# And in this list, rxvt comes before xterm.
50blacklist ${PATH}/rxvt 49blacklist ${PATH}/rxvt
51 50
diff --git a/etc/inc/disable-programs.inc b/etc/inc/disable-programs.inc
index 29d5a8700..b0d1b7a66 100644
--- a/etc/inc/disable-programs.inc
+++ b/etc/inc/disable-programs.inc
@@ -547,6 +547,7 @@ blacklist ${HOME}/.config/midori
547blacklist ${HOME}/.config/mirage 547blacklist ${HOME}/.config/mirage
548blacklist ${HOME}/.config/monero-project 548blacklist ${HOME}/.config/monero-project
549blacklist ${HOME}/.config/mono 549blacklist ${HOME}/.config/mono
550blacklist ${HOME}/.config/mov-cli
550blacklist ${HOME}/.config/mpDris2 551blacklist ${HOME}/.config/mpDris2
551blacklist ${HOME}/.config/mpd 552blacklist ${HOME}/.config/mpd
552blacklist ${HOME}/.config/mps-youtube 553blacklist ${HOME}/.config/mps-youtube
@@ -623,6 +624,7 @@ blacklist ${HOME}/.config/slimjet
623blacklist ${HOME}/.config/smplayer 624blacklist ${HOME}/.config/smplayer
624blacklist ${HOME}/.config/smtube 625blacklist ${HOME}/.config/smtube
625blacklist ${HOME}/.config/smuxi 626blacklist ${HOME}/.config/smuxi
627blacklist ${HOME}/.config/sniffnet
626blacklist ${HOME}/.config/snox 628blacklist ${HOME}/.config/snox
627blacklist ${HOME}/.config/sound-juicer 629blacklist ${HOME}/.config/sound-juicer
628blacklist ${HOME}/.config/specialmailcollectionsrc 630blacklist ${HOME}/.config/specialmailcollectionsrc
diff --git a/etc/profile-a-l/1password.profile b/etc/profile-a-l/1password.profile
index 690086099..63a04330b 100644
--- a/etc/profile-a-l/1password.profile
+++ b/etc/profile-a-l/1password.profile
@@ -13,7 +13,7 @@ whitelist ${HOME}/.config/1Password
13 13
14private-etc @tls-ca 14private-etc @tls-ca
15 15
16# Needed for keychain things, talking to Firefox, possibly other things? Not sure how to narrow down 16# Needed for keychain things, talking to Firefox, possibly other things?
17ignore dbus-user none 17ignore dbus-user none
18 18
19# Redirect 19# Redirect
diff --git a/etc/profile-a-l/abrowser.profile b/etc/profile-a-l/abrowser.profile
index 2e6e8f1af..8b70756ba 100644
--- a/etc/profile-a-l/abrowser.profile
+++ b/etc/profile-a-l/abrowser.profile
@@ -12,6 +12,7 @@ mkdir ${HOME}/.cache/mozilla/abrowser
12mkdir ${HOME}/.mozilla 12mkdir ${HOME}/.mozilla
13whitelist ${HOME}/.cache/mozilla/abrowser 13whitelist ${HOME}/.cache/mozilla/abrowser
14whitelist ${HOME}/.mozilla 14whitelist ${HOME}/.mozilla
15whitelist /usr/share/abrowser
15 16
16# private-etc must first be enabled in firefox-common.profile 17# private-etc must first be enabled in firefox-common.profile
17#private-etc abrowser 18#private-etc abrowser
diff --git a/etc/profile-a-l/audacious.profile b/etc/profile-a-l/audacious.profile
index b31f3f1b2..6abd87c92 100644
--- a/etc/profile-a-l/audacious.profile
+++ b/etc/profile-a-l/audacious.profile
@@ -14,6 +14,7 @@ include disable-common.inc
14include disable-devel.inc 14include disable-devel.inc
15include disable-exec.inc 15include disable-exec.inc
16include disable-interpreters.inc 16include disable-interpreters.inc
17include disable-proc.inc
17include disable-programs.inc 18include disable-programs.inc
18include disable-xdg.inc 19include disable-xdg.inc
19 20
@@ -26,6 +27,7 @@ netfilter
26nogroups 27nogroups
27noinput 28noinput
28nonewprivs 29nonewprivs
30noprinters
29noroot 31noroot
30notv 32notv
31nou2f 33nou2f
@@ -39,8 +41,13 @@ private-cache
39private-dev 41private-dev
40private-tmp 42private-tmp
41 43
42# dbus needed for MPRIS 44dbus-user filter
43# dbus-user none 45dbus-user.own org.atheme.audacious
44# dbus-system none 46dbus-user.own org.mpris.MediaPlayer2.audacious
47dbus-user.talk ca.desrt.dconf
48dbus-user.talk org.freedesktop.Notifications
49dbus-user.talk org.gtk.vfs.UDisks2VolumeMonitor
50dbus-user.talk org.mpris.MediaPlayer2.Player
51dbus-system none
45 52
46restrict-namespaces 53restrict-namespaces
diff --git a/etc/profile-a-l/basilisk.profile b/etc/profile-a-l/basilisk.profile
index a962bfe02..7d2fe143c 100644
--- a/etc/profile-a-l/basilisk.profile
+++ b/etc/profile-a-l/basilisk.profile
@@ -12,6 +12,7 @@ mkdir ${HOME}/.cache/moonchild productions/basilisk
12mkdir ${HOME}/.moonchild productions 12mkdir ${HOME}/.moonchild productions
13whitelist ${HOME}/.cache/moonchild productions/basilisk 13whitelist ${HOME}/.cache/moonchild productions/basilisk
14whitelist ${HOME}/.moonchild productions 14whitelist ${HOME}/.moonchild productions
15whitelist /usr/share/basilisk
15 16
16# Basilisk can use the full firejail seccomp filter (unlike firefox >= 60) 17# Basilisk can use the full firejail seccomp filter (unlike firefox >= 60)
17seccomp 18seccomp
diff --git a/etc/profile-a-l/brave.profile b/etc/profile-a-l/brave.profile
index 071a279b0..b3994c974 100644
--- a/etc/profile-a-l/brave.profile
+++ b/etc/profile-a-l/brave.profile
@@ -9,8 +9,8 @@ include globals.local
9# noexec /tmp is included in chromium-common.profile and breaks Brave 9# noexec /tmp is included in chromium-common.profile and breaks Brave
10ignore noexec /tmp 10ignore noexec /tmp
11# TOR is installed in ${HOME}. 11# TOR is installed in ${HOME}.
12# NOTE: chromium-common.profile enables apparmor. To keep that intact 12# Note: chromium-common.profile enables apparmor. To keep that intact,
13# you will need to uncomment the 'brave + tor' rule in /etc/apparmor.d/local/firejail-default. 13# uncomment the 'brave + tor' rule in /etc/apparmor.d/local/firejail-default.
14# Alternatively you can add 'ignore apparmor' to your brave.local. 14# Alternatively you can add 'ignore apparmor' to your brave.local.
15ignore noexec ${HOME} 15ignore noexec ${HOME}
16# Causes slow starts (#4604) 16# Causes slow starts (#4604)
diff --git a/etc/profile-a-l/cachy-browser.profile b/etc/profile-a-l/cachy-browser.profile
index 7a14d9464..05e1a69f1 100644
--- a/etc/profile-a-l/cachy-browser.profile
+++ b/etc/profile-a-l/cachy-browser.profile
@@ -13,26 +13,21 @@ mkdir ${HOME}/.cache/cachy
13mkdir ${HOME}/.cachy 13mkdir ${HOME}/.cachy
14whitelist ${HOME}/.cache/cachy 14whitelist ${HOME}/.cache/cachy
15whitelist ${HOME}/.cachy 15whitelist ${HOME}/.cachy
16whitelist /usr/share/cachy-browser
16 17
17# Add the next lines to your cachy-browser.local if you want to use the migration wizard. 18# Add the next lines to your cachy-browser.local if you want to use the migration wizard.
18#noblacklist ${HOME}/.mozilla 19#noblacklist ${HOME}/.mozilla
19#whitelist ${HOME}/.mozilla 20#whitelist ${HOME}/.mozilla
20 21
21# To enable KeePassXC Plugin add one of the following lines to your cachy-browser.local. 22# To enable KeePassXC Plugin add one of the following lines to your cachy-browser.local.
22# NOTE: start KeePassXC before CachyBrowser and keep it open to allow communication between them. 23# Note: Start KeePassXC before CachyBrowser and keep it open to allow communication between them.
23#whitelist ${RUNUSER}/kpxc_server 24#whitelist ${RUNUSER}/kpxc_server
24#whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer 25#whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer
25 26
26whitelist /usr/share/doc
27whitelist /usr/share/gtk-doc/html
28whitelist /usr/share/mozilla
29whitelist /usr/share/webext
30include whitelist-usr-share-common.inc
31
32# Add the next line to your cachy-browser.local to enable private-bin (Arch Linux). 27# Add the next line to your cachy-browser.local to enable private-bin (Arch Linux).
33#private-bin dbus-launch,dbus-send,cachy-browser,sh 28#private-bin dbus-launch,dbus-send,cachy-browser,sh
34# Add the next line to your cachy-browser.local to enable private-etc. 29# Add the next line to your cachy-browser.local to enable private-etc.
35# NOTE: private-etc must first be enabled in firefox-common.local. 30# Note: private-etc must first be enabled in firefox-common.local.
36#private-etc cachy-browser 31#private-etc cachy-browser
37 32
38dbus-user filter 33dbus-user filter
diff --git a/etc/profile-a-l/cliqz.profile b/etc/profile-a-l/cliqz.profile
index d0b8cc0ef..d0bf9797e 100644
--- a/etc/profile-a-l/cliqz.profile
+++ b/etc/profile-a-l/cliqz.profile
@@ -15,6 +15,7 @@ mkdir ${HOME}/.config/cliqz
15whitelist ${HOME}/.cache/cliqz 15whitelist ${HOME}/.cache/cliqz
16whitelist ${HOME}/.cliqz 16whitelist ${HOME}/.cliqz
17whitelist ${HOME}/.config/cliqz 17whitelist ${HOME}/.config/cliqz
18whitelist /usr/share/cliqz
18 19
19# private-etc must first be enabled in firefox-common.profile 20# private-etc must first be enabled in firefox-common.profile
20#private-etc cliqz 21#private-etc cliqz
diff --git a/etc/profile-a-l/cyberfox.profile b/etc/profile-a-l/cyberfox.profile
index d1fff0004..a303c5979 100644
--- a/etc/profile-a-l/cyberfox.profile
+++ b/etc/profile-a-l/cyberfox.profile
@@ -12,6 +12,8 @@ mkdir ${HOME}/.8pecxstudios
12mkdir ${HOME}/.cache/8pecxstudios 12mkdir ${HOME}/.cache/8pecxstudios
13whitelist ${HOME}/.8pecxstudios 13whitelist ${HOME}/.8pecxstudios
14whitelist ${HOME}/.cache/8pecxstudios 14whitelist ${HOME}/.cache/8pecxstudios
15whitelist /usr/share/8pecxstudios
16whitelist /usr/share/cyberfox
15 17
16# private-bin cyberfox,dbus-launch,dbus-send,env,sh,which 18# private-bin cyberfox,dbus-launch,dbus-send,env,sh,which
17# private-etc must first be enabled in firefox-common.profile 19# private-etc must first be enabled in firefox-common.profile
diff --git a/etc/profile-a-l/discord-ptb.profile b/etc/profile-a-l/discord-ptb.profile
index c39c0d843..265bf5615 100644
--- a/etc/profile-a-l/discord-ptb.profile
+++ b/etc/profile-a-l/discord-ptb.profile
@@ -1,17 +1,17 @@
1# Firejail profile for discord-ptb 1# Firejail profile for discord-ptb
2# This file is overwritten after every install/update 2# This file is overwritten after every install/update
3# Persistent local customizations 3# Persistent local customizations
4include discord-ptb.local 4include discord-ptb.local
5# Persistent global definitions 5# Persistent global definitions
6include globals.local 6include globals.local
7 7
8noblacklist ${HOME}/.config/discordptb 8noblacklist ${HOME}/.config/discordptb
9 9
10mkdir ${HOME}/.config/discordptb 10mkdir ${HOME}/.config/discordptb
11whitelist ${HOME}/.config/discordptb 11whitelist ${HOME}/.config/discordptb
12 12
13private-bin discord-ptb,DiscordPTB 13private-bin discord-ptb,DiscordPTB
14private-opt discord-ptb,DiscordPTB 14private-opt discord-ptb,DiscordPTB
15 15
16# Redirect 16# Redirect
17include discord-common.profile 17include discord-common.profile
diff --git a/etc/profile-a-l/firedragon.profile b/etc/profile-a-l/firedragon.profile
index 77487161e..3177fb989 100644
--- a/etc/profile-a-l/firedragon.profile
+++ b/etc/profile-a-l/firedragon.profile
@@ -13,6 +13,7 @@ mkdir ${HOME}/.cache/firedragon
13mkdir ${HOME}/.firedragon 13mkdir ${HOME}/.firedragon
14whitelist ${HOME}/.cache/firedragon 14whitelist ${HOME}/.cache/firedragon
15whitelist ${HOME}/.firedragon 15whitelist ${HOME}/.firedragon
16whitelist /usr/share/firedragon
16 17
17# Add the next lines to your firedragon.local if you want to use the migration wizard. 18# Add the next lines to your firedragon.local if you want to use the migration wizard.
18#noblacklist ${HOME}/.mozilla 19#noblacklist ${HOME}/.mozilla
diff --git a/etc/profile-a-l/firefox-common-addons.profile b/etc/profile-a-l/firefox-common-addons.profile
index 6dc1fca8a..f12750fda 100644
--- a/etc/profile-a-l/firefox-common-addons.profile
+++ b/etc/profile-a-l/firefox-common-addons.profile
@@ -74,7 +74,6 @@ whitelist ${HOME}/.zotero
74whitelist ${HOME}/dwhelper 74whitelist ${HOME}/dwhelper
75whitelist /usr/share/lua 75whitelist /usr/share/lua
76whitelist /usr/share/lua* 76whitelist /usr/share/lua*
77whitelist /usr/share/vulkan
78 77
79# GNOME Shell integration (chrome-gnome-shell) needs dbus and python 78# GNOME Shell integration (chrome-gnome-shell) needs dbus and python
80noblacklist ${HOME}/.local/share/gnome-shell 79noblacklist ${HOME}/.local/share/gnome-shell
diff --git a/etc/profile-a-l/firefox-common.profile b/etc/profile-a-l/firefox-common.profile
index 42d12c5d9..9c8601e7b 100644
--- a/etc/profile-a-l/firefox-common.profile
+++ b/etc/profile-a-l/firefox-common.profile
@@ -29,9 +29,14 @@ mkdir ${HOME}/.pki
29whitelist ${DOWNLOADS} 29whitelist ${DOWNLOADS}
30whitelist ${HOME}/.local/share/pki 30whitelist ${HOME}/.local/share/pki
31whitelist ${HOME}/.pki 31whitelist ${HOME}/.pki
32whitelist /usr/share/doc
33whitelist /usr/share/gtk-doc/html
34whitelist /usr/share/mozilla
35whitelist /usr/share/webext
32include whitelist-common.inc 36include whitelist-common.inc
33include whitelist-run-common.inc 37include whitelist-run-common.inc
34include whitelist-runuser-common.inc 38include whitelist-runuser-common.inc
39include whitelist-usr-share-common.inc
35include whitelist-var-common.inc 40include whitelist-var-common.inc
36 41
37apparmor 42apparmor
diff --git a/etc/profile-a-l/firefox.profile b/etc/profile-a-l/firefox.profile
index 1fcbf0562..659519ca8 100644
--- a/etc/profile-a-l/firefox.profile
+++ b/etc/profile-a-l/firefox.profile
@@ -6,7 +6,7 @@ include firefox.local
6# Persistent global definitions 6# Persistent global definitions
7include globals.local 7include globals.local
8 8
9# NOTE: sandboxing web browsers is as important as it is complex. Users might be 9# Note: Sandboxing web browsers is as important as it is complex. Users might be
10# interested in creating custom profiles depending on use case (e.g. one for 10# interested in creating custom profiles depending on use case (e.g. one for
11# general browsing, another for banking, ...). Consult our FAQ/issue tracker for more 11# general browsing, another for banking, ...). Consult our FAQ/issue tracker for more
12# info. Here are a few links to get you going. 12# info. Here are a few links to get you going.
@@ -30,19 +30,14 @@ whitelist ${HOME}/.cache/mozilla/firefox
30whitelist ${HOME}/.mozilla 30whitelist ${HOME}/.mozilla
31 31
32# Add one of the following whitelist options to your firefox.local to enable KeePassXC Plugin support. 32# Add one of the following whitelist options to your firefox.local to enable KeePassXC Plugin support.
33# NOTE: start KeePassXC before Firefox and keep it open to allow communication between them. 33# Note: Start KeePassXC before Firefox and keep it open to allow communication between them.
34#whitelist ${RUNUSER}/kpxc_server 34#whitelist ${RUNUSER}/kpxc_server
35#whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer 35#whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer
36 36
37whitelist /usr/share/doc
38whitelist /usr/share/firefox 37whitelist /usr/share/firefox
39whitelist /usr/share/gnome-shell/search-providers/firefox-search-provider.ini 38whitelist /usr/share/gnome-shell/search-providers/firefox-search-provider.ini
40whitelist /usr/share/gtk-doc/html
41whitelist /usr/share/mozilla
42whitelist /usr/share/webext
43whitelist ${RUNUSER}/*firefox* 39whitelist ${RUNUSER}/*firefox*
44whitelist ${RUNUSER}/psd/*firefox* 40whitelist ${RUNUSER}/psd/*firefox*
45include whitelist-usr-share-common.inc
46 41
47# firefox requires a shell to launch on Arch - add the next line to your firefox.local to enable private-bin. 42# firefox requires a shell to launch on Arch - add the next line to your firefox.local to enable private-bin.
48#private-bin bash,dbus-launch,dbus-send,env,firefox,sh,which 43#private-bin bash,dbus-launch,dbus-send,env,firefox,sh,which
diff --git a/etc/profile-a-l/gnome-calendar.profile b/etc/profile-a-l/gnome-calendar.profile
index 70a302138..ddfe57879 100644
--- a/etc/profile-a-l/gnome-calendar.profile
+++ b/etc/profile-a-l/gnome-calendar.profile
@@ -53,7 +53,7 @@ dbus-user.talk ca.desrt.dconf
53dbus-user.talk org.gnome.evolution.dataserver.* 53dbus-user.talk org.gnome.evolution.dataserver.*
54#dbus-user.talk org.gnome.OnlineAccounts 54#dbus-user.talk org.gnome.OnlineAccounts
55#dbus-user.talk org.gnome.ControlCenter 55#dbus-user.talk org.gnome.ControlCenter
56# NOTE: dbus-system none fails, filter without rules works. 56# Note: dbus-system none fails, filter without rules works.
57dbus-system filter 57dbus-system filter
58#dbus-system.talk org.freedesktop.timedate1 58#dbus-system.talk org.freedesktop.timedate1
59#dbus-system.talk org.freedesktop.login1 59#dbus-system.talk org.freedesktop.login1
diff --git a/etc/profile-a-l/icecat.profile b/etc/profile-a-l/icecat.profile
index 660343a29..b0a42fb77 100644
--- a/etc/profile-a-l/icecat.profile
+++ b/etc/profile-a-l/icecat.profile
@@ -12,6 +12,7 @@ mkdir ${HOME}/.cache/mozilla/icecat
12mkdir ${HOME}/.mozilla 12mkdir ${HOME}/.mozilla
13whitelist ${HOME}/.cache/mozilla/icecat 13whitelist ${HOME}/.cache/mozilla/icecat
14whitelist ${HOME}/.mozilla 14whitelist ${HOME}/.mozilla
15whitelist /usr/share/icecat
15 16
16# private-etc must first be enabled in firefox-common.profile 17# private-etc must first be enabled in firefox-common.profile
17#private-etc icecat 18#private-etc icecat
diff --git a/etc/profile-a-l/krunner.profile b/etc/profile-a-l/krunner.profile
index 27feccf40..a0244ef47 100644
--- a/etc/profile-a-l/krunner.profile
+++ b/etc/profile-a-l/krunner.profile
@@ -6,9 +6,9 @@ include krunner.local
6# Persistent global definitions 6# Persistent global definitions
7include globals.local 7include globals.local
8 8
9# - programs started in krunner run with this generic profile 9# Programs started in krunner run with this generic profile.
10# - when a file is opened in krunner, the file viewer runs in its own sandbox 10# When a file is opened in krunner, the file viewer runs in its own sandbox
11# with its own profile, if it is sandboxed automatically 11# with its own profile, if it is sandboxed automatically.
12 12
13# noblacklist ${HOME}/.cache/krunner 13# noblacklist ${HOME}/.cache/krunner
14# noblacklist ${HOME}/.cache/krunnerbookmarkrunnerfirefoxdbfile.sqlite* 14# noblacklist ${HOME}/.cache/krunnerbookmarkrunnerfirefoxdbfile.sqlite*
diff --git a/etc/profile-a-l/kube.profile b/etc/profile-a-l/kube.profile
index 5cf30ed40..82336969d 100644
--- a/etc/profile-a-l/kube.profile
+++ b/etc/profile-a-l/kube.profile
@@ -6,11 +6,10 @@ include kube.local
6# Persistent global definitions 6# Persistent global definitions
7include globals.local 7include globals.local
8 8
9noblacklist ${HOME}/.gnupg
10noblacklist ${HOME}/.mozilla
11noblacklist ${HOME}/.cache/kube 9noblacklist ${HOME}/.cache/kube
12noblacklist ${HOME}/.config/kube 10noblacklist ${HOME}/.config/kube
13noblacklist ${HOME}/.config/sink 11noblacklist ${HOME}/.config/sink
12noblacklist ${HOME}/.gnupg
14noblacklist ${HOME}/.local/share/kube 13noblacklist ${HOME}/.local/share/kube
15noblacklist ${HOME}/.local/share/sink 14noblacklist ${HOME}/.local/share/sink
16 15
@@ -22,23 +21,28 @@ include disable-programs.inc
22include disable-shell.inc 21include disable-shell.inc
23include disable-xdg.inc 22include disable-xdg.inc
24 23
25mkdir ${HOME}/.gnupg 24# The lines below are needed to find the default Firefox profile name, to allow
25# opening links in an existing instance of Firefox (note that it still fails if
26# there isn't a Firefox instance running with the default profile; see #5352)
27noblacklist ${HOME}/.mozilla
28whitelist ${HOME}/.mozilla/firefox/profiles.ini
29
26mkdir ${HOME}/.cache/kube 30mkdir ${HOME}/.cache/kube
27mkdir ${HOME}/.config/kube 31mkdir ${HOME}/.config/kube
28mkdir ${HOME}/.config/sink 32mkdir ${HOME}/.config/sink
33mkdir ${HOME}/.gnupg
29mkdir ${HOME}/.local/share/kube 34mkdir ${HOME}/.local/share/kube
30mkdir ${HOME}/.local/share/sink 35mkdir ${HOME}/.local/share/sink
31whitelist ${HOME}/.gnupg
32whitelist ${HOME}/.mozilla/firefox/profiles.ini
33whitelist ${HOME}/.cache/kube 36whitelist ${HOME}/.cache/kube
34whitelist ${HOME}/.config/kube 37whitelist ${HOME}/.config/kube
35whitelist ${HOME}/.config/sink 38whitelist ${HOME}/.config/sink
39whitelist ${HOME}/.gnupg
36whitelist ${HOME}/.local/share/kube 40whitelist ${HOME}/.local/share/kube
37whitelist ${HOME}/.local/share/sink 41whitelist ${HOME}/.local/share/sink
38whitelist ${RUNUSER}/gnupg 42whitelist ${RUNUSER}/gnupg
39whitelist /usr/share/kube
40whitelist /usr/share/gnupg 43whitelist /usr/share/gnupg
41whitelist /usr/share/gnupg2 44whitelist /usr/share/gnupg2
45whitelist /usr/share/kube
42include whitelist-common.inc 46include whitelist-common.inc
43include whitelist-runuser-common.inc 47include whitelist-runuser-common.inc
44include whitelist-usr-share-common.inc 48include whitelist-usr-share-common.inc
@@ -63,7 +67,6 @@ tracelog
63 67
64# disable-mnt 68# disable-mnt
65# Add "gpg,gpg2,gpg-agent,pinentry-curses,pinentry-emacs,pinentry-fltk,pinentry-gnome3,pinentry-gtk,pinentry-gtk2,pinentry-gtk-2,pinentry-qt,pinentry-qt4,pinentry-tty,pinentry-x2go,pinentry-kwallet" for gpg 69# Add "gpg,gpg2,gpg-agent,pinentry-curses,pinentry-emacs,pinentry-fltk,pinentry-gnome3,pinentry-gtk,pinentry-gtk2,pinentry-gtk-2,pinentry-qt,pinentry-qt4,pinentry-tty,pinentry-x2go,pinentry-kwallet" for gpg
66# Add "ignore private-bin" for hyperlinks or have a look at the private-bins in firefox.profile and firefox-common.profile.
67private-bin kube,sink_synchronizer 70private-bin kube,sink_synchronizer
68private-cache 71private-cache
69private-dev 72private-dev
@@ -75,6 +78,8 @@ dbus-user filter
75dbus-user.talk ca.desrt.dconf 78dbus-user.talk ca.desrt.dconf
76dbus-user.talk org.freedesktop.secrets 79dbus-user.talk org.freedesktop.secrets
77dbus-user.talk org.freedesktop.Notifications 80dbus-user.talk org.freedesktop.Notifications
81# allow D-Bus communication with firefox for opening links
82dbus-user.talk org.mozilla.*
78dbus-system none 83dbus-system none
79 84
80restrict-namespaces 85restrict-namespaces
diff --git a/etc/profile-a-l/librewolf.profile b/etc/profile-a-l/librewolf.profile
index b84cbb119..65a4a3787 100644
--- a/etc/profile-a-l/librewolf.profile
+++ b/etc/profile-a-l/librewolf.profile
@@ -19,21 +19,16 @@ whitelist ${HOME}/.librewolf
19#whitelist ${HOME}/.mozilla 19#whitelist ${HOME}/.mozilla
20 20
21# To enable KeePassXC Plugin add one of the following lines to your librewolf.local. 21# To enable KeePassXC Plugin add one of the following lines to your librewolf.local.
22# NOTE: start KeePassXC before Librewolf and keep it open to allow communication between them. 22# Note: Start KeePassXC before Librewolf and keep it open to allow communication between them.
23#whitelist ${RUNUSER}/kpxc_server 23#whitelist ${RUNUSER}/kpxc_server
24#whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer 24#whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer
25 25
26whitelist /usr/share/doc
27whitelist /usr/share/gtk-doc/html
28whitelist /usr/share/librewolf 26whitelist /usr/share/librewolf
29whitelist /usr/share/mozilla
30whitelist /usr/share/webext
31include whitelist-usr-share-common.inc
32 27
33# Add the next line to your librewolf.local to enable private-bin (Arch Linux). 28# Add the next line to your librewolf.local to enable private-bin (Arch Linux).
34#private-bin dbus-launch,dbus-send,librewolf,sh 29#private-bin dbus-launch,dbus-send,librewolf,sh
35# Add the next line to your librewolf.local to enable private-etc. 30# Add the next line to your librewolf.local to enable private-etc.
36# NOTE: private-etc must first be enabled in firefox-common.local. 31# Note: private-etc must first be enabled in firefox-common.local.
37#private-etc librewolf 32#private-etc librewolf
38 33
39dbus-user filter 34dbus-user filter
diff --git a/etc/profile-m-z/minetest.profile b/etc/profile-m-z/minetest.profile
index 15474c96e..7b0135695 100644
--- a/etc/profile-m-z/minetest.profile
+++ b/etc/profile-m-z/minetest.profile
@@ -6,8 +6,9 @@ include minetest.local
6# Persistent global definitions 6# Persistent global definitions
7include globals.local 7include globals.local
8 8
9# In order to save in-game screenshots to a persistent location edit ~/.minetest/minetest.conf: 9# In order to save in-game screenshots to a persistent location,
10# screenshot_path = /home/<USER>/.minetest/screenshots 10# edit ~/.minetest/minetest.conf:
11# screenshot_path = /home/<USER>/.minetest/screenshots
11 12
12noblacklist ${HOME}/.cache/minetest 13noblacklist ${HOME}/.cache/minetest
13noblacklist ${HOME}/.minetest 14noblacklist ${HOME}/.minetest
diff --git a/etc/profile-m-z/mov-cli.profile b/etc/profile-m-z/mov-cli.profile
index c5f764912..8007b887a 100644
--- a/etc/profile-m-z/mov-cli.profile
+++ b/etc/profile-m-z/mov-cli.profile
@@ -8,9 +8,13 @@ include mov-cli.local
8# added by included profile 8# added by included profile
9#include globals.local 9#include globals.local
10 10
11noblacklist ${HOME}/.config/mov-cli
12
11include disable-proc.inc 13include disable-proc.inc
12include disable-xdg.inc 14include disable-xdg.inc
13 15
16mkdir ${HOME}/.config/mov-cli
17whitelist ${HOME}/.config/mov-cli
14include whitelist-run-common.inc 18include whitelist-run-common.inc
15include whitelist-runuser-common.inc 19include whitelist-runuser-common.inc
16 20
diff --git a/etc/profile-m-z/mpv.profile b/etc/profile-m-z/mpv.profile
index bd01d4082..fd35483be 100644
--- a/etc/profile-m-z/mpv.profile
+++ b/etc/profile-m-z/mpv.profile
@@ -9,7 +9,7 @@ include globals.local
9 9
10# In order to save screenshots to a persistent location, 10# In order to save screenshots to a persistent location,
11# edit ~/.config/mpv/foobar.conf: 11# edit ~/.config/mpv/foobar.conf:
12# screenshot-directory=~/Pictures 12# screenshot-directory=~/Pictures
13 13
14# mpv has a powerful Lua API and some of the Lua scripts interact with 14# mpv has a powerful Lua API and some of the Lua scripts interact with
15# external resources which are blocked by firejail. In such cases you need to 15# external resources which are blocked by firejail. In such cases you need to
diff --git a/etc/profile-m-z/nodejs-common.profile b/etc/profile-m-z/nodejs-common.profile
index f3b0c8a49..4c463521c 100644
--- a/etc/profile-m-z/nodejs-common.profile
+++ b/etc/profile-m-z/nodejs-common.profile
@@ -7,7 +7,7 @@ include nodejs-common.local
7# added by caller profile 7# added by caller profile
8#include globals.local 8#include globals.local
9 9
10# NOTE: gulp, node-gyp, npm, npx, semver and yarn are all node scripts 10# Note: gulp, node-gyp, npm, npx, semver and yarn are all node scripts
11# using the `#!/usr/bin/env node` shebang. By sandboxing node the full 11# using the `#!/usr/bin/env node` shebang. By sandboxing node the full
12# node.js stack will be firejailed. The only exception is nvm, which is implemented 12# node.js stack will be firejailed. The only exception is nvm, which is implemented
13# as a sourced shell function, not an executable binary. Hence it is not 13# as a sourced shell function, not an executable binary. Hence it is not
diff --git a/etc/profile-m-z/noprofile.profile b/etc/profile-m-z/noprofile.profile
index db4113f94..7d0e01d98 100644
--- a/etc/profile-m-z/noprofile.profile
+++ b/etc/profile-m-z/noprofile.profile
@@ -1,17 +1,16 @@
1# This is the weakest possible firejail profile. 1# This is the weakest possible firejail profile.
2# If a program still fail with this profile, it is incompatible with firejail. 2# If a program still fails with this profile, it is incompatible with firejail.
3# (from https://gist.github.com/rusty-snake/bb234cb3e50e1e4e7429f29a7931cc72) 3# (from https://gist.github.com/rusty-snake/bb234cb3e50e1e4e7429f29a7931cc72)
4# 4#
5# Usage: 5# Usage:
6# 1. download 6# $ firejail --profile=noprofile.profile /path/to/program
7# 2. firejail --profile=noprofile.profile /path/to/program
8 7
9# Keep in mind that even with this profile some things are done 8# Keep in mind that even with this profile some things are done
10# which can break the program. 9# which can break the program:
11# - some env-vars are cleared 10# - some env-vars are cleared;
12# - /etc/firejail/firejail.config can contain options such as 'force-nonewprivs yes' 11# - /etc/firejail/firejail.config can contain options such as 'force-nonewprivs yes';
13# - a new private pid-namespace is created 12# - a new private pid-namespace is created;
14# - a minimal hardcoded blacklist is applied 13# - a minimal hardcoded blacklist is applied;
15# - ... 14# - ...
16 15
17noblacklist /sys/fs 16noblacklist /sys/fs
diff --git a/etc/profile-m-z/palemoon.profile b/etc/profile-m-z/palemoon.profile
index 24701b657..ab4e24595 100644
--- a/etc/profile-m-z/palemoon.profile
+++ b/etc/profile-m-z/palemoon.profile
@@ -12,6 +12,8 @@ mkdir ${HOME}/.cache/moonchild productions/pale moon
12mkdir ${HOME}/.moonchild productions 12mkdir ${HOME}/.moonchild productions
13whitelist ${HOME}/.cache/moonchild productions/pale moon 13whitelist ${HOME}/.cache/moonchild productions/pale moon
14whitelist ${HOME}/.moonchild productions 14whitelist ${HOME}/.moonchild productions
15whitelist /usr/share/moonchild productions
16whitelist /usr/share/palemoon
15 17
16# Palemoon can use the full firejail seccomp filter (unlike firefox >= 60) 18# Palemoon can use the full firejail seccomp filter (unlike firefox >= 60)
17seccomp 19seccomp
diff --git a/etc/profile-m-z/pingus.profile b/etc/profile-m-z/pingus.profile
index 3ff033e0b..e274b6443 100644
--- a/etc/profile-m-z/pingus.profile
+++ b/etc/profile-m-z/pingus.profile
@@ -23,8 +23,9 @@ include disable-xdg.inc
23 23
24mkdir ${HOME}/.pingus 24mkdir ${HOME}/.pingus
25whitelist ${HOME}/.pingus 25whitelist ${HOME}/.pingus
26# Debian keeps games data under /usr/share/games
27whitelist /usr/share/games/pingus
26whitelist /usr/share/pingus 28whitelist /usr/share/pingus
27whitelist /usr/share/games/pingus # Debian keeps games data under /usr/share/games
28include whitelist-common.inc 29include whitelist-common.inc
29include whitelist-runuser-common.inc 30include whitelist-runuser-common.inc
30include whitelist-usr-share-common.inc 31include whitelist-usr-share-common.inc
diff --git a/etc/profile-m-z/rtin.profile b/etc/profile-m-z/rtin.profile
index 87aa69bcb..b1acf8b2e 100644
--- a/etc/profile-m-z/rtin.profile
+++ b/etc/profile-m-z/rtin.profile
@@ -1,6 +1,6 @@
1# Firejail profile for rtin 1# Firejail profile for rtin
2# Description: ncurses-based Usenet newsreader 2# Description: ncurses-based Usenet newsreader
3# symlink to tin, same as `tin -r` 3# symlink to tin, same as `tin -r`
4# This file is overwritten after every install/update 4# This file is overwritten after every install/update
5# Persistent local customizations 5# Persistent local customizations
6include rtin.local 6include rtin.local
diff --git a/etc/profile-m-z/signal-desktop.profile b/etc/profile-m-z/signal-desktop.profile
index 3e1899ef3..8cb4e4173 100644
--- a/etc/profile-m-z/signal-desktop.profile
+++ b/etc/profile-m-z/signal-desktop.profile
@@ -11,7 +11,9 @@ ignore noexec /tmp
11 11
12noblacklist ${HOME}/.config/Signal 12noblacklist ${HOME}/.config/Signal
13 13
14# These lines are needed to allow Firefox to open links 14# The lines below are needed to find the default Firefox profile name, to allow
15# opening links in an existing instance of Firefox (note that it still fails if
16# there isn't a Firefox instance running with the default profile; see #5352)
15noblacklist ${HOME}/.mozilla 17noblacklist ${HOME}/.mozilla
16whitelist ${HOME}/.mozilla/firefox/profiles.ini 18whitelist ${HOME}/.mozilla/firefox/profiles.ini
17 19
@@ -21,11 +23,9 @@ whitelist ${HOME}/.config/Signal
21private-etc @tls-ca 23private-etc @tls-ca
22 24
23dbus-user filter 25dbus-user filter
24
25# allow D-Bus notifications 26# allow D-Bus notifications
26dbus-user.talk org.freedesktop.Notifications 27dbus-user.talk org.freedesktop.Notifications
27 28# allow D-Bus communication with firefox for opening links
28# allow D-Bus communication with Firefox browsers for opening links
29dbus-user.talk org.mozilla.* 29dbus-user.talk org.mozilla.*
30 30
31ignore dbus-user none 31ignore dbus-user none
diff --git a/etc/profile-m-z/sniffnet.profile b/etc/profile-m-z/sniffnet.profile
new file mode 100644
index 000000000..eb18c1f01
--- /dev/null
+++ b/etc/profile-m-z/sniffnet.profile
@@ -0,0 +1,49 @@
1# Firejail profile for sniffnet
2# Description: Network traffic monitor
3# This file is overwritten after every install/update
4# Persistent local customizations
5include sniffnet.local
6# Persistent global definitions
7include globals.local
8
9noblacklist ${HOME}/.config/sniffnet
10
11include disable-common.inc
12include disable-devel.inc
13include disable-exec.inc
14include disable-interpreters.inc
15include disable-proc.inc
16include disable-programs.inc
17include disable-xdg.inc
18
19include whitelist-common.inc
20include whitelist-run-common.inc
21include whitelist-runuser-common.inc
22include whitelist-usr-share-common.inc
23include whitelist-var-common.inc
24
25apparmor
26#caps.drop all
27caps.keep net_admin,net_raw
28netfilter
29nodvd
30nogroups
31noinput
32# nonewprivs - breaks network traffic capture for unprivileged users
33# noroot
34notv
35nou2f
36novideo
37#seccomp
38tracelog
39
40disable-mnt
41#private-bin sniffnet
42# private-dev prevents (some) interfaces from being shown.
43private-etc @network,@tls-ca
44private-tmp
45
46dbus-user none
47dbus-system none
48
49#restrict-namespaces
diff --git a/etc/profile-m-z/spotify.profile b/etc/profile-m-z/spotify.profile
index f07b10319..c893a92fb 100644
--- a/etc/profile-m-z/spotify.profile
+++ b/etc/profile-m-z/spotify.profile
@@ -16,6 +16,7 @@ include disable-common.inc
16include disable-devel.inc 16include disable-devel.inc
17include disable-exec.inc 17include disable-exec.inc
18include disable-interpreters.inc 18include disable-interpreters.inc
19include disable-proc.inc
19include disable-programs.inc 20include disable-programs.inc
20 21
21mkdir ${HOME}/.cache/spotify 22mkdir ${HOME}/.cache/spotify
@@ -34,6 +35,7 @@ nodvd
34nogroups 35nogroups
35noinput 36noinput
36nonewprivs 37nonewprivs
38noprinters
37noroot 39noroot
38notv 40notv
39nou2f 41nou2f
@@ -50,8 +52,11 @@ private-opt spotify
50private-srv none 52private-srv none
51private-tmp 53private-tmp
52 54
53# dbus needed for MPRIS 55dbus-user filter
54# dbus-user none 56dbus-user.own org.mpris.MediaPlayer2.spotify
55# dbus-system none 57dbus-user.talk org.freedesktop.Notifications
58dbus-user.talk org.freedesktop.secrets
59dbus-user.talk org.mpris.MediaPlayer2.Player
60dbus-system none
56 61
57restrict-namespaces 62restrict-namespaces
diff --git a/etc/profile-m-z/steam.profile b/etc/profile-m-z/steam.profile
index 63d629a32..99317c9dc 100644
--- a/etc/profile-m-z/steam.profile
+++ b/etc/profile-m-z/steam.profile
@@ -133,9 +133,9 @@ whitelist ${HOME}/.steampid
133include whitelist-common.inc 133include whitelist-common.inc
134include whitelist-var-common.inc 134include whitelist-var-common.inc
135 135
136# NOTE: The following were intentionally left out as they are alternative 136# Note: The following were intentionally left out as they are alternative
137# (i.e.: unnecessary and/or legacy) paths whose existence may potentially 137# (i.e.: unnecessary and/or legacy) paths whose existence may potentially
138# clobber other paths (see #4225). If you use any, either add the entry to 138# clobber other paths (see #4225). If you use any, either add the entry to
139# steam.local or move the contents to a path listed above (or open an issue if 139# steam.local or move the contents to a path listed above (or open an issue if
140# it's missing above). 140# it's missing above).
141#mkdir ${HOME}/.config/RogueLegacyStorageContainer 141#mkdir ${HOME}/.config/RogueLegacyStorageContainer
diff --git a/etc/profile-m-z/thunderbird.profile b/etc/profile-m-z/thunderbird.profile
index 5df207e25..f2405a7d3 100644
--- a/etc/profile-m-z/thunderbird.profile
+++ b/etc/profile-m-z/thunderbird.profile
@@ -47,10 +47,7 @@ whitelist ${HOME}/.thunderbird
47 47
48whitelist /usr/share/gnupg 48whitelist /usr/share/gnupg
49whitelist /usr/share/gnupg2 49whitelist /usr/share/gnupg2
50whitelist /usr/share/mozilla
51whitelist /usr/share/thunderbird 50whitelist /usr/share/thunderbird
52whitelist /usr/share/webext
53include whitelist-usr-share-common.inc
54 51
55# machine-id breaks audio in browsers; enable or put it in your thunderbird.local when sound is not required 52# machine-id breaks audio in browsers; enable or put it in your thunderbird.local when sound is not required
56#machine-id 53#machine-id
diff --git a/etc/profile-m-z/tin.profile b/etc/profile-m-z/tin.profile
index a03a6caa0..35ff14e88 100644
--- a/etc/profile-m-z/tin.profile
+++ b/etc/profile-m-z/tin.profile
@@ -24,8 +24,8 @@ include disable-xdg.inc
24mkdir ${HOME}/.tin 24mkdir ${HOME}/.tin
25mkfile ${HOME}/.newsrc 25mkfile ${HOME}/.newsrc
26# Note: files/directories directly in ${HOME} can't be whitelisted, as 26# Note: files/directories directly in ${HOME} can't be whitelisted, as
27# tin saves .newsrc by renaming a temporary file, which is not possible for 27# tin saves .newsrc by renaming a temporary file, which is not possible for
28# bind-mounted files. 28# bind-mounted files.
29#whitelist ${HOME}/.newsrc 29#whitelist ${HOME}/.newsrc
30#whitelist ${HOME}/.tin 30#whitelist ${HOME}/.tin
31#include whitelist-common.inc 31#include whitelist-common.inc
diff --git a/etc/profile-m-z/trojita.profile b/etc/profile-m-z/trojita.profile
index ba68ccb53..2578eb0be 100644
--- a/etc/profile-m-z/trojita.profile
+++ b/etc/profile-m-z/trojita.profile
@@ -7,7 +7,6 @@ include trojita.local
7include globals.local 7include globals.local
8 8
9noblacklist ${HOME}/.abook 9noblacklist ${HOME}/.abook
10noblacklist ${HOME}/.mozilla
11noblacklist ${HOME}/.cache/flaska.net/trojita 10noblacklist ${HOME}/.cache/flaska.net/trojita
12noblacklist ${HOME}/.config/flaska.net 11noblacklist ${HOME}/.config/flaska.net
13 12
@@ -19,11 +18,16 @@ include disable-programs.inc
19include disable-shell.inc 18include disable-shell.inc
20include disable-xdg.inc 19include disable-xdg.inc
21 20
21# The lines below are needed to find the default Firefox profile name, to allow
22# opening links in an existing instance of Firefox (note that it still fails if
23# there isn't a Firefox instance running with the default profile; see #5352)
24noblacklist ${HOME}/.mozilla
25whitelist ${HOME}/.mozilla/firefox/profiles.ini
26
22mkdir ${HOME}/.abook 27mkdir ${HOME}/.abook
23mkdir ${HOME}/.cache/flaska.net/trojita 28mkdir ${HOME}/.cache/flaska.net/trojita
24mkdir ${HOME}/.config/flaska.net 29mkdir ${HOME}/.config/flaska.net
25whitelist ${HOME}/.abook 30whitelist ${HOME}/.abook
26whitelist ${HOME}/.mozilla/firefox/profiles.ini
27whitelist ${HOME}/.cache/flaska.net/trojita 31whitelist ${HOME}/.cache/flaska.net/trojita
28whitelist ${HOME}/.config/flaska.net 32whitelist ${HOME}/.config/flaska.net
29include whitelist-common.inc 33include whitelist-common.inc
@@ -49,7 +53,6 @@ seccomp
49tracelog 53tracelog
50 54
51# disable-mnt 55# disable-mnt
52# Add "ignore private-bin" for hyperlinks or have a look at the private-bins in firefox.profile and firefox-common.profile.
53private-bin trojita 56private-bin trojita
54private-cache 57private-cache
55private-dev 58private-dev
@@ -58,6 +61,8 @@ private-tmp
58 61
59dbus-user filter 62dbus-user filter
60dbus-user.talk org.freedesktop.secrets 63dbus-user.talk org.freedesktop.secrets
64# allow D-Bus communication with firefox for opening links
65dbus-user.talk org.mozilla.*
61dbus-system none 66dbus-system none
62 67
63restrict-namespaces 68restrict-namespaces
diff --git a/etc/profile-m-z/waterfox.profile b/etc/profile-m-z/waterfox.profile
index 18f1ca79a..bf6f45e41 100644
--- a/etc/profile-m-z/waterfox.profile
+++ b/etc/profile-m-z/waterfox.profile
@@ -12,6 +12,7 @@ mkdir ${HOME}/.cache/waterfox
12mkdir ${HOME}/.waterfox 12mkdir ${HOME}/.waterfox
13whitelist ${HOME}/.cache/waterfox 13whitelist ${HOME}/.cache/waterfox
14whitelist ${HOME}/.waterfox 14whitelist ${HOME}/.waterfox
15whitelist /usr/share/waterfox
15 16
16# Add the next lines to your watefox.local if you want to use the migration wizard. 17# Add the next lines to your watefox.local if you want to use the migration wizard.
17#noblacklist ${HOME}/.mozilla 18#noblacklist ${HOME}/.mozilla
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index 8a8833968..ce69738eb 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -774,6 +774,7 @@ slashem
774smplayer 774smplayer
775smtube 775smtube
776smuxi-frontend-gnome 776smuxi-frontend-gnome
777sniffnet
777snox 778snox
778soffice 779soffice
779sol 780sol
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 458fb0dd1..e07776163 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -65,7 +65,7 @@ void netfilter_netlock(pid_t pid) {
65 umask(orig_umask); 65 umask(orig_umask);
66 66
67 char *cmd; 67 char *cmd;
68 if (asprintf(&cmd, "%s -e \"%s/firejail/fnettrace --tail --log=%s\"", terminal, LIBDIR, flog) == -1) 68 if (asprintf(&cmd, "%s -e \"%s/firejail/fnetlock --tail --log=%s\"", terminal, LIBDIR, flog) == -1)
69 errExit("asprintf"); 69 errExit("asprintf");
70 int rv = system(cmd); 70 int rv = system(cmd);
71 (void) rv; 71 (void) rv;
@@ -74,7 +74,7 @@ void netfilter_netlock(pid_t pid) {
74 } 74 }
75 75
76 char *cmd; 76 char *cmd;
77 if (asprintf(&cmd, "%s/firejail/fnettrace --netfilter --log=%s", LIBDIR, flog) == -1) 77 if (asprintf(&cmd, "%s/firejail/fnetlock --log=%s", LIBDIR, flog) == -1)
78 errExit("asprintf"); 78 errExit("asprintf");
79 free(flog); 79 free(flog);
80 80
diff --git a/src/fnetlock/Makefile b/src/fnetlock/Makefile
new file mode 100644
index 000000000..789df06ac
--- /dev/null
+++ b/src/fnetlock/Makefile
@@ -0,0 +1,9 @@
1.SUFFIXES:
2ROOT = ../..
3-include $(ROOT)/config.mk
4
5MOD_DIR = src/fnetlock
6PROG = fnetlock
7TARGET = $(PROG)
8
9include $(ROOT)/src/prog.mk
diff --git a/src/fnetlock/fnetlock.h b/src/fnetlock/fnetlock.h
new file mode 100644
index 000000000..018f58223
--- /dev/null
+++ b/src/fnetlock/fnetlock.h
@@ -0,0 +1,51 @@
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#ifndef FNETLOCK_H
21#define FNETLOCK_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
35//#define DEBUG 1
36
37#define NETLOCK_INTERVAL 60 // seconds
38
39static inline uint8_t hash(uint32_t ip) {
40 uint8_t *ptr = (uint8_t *) &ip;
41 // simple byte xor
42 return *ptr ^ *(ptr + 1) ^ *(ptr + 2) ^ *(ptr + 3);
43}
44
45// main.c
46void logprintf(char* fmt, ...);
47
48// tail.c
49void tail(const char *logfile);
50
51#endif
diff --git a/src/fnetlock/main.c b/src/fnetlock/main.c
new file mode 100644
index 000000000..d4169b7e1
--- /dev/null
+++ b/src/fnetlock/main.c
@@ -0,0 +1,394 @@
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 "fnetlock.h"
21#include <limits.h>
22#include <sys/ioctl.h>
23#include <sys/prctl.h>
24#include <signal.h>
25#define MAX_BUF_SIZE (64 * 1024)
26
27static int arg_tail = 0;
28static char *arg_log = NULL;
29
30//*****************************************************************
31// traffic trace storage - hash table for fast access + linked list for display purposes
32//*****************************************************************
33typedef struct hnode_t {
34 struct hnode_t *hnext; // used for hash table and unused linked list
35 struct hnode_t *dnext; // used to display streams on the screen
36 uint32_t ip_src;
37 uint16_t port_src;
38 uint8_t protocol;
39
40 // the firewall is build based on source address, and in the linked list
41 // we could have elements with the same address but different ports
42 uint8_t ip_instance;
43} HNode;
44
45// hash table
46#define HMAX 256
47HNode *htable[HMAX] = {NULL};
48static int have_traffic = 0;
49
50// using protocol 0 and port 0 for ICMP
51static void hnode_add(uint32_t ip_src, uint8_t protocol, uint16_t port_src) {
52 uint8_t h = hash(ip_src);
53 int ip_instance = 0;
54 HNode *ptr = htable[h];
55 while (ptr) {
56 if (ptr->ip_src == ip_src) {
57 ip_instance++;
58 if (ptr->port_src == port_src && ptr->protocol == protocol)
59 return;
60 }
61 ptr = ptr->hnext;
62 }
63
64 logprintf("netlock: adding %d.%d.%d.%d\n", PRINT_IP(ip_src));
65 have_traffic = 1;
66 HNode *hnew = malloc(sizeof(HNode));
67 assert(hnew);
68 hnew->ip_src = ip_src;
69 hnew->port_src = port_src;
70 hnew->protocol = protocol;
71 hnew->hnext = NULL;
72 hnew->ip_instance = ip_instance + 1;
73 if (htable[h] == NULL)
74 htable[h] = hnew;
75 else {
76 hnew->hnext = htable[h];
77 htable[h] = hnew;
78 }
79}
80
81
82
83
84// trace rx traffic coming in
85static void run_trace(void) {
86 logprintf("netlock: accumulating traffic for %d seconds\n", NETLOCK_INTERVAL);
87
88 // trace only rx ipv4 tcp and upd
89 int s1 = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
90 int s2 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
91 if (s1 < 0 || s2 < 0)
92 errExit("socket");
93
94
95 unsigned start = time(NULL);
96 unsigned char buf[MAX_BUF_SIZE];
97 // FIXME: error: variable 'bw' set but not used [-Werror,-Wunused-but-set-variable]
98 //unsigned bw = 0; // bandwidth calculations
99
100 int printed = 0;
101 while (1) {
102 unsigned runtime = time(NULL) - start;
103 if ( runtime >= NETLOCK_INTERVAL)
104 break;
105 if (runtime % 10 == 0) {
106 if (!printed)
107 logprintf("netlock: %u seconds remaining\n", NETLOCK_INTERVAL - runtime);
108 printed = 1;
109 }
110 else
111 printed = 0;
112
113 fd_set rfds;
114 FD_ZERO(&rfds);
115 FD_SET(s1, &rfds);
116 FD_SET(s2, &rfds);
117 int maxfd = (s1 > s2) ? s1 : s2;
118 maxfd++;
119
120 struct timeval tv;
121 tv.tv_sec = 1;
122 tv.tv_usec = 0;
123
124 int rv = select(maxfd, &rfds, NULL, NULL, &tv);
125 if (rv < 0)
126 errExit("select");
127 else if (rv == 0)
128 continue;
129
130
131 // rx tcp traffic by default
132 int sock = s1;
133
134 if (FD_ISSET(s2, &rfds))
135 sock = s2;
136
137 unsigned bytes = recvfrom(sock, buf, MAX_BUF_SIZE, 0, NULL, NULL);
138 if (bytes >= 20) { // size of IP header
139#ifdef DEBUG
140 {
141 uint32_t ip_src;
142 memcpy(&ip_src, buf + 12, 4);
143 ip_src = ntohl(ip_src);
144
145 uint32_t ip_dst;
146 memcpy(&ip_dst, buf + 16, 4);
147 ip_dst = ntohl(ip_dst);
148 printf("%d.%d.%d.%d -> %d.%d.%d.%d, %u bytes\n", PRINT_IP(ip_src), PRINT_IP(ip_dst), bytes);
149 }
150#endif
151 // filter out loopback traffic
152 if (buf[12] != 127 && buf[16] != 127) {
153 // FIXME: error: variable 'bw' set but not used [-Werror,-Wunused-but-set-variable]
154 //bw += bytes + 14; // assume a 14 byte Ethernet layer
155
156 uint32_t ip_src;
157 memcpy(&ip_src, buf + 12, 4);
158 ip_src = ntohl(ip_src);
159
160 uint8_t hlen = (buf[0] & 0x0f) * 4;
161 uint16_t port_src = 0;
162 memcpy(&port_src, buf + hlen, 2);
163 port_src = ntohs(port_src);
164
165 uint8_t protocol = buf[9];
166 hnode_add(ip_src, protocol, port_src);
167 }
168 }
169 }
170
171 close(s1);
172 close(s2);
173}
174
175static char *filter_start =
176 "*filter\n"
177 ":INPUT DROP [0:0]\n"
178 ":FORWARD DROP [0:0]\n"
179 ":OUTPUT DROP [0:0]\n";
180
181// return 1 if error
182static int print_filter(FILE *fp) {
183 fprintf(fp, "%s\n", filter_start);
184 fprintf(fp, "-A INPUT -s 127.0.0.0/8 -j ACCEPT\n");
185 fprintf(fp, "-A OUTPUT -d 127.0.0.0/8 -j ACCEPT\n");
186 fprintf(fp, "\n");
187
188 int i;
189 for (i = 0; i < HMAX; i++) {
190 HNode *ptr = htable[i];
191 while (ptr) {
192 // filter rules are targeting ip address, the port number is disregarded,
193 // so we look only at the first instance of an address
194 if (ptr->ip_instance == 1) {
195 char *protocol = (ptr->protocol == 6) ? "tcp" : "udp";
196 fprintf(fp, "-A INPUT -s %d.%d.%d.%d -p %s -j ACCEPT\n",
197 PRINT_IP(ptr->ip_src),
198 protocol);
199 fprintf(fp, "-A OUTPUT -d %d.%d.%d.%d -p %s -j ACCEPT\n",
200 PRINT_IP(ptr->ip_src),
201 protocol);
202 fprintf(fp, "\n");
203 }
204 ptr = ptr->hnext;
205 }
206 }
207 fprintf(fp, "COMMIT\n");
208
209 return 0;
210}
211
212static char *flush_rules[] = {
213 "-P INPUT ACCEPT",
214// "-P FORWARD DENY",
215 "-P OUTPUT ACCEPT",
216 "-F",
217 "-X",
218// "-t nat -F",
219// "-t nat -X",
220// "-t mangle -F",
221// "-t mangle -X",
222// "iptables -t raw -F",
223// "-t raw -X",
224 NULL
225};
226
227static void deploy_netfilter(void) {
228 int rv;
229 char *cmd;
230 int i;
231
232 if (have_traffic == 0) {
233 logprintf("Sorry, no network traffic was detected. The firewall was not configured.\n");
234 return;
235 }
236 // find iptables command
237 char *iptables = NULL;
238 char *iptables_restore = NULL;
239 if (access("/sbin/iptables", X_OK) == 0) {
240 iptables = "/sbin/iptables";
241 iptables_restore = "/sbin/iptables-restore";
242 }
243 else if (access("/usr/sbin/iptables", X_OK) == 0) {
244 iptables = "/usr/sbin/iptables";
245 iptables_restore = "/usr/sbin/iptables-restore";
246 }
247 if (iptables == NULL || iptables_restore == NULL) {
248 fprintf(stderr, "Error: iptables command not found, netfilter not configured\n");
249 exit(1);
250 }
251
252 // flush all netfilter rules
253 i = 0;
254 while (flush_rules[i]) {
255 char *cmd;
256 if (asprintf(&cmd, "%s %s", iptables, flush_rules[i]) == -1)
257 errExit("asprintf");
258 int rv = system(cmd);
259 (void) rv;
260 free(cmd);
261 i++;
262 }
263
264 // create temporary file
265 char fname[] = "/tmp/firejail-XXXXXX";
266 int fd = mkstemp(fname);
267 if (fd == -1) {
268 fprintf(stderr, "Error: cannot create temporary configuration file\n");
269 exit(1);
270 }
271
272 FILE *fp = fdopen(fd, "w");
273 if (!fp) {
274 rv = unlink(fname);
275 (void) rv;
276 fprintf(stderr, "Error: cannot create temporary configuration file\n");
277 exit(1);
278 }
279 print_filter(fp);
280 fclose(fp);
281
282 logprintf("\n\n");
283 logprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
284 if (asprintf(&cmd, "cat %s >> %s", fname, arg_log) == -1)
285 errExit("asprintf");
286 rv = system(cmd);
287 (void) rv;
288 free(cmd);
289
290 if (asprintf(&cmd, "cat %s", fname) == -1)
291 errExit("asprintf");
292 rv = system(cmd);
293 (void) rv;
294 free(cmd);
295 logprintf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
296
297
298 // configuring
299 if (asprintf(&cmd, "%s %s", iptables_restore, fname) == -1)
300 errExit("asprintf");
301 rv = system(cmd);
302 if (rv)
303 fprintf(stdout, "Warning: possible netfilter problem!");
304 free(cmd);
305
306 rv = unlink(fname);
307 (void) rv;
308 logprintf("\nnetlock: firewall deployed\n");
309}
310
311void logprintf(char *fmt, ...) {
312 if (!arg_log)
313 return;
314
315 FILE *fp = fopen(arg_log, "a");
316 if (fp) { // disregard if error
317 va_list args;
318 va_start(args, fmt);
319 vfprintf(fp, fmt, args);
320 va_end(args);
321 fclose(fp);
322 }
323
324 va_list args;
325 va_start(args, fmt);
326 vfprintf(stdout, fmt, args);
327 va_end(args);
328}
329
330static const char *const usage_str =
331 "Usage: fnettrace [OPTIONS]\n"
332 "Options:\n"
333 " --help, -? - this help screen\n"
334 " --log=filename - netlocker logfile\n"
335 " --tail - \"tail -f\" functionality\n";
336
337static void usage(void) {
338 puts(usage_str);
339}
340
341int main(int argc, char **argv) {
342 int i;
343
344 for (i = 1; i < argc; i++) {
345 if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") == 0) {
346 usage();
347 return 0;
348 }
349 else if (strcmp(argv[i], "--tail") == 0)
350 arg_tail = 1;
351 else if (strncmp(argv[i], "--log=", 6) == 0)
352 arg_log = argv[i] + 6;
353 else {
354 fprintf(stderr, "Error: invalid argument\n");
355 return 1;
356 }
357 }
358
359 // tail
360 if (arg_tail) {
361 if (!arg_log) {
362 fprintf(stderr, "Error: no log file\n");
363 usage();
364 exit(1);
365 }
366
367 tail(arg_log);
368 sleep(5);
369 exit(0);
370 }
371
372 if (getuid() != 0) {
373 fprintf(stderr, "Error: you need to be root to run this program\n");
374 return 1;
375 }
376
377 // kill the process if the parent died
378 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
379
380 logprintf("netlock: starting network lockdown\n");
381 run_trace();
382
383 // TCP path MTU discovery will not work properly since the firewall drops all ICMP packets
384 // Instead, we use iPacketization Layer PMTUD (RFC 4821) support in Linux kernel
385 int rv = system("echo 1 > /proc/sys/net/ipv4/tcp_mtu_probing");
386 (void) rv;
387
388 deploy_netfilter();
389 sleep(3);
390 if (arg_log)
391 unlink(arg_log);
392
393 return 0;
394}
diff --git a/src/fnettrace/tail.c b/src/fnetlock/tail.c
index 3b1b274f8..e5d0367f6 100644
--- a/src/fnettrace/tail.c
+++ b/src/fnetlock/tail.c
@@ -17,7 +17,7 @@
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "fnettrace.h" 20#include "fnetlock.h"
21 21
22void tail(const char *logfile) { 22void tail(const char *logfile) {
23 assert(logfile); 23 assert(logfile);
diff --git a/src/fnettrace-dns/main.c b/src/fnettrace-dns/main.c
index 1cde1942c..6324a17db 100644
--- a/src/fnettrace-dns/main.c
+++ b/src/fnettrace-dns/main.c
@@ -26,6 +26,7 @@
26#include <signal.h> 26#include <signal.h>
27#define MAX_BUF_SIZE (64 * 1024) 27#define MAX_BUF_SIZE (64 * 1024)
28 28
29static int arg_nolocal = 0;
29static char last[512] = {'\0'}; 30static char last[512] = {'\0'};
30 31
31// pkt - start of DNS layer 32// pkt - start of DNS layer
@@ -116,7 +117,7 @@ static void print_date(void) {
116 struct tm *t = localtime(&now); 117 struct tm *t = localtime(&now);
117 118
118 if (day != t->tm_yday) { 119 if (day != t->tm_yday) {
119 printf("\nDNS trace for %s", ctime(&now)); 120 printf("DNS trace for %s", ctime(&now));
120 day = t->tm_yday; 121 day = t->tm_yday;
121 } 122 }
122 fflush(0); 123 fflush(0);
@@ -159,6 +160,14 @@ static void run_trace(void) {
159 memcpy(&ip_src, buf + 14 + 12, 4); 160 memcpy(&ip_src, buf + 14 + 12, 4);
160 ip_src = ntohl(ip_src); 161 ip_src = ntohl(ip_src);
161 162
163 if (arg_nolocal) {
164 if ((ip_src & 0xff000000) == 0x7f000000 || // 127.0.0.0/8
165 (ip_src & 0xff000000) == 0x0a000000 || // 10.0.0.0/8
166 (ip_src & 0xffff0000) == 0xc0a80000 || // 192.168.0.0/16
167 (ip_src & 0xfff00000) == 0xac100000) // 172.16.0.0/12
168 continue;
169 }
170
162 // if DNS packet, extract the query 171 // if DNS packet, extract the query
163 if (port_src == 53 && protocol == 0x11) // UDP protocol 172 if (port_src == 53 && protocol == 0x11) // UDP protocol
164 print_dns(ip_src, buf + 14 + ip_hlen + 8); // IP and UDP header len 173 print_dns(ip_src, buf + 14 + ip_hlen + 8); // IP and UDP header len
@@ -170,7 +179,8 @@ static void run_trace(void) {
170static const char *const usage_str = 179static const char *const usage_str =
171 "Usage: fnettrace-dns [OPTIONS]\n" 180 "Usage: fnettrace-dns [OPTIONS]\n"
172 "Options:\n" 181 "Options:\n"
173 " --help, -? - this help screen\n"; 182 " --help, -? - this help screen\n"
183 " --nolocal\n";
174 184
175static void usage(void) { 185static void usage(void) {
176 puts(usage_str); 186 puts(usage_str);
@@ -184,6 +194,8 @@ int main(int argc, char **argv) {
184 usage(); 194 usage();
185 return 0; 195 return 0;
186 } 196 }
197 else if (strcmp(argv[i], "--nolocal") == 0)
198 arg_nolocal = 1;
187 else { 199 else {
188 fprintf(stderr, "Error: invalid argument\n"); 200 fprintf(stderr, "Error: invalid argument\n");
189 return 1; 201 return 1;
diff --git a/src/fnettrace-sni/main.c b/src/fnettrace-sni/main.c
index e7782d656..d4fbf703a 100644
--- a/src/fnettrace-sni/main.c
+++ b/src/fnettrace-sni/main.c
@@ -152,7 +152,7 @@ static void print_date(void) {
152 struct tm *t = localtime(&now); 152 struct tm *t = localtime(&now);
153 153
154 if (day != t->tm_yday) { 154 if (day != t->tm_yday) {
155 printf("\nSNI trace for %s", ctime(&now)); 155 printf("SNI trace for %s", ctime(&now));
156 day = t->tm_yday; 156 day = t->tm_yday;
157 } 157 }
158 158
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/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 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