MAC policies and shared hosting
Borja Marcos
BORJAMAR at SARENET.ES
Fri May 5 09:09:32 UTC 2006
> I think the approach you've described sounds like the right sort of
> approach -- a hybrid model that allows the web server to tell the
> kernel when its switching to a particular user domain, taking
> advantage of existing user credential elements, etc. I guess what
> I'd start out by doing is identifying what it is you want to
> protect against, and specifically, write a couple of short stories
> (a few sentences) describing specific sequences of events you want
> to protect against with the policy. It sounds like, in particular,
> you're looking for an outcome that could be expressed using
> mac_bsdextended, but perhaps not efficiently due to the number of
> rules it would take to implement.
The problem is: Is it possible to run a shared web hosting for many
servers (imagine 1000) on FreeBSD with a reasonable security level?
Most of them would be low-traffic websites with a couple of .html
files, some images... And some of them need the ability to run CGIs
and PHP, which creates a real nightmare.
I know there exists the jail mechanism, but it's complex to manage,
and you loose the flexibility of virtual hosts, needing a different
IP address for each hosted server. Moreover, you need a lot of chroot
trees (one for each user).
A hybrid scheme would need to create a single chroot, imagine:
/chroot/
/chroot/etc
/chroot/usr/
....
/chroot/webs/user1
/chroot/webs/user2
but it has an important shortcoming:
1- User directories must be visible in order to be accesible by
unprivileged web server processes. However, it's not desirable to
allow a CGI or PHP script by a given user to access a directory
belonging to another user.
I would like the CGI and PHP scripts to be as flexible as possible,
but without compromising the other users.
I had a look at the different MAC modules, and saw that
mac_bsdextended could be really useful for this. However, it has some
problems:
1- Lack of flexibility to specify general rules.
2- Rule number limitation, I guess because a lot of rules would
impose a serious performance penalty. This could be changed by
implementing a set of orderless rules stored in the form of a sparse
matrix, so that an access from a subject with uid X to an object with
uid Y would be checked in a very short time, instead of looking for a
match for each of the rules.
So, for example, imagine that I want each uid belonging to the set
[10000,20000] unable to act on objects belonging to users in the same
range, I could define something like:
# deny for uid belonging to [10000,20000] on uid belonging to
[10000,20000], being both # different
ugidfw add subject uid 10000-20000 object different uid 10000-20000 mode
# allow for uid belonging to the interval, on uid belonging to the
same interval, being
# both uids the same
ugidfw add subject uid 10000-20000 object uid 10000-20000 mode arswxn
I'm testing this approach by a quick'n dirty way. I've got
mac_bsdextended, and doing some trivial changes I've created a new
mac module called mac_isolateduids. It specifies a range of uids
(security.mac.isolateduid.uid_min and
security.mac.isolateduid.uid_max). I've changed the
mac_bsdextended_check so that:
if uid of subject belongs to [uid_min,uid_max] and uid of subject
belongs to [uid_min,uid_max], and uid(subject) != uid(object) the
access is always denied. It's a quick and dirty solution, but it
would implement the desired behavior. I'm right now tinkering with it
and will let you know the results :)
Of course, this policy could be extended, for example, to forbid
execution of setuid/setgid programs, etc. Right now, mine is a simple
experiment (but it could go into actual production). I think there is
a great work in the MAC framework, but security policies are hard to
understand, manage and implement. We should look for something
similar to the Unix model, but more flexible.
Perhaps some rework of the whole bsdextended idea could enhance it.
Regarding the multi-level idea, it would be a second phase. I would
like to be able to contain effectively a possible root escalation
from a poorly written CGI or PHP script. I know, it would be anyway
extremely hard. But if we could launch the web server process with an
additional lower security level inherited by all of its child
processes, we could prevent damage to the system even by a child
processes that escalated to root.
I guess I should sit down this weekend and prepare a properly written
paper, but I think the idea is quite clear here :)
The possible practical implementation of this scheme would use Zeus
webserver, which has an option to execute each CGI with the uid of
its owner. Of course, it could be interesting to add some
functionality, for example, to Apache, in order to take advantage of
the new security mechanisms.
Best regards,
Borja.
More information about the freebsd-security
mailing list