-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ghaf security hardening #661
base: main
Are you sure you want to change the base?
Changes from 7 commits
23265d8
74a555a
86df98c
26854c1
b31c1a8
f753f2d
a5ffa7b
74afc89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Copyright 2024-2025 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
{ | ||
config, | ||
lib, | ||
... | ||
}: let | ||
cfg = config.ghaf.security.apparmor; | ||
in { | ||
## Option to enable Apparmor security | ||
options.ghaf.security.apparmor = { | ||
enable = lib.mkOption { | ||
description = '' | ||
Enable Apparmor security. | ||
''; | ||
type = lib.types.bool; | ||
default = false; | ||
}; | ||
}; | ||
|
||
imports = [ | ||
./profiles/firefox.nix | ||
./profiles/chromium.nix | ||
]; | ||
|
||
config = lib.mkIf cfg.enable { | ||
security.apparmor.enable = true; | ||
security.apparmor.killUnconfinedConfinables = lib.mkDefault true; | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
# Copyright 2024-2025 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
{ | ||
config, | ||
lib, | ||
pkgs, | ||
... | ||
}: let | ||
cfg = config.ghaf.security.apparmor; | ||
xprofile = | ||
if config.ghaf.security.system-security.enable | ||
then '' | ||
capability sys_admin, | ||
capability sys_chroot, | ||
|
||
capability chown, | ||
capability fsetid, | ||
capability setgid, | ||
capability setuid, | ||
capability dac_override, | ||
capability sys_chroot, | ||
|
||
capability sys_ptrace, | ||
ptrace (read, readby), | ||
capability sys_chroot, | ||
capability ipc_lock, | ||
|
||
capability setuid, | ||
capability setgid, | ||
|
||
owner @{PROC}/[0-9]*/gid_map w, | ||
owner @{PROC}/[0-9]*/setgroups w, | ||
owner @{PROC}/[0-9]*/uid_map w, | ||
} | ||
'' | ||
else '' | ||
} | ||
''; | ||
in { | ||
## Option to enable Apparmor profile for chromium | ||
options.ghaf.security.apparmor.apps.chromium = { | ||
enable = lib.mkOption { | ||
description = '' | ||
Enable Chromium AppArmor profile. | ||
''; | ||
type = lib.types.bool; | ||
default = false; | ||
}; | ||
}; | ||
## Apparmor profile for Chromium | ||
config.security.apparmor.policies."bin.chromium" = lib.mkIf cfg.apps.chromium.enable { | ||
profile = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does this compare to: https://gitlab.com/apparmor/apparmor/-/blob/master/profiles/apparmor/profiles/extras/chromium_browser?ref_type=heads Which is already packaged in NixOS ( And if we have improvements to the Chromium apparmor policy, should it be upstreamed or included as a patch to |
||
'' | ||
abi <abi/3.0>, | ||
include <tunables/global> | ||
|
||
@{CHROMIUM} = ${pkgs.chromium.browser}/libexec/chromium/chromium | ||
@{INTEGER}=[0-9]{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],} | ||
@{ETC}=/etc | ||
@{NIX_STORE}=/nix/store | ||
|
||
profile chromium @{CHROMIUM} flags=(enforce){ | ||
include <abstractions/base> | ||
include <abstractions/audio> | ||
include <abstractions/cups-client> | ||
include <abstractions/dbus-session> | ||
include <abstractions/gnome> | ||
include <abstractions/ibus> | ||
include <abstractions/kde> | ||
include <abstractions/nameservice> | ||
|
||
include "${pkgs.apparmorRulesFromClosure {name = "chromium";} [pkgs.chromium]}" | ||
|
||
${config.environment.etc."os-release".source} r, | ||
${config.environment.etc."lsb-release".source} r, | ||
|
||
# All of these are for sanely dropping from root and chrooting | ||
|
||
# optional | ||
capability sys_resource, | ||
owner @{PROC}/[0-9]*/gid_map w, | ||
owner @{PROC}/[0-9]*/setgroups w, | ||
owner @{PROC}/[0-9]*/uid_map w, | ||
|
||
@{ETC}/nixos/** r, | ||
@{ETC}/nix/** r, | ||
@{NIX_STORE}/** mrix, | ||
|
||
@{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r, | ||
@{sys}/devices/system/cpu/present r, | ||
@{sys}/devices/system/cpu/kernel_max r, | ||
@{sys}/devices/system/cpu/cpu[0-9]/cache/index[0-9]/size r, | ||
@{sys}/bus/ r, | ||
@{sys}/bus/** r, | ||
|
||
@{sys}/class/ r, | ||
@{sys}/class/** r, | ||
@{sys}/devices/pci*/** rw, | ||
@{sys}/devices/virtual/tty/** r, | ||
@{sys}/devices/virtual/dmi/** r, | ||
|
||
/tmp/.X[0-9]*-lock r, | ||
|
||
@{CHROMIUM} mrix, | ||
${pkgs.chromium}/share/{,**} r, | ||
${pkgs.chromium.sandbox}/bin/* rix, | ||
${pkgs.chromium.browser} r, | ||
${pkgs.chromium.browser}/share/{,**} r, | ||
${pkgs.chromium.browser}/libexec/chromium/chromium rix, | ||
${pkgs.chromium.browser}/libexec/chromium/*.so mr, | ||
${pkgs.chromium.browser}/libexec/chromium/* rix, | ||
${pkgs.chromium.browser}/libexec/chromium/** r, | ||
|
||
@{PROC} r, | ||
@{PROC}/[0-9]*/net/ipv6_route r, | ||
@{PROC}/[0-9]*/net/arp r, | ||
@{PROC}/[0-9]*/net/if_inet6 r, | ||
@{PROC}/[0-9]*/net/route r, | ||
@{PROC}/[0-9]*/net/ipv6_route r, | ||
@{PROC}/[0-9]*/stat rix, | ||
@{PROC}/[0-9]*/task/@{tid}/comm rw, | ||
@{PROC}/[0-9]*/task/@{tid}/status rix, | ||
owner @{PROC}/[0-9]*/cgroup r, | ||
owner @{PROC}/[0-9]*/fd/ r, | ||
owner @{PROC}/[0-9]*/io r, | ||
owner @{PROC}/[0-9]*/mountinfo r, | ||
owner @{PROC}/[0-9]*/mounts r, | ||
owner @{PROC}/[0-9]*/oom_score_adj w, | ||
owner @{PROC}/[0-9]*/smaps rix, | ||
owner @{PROC}/[0-9]*/statm rix, | ||
owner @{PROC}/[0-9]*/task/ r, | ||
owner @{PROC}/[0-9]*/cmdline rix, | ||
owner @{PROC}/[0-9]*/environ rix, | ||
owner @{PROC}/[0-9]*/clear_refs rw, | ||
owner @{PROC}/self/* r, | ||
owner @{PROC}/self/fd/* rw, | ||
@{PROC}/sys/kernel/yama/ptrace_scope rw, | ||
@{PROC}/sys/fs/inotify/max_user_watches r, | ||
@{PROC}/ati/major r, | ||
|
||
/dev/fb0 rw, | ||
/dev/ r, | ||
/dev/hidraw@{INTEGER} rw, | ||
/dev/shm/** rw, | ||
/dev/tty rw, | ||
/dev/video@{INTEGER} rw, | ||
owner /dev/shm/pulse-shm* m, | ||
owner /dev/tty@{INTEGER} rw, | ||
|
||
owner @{HOME} r, | ||
owner @{HOME}/.cache/chromium wrk, | ||
owner @{HOME}/.cache/mesa_shader_cache/index wrk, | ||
owner @{HOME}/.cache/chromium/** mrwk, | ||
owner @{HOME}/.cache/fontconfig/** rwk, | ||
owner @{HOME}/.config/chromium rwkm, | ||
owner @{HOME}/.config/chromium/** rwkm, | ||
owner @{HOME}/.config/** rw, | ||
owner @{HOME}/.local/share/mime/mime.cache m, | ||
owner @{HOME}/.pki/nssdb/ rwk, | ||
owner @{HOME}/.pki/nssdb/** rwk, | ||
owner @{HOME}/Downloads/ r, | ||
owner @{HOME}/Downloads/* rw, | ||
owner @{run}/user/1000/ rw, | ||
owner @{run}/user/1000/** rw, | ||
owner /tmp/** rwk, | ||
owner /var/tmp/** m, | ||
|
||
owner /tmp/chromiumargs.?????? rw, | ||
|
||
deny /boot/EFI/systemd/** r, | ||
deny /boot/EFI/nixos/** r, | ||
deny /boot/loader/** r, | ||
deny /.suspended r, | ||
deny /boot/vmlinuz* r, | ||
deny /var/cache/fontconfig/ w, | ||
|
||
### Networking ### | ||
network inet stream, | ||
network inet6 stream, | ||
network inet dgram, | ||
#network inet6 dgrap, | ||
network netlink raw, | ||
'' | ||
+ xprofile; | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
# Copyright 2024-2025 TII (SSRC) and the Ghaf contributors | ||
# SPDX-License-Identifier: Apache-2.0 | ||
{ | ||
config, | ||
lib, | ||
pkgs, | ||
... | ||
}: let | ||
cfg = config.ghaf.security.apparmor; | ||
xprofile = | ||
if config.ghaf.security.system-security.enable | ||
then '' | ||
capability sys_admin, | ||
capability sys_chroot, | ||
owner @{PROC}/@{pid}/gid_map w, | ||
owner @{PROC}/@{pid}/setgroups w, | ||
owner @{PROC}/@{pid}/uid_map w, | ||
} | ||
'' | ||
else '' | ||
} | ||
''; | ||
in { | ||
## Option to enable Apparmor profile for Firefox | ||
options.ghaf.security.apparmor.apps.firefox = { | ||
enable = lib.mkOption { | ||
description = '' | ||
Enable firefox AppArmor profile. | ||
''; | ||
type = lib.types.bool; | ||
default = false; | ||
}; | ||
}; | ||
|
||
## Apparmor profile for Firefox | ||
config.security.apparmor.policies."bin.firefox" = lib.mkIf cfg.apps.firefox.enable { | ||
profile = | ||
'' | ||
abi <abi/3.0>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just like Chromium, I think if we package our own version, it should be clear how it is different than the profile that is packaged in NixOS? |
||
include <tunables/global> | ||
|
||
@{MOZ_LIBDIR} = ${pkgs.firefox}/lib/firefox{,-esr} | ||
@{MOZ_HOMEDIR} = @{HOME}/.mozilla | ||
@{CACHEDIR} = @{HOME}/.cache | ||
@{MOZ_CACHEDIR} = @{CACHEDIR}/mozilla | ||
@{FIREFOX} = ${pkgs.firefox}/bin/firefox | ||
@{INTEGER}=[0-9]{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],}{[0-9],} | ||
@{ETC}=/etc | ||
@{NIX_STORE}=/nix/store | ||
|
||
profile firefox @{FIREFOX} flags=(enforce){ | ||
include <abstractions/base> | ||
include <abstractions/audio> | ||
include <abstractions/cups-client> | ||
include <abstractions/dbus-session> | ||
include <abstractions/gnome> | ||
include <abstractions/ibus> | ||
include <abstractions/kde> | ||
include <abstractions/nameservice> | ||
|
||
include "${pkgs.apparmorRulesFromClosure {name = "firefox";} [pkgs.firefox]}" | ||
|
||
# Uncomment these, if kernel.unprivileged_userns_clone = 1 | ||
#capability sys_admin, | ||
#capability sys_chroot, | ||
#owner @{PROC}/@{pid}/gid_map w, | ||
#owner @{PROC}/@{pid}/setgroups w, | ||
#owner @{PROC}/@{pid}/uid_map w, | ||
|
||
${config.environment.etc."os-release".source} r, | ||
${config.environment.etc."lsb-release".source} r, | ||
|
||
@{ETC}/nixos/** r, | ||
@{ETC}/nix/** r, | ||
@{NIX_STORE}/** mr, | ||
|
||
@{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r, | ||
@{sys}/devices/system/cpu/present r, | ||
@{sys}/devices/system/cpu/cpu[0-9]/cache/index[0-9]/size r, | ||
@{sys}/bus/pci rw, | ||
@{sys}/bus/pci_express rw, | ||
@{sys}/bus/pci/devices/ rw, | ||
@{sys}/bus/pci/devices/** rw, | ||
@{sys}/devices/pci*/** rw, | ||
/tmp/.X[0-9]*-lock r, | ||
|
||
@{FIREFOX} mrix, | ||
${pkgs.firefox}/lib/firefox/firefox rix, | ||
${pkgs.firefox}/lib/firefox/glxtest rix, | ||
${pkgs.firefox}/lib/firefox/firefox-bin rix, | ||
${pkgs.firefox}/lib/firefox/*.so mr, | ||
${pkgs.firefox}/share/firefox/{,**} r, | ||
${pkgs.firefox}/share/firefox/fonts r, | ||
${pkgs.firefox}/lib/mozilla/plugins/ r, | ||
${pkgs.firefox}/lib/mozilla/plugins/libvlcplugin.so mr, | ||
|
||
${pkgs.firefox-unwrapped}/lib/firefox/glxtest rix, | ||
${pkgs.firefox-unwrapped}/lib/firefox/firefox rix, | ||
${pkgs.firefox-unwrapped}/lib/firefox/firefox-bin rix, | ||
${pkgs.firefox-unwrapped}/lib/firefox/*.so mr, | ||
${pkgs.firefox-unwrapped}/lib/firefox/fonts r, | ||
${pkgs.firefox-unwrapped}/lib/firefox/pingsender r, | ||
${pkgs.firefox-unwrapped}/share/firefox/{,**} r, | ||
${pkgs.firefox-unwrapped}/lib/mozilla/plugins/ r, | ||
${pkgs.firefox-unwrapped}/lib/mozilla/plugins/libvlcplugin.so mr, | ||
|
||
@{PROC}/@{pid}/net/ipv6_route r, | ||
@{PROC}/@{pid}/net/arp r, | ||
@{PROC}/@{pid}/net/if_inet6 r, | ||
@{PROC}/@{pid}/net/route r, | ||
@{PROC}/@{pid}/net/ipv6_route r, | ||
owner @{PROC}/@{pid}/cgroup r, | ||
owner @{PROC}/@{pid}/fd/ r, | ||
owner @{PROC}/@{pid}/mountinfo r, | ||
owner @{PROC}/@{pid}/mounts r, | ||
owner @{PROC}/@{pid}/oom_score_adj w, | ||
owner @{PROC}/@{pid}/smaps r, | ||
owner @{PROC}/@{pid}/stat r, | ||
owner @{PROC}/@{pid}/statm r, | ||
owner @{PROC}/@{pid}/task/ r, | ||
owner @{PROC}/@{pid}/task/@{tid}/comm rw, | ||
owner @{PROC}/@{pid}/task/@{tid}/stat r, | ||
owner @{PROC}/@{pids}/cmdline r, | ||
owner @{PROC}/@{pids}/environ r, | ||
owner @{PROC}/self/* r, | ||
owner @{PROC}/self/fd/* rw, | ||
|
||
/dev/fb0 rw, | ||
/dev/ r, | ||
/dev/hidraw@{INTEGER} rw, | ||
/dev/shm/ r, | ||
/dev/tty rw, | ||
/dev/video@{INTEGER} rw, | ||
owner /dev/shm/org.chromium.* rw, | ||
owner /dev/shm/org.mozilla.ipc.@{pid}.@{INTEGER} rw, | ||
owner /dev/shm/wayland.mozilla.ipc.@{INTEGER} rw, | ||
owner /dev/tty@{INTEGER} rw, | ||
|
||
owner @{MOZ_HOMEDIR}/ rw, | ||
owner @{MOZ_HOMEDIR}/{extensions,systemextensionsdev}/ rw, | ||
owner @{MOZ_HOMEDIR}/firefox/ rw, | ||
owner @{MOZ_HOMEDIR}/firefox/installs.ini rw, | ||
owner @{MOZ_HOMEDIR}/firefox/profiles.ini rw, | ||
owner @{MOZ_HOMEDIR}/firefox/*/ rw, | ||
owner @{MOZ_HOMEDIR}/firefox/*/** rwk, | ||
owner @{HOME}/.cache/ rw, | ||
owner @{MOZ_CACHEDIR}/ rw, | ||
owner @{MOZ_CACHEDIR}/** rwk, | ||
owner @{CACHEDIR}/mesa_shader_cache/index wr, | ||
owner @{run}/user/1000/ rw, | ||
owner @{run}/user/1000/** rw, | ||
owner /tmp/** m, | ||
owner /var/tmp/** m, | ||
|
||
deny /boot/EFI/systemd/** r, | ||
deny /boot/EFI/nixos/** r, | ||
deny /boot/loader/** r, | ||
deny /.suspended r, | ||
deny /boot/vmlinuz* r, | ||
deny /var/cache/fontconfig/ w, | ||
|
||
### Networking ### | ||
network inet stream, | ||
network inet6 stream, | ||
network inet dgram, | ||
#network inet6 dgrap, | ||
network netlink raw, | ||
'' | ||
+ xprofile; | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was always a bit skeptical about this option when it was added to NixOS. Does firefox/chromium properly restarts itself afterwards?