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?