On Tue, Aug 04, 2020 at 10:46:46PM -0400, Murali Selvaraj wrote:
> Goal: Converting root process to non-root process by enabling required
> capabilities for the process.
> [...]
> Process (A) will be running in "non-root" but with all enabled capabilities
> and check the apparmor logs.
> Apparmor logs will show the required capabilities.

Yes, this should work fine. There's several ways I can think of to do
this:

- Run the program as root (it sounds like it already runs as root and
  you're converting it) and keep track of AppArmor DENIED or ALLOWED
  entries.

- Run the program via a systemd unit file and add capabilities to the
  program via the AmbientCapabilities= directive. If you know nothing
  about your application or how it works, you could add them all, and
  once you've learned what it requires, trim the list appropriately.

- Run the program via an executable with fscaps and set all the
  capabilities on the file.

If you already know something about the program, you could skip the
capabilities that it will obviously never use.

> In any event, AppArmor will usually see capability requests after the usual
> DAC permissions are handled.
> 
> Can you please explain this above statement with simple example?
> 
> For example, Process (x) tries to open a file (/etc/security) which is root
> permission but the process (x) runs in "non-root mode.
> Pls note, process (x) does not have permission to open this file
> ((/etc/security) )
> 
> open => sys_open() => kernel further code for handing the code.
> 
> sys_open() => will return permission denied error due to permission issue.
> 
> Here, capable() check won't happen. Does DAC take care of this check
> without using capability (CAP_DAC_READ_SEARCH)?
> 
> In such a case, trying to understand when Kernel uses capable() to check
> CAP_DAC_READ_SEARCH/CAP_DAC_OVERRIDE before/after DAC.
> Can you please explain the relation between DAC, apparmor and linux
> capability with this context?

CAP_DAC_READ_SEARCH will only be used if you've changed the permissions on
/etc to forbid owner, group, or world read or execute permissions,
depending upon the owner and group of the file, and fsuid and groups of
the process.

CAP_DAC_OVERRIDE will only be used if /etc/security owner, group, or
world, permissions don't allow the operation to the process's fsuid and
groups.

Unix permissions are flexible -- and indeed, it is their flexiblity that
provides motivation for mandatory access control systems like AppArmor.
Your program may or may not need either of these capabilities, even if it
works with files owned by other users, because the permissions on those
files may also be set to allow your program to use them.

If you're writing an application from scratch it is probably worth taking
some time to decompose your application into smaller pieces determining
the flow of data through your application, and trying to use Unix users
and groups to do what you can to use the Unix permissions model to
enforce the right flow of data.

For example, the qmail suite of programs run with several users and a
strict dataflow through the program. The author, djb, said a dozen years
after writing qmail that he thinks this did not actually contribute to
qmail's better-than-average security record, but I disagree: This approach
also forced a clear understanding of responsibilities, data flows, etc.
(To be clear, I think djb could just as well write a secure qmail without
this restriction, but djb's skills are unique.)

Of course not all applications lend themselves to this kind of
decomposition.

If you are developing an application from scratch rather than porting
an existing application, aim for *no* capabilities. Try to replace every
capability with something else. If you need CAP_NET_BIND_SERVICE to bind
to a low TCP or UDP port, you could use systemd's socket activation
instead. That's two or three extra lines in systemd configuration and
no chance for introducing privilege dropping bugs.

The usual "classic Unix daemon" quite often just needs CAP_NET_BIND_SERVICE,
CAP_SETGID, and CAP_SETUID -- and the latter two, only to drop the
privileges that were required for the initial bind(2) call. systemd socket
activation and User=, Group=, etc directives means this can be done
completely outside of your own application and your application can run
without privileges at all.

AppArmor is a useful tool but standard tools and careful design work may
be able to reduce the amount of privileges an application needs in the
first place.

Thanks

Attachment: signature.asc
Description: PGP signature

-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to