Skip to content
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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/icons/png/chromium.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icons/png/firefox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions modules/common/security/apparmor/default.nix
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;
Copy link
Collaborator

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?

};
}
186 changes: 186 additions & 0 deletions modules/common/security/apparmor/profiles/chromium.nix
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 =
Copy link
Member

Choose a reason for hiding this comment

The 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 (apparmor-profiles).

And if we have improvements to the Chromium apparmor policy, should it be upstreamed or included as a patch to apparmor-profiles package?

''
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;
};
}
171 changes: 171 additions & 0 deletions modules/common/security/apparmor/profiles/firefox.nix
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>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just like Chromium, apparmor-profiles package also contains policy for firefox: https://gitlab.com/apparmor/apparmor/-/blob/master/profiles/apparmor/profiles/extras/firefox?ref_type=heads

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;
};
}
Loading