[apparmor] default profile
John Johansen
john.johansen at canonical.com
Fri May 10 20:48:39 UTC 2013
On 05/10/2013 01:04 PM, Jamie Strandboge wrote:
> On 05/10/2013 01:24 PM, John Johansen wrote:
>> So with apparmor 3.0 we pickup a default profile that can be used to confine
>> init, without having to load policy in the initrd and then re-exec init
>>
> Cool! :)
>
>> how this works is the default profile starts in the unconfined mode and init
>> in early boot is unconfined. Once the default profile is replaced
>> everything in the default profile picks up the new confinement.
>>
>> to replace the default profile you define a new
>>
>> profile default {
>> ..
>> }
>>
>> and load it, or if you want it to have default attachment
>>
>> profile default /** {
>> ...
>> }
>>
>
> I don't understand the difference between these, can you explain? (The
> source of my not understanding is that unconfined seems to already have
> attachment to everything, and so if we setup the default profile, to me,
> that implies everything attaches to it).
>
sorry the difference is subtle. The unconfined profile is the equiv of
profile unconfined {
/** pix,
file, capability, ...
}
that is any task with unconfined attached will search for a matching
profile and if one is not found, inherit unconfined.
specifying an attachment rule is different in that it influences the
profile search.
profile unconfined /** {
/** pix,
}
would not behave any different than unconfined
however other profiles loaded with the unconfined /** profile will
behave different
eg. given
profile A {
/usr/* px,
/bin/* pix,
}
the behavior would be
| unconfined | unconfined /** |
-----------|--------------------------------------------------------
/usr/* px | fail exec | exec to unconfined - profile match found |
/bin/* pix | inherit A | exec to unconfined - profile match found |
this same behavior is the difference between
profile default, and default /**
> ...
>
>> currently the override to select the default profile is
>> apparmor.unconfined=0 or N
>>
>> and to select unconfined
>> apparmor.unconfined=Y
>>
>> this option is fine but I'm not fond of apparmor.unconfined=0 We could
>> change this so that the apparmor= boot option could select the values, so
>> something like
>>
>> apparmor=unconfined
>>
>> apparmor=default
>>
>
> +1 :)
>
I'm fine with apparmor=unconfined, but not so happy with apparmor=default
other suggestion might be
apparmor=enforce
apparmor=confined
>>
>>
>> 2. default attachment
>>
>> currently specifying the attachment may not be what you want it means that
>> px will always find a profile. This is different behavior from what you
>> would get with unconfined.
>>
>> Instead a rule in the default profile can be used
>>
>> profile default {
>> /** pix,
>> }
>>
>> This will retain the current unconfined behavior of other profiles px and
>> pix failing/inheriting if a profile is not defined.
>>
>> Is this adequate? It certainly needs to be documented.
>>
>
> I think we want to define what we intend for the default profile to do.
> First off, I think if you setup a default profile you should be expected
> to know what you are doing. Second, I think the default profile should
yes
> provide a blank slate for people to use if they choose to. Third, we do
it does, its equivalent to
profile default (unconfined)
which means it behaves as unconfined until replaced. An admin can define
how they want the profile to look, and even replace it back to the
unconfined state by replacing the profile with
profile default (unconfined) { }
I guess I should mention unconfined is a state that is available to
any profile. There is nothing special about default besides the kernel
allocates and attaches it early
> need to make sure that we document things, like you said, so people
> understand what is happening.
>
yep
> To me, the default profile is one which wholly replaces what apparmor
> would normally do if booting with apparmor=unconfined. I also think
> that, if possible, the default profile should be able to be defined such
> that it the system will behave exactly like when booting with
> apparmor=confined. This would be useful for testing and also helps
> ensure a 'blank slate' is truly possible.
>
hrmm I'm not sure I follow you here. So here is a broad shot at some more
detail.
The policy author is free to define default however they want, including
complain mode or any other rule combinations, transitions etc that are
available to other profiles.
The author does need to define what goes in default if default is not in
the unconfined mode. We have the issue of not being able to define what
goes in default until it is replaced.
The default profile does make it possible to load the default profile in
the initrd without having to re-exec init, and have confinement apply.
But we can not define policy as part of the kernel boot parameters
because we are not putting the compiler in the kernel.
In general there should be some guidance to authors on how to use the
default profile, and what should/shouldn't go in it.
Eg. It would be a very bad idea to stick
/** px,
in the profile and load it without other profiles in the same atomic set.
> As such, if you define the default profile, everything will attach to it
> (just like everything attaches to unconfined when there are no other
> profiles defined on the system). It is then up to the policy writer to
> determine how transitions work. Since there are some subtleties here and
> we believe that there may be best practices surrounding the default
> profile, we might then say that it is best practice to have the default
> profile include this at minimum:
>
> profile default {
> ...
> /** pix,
> ...
> }
>
> since this will allow transitions to existing profiles on the system in
> the manner people are accustomed to.
>
yep
>>
>> 3. Profile/Namespace removal
>> Currently when a profile or namespace is removed it inherits the task
>> that where confined by the profile inherit the unconfined profile.
>>
>> If the default profile is selected should this be inherited instead of
>> the unconfined profile.
>>
> I did not understand the first sentence, but I think I understand the
thats because it was broken
> question. IMO, because the default profile wholly replaces
> apparmor=unconfined, it should be inherited.
>
yes that was the question and my inclination as well
>>
>> 4. ux
>>
>> there is no equivalent ux, pux for the default profile, and I would rather
>> avoid dx, and pdx
>>
>> Instead ux can be replaced with
>> /foo px -> default,
>>
>> but we have nothing to enable a fall back like pux
>> a glob rule like
>> /** px -> default,
>>
>> would come close as long as no other x rules used globbing and you
>> wanted the fallback to apply to all x rules (you usually don't)
>>
>> We need to fix the overlapping x rule problem (this is just compiler work),
>> ie.
>> /** px -> default,
>> /usr/* px,
>>
>> will currently fail to compile, but this still does not give use per rule
>> control of the fallback.
>>
>> Finally we could introduce the explicit fallback that steve suggested years
>> ago
>>
>> /usr/bin/* px -> @{\1}, default, inherit,
>>
>> (Note: syntax is just of the cuff and would need to be worked on)
>>
>>
>>
>> Now to ux, should that even work when the default profile is selected
>> or should we just fail it, as ux remains away to escape confinement
>> and the default profile?
>>
>
> I think that the transition to unconfined that ux represents should not
> be supported when the default profile is selected. 'u' stands for
> 'unconfined' and when the default profile is selected, there is nothing
> that is 'unconfined' (sure, things may be effectually unconfined, but
> that is different).
>
> I recognize this is a problem with usability though. Ie, if I already
> have a profile with [Uu]x in it and want to start using the default
> profile, what do we do? The profile is still correct syntactically and
> the parser shouldn't have to know if the default profile is in place. It
> seems like [Uu]x in a profile on a system with the default profile
> enabled should transparently allow transitions back to the default
> profile so things don't break, but even that gets weird because the
> default profile may have '/** pix,', so what does this actually mean?
>
yeah its a hard problem.
I am inclined to just leave the transition to ux as is at the moment,
though maybe we make it mean transition to default
I think just failing it could be problematic as it could result in odd
breakage.
We certainly should actively discourage its use
> profile default {
> /** pix,
> }
>
> /bin/foo {
> /bin/bar ux,
> }
>
> /bin/bar {}
>
right now it mean bin/bar when started from /bin/foo will be put in the
unconfined profile, and the unconfined profile behaves as it always does
> The profiler intended that /bin/bar go unconfined when executed by foo.
> Having the transition go to 'default' cause of the ux makes sense, but
> then default defines the attachment such that bar gets '/bin/bar {}' policy.
>
nope. The exec rule for the profile on the subject is applied so ux (if it
transitioned to default) would mean the exec went into the default profile
and subsequent execs would depend on the rules defined in the default profile
> As weird as it is, this seems correct to me. If 'profile default {}'
> didn't have the '/** pix,' rule there would be no problem. Maybe we can
as mentioned above it is not a problem because it does not apply to the
exec from /bin/foo
> document 'u' as another word when the default profile is in use.
> 'u'nspecified maybe?
>
this is possible, or just the default profile which is usually unconfined
> That said, I think this requires more exploration.
>
yes
>>
>> 5. Tooling
>>
>> Currently the userspace tooling does not work well with the default
>> profile or the unconfined mode. This needs to get updated. But the question
>> remains how aa-status et al should represent profiles in the unconfined
>> mode.
>>
>> should it report them as confined, unconfined, ...
>>
>
> Confined because there is a profile defined for them. Case in point,
> even now I can define this:
> /bin/foo {
> file,
> capability,
> network,
> mount,
> dbus,
> }
>
yes but then nothing is unconfined.
IF we wanted we could have multiple profiles in the unconfined state and
they could all be reported as a single unconfined. I'm not sure that is
best, just an option
> and aa-status will happily say it is confined. If the default profile is
> truly a blank slate, we can't guess what the policy is. aa-status knows
well its mode reports whether its unconfined or enforcing etc.
> the default policy is in place, so it can use this when apparmor=unconfined:
> ...
> 248 processes are unconfined but have a profile defined.
>
> and this when apparmor=default:
> ...
> 248 processes are using the default profile but have a profile defined.
>
Heh that looks funny, I'd rather just
248 processes are using the default profile
More information about the AppArmor
mailing list