linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [RFC] packet/socket owner match (fireflier) using skfilter
       [not found] <5X7nH-7n6-7@gated-at.bofh.it>
@ 2006-04-06 12:21 ` Bodo Eggert
  2006-04-07 18:58   ` edwin
  0 siblings, 1 reply; 11+ messages in thread
From: Bodo Eggert @ 2006-04-06 12:21 UTC (permalink / raw)
  To: Török Edwin, linux-kernel, fireflier-devel

Török Edwin <edwin@gurde.com> wrote:

> Fireflier aims at providing per application filtering. That is allowing to
> create rules like: allow apache to listen on port 80 (and only apache, nobody
> else).

I had a very simple idea for doing something like this:

Assign a special semantic to GID $n: Being in group $n allows you to listen
on port $n-$offset. $offset == -1 disables this feature (default).

E.g. You want apache to listen on 80 and 443: Set $offset to 60000 and put
apache into groups 60080 and 60443.

> I didn't include the patch inline, since it is quite long (1800+ lines ,
> ~100k). So I uploaded them here:
> http://edwintorok.googlepages.com/fireflier_kernel.html

(Text in parentheses written after completely reading the posting)

If I'd want it to work with iptables, I'd extend the socket struct to contain
the device:inode of the corresponding application (not changing it on exec)
and stat() the allowed applications on rule setups.
(I see you choose similar but more complicated approach, but:)

I'd deliberately allow access to these sockets if it's passed to other
applications since it's the intended behaviour. (BTW: Your approach isn't
going to be 100 % reliable, since it will allow other processes to illegaly
receive data if the socket is transfered after filtering, isn't it?)

Downside of both approaches:
 You'll have to guarantee stable dev:inode pairs. NFS? umount/mount?
 Workaround: suid helper setting/deleting the allowed-rule?

-- 
Ich danke GMX dafür, die Verwendung meiner Adressen mittels per SPF
verbreiteten Lügen zu sabotieren.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-06 12:21 ` [RFC] packet/socket owner match (fireflier) using skfilter Bodo Eggert
@ 2006-04-07 18:58   ` edwin
  2006-04-07 20:06     ` Bodo Eggert
  0 siblings, 1 reply; 11+ messages in thread
From: edwin @ 2006-04-07 18:58 UTC (permalink / raw)
  To: 7eggert; +Cc: linux-kernel, fireflier-devel

> I had a very simple idea for doing something like this:
Your idea is interesting. Unfortunately it is not directly applicable, and
is more a "hack", than a solution.
>
> Assign a special semantic to GID $n: Being in group $n allows you to
> listen
> on port $n-$offset. $offset == -1 disables this feature (default).
Modifying gids is not a good idea, the sysadmin might need it for other
purposes.
> If I'd want it to work with iptables, I'd extend the socket struct to
> contain
> the device:inode of the corresponding application (not changing it on
> exec)
and that would require recompiling the kernel
> and stat() the allowed applications on rule setups.
>
> I'd deliberately allow access to these sockets if it's passed to other
> applications since it's the intended behaviour.
It might be intended behaviour, or it might be a file descriptor leak.
If I have a rule in iptables saying to allow only apache (just an example)
access to port 80, I don't want any other program to have access to it.
If apache might leak a file descriptor (it doesn't, just an example), and
give access to other programs, the firewall would restrict those programs.
If I would implicitly trust them, then fireflier rules wouldn't be any
better, than just creating rules to allow any program to listen on port
80.

> (BTW: Your approach isn't
> going to be 100 % reliable, since it will allow other processes to
> illegaly
> receive data if the socket is transfered after filtering, isn't it?)
filtering is done on each packet, how could the socket be transfered
between the time the packet is filtered, and the time it is received by
the program?
A socket transfer can be done via execve, or IPC, both covered (I hope) by
the fireflier lsm.
>
> Downside of both approaches:
>  You'll have to guarantee stable dev:inode pairs.
This could be ensured from userspace, if it becomes an issue.
> NFS?
running a program via NFS, and giving access for it to the network? why
would I want that?
Anyway, if somebody wants that, we could determine the inode of the
program on nfs mount time. We could store the path+hash of the program to
be sure it is the same program.
>umount/mount?
Aren't inodes stored on the disk?
>  Workaround: suid helper setting/deleting the allowed-rule?
No need for suid though, fireflier-server runs as root.
>

Cheers,
Edwin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-07 18:58   ` edwin
@ 2006-04-07 20:06     ` Bodo Eggert
  2006-04-08  7:50       ` edwin
  0 siblings, 1 reply; 11+ messages in thread
From: Bodo Eggert @ 2006-04-07 20:06 UTC (permalink / raw)
  To: edwin; +Cc: 7eggert, linux-kernel, fireflier-devel

On Fri, 7 Apr 2006 edwin@gurde.com wrote:

> > I'd deliberately allow access to these sockets if it's passed to other
> > applications since it's the intended behaviour.

> It might be intended behaviour, or it might be a file descriptor leak.
> If I have a rule in iptables saying to allow only apache (just an example)
> access to port 80, I don't want any other program to have access to it.
> If apache might leak a file descriptor (it doesn't, just an example), and
> give access to other programs, the firewall would restrict those programs.
> If I would implicitly trust them, then fireflier rules wouldn't be any
> better, than just creating rules to allow any program to listen on port
> 80.

If apache is running a CGI script, it must pass the socket (bound to 
remote:port,local:80, to the CGI at fd 2*. If your firewall is blocking
this, your CGI scripts will stop working.

* unless it intends to proxy the connection

> > (BTW: Your approach isn't
> > going to be 100 % reliable, since it will allow other processes to
> > illegaly
> > receive data if the socket is transfered after filtering, isn't it?)
> filtering is done on each packet, how could the socket be transfered
> between the time the packet is filtered, and the time it is received by
> the program?
> A socket transfer can be done via execve, or IPC, both covered (I hope) by
> the fireflier lsm.
> >
> > Downside of both approaches:
> >  You'll have to guarantee stable dev:inode pairs.
> This could be ensured from userspace, if it becomes an issue.
> > NFS?

> running a program via NFS, and giving access for it to the network? why
> would I want that?

Why not? E.g. you could set up a farm of redundand apache servers.

> Anyway, if somebody wants that, we could determine the inode of the
> program on nfs mount time. We could store the path+hash of the program to
> be sure it is the same program.

> >umount/mount?
> Aren't inodes stored on the disk?

At least Mostly, but is this a requirement?
-- 
Fun things to slip into your budget
True and it was approved:  128 MBytes of VIRTUAL memory.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-07 20:06     ` Bodo Eggert
@ 2006-04-08  7:50       ` edwin
  0 siblings, 0 replies; 11+ messages in thread
From: edwin @ 2006-04-08  7:50 UTC (permalink / raw)
  To: Bodo Eggert; +Cc: linux-kernel, fireflier-devel

On Fri, Apr 07, 2006 at 10:06:45PM +0200, Bodo Eggert wrote:
> On Fri, 7 Apr 2006 edwin@gurde.com wrote:
> 
> If apache is running a CGI script, it must pass the socket (bound to 
> remote:port,local:80, to the CGI at fd 2*. If your firewall is blocking
> this, your CGI scripts will stop working.
Hmm, an exception could be made for programs like apache.
The user would then create a rule that says that apache is allowed to pass on
file descriptors.
Or a rule could be created for the userspace part of fireflier that would auto-add the cgi-scripts 
to apache's group sid. Which IMHO would be the best, because the user will still have control on
what programs have access to the network. He can see that list at any time, and modify it, if not correct.
If we would simply allow file descriptors to be passed on, he wouldn't have that control.
(none of this is implemented yet)
> > running a program via NFS, and giving access for it to the network? why
> > would I want that?
> 
> Why not? E.g. you could set up a farm of redundand apache servers.
Ok, so the userspace part of fireflier will have to deal with nfs mounts as a special case.
It should store the rules in "server,path,executable hash" format, and do the inode lookup on startup,
or when the first packet arrives.
> > Aren't inodes stored on the disk?
> 
> At least Mostly, but is this a requirement?
Currently it is, until we implement path+hash rules for nfs mounts,etc.
What devices can I safely assume that the inodes won't change over boots/mounts?

Cheers,
Edwin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-21 15:26 ` Mikado
@ 2006-04-21 16:18   ` Török Edwin
  0 siblings, 0 replies; 11+ messages in thread
From: Török Edwin @ 2006-04-21 16:18 UTC (permalink / raw)
  To: mikado4vn; +Cc: linux-kernel, fireflier-devel

On Friday 21 April 2006 18:26, Mikado wrote:
> Does your module get into below problem?
>
> http://lkml.org/lkml/2006/4/20/132
Nope.

A short test:
On host:
sudo iptables -A INPUT -p tcp --dport 81 -j DROP
In qemu:
#iptables -t skfilter -A OUTPUT -m fireflier_match --inode-owner 
24392 --dev-owner /dev/root -j LOG --log-prefix test_out2
#netcat 172.20.0.1 81
[4295327.547000] test_out2:IN= OUT=eth0 SRC=172.20.0.10 DST=172.20.0.1 LEN=60 
TOS=0x00 PREC=0x00 TTL=64 ID=11865 DF PROTO=TCP SPT=34945 DPT=81 WINDOW=5840 
RES=0x00 SYN URGP=0
[4295327.549000] test_out2:IN= OUT=eth0 SRC=172.20.0.10 DST=172.20.0.1 LEN=60 
TOS=0x00 PREC=0x00 TTL=64 ID=11865 DF PROTO=TCP SPT=34945 DPT=81 WINDOW=5840 
RES=0x00 SYN URGP=0
[4295330.550000] test_out2:IN= OUT=eth0 SRC=172.20.0.10 DST=172.20.0.1 LEN=60 
TOS=0x00 PREC=0x00 TTL=64 ID=11866 DF PROTO=TCP SPT=34945 DPT=81 WINDOW=5840 
RES=0x00 SYN URGP=0

As you can see several packets are sent out, and each one is matched (24392 is 
the inode of netcat here). 

Please note that using fireflier LSM is not recomended, as I am working on 
writing SELinux policies that do the same (fireflier LSM is itself using code 
from hooks.c from selinux). 
See: http://lkml.org/lkml/2006/4/17/81


Also take a look at James Morris's skfilter patches (which are used in 
fireflier too), they allow you to match at socket level, and also allow to 
match based on selinux context.

Cheers,
Edwin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-02  9:40 Török Edwin
  2006-04-03 15:18 ` James Morris
@ 2006-04-21 15:26 ` Mikado
  2006-04-21 16:18   ` Török Edwin
  1 sibling, 1 reply; 11+ messages in thread
From: Mikado @ 2006-04-21 15:26 UTC (permalink / raw)
  To: Török Edwin; +Cc: linux-kernel, fireflier-devel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Does your module get into below problem?

http://lkml.org/lkml/2006/4/20/132
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFESPmnNWc9T2Wr2JcRAnMtAKDZvLH2MRmY/jeW/YW/9UP1fm/xwgCfSZZ/
Qom6TxVirR4HWV9Asc2ZixY=
=xlSu
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-05 15:06     ` Stephen Smalley
@ 2006-04-07 17:34       ` Török Edwin
  0 siblings, 0 replies; 11+ messages in thread
From: Török Edwin @ 2006-04-07 17:34 UTC (permalink / raw)
  To: sds; +Cc: James Morris, linux-kernel, fireflier-devel

On Wednesday 05 April 2006 18:06, Stephen Smalley wrote:
> On Mon, 2006-04-03 at 18:39 +0300, Török Edwin wrote:
> > - the security labels of processes be assigned based on their
> > executable's inode+mountpoint.
>
> Not sure what you mean by inode+mountpoint here. 
I meant security labels generated automatically based on the inode and 
mountpoint of executable, without having to apply extended attributes to 
them.
> > Is there a way to do auto-labeling with SELinux? I mean having a security
> > context applied based on the inode, without me having to run 'make
> > relabel', setfiles, and so on....
>
> Attributes have to be bound to the actual objects, which means that
> something has to set those attributes.
Obviously.
> This is no different than normal 
> Linux DAC attributes like file owner/group/mode (aside from the need to
> use extended attributes for storage).
I don't want to store the attribute.
>
> > (From my very limited understanding of SELinux, this would mean creating
> > a context for each executable, 
>
> If you truly need to distinguish each such program, then yes, they would
> need separate contexts, although you likely can organize them into
> equivalence classes. 
I thought of equivalence classes like: class_ports_all_access, 
class_port_80_access, class_port_25_access, etc. But can a program have 
multiple classess associated? (or multiple contexts?) If not, I should also 
create some sort of group classes (class_port_80_443: 
class_port_80,class_port_443)
> You could generate a policy module in userspace 
> and feed it to semodule to be linked into the base policy and loaded,
> although the details are not entirely clear as to what you would need to
> put into the policy module (e.g. you seem to just want to define the
> domain and type and then make the domain identical to the caller's
> domain since you aren't trying to restrict it any further, just use it
> for labeling purposes).
Thanks, this is very usefull.I didn't know about the modular policy support. 
It is great, as it will allow easier installation :)
Let me see if I got it right:
- I can generate a policy from userspace
- compile it into a module package
- load that using semodule
- generating the policy will be indepedent of the base policy
- the user can change the base policy, and the my policy module will still 
work (without recompiling it)


I am not sure what should be in the policy either, I thought of this:
- when a new rule is added to fireflier the policy module is updated
- domain&type is generated, that is unique to each program
- "labels" the program with the generated domain&type (is this possible 
without storing the context on disk?)
- "labels" each socket created by the program with the program's label
- when a domain transition occurs, all sockets that are open, are relabeled, 
to show that 2 domains have access to it (relabeled with an auto-generated 
context, that is some sort of a group, i.e. I can later retrieve what the 
members of that group was)
- the policy doesn't have to restrict anything, only label

Since I have already written a LSM that accomplishes what I want, can 
somebody "guide" me how to "convert" the LSM to an SELinux policy? I'd 
appreciate if you can give me ideas how to implement the parts that would 
be "translated" to a "non-standard"(unusual, features not used in the 
reference policy,...) policy file (are there such parts?).

To get started I have the following  (fundamental) question: can a program 
have multiple contexts? If not, how I can let the user use whatever context 
he wants for the program, and still apply my label to it?

If I get an answer to that question above, I'll start learning, and 
experimenting, and come back later with more questions.

If such a policy module is written, can that be used as base policy, if the 
user doesn't (yet) have a base policy? For example he boots with selinux=1, 
but he didn't set up his policy....
>
> > It doesn't have to have a security label applied by its inode, but that
> > is unique, I don't know how secure would it be to identify processes by
> > path...
>
> It isn't.  Path-based access control considered harmful.
Agreed. The fireflier LSM I've written does filtering based on inode.
Fireflier currently does (userspace) filtering based on the path, but I'll 
change that, and put the inode in the rule file too. And in case the path no 
longer matches the inode, the user is asked if he wants to update the 
rules.... but this is the userspace part of it.
> You aren't likely to get much review of your actual LSM without breaking
> it up into manageable chunks and posting with patches inline for review
> to linux-security-module@vger.kernel.org.
I will do that, I'll post them as replies to this mail. Thanks for pointing me 
to the proper list.

The fireflier LSM will be used only if the user has selinux disabled. This is 
my plan:

- if selinux is enabled: use the userspace policy module generator (not yet 
written)
- if selinux is disabled: use fireflier LSM (already written)

Please note that I am not trying to reinvent SELinux, I just want to provide a 
way of doing this application filtering, when the user has selinux disabled.

The actual packet filtering will be done:
 - userspace (using nf_queue, and getxattr)
 - using skfilter patches (as soon as they are merged in mainline)


In the end I want to thank all of you for helping me develop fireflier.

Cheers,
Edwin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-03 15:39   ` Török Edwin
@ 2006-04-05 15:06     ` Stephen Smalley
  2006-04-07 17:34       ` Török Edwin
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Smalley @ 2006-04-05 15:06 UTC (permalink / raw)
  To: edwin; +Cc: James Morris, linux-kernel, fireflier-devel

On Mon, 2006-04-03 at 18:39 +0300, Török Edwin wrote:
> I am not trying to reinvent SELinux. But I do not know how to accomplish what 
> I want with SELinux.
> 
> Here it is what I want:
> - have security labels applied to sockets based on their owners (ok, I guess 
> SELinux does this by default)

Yes, if owner == creator.

> - the security labels of processes be assigned based on their executable's 
> inode+mountpoint.

Not sure what you mean by inode+mountpoint here.  SELinux already allows
you to define a domain transition for the process based on the caller's
domain and the type assigned to the executable file via inode extended
attribute.

> Is there a way to do auto-labeling with SELinux? I mean having a security 
> context applied based on the inode, without me having to run 'make relabel', 
> setfiles, and so on....

Attributes have to be bound to the actual objects, which means that
something has to set those attributes.  This is no different than normal
Linux DAC attributes like file owner/group/mode (aside from the need to
use extended attributes for storage).  Some package managers have
already been extended to support setting SELinux attributes when files
are installed, like rpm in Fedora, dpkg in Debian unstable, portage in
Hardened Gentoo.  install(1) in Fedora also is patched to apply the
proper context for installation of files without using the package
manager.  restorecon can be selectively applied to specific files to
restore their labels to the initial values specified in the
configuration.

> Let's say I compile&install a program. Can it have a security label 
> auto(magically) applied, based on the inode of its executable? (without 
> recompiling, & reloading the policy)
>
> (From my very limited understanding of SELinux, this would mean creating a 
> context for each executable, that is altering the policy, if each executable 
> needs to have a separate context. Is it possible to dinamically generate the 
> context at runtime? Is it possible to integrate my autolabel.c with SELinux?)

If you truly need to distinguish each such program, then yes, they would
need separate contexts, although you likely can organize them into
equivalence classes.  You could generate a policy module in userspace
and feed it to semodule to be linked into the base policy and loaded,
although the details are not entirely clear as to what you would need to
put into the policy module (e.g. you seem to just want to define the
domain and type and then make the domain identical to the caller's
domain since you aren't trying to restrict it any further, just use it
for labeling purposes).

> It doesn't have to have a security label applied by its inode, but that is 
> unique, I don't know how secure would it be to identify processes by path...

It isn't.  Path-based access control considered harmful.

> If the above is possible, could you please provide pointers to documentation?
> 
> How can I implement auto-labeling with SELinux? (is there a possibility to 
> write some sort of plugins that provide this functionality?)
> 
> To sum up, I wrote my LSM stuff because I didn't know how to use SELinux to 
> accomplish what I wanted. 
> If it can be done with SELinux easily, I'm happy to switch to that. (easy from 
> the end-user's perspective, using fireflier for example. it doesn't matter 
> how much work it would imply to make fireflier handle the stuff "behind the 
> scenes")

You aren't likely to get much review of your actual LSM without breaking
it up into manageable chunks and posting with patches inline for review
to linux-security-module@vger.kernel.org.

-- 
Stephen Smalley
National Security Agency


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-03 15:18 ` James Morris
@ 2006-04-03 15:39   ` Török Edwin
  2006-04-05 15:06     ` Stephen Smalley
  0 siblings, 1 reply; 11+ messages in thread
From: Török Edwin @ 2006-04-03 15:39 UTC (permalink / raw)
  To: James Morris; +Cc: linux-kernel, fireflier-devel, Stephen Smalley

On Monday 03 April 2006 18:18, James Morris wrote:
> On Sun, 2 Apr 2006, Török Edwin wrote:
> > Before continuing the work on it, I ask for your advice, and comments on
> > what I've done so far.
>
> I would suggest dropping your LSM stuff and just using SELinux.  It's
> crazy to try and reinvent it.
I am not trying to reinvent SELinux. But I do not know how to accomplish what 
I want with SELinux.

Here it is what I want:
- have security labels applied to sockets based on their owners (ok, I guess 
SELinux does this by default)

- the security labels of processes be assigned based on their executable's 
inode+mountpoint.
Is there a way to do auto-labeling with SELinux? I mean having a security 
context applied based on the inode, without me having to run 'make relabel', 
setfiles, and so on....
Let's say I compile&install a program. Can it have a security label 
auto(magically) applied, based on the inode of its executable? (without 
recompiling, & reloading the policy)

(From my very limited understanding of SELinux, this would mean creating a 
context for each executable, that is altering the policy, if each executable 
needs to have a separate context. Is it possible to dinamically generate the 
context at runtime? Is it possible to integrate my autolabel.c with SELinux?)

It doesn't have to have a security label applied by its inode, but that is 
unique, I don't know how secure would it be to identify processes by path...

If the above is possible, could you please provide pointers to documentation?

How can I implement auto-labeling with SELinux? (is there a possibility to 
write some sort of plugins that provide this functionality?)

To sum up, I wrote my LSM stuff because I didn't know how to use SELinux to 
accomplish what I wanted. 
If it can be done with SELinux easily, I'm happy to switch to that. (easy from 
the end-user's perspective, using fireflier for example. it doesn't matter 
how much work it would imply to make fireflier handle the stuff "behind the 
scenes")

Thanks in advance,
Edwin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC] packet/socket owner match (fireflier) using skfilter
  2006-04-02  9:40 Török Edwin
@ 2006-04-03 15:18 ` James Morris
  2006-04-03 15:39   ` Török Edwin
  2006-04-21 15:26 ` Mikado
  1 sibling, 1 reply; 11+ messages in thread
From: James Morris @ 2006-04-03 15:18 UTC (permalink / raw)
  To: Török Edwin; +Cc: linux-kernel, fireflier-devel, Stephen Smalley

[-- Attachment #1: Type: TEXT/PLAIN, Size: 290 bytes --]

On Sun, 2 Apr 2006, Török Edwin wrote:

> Before continuing the work on it, I ask for your advice, and comments on what 
> I've done so far.

I would suggest dropping your LSM stuff and just using SELinux.  It's 
crazy to try and reinvent it.



- James
-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC] packet/socket owner match (fireflier) using skfilter
@ 2006-04-02  9:40 Török Edwin
  2006-04-03 15:18 ` James Morris
  2006-04-21 15:26 ` Mikado
  0 siblings, 2 replies; 11+ messages in thread
From: Török Edwin @ 2006-04-02  9:40 UTC (permalink / raw)
  To: linux-kernel, fireflier-devel

Fireflier aims at providing per application filtering. That is allowing to 
create rules like: allow apache to listen on port 80 (and only apache, nobody 
else).

A couple of days ago fireflier security module + iptables fireflier match 
module started to work [8].

Before continuing the work on it, I ask for your advice, and comments on what 
I've done so far.
I have marked with [!] the issues that are currently the most important.

0. Getting the patch/code
---------------------
All code/patches is for kernel 2.6.16.1, and iptables 1.3.5

I didn't include the patch inline, since it is quite long (1800+ lines , 
~100k). So I uploaded them here:
http://edwintorok.googlepages.com/fireflier_kernel.html

James Morris's patches [5] didn't apply cleanly to 2.6.16.1, so I had to 
modify them a bit, I have uploaded the actual patches applied
to the kernel, and iptables. (I might have made mistakes in "porting" the 
skfilter patches to 2.6.16, please point them out to me)

For the impatient, a direct link to the download:
http://edwintorok.googlepages.com/fireflier_modules.zip
http://edwintorok.googlepages.com/skfilter_patches.zip

1. Background
-----------------------
The initial approach [1] as pointed out by several ([2],[3])  people was 
fundamentally wrong.

AFAIK there is currently work being done to solve this using SELinux [4], but 
I'd like to have 'per application filtering' even without SELinux, so I
looked at James Morris and Patrick McHardy's skfilter patches [5].

So my idea was, that we use James Morris's patches, but instead of using the 
selinux security context, we use a security context based on the process's 
(its executable's) inode+mountpoint. For this we need some sort of 
auto-labeling. The LSM hooks provide just enough hooks in the right places to 
support this.
I have also written an iptables match target (and appropriate userspace 
libipt_...) based on ipt_owner.c, that matches based on the labels (SIDs) 
provided by fireflier LSM.

A detailed description of why, and how I've done this can be found on the 
wiki[6].

This code is currently working, see the tests I have done:[8]

2. Goals of fireflier LSM module
----------------------------------------
    * auto label each process with its executable's inode+mountpoint, i.e. a 
process's security context = SID based on {mountpoint+inode of its 
executable}
    * auto label each file a process has access to. If multiple processes have 
access to the same file, then create a group SID, containing all the SIDs of 
processes having access it. 
    * If multiple processes have access to the same file, but were launched 
from the same executable, then don't label with group SID (like 10 apache 
processes accessing the same socket: the socket will get the SID of apache)
    * it won't deny any operation, it just labels
    * it is not intended to be used when selinux=1 enabled at boot. If selinux 
is enabled then selinux should be used to provide the security context, and 
not fireflier 

3. Issues with fireflier LSM
-----------------------------------------

3.1 Duplicate code
---------------------
I needed a SID <-> context mapping, and I've seen that SELinux already has 
such a data structure in sidtab.c
There was no way to use that as is, since it had no exported symbols, and 
besides my context structure was different from an SELinux context,
so I copied sidtab.c to fireflier LSM. The problem is that a bug gets fixed in 
sidtab.c, ... it doesn't in fireflier LSM.
How can I use the functionality provided by sidtab.c in my LSM without 
duplicating the code?
I have thought of this solution, but I'm not sure if it is the best:
* create a patch between the selinux sidtab, and fireflier sidtab
* every time sidtab.c is changed in the kernel copy it to fireflier
* apply the patch

Also hooks.c is based on hooks.c from SELinux.

3.2 Capability module doesn't support stacking [!]
-----------------------------------------------
I have to boot with capability.disable=1 in order to be able to load 
fireflier. Otherwise it fails to register (it can't register neither as 
primary, neither as secondary LSM). Can stacking be added to the capability 
module? 

3.3 Fireflier LSM loaded as module [!]
-----------------------------------
Currently fireflier LSM is loaded as a module, and not compiled in the kernel. 
Are there any security issues that might arise from this?
(such as [9])

3.4 Performance
------------------
The SID->context lookup uses hashtable, ok.
But  context->SID lookup uses linear search (through the hash-table), can this 
be improved?
Using another hash-table, that based on the hash of a context maps to a SID 
would solve this, but it needs additional memory.

As far as autolabel.c is concerned I need to do the following: label only 
sockets, and not all inodes, for this I need to provide hook for 
socket_create, and label inodes only there?

3.5 Testing
------------
I will have to implement auto-test, that test the labels are properly applied. 
For this purpose I have created a debugging mode, where I create files
in debugfs (it currently only creates them, that is it leaks memory, I'll fix 
this later).
Is there a recommended way to do such tests? How is SELinux being tested?



4. Issues with fireflier iptables match
----------------------------------------
This is what it can currently handle:
iptables -t skfilter -A SOCKET -m fireflier_match --inode-owner 
81949 --dev-owner /dev/root -j ACCEPT

4.1 No group matching yet [!]
--------------------------
It currently matches against individual SIDs only, and can't match against 
groups. (in case a socket has a group SID, it won't be matched by the rule)
I have thought of several [7] solutions, but I am not sure which one is the 
Right Way to do it. 
IMHO solution II ([7]) would be the appropriate one:
* if a packet arrives on a socket having a group SID, and the rule tells to 
match on a SID contained in that group, then:
   * mark the packet, that it has been matched by the SID (of this rule)
   * if the packet has been marked that is has been matched by all SIDs in the 
group, then the packet is allowed to pass (i.e. matched by the rule)

The problems are:
* Can I do packet marking outside the mangle table? (in the skfilter table)?
* What would the performance penalty be to mark packets?
* How much memory would this need?
* How do I do the actual packet marking?

4.2 Duplicate code
-------------------------

I haven't included the fireflier match inside ipt_owner.c, because I wanted it 
to be installed as easy as possible, and this means, that
both the LSM module, and math module are compiled outside of the kernel tree 
currently.

What would I need to do in order to have this merged in the kernel tree? What 
conditions does the module (patch) have to meet?
Should I create a patch that can be applied with patch-o-matic-ng?

4.3 Performance benchmark
---------------------------
What is recommended way to profile an iptables match module? What tests do you 
suggest?

4.4. Testing
--------------------
I'd like to implement auto-tests for the iptables module too.
Besides testing saving/loading the rules, I'd like to test if it actually 
works. I am thinking of doing this:
* start up 3 processes:
  - program A that forks itself, and listens on a non-shared socket (lets say 
port 80, apache)
  - program B, and C share a socket with the 3rd one (lets say port 25, 
postfix)
  - program D that doesn't fork (and listens on port 22, sshd)
* create rules that match on different scenarios:
  - dst port 80, apache inode => this has to match
  - dst port 25, inode of B => this mustn't match
  - dst port 25, inode of C => this should match (if using solution II[7])
  - dst port 22, inode of B => mustn't match
  - dst port 22, inode of D => has to match
and so on
Is there a "standard" way to run such tests?

4.5 IPV6
---------
Currently the fireflier module is IPv4 only, is there anything I have to look 
out for when I "port" it to ipv6?
Should I do this now? I see that ip|ip6|arp_tables are being moved to 
x_tables, does it mean that ipv4 and ipv6 are going to be "unified"?
Do I have to do anything to support x_tables?

5. Use of the kernel API [!]
----------------------

Are the functions I used in the 2 modules part of a stable kernel API? Did I 
use functions/structures that a driver isn't supposed to use?
Are there any plans to remove a feature I used in my modules?

P.S.: there are hard coded path in some files, that is going to be fixed in a 
later version

I am waiting for your advice/suggestions/comments.

(note: although some of the pages on the wiki were last updated on April the 
1st, they are not an April's fool joke)

Thanks in advance,
Edwin

[1] http://www.uwsg.iu.edu/hypermail/linux/kernel/0602.2/0701.html
[2] http://www.uwsg.iu.edu/hypermail/linux/kernel/0602.2/0709.html
[3] http://www.uwsg.iu.edu/hypermail/linux/kernel/0602.2/0725.html
[4] http://www.uwsg.iu.edu/hypermail/linux/kernel/0602.2/0792.html
[5] http://www.uwsg.iu.edu/hypermail/linux/kernel/0602.2/1310.html
[6] http://fireflier.isgeeky.com/wiki/Kernel_module
[7]http://fireflier.isgeeky.com/wiki/Kernel_module#Multiple_programs_accessing_a_socket
[8] http://fireflier.isgeeky.com/wiki/Ipt_fireflier_test
[9]http://www.derkeiler.com/Mailing-Lists/securityfocus/bugtraq/2004-12/0390.html

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-04-21 16:19 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5X7nH-7n6-7@gated-at.bofh.it>
2006-04-06 12:21 ` [RFC] packet/socket owner match (fireflier) using skfilter Bodo Eggert
2006-04-07 18:58   ` edwin
2006-04-07 20:06     ` Bodo Eggert
2006-04-08  7:50       ` edwin
2006-04-02  9:40 Török Edwin
2006-04-03 15:18 ` James Morris
2006-04-03 15:39   ` Török Edwin
2006-04-05 15:06     ` Stephen Smalley
2006-04-07 17:34       ` Török Edwin
2006-04-21 15:26 ` Mikado
2006-04-21 16:18   ` Török Edwin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).