[apparmor] IPC syntax - again

Seth Arnold seth.arnold at canonical.com
Fri Jul 5 23:27:44 UTC 2013


On Sun, Jun 30, 2013 at 03:07:38AM -0700, John Johansen wrote:
> > You've very nearly convinced me that for the various forms of on-machine
> > IPC pairing does not make a lot of sense and the automatic label mechanism
> > is a better fit.
> > 
> Ha! I haven't convinced my self. That is I know we can do mediation based
> off of treating it as a shared object, but at a cost of throwing away
> some semantic information.

Yes, some information is thrown away, but the use of label=<foo> more or
less covers the local IPC cases I can think of. In fact, label=<foo> feels
like a better fit for where I would have wanted pairing anyway.

> > But TCP and UDP feels like one place where we cannot compromise
> > pairing. Many services offer vastly dissimilar services on different
> > ports, even if one event loop in one profile handles all the sockets:
> > 
> > - Python Twisted makes it easy to set up a 'manhole' shell in a service
> >   with full code-execution privileges; this is different from the services
> >   it might offer to clients that wouldn't be wide-open code execution.
> > 
> >     network inet tcp subject { address=192.168.122.1 port=1337 }
> >         peer { address=192.168.122.1/24 },
> 
> okay, but do we want to only accept connections from 192.168.122.1/24 to
> 192.168.122.1:1337 or would it be acceptable for communications from
> 192.168.122.1/24 on port 2000, if or service had a port open @ 2000.
> 
> That is security wise is it important to tie communications from
> 192.168.122.1/24 to the or services port of 1337

In all these examples, the security of the system is somewhat improved
by the pairing. I left out the thousands of applications where it
wouldn't really matter. :)

There are already multiple places that these pairings can be enforced:
- in the application
- in border firewalls
- in a local firewall

Border firewalls aren't always available or may be under someone else's
administrative control.

Local firewalls are often configured to be very permissive -- or at
least very simplistic.

So, that leaves just the application. Obviously, an application that
uses source or destination or both as parts of access controls needs to
be carefully programmed in the first place, but AppArmor can provide a
useful additional check on proper configuration and working.

Some applications may not make it easy to restrict access to
administrative or higher-privileged ports to only certain subnets.
AppArmor could especially help these applications.

Application flaws may allow an 'untrusted client' to perform 'trusted
administrator' actions regardless of which listening socket it connects
to, or which addresses it connects from. (These flaws would be easier to
mitigate against if the program runs in multiple processes with different
profiles, but that's outside of our control a bit.)

> >     network inet tcp subject { address=0.0.0.0 port=80 }
> >         peer { address=0.0.0.0 },
> > 
> > - Erlang connects nodes in a cluster over a socket that gives full
> >   code-execution privileges, again separate from the services the Erlang
> >   programs would offer to clients.
> > 
> ugh please don't tell me they are doing this on anything that isn't ipsec
> or at least if they are not is there security value in the peer address
> that is provided?

At least the Erlang documentation is quite clear that this functionality
should only be used with e.g. stunnel or on completely trusted LANs. I
don't know how carefully users follow this advice.

So you can see my interest in restricting access to _this_ port on an
Erlang VM to only other trusted hosts.

> >     network inet tcp subject { port=4369 } peer { address=10.0.0.0/8 },
> >     network inet tcp subject { port=465 },
> > 
> > - Administrators may configure web servers to provide different
> >   privileges for data or control structures, and want to restrict access
> >   to the more-privileged interface to a subset of network-connected
> >   machines.
> > 
> okay, is MAC policy the correct place to do this?

Well, that's the thing. There are other places to do this, but AppArmor
may be the most convenient place to put the belt-and-suspenders.

Firewall policies apply host-wide and aren't targetted to the specific
applications running on the system. Doing meaningful mediation at the
firewall for one specific application may require a policy that is too
strict for the host as a whole.

> > Can we instead treat tcp and udp (and sctp and ..) as labeled shared
> > objects, just like everything else you've proposed, but with the caveat
> > that userspace is responsible for putting together the labels?
> > 
> err userspace? As in iptable rules? Yes as a first pass. Do we want to
> split policy out in such a way? NO!

Well, that's part of it -- I don't see how we can simultaneously
provide pairing in the network rules _and_ allow users to write
their own arbitrary secmark rules. If we're going to keep the policy
entirely in AppArmor profiles, then I don't see any way to let users
hand-write secmark rules. Getting the entirely-automated approach is a
huge undertaking.

I think we can provide _good_ security improvements for most network
applications without secmark. Implementing this should be a fraction of
the effort -- and I think distributions can reasonably ship profiles
with these simpler rules enabled by default.

I think the cases when secmark can add to the overall security of the
system is fairly rare -- and site-specific.

> So be careful here part of the problem and why we need to deal with things
> at the kernel level is that we don't want to just out right reject things
> post accept. We need to be able to determine whether a connection can
> be accepted at the interrupt level without a task context.

That's right, that's the complicating factor. :/ Thanks.

> Interestingly enough, using compound labels we can do this without needing
> to use the secmark. That doesn't mean we want want to use it just that
> we can do certain things that previously we would have needed a full
> policy compile for.
> 
> I think the connsecmark in particular might still be very useful for things
> like ftp. Btw please provide some nice examples of how you see policy
> working with ftp, since its such a fun protocol to deal with.

Ugh. I ignored FTP because it's such a horrid old busted protocol. (Not
everything old was done well. Sometimes we had to learn from the mistakes
of the past. :)

One very useful AppArmor profile for FTP would prevent FTP "bounce"
scanning:

profile ftpd {
  network inet stream (bind, listen, accept) subject=(port=21),
  network inet stream (bind, listen, accept) subject=(port=20),
  network inet stream (connect),
  # deny access to internal hosts
  deny network inet stream (connect) peer=(address4=192.168.0.0/16),
  deny network inet6 stream (connect) peer=(address6=fe80::/64),
  deny network inet6 stream (connect) peer=(address6=2001:db8::/32),
}

> Again if/when we use secmark manually setting labeling will become possible.
> However I do not want to encourage it as a default behavior. When it comes
> to implementation vs. policy management complexity I will almost always
> choose implementation complexity so our users don't have to deal with it.
> 
> Policy is already too hard

Understood, and very nearly agreed. :) But I might be willing to
compromise on features if we can keep both policy and implementation
simple as a result.

> > We don't have to use ufw -- standard iptables --selctx can also work --
> > but ufw is easier for me to understand. ufw can also provide a
> > convenient location for name <-> number mappings, or perhaps a
> > convenient interface for managing the mappings.
> > 
> Look I like ufw, but as an upstream project we need to look at the
> solution that is widely applicable to the distributions that ship apparmor
> so iptables seems the better target from that perspective. I am not saying
> don't support ufw just that iptables would need to be supported.

Completely agreed here. It's just that ufw's syntax is so much nicer. :)

> > This also gives us a possibility for a staged deployment: we can get the
> > "simple" stuff done first -- the bind, listen, accept, connect, sendmsg?,
> > recvmsg?, that can be decided simply from the contents of a profile -- 
> > 
> Staged deployment has always been planned. We just can't get everything
> done in the time frame we have. We are just trying to plan to make sure
> what we do ship is consistent with where we are going

Well, then, how about bind, listen, connect, sendmsg, and recvmsg? :)
Push off 'accept' until later...

Thanks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20130705/2ed6012b/attachment.pgp>


More information about the AppArmor mailing list