MOD_APPARMOR(8)

✨ NAME ✨

mod_apparmor β€” fine-grained AppArmor confinement for Apache, bestie πŸ’–


🌸 DESCRIPTION 🌸

okay so here's the vibe πŸ’… an AppArmor profile applies to an executable program. but like… if one part of that program needs different access permissions than the other parts, the program can "change hats" β€” via aa_change_hat(2) β€” into a different role, also known as a subprofile. 🎩✨

and THAT'S what the mod_apparmor Apache module does, fr fr. it uses the aa_change_hat(2) mechanism to offer more fine-grained confinement of dynamic elements within Apache β€” think individual php and perl scripts β€” while still letting you keep the performance benefits of using mod_php and mod_perl. no cap, it's giving best of both worlds. 😌πŸ”₯

πŸ¦‹ how do i even turn it on

To use mod_apparmor with Apache, make sure mod_apparmor is configured to be loaded into Apache β€” either via a2enmod, yast, or manual editing of the apache2(8)/httpd(8) configuration files β€” and restart Apache. also please make sure that apparmor is actually functioning. like. that part matters. πŸ™ˆ

🌈 what happens once it's loaded

Once mod_apparmor is loaded within Apache, all requests to Apache will cause mod_apparmor to attempt to change into a hat that matches the ServerName for the server/vhost.

and if no such hat is found? bestie it does NOT just give up, it falls back like the icon it is:

  1. first it falls back by attempting to change into a hat composed of the ServerName-URI (e.g. "www.example.com-/app/some.cgi").
  2. if that hat is not found, it falls back to attempting to use the hat named by the URI (e.g. "/app/some.cgi").
  3. if that hat is not found, it falls back to attempting to use the hat DEFAULT_URI.
  4. if that also does not exist, it falls back to using the global Apache profile.

Most static web pages can simply make use of the DEFAULT_URI hat. slay. πŸ’…

πŸ’œ the untrusted input era

Additionally, before any requests come in to Apache, mod_apparmor will attempt to change hat into the HANDLING_UNTRUSTED_INPUT hat. mod_apparmor will attempt to use this hat while Apache is doing the initial parsing of a given http request β€” before it's given to a specific handler (like mod_php) for processing. it's literally the bouncer at the door checking IDs. πŸ‘‘πŸ«Ά

πŸŽ€ because doing this by hand is exhausting

Because defining hats for every URI/URL often becomes tedious, mod_apparmor provides the AAHatName and AADefaultHatName Apache configuration options. you're welcome. πŸ’–

🌟 AAHatName

AAHatName allows you to specify a hat to be used for a given Apache <Directory>, <DirectoryMatch>, <Location> or <LocationMatch> directive (see the Apache documentation for more details).

⚠️ note that mod_apparmor behavior can become confused if <Directory*> and <Location*> directives are intermingled, and it is recommended to use one type of directive. pick a lane bestie 😭

If the hat specified by AAHatName does not exist in the Apache profile, then it falls back to the behavior described above. πŸ”

🌟 AADefaultHatName

AADefaultHatName allows you to specify a default hat to be used for virtual hosts and other Apache server directives, so that you can have different defaults for different virtual hosts. cute, right? πŸŽ€

This can be overridden by the AAHatName directive, and is checked for only if there isn't a matching AAHatName. The default value of AADefaultHatName is the ServerName for the server/vhost configuration.

If the AADefaultHatName hat does not exist, then it falls back to the behavior described above. πŸ”


✨ URI REQUEST SUMMARY ✨

When profiling with mod_apparmor, it is helpful to keep the following order of operations in mind (iykyk πŸ‘€):

On each URI request, mod_apparmor will first aa_change_hat(2) into ^HANDLING_UNTRUSTED_INPUT, if it exists.

Then, after performing the initial parsing of the request, mod_apparmor will:

  1. try to aa_change_hat(2) into a matching AAHatName hat if it exists and applies, otherwise it will
  2. try to aa_change_hat(2) into an AADefaultHatName hat, either the ServerName (the default) or the configuration value specified by the AADefaultHatName directive, for the server/vhost, otherwise it will
  3. try to aa_change_hat(2) into the ServerName-URI, otherwise it will
  4. try to aa_change_hat(2) into the URI itself, otherwise it will
  5. try to aa_change_hat(2) into the DEFAULT_URI hat, if it exists, otherwise it will
  6. fall back to the global Apache policy

πŸ’€ BUGS πŸ’€

mod_apparmor() currently only supports apache2, and has only been tested with the prefork MPM configuration β€” threaded configurations of Apache may not work correctly. 😭 For Apache 2.4 users, you should enable the mpm_prefork module. do it. don't skip this one. πŸ™ˆ

There are likely other bugs lurking about; if you find any, please report them at <https://gitlab.com/apparmor/apparmor/-/issues>. bestie we WANT the bug reports, they're a gift 🫢


πŸ¦‹ SEE ALSO πŸ¦‹


okay that's the whole page!! ✨ go forth and confine your Apache, you absolute legend. this was AppArmor 6.0.0~alpha1, dated 2026-10-05 β€” periodt πŸ’…πŸ’–πŸŽ€

πŸ“¦ where this page comes from