Fedora-downstream-hardening package: now to be adjusted for Kinoite/Silverblue

Fedora-downstream-hardening is now in version 0.6 (if someone wants to test, the 0.6 rpm is in the Security SIG ticket #1 comment 609078): 0.6 is likely ready for the mutable variants, but not yet for the immutable ones.

It’s not yet clear if I can support Silverblue / Kinoite when I release 1.0 (with 1.0 I will submit it for package review), as it’s not clear if I need to implement major changes.

I open this in case someone with experience in Silverblue / Kinoite knows an easy answer or is interested in contributing, as my experience with the immutable ones is yet limited, but no pressures, just in case someone has ideas off the cuff or is an enthusiast about the topic :classic_smiley: I’ll find my way through it :slight_smile: I will use this also a little as a log.

Testing is done so far with Kinoite, I expect Silverblue will behave equally, but it will be tested later as well when everything works fine on Kinoite. I did not yet do large testing (I’m done for today:), but when just installing the package with rpm-ostree install ....rpm and then do harden activate after reboot, the outcome is broken, which I at first glance link to two issues, while only the second one was predicted:

  1. /etc/firewalld/zones/ is empty in Kinoite. While it’s logical that the files are in /usr/lib/firewalld/zones/ and then end up in /sysroot/ostree/deploy/fedora/..., I have to find out how to get the hardened files derived from the files in /etc/firewalld/zones/, and then to be used in future overlays in /sysroot/ostree/deploy/fedora/.... The related file of the package is harden, lines 80-82. As there can be differences among admins and Fedora variants, I cannot just copy/paste files, but need to derive them from the xml that are there (it effectively just removes the ports but also retains the original files to be able to deactivate itself later).

  2. The installed file /usr/share/doc/Fedora-downstream-hardening/99-kernel-hardening.conf could not create a link to /usr/lib/sysctl.d/, as the latter is obviously RO. Related for this is harden, line 85

I expect the second will be an easier one. I’m sure there is an intended way to enable a file, or contents, for kernel parameters that I can adopt. However, the first one makes me a little worrying if there is an easy solution without much re-writing. We’ll see :classic_smiley:

2 Likes

Nr. 2 has been solved, though it seems that some common practices might need to change over time, and I expect I found a mitigation for Nr. 1 too :classic_smiley: I know how to solve 1. but not yet understand why active XMLs are not stored in /etc/firewalld/zones by default the same way as on other variants.

This package shall work in several customizations, and allow them as far as possible: even if there is a narrowed scope of the audience, people still might have different firewall configurations and needs. I don’t want to override their configuration, but only remove the open ports IF their configuration has them, as open ports are assumed to be not relevant for the general workstation, but relevant for certain (attack) scenarios → thus the compromise to remove the ports, but leave the rest as the user has customized it

I was considering commands rather than the xml modifications about the way you suggest it, but came to the conclusion that all they have an impact that might be more than necessary. Also, different Fedora variants might also come with different defaults, which I would leave as far as possible to not change the behavior more then necessary (also for troubleshooting etc).

Thanks for that, every contribution and feedback is appreciated :classic_smiley:

The repo is no longer at the current state, as I already made some changes to get it towards compatibility of silverblue/kinoite (might push something new tomorrow). Obviously, mostly about the two mentioned issues :classic_smiley:

I considered that, butt didn’t do it. To be honest, I don’t know off the cuff why :classic_smiley: But I have another review about it: much has changed in the recent days and many assumptions and conditions of before are no longer applicable.

That can get complex and add a lot of lines, because different users/variants have different defaults (which ports open/closed etc), and I need to be able to revert the state.

Thanks for sharing :classic_smiley:

Yeah I think that’s good thoughts. An /etc/harden to save some stuff existed in an earlier version but became obsoleted later. I am still a little experimenting to get all implications of Kinoite/Silverblue, but it’s again on the “to evaluate/test” list :classic_smiley: Thanks for the incentives

I have not yet tested it, so might be a bug inside, but I test that out later. But the changed approach is contained. It should work on mutable and immutable: prepare 0.7,untested,immutable-compatible · py0xc3/Fedora-downstream-hardening@50aaa65 · GitHub

I don’t like that became so much bash including if/else though… I’m not used to much bash and wanted to use that just for procedural things. But I think it is in the context still the most comprehensible/straightforward way. The if/else remain easy to understand imho

Unfortunately, I think I remember now the second reason why I stopped considering the commands (after testing :face_with_hand_over_mouth: ) … firewall-cmd fails if I want to remove ports that are not open anyway. So I need to gather in advance the information of what is open on the very variant / customization. That adds complexity and makes bash hard to read too. So a new py tool would be necessary for this.

However, given the differences between the mutable and immutable variants, I think a separated python tool für the firewall-cmd is indeed more stable than the earlier solution, that worked fine only for mutable variants… I’ll test a little and then let’s see if I find a mitigation or setup a new py tool for that. Maybe there’s an API for that too, I’ll find out :classic_smiley:

I stick with that as best solution that fits both mutable and immutable. In the end, the goal is that the hardening gives a general but secure workstation compromise. Leaving whatever the firewall has configured other than ports can be seen as counterproductive up to false security anyway. With the public default, the hardening of the firewall settings is as predictable/expectable as the other settings, and I guess I can expect everything else goes beyond a normal workstation/laptop approach anyway.

With that approach, a lot of error-prone complexities are avoided, it can fit all variants, and it is easier to read for users/admins who customize files/lines but who have no dev experience.

Thanks again for your thoughts, much appreciated, and obviously with impact :classic_smiley:

The current state solves both problem 1 and 2, self-tests are already updated too. First test on immutable worked out. Some more testing in the next days to ensure all is fine :classic_smiley: Maybe some more optimization possible, we’ll see (my bash skepticism remains though :unamused_face: )

Hey Chris. I think you should take a look at SecureBlue, which is a more native way of doing this instead of pushing things into an RPM.

1 Like

Thanks. I’m indeed not satisfied by the current way. Did yesterday another total rewrite of the firewall part as its too ugly / bad practice and error-prone (not yet pushed). Not a fan of the “bash is used to enable everything” variant, but it has prove as dependency to achieve both the requirement to not enable anything on package installation, and to have the main tool readable by people with cli experience but no dev experience. rpm indeed feels not native to this…

However, do you mean to put everything in a container way? Or to create a new variant based on an existing base image? That would cause trouble as I cannot get it to impact systemwide on all variants.

I talked to one of their developers in the security channel and we compared the sysctl parameter we considered (it seems they also consider some changes). Indeed worth to stay connected and exchange, but off the cuff I couldn’t find more to take over of them (?)

Maybe there is a misunderstanding (?): this package does not aim to radically harden the system or so. To some extent, it does not harden, but a hardened state is the “side-effect”. This goes back to, e.g., the yama.ptrace_scope debate → my package shall capture the whole experience of any Fedora/CentOS/Alma/Rocky variant any user want, containing all the reviews and tailoring of any of these (incl. security and stability and behavior guarantees). The only impact it should make is a dynamic one: change the approach to compromises. In yama, the decision was to consider a minority (in terms of the number of affected people) over a majority, leaving the latter with something that can cause serious issues if - as many do - install untrusted third party software etc. This package just changes the way of compromises: only the majority matters (assuming that is average desktop/workstation users), so the scope of compromises is narrowed, for average users just 1 install and 1 command, to get an optimal compromise facilitating everything average users need (secureblue would be already overkill for average users), without DoS for any of them but still excluding the most dangerous risks they partially introduce themselves. For cli experienced users, they can review the files and select themselves what is useful for them, or just pick lines to enable manually. Massive simplified summary of the elaboration of the repo’s README.md (which indeed should be shortened at some point) :classic_smiley:

With yama in mind, a developer and an average user can both get the Fedora Workstation experience, but whereas any new innovation of the Workstation team would come with the next update to both, one would go the way of yama=disabled and the other yama=enabled, and both would not be affected by issues as the first can use their gdb while the second has as much protection as possible of untrusted software they install (extreme example). So if I get you right, the secureblue approach is unfortunately not useful for this, even if it feels indeed much more “best practice” than an rpm->bash-tool approach :frowning: