Professional Documents
Culture Documents
Apparmor Apache
Apparmor Apache
How to do that?
First you need to patch you kernel with apparmor patches (these are very small and non-intrusive);
most of AppArmor lives in separate directory in kernel tree: security/apparmor so it’s not conflicting
even with grsecurity patches. You will also need to download and build apparmor-parser, apparmor-profiles
and apparmor-utils packages. All these available on AppArmor Home Page.
AppArmor keeps policy files in /etc/apparmor.d/. These are simple text files, for example
/etc/apparmor.d/usr.sbin.httpd.prefork policy:
# vim:syntax=apparmor
# Last Modified: Tue Dec 12 02:37:27 2006
#include <tunables/global>
/usr/sbin/httpd.prefork flags=(complain) {
#include <abstractions/base>
#include <abstractions/nameservice>
/usr/sbin/httpd.prefork mr,
capability setuid,
capability setgid,
capability kill,
capability dac_override,
capability dac_read_search,
/etc/httpd/apache.conf r,
/etc/httpd/conf.d r,
/etc/httpd/conf.d/* r,
/etc/httpd/ssl/* r,
/usr/lib{,64}/apache/*.so mr,
/etc/httpd/webapps.d r,
/etc/gai.conf r,
/etc/httpd/magic r,
/etc/mime.types r,
/usr/share/file/magic* r,
/etc/openssl/** r,
/var/log/httpd/** w,
/var/log/archive/httpd/* w,
/etc/php4/** r,
/usr/lib{,64}/php4/*.so mr,
/etc/php/** r,
/usr/lib{,64}/php/*.so mr,
/var/run/httpd.pid rw,
/var/run/httpd/** rw,
/proc/[0-9]*/attr/current rw,
/etc/snmp/** r,
/usr/share/snmp/** r,
/usr/share/perl5/** r,
/usr/lib{,64}/perl5/** r,
/usr/lib{,64}/perl5/**.so* mr,
/usr/X11R6/lib{,64}/lib*.so* mr,
^HANDLING_UNTRUSTED_INPUT flags=(complain) {
/home/services/httpd/** r,
/var/log/httpd/** w,
/var/log/archive/httpd/* w,
/home/users/**/.htaccess r,
}
^HAT_no_access flags=(complain) {
/home/services/httpd/** r,
/var/log/httpd/** w,
/var/log/archive/httpd/* w,
}
#include <abstractions/httpd-users>
}
r – read, w – write, ix – inherited policy on execution, * – simple globbing, **– glob that also matches slash
character (there is more of these of course – see man apparmor.d(5) for details).
HANDLING_UNTRUSTED_INPUT and HAT_no_access are HATs configuration (HAT is previously
mentioned subpolicy). By default mod_apparmor runs in HANDLING_UNTRUSTED_INPUT hat. That hat
can be changed from configuration file for example:
AADefaultHatName HAT_no_access
<VirtualHost vhost.domain.org>
AADefaultHatName HAT_domain_org
[...]
</VirtualHost>
<VirtualHost vhost.other-domain.com>
AADefaultHatName HAT_other_domain_com
[...]
</VirtualHost>
will cause that mod_apparmor sets appropriate hat on per virtual host basis (as mentioned earlier we can use
AADefaultHatName in Location and Directory directives, too).
Now we need to sets policies for these new vhost hats, but first we will put common rules into single
abstraction/httpd-hat file that later will be used in HAT policies:
#include <abstractions/base>
capability setuid,
capability setgid,
/proc/[0-9]*/mounts r,
/proc/filesystems r,
/home/services/httpd/** r,
/var/log/httpd/** w,
/var/log/archive/httpd/* w,
/usr/lib{,64}/perl5/** r,
/usr/lib{,64}/perl5/**.so* mr,
/etc/mysql/mysql-client.conf r,
/etc/services r,
/etc/protocols r,
/etc/nsswitch.conf r,
/etc/hosts r,
/etc/host.conf r,
/etc/resolv.conf r,
/etc/mtab r,
/etc/fstab r,
/etc/xml/* r,
/etc/fonts/** r,
/usr/share/** r,
/var/cache/fontconfig/* r,
/var/run/php r,
/var/run/php/** rw,
/var/run/nscd/socket rw,
/tmp r,
/tmp/** rwl,
/bin/* ixr,
/usr/bin/* ixr,
/usr/lib{,64}/lib*.so* mr,
/usr/X11R6/lib{,64}/lib*.so* mr,
/usr/lib{,64}/ImageMagick-** r,
/usr/lib{,64}/ImageMagick-**.so* mr,
and finally HAT policies in abstractions/httpd-users:
^HAT_domain_org {
#include <abstractions/httpd-hat>
/home/users/web-pages/domain_org rw,
/home/users/web-pages/domain_org/** rw,
/home/users/web-pages/domain_org/cgi-bin/** ixrw,
}
^HAT_other_domain_com {
#include <abstractions/httpd-hat>
/home/users/web-pages/other_domain_com rw,
/home/users/web-pages/other_domain_com/** rw,
/home/users/web-pages/other_domain_com/cgi-bin/** ixrw,
}
That’s all. We load policy using rcapparmor init script (/etc/rc.d/init.d/apparmor in PLD/Linux). We can put
profile into complain mode (everything is logged but no restriction is in effect) or in enforce mode (apparmor
will enforce profile and log rejects). Example /var/log/audit/audit.log:
type=UNKNOWN[1500] msg=audit(1166014976.862:130983): REJECTING r access
to /var/cache/fontconfig/2ee5dd3f6641dbe23533346fa3fce51a-x86-64.cache-2
(convert(13663) pro
file /usr/sbin/httpd.prefork active HAT_domain_org)
type=UNKNOWN[1500] msg=audit(1166015781.907:130984): REJECTING r access
to /etc/fonts/conf.avail/20-fix-globaladvance.conf (convert(17219) profile /usr/sbin/httpd.p
refork active HAT_domain_org)
type=UNKNOWN[1500] msg=audit(1166015781.907:130985): REJECTING r access
to /etc/fonts/conf.avail/20-lohit-gujarati.conf (convert(17219) profile /usr/sbin/httpd.pref
ork active HAT_domain_org)
[...]
type=UNKNOWN[1500] msg=audit(1166016116.536:131037): REJECTING r access
to /var/cache/fontconfig/2ee5dd3f6641dbe23533346fa3fce51a-x86-64.cache-2
(convert(17596) pro
file /usr/sbin/httpd.prefork active HAT_other_domain_com)
type=UNKNOWN[1500] msg=audit(1166016139.393:131038): REJECTING r access
to /var/tmp (httpd.prefork(7442) profile /usr/sbin/httpd.prefork active
HAT_other_domain_com)
type=UNKNOWN[1500] msg=audit(1166016139.405:131039): REJECTING r access
to /var/tmp (httpd.prefork(7442) profile /usr/sbin/httpd.prefork active
HAT_other_domain_com)
type=UNKNOWN[1500] msg=audit(1166016139.429:131040): REJECTING r access
to /var/tmp (httpd.prefork(7442) profile /usr/sbin/httpd.prefork active
HAT_other_domain_com)
This log file is very usefull when creating policy (of course apparmor provides some tools that will create
policy for you by parsing log file but I was doing everything manually with vim in one hand and tail in
second).
Note that .htaccess checking is done at HANDLING_UNTRUSTED_INPUT level, before vhost HAT is
applied.
ps. you will probably need to pass capability.disable=1 selinux=off when booting kernel. Otherwise apparmor
won’t even load.