Reorganization and formatting adjustments to Desktop Linux Hardening (#93)

This commit is contained in:
WfKe9vLwSvv7rN 2022-11-26 03:36:42 -07:00 committed by GitHub
parent 1be4d6dbbb
commit 8e1df9bf79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 212 additions and 164 deletions

View File

@ -5,13 +5,13 @@ tags: ['Operating Systems', 'Linux', 'Privacy', 'Security']
author: Tommy
---
Linux is [not](/posts/os/linux-insecurities) a secure operating system. However, there are steps you can take to harden it, reduce its attack surface and improve its privacy.
Linux is [not a secure desktop operating system](/posts/linux/linux-insecurities/). However, there are steps you can take to harden it, reduce its attack surface, and improve its privacy.
**Before We Start**...
**Before we start...**
This guide is largely based on [Madaidan's Linux hardening guide](https://madaidans-insecurities.github.io/guides/linux-hardening.html); however, it does take into account usability and ease of maintenance of each recommendation. The goal is to produce a guide that intermediate to advanced Linux users can reasonably follow to set up and maintain the security configurations. It will also **not** try to be distribution agnostic, and there will be many distribution specific recommendations.
This guide is largely based on [Madaidan's Linux Hardening Guide](https://madaidans-insecurities.github.io/guides/linux-hardening.html), however this guide strives to consider the usability and ease of maintenance of each recommendation. The goal is to produce a guide that intermediate to advanced Linux users can reasonably follow to set up and maintain the security configurations. It does **not** endeavor to be distribution agnostic; distribution‑specific recommendations are to be expected.
Some of the sections will include mentions of unofficial builds of packages like `linux-hardened`, `lkrg-akmod`, `hardend-malloc`, and so on. These are not endorsements. They are merely there to show you that you have an option to easily obtain and update these packages. Using unofficial builds of packages means adding more parties to trust, and you have to evaluate whether it is worth doing so for the potential privacy or security benefits or not.
Some of the sections will include mentions of unofficial builds of packages like linux-hardened, lkrg-akmod, hardened_malloc, and so on. These are not endorsements --- they are merely to show that you have options to easily obtain and update these packages. Using unofficial builds of packages means adding more parties to trust, and you have to evaluate whether it is worth doing so for the potential privacy/security benefits or not.
![Fedora Tux](/images/fedora-tux.png)
@ -19,7 +19,7 @@ Some of the sections will include mentions of unofficial builds of packages like
### Drive Encryption
Most Linux distributions have an option within its installer for enabling [LUKS](../encryption.md#linux-unified-key-setup) full disk encryption. If this option isnt set at installation time, you will have to backup your data and re-install, as encryption is applied after [disk partitioning](https://en.wikipedia.org/wiki/Disk_partitioning), but before [file systems](https://en.wikipedia.org/wiki/File_system) are formatted.
Most Linux distributions have an option within its installer for enabling LUKS full disk encryption. If this option isnt set at installation time, you will have to backup your data and re-install, as encryption is applied after [disk partitioning](https://en.wikipedia.org/wiki/Disk_partitioning) but before [filesystem](https://en.wikipedia.org/wiki/File_system) creation.
### Encrypted Swap
@ -33,7 +33,7 @@ Depending on your distribution, encrypted swap may be automatically set up if yo
Most desktop Linux distributions including Fedora, openSUSE, Ubuntu, and so on come with [NetworkManager](https://en.wikipedia.org/wiki/NetworkManager) by default to configure Ethernet and Wi-Fi settings.
WfKe9vLwSvv7rN has detailed guide on [trackability reduction with NetworkManager](/posts/os/networkmanager-trackability-reduction/) and I highly recommend that you check it out.
WfKe9vLwSvv7rN has detailed guide on [trackability reduction with NetworkManager](/posts/linux/networkmanager-trackability-reduction/) which I highly recommend you check out.
In short, if you use NetworkManager, add the following to your `/etc/NetworkManager/conf.d/00-macrandomize.conf`:
```
@ -70,153 +70,161 @@ Note that randomizing Wi-Fi MAC addresses depends on support from the Wi-Fi card
There are other system identifiers which you may wish to be careful about. You should give this some thought to see if it applies to your [threat model](/posts/knowledge/threat-modeling/):
- **Usernames:** Similarly, your username is used in a variety of ways across your system. Consider using generic terms like "user" rather than your actual name.
- **Machine ID:**: During installation a unique machine ID is generated and stored on your device. Consider [setting it to a generic ID](https://madaidans-insecurities.github.io/guides/linux-hardening.html#machine-id).
Username
: Your username is used in a variety of ways across your system. Consider using generic terms like "user" rather than your actual name.
### System Counting
Machine ID
: During installation a unique machine ID is generated and stored on your device. Consider [setting it to a generic ID](https://madaidans-insecurities.github.io/guides/linux-hardening.html#machine-id).
#### System Counting
Many Linux distributions sends some telemetry data by default to count how many systems are using their software. Consider disabling this depending on your threat model.
The Fedora Project does this by [counting](https://fedoraproject.org/wiki/Changes/DNF_Better_Counting) how many unique systems access its mirrors by using a [`countme`](https://fedoraproject.org/wiki/Changes/DNF_Better_Counting#Detailed_Description) variable instead of a unique ID.
The Fedora Project offers a ["countme" variable](https://dnf.readthedocs.io/en/latest/conf_ref.html#countme-label) to much more accurately [count unique systems accessing its mirrors](https://fedoraproject.org/wiki/Changes/DNF_Better_Counting) without involving unique IDs. While currently disabled by default, you could add `countme=false` to `/etc/dnf/dnf.conf` in case the default changes in the future. On rpm‑ostree systems such as Fedora Silverblue and Kinoite, the `countme` option can be disabled by [masking the rpm-ostree-countme timer](https://coreos.github.io/rpm-ostree/countme/).
This [option](https://dnf.readthedocs.io/en/latest/conf_ref.html#options-for-both-main-and-repo) is currently off by default. However, you could add `countme=false` to `/etc/dnf/dnf.conf` just in case it is enabled in the future. On systems that use rpm-ostree such as Fedora Silverblue or Kinoite, the `countme` option can be disabled by masking the [rpm-ostree-countme](https://fedoramagazine.org/getting-better-at-counting-rpm-ostree-based-systems/) timer.
[openSUSE uses a unique ID to count systems](https://en.opensuse.org/openSUSE:Statistics), which can be disabled by deleting the `/var/lib/zypp/AnonymousUniqueId` file.
openSUSE uses a [unique ID](https://en.opensuse.org/openSUSE:Statistics) to count systems, which can be disabled by deleting the `/var/lib/zypp/AnonymousUniqueId` file.
[Zorin OS also uses a unique ID to count systems.](https://zorin.com/legal/privacy/#census) You can opt‑out by running `sudo apt purge zorin-os-census` and optionally holding the package with `sudo apt-mark hold zorin-os-census` to avoid accidental reinstallation.
Zorin OS uses the `zorin-os-cencus` package, which also uses a [unique ID](https://zorin.com/legal/privacy/) to count systems. You can opt out of this by doing `sudo apt purge zorin-os-census`, and optionally hold it with `sudo apt-mark hold zorin-os-census` to avoid accidentally installing it in the future.
[snapd (Snap) assigns a unique ID to your installation and uses it for telemetry.](https://snapcraft.io/docs/snap-store-metrics) While this is generally not a problem, if your threat model calls for anonymity, you should avoid using Snap packages and uninstall snapd. Accidental reinstallation on Ubuntu can be prevented with `sudo apt-mark hold snapd`.
[Snapd](https://github.com/snapcore/snapd) assigns a [unique ID](https://snapcraft.io/docs/snap-store-metrics) to your snapd installation and use it for telemetry. While this is generally not a problem, if your threat model calls for anonymity, you should not be using snap packages, and you should remove snapd from your Ubuntu installation. Like with Zorin Census, on Debian based distributions, and especially Ubuntu, consider holding `snapd` with `sudo apt-mark hold snapd`.
Of course, this is a non-exhaustive list of how different Linux distributions do this. If you are aware of any other tracking mechanisms that different distributions use, feel free to make a [pull request](https://github.com/PrivSec-dev/privsec.dev/blob/main/content/posts/linux/Linux-Desktop-Hardening.md) or [discussion post](https://github.com/PrivSec-dev/privsec.dev/discussions) detailing them!
_Of course, this is a non‑exhaustive list of telemetry on different Linux distributions. If you are aware of other tracking mechanisms used by these or other distributions, feel free to make a [pull request](https://github.com/PrivSec-dev/privsec.dev/blob/main/content/posts/linux/Linux-Desktop-Hardening.md) or [discussion post](https://github.com/PrivSec-dev/privsec.dev/discussions) detailing them!_
### Keystroke Anonymization
You could be [fingerprinted based on soft biometric traits](https://www.whonix.org/wiki/Keystroke_Deanonymization) when you use the keyboard. The [Kloak](https://github.com/vmonaco/kloak) package could help you mitigate this threat. It is available as a .deb package from [Kicksecure's repository](https://www.kicksecure.com/wiki/Packages_for_Debian_Hosts) and an [AUR package](https://aur.archlinux.org/packages/kloak-git).
With that being said, if your threat model calls for using something like Kloak, you are probably better off just using Whonix.
## Application Confinement
Some sandboxing solutions for desktop Linux distributions do exist; however, they are not as strict as those found in macOS or ChromeOS. Applications installed from the package manager (`dnf`, `apt`, etc.) typically have **no** sandboxing or confinement whatsoever. Below are a few projects that aim to solve this problem:
Some sandboxing solutions for desktop Linux distributions do exist; however, they are not as strict as those found in macOS or ChromeOS. Software installed with distro package managers (DNF, APT, etc.) typically have **no** sandboxing or confinement whatsoever. Several projects which aim to tackle this problem are discussed here.
### Flatpak
{{< youtube id="GkgPIJp8_30">}}
[Flatpak](https://flatpak.org) aims to be a universal package manager for Linux. One of its main goals is to provide a universal package format which can be used in most Linux distributions. It provides some [permission control](https://docs.flatpak.org/en/latest/sandbox-permissions.html). With that being said, Flatpak sandboxing is [quite weak](https://madaidans-insecurities.github.io/linux.html#flatpak).
[Flatpak](https://flatpak.org) aims to be a distribution-agnostic package manager for Linux. One of its main goals is to provide a universal package format which can be used in most Linux distributions. It provides some [permission control](https://docs.flatpak.org/en/latest/sandbox-permissions.html). With that being said, [Flatpak sandboxing is quite weak](https://madaidans-insecurities.github.io/linux.html#flatpak).
You can restrict applications further by issuing [Flatpak overrides](https://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-override). This can be done with the command-line or by using [Flatseal](https://flathub.org/apps/details/com.github.tchx84.Flatseal). Some sample overrides are provided by [me](https://github.com/tommytran732/Flatpak-Overrides) and [rusty-snake](https://github.com/rusty-snake/kyst/tree/main/flatpak). Note that this only helps with the lax high level default permissions, but cannot solve the low level issues like `/proc` and `/sys` access, or an insufficient seccomp blacklist.
You can restrict applications further by setting [Flatpak overrides](https://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-override). This can be done with the command&nbsp;line or by using [Flatseal](https://github.com/tchx84/Flatseal). Some sample overrides are provided by [me](https://github.com/tommytran732/Flatpak-Overrides) and [rusty-snake](https://github.com/rusty-snake/kyst/tree/main/flatpak). Note that this only helps with lax high&#8209;level default permissions and cannot solve the low&#8209;level issues like `/proc` and `/sys` access or an insufficient seccomp blacklist.
Some sensitive permissions you should pay attention to:
Some sensitive permissions of note:
- the Network (`--share=network`) socket (internet access)
- the PulseAudio socket (`--socket=pulseaudio`) for audio and sound
- `--device=all` access to all devices including the camera
- `--talk-name=org.freedesktop.secrets` dbus (access to secrets stored on your keychain) for applications which do not need it
- `--share=network`: network and internet access
- `--socket=pulseaudio`: the PulseAudio socket, grants access to all audio devices (including inputs)
- `--device=all`: access to all devices (including webcams)
- `--talk-name=org.freedesktop.secrets`: D&#8209;Bus access to secrets stored on your keychain
If an application works natively with Wayland (*not* running through the [XWayland](https://wayland.freedesktop.org/xserver.html) compatibility layer), consider revoking its access to the X11 (`--socket=x11`) and [inter-process communications (IPC)](https://en.wikipedia.org/wiki/Unix_domain_socket) socket (`--share=ipc`) as well.
If an application works natively with Wayland (*not* running through the [XWayland](https://wayland.freedesktop.org/xserver.html) compatibility layer), consider revoking its access to X11 (`--nosocket=x11`) and the [inter&#8209;process communications (IPC)](https://en.wikipedia.org/wiki/Unix_domain_socket) socket (`--unshare=ipc`) as well.
Many Flatpak apps come with broad filesystem permissions such as `--filesystem=home` and `--filesystem=host`. Some applications implement the [Portal API](https://docs.flatpak.org/en/latest/portal-api-reference.html), which allows a file manager to pass files to the Flatpak application (e.g. VLC) without specific filesystem access privileges. Despite this, many of them, including ones like VLC [still use](https://github.com/flathub/org.videolan.VLC/blob/master/org.videolan.VLC.json) `--filesystem=host`.
Many Flatpak apps ship with broad filesystem permissions such as `--filesystem=home` and `--filesystem=host`. Some applications implement the [Portal API](https://docs.flatpak.org/en/latest/portal-api-reference.html), which allows a file manager to pass files to the Flatpak application (e.g. VLC) without specific filesystem access privileges. Despite this, many of them [still declare `--filesystem=host`](https://github.com/flathub/org.videolan.VLC/blob/master/org.videolan.VLC.json).
My strategy to deal with this is to revoke all filesystem access first, then test if an application works without it. If it does, it means the app is already using Portals and I don't need to do anything else. If it doesn't, then I start granting permission to specific directories.
My strategy to deal with this is to revoke all filesystem access first, then test if an application works without it. If it does, it means the app is already using portals and no further action is needed. If it doesn't, then I start granting permission to specific directories.
As odd as this may sound, **you should not do unattended updates with your Flatpak packages**. The problem with Flatpak is that it grants install-time permissions when you update your applications, and you will not be notified of the permission change if you or app store simply executes `flatpak update -y`. Using automatic update with `gnome-software` is fine, as it will not update packages with permission changes, and you have to manually open it's update tab to apply the update.
As odd as this may sound, **you should not enable (blind) unattended updates of Flatpak packages**. If you or a Flatpak frontend (app store) simply executes `flatpak update -y`, Flatpaks will be automatically granted any new permissions declared upstream without notifying you. Using automatic update with GNOME Software is fine, as it does not automatically update Flatpaks with permission changes and notifies the user instead.
### Snap
Snap is another universal package manager with some sandboxing support. It is developed by Canonical and heavily pushed on Ubuntu.
Snap is another distribution-agnostic package manager with some sandboxing support. It is developed by Canonical and heavily promoted in Ubuntu.
Snap packages come in [two variants](https://snapcraft.io/docs/snap-confinement): classic snap with no confinement and strict snap with confinement on systems with AppArmor and Cgroupsv1. If a snap package is classic snap, you are better off using a version provided by your distribution's repository instead, if one is available. If your system does not have AppArmor, then you are better off not using snap at all. Most modern systems outside of Ubuntu and its derivatives only use Cgroupsv2 by default, so you have to set `systemd.unified_cgroup_hierarchy=0` in your kernel parameters to get Cgroupsv1 working.
Snap packages come in [two variants](https://snapcraft.io/docs/snap-confinement): classic, with no confinement, and strictly confined, where AppArmor and cgroups&nbsp;v1 are used to facilitate sandboxing. If a snap uses classic confinement ("classic snap"), you are better off installing an equivalent package from your distribution's repository if possible. If your system does not have AppArmor, then you should avoid Snap entirely. Additionally, most modern systems outside of Ubuntu and its derivatives use cgroups&nbsp;v2 by default, so you have to set `systemd.unified_cgroup_hierarchy=0` in your kernel parameters to get cgroups&nbsp;v1 working.
Snap permissions can be managed via the Snap Store or Ubuntu's custom patched GNOME Control Center.
One caveat with Snap packages is that you only have control over the interfaces declared in their manifests. For example, snap has separate interfaces for `audio-playback` and `audio-record`; however, some packages will only declare the legacy `pulseaudio` interface which grants them permission to both play and record audio. Likewise, some applications may work perfectly fine with Wayland, but the package maintainer may only declare the X11 interface in their manifest. For these cases, you need to reach out to the maintainer of the Snap package to update the manifest accordingly.
One caveat with Snap packages is that you only have control over the interfaces declared in their manifests. For example, Snap has separate interfaces for `audio-playback` and `audio-record`, but some packages will only declare the legacy `pulseaudio` interface which grants access to both play and record audio. Likewise, some applications may work perfectly fine with Wayland, but the package maintainer may only declare the X11 interface in their manifest. For these cases, you need to reach out to the maintainer of the snap to update the manifest accordingly.
### Firejail
{{< youtube id="N-Mso2bSr3o">}}
[Firejail](https://firejail.wordpress.com/) is another method of sandboxing. As it is a large [setuid](https://en.wikipedia.org/wiki/Setuid) binary, it has a large attack surface which may assist in [privilege escalation](https://en.wikipedia.org/wiki/Privilege_escalation).
[Firejail](https://firejail.wordpress.com/) is another method of sandboxing. As it is a large [setuid](https://en.wikipedia.org/wiki/Setuid) binary, it has a large attack surface which increase susceptibility to [privilege escalation vulnerabilities](https://en.wikipedia.org/wiki/Privilege_escalation). [Madaidan offers additional details on how Firejail can worsen the security of your device.](https://madaidans-insecurities.github.io/linux.html#firejail)
Madaidan [provided](https://madaidans-insecurities.github.io/linux.html#firejail) additional details on how Firejail can worsen the security of your device.
If you do use Firejail, [Firetools](https://github.com/netblue30/firetools) can help to quickly manage application permissions and launch sandboxed applications. Note that Firetools configurations are temporary with no option to save profiles for long&#8209;term use.
If you do use Firejail, there is a tool called [Firetools](https://github.com/netblue30/firetools) which can help you quickly manage what an application can have access to and launch them. Note that the configurations by `Firetools` are temporary and it does not provide you with an option to save a profile for long term use.
Firejail can also confine X11 windows using Xpra or Xephr, something that Flatpak and Snap cannot do. I highly recommend checking out [their documentation on X11 sandboxing](https://firejail.wordpress.com/documentation-2/x11-guide/).
Firejail can also confine X11 windows using Xpra or Xephr, something that Flatpak and Snap cannot do. I highly recommend that you check out their [documentation](https://firejail.wordpress.com/documentation-2/x11-guide/) on how to set this up.
One trick to consistently launch applications which have a Firejail profile confined is to use the `sudo firecfg` command. This will create a symlink in `/usr/local/bin/app_name_here` pointing to Firejail. `.desktop` files which do not specifically specify the absolute path of the binaries to use will launch the application through the symlink and have Firejail sandbox them this way. Of course, this is bypassable if you or some other applications launch the application directly from `/usr/bin/app_name_here` instead.
One trick to launch applications with their Firejail profile is to use the `sudo firecfg` command. This will create a symlink `/usr/local/bin/app_name_here` pointing to Firejail, which will get used automatically by most .desktop files (which do not specify the absolute paths of their binaries) to use will launch the application through the symlink and have Firejail sandbox them this way. Of course, this is bypassable if you or some other applications launch the application directly from `/usr/bin/app_name_here` instead.
### Mandatory Access Control
Common Linux [Mandatory access control](https://en.wikipedia.org/wiki/Mandatory_access_control) frameworks require policy files in order to force constraints on the system.
Common Linux [mandatory access control (MAC)](https://en.wikipedia.org/wiki/Mandatory_access_control) frameworks require policy files in order to force constraints on the system. The two most notable are [SELinux](https://github.com/SELinuxProject/selinux) (used on Android and Fedora&#8209;based distributions) and [AppArmor](https://gitlab.com/apparmor/apparmor) (used on Debian&#8209;based distributions and most openSUSE variants).
The two main control systems are [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) (used on Android and Fedora based distributions) and [AppArmor](https://en.wikipedia.org/wiki/AppArmor) (Used on Debian based distributions and most openSUSE variants).
Fedora includes SELinux preconfigured with some policies to confine system daemons (background processes). You should keep it in _enforcing_ mode.
Fedora includes SELinux preconfigured with some policies that will confine [system daemons](https://en.wikipedia.org/wiki/Daemon_(computing)) (background processes). You should keep it in Enforcing mode.
openSUSE gives the choice of SELinux or AppArmor during the installation process. You should stick to the default for each variant (AppArmor for [Tumbleweed](https://get.opensuse.org/tumbleweed/) and SELinux for [MicroOS](https://microos.opensuse.org/)). openSUSEs SELinux policies are derived from Fedora.
openSUSE gives the choice of AppArmor or SELinux during the installation process. You should stick to the default for each variant (AppArmor for [Tumbleweed](https://get.opensuse.org/tumbleweed/) and SELinux for [MicroOS](https://microos.opensuse.org/)). openSUSEs SELinux policies are derived from Fedora.
Arch and its derivatives often do not come with a mandatory access control system, and you must manually install and configure [AppArmor](https://wiki.archlinux.org/title/AppArmor).
Arch and Arch-based operating systems often do not come with a mandatory access control system and you must manually install and configure [AppArmor](https://wiki.archlinux.org/title/AppArmor) for it.
Note that unlike Android, traditional desktop Linux distributions typically do not have full system Mandatory Access Control policies, and only a few system daemons are actually confined.
Note that, unlike Android, traditional desktop Linux distributions typically do not have full system Mandatory Access Control policies; only a few system daemons are actually confined.
### Making Your Own Policies/Profiles
You can make your own AppArmor profiles, SELinux policies, Bubblewrap profiles, and [seccomp](https://en.wikipedia.org/wiki/Seccomp) blacklist to have better confinement of applications. This is an advanced and sometimes tedious task, so I wont go into detail about how to do it here, but there are a few projects that you could use as reference.
You can make your own AppArmor profiles, SELinux policies, [bubblewrap](https://github.com/containers/bubblewrap) profiles, and [seccomp](https://docs.kernel.org/userspace-api/seccomp_filter.html) blacklist to have better confinement of applications. This is an advanced and sometimes tedious task, but there are various projects you could use as reference:
- Whonixs [AppArmor Everything](https://github.com/Whonix/apparmor-profile-everything)
- Krathalans [AppArmor profiles](https://github.com/krathalan/apparmor-profiles)
- noatsecures [SELinux templates](https://github.com/noatsecure/hardhat-selinux-templates)
- Seirdys [Bubblewrap scripts](https://sr.ht/~seirdy/bwrap-scripts)
- [Kicksecure's apparmor-profile-everything](https://github.com/Kicksecure/apparmor-profile-everything)
- [Krathalans AppArmor profiles](https://github.com/krathalan/apparmor-profiles)
- [noatsecures SELinux templates](https://github.com/noatsecure/hardhat-selinux-templates)
- [Seirdys bubblewrap scripts](https://sr.ht/~seirdy/bwrap-scripts)
### Securing Linux Containers
If youre running a server, you may have heard of Linux Containers. They are more common in server environments where individual services are built to operate independently. However, you may sometimes see them on desktop systems as well, especially for development purposes.
If youre running a server, you may have heard of containers. They are more common in server environments where individual services are built to operate independently. However, you may sometimes see them on desktop systems as well, especially for development purposes.
[Docker](https://en.wikipedia.org/wiki/Docker_(software)) is one of the most common container solutions. It is **not** a proper sandbox, and this means that there is a large kernel attack surface. You should follow the [Docker and OCI Hardening](/posts/apps/docker-and-oci-hardening/) guide to mitigate this problem. In short, there are things you can do like using rootless containers (either through configuration or through using [Podman](https://podman.io/)), using a runtime which provides a psuedo-kernel for each container ([gVisor](https://gvisor.dev/)), and so on.
[Docker](https://www.docker.com/) is one of the most popular container solutions. It does **not** offer a proper sandbox, meaning there is a large kernel attack surface. You should follow the [Docker and OCI Hardening guide](/posts/linux/docker-and-oci-hardening/) to mitigate this problem. In short, there are things you can do like using rootless containers (via configuration changes or [Podman](https://podman.io/)), using a runtime which provides a psuedo&#8209;kernel for each container ([gVisor](https://gvisor.dev/)), and so on.
Another option is [Kata containers](https://katacontainers.io/), where virtual machines masquerade as containers. Each Kata container has its own Linux kernel and is isolated from the host.
Another option is [Kata Containers](https://katacontainers.io/) which masquerades virtual machines as containers. Each Kata container has its own kernel and is isolated from the host.
## Security Hardening
![opensuse-computer.jpg](/images/opensuse-computer.jpg)
### Umask 077
If you are not using openSUSE, consider changing the default [umask](https://en.wikipedia.org/wiki/Umask) for both regular user accounts and root to 077. Changing umask to 077 can break snapper on openSUSE and is **not** recommended.
On distributions besides openSUSE, consider changing the default [umask](https://wiki.archlinux.org/title/Umask) for both root and regular users to `077` (symbolically, `u=rwx,g=,o=`). _On openSUSE, a umask of 077 can break snapper and is thus not recommended._
The configuration for this varies per distribution, but typically it can be set in `/etc/profile`, `/etc/bashrc`, or `/etc/login.defs`.
Note that unlike on macOS, this will only change the umask for the shell. Files created by running applications will not have their permissions set to 600.
Note that, unlike on macOS, this will only change the umask for the shell. Files created by running applications will not have their permissions set to 600.
### Microcode Updates
You should make sure that your system has microcode updates to get security fixes for vulnerabilities like [Meltdown and Spectre](https://meltdownattack.com/).
Debian does not ship microcode updates out of the box, so be sure to [enable the non-free repository](https://wiki.debian.org/SourcesList) and install the `microcode` package.
You should make sure your system receives microcode updates to get fixes and mitigations for CPU vulnerabilities like [Meltdown and Spectre](https://meltdownattack.com/).
Debian does not ship microcode updates by default, so be sure to [enable the non-free repository](https://wiki.debian.org/SourcesList) and install the `microcode` package.
On Arch Linux, make sure you have the `intel-ucode` or `amd-ucode` package installed.
Avoid the Linux-libre kernel at all cost, as they actively block [microcode updates to be loaded in runtime](https://www.phoronix.com/news/GNU-Linux-Libre-5.13). If you are looking to use [GUIX](https://guix.gnu.org/en/download/), you should absolutely use something like the [Nonguix](https://gitlab.com/nonguix/nonguix) repository and get the microcode updates.
If you are looking to use the [GNU Guix](https://guix.gnu.org/en/download/) distribution, you should absolutely use the [Nonguix channel](https://gitlab.com/nonguix/nonguix) or similar to get microcode updates.
Avoid the Linux-libre kernel at all costs, as they [actively block loading binary&#8209;only microcode](https://www.phoronix.com/news/GNU-Linux-Libre-5.13).
### Firmware Updates
Hardware vendors typically offer updates to Linux systems through the [Linux Vendor Firmware Service](https://fwupd.org/). You can download the updates using the following commands:
Many hardware vendors offer firmware updates to Linux systems through the [Linux Vendor Firmware Service](https://fwupd.org/). You can download and install updates using the following commands:
```bash
# Update metadata
fwupdmgr refresh
# Download firmware updates and apply them
# Download and install firmware updates
fwupdmgr update
```
On a typical desktop Linux system, the desktop enviroment's app store such as `gnome-software`, `discover`, or `snap-store` would integrate with `fwupd` and update your system firmware automatically. However, not all desktop environment/app store have this integration, so you should check your specific system and setup scheduled update tasks using [systemd timers](https://wiki.archlinux.org/title/systemd/Timers) or [cron](https://wiki.archlinux.org/title/Cron) if needed.
Some distributions like Debian do not have `fwupd` installed by default, so you should check for its existence on your system and install it if needed as well.
Some distributions like Debian do not have fwupd installed by default, so you should check for its existence on your system and install it if needed.
Note that `fwupd` supports UEFI update using the UEFI capsule. This could potentially cause issues if your system gets shutdown in the middle of an update. Unless you have USB FlashBack, you should disable this in your UEFI firmware (it is usually called Windows UEFI Firmware Update) or in `/etc/fwupd/uefi_capsule.conf` by adding `uefi` to the end of the `DisabledPlugins` line.
Several graphical frontends integrate with fwupd to offer firmware updates (GNOME Software, KDE Discover, Snap Store, [GNOME Firmware](https://gitlab.gnome.org/World/gnome-firmware), Pop!\_OS Settings app). However, not all distributions offer this integration by default, so you should check your specific system and setup scheduled updates or update notifications using [systemd timers](https://wiki.archlinux.org/title/systemd/Timers) or [cron](https://wiki.archlinux.org/title/Cron) if needed.
### Firewalls
Note that fwupd, like Windows Update, supports updating the UEFI. Power loss or forced shutdown in the middle of a UEFI update can brick your system, so unattended UEFI updating is not recommended unless you have the means to recover from a corrupted UEFI (motherboard flashback functionality or EEPROM flashing tools). fwupd UEFI updates can be disabled by adding `uefi_capsule` to `DisabledPlugins` in `/etc/fwupd/daemon.conf` and then restarting the fwupd daemon (`sudo systemctl restart fwupd`). **Keeping your UEFI up&#8209;to&#8209;date is important for security patches, so make sure to periodically revert this setting and apply updates manually or install UEFI updates via other methods supported by some motherboards.**
### Firewall
A [firewall](https://en.wikipedia.org/wiki/Firewall_(computing)) may be used to secure connections to your system.
Red Hat distributions (such as Fedora) are typically configured through [firewalld](https://en.wikipedia.org/wiki/Firewalld). Red Hat has plenty of [documentation](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/using-and-configuring-firewalld_configuring-and-managing-networking) regarding this topic. There is also the [Uncomplicated Firewall](https://en.wikipedia.org/wiki/Uncomplicated_Firewall) which can be used as an alternative.
Red&nbsp;Hat distributions (such as Fedora) and openSUSE typically use [firewalld](https://firewalld.org/). Red&nbsp;Hat maintains [extensive documentation about firewalld and its graphical frontend firewall-config](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/using-and-configuring-firewalld_configuring-and-managing-networking).
You could also set your default firewall zone to drop packets. If you're on a Red Hat or SUSE based distribution such as Fedora this can be done with the following commands:
Distributions based on Debian or Ubuntu typically use the [Uncomplicated Firewall (ufw)](https://wiki.ubuntu.com/UncomplicatedFirewall). As the name suggests, it is much less sophisticated than firewalld. One notable missing feature is the ability to apply different firewall rules for different connections (see _zones_ in firewalld).
You could also set your default firewall zone to drop packets. To implement this with firewalld (with the necessary exceptions for IPv6):
```
firewall-cmd --set-default-zone=drop
@ -224,212 +232,252 @@ firewall-cmd --add-protocol=ipv6-icmp --permanent
firewall-cmd --add-service=dhcpv6-client --permanent
```
All these firewalls use the [Netfilter](https://en.wikipedia.org/wiki/Netfilter) framework and therefore cannot protect against malicious programs running on the system. A malicious program could insert its own rules.
These firewalls use the [netfilter](https://netfilter.org/) framework and therefore cannot (without the help of strict [mandatory access control](#mandatory-access-control)) protect against malicious software running privileged on the system, which can insert their own routing rules that sidestep firewalld/ufw.
There are some per-binary outbound firewalls such as [OpenSnitch](https://github.com/evilsocket/opensnitch) or [Portmaster](https://safing.io/portmaster/) that you could use as well. But just like firewalld and UFW, they are bypassable.
There are some per&#8209;binary outbound firewalls such as [OpenSnitch](https://github.com/evilsocket/opensnitch) and [Portmaster](https://safing.io/portmaster/) that you could use as well. But, just like firewalld and ufw, they are bypassable.
If you are using Flatpak packages, you can revoke their network socket access using Flatseal and prevent those applications from accessing your network. This permission is not bypassable.
If you are using Flatpak packages, you can [set an override to block network access](#flatpak). This is not bypassable.
If you are using non-classic [Snap](https://en.wikipedia.org/wiki/Snap_(package_manager)) packages on a system with proper snap confinement support (with both AppArmor and [cgroups](https://en.wikipedia.org/wiki/Cgroups) v1 present), you can use the Snap Store to revoke network permission as well. This is also not bypassable.
If you are using non&#8209;classic Snap packages on a system that [supports proper confinement (both AppArmor and cgroups&nbsp;v1 present)](#snap), you can use the Snap&nbsp;Store to revoke network permission. This is also not bypassable.
### Kernel Hardening
There are some additional kernel hardening options such as configuring [sysctl](https://en.wikipedia.org/wiki/Sysctl#Linux) keys and [kernel command-line parameters](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html) which are described in the Madaidan's guide. You should read through them before applying these changes.
- [2.2 Sysctl](https://madaidans-insecurities.github.io/guides/linux-hardening.html#sysctl)
- [2.5.2 Blacklisting kernel modules](https://madaidans-insecurities.github.io/guides/linux-hardening.html#kasr-kernel-modules)
There are several things you can do to harden the Linux kernel, including setting appropriate [kernel parameters](https://wiki.archlinux.org/title/Kernel_parameters) and blacklisting unnecessary kernel modules.
Madaidan recommends that you disable unprivileged [user namespaces](https://madaidans-insecurities.github.io/linux.html#kernel) due to it being responsible for various privilege escalation vulnerabilities. However, some software such as Podman and LXD require unprivileged user namespaces to function. If you decide that you want to use these technologies, do not disable `kernel.unprivileged_userns_clone`.
_This section extensively references [Madaidan's Linux Hardening Guide](https://madaidans-insecurities.github.io/guides/linux-hardening.html) and in the interest of brevity does not repeat all the information contained there. You are strongly encouraged to read through the relevant sections of Madaidan's guide (linked for convenience)._
If you are using KickSecure or Whonix, most of these hardening have already been done for you thanks to [security-misc](https://github.com/Kicksecure/security-misc). If you are using a Debian, you should consider [morphing](https://www.kicksecure.com/wiki/Debian) it into KickSecure. On other distributions, you can copy the configurations from the following files to use:
#### Runtime Kernel Parameters (sysctl)
_See ["2.2&nbsp;Sysctl"](https://madaidans-insecurities.github.io/guides/linux-hardening.html#sysctl) in Madaidan's guide._
Madaidan recommends that you disable [unprivileged user namespaces](https://www.containerlabs.kubedaily.com/LXC/Linux%20Containers/User_namespaces.html) due to the [significant attack surface for privilege escalation](https://madaidans-insecurities.github.io/linux.html#kernel). However, some software such as Podman and LXC relies on unprivileged user namespaces. If you wish to use such software, do not disable `kernel.unprivileged_userns_clone`.
If you are using Kicksecure or Whonix, most of this hardening is included by default. If you are using Debian, you should consider [morphing it into Kicksecure](https://www.kicksecure.com/wiki/Debian). On other distributions you can copy the configuration files from Kicksecure:
- [`/etc/sysctl.d/30_security-misc.conf`](https://github.com/Kicksecure/security-misc/blob/master/etc/sysctl.d/30_security-misc.conf)
- [`/etc/sysctl.d/30_silent-kernel-printk.conf`](https://github.com/Kicksecure/security-misc/blob/master/etc/sysctl.d/30_silent-kernel-printk.conf)
- [`/etc/modprobe.d/30_security-misc.conf`](https://github.com/Kicksecure/security-misc/blob/master/etc/modprobe.d/30_security-misc.conf)
Note that these configurations do not disable unprivileged user namespaces. There are also a few things in `/etc/modprobe.d/30_security-misc.conf` to keep in mind:
- The `bluetooth` and `btusb` kernel modules are disabled by default. You need to comment out `install bluetooth /bin/disabled-bluetooth-by-security-misc` and `install btusb /bin/disabled-bluetooth-by-security-misc` if you want to use Bluetooth.
- Apple filesystems are disabled by default. This is generally fine on non-Apple systems; however, if you are using Linux on an Apple product, you **must** check what filesystem your EFI partition uses. For example, if your EFI filesystem is HFS+, you need to comment out `install hfsplus /bin/disabled-filesys-by-security-misc`, otherwise your computer will not be able to boot into Linux.
Note that these configurations do not disable unprivileged user namespaces.
### Harding Boot Parameters
#### Boot Parameters
Read through this section on how to harden your boot parameters:
- [2.3 Boot Parameters](https://madaidans-insecurities.github.io/guides/linux-hardening.html#boot-parameters)
_See ["2.3&nbsp;Boot parameters"](https://madaidans-insecurities.github.io/guides/linux-hardening.html#boot-parameters) in Madaidan's guide. If desired, [formal documentation of boot parameters](https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html) is available upstream._
Kicksecure comes with these boot parameters by default. This section is fairly short, so I'd recommend that you read it through. With that being said, here are all of the parameters that you would need:
These recommended boot parameters are included in Kicksecure by default:
```
slab_nomerge init_on_alloc=1 init_on_free=1 page_alloc.shuffle=1 pti=on vsyscall=none debugfs=off oops=panic module.sig_enforce=1 lockdown=confidentiality mce=0 quiet loglevel=0 spectre_v2=on spec_store_bypass_disable=on tsx=off tsx_async_abort=full,nosmt mds=full,nosmt l1tf=full,force nosmt=force kvm.nx_huge_pages=force randomize_kstack_offset=on
```
Note that [SMT](https://en.wikipedia.org/wiki/Simultaneous_multithreading) is disabled due to it being the cause of various security vulnerabilities. Also, on rpm-ostree based distributions, you should set the kernel parameters using `rpm-ostree kargs` rather than messing with `GRUB` configurations directly.
_See ["Disabling SMT"](#disabling-smt) for more about the effects of disabling SMT._
### Restricting access to /proc and /sys
Copy these parameters into [your bootloader's configuration](https://wiki.archlinux.org/title/Kernel_parameters#Configuration). On rpm&#8209;ostree distributions, make sure to use `rpm-ostree kargs` rather than editing GRUB configuration directly.
You should read these 2 sections in Madaidan's guide to further reduce the attack surface on the kernel:
#### Kernel Modules
- [2.4 hidepid](https://madaidans-insecurities.github.io/guides/linux-hardening.html#hidepid)
- [2.7 Restricting access to sysfs](https://madaidans-insecurities.github.io/guides/linux-hardening.html#restricting-sysfs)
_See ["2.5.2&nbsp;Blacklisting kernel modules"](https://madaidans-insecurities.github.io/guides/linux-hardening.html#kasr-kernel-modules) in Madaidan's guide._
Disabling access to `/sys` without a proper whitelist will lead to various applications breaking. This will unfortunately be an extremely tedious process for most users. Kicksecure, and by extension, Whonix, has the experimental [proc-hidepid](https://github.com/Kicksecure/security-misc/blob/master/lib/systemd/system/proc-hidepid.service) and [hide-hardware-info](https://github.com/Kicksecure/security-misc/blob/master/lib/systemd/system/hide-hardware-info.service) services which do just this. From my testing, these work perfectly fine on minimal Kicksecure installations and both Qubes-Whonix Workstation and Gateway.
Once again, Kicksecure includes this hardening by default and provides a config file which can be used on other distros: [`/etc/modprobe.d/30_security-misc.conf`](https://github.com/Kicksecure/security-misc/blob/master/etc/modprobe.d/30_security-misc.conf)
### linux-hardened
There are a few things in this config to keep in mind:
Some distributions like Arch Linux have the [linux-hardened](https://github.com/anthraxx/linux-hardened) kernel package. It includes [hardening patches](https://wiki.archlinux.org/title/security#Kernel_hardening) and more security-conscious defaults.
- The _bluetooth_ and _btusb_ kernel modules are disabled by default. If you wish to use Bluetooth, comment out the lines beginning with `install bluetooth` and `install btusb`.
- Apple filesystems are disabled by default. This is generally fine on non&#8209;Apple systems; however, if you are using Linux on an Apple device, you **must** check what filesystem your EFI partition uses. For example, if your EFI filesystem is HFS+, you need to comment out `install hfsplus /bin/disabled-filesys-by-security-misc`, otherwise your computer will not be able to boot into Linux.
linux-hardened has `kernel.unprivileged_userns_clone=0` disabled by default as well. See the [note above](#kernel-hardening) about how this might impact you.
#### Restricting access to /proc and /sys
### Linux Kernel Runtime Guard (LKRG)
_See ["2.4&nbsp;hidepid"](https://madaidans-insecurities.github.io/guides/linux-hardening.html#hidepid) and ["2.7&nbsp;Restricting access to sysfs"](https://madaidans-insecurities.github.io/guides/linux-hardening.html#restricting-sysfs) in Madaidan's guide._
LKRG is a kernel module that performs runtime integrity check on the kernel to help detect exploits against the kernel. LKRG works in a *post*-detect fashion, attempting to respond to unauthorized modifications to the running Linux kernel. While it is [bypassable by design](https://lkrg.org/), it does stop off-the-shelf malware that does not specifically target LKRG itself. This may make exploits harder to develop and execute on vulnerable systems.
Disabling access to `/sys` without a proper whitelist will lead to various applications breaking. Developing such a whitelist will unfortunately be extremely tedious for most users. Kicksecure, and by extension Whonix, has the experimental [proc-hidepid](https://github.com/Kicksecure/security-misc/blob/master/lib/systemd/system/proc-hidepid.service) and [hide-hardware-info](https://github.com/Kicksecure/security-misc/blob/master/lib/systemd/system/hide-hardware-info.service) services which do just this. From my testing, these work perfectly fine on minimal Kicksecure installations and both Qubes-Whonix-Workstation and Qubes-Whonix-Gateway.
If you can get LKRG and maintain module updates, it provides a worthwhile improvement to security. Debian-based distributions can get the LKRG DKMS package from KickSecure's repository and the [KickSecure documentation](https://www.kicksecure.com/wiki/Linux_Kernel_Runtime_Guard_LKRG) has installation instructions. Once again, if you are using Debian, consider [morphing](https://www.kicksecure.com/wiki/Debian) it into KickSecure. It should be noted that KickSecure does not currently install LKRG by default, and you will need to run `sudo apt install lkrg-dkms linux-headers-amd64` to obtain it.
#### linux-hardened
On Fedora, [fepitre](https://github.com/fepitre), a QubesOS developer, has a [COPR repository](https://copr.fedorainfracloud.org/coprs/fepitre/lkrg/) where you can install it. Arch based systems can obtain the LKRG DKMS package via an [AUR package](https://aur.archlinux.org/packages/lkrg-dkms).
Some distributions like Arch Linux offer the [linux-hardened](https://github.com/anthraxx/linux-hardened) kernel package. It includes [hardening patches](https://wiki.archlinux.org/title/security#Kernel_hardening) and more security-conscious defaults.
### grsecurity
linux-hardened has unprivileged user namespaces (`kernel.unprivileged_userns_clone`) disabled by default. [This may impact some software.](#runtime-kernel-parameters-sysctl)
grsecurity is a set of kernel patches that attempt to improve security of the Linux kernel. It requires [payment to access](https://grsecurity.net/purchase) the code and is worth using if you have a subscription.
#### Linux Kernel Runtime Guard (LKRG)
### Disabling Simultaneous Multithreading (SMT)
LKRG is a kernel module which self&#8209;describes as a runtime kernel integrity checker and exploit detector:
[SMT](https://en.wikipedia.org/wiki/Simultaneous_multithreading) has been the cause of numerous hardware vulnerabilities, and subsequent patches for those vulnerabilities often come with performance penalties that negate a lot of the performance gain given by SMT. If you followed the “Hardening Boot Parameters” section above, some kernel parameters already disable SMT. If the option is available to you, I recommend that you disable it in your firmware as well.
> As controversial as this concept is, LKRG attempts to _post_&#8209;detect and _hopefully_ promptly respond to unauthorized modifications to the running Linux kernel (integrity checking) or to credentials such as user IDs of the running processes (exploit detection). For process credentials, LKRG attempts to detect the exploit and take action before the kernel would grant access (such as open a file) based on the unauthorized credentials.
>
> LKRG defeats many pre-existing exploits of Linux kernel vulnerabilities, and will likely defeat many future exploits (including of yet unknown vulnerabilities) that do not specifically attempt to bypass LKRG. While LKRG is _bypassable by design_, such bypasses tend to require more complicated and/or less reliable exploits.
_(From [LKRG - Linux Kernel Runtime Guard](https://lkrg.org).)_
If you can get LKRG and maintain module updates, it provides a worthwhile improvement to security.
Debian-based distributions can get the LKRG DKMS package [from Kicksecure](https://www.kicksecure.com/wiki/Linux_Kernel_Runtime_Guard_LKRG), though Kicksecure does not install it by default. Packaging for Fedora is available through a [Copr repository](https://copr.fedorainfracloud.org/coprs/fepitre/lkrg/) maintained by Qubes OS developer fepitre. Arch users can obtain the LKRG DKMS package [from the AUR](https://aur.archlinux.org/packages/lkrg-dkms).
#### grsecurity
[Grsecurity](https://grsecurity.net/) offers a set of kernel patches that attempt to improve security of the Linux kernel. Payment is required, but grsecurity is worth using if you have a subscription.
### Disabling SMT
[Simultaneous multithreading (SMT)](https://en.wikipedia.org/wiki/Simultaneous_multithreading) has been the cause of numerous hardware&#8209;level vulnerabilities, and subsequent mitigations often negate much of the performance gain offered by SMT.
The [hardened boot parameters](#boot-parameters) presented here include disabling SMT. If the option is available, you should disable SMT/"Hyper&#8209;Threading" in your firmware as well.
Note that disabling SMT may have a significant performance impact.
### Hardened Memory Allocator
The [hardened memory allocator](https://github.com/GrapheneOS/hardened_malloc) from [GrapheneOS](https://grapheneos.org) can also be used on general Linux distributions. It is available as an [AUR package](https://wiki.archlinux.org/title/Security#Hardened_malloc) on Arch based distributions, and (though not enabled by default) on Whonix and Kicksecure.
The [hardened memory allocator (hardened_malloc)](https://github.com/GrapheneOS/hardened_malloc) from GrapheneOS can be used on general Linux distributions, though [only for some programs](https://www.kicksecure.com/wiki/Hardened_Malloc).
On Fedora, there is currently a build for it by Divested Computing Group that you can find [here](https://github.com/divestedcg/rpm-hardened_malloc)
If you are using Whonix, Kicksecure or have Hardened_Malloc installed somewhere, consider setting up `LD_PRELOAD` as described in the [Kicksecure Documentation](https://www.kicksecure.com/wiki/Hardened_Malloc) or [Arch Wiki](https://wiki.archlinux.org/title/Security#Hardened_malloc).
Kicksecure installs it by default (though not enabled by default) and provides [in&#8209;depth usage instructions](https://www.kicksecure.com/wiki/Hardened_Malloc) relevant to all distributions. On Arch-based systems, hardened_malloc is [available through the AUR](https://wiki.archlinux.org/title/Security#Hardened_malloc). Divested Computing Group maintains a [Fedora build](https://github.com/divestedcg/rpm-hardened_malloc).
### Mountpoint Hardening
Consider adding the [following options](https://man7.org/linux/man-pages/man8/mount.8.html) `nodev`, `noexec`, and `nosuid` to mountpoints which do not need them. Typically, these could be applied to `/boot`, `/boot/efi`, and `/var`.
Consider adding the [mount options](https://man7.org/linux/man-pages/man8/mount.8.html#FILESYSTEM-INDEPENDENT_MOUNT_OPTIONS) `nodev`, `noexec`, and `nosuid` to mountpoints which do not need the respective capabilities. Typically, these can be applied to `/boot`, `/boot/efi`, and `/var`. These flags could also be applied to `/home` and `/root`, however `noexec` will prevent applications that require binary execution in those locations from working (including Flatpak and Snap).
These flags could also be applied to `/home` and `/root` as well, however, `noexec` will prevent applications from working that require binary execution in those locations. This includes products such as Flatpak and Snap. It should also be noted that this is not fool proof, as `noexec` is bypassable. You can see an example of that [here](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/security/noexec_shell_scripts.md)
It should be noted that `noexec` is not foolproof and actually [quite easy to bypass](https://chromium.googlesource.com/chromiumos/docs/+/HEAD/security/noexec_shell_scripts.md#what-about-interpreted-code).
If you use [Toolbox](https://docs.fedoraproject.org/en-US/fedora-silverblue/toolbox/), you should not set any of those options on `/var/log/journal`. From my testing, the Toolbox container will fail to start if you have `nodev`, `nosuid`, or `noexec` on said directory. If you are on Arch Linux, you probably would not want to set `noexec` on `/var/tmp`, as it will make some AUR packages fail to build.
If you use [Toolbox](https://docs.fedoraproject.org/en-US/fedora-silverblue/toolbox/), do not set any of these mount options on `/var/log/journal`. From my testing, the Toolbox container will fail to start if you have `nodev`, `nosuid`, or `noexec` on said directory. If you are on Arch&nbsp;Linux, you probably do not want to set `noexec` on `/var/tmp`, as some AUR packages will then fail to build.
### Disabling SUID
SUID allows a user to execute an application as the owner of that application, which in many cases, would be the `root` user. Vulnerable SUID executables could lead to privilege escalation vulnerabilities.
SUID allows a user to execute an application as the owner of that application, which in many cases is the `root` user. Vulnerable SUID executables could lead to privilege escalation vulnerabilities.
It is desirable to remove SUID from as many binaries as possible; however, this takes substantial effort and trial and error on the user's part, as some applications require SUID to function.
Kicksecure, and by extension, Whonix has an experimental [permission hardening service](https://github.com/Kicksecure/security-misc/blob/master/lib/systemd/system/permission-hardening.service) and [application whitelist](https://github.com/Kicksecure/security-misc/tree/master/etc/permission-hardening.d) to automate SUID removal from most binaries and libraries on the system. From my testing, these work perfectly fine on a minimal Kicksecure installation and both Qubes-Whonix Workstation and Gateway.
Kicksecure, and by extension Whonix, has an experimental [permission hardening service](https://github.com/Kicksecure/security-misc/blob/master/lib/systemd/system/permission-hardening.service) and [application whitelist](https://github.com/Kicksecure/security-misc/tree/master/etc/permission-hardening.d) to automate SUID removal from most binaries and libraries on the system. From my testing, these work perfectly fine on minimal Kicksecure installations and both Qubes-Whonix-Workstation and Qubes-Whonix-Gateway.
If you are using Kicksecure or Whonix, consider enabling the `permission-hardening` service.
### Time Synchronization
### Securing Time Synchronization
Most Linux distributions by default use the unencrypted and unauthenticated [Network Time Protocol (NTP)](https://en.wikipedia.org/wiki/Network_Time_Protocol) for time synchronization. There are two ways to easily solve this problem:
Most Linux distributions by default (especially distributions with `systemd-timesyncd`) use NTP for time synchronization which is unencrypted and unauthenticated. There are two ways to easily solve this problem:
- [Configure Network Time Security (NTS) with chronyd](https://fedoramagazine.org/secure-ntp-with-nts/)
- Use Kicksecure's [sdwdate](https://github.com/Kicksecure/sdwdate) on Debian&#8209;based distributions.
- [Configure NTS with chronyd](https://fedoramagazine.org/secure-ntp-with-nts/)
- Use [sdwdate](https://github.com/Kicksecure/sdwdate) on Debian based distributions.
If decide on using NTS with chronyd, consider using multiple, independent time providers and setting [`minsources`](https://chrony.tuxfamily.org/doc/devel/chrony.conf#minsources) greater than 1.
If decide on using NTS with chronyd, consider using multiple different sources to synchronize your time with, and require at least half or more of those providers to actually change the time on your system.
GrapheneOS uses a [quite nice chrony configuration](https://github.com/GrapheneOS/infrastructure/blob/main/chrony.conf) for their infrastructure. I recommend that you replicate their `chrony.conf` on your system.
[GrapheneOS](https://grapheneos.org) actually uses a quite nice configuration for this with their infrastructure. I recommend that you replicate their [`chrony.conf`](https://github.com/GrapheneOS/infrastructure/blob/main/chrony.conf) on your system.
### Pluggable Authentication Modules (PAM)
### Linux Pluggable Authentication Modules (PAM)
[PAM](https://wiki.archlinux.org/title/PAM)'s [settings can be hardened](https://madaidans-insecurities.github.io/guides/linux-hardening.html#pam) to improve authentication security (though keep in mind the bypassable nature of PAM as opposed to encryption).
The security of [PAM](https://en.wikipedia.org/wiki/Linux_PAM) can be [hardened](https://madaidans-insecurities.github.io/guides/linux-hardening.html#pam) to allow secure authentication to your system.
On Red&nbsp;Hat distributions, you can use [authselect](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel) to configure this, e.g.:
On Red Hat distributions you can use [`authselect`](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-user-authentication-using-authselect_configuring-authentication-and-authorization-in-rhel) to configure this e.g.:
```bash
```
sudo authselect select <profile_id, default: sssd> with-faillock without-nullok with-pamaccess
```
On systems where [`pam_faillock`](https://man7.org/linux/man-pages/man8/pam_tally.8.html) is not available, consider using [`pam_tally2`](https://man7.org/linux/man-pages/man8/pam_tally.8.html) instead.
On systems where `pam_faillock` is not available, consider using [`pam_tally2`](https://www.man7.org/linux/man-pages/man8/pam_tally2.8.html) instead.
If you have a Yubikey, you can also use the `pam_u2f` module to require second factor authentication for your login. Follow the [Arch Wiki](https://wiki.archlinux.org/title/Universal_2nd_Factor) documentation for this. Note that you **must** set a non-transient hostname before setting this up, as you will not be able to login when your hostname changes.
If you have a YubiKey or other U2F/FIDO2 authenticator, you can use [pam-u2f](https://github.com/Yubico/pam-u2f) to implement two&#8209;factor authentication for login. **Make sure to use a hardcoded `origin` and `appid` as [indicated in the ArchWiki](https://wiki.archlinux.org/title/Universal_2nd_Factor#Authentication_for_Arch_Linux). Do not use the default identifier `pam://$HOSTNAME` which will break if your hostname changes.**
### Storage Media Handling
Most Linux distributions automatically mount arbitary filesystems from storage medias plugged into the computer. This is a security risk, as an adversary can attach a malicious storage device to your computer to exploit vulnerable filesystem drivers.
Some Linux distributions and desktop environments automatically mount arbitary filesystems upon storage media insertion. This is a security risk, as an adversary can attach a malicious storage device to your computer to exploit vulnerable filesystem drivers.
**udisks**
_This behavior is disabled by default on Whonix._
On systems which use `udisks` to automount and use `GNOME`/`Cinnamon` as their desktop environment, along with `Nautilus`/`Nemo` as the file manager can mitigate this risk by running the following commands:
#### UDisks
GNOME users on systems with UDisks can mitigate this risk by running the following commands:
```bash
echo "[org/gnome/desktop/media-handling]
echo '[org/gnome/desktop/media-handling]
automount=false
automount-open=false" | sudo tee /etc/dconf/db/local.d/custom
automount-open=false' | sudo tee /etc/dconf/db/local.d/automount-disable
echo 'org/gnome/desktop/media-handling/automount
org/gnome/desktop/media-handling/automount-open' | sudo tee /etc/dconf/db/local.d/locks/automount-disable
sudo dconf update
```
This will set the default `dconf` settings for new users and override all `dconf` settings for existing users. Note that this can be overidden by regular users on your system, simply by changing their individual `dconf` settings.
This will disable automounting and prevent users from overriding that setting (without privileges).
**autofs**
_Cinnamon uses the same configuration/commands except with `cinnamon` substituted in place of `gnome`. Other desktop environments based on GNOME&nbsp;3 likely follow a similar pattern&nbsp;--- use `gsettings` to investigate._
#### autofs
On older systems where `autofs` is used, you should mask the `autofs` service to disable this behavior.
**Whonix**
On Whonix, you generally do not need to worry about this behavior since it is disabled by default.
### USB Port Protection
To better protect your [USB](https://en.wikipedia.org/wiki/USB) ports from attacks such as [BadUSB](https://en.wikipedia.org/wiki/BadUSB), I recommend [USBGuard](https://github.com/USBGuard/usbguard). USBGuard has [documentation](https://github.com/USBGuard/usbguard#documentation) as does the [Arch Wiki](https://wiki.archlinux.org/title/USBGuard).
To better protect your USB ports from attacks such as [BadUSB](https://www.srlabs.de/bites/usb-peripherals-turn) and the infamous [Hak5 USB Rubber Ducky](https://hak5.org/products/usb-rubber-ducky), I recommend [USBGuard](https://usbguard.github.io). Documentation is available on the [USBGuard website](https://usbguard.github.io) and [ArchWiki](https://wiki.archlinux.org/title/USBGuard).
Another alternative option if youre using the [linux-hardened](#linux-hardened) is the [`deny_new_usb`](https://github.com/GrapheneOS/linux-hardened/commit/96dc427ab60d28129b36362e1577b6673b0ba5c4) sysctl. See [Preventing USB Attacks with `linux-hardened`](https://blog.lizzie.io/preventing-usb-attacks-with-linux-hardened.html).
If you are using [linux-hardened](#linux-hardened), you can alternatively use the `deny_new_usb` kernel parameter&nbsp;--- see ["Preventing USB Attacks with `linux-hardened`"](https://blog.lizzie.io/preventing-usb-attacks-with-linux-hardened.html).
## Secure Boot
[Secure Boot](https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface#Secure_Boot) can be used to secure the boot process by preventing the loading of [unsigned](https://en.wikipedia.org/wiki/Public-key_cryptography) [UEFI](https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface) drivers or [boot loaders](https://en.wikipedia.org/wiki/Bootloader).
[Secure Boot](https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface#Secure_Boot) can be used to secure the boot process by preventing the loading of unsigned UEFI drivers and bootloaders.
One of the problems with Secure Boot, particularly on Linux is, that only the chainloader (shim), the [boot loader](https://en.wikipedia.org/wiki/Bootloader) (GRUB), and the [kernel](https://en.wikipedia.org/wiki/Kernel_(operating_system)) are verified and that's where verification stops. The [initramfs](https://en.wikipedia.org/wiki/Initial_ramdisk) is often left unverified, unencrypted, and open up the window for an [evil maid](https://en.wikipedia.org/wiki/Evil_maid_attack) attack. The firmware on most devices is also configured to trust Microsoft's keys for Windows and its partners, leading to a large attacks surface.
One of the problems with Secure Boot, particularly on Linux, is that [only the chainloader (shim), bootloader (GRUB), and kernel are verified in a typical setup](https://wiki.ubuntu.com/UEFI/SecureBoot#How_UEFI_Secure_Boot_works_on_Ubuntu). The [initramfs](https://wiki.ubuntu.com/Initramfs#Detailed_Description) is often left unverified and unencrypted, leaving the door open for an [evil maid attack](https://en.wikipedia.org/wiki/Evil_maid_attack).
The firmware on most devices is also preconfigured to trust Microsoft's keys for both Windows and third&#8209;parties, leading to a [large attacks surface](https://github.com/ventoy/Ventoy/issues/135).
### Enrolling your own keys
To eliminate the need to trust the OEM's key, I recommend using [`sbctl`](https://github.com/Foxboron/sbctl).
---
First, you need to boot into your firmware and set the UEFI Secure Boot mode to the setup mode. Then follow the [README page](https://github.com/Foxboron/sbctl#key-creation-and-enrollment) to generate and enroll your own keys.
_**Please note that this procedure [will brick some non&#8209;compliant UEFI implementations](https://forums.lenovo.com/t5/Other-Linux-Discussions/Reports-of-custom-secure-boot-keys-bricking-recent-X-P-and-T-series-laptops/m-p/5105571).** You should research your specific computer/motherboard, looking for reported successes and failures alike, before attempting. Ideally, you should be prepared to reprogram the EEPROM to a known&#8209;good state if something goes catastrophically wrong. Integrated 'BIOS&nbsp;flashback' functionality may be an adequate recovery option._
On certain hardware, this will not work. Instead, you will need to import this in your firmware. You can export the public key to your EFI partition:
---
`openssl x509 -in /usr/share/secureboot/keys/db/db.pem -outform DER /boot/efi/EFI/fedora/DB.cer`
To eliminate the need to trust the OEM's keys, I recommend using [sbctl](https://github.com/Foxboron/sbctl).
First, you need to boot into your firmware interface and enter Secure Boot setup mode. Then boot back into Linux and [follow the instructions](https://github.com/Foxboron/sbctl/blob/master/README.md#key-creation-and-enrollment) to generate and enroll your own keys.
On certain hardware, this will not work. Instead, you will need to export the public key to your EFI partition and manually import it through your firmware interface:
```
openssl x509 -in /usr/share/secureboot/keys/db/db.pem -outform DER -out /boot/efi/EFI/fedora/DB.cer
```
### Unified Kernel Image
On most desktop Linux systems, it will be possible to create a [Unified Kernel Image](https://wiki.archlinux.org/title/Unified_kernel_image) that contains the kernel, [initramfs](https://en.wikipedia.org/wiki/Initial_ramdisk), and [microcode](https://en.wikipedia.org/wiki/Microcode). This unified kernel image can then be signed by the keys you created above.
On most desktop Linux systems, it is possible to create a [unified kernel image](https://wiki.archlinux.org/title/Unified_kernel_image) (UKI) that contains the kernel, initramfs, and microcode. This unified kernel image can then be signed with the keys created by sbctl.
For a Fedora Workstation specific guide, you can follow this [blog post](https://haavard.name/2022/06/22/full-uefi-secure-boot-on-fedora-using-signed-initrd-and-systemd-boot/) by Håvard Moen. He will walk you through the sbctl installation, unified kernel image generation with `dracut`, and automtic signing with systemd-boot.
For Fedora Workstation, you can follow [H&aring;vard Moen's guide](https://haavard.name/2022/06/22/full-uefi-secure-boot-on-fedora-using-signed-initrd-and-systemd-boot/) which covers sbctl installation, unified kernel image generation with [dracut](https://wiki.archlinux.org/title/Dracut), and automatic signing with systemd&#8209;boot.
For Arch Linux is very similar, though `sbctl` is already included in the official Arch Linux repository, and you will need to switch from `mkinitpcio` to `dracut`.
On Arch, the process is very similar, though sbctl is already included in the official repositories and you will need to switch from [mkinitpcio](https://wiki.archlinux.org/title/Mkinitcpio) to dracut.
In my opinion, this is most straight forward setup possible with a lot of potential such as integration with [systemd-measure](https://www.freedesktop.org/software/systemd/man/systemd-measure.html) in the future for better verification of the unified kernel image. With that being said, it does not appear to work well with specialized setups such as Fedora Silverblue/Kinoite or Ubuntu with `ZSYS`, and I need to do more testing to see if I can get them working.
In my opinion, this is the most straightforward setup, with a lot of future potential such as integration with [systemd-measure](https://www.freedesktop.org/software/systemd/man/systemd-measure.html) for better verification of the unified kernel image. With that being said, it does not appear to work well with specialized setups such as Fedora Silverblue/Kinoite or Ubuntu with [ZSys](https://github.com/ubuntu/zsys). More testing is needed to see if they can be made to work.
### Encrypted `/boot`
### Encrypted /boot
#### openSUSE
openSUSE and its derivatives come with encrypted `/boot` out of the box, with `/boot` being part of the root partition. This setup does work, as encryption will mask the problem that the initramfs is unsigned and unverified.
However, there are a few things to keep in mind:
openSUSE and its derivatives come with encrypted /boot out of the box (as part of the root partition). This setup does work, using encryption to sidestep the unverified initramfs problem.
- openSUSE uses `LUKS1` instead of `LUKS2` for encryption.
- `GRUB` only supports `PBKDF2` key derivation, and not `Argon2` (the default with `LUKS2`).
- You have to type the encryption password twice, though it could be solved by following the [openSUSE Wiki](https://en.opensuse.org/SDB:Encrypted_root_file_system#Avoiding_to_type_the_passphrase_twice).
- You could potentially improve your security by enrolling your own key as described [above](#enrolling-your-own-keys), reinstalling `GRUB` with the `--no-shim-lock` option, signing the kernel and `GRUB` it with your own keys, removing shim and MOK from the boot chain, and finally setting up hooks to automate these tasks every update. This is a rather tedious task and I have not yet tested it out on openSUSE.
However, there are some caveats:
- openSUSE uses LUKS1 instead of LUKS2 for encryption.
- GRUB supports PBKDF2 key derivation only, not Argon2 (the LUKS2 default).
- Some extra steps are necessary to [avoid typing the encryption password twice](https://en.opensuse.org/SDB:Encrypted_root_file_system#Avoiding_to_type_the_passphrase_twice_in_Leap_and_Tumbleweed).
- Though rather tedious, you could potentially improve security by:
- [Enrolling your own Secure Boot keys](#enrolling-your-own-keys)
- Reinstalling GRUB with `--no-shim-lock`
- Signing GRUB and the kernel with your own keys
- Removing shim and MOK from the boot chain
- Setting up hooks to automate these tasks for every update
#### Other Distributions
On systems which use [`grub-btrfs`](https://github.com/Antynea/grub-btrfs) to mimic openSUSE such as my old [Arch setup](https://github.com/tommytran732/Arch-Setup-Script), there are also a few things to keep in mind:
On systems which use [grub-btrfs](https://github.com/Antynea/grub-btrfs) to mimic openSUSE (such as [my old Arch setup](https://github.com/tommytran732/Arch-Setup-Script)), there are a few things to keep in mind:
- It will be easier to use `LUKS1` instead of `LUKS2` with `PBKDF2` for this setup. I have run into issues in the past where `GRUB` will detect a `LUKS1` partition converted to `LUKS2` with `PBKDF2`, but `grub-install` will not detect an existing `LUKS2` partition.
- You should make `/boot` part of your root partition instead of a seperate one. In theory, if you have a seperate `/boot` partition, an evil maid attack can replace it with a malicious `/boot` partition and setup a fake `GRUB` decryption prompt for you to unlock the drive and subsequently compromising the rest of the system.
- You will need to install `GRUB` with the `--no-shim-lock` option. The full command I use on my Arch Linux system is
```bash
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB --modules="normal test efi_gop efi_uga search echo linux all_video gfxmenu gfxterm_background gfxterm_menu gfxterm loadenv configfile gzio part_gpt cryptodisk luks gcry_rijndael gcry_sha256 btrfs tpm" --disable-shim-lock
```
- You will need to enroll your own key as described [above](#enrolling-your-own-keys), sign the kernel and `GRUB` with your own keys, removing shim and MOK from the boot chain (if you are using them), and finally setting up hooks to automate these tasks every update. On Arch-based distributions, you can find the instructions on setting up the hooks in the [Arch Wiki](https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Signing_the_kernel_with_a_pacman_hook).
- You will need to disable the TPM module in your firmware to prevent `GRUB` from attempting to do [Measured Boot](https://www.gnu.org/software/grub/manual/grub/html_node/Measured-Boot.html), which does not work with `grub-btrfs`. The discussion for this issue can be found [here](https://github.com/Antynea/grub-btrfs/issues/156).
- It will be easier to use LUKS1 than LUKS2 with PBKDF2 for this setup.
- I have run into issues where GRUB will detect a LUKS1 partition converted to LUKS2 with PBKDF2 but not a pre&#8209;existing LUKS2 partition.
- Include /boot in your root partition instead of as a seperate partition.
- With a seperate /boot partition, an evil maid attack can theoretically replace it with a malicious /boot partition. Unlocking the drive through a fake decryption prompt on the malicious partition will subsequently compromise the rest of the system.
- [Enroll your own Secure Boot keys](#enrolling-your-own-keys)
- Install GRUB with the `--no-shim-lock` option. The full command I use on Arch is:
```
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB --modules="normal test efi_gop efi_uga search echo linux all_video gfxmenu gfxterm_background gfxterm_menu gfxterm loadenv configfile gzio part_gpt cryptodisk luks gcry_rijndael gcry_sha256 btrfs tpm" --disable-shim-lock
```
- Sign GRUB and the kernel with your own keys
- Remove shim and MOK from the boot chain (if applicable)
- Set up hooks to automate these tasks for every update ([pacman hooks for Arch](https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Signing_the_kernel_with_a_pacman_hook))
- Disable the TPM from your firmware to prevent GRUB attempting [measured boot](https://www.gnu.org/software/grub/manual/grub/html_node/Measured-Boot.html), which [does not work with grub-btrfs](https://github.com/Antynea/grub-btrfs/issues/156).
### Notes
### Notes on Secure Boot
After setting up Secure Boot it is crucial that you set a “firmware password” (also called a “supervisor password”, “BIOS password” or “UEFI password”), otherwise an adversary can simply disable Secure Boot.
After setting up Secure Boot, it is crucial that you password-protect your UEFI settings (sometimes called 'supervisor' or 'administrator' password), otherwise an adversary can simply disable Secure Boot.
These recommendations can make you a little more resistant to [evil maid](https://en.wikipedia.org/wiki/Evil_maid_attack) attacks, but they not good as a proper verified boot process such as that found on [Android](https://source.android.com/security/verifiedboot), [ChromeOS](https://support.google.com/chromebook/answer/3438631) or [Windows](https://docs.microsoft.com/en-us/windows/security/information-protection/secure-the-windows-10-boot-process).
These recommendations can make you a little more resistant to evil maid attacks, but they do not constitute a proper verified boot process as found on [Android](https://source.android.com/security/verifiedboot), [ChromeOS](https://support.google.com/chromebook/answer/3438631), or [Windows](https://docs.microsoft.com/en-us/windows/security/information-protection/secure-the-windows-10-boot-process).