On Fri, Oct 03, 2008 at 03:27:38PM +0100, Nick Kew wrote:
> In the past, we've had some efforts to improve separation, based on
> worker children running under different user IDs. See for example
> the perchild MPM at apache.org. There's a lot of demand for
> perchild-like solutions, but no really satisfactory solution.
> My proposal is to provide an option whereby worker children perform
> a zone_enter before accepting connections or reading application-
> sensitive data. This of course assumes apache is started up in the
> root zone. Each zone will be the home for one or more virtualhost.
> It should be possible for zones to have different sizes (numbers of
> worker threads) and bandwidths (through crossbow), and other
> customisations. But the primary purpose - and I believe a huge
> selling-point - is the increased security of this virtualisation.
There are several problems with this approach.
First, user authentication in web applications often happens, for better
or for worse, at the application layer, not at the TLS or even HTTP
layers. Which means that you'd need to do the zone_enter() pretty late.
Another problem is that zone_enter() is extremely restrictive with
regard to the environment of the caller and the result. E.g., you can't
have file descriptors referring to NFS resources survive a zone_enter().
Yet another problem is that your zones won't be sharing IP addresses.
Though if connected socket file descriptors can survive a zone_enter()
then this may not be a problem.
A few observations/suggestions:
- You'll need a component in the architecture to do user
- And since that could happen in TLS (e.g., user certs, PSK), HTTP
(Basic, DIGEST, Negotiate) or at the application layer (e.g.,
username and password POSTed forms), that component may need to
actually be multiple components.
- Once you know what user (or what administrative domain the user is
in) is making what request then you can forward the request to an
isolated service, possibly running in another zone, over doors or
other inter-zone IPC (hey, Unix domain sockets soon will support
GZ-arranged inter-zone IPC) that is arranged by the global zone.
- The isolated service in question should run as some user. If you
are doing per-user services then you'll need to map users to some
UIDs. That's going to be difficult, but in a zoned environment
you can edit /etc/passwd on the fly, so you could always
dynamically assign them.
- Perhaps we could do something here in terms of mapping web IDs
to ephemeral UIDs (and SIDs based on, say, hashed ID data).
Couple this with ZFS.
OT: This could also be a solution for the reserved UIDs/GIDs
problem. Though I'd handle that slightly differently, but
let's not get into that here.
- Otherwise the isolated services should run as a UID associated
with the user's administrative domain, not with the user
itself. If you don't trust your users, then this is not good
- Of course, if you don't trust your users then you also have
other problems (e.g., XSS prevention by verifying the form
of user inputs that will be re-displayed to others).
- The isolated service in question will have to authenticate the IPC
caller (as opposed to the user) and trust that it authenticated
the user OR the isolated service will have to BE the
- The latter probably has a variety of implications. If this is
where you're headed then we could flesh those out.
- With the former you get isolation between the services actually
servicing requests, but not with respect to infrastructure
services (authentication). I think this is OK. It reflects
the fact that the application must trust the underlying
transport (let's not argue about whether HTTP, TLS are
- You probably don't actually need zones for this. Just being able to
isolate processes by making them run as different UIDs will suffice.
- Though, of course, to the extent that different sites hosted on
the same system have different IP addresses, then you should run
each in its own zone.
zones-discuss mailing list