Nix is an extremely powerful tool for security research, especially because of quite simple impermanence, both on metal and in VMs. Spinning up clean VMs with all the nice tool is a matter of one command and a second to execute. However, i currently can not seriously recommend NixOS for that kind of stuff, as hardening features are currently quite lacking. Mandatory Access Control (MAC) is one of the things that can improve that state.
AppArmor will be shorted to aa. I will link articles and issues, but i can not guarantee they will all stay up forever. These lists wonât be complete either, iâll try to update them as i do work and come across new issues.
Roadmap
adopt apparmor package, NixOS module and NixOS test (PR merged)
improve NixOS test coverage (PR open)
- catch profiles actually containing processes and denying certain access
- catch profiles actually allowing certain resources
- catch state of profile applying properly (enforce/complain/disable)
- match profile placement in /etc/apparmor.d to have expected file contents
- format
- move to folder to be extendable later
Clean up the many booleans to define profile state (PR open)
- This is a breaking change!!
- This prepares to later expand the state definition to allow states kill, prompt, unconfined without breaking user configs again
Allow defining policy paths to link, instead of relying on a lines-type NixOS config option being written to store (PR open)
- This is ideally a non-breaking change
- Previously, including existing policy paths would have been done either with readFile (dangerous IFD territory, especially doing it on lots of files gets slow. Especially because itâll immediately be written to the store again), or defining security.apparmor.policies.<name>.profile = ''include "${./path/to/file}",'' (which leaves it to the aa parser to realize that include directive, which is also potentially slow.)
- Including profiles by path instead of by content is important to make apparmor rules packages work in the future
Fix roddhjav-apparmor-rules package
- very broken currently
- does not follow upstream build script
- Introduced in #319286
> This is meant to be used with AppArmor module: security.apparmor.packages = with pkgs; [ roddhjav-apparmor-rules ];
This never worked. Includes link the files, but donât make the apparmor parser read those profiles.
- Rules packages either need extensive patching or an entirely new design to accomodate them. NixOS is not FHS-compliant. This means all the profiles matching against /bin/something or usr/share/something and similar wonât ever just work. I outlined that problem in my hedgedoc posts before. The original contributor of that package also realized these issues later in #331645 (comment)
- Conclusion: full rewrite of that package.
Set up Nix-compatible development environment to work on AppArmor
- expose latest git packages
- make upstream contribution easier
- running tests
- compiling apparmor and components
Contribute on apparmor upstream
- more test cases testing things we rely on in nix
- improving the alias system as outlined in aa #460 (comment)
- needs a design doc of how exactly aliases should work first. I am working on that.
Is there anywhere to discuss/collaborate on this? Iâve been looking into and vaguely following the process of your efforts, but I would love to help out with this if possible!
Hello, and i appreciate the offer to help! I intended this as a tracker, but turns out posts on discourse are not editable 24h after posting them. So i will probably move to a github tracking issue soon.
This list is basically a non-exhaustive list of things that need doing. Some of those things simple, some complex, and some depend on others.
Imo the immediate focus should be two things:
get apparmor to a state where future changes to the module are likely not breaking (this means extendable enough, both in profile state definitions and profile content definitions)
improve test coverage, including integration tests and package tests.
Organizing work:
i am open to suggestions about organizing. But it seems i misunderstood what discourse is good for. Tracking doesnât work well at least. Iâd be happy with both a github project board or a github tracking issue. Project board would be editable by anyone working on this, but i am not sure what the agreed procedures about project boards are. Maybe @hexa can give some insight? Just a short âyeah sure make a projectâ/âtracking issue would be best because âŚâ would be amazing! Is there precedent in the security team about long-term projects like this?
Sidenote: It seems regular nixos org members canât just create projects in nixpkgs. So if that were to be the decided organizing platform, i wouldnât be the one who is able to start that.
Tracking issue has the benefit: I can actually open it!
Next steps/Where i am stuck
the alias rework: try and make the alias solution work (i am currently still testing against globs, which is not ideal). This needs a design document that is flexible enough for nix to use aliases, but well-defined in a way where it is reasonable to upstream those things.
regression tests: for the life of me i can not figure out how to get the regression tests working. It needs root to test, because it tests on a running system. This means this test would have to be built in a nixos VM and run as a VM check. But even then, i did not have any luck. Iâd be happy to have anyone more familiar have a go at it. HOWEVER: This is non-critical. Tests are nice to spot issues, but not immediately crucial for getting stuff working.
dev shells: I expect weâll be upstreaming quite a bit to apparmor. A dev shell is on my list of things to do, but i am open to someone else writing one too. Good shells are magic.
some consideration about python + perl in apparmor. Python is needed, but we might be able to reduce perl useage to check inputs only. This does however need more testing.
Nixos module/Overlays: Itâd be nice to use a flake to pull and test git versions of apparmor on a real system or reuse the nixos VM test i implemented in #356796. Ideally, the flake would live outside of the apparmor repo to not bother the apparmor maintainers with nix stuff, and have some github bot to update the apparmor repo it pulls or something. I didnât yet fully consider the architecture here, thisâd need discussion.
I did a bit of tinkering, and i have almost all tests passing, and those that donât pass blacklisted.
Thing is: these tests still need a running system to run, they donât actually run in a build sandbox. So next up is throwing this into a nixos VM test. But, i am making progress!
This is (imo) the first usable state for apparmor git packages, and now i can work on improving testing (reg tests still need a vm test output) as well as finally doing dev shells.
I did have to switch the flake tracking branch over to my nixkgs fork with the apparmor test cases fixed, but i will drop that as soon as my module/test fix PR is merged.
I am happy if people try it and open issue reports for issues they come across. But as always, keep backups and fallbacks (e.g. a specialization that disables apparmor) so you donât brick your system.
With #356796 merged and the apparmor-dev packages/overlay being mostly tested and ready, it is now time to move ahead and clean up the apparmor packages. Iâll soon open a draft PR, but i am not super familiar with how multiple packages from one source set with shared patches is supposed to be implemented.
The current plan is to have one source derivation applying patches, and a âsharedâ file applying things like check enable and meta definitions, with the actual packages being separate files. But if anyone has good pointers, this is definitely something for which iâd appreciate some help.
If someone wanted to test AppArmor rules in a self-packaged application, is there a suggested way to do so or place to start?
Edit after posting: Iâm not sure if this is actually the right place for this question or not (and apologies if so), unfortunately. I figured that this would be good to ask considering the changes to AppArmor being done here!
Testing rules is hard because you basically need to run through all the functions of the app to be certain the rules donât break stuff. Doing this well is not trivial, sadly.
For some apps, rules can be tested by running their nixos tests in a VM test that you extend with the apparmor-specific things. Hijacking a nixos test and modifying the config it runs with isnât easy either, but with enough headaches you can do it. An example can be found here: apparmor-dev/flake.nix at 032cb3469176411d5bda5642049abc468073e18a ¡ LordGrimmauld/apparmor-dev ¡ GitHub [sidenote: improvements are welcome, i really donât like the hacks i do thereâŚ]. That might be a good benchmark if you want automated testing for your profiles.
The next best thing is just manual testing. Youâd define the apparmor profile in the exact same way, but test the app for all its (core) features manually. This is largely how i test my own profiles for now.
Shipping apparmor profiles with an app is not trivial either: profiles need maintenance and testing. In an ideal world, every package maintainer would be diligent enough and care enough to do that. But i am under no illusions: that simply wonât happen. And i am not exactly keen on the idea of maintaining 120k profiles by myself. Until a sustainable model for maintaining profiles is found (which, imo, requires making profiles compatible with profiles not specifically designed for nixos systems) then we can start work on improving profile coverage imo. I am not the only person who has a say in that though. Just not my concern (yet).
As to place to ask: AppArmor is neglected. I donât know of any other place on this forum actually taking aa serious. So eh, fine to bring it up here.
This is basically the same problem as systemd hardening and we have been able to roll that out to NixOS modulesâ services to a decent degree on a best-effort basis.
In the long term, Iâd ideally like to see upstreams maintain the aa profiles for their apps because they know best what those should and shouldnât be able to do. (Just like with systemd hardening.)
I feel like that should become more prevalent because I see the Zeitgeist moving towards more hardening as we become aware of just how insecure our (in other respects awesome) systems are.
Iâm under no illusion that we wonât get every upstream to do so though, so I think an independent collection of permissively licensed (i.e. apache-20) profiles would be the next best thing.
This should ideally be a cross-distro effort as, for any given program, the associated aa profile should dictate the same policy on basically any distro.
Itâs also not like we need to provide complete aa profiles for each and every program. You could provide default rules for all programs that provide some basic hardening and work for 99% of them and then manually fix the remaining 1%. That 1% would be much more manageable.
What I mean by âbasic hardeningâ would be preventing any old program from accessing high-value targets such as SSH keys, GPG keys, browser cookies, executables (user bin, bashrc, systemd user services) or perhaps even personal documents.
If we could produce profiles that only allow the few % of programs that actually need to be able to access these, that would be an immense security benefit already IMHO.
It would be cool to have some baseline rule that a nix store path can only execute things and also only load shared libs in its closure.
Another useful rule would be that a caller of a nix store path can pass elements of its closure down to callees.
For example systemd service for nginx has nginx in its closure so systemd can spawn nginx. Systemd service has config in its closure so it can pass down read access to the config down to nginx. But nginx doesnât have permission to read sshd config from nix store.
This would divert from a model where we assume the whole nix store is readable. Instead we can use (transformations) over the nix store closure property to define access control efficiently.
I have no idea how to implement this. My first thought was storing closure info in xattrs so that SELinux can access closure info or something.
Maybe something similar is possible in Apparmor too.
Any how my point is my feeling is that the model of the nix store and the explicit dependencies should in theory allow for very elegant access control. Much more elegant than any existing distros.
This is the best place, but the project is paused until apparmor 4.1 releases with some required fixes and until i have some more time to commit to this (=when i am done with my bachelors thesis i am writing currently)
I have opened a PR updating apparmor to the recently released 4.1.0.
This includes a complete rewrite of the packaging, as well as making all apparmor packages work with pkgsLLVM, pkgsMusl, and pkgsCross. Reviews are appreciated.
Excuse the fanboying, but what you are doing is great, and you have personally caused me to go from being completely uninterested in apparmor to investigate rewriting our nix expressions at work to automatically generate apparmor policies (which is trivial because they are java server applications). Way to advance the state of the art!