From 5f7a6d2a6fdd2852a4ab1a86de3578cac9ffb96a Mon Sep 17 00:00:00 2001 From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:06:03 -0800 Subject: [PATCH] feat: (almost) entirely remove suid (#606) --- .github/workflows/tests/justfile_tests.bats | 2 +- docs/POSTINSTALL-README.md | 5 +- files/justfiles/hardening.just | 2 +- files/justfiles/toggles.just | 60 ++++++++++----------- files/justfiles/utilities.just | 16 +++--- files/scripts/removesuid.sh | 39 +++++--------- files/scripts/unprotectsudo.sh | 6 +++ recipes/common/common-modules.yml | 1 + recipes/common/common-scripts.yml | 1 - recipes/common/desktop-packages.yml | 3 ++ recipes/common/desktop-scripts.yml | 2 +- recipes/common/final-modules.yml | 1 + recipes/common/server-modules.yml | 5 +- 13 files changed, 71 insertions(+), 72 deletions(-) create mode 100644 files/scripts/unprotectsudo.sh diff --git a/.github/workflows/tests/justfile_tests.bats b/.github/workflows/tests/justfile_tests.bats index 7ff184c..5e95c74 100644 --- a/.github/workflows/tests/justfile_tests.bats +++ b/.github/workflows/tests/justfile_tests.bats @@ -17,7 +17,7 @@ setup() { } @test "Ensure ujust is configured correctly for tests" { - run ujust logs-this-boot + run ujust bios [ "$status" -eq 0 ] } diff --git a/docs/POSTINSTALL-README.md b/docs/POSTINSTALL-README.md index fe146e7..f09a243 100644 --- a/docs/POSTINSTALL-README.md +++ b/docs/POSTINSTALL-README.md @@ -68,9 +68,8 @@ Setting a GRUB password helps protect the device from physical tampering and mit To set a GRUB password, use the following command. By default, the password will be required when modifying boot entries, but not when booting existing entries. -``` -sudo grub2-setpassword -``` +1. `run0` +2. `grub2-setpassword` GRUB will prompt for a username and password. The default username is root. diff --git a/files/justfiles/hardening.just b/files/justfiles/hardening.just index e68d67e..ca639d5 100644 --- a/files/justfiles/hardening.just +++ b/files/justfiles/hardening.just @@ -19,7 +19,7 @@ setup-usbguard: #!/usr/bin/bash echo "Notice: This will generate a policy based on your existing connected USB devices." ACTIVE_USERNAME=$(whoami) - pkexec sh -c ' + run0 sh -c ' mkdir -p /var/log/usbguard mkdir -p /etc/usbguard chmod 755 /etc/usbguard diff --git a/files/justfiles/toggles.just b/files/justfiles/toggles.just index 93a4fde..0b3a8ca 100644 --- a/files/justfiles/toggles.just +++ b/files/justfiles/toggles.just @@ -1,6 +1,6 @@ # Toggle the cups service on/off toggle-cups: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash if systemctl is-enabled --quiet cups; then firewall-cmd --permanent --remove-port=631/tcp firewall-cmd --permanent --remove-port=631/udp @@ -23,21 +23,21 @@ toggle-cups: # Toggle bluetooth kernel modules on/off (requires reboot) toggle-bluetooth-modules: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash BLUE_MOD_FILE="/etc/modprobe.d/99-bluetooth.conf" if test -e $BLUE_MOD_FILE; then - sudo rm -f $BLUE_MOD_FILE + rm -f $BLUE_MOD_FILE echo "Bluetooth kernel modules disabled. Reboot to take effect." else - sudo sh -c 'echo "install bluetooth /sbin/modprobe --ignore-install bluetooth" >> "$1"' _ "$BLUE_MOD_FILE" - sudo sh -c 'echo "install btusb /sbin/modprobe --ignore-install btusb" >> "$1"' _ "$BLUE_MOD_FILE" - sudo chmod 644 $BLUE_MOD_FILE + sh -c 'echo "install bluetooth /sbin/modprobe --ignore-install bluetooth" >> "$1"' _ "$BLUE_MOD_FILE" + sh -c 'echo "install btusb /sbin/modprobe --ignore-install btusb" >> "$1"' _ "$BLUE_MOD_FILE" + chmod 644 $BLUE_MOD_FILE echo "Bluetooth kernel modules enabled. Reboot to take effect." fi # Toggle GHNS (KDE Get New Stuff) toggle-ghns: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash KDE_GLOBALS_FILE="/etc/xdg/kdeglobals" if test -e $KDE_GLOBALS_FILE; then if grep -q "ghns=false" "$KDE_GLOBALS_FILE"; then @@ -55,24 +55,24 @@ toggle-ghns: # enable a kernel module that is disabled by modprobe.d (requires restart) override-enable-module mod_name: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash MOD_NAME="{{ mod_name }}" MOD_FILE="/etc/modprobe.d/99-$MOD_NAME.conf" if test -e $MOD_FILE; then echo "$MOD_NAME module is already enabled." else - sudo sh -c 'echo "install $1 /sbin/modprobe --ignore-install $1" >> "$2"' _ "$MOD_NAME" "$MOD_FILE" - sudo chmod 644 $MOD_FILE + sh -c 'echo "install $1 /sbin/modprobe --ignore-install $1" >> "$2"' _ "$MOD_NAME" "$MOD_FILE" + chmod 644 $MOD_FILE echo "Override created to enable $MOD_NAME module. Reboot to take effect." fi # reset the override by `just override-enable-module`, i.e. disable the module again (requires restart) override-reset-module mod_name: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash MOD_NAME="{{ mod_name }}" MOD_FILE="/etc/modprobe.d/99-$MOD_NAME.conf" if test -e $MOD_FILE; then - sudo rm -f $MOD_FILE + rm -f $MOD_FILE echo "The override for $MOD_NAME module has been reset. Reboot to take effect." else echo "No override found for $MOD_NAME module." @@ -80,7 +80,7 @@ override-reset-module mod_name: # Toggle anticheat support by changing ptrace scope (requires restart) toggle-anticheat-support: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash SYSCTL_HARDENING_FILE="/etc/sysctl.d/hardening.conf" if grep -q "kernel.yama.ptrace_scope = 3" "$SYSCTL_HARDENING_FILE"; then sed -i "s/kernel.yama.ptrace_scope = 3/kernel.yama.ptrace_scope = 1/" "$SYSCTL_HARDENING_FILE" @@ -94,20 +94,20 @@ toggle-anticheat-support: # Toggle Gnome JIT JavaScript for GJS and WebkitGTK (requires session restart) toggle-gnome-jit-js: - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash ENV_FILE="/etc/profile.d/gnome-disable-jit.sh" if test -e $ENV_FILE; then - sudo rm -f $ENV_FILE + rm -f $ENV_FILE echo "JIT JavaScript for Gnome and WebkitGTK has been enabled." else - sudo cp /usr$ENV_FILE $ENV_FILE - sudo chmod 644 $ENV_FILE + cp /usr$ENV_FILE $ENV_FILE + chmod 644 $ENV_FILE echo "JIT JavaScript for Gnome and WebkitGTK has been disabled." fi # Toggle support for using GNOME user extensions toggle-gnome-extensions: - #!/usr/bin/bash + #! /bin/run0 /bin/bash GSETTING="$(gsettings get org.gnome.shell allow-extension-installation)" if [[ "${GSETTING}" == "false" ]]; then gsettings set org.gnome.shell allow-extension-installation true @@ -119,7 +119,7 @@ toggle-gnome-extensions: # Toggle Xwayland support toggle-xwayland ACTION="prompt": - #!/usr/bin/pkexec /usr/bin/bash + #! /bin/run0 /bin/bash source /usr/lib/ujust/ujust.sh OPTION={{ ACTION }} if [ "$OPTION" == "prompt" ]; then @@ -137,31 +137,31 @@ toggle-xwayland ACTION="prompt": if [ "$OPTION" == "GNOME" ] || [ "${OPTION,,}" == "gnome" ]; then GNOME_XWAYLAND_FILE="/etc/systemd/user/org.gnome.Shell@wayland.service.d/override.conf" if test -e $GNOME_XWAYLAND_FILE; then - sudo rm -f $GNOME_XWAYLAND_FILE + rm -f $GNOME_XWAYLAND_FILE echo "Xwayland for GNOME has been enabled." else - sudo cp /usr$GNOME_XWAYLAND_FILE $GNOME_XWAYLAND_FILE - sudo chmod 644 $GNOME_XWAYLAND_FILE + cp /usr$GNOME_XWAYLAND_FILE $GNOME_XWAYLAND_FILE + chmod 644 $GNOME_XWAYLAND_FILE echo "Xwayland for GNOME has been disabled." fi elif [ "$OPTION" == "KDE Plasma" ] || [ "${OPTION,,}" == "plasma" ]; then PLASMA_XWAYLAND_FILE="/etc/systemd/user/plasma-kwin_wayland.service.d/override.conf" if test -e $PLASMA_XWAYLAND_FILE; then - sudo rm -f $PLASMA_XWAYLAND_FILE + rm -f $PLASMA_XWAYLAND_FILE echo "Xwayland for KDE Plasma has been enabled." else - sudo cp /usr$PLASMA_XWAYLAND_FILE $PLASMA_XWAYLAND_FILE - sudo chmod 644 $PLASMA_XWAYLAND_FILE + cp /usr$PLASMA_XWAYLAND_FILE $PLASMA_XWAYLAND_FILE + chmod 644 $PLASMA_XWAYLAND_FILE echo "Xwayland for KDE Plasma has been disabled." fi elif [ "$OPTION" == "Sway" ] || [ "${OPTION,,}" == "sway" ]; then SWAY_XWAYLAND_FILE="/etc/sway/config.d/99-noxwayland.conf" if test -e $SWAY_XWAYLAND_FILE; then - sudo rm -f $SWAY_XWAYLAND_FILE + rm -f $SWAY_XWAYLAND_FILE echo "Xwayland for Sway has been enabled." else - sudo cp /usr$SWAY_XWAYLAND_FILE $SWAY_XWAYLAND_FILE - sudo chmod 644 $SWAY_XWAYLAND_FILE + cp /usr$SWAY_XWAYLAND_FILE $SWAY_XWAYLAND_FILE + chmod 644 $SWAY_XWAYLAND_FILE echo "Xwayland for Sway has been disabled." fi fi @@ -179,7 +179,7 @@ toggle-bash-environment-lockdown: if lsattr "${BASH_ENV_FILES[0]}" 2>/dev/null | awk '{print $1}' | grep -q 'i'; then echo "Bash environment '(${BASH_ENV_FILES[@]})' is locked down. Unlocking it." for file in "${BASH_ENV_FILES[@]}"; do - pkexec chattr -i "$file" + run0 chattr -i "$file" done else echo "Bash environment '(${BASH_ENV_FILES[@]})' is unlocked. Locking it." @@ -215,7 +215,7 @@ toggle-bash-environment-lockdown: " > ~/.bash_profile for file in "${BASH_ENV_FILES[@]}"; do - pkexec chattr +i "$file" + run0 chattr +i "$file" done fi else diff --git a/files/justfiles/utilities.just b/files/justfiles/utilities.just index b3854d1..5d72674 100644 --- a/files/justfiles/utilities.just +++ b/files/justfiles/utilities.just @@ -25,26 +25,28 @@ bios: # Show all messages from this boot logs-this-boot: - sudo journalctl -b 0 + #! /bin/run0 /bin/bash + journalctl -b 0 # Show all messages from last boot logs-last-boot: - sudo journalctl -b -1 + #! /bin/run0 /bin/bash + journalctl -b -1 # Regenerate GRUB config, useful in dual-boot scenarios where a second operating system isn't listed regenerate-grub: - #!/usr/bin/bash + #! /bin/run0 /bin/bash if [ -d /sys/firmware/efi ]; then - sudo grub2-mkconfig -o /etc/grub2-efi.cfg + grub2-mkconfig -o /etc/grub2-efi.cfg else - sudo grub2-mkconfig -o /etc/grub2.cfg + grub2-mkconfig -o /etc/grub2.cfg fi # Enroll Nvidia driver & KMOD signing key for secure boot - Enter password "universalblue" if prompted enroll-secure-boot-key: - sudo mokutil --timeout -1 + run0 mokutil --timeout -1 echo 'The next line will prompt for a MOK password. Then, input "universalblue"' - sudo mokutil --import /etc/pki/akmods/certs/akmods-ublue.der + run0 mokutil --import /etc/pki/akmods/certs/akmods-ublue.der echo 'At next reboot, the mokutil UEFI menu UI will be displayed (*QWERTY* keyboard input and navigation).\nThen, select "Enroll MOK", and input "universalblue" as the password' # Toggle display of the user-motd in terminal diff --git a/files/scripts/removesuid.sh b/files/scripts/removesuid.sh index a865f00..e8efccd 100644 --- a/files/scripts/removesuid.sh +++ b/files/scripts/removesuid.sh @@ -6,36 +6,17 @@ set -oue pipefail # Reference: https://gist.github.com/ok-ryoko/1ff42a805d496cb1ca22e5cdf6ddefb0#usrbinchage whitelist=( - # Needed for flatpak on no-userns images - "/usr/bin/bwrap" - # Requires cap_setuid if the suid bit is removed - "/usr/bin/gpasswd" - # "In effect, when the SUID bit is unset on /usr/bin/mount, mount(8) will never drop permissions. If /usr/bin/mount were to have a" - # "nonempty permitted capability set and its effective capability bit were set, then mount(8) would never have its effective " - # "capability set cleared during execution, potentially allowing unprivileged users to perform actions they shouldn’t be able to perform" - # https://gist.github.com/ok-ryoko/1ff42a805d496cb1ca22e5cdf6ddefb0#can-we-replace-the-suid-bit-with-zero-or-more-file-capabilities-4 - "/usr/bin/mount" - # Required for nvidia images - "/usr/bin/nvidia-modprobe" - # https://gist.github.com/ok-ryoko/1ff42a805d496cb1ca22e5cdf6ddefb0#can-we-replace-the-suid-bit-with-zero-or-more-file-capabilities - "/usr/bin/passwd" - # https://gist.github.com/ok-ryoko/1ff42a805d496cb1ca22e5cdf6ddefb0#why-does-this-binary-need-to-be-suid-root-9 - "/usr/bin/pkexec" - # https://gist.github.com/ok-ryoko/1ff42a805d496cb1ca22e5cdf6ddefb0#can-we-replace-the-suid-bit-with-zero-or-more-file-capabilities-6 - "/usr/bin/su" - # https://gist.github.com/ok-ryoko/1ff42a805d496cb1ca22e5cdf6ddefb0#can-we-replace-the-suid-bit-with-zero-or-more-file-capabilities-6 - "/usr/bin/sudo" - # See /usr/bin/mount - "/usr/bin/umount" # https://gitlab.freedesktop.org/polkit/polkit/-/issues/168 "/usr/lib/polkit-1/polkit-agent-helper-1" - # https://github.com/secureblue/secureblue/issues/119 - "/usr/lib64/libhardened_malloc-light.so" - "/usr/lib64/libhardened_malloc-pkey.so" - "/usr/lib64/libhardened_malloc.so" + # Needed for flatpak on no-userns images + "/usr/bin/bwrap" # Required for chrome suid sandbox on no-userns images "/usr/lib64/chromium-browser/chrome-sandbox" # https://github.com/secureblue/secureblue/issues/119 + # Required for hardened_malloc to be used by suid-root processes + "/usr/lib64/libhardened_malloc-light.so" + "/usr/lib64/libhardened_malloc-pkey.so" + "/usr/lib64/libhardened_malloc.so" "/usr/lib64/glibc-hwcaps/x86-64/libhardened_malloc-light.so" "/usr/lib64/glibc-hwcaps/x86-64/libhardened_malloc-pkey.so" "/usr/lib64/glibc-hwcaps/x86-64/libhardened_malloc.so" @@ -48,8 +29,6 @@ whitelist=( "/usr/lib64/glibc-hwcaps/x86-64-v4/libhardened_malloc-light.so" "/usr/lib64/glibc-hwcaps/x86-64-v4/libhardened_malloc-pkey.so" "/usr/lib64/glibc-hwcaps/x86-64-v4/libhardened_malloc.so" - # Requires cap_setgid,cap_setuid if the SUID bit is removed - "/usr/sbin/grub2-set-bootflag" ) @@ -81,4 +60,10 @@ find /usr -type f -perm /2000 | fi done + +rm -f /usr/bin/chsh +rm -f /usr/bin/pkexec +rm -f /usr/bin/sudo +rm -f /usr/bin/su + systemctl enable setcapsforunsuidbinaries.service diff --git a/files/scripts/unprotectsudo.sh b/files/scripts/unprotectsudo.sh new file mode 100644 index 0000000..90e7cbb --- /dev/null +++ b/files/scripts/unprotectsudo.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# Tell build process to exit if there are any errors. +set -oue pipefail + +rm -f /etc/dnf/protected.d/sudo.conf \ No newline at end of file diff --git a/recipes/common/common-modules.yml b/recipes/common/common-modules.yml index 8b306b5..4463802 100644 --- a/recipes/common/common-modules.yml +++ b/recipes/common/common-modules.yml @@ -5,6 +5,7 @@ modules: - type: script scripts: - installrpmfusion.sh + - unprotectsudo.sh - from-file: common/common-packages.yml - type: files files: diff --git a/recipes/common/common-scripts.yml b/recipes/common/common-scripts.yml index c4ad3e9..ddede0c 100644 --- a/recipes/common/common-scripts.yml +++ b/recipes/common/common-scripts.yml @@ -5,7 +5,6 @@ scripts: - disablesealertpopups.sh - httpsmirrors.sh - createmissingdirectories.sh - - removesuid.sh - disablegeoclue.sh - enablesecurebluefirstrun.sh - createjustcompletions.sh diff --git a/recipes/common/desktop-packages.yml b/recipes/common/desktop-packages.yml index 19cfba3..8b3f492 100644 --- a/recipes/common/desktop-packages.yml +++ b/recipes/common/desktop-packages.yml @@ -34,6 +34,9 @@ remove: - open-vm-tools-desktop - virtualbox-guest-additions - passim + - sudo + - sudo-python-plugin + diff --git a/recipes/common/desktop-scripts.yml b/recipes/common/desktop-scripts.yml index 75dac12..f4b2d9d 100644 --- a/recipes/common/desktop-scripts.yml +++ b/recipes/common/desktop-scripts.yml @@ -7,4 +7,4 @@ scripts: - disablealsastate.sh - disablemodemmanager.sh - disablenfsdaemons.sh - - disablesssd.sh \ No newline at end of file + - disablesssd.sh diff --git a/recipes/common/final-modules.yml b/recipes/common/final-modules.yml index 36918fb..407d6b9 100644 --- a/recipes/common/final-modules.yml +++ b/recipes/common/final-modules.yml @@ -2,4 +2,5 @@ modules: - type: script scripts: - removeunusedrepos.sh + - removesuid.sh - regenerateinitramfs.sh \ No newline at end of file diff --git a/recipes/common/server-modules.yml b/recipes/common/server-modules.yml index d0d81c2..1556b32 100644 --- a/recipes/common/server-modules.yml +++ b/recipes/common/server-modules.yml @@ -16,6 +16,8 @@ modules: - usbguard - firewalld - policycoreutils-python-utils + remove: + - sudo - type: files files: @@ -27,4 +29,5 @@ modules: - type: script scripts: - excludepcsc.sh - - setserverdefaultzone.sh \ No newline at end of file + - setserverdefaultzone.sh + - removesuid.sh