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:

1 Like

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.

Hello Chris,

It is entirely possible that I might be missing the point, but why don’t you just use the built-in firewalld-cmd tooling to remove the ports? You could get the current zone, save it, and then change the default zone to something more strict like drop or public. You can always revert by going back to the original zone they had set. I feel utilizing purpose specific tooling would be more reliable than modifying the XML file.

I appreciate the effort you’re making and just wanted to provide my two cents.

Edit: I just wanted to clean my post up a bit so it would read better.

1 Like

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:

Thank you for clarifying why you made the choice to harden the firewall rules this way. I fully understand wanting to make minimal changes so you do not disrupt any custom rules they may have set up. Given this context, I can see how my suggestion might be a bit heavy handed and could potentially even cause problems. However, I still feel like trying to leverage built-in tooling would make this less prone to breaking in the future. For example, if you could potentially leverage firewall-cmd --remove-port= to remove the default ports that are opened up and then use a similar command to add them back if the user wants to revert the changes.

Unfortunately, I don’t have any feedback to help improve your existing way of making the change. However, I do appreciate you taking the time to listen to my ideas. I’ll keep an eye on this project and try to make contributions where I am able to if the opportunity arises.

Take care!

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:

1 Like

I think you could potentially avoid this problem by just saving their current port configuration before making any changes. This way, regardless of any changes they made, you can always revert back to the exact state they had before your script removed the ports. I am not saying this will definitely work for you, but it just might be something worth exploring to see how it pans out. :slight_smile:

1 Like

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

1 Like

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: )