On 07/05/2013 04:27 PM, Seth Arnold wrote: > 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. > I assume you mean the object/message/peer labeling as the local/subject labeling is already implied by the rule being in a profile
>>> 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. :) > sure > 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. > yeah > Local firewalls are often configured to be very permissive -- or at > least very simplistic. > yep > 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. > yes, network rules in the profile are basically an application fw > 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. > yes > 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.) > sure, but at the cost of potentially having conflicting security and application policy configuration. Its potential complexity but it doesn't mean we don't allow for it >>> 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. > hahaha, like they know > So you can see my interest in restricting access to _this_ port on an > Erlang VM to only other trusted hosts. > sure >>> 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. > right, I tend to like to be able to specify things at the natural layer. If I am trying to control the behavior of an app I want to specify restriction for that app. If I am trying to control ports at the machine level I would look at the firewall. I do find it unfortunate that they are so separated but ... >>> 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. > Alright let me reiterate, secmark carries the label on the packet. So what the user is doing is sticking a label on the packet. Our implicit labeling derives a "label" from addresses for things that are unlabeled. So what setting up iptable rules would do is provide an explicit labeling for an object just as setting an explicit label on a file would. It could very well result in the packet being rejected if the labeling on the socket that did not allow for that labeling. > 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. > sure, again secmark does not necessarily mean iptables > I think the cases when secmark can add to the overall security of the > system is fairly rare -- and site-specific. > hrmmm maybe >> 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. > Not really that is part of the whole stacking/compound label design. The socket acts as a proxy for the set of tasks that could accept the packet. Since it could be delivered to any of them (its a race on the socket), it must be able to be accepted by all of them. Its just like the stack on a task for accessing a file. >> 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. :) > heh, make that most of the past wasn't done well on the first pass. > 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), > } > Haha, again! Where are we going to stick those pesky permission So this will work with active ftp but not passive. Nor does it provide a binding between the connect and the peer that did the initial connection Do I have a good suggested syntax for doing those things? Not yet just saying this really isn't sufficient for ftp, at least in passive mode as we need to be able to accept a connection on N > 1024 from the host that made the initial connection to port 21. Some thing along the lines of (and no I am not proposing doing this) network inet stream (bind, list, accept) subject=(port=20) { network inet stream (bind, list, accept) peer=(address=@{peeraddress} port=@{peerport}+1) network inet stream (connect) peer=(address=@{peeraddress} port=@{peerport}+1) } yes tcp is an awful protocol, but that is one reason its interesting to look at. Is doing this with in the apparmor policy the correct place to do stuff like this? I'm inclined to say no when we have the conntracker that already has rules for dealing with ftp's weirdness. And we could get away with something like network inet stream label=ftp_t connected, or some such. >> 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. > heh, well time will tell, the first pass won't be using anything from secmark (I don't think). >>> 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. :) > sure >>> 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... > bad sarnold we could be asking whether bind and accept could be implicit perms. We could get away with that if you only specified the network addresses in the profile that can bind to it. And delegate the sockets profile A { delegate to B { network inet address=127.0.0.1:80, } } profile B { allow delegation from A, } or what ever -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor