Hi all, i made some SMACK related patches. I hope this list is the right place to post them. The intention behind this patch is that i needed a way to (firewall) match for packets originating from specific processes. The existing owner match did not work well enough, especially since the cmd-owner part is removed. Then i thought about a way to tag processes and somehow match this tag in the firewall. I recalled that SELinux can do this (SECMARK) but SELinux would have been way to complex for what i want. But the idea was born, i just needed something more simple. SMACK seemed to be the right way. So i made a little primitive netfilter match to match against the security context of sockets. SMACK does CIPSO labels, but this was not what i wanted, i wanted to label the socket not the packet (on the wire). This of course only works for packets with a local socket, but this was my intention anyway. This way i can label a process and all it's sockets carry the same label which i then can use to match against in the firewall. The code is pretty much based on cargo cult coding from other netfilter matches, especially the owner match (which turned out to be a bad reference since it is crapped with tons of compat interfaces). I have no kernel coding experience whatsoever and little C coding history. So i would really like you guys to look over it a bit. Originally i intended to put this mask in the xtables_match structure. .hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN) But it turned out that i then could not longer put the rule in a chain which is called by the OUTPUT chain but only in OUTPUT directly. I did not investigate much more since i did not really understand this part. Allowing the user to add this match wherever he wants to does not hurt, if there is no local socket there is no matching. But maybe this is something that should be changed. About the Files: SMACK-netfilter-socket-label-match.patch is a git patch for the current ...
Most Smack development has taken place on the LSM mailing list. At the
very least I would recommend you CC the LSM list when sending Smack
patches. I've taken the liberty of CC'ing both the LSM list and Casey
It appears the simplest option would be to provide the necessary SECMARK
support in Smack. SECMARK has provisions for supporting different
types of LSMs and adding Smack support should be relatively trivial.
In fact, it is possible for SECMARK to be made entirely LSM agnostic
and have it deal strictly with secctx/label and secid/token values. We
would need to retain the SELinux specific interface for
legacy/compatibility reasons but I would encourage new patches to take
I would encourage you to look at selinux_ip_postroute() since it does
exactly what you describe above using the SECMARK mechanism (in
addition to other work). In particular look at the following code
snippet:
sk = skb->sk;
if (sk) {
struct sk_security_struct *sksec = sk->sk_security;
peer_sid = sksec->sid;
secmark_perm = PACKET__SEND;
} else {
if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
return NF_DROP;
secmark_perm = PACKET__FORWARD_OUT;
}
if (secmark_active)
if (avc_has_perm(peer_sid, skb->secmark,
SECCLASS_PACKET, secmark_perm, &ad))
return NF_DROP;
In the first if block you see that we are actually getting the security
label from the socket, _not_ the packet, and then using that to perform
the access control decision with avc_has_perm(). It should be easy to
do the same with Smack and SECMARK.
[NOTE: you may notice the above code changing slightly in future
kernels, it turns out that skb->sk == NULL is not a true indicator of a
non-local sender, see my labeled networking patches for 2.6.28 or
You could also expand it to handle ...Sounds like a good idea. When i looked at the SECMARK code i could not get my head around the SELinux specific stuff, so i discarded the idea as to complex. For this to be complete i guess the CIPSO labels for SMACK would need to be taken into account. Far more than my quick and dirty approach, and probably more than i'm the right person to do it. Il try to understand the inner workings of the SECMARK stuff tough. I have not investigated further into that, but if there is some way to match on CIPSO labels, there would be at least a vehicle to base this Access control was actually not what i needed in this case. This would in this case as far as i know actually be done in the SMACK LSM. I'm not sure how much it would make sense to base firewall decisions on capability checks (i guess this is what you referring to). Like decisions in the form of who/what may access a process in which way. Please correct me if i understood you wrong. What i do with this match is just setting some CONNMARK and respectively FWMARKS to make crazy routing rules for different kinds (marked processes) of my outgoing traffic based on them. Regards Tilman --
With SELinux the packet's CIPSO label (called the packet's peer label) is different from the SECMARK label. Assuming you take a similar approach in Smack, you should be able to implement SECMARK without Yes, in the absence of the sending socket to obtain the packet's peer label you need to examine the packet itself and any labeling Well, if you are accepting or dropping packets you are applying some form of access control. I thought that was the point of your patch? Hmmm, the term "capability" is probably not the best term to use, but there are valid reasons to use the netfilter mechanism, i.e. SECMARK, to apply a network label to both incoming and outgoing packets. The idea is that this allows the LSM to make network access control decisions based on the network attributes of a packet (address, protocol, port, etc.) and the powerful packet/connection matching I think I understand you goal now, essentially you want to route traffic based on the security label of the sender, yes? There was some brief talk about this at the SELinux Developer's Summit this year at OLS. Unfortunately, it was just a casual conversation and I haven't seen any patches since then implementing security label based routing. -- paul moore linux @ hp --
Wow, now it strikes me that i was running around blind all the time. SECMARK is a target not a match. I always thought i would implementing much the same thing. I guess there would be in fact currently not way to set a MARK or CONNMAK based on a SECMARK. Most of the *MARK targets have a --restore-mark option to restore a mark into the packet mark. But since the SECMARK is not numeric/bitmask there is nothing to restore. They however can do the same in regard do CONNSECMARK and SECMARK but which would not help in this case. A secmark netfilter _match_ could do the trick here. Well here is how i did this, maybe something like this is the way to go for SELinux (or LSM in general) too. I'm surprised that i have not realized this little detail before. :-/ Regards Tilman --
Can you give me a pointer where to look? Will this mean that skb->sk may be invalid or that it will point to a a context based on the network label the packet has? In the later case, being able to match remote labels in my match would just give added benefit. (Though a netlabel (CIPSO) match would probably be more sane than a smack specific match.) One would just have more choices where to put a rule like this. Like in the FORWARD chain. If non local packets are of no interest, one could put the rule in the right chain. But i think i just misunderstood you here. Since having a socket for non local packets is probably not what you meant. Regards Tilman -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
Sure. You want to look at the selinux_ip_postroue() function which is located in the security/selinux/hooks.c file in a patched version of the kernel. The particular patch you need can be found here: * http://marc.info/?l=linux-security-module&m=122156989812425&w=2 You can grab the patch (and others in the queue for 2.6.28) from the labeled networking git tree located here: * http://git.infradead.org/users/pcmoore/lblnet-2.6_testing No. It just means that if the skb->sk pointer is NULL the packet might not actually be for another system, i.e. a forwarded packet. It turns out there are a few places in the kernel that send packets without an associated socket. If you look towards the very bottom of the patch I referenced at the top of this email you will see the following code/patch which should now handle this case correctly for SELinux. Smack is unaffected because of it's current network access controls. You want to pay attention to how the 'peer_sid' value is derived as this is the SELinux "security label". [NOTE: I hacked up the diff below a bit so it is a bit cleaner in this email] @@ -4574,21 +4586,45 @@ static unsigned int selinux_ip_postroute(struct if (!secmark_active && !peerlbl_active) return NF_ACCEPT; - /* if the packet is locally generated (skb->sk != NULL) then use - * socket's label as the peer label, otherwise the packet is - * forwarded through this system and we need to fetch the peer - * directly from the packet */ + /* if the packet is being forwarded then get the peer label from + * packet itself; otherwise check to see if it is from a local + * application or the kernel, if from an application get the + * from the sending socket, otherwise use the kernel's sid */ sk = skb->sk; - if (sk) { + if (sk == NULL) { + switch (family) { + case PF_INET: + if (IPCB(skb)->flags ...
Here and, probably more importantly linux-security-module@vger.kernel.org as that's Hmm. It looks as if your code will do what you're asking it to do. Are you going to be happy with the access restrictions that will be --
I helped myself with rules like this. _ foo rwx But i wanted to add some security stuff like selinux for years, and SMACK seems to be just great. So i will spend some time making security rules after i got this routing stuff to work. :) Regards Tilman --
I confess that I'm still not completely sure what you're up too, but you might want to look at smackpolyport (it's in the smack-util tarball) and might make your life easier if you want to have a single server (running at foo) that deals with connections from processes with multiple labels. --
I'm essentially using this as some kind of iptables owner-match on steroids. Owner match allows to filter on the processes uid, gid, and some other process attributes. Unfortunately owner match is pretty much useless because of it's limited matching capabilities. I'm really just abusing the way how security contexts of processes are transfered to all it's sockets. This way I can label a process with a specific label which then gets transfered to all of it's sockets. With this match I can look at the label via the socket of any packet in iptables. I'm pretty much ignoring the Security aspect of SMACK right now and just use it as some label that I can stick to processes. What I then to is write iptables OUTPUT chain matches which match for any of these labels and set some connection marks and firewall marks. Which I then can use in routing rules to give different routing rules to specific processes. (Like all proxy traffic over a second DSL line) I know, it's totally crazy. But it seems to work. :) I just hope the security part of this all will not break anything. But it does not look like it would right now. -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
If you really want to be abusive you could replace the smack_access() function in security/smack/smack_access.c (of all places) with a no-op Smack will eventually bite you if you're not careful, but users of MAC systems wouldn't be surprised by that. I don't think it's crazy, I think it's a matter of using what's available in novel ways. Don't hesitate if there's anything I can do to be helpful. --
I thought of that too. :) But i would rather like to use the thing in it's intended function Speaking of the devil... This is exactly what happened to me right now. I have problems with _some_ https connects. The problem lies somewhere in openssl. I did not yet find any clue with strace. Is there some straight forward way to audit/debug LSM interventions? I have probably missed something that a labeled process could not do as a '_' process could. Have no idea right now, but it is probably I like that attitude. :) -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
strace is probably your best bet, as it will tell you what syscalls fail. Your current situation is most likely a case where your program running with a label "Foo" is trying to communicate with a service on a machine that doesn't talk CIPSO and hence Smack is treating all packets to and from that host with the ambient (%cat /smack/ambient) A labeled system hoping to get services from an unlabeled server is the biggest single pain in dealing with labeled systems. Per-host labeling is in the works, and it will help in some cases. What I really need is a way to designate an unlabeled host as safe to talk to at any label, but it will take some serious work to come up with a scheme that makes that palatable for a labeled environment. It got me where I am today. Hmm, maybe you should be just a little bit careful. --
Yea, I just found that out. I did not expect smack to add netlabels by default. I thought I would need to configure something before it will start adding netlabels 'on the wire'. In my case 'security' is something that should only concern the local machine. Unfortunately I never bothered to test this before. :-/ If I set /smack/nltype to 'unlabeled' I have effectively shut off the network. I guess I'm missing some essential point here. Sorry to bother you with such trivialities. btw. I find it very hard to find informations on the various files in /smack/ and it's respective intention and formating rules. security/smack/smackfs.c helps a bit. This is my current setup: /smack/ambient (default) /smack/load = _ foo rwx Unlabeled process work fine. Labeled processes produce CIPSO labeled packets (which never get any answer anywhere from the internet) If i set /smack/nltype to 'unlabled' i don't even get SYN packets out. (operation not permitted) -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
It's pretty important to do it the way it is, because if a "Foo" process can talk to port/host and a "Bar" process can talk to the same you can pretty well assume that you have an information channel. I'm starting Unfortunately, any time you talk off the machine you have to consider that Not to worry. The essential point is that with MAC you can't just lock the doors, you have to lock the windows as well. What I mean by that is that traditional access controls apply to files, but not network communications. Network communications became popular in part because they were allowed to leave any restrictions up to the applications and their protocols. MAC requirements are pickier than that. The good news is that with a scheme like CIPSO you can easily enforce the policy. The bad news is that network services in general assume that If you pull down the smack-util-0.1 package from http://schaufler-ca.com That's probably a bug, but I think the "fix" is to disable the ability to set the nltype to anything other than CIPSO at least for the time being. --
This might work well in trusted networks. But Internet is untrusted and needs to work too. At least in the most Well, there is a case statement in smack_lsm.c that checks for the nltype (smack_net_nltype) and omits net labeling if cipso is not set. This seems to be a very sensible thing to do. I strongly advice for a way to omit netlabel based access control. As soon as you leave controlled and trusted networks, netlabels seem in my eyes like a maybe even critical information leak. btw. I tried return 0; in smk_access(), but it did not make networking work again with nltype set to unlabled. So I guess the problem is not some access check. If you have any idea how i can avoid any cipso labels on the network but use smack for local access control? I don't try to secure information channels. Our system is a general purpose server, it would defeat the purpose of our system to lock it up since our clients are never going to use cipso. I'm pretty sure the cipso labels are the problem. Since I can easily access resources in the local network. But things break when I access over Internet. And I can not even expect this to work in any network where the system will be deployed. -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
Hi Tilman, On Mon, Oct 6, 2008 at 2:57 PM, Tilman Baumann Check this patch: http://article.gmane.org/gmane.linux.network/95294/match= As far as I can remember, it does exactly what you're asking for. There have been some arguments against it, but at least you can get the idea and _try_ to discuss/enhance it further. Regards -- Ahmed S. Darwish Homepage: http://darwish.07.googlepages.com Blog: http://darwish-07.blogspot.com --
Yes. I'm pretty close to convinced that it needs to be included as part of the single-label host solution. Not that it can possibly be --
Hi Casey, the last weeks I tried to come up with some way to circumvent my problems by aimlessly poking around in the code. Did not work though. Not yet at least. :) Maybe it makes more sense for me to wait until you have a solution. My whole project is stalled right now because of this and I'm not sure what next. Do you plan to change something there soon? If so I would stop wasting my time with hopeless attempts. My problem is at the moment that I don't really know what to do. If you can give some aim I would be glad if I could do something. Thanks -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
Well, the good news is that I have a change under test that will address your needs, allowing a host or set of hosts to be generally accessible from the Smack system. The bad news is that it uses a set of netlabel apis that are not going to get released in favor of a redesigned set of apis which are not available yet. The good news is that those apis will handle Smack's needs just fine, but again the bad news is that I don't have them to use yet. If you're up to trying out something that you know is going to get rewhacked before it goes in anywhere let me know. --
Sure. I will be happy to use that. Just tell me where to find it and how to use it and what I should look out for. -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
OK. I'll throw a patch together. It may take a day or two due to the heap on my plate. --
You'll need to start out with Paul Moore's testing tree: % git clone git://git.infradead.org/users/pcmoore/lblnet-2.6_testing Apply the attached patch (attachments are discouraged for review purposes, but this is handier for this purpose) and compile. This is NOT production code. Again, we're hashing out the netlabel api and we know that they are going to change. This is demo only. The amount of testing it's gotten is really small. I have created a new system label "@", pronounced "at" and referred to as the internet label. Processes cannot be assigned the internet label. A subject with the internet label (as identified by a packet thus labeled) can write to any object and any subject can write to an object thus labeled, thereby explicitly blowing a hole in the Access Control Policy. Have fun, let me know what you hit next. Thank you.
Sorry for the long delay. I was annoyingly occupied with other things. I just tried this out. But one thing makes me wonder if I had understood what it should do. The syntax for /smack/slhost is IP[/MASK] LABEL. When I give one host (in my case generously 0.0.0.0/0 *g*) a label what is the significance of the @ label? First I used the _ label here which had the effect that everything seems to work but labeled processes still produced labeled packet which got slaughtered in different ways and degrees over the internet. If I gave my slhost the @ label my machine was offline and did not even get pings out locally. I get the feeling I did not understand the concept yet. Sorry but if you don't mind giving me a hint... -- Tilman Baumann Software Developer Collax GmbH . Boetzinger Strasse 60 . 79111 Freiburg . Germany p: +49 (0) 89-990157-0 f: +49 (0) 89-990157-11 Geschaeftsfuehrer: William K. Hite / Boris Nalbach AG Muenchen HRB 158898, Ust.-IdNr: DE 814464942 --
OK, I made a mistake here. The syntax will allow for a mask soon, but the code I passed along only supports IP addresses, not ranges. For I don't think that I've passed along the patch that supports "@" yet. I'm hoping to give it a little bit of test before it goes out. Sorry that I seem to have given you the impression that it should work Now where's the fun in giving out hints? (smiley goes here) The idea behind the "@" label is that there are a class of people who don't trust the other processes on their machine, but who are willing to trust anything so long as it comes off the network. Further, anything that they put on the network is inherently worthy of trust. Somehow this does not match my personal notions, but it is a common request. So, a packet labeled "@" will be delivered to any socket. A single-label host at "@" will accept packets from anyone. It's a wild-card, no holds barred, laze fair approach to networking that makes no sense whatsoever from a security standpoint but that everyone seems to believe is necessary. --
OK, Paul and I knocked our heads together until we got the behavior and
interfaces ironed out if not to our mutual satisfaction at least to a
workable level. Paul's next tree:
% git clone git://git.infradead.org/users/pcmoore/lblnet-2.6_next
has the current version. There are a couple interesting things going on.
- /smack/nltype is gone. It never lived up to its promise and is no
longer required to determine the labeling scheme.
- /smack/netlabel replaces the earlier /smack/slhost because it better
describes what it gets used for.
- The "@" label (pronounced "web") has been added to the list of special
labels. A packet with the web label will get delivered anywhere. A
network address specified to have the web label can be written to by
any process. Processes can not have the web label.
- An incoming packet from an address in the netlabel list that has a
CIPSO
label attached will still use the label from the CIPSO packet.
- An unlabeled packet coming from an address in the netlabel list
will be
given the label associated with that address.
- A process that wants to send a packet to an address on the list needs
write access to the label associated with that address. The packet
will
be sent unlabeled if it is allowed.
So, if I want my old Sony to be treated as a single-label host with the
label "Pop" I can say:
# echo 192.168.1.102/32 Pop > /smack/netlabel
If I want the secondary network for my development machines to be
single-label
# echo 192.168.2.0/24 Snap > /smack/netlabel
And if I want everyone to be able to communicate with my spam server
# echo 207.69.188.187 '@' > /smack/netlabel
--
I guess the question will be, can the /smack/netlabel network also be 0.0.0.0/0? I know, that's not how it was meant to be used, but that's what would solve my problems with outgoing labeled packets. However, I will try this out... Thanks Regards Tilman --
Yes. If you want all internet domain sockets to be unlabeled and
accessible to all:
# echo 0.0.0.0/0 '@' > /smack/netlabel
I have tested this some, but not to the extent I've done on what I
expect to be the more normal cases. Please let me know how well the
Thank you. I'm eager to hear your next set of questions.
--
Just a quick update. You can blame me for the delay, I was a bit distracted trying to get things ready for the 2.6.28 merge window and the NetLabel kernel API changes got pushed aside for a few weeks. I just sent Casey a draft patch of the new API bits to review; with any luck I'll have something to post as an RFC patch shortly. Thanks for your patience. -- paul moore linux @ hp --
