{{Header}}
{{Title
|title=Remount Secure
}}
{{#seo:
|title=Remount Secure
|description=Secure Mount Options for better Security Hardening / /etc/fstab modifications by a Linux distribution
|image=Mountoptions.jpg
}}
{{intro|
Secure Mount Options for better Security Hardening / /etc/fstab modifications by a Linux distribution
Considering the most maintainable, stable solution. See also [[Dev/maintainability]] and [[Stable Version User Experience]].
See also:
* [[Security-misc#Remount_Secure|Remount Secure]]
* [[noexec|Enhanced Security via Mount Options and Compiler Restrictions]]
}}
[[File:Mountoptions.jpg|thumb]]
= Environments =
* servers
* desktops
* initrdless
* initramfs-tools
* dracut
* mkosi-initrd
* perhaps other init systems
* OpenVZ (not using initrd?)
* Qubes
* systemd-nspawn (not using initrd)
= Mount Points =
* A) API file systems
* B) real partitions
* C) directories
= Build Tools =
There are at four two major build tools.
These tools are responsible for creating /etc/fstab
. That is why changing /etc/fstab
by default in {{project_name_short}} as a Linux distribution is difficult.
* '''VM images:''' {{project_name_short}} VM images are built using derivative-maker which uses grml-debootstrap but might use mkosi in the future.
* '''ISO installer:''' When installing {{project_name_short}} from [[ISO]] using Calamares creates /etc/fstab
.
* '''Qubes:''' [[Qubes|{{project_name_short}} for Qubes]] (non-existing Template at time of writing) is created by Qubes builder.
** https://github.com/QubesOS/qubes-core-agent-linux/blob/main/filesystem/fstab
* '''Others:''' [[chroot]] and [[Distribution Morphing]].
= Approaches =
== initrd based mount options hardening ==
* initramfs-tools: /usr/share/initramfs-tools/init
* [https://forums.whonix.org/t/replacing-initramfs-tools-with-dracut/4487 dracut: used by Kicksecure by default at time of writing.]
** There is an implementation in security-misc currently disabled by default.
*** /usr/lib/dracut/modules.d-disabled
*** Was functional.
*** Was said to slow down the boot process.
*** Maybe the slowness issues could be worked on by debugging the script. Tracing, debug output execution times throughout its run. Perhaps parallelization, i.e. running the mount commands into the background.
Advantages:
* happens at early boot before switch-root
into the root file system
Disadvantages:
* initrd specific (initramfs-tools vs dracut vs maybe mkosi-initrd or perhaps other init systems)
* Does not work with initrdless systems, such as:
** Custom kernel with all modules already compiled-in.
** Boot / virtualization methods not involving an initrd such as systemd-nspawn, and perhaps docker, OpenVZ.
* configurability: Not as expected by sysadmins using /etc/fstab. Needs different way to customize.
* shell scripting (in case of the dracut based implementation by security-misc)
== Systemd drop-in mount options for units that already exist ==
For example, /etc/systemd/system/home.mount.d/hardening.conf
:
[Mount] Options=nodev,nosuidThere is a reason we create a configuration file under
unit.mount.d
and do not do our hardening directly within the unit file unit.mount
. There also is a very valid reason we choose to do this under /etc
instead of doing everything under /usr/lib
and respecting the conventions.
Firstly, we do not create a unit file directly. The goal of having drop in config files for mount option hardening is to be universal. If we create a mount unit, we would make several assumptions. We do not know if the user really has a dedicated partition for our target unit, and even if they do, we do not which one it is. We also do not want to make the assumption that it does not existing and bind it directly. Adding this config file under this path provides many benefits. For example, if there is no dedicated partition for /home
on disk, our config file /etc/systemd/system/home.mount.d/hardening.conf
has literally no effect. It is a unit configuration extension that does not exist, so it will have no effect. The effect will be there if there is a home.mount
unit. Then our hardneing takes place.
Advantages:
* Systemd drop-in files.
* No further system specific adjustments and/or configurations required.
* No shell scripting requried.
* Hardening what already exists as a mount unit.
Disadvantages:
* Can only be used for mount points declared in /etc/fstab.
* Will not work for API file systems, like /dev/shm, /run, /proc, /sys, etc.
* minor: systemd dependent
* minor: drop in files need to be placed in /etc and cannot be placed in /lib, not too conventional for a package
* configurability: Not as expected by sysadmins using /etc/fstab. Needs different way to customize.
See also:
* https://github.com/Kicksecure/security-misc/pull/165
* https://github.com/Kicksecure/security-misc/pull/195#issuecomment-1938716410
== Systemd drop-in mount units for units that normally do not exist ==
This one is a rather tricky one. For example, we might place under the path /usr/lib/systemd/system/var.mount
the following file:
[Unit] Description=Bind Mount /var with no dedicated partition [Mount] What=/var Where=/var Options=defaults,nodev,nosuid,bind [Install] WantedBy=sysinit.targetNow the tricky part is, we want unit to come into effect when there is actually no partition for
/var
on disk. Should this be the case, this a proper mount unit will be created on start up by the system using the /etc/fstab
file. Having this unit under this specific path provides us with this exact functionality. When there is a line in fstab for a partition, a proper mount unit gets created dynamically that overrides our unit under this path, so it effectively becomes non existent. But if there is no such unit to override us, we take effect and assume that since there is no mount unit to override us, there is no partition on disk for /var
, so we can bind it to itself.
Binding partitions to itself is also tricky for other reasons. This is not a real mount. Binding one directory to itself allows us a workaround to make use of the hardened mount options for that said directory. But if we want to bind several path, that may be nested in a way, the order of binding would then be of the essence. Having bound /var
to itself before binding /var/tmp
will result in a double bind situation that allows several points of acces to /var/tmp
. A process that might opened this directory before the second bind might retain access under the options normally meant for /var
. Not to mention the extra complexity introduced during boot and shut down with nested bind mounts. So when writing such units, attention must be paid to the order.
Advantages:
* Systemd drop-in files.
* No further system specific adjustments and/or configurations required.
* No shell scripting requried.
Disadvantages:
* Can be used only for directories with no dedicated partitions on disk.
* Will not work for API file systems, like /dev/shm, /run, /proc, /sys, etc.
* Whether or not it is conventionally acceptable for a package to directly create mount units is unclear.
* Nested binds need to be configured properly not to break or cause breakage.
* There 'may' be a time window to access these directories before the bind mount, untested.
== systemd kernel parameter based mount options hardening ==
/etc/default/grub.d/40_secure-mount.cfg
as suggested in https://github.com/Kicksecure/security-misc/pull/195 thanks to monsieuremre!
# tmp and api file systems GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX systemd.mount-extra=tmpfs:/tmp:[:tmpfs[:defaults,nodev,nosuid,noexec]]" GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX systemd.mount-extra=udev:/dev:[:devtmpfs[:defaults,nosuid,noexec]]" GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX systemd.mount-extra=tmpfs:/dev/shm:[:tmpfs[:defaults,nodev,nosuid,noexec]]" GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX systemd.mount-extra=tmpfs:/run:[:tmpfs[:defaults,nodev,nosuid,noexec]]"
systemd.mount-extra=tmpfs:/dev/shm[:tmpfs[:defaults,noexec,nosuid,nodev]]Each field is handled as the corresponding fstab field. This option can be specified multiple times, like the following:
systemd.mount-extra=udev:/dev:devtmpfs:defaults,nosuid,noexec systemd.mount-extra=tmpfs:/dev/shm:tmpfs:defaults,nosuid,noexec,nodev systemd.mount-extra=tmpfs:/tmp:tmpfs:defaults,nosuid,noexec,nodevWe could also use the system credential fstab.extra to declare a path to our alternative fstab file. Lines in this file would parsed in addition to the usual fstab. * https://github.com/Kicksecure/security-misc/pull/165#issuecomment-1817934219 * https://github.com/Kicksecure/security-misc/issues/157#issuecomment-1869080721 * https://www.freedesktop.org/software/systemd/man/latest/systemd-fstab-generator.html Adventages: * Can be used for all mount points. * No package owns or modifies the fstab file, reducing implementation and maintenance complexity. * Ideal and only way to modify the mount options for API file systems without manually remounting them. Disadvantages: * (acceptable) increase length of already (for other reasons) lengthy kernel command line. * (minor) Newer kernel or systemd version (254) required, while stable Debian uses systemd version 252. (Will fix itself after next Debian stable is out and Kicksecure has been rebased) * configurability: Not as expected by sysadmins using /etc/fstab. Needs different way to customize. == Autogenerated alternative /etc/fstab ==
GRUB_CMDLINE_LINUX_DEFAULT="LIBMOUNT_FSTAB=/etc/something SYSTEMD_SYSROOT_FSTAB=/etc/something SYSTEMD_FSTAB=/etc/something"https://github.com/Kicksecure/security-misc/pull/165#issuecomment-1827922062 Advantages: * Not touching /etc/fstab. * Not using the old fstab directly. * We never call mount. * We never remount. * Systemd handles everything as usual. * Everything mounts securely in the first place. * We never manually check anything. * All we do is generate a custom fstab from the original one, without modifying or owning it. * (minor) Short kernel command line expansion. * Can be reverted in grub boot menu by editing kernel command line in case it is broken. * configurability: Not as expected by sysadmins using /etc/fstab. Needs different way to customize. Disadvantages: * Parsing /etc/fstab. Shell scripting required to create alternative /etc/fstab. awk, sed, str_replace, bash while true read loop? That would be the difficult, fragile, messy part. * (Unlikely but untested) If the user edits /etc/fstab and uses mount, it might reset the hardened mount options? (Most probably not) * Also be confusing for users why mount options are hardened in the first place because these aren't done in the place where everyone would except these. That is in /etc/fstab. Maybe could be mitigated by documenting this fact in original /etc/fstab. Which would be modifying the fstab, which is the very thing we try avoiding. * configurability: how to disable /tmp noexec? (Parser can be configured to respect simple config files) * Might be confusing for the unaware user. == systemd unit file based mount options hardening == * A "normal" systemd unit file (Type=oneshot) that runs early during the boot process and remounts. * https://github.com/Kicksecure/security-misc/blob/master/usr/bin/remount-secure * https://github.com/Kicksecure/security-misc/blob/master/usr/lib/systemd/system/remount-secure.service * https://github.com/Kicksecure/security-misc/blob/master/usr/lib/systemd/system/sysinit-post.target Advantages: * No initrd modifications. Disadvantages: * Shell scripting. * Happens after initrd. * configurability: Not as expected by sysadmins using /etc/fstab. Needs different way to customize. * ...? == /etc/fstab file based mount options hardening == * Shipping a hardened by default /etc/fstab in new Kicksecure builds. * Upgrading existing Kicksecure builds is possible too, can be considered later. * https://github.com/Kicksecure/security-misc/blob/master/usr/share/doc/security-misc/fstab-vm * https://github.com/Kicksecure/security-misc/issues/157 Advantages: * No initrd modifications. * No shell scripting. * configurability: As expected by sysadmins. /etc/fstab could be used normally. No special user documentation required. * Should be the most robust, stable place as this is traditionally the place to configure this. Disadvantages: * Tailored for Kicksecure such as for VM builds or installations from [[ISO]] using Calamares installer. * Not a generic solution for security-misc. * Needs to be contributed separately to Qubes: https://github.com/QubesOS/qubes-issues/issues/5329 Plan: * If and only if needed: Combine this with [[#systemd kernel parameter based mount options hardening]] for the API file systems. = Issues = * [https://github.com/Kicksecure/security-misc/issues/198 pam-tmpdir-helper breaks certain initramfs-update actions on systems with noexec on the /tmp mount] = Miscellaneous = == /run/user/1000 bypass == Quote madaidan:
/run/user/1000 bypasses /run's `noexec` as it is its own mount point. We might want to look into restricting that too.== Resources == * https://github.com/{{project_name_short}}/security-misc/pull/68 * https://github.com/{{project_name_short}}/security-misc/pull/69 * [https://phabricator.whonix.org/T941 lock down interpreters / compilers (interpreter lock) (compiler lock)] * https://seifried.org/lasg/installation/ = Implementations by Other Operating Systems = == CLIP OS == https://github.com/clipos/products_clipos/blob/master/core/configure.d/40_fstab.sh == RedHat == Note: Extremely outdated and no more valid or relevant, but still is a good point of reference to understand the underlying concept. Quote https://people.redhat.com/sgrubb/files/hardening-rhel5.pdf
Partitioning Allow minimal privileges via mount options * Noexec on everything possible * Nodev everywhere except / and chroot partitions * Nosetuid everywhere except / * Consider making /var/tmp link to /tmp, or maybe mount –bind option A reasonable /etc/fstab:== CentOS == Quote https://wiki.centos.org/HowTos/OS_Protection#Modifying_fstabLABEL=/ / ext3 defaults 1 1 LABEL=/tmp /tmp ext3 defaults,nosuid,noexec,nodev 1 2 LABEL=/var/log/audit /var/log/audit ext3 defaults,nosuid,noexec,nodev 1 2 LABEL=/home /home ext3 defaults,nosuid,nodev 1 2 LABEL=/var /var ext3 defaults,nosuid 1 2 LABEL=/boot /boot ext3 defaults,nosuid,noexec,nodev 1 2 /tmp /var/tmp ext3 defaults,bind,nosuid,noexec,nodev 1 2 tmpfs /dev/shm tmpfs defaults,nosuid,noexec,nodev 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 LABEL=SWAP-sda6 swap swap defaults 0 0
Modifying fstab Once you have your partitions broken out and sized accordingly, you can begin to restrict the various mount points as much as possible. You should add nodev, noexec, and nosuid wherever possible. An example of a decently restricted /etc/fstab file is below:== Arch Linux ==/dev/VG_OS/lv_root / ext3 defaults 1 1 /dev/VG_OS/lv_tmp /tmp ext3 defaults,nosuid,noexec,nodev 1 2 /dev/VG_OS/lv_vartmp /var/tmp ext3 defaults,nosuid,noexec,nodev 1 2 /dev/data_vol/lv_home /home ext3 defaults,nosuid,nodev 1 2 /dev/VG_OS/lv_var /var ext3 defaults,nosuid 1 2 /dev/data_vol/lv_web /var/www ext3 defaults,nosuid,nodev 1 2 /dev/sda1 /boot ext3 defaults,nosuid,noexec,nodev 1 2 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 /dev/_VG_OS/lv_swap swap swap defaults 0 0Obviously you'll need to modify this example to suit your own system. LVM, volume names, labels etc are all subject to change. Please don't copy this example verbatim and expect it to work for you. The webserver mount can also be set noexec, however this will impact cgi based applications, as well as server side includes which rely on the execute bit hack. If you're not using cgi applications, I would recommend at least testing noexec and using it if there are no negative side-effects.
Mount options Following the principle of least privilege, file systems should be mounted with the most restrictive mount options possible (without losing functionality). Relevant mount options are: * nodev: Do not interpret character or block special devices on the file system. * nosuid: Do not allow set-user-identifier or set-group-identifier bits to take effect. * noexec: Do not allow direct execution of any binaries on the mounted file system. ** Setting noexec on /home disallows executable scripts and breaks Wine* and Steam. ** Some packages (building nvidia-dkms for example) may require exec on /var. *Wine does not need the exec flag for opening Windows executables. It is only needed when Wine itself is installed in /home. File systems used for data should always be mounted with nodev, nosuid and noexec. Potential file system mounts to consider: * /var * /home * /dev/shm * /tmp * /boot= Forum Discussion = https://forums.whonix.org/t/re-mount-home-and-other-with-noexec-and-nosuid-among-other-useful-mount-options-for-better-security/7707 = Attribution = {{sdebian |link=https://www.debian.org/doc/manuals/securing-debian-manual/ch04s10.en.html |text=Mounting partitions the right way }} = Footnotes = {{reflist|close=1}} {{Footer}} [[Category:Design]]