-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
why remount-secure even needed? fix insecure mount options at the root, not here #157
Comments
Well, actually there is a better way. A solution that is no band-aid. And it is modifiying the fstab. There is also another solution, that is direct and involves no remounting. We can write custom systemd mount targets and ship them with the package. The only problem with the latter is, fstab entries take precedence over those units. So we can't harden what is covered in fstab with this way. |
Like if the user has a seperate /home volume, we can't harden it with our custom systemd unit. I think the reason behind this is, systemd dynamically overrides our unit with the unit it auto generates from fstab on startup. |
That doesn't really answer why it's insecure by Debian (or most Linux distributions) default. |
Because by default debian and most distributions don't do too much disk partitioning. If you want a seperate tmp or var partition, most of the time you manually configure them when installing. And bind mounting to itself is clever workaround to get all the good mounting option benefits without having the partition itself, but it is really not that surprising that no distro would mount a directory to itself by default. |
A very highly unrelated sidenote: the only distribution that I see who ships secure defaults by default is openSUSE. Debian by default ships with very slack file permissions for anything. OpenSUSE however ships with already mostly hardened defaults. Tumbleweed gets a score of 87 on lynis after a default install. Debian and most other distros get like 60. And this isn't surprising, because Debian does not try to be better desktop or server os. Debian tries to be the universal os, compatible with every device ever. So actually makes sense for them to ship slack defaults. A price to pay for universal compatibility. |
Where is the source code where it says "use these default mount options for this and that partition"? |
Created #161 for it. |
quote https://lists.freedesktop.org/archives/systemd-devel/2019-December/043845.html
This might be the referenced source file:
This implies that initramfs (initramfs-tools, dracut) is responsible for mount options too. |
Ok I tell you the source. Systemd calls the binart
These would not be necessary for stuff that have no entries in fstab. Like if the use has no seperate partition for var, we can create a |
But dracut earlier also already uses mount? Or do you mean the systemd which already runs during dracut? I couldn't find yet the mount options that dracut uses. |
When you mount, if you do |
At least 3 different things we could accomplish here.
In case of A),
In case of B),
In case of C), directly writing to |
|
Yeah I don't think that will work. Pushing to debian upstream. Like it might, but the debian team is very unresponsive unless it is a bug fix. It would happen probably, but like, in about 3 debian releases later. We can just make our own good defaults ISO. Which isn't that hard to be honest. I feel like we are on our own for the most part tho. I don't want to take every opportunity to shill suse, so I'm sorry. But opensuse puts in effort to harden their default fstab entries. |
Debian isn't a conglomerate. It depends on the individual packages, maintainers. I was talking about grml-debootstrap. Pushing fixes to grml-debootstrap seems entirely doable. I managed to land a few patches in grml-debootstrap. The only condition is that it needs to be clean, high quality code. You can see my commits here: It doesn't take long either until it reaches derivative-maker. I copied grml-debootstrap to derivative-maker source code folder. A soft fork if you want so. (Not with the intention splitting from upstream due to disagreement or running a separate project. Just to make the updated code available earlier in derivative-maker waiting for the next major Debian release. No big story.) grml-debootstrap recently learned arm64 support which was contributed by a Whonix contributor. Upstream grml-debootstrap took even did the cleanup / refactoring commits. Building VM images with EFI and Secure Boot was also recently contributed and merged by another contributor. Until now, grml-debootstrap upstream is entirely reasonable. I might even be capable of running a "full fork" of grml-debootstrap should upstream disappear which I don't hope because they've been doing great work for years. Improving grml-debootstrap fstab will result in improved Kicksecure VM images. (Would also be possible to leave grml-debootstrap as is and add a better fstab at the derivative-maker level only but that would be more hacky and less beneficial for the overall ecosystem, less use and testing, less bugs only happening inside Kicksecure and derivatives.) Non-responsiveness of other Debian maintainers is inapplicable here. |
You are right. I was talking about changes you would suggest debian to make in their iso installer. In that case they would not be involved anyway. And also the unresponsiveness of debian maintainers are not meant in a bad way. They are very responsive on security fixes and bug fixes, but thats pretty much it. If they wanted, they could be responsive to feature requests, if they weren't shipping one billion packages in their repositories, which even for them is really impossible to maintain. Instead they choose the way of trying to be the universal os. Which I think is something that holds kicksecure back. There are two things I see that are holding kicksecure back. First is QubesOS compatibility. Which is understandable and there isn't much to do against this. The second is debian. Debian's package freezing is really not we want. Like even if you fix your thing upstream, good luck waiting another 2 years till the next debian, in which that version still might not be in the repos anyway. And they even microcode updates too, between point releases. This is also, a no no for a security system. Actually imma open an issue in a sec with a suggestion. |
Btw the installer would be calamares based which is also a project independent of Debian which apparently is popular, used by many Linux distributions nowadays, configurable, supports plugins, is responsive. It's also packaged for Debian. Any fstab issues could be reported there. However, I am not sure how great the chances are of fstab hardening feature requests to be implemented without also sending a pull request doing the actual implementation. Testing calamares fstab and feature request if applicable would be a helpful contribution nonetheless to see what upstream calamares thinks about this. (A calamare based installer is entirely realistic. There once was a Whonix-Host installer. Implying that the same would be possible for Kicksecure. The calamares config files can nowadays be found in Kicksecure package |
A completely different approach would be having no fstab at all. I've had a chat with chatgpt on this topic: In summary, use bootloader, dracut and systemd mounts to mount the root disk and everything else. Not sure that is possible with grub. systemd-boot might be capable of that. But systemd-boot isn't signed by Debian yet. [1] For rather mysterious reasons if you read that ticket. [2] Dunno if the Boot Loader Specification (BLS) is required which grub might not support. I couldn't find a ticket for grub. Seems like some distributions as Fedora are patching grub. In summary, seems difficult to research and create a stable implementation to me. [1] https://groups.google.com/g/linux.debian.bugs.dist/c/n0-eRL6eVtQ |
Well then I am really pleased to share that I have found a way. Real, no bandaid, no workaround. Just mounting stuff the way we want it. I tested it too. It's just writing mount units, but they have to be under etc. From the manpage:
It means exactly what it means. Tho fstab takes precedence over mount units, mount units under etc take precedence even over fstab. So we just create mount unis under etc. We can even do this under a something.mount.d directory to allow the user to override us. The only thing that is problematic is, the mount options. We can not preemptively know before shipping a mount unit for home if needs bind or not. If we tackle that, I think we got a solid solution. |
How about |
Unfortunately doesn't work. Gets overriden by fstab. You can see it in the manpage section I quoted. |
systemd supports many conditionals: Such as Does that work? If not, please post a systemd feature request. 1) The feature might exist already anyhow 2) they might implement the feature. |
I'd still prefer Then how about
These migration details can be tackled later. First priority are the systemd units as a proof of concept. |
Yeah, a systemd based implementation would be best. We could deploy the more restrictive mount settings by default. ( Another detail: For Whonix, tb-starter would need a sudoers exception to run a script which mounts Tor Browser's folder (unfortunately resides in |
Actually we kinda need the fstab to read the mount points. At least initially. Else how would we know where to mount /boot for example? If we write mount units under /usr/lib with --bind options, this might be a good enough solution. If there is no partition, it gets binded to itself with the secure defaults. If there is a partition, it gets overriden by fstab anyway, so the unit will do nothing. This won't harden a the /home directory if it is on a seperate partition for example. |
To avoid user complaints and get everyone on board: |
That is what I meant by
in #157 (comment) which also mentions how that might be possible to go completely fstab-less. (grub kernel parameter, dracut to mount the root disk, systemd to handle all other mounts) It might be the case to go fstab-less would only be possible for (new) Kicksecure (VM) builds where we know the (simple) partitioning. Next version will be built using grml-debootstrap using I had in mind here a completely static systemd mount files configuration. Nothing auto generated by any scripts. Just simple systemd config snippets. And no fstab at all.
There could be two different systemd mount drop-ins? One with ConditionPathIsDirectory the other with ConditionPathIsMountPoint? |
Addressed in the new pull request. For the most part it is solved. |
A little off topic: By the way the guide you provided, I have also gone through it several times before, but it should be noted that it is super duper old. Mounting The only case where running some kind of anything on |
By the way, while we are at it, I wanna refer to #178, where you said:
In that case I would suggest we set the following parameters in grub, as they will work for the newer systemd versions. This has the same behavior as adding new lines to fstab. And since these are universal and system independent, they can be set this way. They won't change based on the users partitioning scheme. |
I am also surprised we're the first ones inventing a hardened fstab file and publishing it.
What is "Debian"? I mean, where is it down, how, source file? This could be specific to initramfs-tools vs dracut vs other init systems vs booting a system for real vs systemd-nspawn etc.
Also Qubes is also a legitimate user of Debian and Qubes most likely didn't purposefully downgrade /run. Rather something else (something similar to initramfs-tools vs dracut).
Why?
Added and then from the running system
Works for me only when using Could say your syntax works when booting but not from the running system. But using bind seems easier to to work with since then no reboot is required every time. Maybe the current syntax would fail to boot (or actually do nothing). In any case, a completely hardened fstab file that is fully tested would be most helpful.
Ok.
If mounting /var as noexec,nosuid fails, I'd prefer a booting system. Way easier to debug and fix than a non-booting system. Unit testing can be done in other places such as in systemcheck. In any case, nofail can stay for the first iteration and maybe removed later when this is stable.
Yes, a complete fstab that can be used in Kicksecure VMs. Would a great start.
There are no partitions in the VM except for:
And also /boot/efi but the latter is simply not done yet. I don't know if it has a stable uuid yet or maybe blocked by migration to (maybe) mkosi which creates stable uuids presumably.
Great to know!
I want to test a hardened /etc/fstab first over several releases. Then everything is in 1 expected place and easy for users to customize. When nothing breaks, maybe systemd kernel parameters can be used. Maybe /etc/fstab could contain a comment to mention how /dev/, /dev/shm, /tmp is hardened (by using kernel parameters). That would be good too. Feel free to send a PR. That could remain open until the next Debian release.
True, I said that. However, in this case I would make an exception. This is the second step. Would be rushing ahead and confusing myself to merge that right now. Also because of the potential regressions when porting to the next major version of Debian. Could take a while to remember and figure out what is causing it. Because /etc/fstab hardening is realistic in this Debian release cycle so that should be done as first step. |
I don't think we are. Debian already does some hardening for api file systems. For example run is fully hardened and /dev/shm is partially hardened on debian, which would not be the case by default if debian devs didn't set it that way.
On a debian system run Also, I have discovered that, api file systems are still remounted if we modify the fstab. Because when these file systems are mounted the first time, there is no universal way of accessing the fstab file, so the init script just runs and does its thing. If there is a line for an api file system in fstab, they are remounted by systemd-remount-fs.service. So the ultra clear solution would be modifying the init script, which I think is possible for packages to do as well. You asked
Because it is meant to work on boot only. Bind mounting provides no solution because we never use fstab to mount things midway. But it creates new problems on its own. This would also be true if we had a line for proc there. We can also use bind, but then if a process was accessing that path before we bind, it won't be affected by our hardening at all, including init I think, which obviously can't be good if anything. So for the ultimate solution, I suggest we find a way to solve the api file systems in initramfs. For other, real partitions, we already have a working solution that uses drop in config files, from my old pull request. So combining these would be, I think, optimal. |
This is only 1 way to use Debian. That is initramfs-tools, which Kicksecure doesn't use. At time of writing, Kicksecure uses dracut by default. Reference: It is also possible to have an initrdless system (a kernel with all required modules compiled-in), perhaps other init systems (in the future maybe mkosi-initrd, which is a systemd based initrd without special init queues by initramfs-tools or dracut, which might simplify initrd a lot), and certain types of virtualization such as systemd-nspawn does not use and initrd. Might be similar for docker, OpenVZ. They all however should be honoring /etc/fstab.
There's a dracut module right in security-misc: It was working but it was said to be slow. 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. If you're interested in initramfs-tools or any other init system, you could contribute fstab hardening upstream. That would also get way more scrutiny and probably stability than anything invented and only in Kicksecure.
Also seems we're going in circles here (as the dracut module was previously enabled) and without writing a technical design with all the different approaches, pros and cons of each, solution impartial research this will probably keep going in circles. |
Created an overview now: Contributions welcome. There are at least 6 different approaches to mount options hardening, 3 different types of mount points (API, partition, folder) and various different environment. |
Ok very interesting. I have said this is the debian default because debian by default does not use dracut. Because systemd is also just one way to use debian, since they offer other init systems in their repos. But since it is the default, I think it is reasonable to say debian by default uses systemd, and by default uses initramfs-tools. I see the reasoning the porject had to switch to dracut is to support a live system. Is this necessary? I'm pretty sure Ubuntu uses initramfs and they offer a live system. So I don't know why you switched there. Does this make development somehow easier?
I agree. But for this, the place to contribute is the package maintainer of the distribution. Because even this semi-hardening is the choice of debian packagers, and not the upstream devs, far as I know. So instead of bothering with that, we might as well fix it for us ourselves.
Good. This is a good way to keep track of this long discussion. It is more complicated than the our good old usual hardening and there are many ways. |
I am getting confused by the many different approaches, tickets, pull requests on this topic. Wasn't there some git branch you wanted to restore, older approach which you wanted to re-vitalize? Instead #195 was done? |
found the comment here:
|
Live mode (grub-live) indeed also works with initramfs-tools. The full story about porting to dracut is here: Main reasons here: Updated summary why here: The very main reason is: |
After long consideration of the many different options, I've decided that /etc/fstab file based mount options hardening is the most suitable way to implement secure mount options for Kicksecure. This is the way forward. Contributions to |
Will there be a way to control some mount options or control the timing on mounting? If it will use systemd to trigger the fstab read, being able to add an override.d like With current configuration released to end users, I believe I am having a similar issue to this one: Caused quite an interesting scenario where all my data became hidden with a recent patch. https://old.reddit.com/r/zfs/comments/hpnmiw/systemd_mount_order_between_zfs_and_etcfstab_bind/
|
Mounting |
No. There's no need for it. Simply a modified |
fstab is a user artefact. So the solution there would be to somehow configure the calamares installer or whatever we plan to use to set these secure defaults in the installer. But even then, there won't be binding anything. You can not add bind lines to fstab in the installer. So package would need to do that. And we are back to here.
If you messed a little with these stuff you probably know that this gets really complicated real quickly. Even with /var and /var/log the order is not possible to configure in the fstab file. In a unit file, it is possible, but then it is almost always guaranteed to slow up the boot massively (when we are binding, especially nested binding). |
Calamares supports fstab configuration already. Quote https://github.com/calamares/calamares/blob/calamares/src/modules/fstab/fstab.conf
Why not? |
Because the installer is a dynamic program. In like the expected scenario the user plugs in a usb and live boots to kicksecure, there is the live environment, he looks around for a minute, ok nice, now he decides to install. Calamares installer, ok nice. When you are at the place where you do the partitions and stuff, the installer does not do everything for you. The installer just makes suggestions basically, but the user still chooses the partitions and whatnot. In an ideal scenarion, we modify the default suggestions made by calamares to use secure defaults. Ok nice, but then there can't be any bind mounts. Which binds are we going to include? Does calamares even have an interface to suggest bind mounts in the installer? There we need some program to make decisions with elaborate if else statements. Ok if boot is not a separate partition then do this, if it is, do this, if it is like a different file system, then obviously do these stuff because it is different on this. If the user changes the installation or formats one of the partitions or like a billion other things, we still have to at some point decide dynamically. The "let's put the config and forget about it and it works universally" logic only works for api file systems with kernel params and real mounts with real partitions with drop in configs. For binds, there is no such solution that I could find, at least not without creating several layers of abstraction. The other issue is the fact that bind mounts are already problematic on their own. I remeber I encountered this problem. There is no way to make nested binds work universally. Firstly, having the wrong order with nested binds will result in two valid points of accessing a directory, one of which will easily circumvent the hardened mount options. To remove this possible work around, they have to be mounted in cordination with the order from inner to outer. And that, requires some big Sorry for the long answer. Think of it as if I'm brainstorming loudly. |
Partioning is automatic.
Same as #157 (comment)
No, and it's probably not needed either. And if needed, then calamares seems easily extensible with python modules.
I am not sure Calamares supports custom partitioning or if that should be supported. But if Calamares can do that, then fstab.conf (speak calamares fstab module) can probably handle that as well.
If that's true, then this ticket is a
Then upstream needs to be consulted regarding these issues. |
Once again. Calamares is a solution, no doubt, at least when installing. If we want a universal solution that ships with a package tho, the remount service is really a good solution. I have done some reading of systemd source code. For api file systems, changing fstab entries just makes systemd remount them with the new options using a service. The initial mounting still takes places with the options of the init script, written by debian mostly. So like, having our own service is not so different than modifying fstab for these file systems at least. The trickster here is, the remount service systemd has is written in c. Shell scripting a bunch of remounts is slow. Also shell scripts are non universal. Bash or zsh, synthax changes. We should avoid having shell executables whenever possible, especially for services. This is not only for speed, but also for security. The suid-disabler-permission-hardener deserves a separate repo. So does the remount-secure service. Having the mount service and permission thing trigger on boot would be enough. Also we would trigger the permission thing with a post apt hook (better than using stat-override for various reasons). I can personally write these things. I can write makefiles, and dedicated apparmor profiles and like at the end, you would just run make all and you would have everything in a conventional structure under a directory. Or literally like github workflows to build them binaries and put them in a good structure. Packaging that directory then would be the classical good old stuff that you already know. This is just my suggestion. Moving away from shell scripts is a better and cleaner way, and provides modularity. Having several services under a single package is not developer friendly. and if you think this would be complicated than necessary, well, it wouldn't be because the source code is gonna really short and minimalistic. Either way, moving away from shell scripts or not, I think these services deserve separate repos. |
The initial mounting still takes places with the options of the init script, written by debian mostly.
That one I would like to see the source code for.
The trickster here is, the remount service systemd has is written in c. Shell scripting a bunch of remounts is slow.
Why slow? The slowness isn't inherited from being shell scripting. If
you run the remount-secure from within the running system it should
complete in seconds. Perhaps 1-3 seconds. Please measure that.
But during boot, it might be a lot slower slower. 10, 20 seconds? But
that's not because of the shell. There must be other reasons for that.
So first, please compare the speeds:
- A) shell, from running system
- B) shell, using systemd or dracut
- C) versus compiled language
Bash or zsh, synthax changes.
In 12 years, bash never required a syntax change that I can remember.
We should avoid having shell executables whenever possible, especially for services. This is not only for speed, but also for security.
I am yet to see a threat model where remount-secure being shell versus
compiled language results in a significant difference.
The suid-disabler-permission-hardener deserves a separate repo. So does the remount-secure service.
Either way, moving away from shell scripts or not, I think these
services deserve separate repos.
Yes, these functionalities are really heavy-weight and ideally had
separate repositories.
milestone: "one day"
Having the mount service and permission thing trigger on boot would be enough. Also we would trigger the permission thing with a post apt hook (better than using stat-override for various reasons).
For permission hardener that is already implemented. It has an dpkg
trigger that runs wherever any package on the system is installed or
updated. dpkg-statoverride is the tool to configure DPKG to prevent
restoration of layer permissions when packages that contain files with
SUID that are removed are upgraded. If you think there's something
missing, please open a separate issue for that.
I can personally write these things. I can write makefiles, and dedicated apparmor profiles and like at the end, you would just run make all and you would have everything in a conventional structure under a directory. Or literally like github workflows to build them binaries and put them in a good structure. Packaging that directory then would be the classical good old stuff that you already know. This is just my suggestion.
Please maintain as independent upstream: source code, binaries,
popularity, review, etc.
That would help so I don't have to look into it. If it's independently
used and reviewed, then integration into Kicksecure will be much simpler.
|
@monsieuremre in #203 (comment):
@adrelanos above:
Solutions are all messy but the least messy I've settled with is
Otherwise there are too many mount points.
And each requirement a different mechanism to change these would make it even more messy.
It cannot really cover all mount points A), B), C)? |
It surely can cover everything apart from API file systems, and they can be covered with just drop in kernel parameters, but its just not a good idea. |
Anything missing here? |
Which software / source code sets the initial insecure mount options anyhow?
Could we fix it there instead of adding a band-aid on top?
The text was updated successfully, but these errors were encountered: