Did you check Metux MPM?
It works by passing socket discriptor to worker process.

The project is on beta status but works fine.
Please see the following pages.
http://www.metux.de/mpm/
http://www.sannes.org/metuxmpm/

If you are interested in extending this MPM, join in the 
project. I'm sure some of the maintainers are still watching the
move.

Hideki Noma

> Hi,
> 
> I'm going to make a new MPM (I called it Dispatching MPM, or D-MPM) that
> would do what perchild is supposed to do.  Here is a rough proposal of 
> the architecture.
> 
> My general idea is shown on the following diagram of example state of
> D-MPM:
> 
>      +-------+   +-------+    +-------+       +-------+
>      |worker1|   |worker2|    |worker3|       |workerN|
>      |-------|   |-------|    |-------|       |------ |
>      |user1  |   |user2  |    |user1  |  ...  |userX  |
>      |group1 |   |group2 |    |group2 |       |groupY |
>      |/home/a|   |/home/b|    |/home/c|       |/home/Z|
>      +-------+   +-------+    +-------+       +-------+
>      /\  /\          /\           /\              /\
>      ||  ||          ||           ||     ...      ||
>      ||  \/          \/           \/              \/
>      || +--------------------------------------------+         +--------+
>      || |               dispatcher                   |         | master |
>      || |--------------------------------------------|         |--------|
>      || |               nobody                       |         |root    |
>      || |               nogroup                      |  <===>  |root    |
>      || |               /var/empty                   |         |/       |
>      || +--------------------------------------------+         +--------+
>      ||           /\
>      ||           ||
>      ||           ||
>      \/           \/
>   +-------+   +-------+
>   |client1|   |client2|
>   +-------+   +-------+
> 
> Arrows indicate communication, eg. using sockets. First line of each
> item contains its name, next lines contain user, group, and root
> directory it runs with, respectively.
> 
> System consists of 3 parts:
> 
> Workers--they are basically the same as in other MPMs, the only
> difference is that each has some set of permissions (uid, gid, root
> directory, etc.) of particular group of virtual hosts.
> 
> Dispatcher, accepting incoming connections, reading requests and
> redirecting them to one of appropriate workers (i.e. those having set
> of permissions needed to handle that virtual host).
> 
> Apache master process, listening to requests from dispatcher, and
> creating new workers with specified permissions, according to the
> requests.
> 
> In presented example, client1 has specified Host: header and has been
> redirected to worker1, while client2 hasn't specified it yet, so it is
> still connected to the dispatcher.  The diagram is created with
> assumption that socket passing will be used, not proxying.
> 
> Rationale for the Architecture
> 
>   Most existing solutions (that separate different virtual hosts) have
>   the architecture where many threads/processes (each running with
>   privilege of some virtual host) accept connections, and redirect them
>   if client wants another virtual host. This may create potential
>   security problem--if there were an exploitable bug in code before
>   redirection, an attacker would have a possibility to gain privilege
>   of user of any virtual host. In D-MPM, an attacker would gain only
>   dispatcher's permissions, which can be very restricted.
> 
>   In existing MPMs number of threads for each virtual host is static,
>   set in configuration file. D-MPM approach fixes that problem--new
>   workers are dynamically created by master process on dispatcher's
>   demand.
> 
>   Of course there might be a security hole in master's code. But
>   communication protocol between dispatcher and creator is going to be
>   rather simple: dispatcher may only request that new worker with
>   specified permissions should be created, creator returns socket
>   descriptor connected to a newly created child or error code.
> 
> Extensibility
> 
>   Nowadays permissions of process depend not only on process user and
>   group ID, but on many other settings that vary from system to system.
>   The most popular is process' root directory (changable by chroot(2)),
>   but there are many others (eg. POSIX capabilities, jails, other
>   security settings in RSBAC and SELinux).
> 
>   To allow to utilize any of security extensions particular system has,
>   D-MPM will have a loadable module support. Making D-MPM change some
>   non-standard permissions would involve only writing a small shared
>   library, without need for changing D-MPM's source or even recompiling
>   it.
> 
>   Someone creating a module needs to provide only two functions: first,
>   that reads part of virtual host's configuration, and second, that
>   changes process permissions according to that configuration.
> 
> Implementation issues
> 
>   Dispatcher
> 
>     It would be best to make dispatcher single-threaded, I suppose that
>     creating separate thread for each connection would take much more
>     resources.  OTOH it may cause some problems.  One I am currently
>     aware of is mod_ssl, which AFAIK doesn't currently have non-blocking
>     API.  Would it be difficult to create such API?
> 
>     I want dispatcher to be as simple as possible, and make workers do
>     all the work (filters, handlers, etc.).  Of course, as dispatcher
>     must read Host header, it must use connection filters.
> 
>     This headers is needed, because dispatcher has to decide to which
>     worker a connection should be redirected.  I think that it would be
>     best if it didn't do full header parsing, but just look for virtual
>     host name.
> 
>     There are two ways of dispatching connection:
>     - passing a socket descriptor (along with data that were already
>       read) to the appropriate worker,
>     - acting as a proxy, redirecting data to the appropriate worker.
> 
>     Passing a descriptor wouldn't involve unnecessary copying.  But in
>     case of SSL connection, passing whole connection state may be
>     difficult.  I have also heard that sending socket is very resource
>     consuming.  So probably proxying whole connection would be a better
>     solution.  Another advantage of acting as a proxy would be that less
>     things would have to be changed on worker side.
> 
>     Many dispatchers may be needed only in specific situations, eg. when
>     someone wants each dispatcher to run on a different processor on a SMP
>     system.
> 
>   Workers
> 
>     Workers won't change much, so code from existing MPMs should be
>     somehow reused.  Even running different workers for different
>     virtual hosts should be possible.  So I'm thinking of possibility of
>     some generic code reuse, that would allow me to use workers from
>     almost any MPM (prefork, worker, event...).
> 
>     Keep-alive requests.  If client, during kept-alive connection,
>     specifies request to virtual host that has other set of
>     permissions than previous one, worker will have to redirect that
>     connection back to dispatcher, to let it find a worker for that
>     virtual host and make it handle the connection.  If we decide that
>     dispatcher acts as a proxy, it will also have to track Connection
>     headers, and redirect connection to other worker, when needed.
>     It would involve a lot of work, so I have a proposal of going around
>     the problem: if a client specifies another virtual host than before,
>     server responds with
>     Connection: close
>     Location: URL
>     sending URL that client has just requested.  It would force client
>     to reconnect, and then it would be dispatched to an appropriate
>     worker.
> 
>     Logging.  Currently every worker has descriptors of every log file.
>     To provide security, after creating a worker and changing its
>     permissions all the unnecessary log file descriptors will be closed.
> 
>   Master
> 
>     It is the only part of code that must run with root permissions. 
>     It will be a part of Apache master process.  Protocol between
>     dispatcher and master will consist of requests (issued by
>     dispatcher) to create new workers, and answers, that would allow
>     dispatcher communicate with newly created worker (or indicate an
>     error).
> 
>     It can be done by:
> 
>     - passing a socket descriptor,
>     - passing name of the socket (it should be a Unix socket),
>     - passing port number of the socket (should be a TCP socket bound to
>       eg. localhost address).
> 
>     I think that passing a descriptor is the best option in this case,
>     as it doesn't involve creating sockets that, in some circumstances,
>     might be accessible to other processes.
> 
> Feedback greatly appreciated...
> 
>       Micha?

Reply via email to