<div dir="ltr"><div>Thank you John for your very extensive and clear answer and explanation! I had to read it twice to really get it, but now I see :). I find AppArmor really interesting and also simple to use.<br></div><div><br></div><div>I will continue to explore AppArmor as I intend to use it on my servers and my work computer. I find it funny that this technology seems so helpful and I or my colleagues weren't even really aware of it.<br></div><div>I will  also try to integrate it into a programming language I am working on (<a href="http://ryelang.blogspot.com">ryelang.blogspot.com</a>) as I think all serious apps of the future will have to be well integrated with something like apparmor.</div><div>(I intend to make Rye so that it can also only evaluate source files signed with specific ed25519 keys, but I have to make the Rye binary irreplaceable then, it seems AA could also help me with that)<br><br></div><div>Thanks again!</div><div>Janko<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Nov 16, 2022 at 9:31 PM John Johansen <<a href="mailto:john.johansen@canonical.com">john.johansen@canonical.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 11/16/22 11:59, janko metelko wrote:<br>
> Thank you for making AppArmor, if any of the developers are here. I am not a security guy, but such a solution seems like it should or will become an absolute must-use for any application deployment, locally or on a server.<br>
> <br>
> I have a question. I want to make a profile that prevents execution of any file from user-writable directories like /home /tmp, *except* if the executable has a AA profile.<br>
> <br>
> This would effectively mean that the user (or user level process) can't (knowingly or unknowingly) "install" and run anything that wasn't "confirmed" by root.<br>
> <br>
> It seems I can do this by creating an empty profile for /home/** which denies everything and then creating separate AA profiles for specific executable files inside /home that I allow to run.<br>
> <br>
> If I understand it right, all executables in /home without profiles will in this case crash or at least can't do any side effects since they are blocked from all IO/shared libs/configs/etc. In practice, they will probably just crash. It would be much nicer experience if such apps would be prevented to run, not start and crash.<br>
> <br>
> But I can only find directives in AA, that limit or allow certain resorces to the executable, and no directive, that would prevent executable to be ran in the first place.<br>
> <br>
> Is there any such solution? Am I maybe looking at it all wrong? Should I do this on another level, not with AppArmor?<br>
> <br>
> *Example*<br>
> <br>
> Maybe stupid example, but still. Let's say I want to prevent non-root users or RCEs from wget-ing into any other directory other than /tmp. I can simply create a profile for /usr/bin/wget { ... /tmp w, } and the job is done. But user/RCE can then simply do cp /usr/bin/wget ~/mywget and use wget for whatever it wants. If we prevent execution of non-profiled executables in user writable directories then he/it can't do that and our primary objective stands.<br>
> <br>
> I hope it makes some sense ... Thank you again. Ubuntu rocks also, and Xubuntu! :)<br>
> <br>
<br>
So lets split this into two cases.<br>
1. Executing an application when confined<br>
2. Executing an application when unconfined<br>
<br>
there are some differences so it is worth covering<br>
<br>
1. Executing an application when confined<br>
<br>
When an application is confined all execs are covered by the profiles domain transition rules. Those rules require a qualifier to determine what should be done at exec.<br>
ix - inherit<br>
px - transition to a profile if it exists, otherwise FAIL the exec<br>
cx - transition to a child profile if it exists, otherwise FAIL the exec<br>
ux - transition to unconfined<br>
<br>
there are currently a set of fallback options available instead of failing the exec<br>
pix, cix - transition to profile if it exists, otherwise inherit current confinement<br>
pux, cux - transition to profile if it exists, otherwise transition to unconfined.<br>
<br>
you can also explicitly deny an exec with a deny rule<br>
<br>
   deny x /tmp/*,  # no need for a qualifier on deny rules<br>
<br>
<br>
So in this case there are a few ways to deny at exec time instead of crashing<br>
<br>
<br>
2. Executing an application when unconfined<br>
<br>
This case is the currently problematic one. Where unconfined tasks essentially use an exec rule of<br>
<br>
   pix /**,<br>
<br>
meaning no exec will fail, it will either transition to a defined profile or allow the exec to continue as unconfined.<br>
<br>
Currently the only way to deal with this is indeed create a "trap" profile that doesn't grant permissions, causing the application to fault after exec<br>
<br>
profile trap /tmp/** {<br>
   # no permissions.<br>
}<br>
<br>
<br>
Obviously this is less than satisfactory. Ideally to avoid this you would be in situation #1, but the reality is that this just isn't how apparmor has been deployed and not all user tasks are confined.<br>
<br>
<br>
There is work going on to fix this, but it has not landed as of upstream kernel 6.1 or Ubuntu 22.10. When it lands (hopefully 23.04) you will be able to specify attachments that should be denied. Instead of having to create a trap profile. It will be a rule similar to what is in the profile.<br>
<br>
   deny x /tmp/**,<br>
<br>
and will have the longest left match prioritization, that attachments currently have. That is<br>
<br>
   deny x /**,<br>
<br>
would stop execution of anything that didn't have a profile defined. But since<br>
   profile example /bin/foo { }<br>
<br>
has a more specific attachment match it would take priority and allow exec under that profile.<br>
<br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature"><br><div>Janko Metelko</div><div><br></div><div>Refaktor Labs, InvoiceFox, Cebelca.biz, UsrJoy ..</div></div>