-
Notifications
You must be signed in to change notification settings - Fork 575
Comparison of firejail and systemd's hardening options
rusty-snake edited this page Sep 13, 2021
·
8 revisions
TL;DR: These tables list equivalent options rather than equal options. Read
their docs!
NOTE: Keep in mind that systemd is made to run and sandbox system-services
while firejail has its focus on desktop programs. Therefore some options differ
in their behavior, for example does firejail's private-tmp
always bind-mount
/tmp/.X11-unix
, while systemd's PrivateTmp=yes
does not. Always read the
documentation of the option you use!
man 5 systemd.exec
man 5 systemd.resource-control
man 5 systemd.service
man 5 systemd.unit
man 1 firejail
man 5 firejail-profile
firejail | systemd |
---|---|
always | PrivateMounts=yes |
blacklist /home blacklist /root blacklist /run/user
|
ProtectHome=yes |
blacklist /boot |
InaccessiblePaths=/boot |
chroot /foobaz |
RootDirectory=/foobaz |
disable-mnt |
InaccessiblePaths=/mnt InaccessiblePaths=/media InaccessiblePaths=/run/mount (breaks systemd)InaccessiblePaths=/run/media
|
mkdir |
Not Implemented You can use RuntimeDirectory= , StateDirectory= , CacheDirectory= , LogsDirectory= , ConfigurationDirectory= .You could write a mkdir@.service and use After=mkdir\x2fetc\x2fdnsmasq.service /After=mkdir@etc-dnsmasq.service . |
mkfile |
Not Implemented |
noexec /tmp |
NoExecPaths=/tmp |
Not Implemented | ExecPaths=/tmp/bin |
private-bin bash,getenforce,python3 |
TemporaryFileSystem=/bin TemporaryFileSystem=/usr/bin TemporaryFileSystem=/sbin TemporaryFileSystem=/usr/sbin BindReadOnlyPaths=/bin/bash BindReadOnlyPaths=/usr/bin/python3 BindReadOnlyPaths=/usr/sbin/getenforce
|
private-cwd |
WorkingDirectory=~ |
private-cwd /root |
WorkingDirectory=/root |
private-etc ca-certificates,crypto-policies,nsswitch.conf,pki,resolv.conf,ssl |
TemporaryFileSystem=/etc BindReadOnlyPaths=-/etc/ca-certificates BindReadOnlyPaths=-/etc/crypto-policies BindReadOnlyPaths=-/etc/nsswitch.conf BindReadOnlyPaths=-/etc/pki BindReadOnlyPaths=-/etc/resolv.conf BindReadOnlyPaths=-/etc/ssl
|
private-lib |
Not Implemented |
private-opt vivaldi |
TemporaryFileSystem=/opt BindReadOnlyPaths=/opt/vivaldi
|
private-srv www |
TemporaryFileSystem=/srv BindReadOnlyPaths=-/srv/www
|
private-tmp |
PrivateTmp=yes |
read-only /usr |
ProtectSystem=yes |
read-only /usr read-only /etc
|
ProtectSystem=full |
read-only / |
ProtectSystem=strict |
read-only /home read-only /root read-only /run/user
|
ProtectHome=read-only |
read-only /sys/fs/cgroup |
ProtectControlGroups=yes |
read-only /proc/acpi read-only /proc/fs read-only /proc/irq read-only /proc/latency_stats read-only /proc/sys read-only /proc/sysrq-trigger read-only /proc/timer_stats read-only /sys
|
ProtectKernelTunables=yes |
read-only /foo |
ReadOnlyPaths=/foo |
read-write /foo/bar |
ReadWritePaths=/foo/bar |
tmpfs /home tmpfs /root tmpfs /run/user
|
ProtectHome=tmpfs |
tmpfs /xyzzy |
TemporaryFileSystem=/xyzzy |
tracelog |
Not Implemented |
whitelist /mnt/backup |
TemporaryFileSystem=/mnt BindPaths=/mnt/backup
|
fixme |
BindPaths= BindReadOnlyPaths=
|
always (via pid-namespace) | ProtectProc=invisible |
Not Implemented | ProtectProc=noaccess |
fixme | ProcSubset=pid |
Not Implemented | RestrictSUIDSGID=yes |
firejail | systemd |
---|---|
private-dev |
PrivateDevices=yes |
no3d |
InaccessiblePaths=/dev/dri |
nodvd |
InaccessiblePaths=/dev/sr* |
noinput |
InaccessiblePaths=/dev/input |
nosound |
InaccessiblePaths=/dev/snd |
notv |
InaccessiblePaths=/dev/dvb |
nou2f |
InaccessiblePaths=/dev/hidraw* |
novideo |
InaccessiblePaths=/dev/video* |
firejail | systemd |
---|---|
caps.drop all |
CapabilityBoundingSet= |
caps.drop sys_admin,net_admin |
CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_NET_ADMIN |
caps.keep net_bind_service |
CapabilityBoundingSet=CAP_NET_BIND_SERVICE |
memory-deny-write-execute |
MemoryDenyWriteExecute=yes SystemCallFilter=~memfd_create
|
nonewprivs |
NoNewPrivileges=yes |
seccomp |
SystemCallFilter=<omitted because it is to long, look at syscalls.txt> |
seccomp.block-secondary |
SystemCallArchitectures=native |
seccomp.drop @debug |
SystemCallFilter=~@debug |
seccomp.keep @file-system,mount |
SystemCallFilter=@file-system mount |
#3106 | SystemCallFilter=@system-service |
seccomp-error-action EPERM (default) |
SystemCallErrorNumber=EPERM |
seccomp-error-action kill |
SystemCallErrorNumber= (default) |
caps.drop sys_time,wake_alarm seccomp.drop @clock read-only /dev/rtc*
|
ProtectClock=yes |
caps.drop syslog seccomp.drop syslog blacklist /dev/kmsg blacklist /proc/kmsg
|
ProtectKernelLogs=yes |
caps.drop sys_module blacklist /usr/lib/modules seccomp.drop @module
|
ProtectKernelModules=yes |
fixme | LockPersonality=yes |
firejail | systemd |
---|---|
dns 9.9.9.9 |
Not Implemented |
hosts-file |
Not Implemented |
hostname myhost |
Not Implemented |
net none |
PrivateNetwork=yes |
net eth0 |
Not Implemented |
netfilter /etc/firejail/myfilter.net |
Not Implemented |
Not Implemented |
IPIngressFilterPath= IPEgressFilterPath=
|
net eth0 netfilter ipdenyallow.net
|
IPAddressDeny= IPAddressAllow=
|
netns NAME |
NetworkNamespacePath=/var/run/netns/NAME |
protocol unix,inet,inet6 |
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 |
fixme | ProtectHostname=yes |
D-Bus filtering is not implemented for systemd and blocking the system-bus socket breaks systemd.
firejail | systemd |
---|---|
cpu 0,1 |
CPUAffinity=0,1 |
nice 2 |
Nice=2 |
rlimit* |
Limit* |
timeout |
TimeoutSec= |
fixme | RestrictRealtime=yes |
Not Implemented | CoredumpFilter= |
Not Implemented | KeyringMode= |
Not Implemented | OOMScoreAdjust= |
Not Implemented | UMask=0077 |
firejail | systemd |
---|---|
nogroups |
Not Implemented |
noroot |
PrivateUsers=yes |
Not Implemented |
User=user Group=group SupplementaryGroups=supp_group1 supp_group2
|
Not Implemented | DynamicUser=yes |
Not Implemented | RemoveIPC=yes |
firejail | systemd |
---|---|
env FOO=bar |
Environment=FOO=bar |
rmenv |
UnsetEnvironment=EDITOR |
firejail | systemd |
---|---|
include some-common.inc |
Not Implemented You can use symlinks / hardlinks in /etc/systemd/system/UNIT.d . |
ipc-namespace |
PrivateIPC=yes |
join |
JoinsNamespaceOf= |
machine-id |
Not Implemented Maybe you can use ExecStartPre=!/bin/sh -c "dbus-uuidgen > /etc/machine-id" , however until now nobody had tested this. |
Not Implemented | RestrictNamespaces= |