No subject


Sat Apr 5 03:57:03 MDT 2008


that planned AppArmor network model is at least partially leaning to
the direction of examining each packet and verifying whether the
packet originator or receiver has a right to this packet?

To me this seems to be totally different model than AppArmor uses for
file access: AppArmor verifies the access rights on file operations
relating to opening and manipulating complete files as objects. It
does not concern itself with each individual write or read operation,
it relies on the kernel to work correctly after access bits have been
set for it.

AppArmor on network operations could follow the same model:
concentrate on protecting the socket opening and binding processes,
and (in most cases) don't worry about individual packets. Assume the
kernel does its job correct.

All network connects can be checked (and denied if needed) on socket
connect. The destination address is known and kernel does not allow it
to be changed for that socket (right?).

However, I'm not yet familiar enough with Linux networking, to know
whether LSM networking hooks are in such place that the actual target
interface is already known for the hook, thus the following rule may
prove problematic, if information is not available

  tcp_connect to 10.0.0.17/16:50-100 via eth1,

The server sockets just need to be checked on bind time (in
general). I would expect most common profile requirement for the
servers would be simply stating what ports the server can listen, like
for a generic web server

  tcp_accept to 0/0:80,

I'm not quite sure to what "from" and "to" refer -- the confusion
comes whether looking at incoming or outgoing packet -- for that
reason, at least some implementations of IPSEC policies normally use
terminology "local" (address/port) and "remote" (address/port), which
maker rules same and clear for incoming and outgoing packets. I would
write above rule as

      tcp_accept local 0/0:80,

Anyway, this would just verify on bind time that the local port is
80. Things do get trickier, if you need to limit the service to
specific interface. The following already does rather good

  tcp_accept local 10.0.0.17/32:80

because it would only accept connects to a specific configured
address. To keep all checking in bind time, this rule would require
that application actually binds to specific address and bind would be
denied otherwise (other option, which I'm not too sure about, would be
for AppArmor hook implicitly do the specific binding, if application
left it open, but deny operation if any other address is used).

Outgoing unconnected sockets (datagrams) do pose a problem. There is
not much to check at bind time (except the source port). If there are
limitations for outgoing packets, each send operation needs to be
checked for destination.

Concerning outgoing packets (or remote addresses or ports) in general,
I don't see actual address ranges very important here. Use of address
ranges probably is just indirect way of controlling what users really
want have a say: is this application allowed to talk a) only on
loopback, b) some local network or c) to internet.

There are two basic reasons why such limits might be desired by the
user:

  1) information security (e.g. I want my web server only be
     accessible to local network, or I only want this application to
     talk locally, and not "call home" :-)

  2) communication cost. Use of some links actually cost money to the
     user and they don't want some random application to generate huge
     bill to them (for example, internet connection could be via
     expensive GPRS connection).

One could try to say, that a rule like

  tcp_connect to 10.0.0.17/16:50-100 via eth1,

could satisfy the requirement. But, I think there might be problems,
with mobile devices, eth1 could at one place be just local lan or
wireless and free, but at other times incur cost. Interface names may
not always be the best. How do make a generic profile to for a
specific application? Interface names can vary from host to host!

Solving the problem might need changes to linux device driver
API. There could be some way of asking the driver for some cost/access
tag name, which could be used instead of interface name (or use sysfs
/ udev in some ingenious way).

What I would like to express, is a rule:

  tcp_connect to anywhere via "no-cost-interface"

or allow costly connect, but limit the bytes, time etc.




More information about the Apparmor-dev mailing list