httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Hideki Noma <>
Subject Re: Dispatching MPM
Date Tue, 19 Jul 2005 07:05:06 GMT
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.

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

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?

View raw message