Whonix should implement more kernel hardening. All of these settings add no or a very minimal performance decrease.
Setting “kernel.kptr_restrict=1” makes kernel symbols in /proc/kallsyms only accessible to root which can make it more difficult for a kernel exploit to resolve addresses/symbols. Setting it to 2 hides the symbols regardless of privileges.
Setting “kernel.dmesg_restrict=1” restricts access to the kernel logs which can give an attacker less information on what they can do.
Setting “kernel.unprivileged_bpf_disabled=1” and “net.core.bpf_jit_harden=2” hardens the BPF JIT compiler and restricts it to root. It comes with a performance drop on systems that use the JIT compiler a lot but this should only really effect servers.
Setting “vm.mmap_rnd_bits=32” and “vm.mmap_rnd_compat_bits=16” improves KASLR effectiveness for mmap.
These can all be set in files in /etc/sysctl.d
I have tested all of these on Whonix Gateway and Whonix Workstation and they worked fine.
Adding “slab_nomerge” as a boot parameter may also be useful. slab_nomerge disables the merging of slabs of similar sizes. Sometimes a slab can be used in a vulnerable way which an attacker can exploit.
Mounting /proc with hidepid=2 in /etc/fstab will hide other users’ processes from unprivileged users. This makes it a lot harder for an attacker to get information about other running processes. This did break systemd-logind for me on Whonix even when I added an exception for systemd-logind.
It may also be good to look into using the linux-hardened kernel. Would it be possible to use this for Whonix?
“page_poison=1” and the P on the “slub_debug” option are mainly used for Tails’ RAM poisoning. These may improve security anyway by preventing some use-after-free vulnerabilites. These might not work properly in a VM as it doesn’t have access to all of the host’s RAM.
“mce=0” is only useful for ECC memory. It might be good to have just incase but it also might not work properly in a VM.
“vsyscall=none” disables vsyscalls which were removed so this setting is redundant.
The rest except “slab_nomerge” seems to be related to live mode or some other features unrelated to security.
It seems to be enabled by default now. I didn’t know that. I checked Whonix and it’s enabled there too.
Also, one problem with "kernel.dmesg_restrict=1” is that the kernel logs can still be read out by journalctl if the user is part of the systemd-journal, adm or wheel groups. The ordinary user in Whonix is part of the adm group so the kernel logs can still easily be read by an attacker. Maybe there is a way to somehow restrict this even further?
Disabling journald altogether could prevent this but it shouldn’t be done as it’s very useful in debugging errors.
Another way would be to change the permissions for /var/log/journal, /run/log/journal and /bin/journalctl so only root can use it. I don’t know how useful this would be though.
There is an issue on the linux-hardened github repo about this.
For some reason it doesn’t allow me to send the actual link. (Edit by Patrick: link fixed)
Edit: It seems I needed to get the basic badge to send links which I just got.
Since Tails is using most if not all of these configuration changes, shipping these in Whonix might be sustainble (not breaking too many things than current development manpower allows to triage, fix and user support).
Users might manually do this as per Whonix Documentation but I don’t think this is sustainable for default installation in Whonix with current developer manpower since the package is not available from packages.debian.org, see also:
(Kernel is not an “app” but stuff written there applies here too.)
Will I create a pull request for these or something else?
Yes, please.
For /etc/sysctl.d and /etc/default/grub.d (and perhaps /etc/modprobe.d
if needed).
How would hidepid be added if at all?
Please test if it works. If yes, we can take it too.
Which platforms could you test?
virtualbox-guest-additions in Whonix VirtualBox shouldn’t break by this.
(Then things would get more complex - another package or if/else code if
possible required.)
I’m not sure if I should add the other boot parameters like page_poison=1 and slub_debug=FZP. What do you think of these? The tails kernel hardening page goes over these.
I can test on Virtualbox and virt-manager (KVM).
Also, regarding the journalctl thing, I’ve made a simple bash script and systemd service that restricts everything to root at boot. It works well and I haven’t gotten any errors yet. Do you think it’d be good to add this to Whonix?
Looks really good at first! Will probably be merged soon.
Haven’t seen anything negative about these. Why not. Yes, please add.
Awesome, that helps a lot! I’ll test in Qubes first.
Can be considered but I am not sure that would be a clean implementation. Rather, I would like to possibly fix the original cause of these issues. Will answer more soon.
That code was carried around probably from the early TorBOX script version and never been questioned unfortunately.
usermod --append --groups adm,cdrom,audio,dip,sudo,plugdev user || true
Maybe that has to be reworked. Should we remove some user groups, we can modify that for existing users to in whonix-legacy package (using the “do only once” style).
Could you please try removing user user from adm (and whatever else seems to make sense) and see how that works generally?
What’s next? Suggest removal of user user being in group sudo by default?
Strong Linux User Account Isolation i.e. how well can linux protect from root privileged escalation after user user account was compromised (by a remote code execution vulnerability).
If we must yes. But fixing the original issue above is better. (Since this solution is more fragile - overriding config of with [systemd or whatever that will be in future or ports] tmpfiles.d mechanism.)
I’ll test that now on the Gateway and Workstation. I’m not sure what purpose adm has except for the journal.
Well for a completely locked down system, that would actually be good. Just make a systemd service for updating at boot. It’d be incredibly difficult to use properly though.
I agree. My way would probably break a lot of things.
Removing the user from the adm group works perfectly. I get an error when running journalctl and I can’t view the log files manually. There are no other errors.