[apparmor] AppArmor and virtual hosts in Apache

John Johansen john.johansen at canonical.com
Tue May 2 09:26:36 UTC 2017


On 05/02/2017 01:58 AM, Lentes, Bernd wrote:
> 
> 
> ----- On Apr 29, 2017, at 3:02 AM, Seth Arnold seth.arnold at canonical.com wrote:
> 
>> On Wed, Apr 26, 2017 at 08:26:10PM +0200, Lentes, Bernd wrote:
> 
>>
>> Hello Bernd, welcome. mod_apparmor for Apache doesn't care about name vs
>> ip hosting. However, mod_apparmor can't run the other vhosts in the Apache
>> process "unconfined" -- if you're going to confine any of it, you're going
>> to confine all of it. The idea with mod_apparmor is that you could be
>> broad with some applications and tight with others.
>>
> 
> Why not ? I can provide for each vhost a uniques subprofile.
> So the level of confinement for each can be different. Am i wrong ?

Not wrong, you can have unique subprofiles each with their own
confinement.  What Seth is specifically referring to is can't switch
to the unconfined state. You can have a subprofile that allows
everything and is virtually the same as unconfined but is not exactly
what the special profile state that the term unconfined is usually
used for in apparmor

> Or do you mean that, if i create a subprofile for a dedicated vhost the apache (the "parent" profile) needs to run in
> confined mode and that this confined mode is valid for all vhosts ?

no

> Does the subprofile for one vhost influence other vhosts ?

it shouldn't. There are caveats around userspace, which the kernel
module can't enforce unless task state is cleared out.

Eg. a process mapping memory, and then doing change_hat, the mapped
memory would still be available on the other side. Or potentially to
another vhost.

Applications that use change_hat are responsible to ensure they are
doing what needs to be done in this area to make sure their use of
change_hat is safe, as basically they are reusing a process to avoid
the overhead of letting the kernel do a full flush.

Generally this should be safe with apache, and mod_apparmor but you
certainly could construct something that unsafely leaks some of the
uncleared state between change_hats and thread/process reuse.


> Is it possible to run apache unconfined but the subprofile for a hat confined ?
> 

Not at this time. change_hat requires a parent profile and a set of
subprofiles that are defined as hats. Hats are really just subprofiles
that have the hat flag set so that they can be used by the change_hat
api.

Witht that said the parent profile can allow everything, being
basically unconfined. Just not the special unconfined state.

I do have an api extension that will allow a change_and_return (name?)
api that would work with unconfined. But that is not available in any
released version of apparmor at this time.

>>> I have a SLES 10 SP4 box.
>>>
>>> I installed apparmor and the module for apache. The module is enabled. I
>>> added the following to the conf-file of the vhost:
>>>
>>> AADefaultHatName genetrap
>>>
>>> To /etc/apparmor.d/usr.sbin.httpd2-prefork i added the following:
>>>
>>> /usr/sbin/httpd2-prefork//genetrap flags=(complain) {
>>>     #include <abstractions/base>
>>>     #include <abstractions/nameservice>
>>> }
>>> It seems this is the suse way, i also saw subprofiles definitions
>>> beginning with an ^ and afterwards just the name of the hat.  Is both
>>> correct ?
>>
>> This is sorely under-documented but I believe the hats must be named with
>> '^' or 'hat' in the files, whether it is of the format:
>>
>> /outer/profile/name^hatname { }
>>
>> or of the format:
>>
>> /outer/profile/name {
>> ...
>> ^hatname { }
>> ...
>> }
>>
>> The // is usually reserved for child profiles and i'm not sure of the
>> consequences of mixing the two formats.
>>
>>
>>> Restarts of apache and apparmor don't complain.
>>>
>>> Having a look in /var/log/audit/audit.log shows lines like:
>>> type=APPARMOR_ALLOWED msg=audit(1493230551.040:17953):  type=1502
>>> operation="inode_permission" requested_mask="r" denied_mask="r"
>>> name="/usr/share/apache2/error/include/top.html" pid=3405
>>> profile="/usr/sbin/httpd2-prefork//genetrap"
>>>
>>> Does that mean that the profile is running fine ?
>>
>> This certainly gives the impression that it's working correctly. Maybe I'm
>> wrong.
>>
>>> Is the procedure i did correct ?
>>> aa-status does not show the subprofile:
>>>
>>> pc52842:~ # aa-status
>>> apparmor module is loaded.
>>> 11 profiles are loaded.
>>> 10 profiles are in enforce mode.
>>>    /usr/sbin/ntpd
>>>    /usr/sbin/identd
>>>    /sbin/klogd
>>>    /sbin/syslogd
>>>    /sbin/syslog-ng
>>>    /usr/sbin/traceroute
>>>    /usr/sbin/nscd
>>>    /bin/ping
>>>    /usr/sbin/mdnsd
>>>    /usr/sbin/named
>>> 1 profiles are in complain mode.
>>>    /usr/sbin/httpd2-prefork
>>> 15 processes have profiles defined.
>>> 3 processes are in enforce mode :
>>>    /sbin/syslog-ng (3084)
>>>    /usr/sbin/nscd (3762)
>>>    /sbin/klogd (3087)
>>> 12 processes are in complain mode.
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3410)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3408)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3030)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3407)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3032)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3031)
>>>    /usr/sbin/httpd2-prefork (3028)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (11334)
>>>    /usr/sbin/httpd2-prefork (3027)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3029)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3409)
>>>    /usr/sbin/httpd2-prefork^HANDLING_UNTRUSTED_INPUT (3405)
>>> 0 processes are unconfined but have a profile defined.
>>>
>>> Is that correct ? Is it possible now to have the vhost running for a
>>> certain time in complain mode and then use logprof to create a profile
>>> just for this one vhost ?
>>
>> Ideally yes but this is tricky -- complain mode causes every
>> aa_change_hat() to every hat name, known or not, to succeed. This case
>> make it more annoying than it should be to use the automatic learning
>> tools in complain mode when the application 'probes' multiple hat names,
>> as it prevents second or third names in the list from being useful.
>>
> 
> I realized that. I tried to generate a profile using logrpof, and apparmor wants to create a lot
> of hats, which i don't want. Why is apparmor doing that ? It's annoying.
> Is there  a way to prevent apparmor from doing that ?
> 

Hat learning is Just annoying and there isn't a great way to fix
this. Basically change_hat works by providing a list of possible
targets in order of priority.  However when you are in learning mode,
which of those should match? Perhaps you have a low priority catch all
generic hat defined but you really want a custom profile for the
vhost. If apparmor assigns the transition to the generic hat all the
information for that vhost gets folded into that profile. Making it
hard to separate back out.

So what apparmor does is check if the highest priority transition
exists, if it does that transition is done, otherwise a custom
learning profile is created and that transition is made, ensure no
information is lost. That custom learning hat can be used to create a
custom profile, or all the information gathered can be folded back
into an existing profile after the fact.

There are a couple of things that could be done to help. An
interactive learning mode could make the decision at request time, at
the cost of blocking until ready. We could also allow adding some
rules that would provide patterns for what kind of requests should map
to which profiles, or if they should create a new custom learning
profile.





More information about the AppArmor mailing list