From owner-freebsd-isp@FreeBSD.ORG Tue Jul 18 12:46:03 2006 Return-Path: X-Original-To: freebsd-isp@freebsd.org Delivered-To: freebsd-isp@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2867016A4DE for ; Tue, 18 Jul 2006 12:46:03 +0000 (UTC) (envelope-from b.candler@pobox.com) Received: from proof.pobox.com (proof.pobox.com [207.106.133.28]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9C03143D4C for ; Tue, 18 Jul 2006 12:46:02 +0000 (GMT) (envelope-from b.candler@pobox.com) Received: from proof (localhost [127.0.0.1]) by proof.pobox.com (Postfix) with ESMTP id 861062A312; Tue, 18 Jul 2006 08:46:01 -0400 (EDT) Received: from mappit.local.linnet.org (212-74-113-67.static.dsl.as9105.com [212.74.113.67]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by proof.sasl.smtp.pobox.com (Postfix) with ESMTP id 3605564AD2; Tue, 18 Jul 2006 08:46:00 -0400 (EDT) Received: from lists by mappit.local.linnet.org with local (Exim 4.61 (FreeBSD)) (envelope-from ) id 1G2oxa-0006wx-NQ; Tue, 18 Jul 2006 13:45:58 +0100 Date: Tue, 18 Jul 2006 13:45:58 +0100 From: Brian Candler To: Mark Bucciarelli Message-ID: <20060718124558.GA26642@uk.tiscali.com> References: <20060714195603.GE396@rabbit> <20060714202233.GF396@rabbit> <20060715181054.GA15489@uk.tiscali.com> <20060716221935.GA3600@rabbit> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060716221935.GA3600@rabbit> User-Agent: Mutt/1.4.2.1i Cc: freebsd-isp@freebsd.org Subject: Re: CGI apps in C? X-BeenThere: freebsd-isp@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Internet Services Providers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Jul 2006 12:46:03 -0000 On Sun, Jul 16, 2006 at 06:19:35PM -0400, Mark Bucciarelli wrote: > "fork a shell" > > This would be used if you want to run "find" or some other shell > utility from your C code. Correct? Yes, if you call system(), or popen(), or something else which invokes a command via a shell. If you explictly fork() and in the child do execl("/usr/bin/find",arg1,arg2...) then you don't have this problem, as you're running the program directly. Silly example: don't write things like snprintf(buf, sizeof(buf), "rm /tmp/sessions/%s", sessionid); system(str); when the user could present a sessionid of ../../etc/passwd or worse something like 1234;echo "foobar"|passwd root > Yes, I did a bunch of reading when setting up my first FreeBSD > server and settled on running PHP apps using fastcgi + suexec. > Very RAM-heavy, as each client get's their own php interpreter > resident. They time out pretty fast, which is good for RAM but > bad for the next time someone visits the site. There is no > better solution I have found for performance + security with PHP. > And I don't like it much ... hence my initial post. Well, the Unix security model is that once a process has switched to user id X, it cannot switch to another userid (at least not unless it exec's a setuid binary and hence becomes a new program). That's the basis of the security model; if you assume that an attacker comes across a process running as X where they can substitute their own code, there should be no way they can switch to user Y. So if you have 1000 users, then either you need 1000 processes floating around, each running as one of those userids, or you need to start a new process for each request. In the limiting case, you could run 1000 webservers under different uids listening on different ports, and have a front-end webserver answering on port 80 and relaying the requests to those other servers (e.g. using mod_proxy under Apache). It will eat RAM, but perhaps not as much as you might expect due to shared code pages (especially for those sites which don't have mod_php and the like loaded) Since in my experience the vast number of websites are either (a) idle, or (b) completely static content, then having a split where the majority of sites run on a single process with suexec for the odd CGI request, and a small number of "premium" servers where each user has their own httpd server process, seems to make sense. Each user can then customise their config, e.g. those who want mod_perl or mod_ruby can have it. Of course, "super premium" customers can have their own operating system too, running under Xen or VMware :-) > > Another thing I did was to modify suexec so > > that it would fork(), wait4(), and then log the rusage > > information for each CGI execution. Analysing these logs lets > > you work out, site by site, which are the CGI hogs. > > That sounds pretty interesting. Did you publish your work? Unfortunately not - it belongs to my ex-employer. However I did suggest that this functionality could easily be included in mod_cgi, with an outline patch you might be able to use here: http://mail-archives.apache.org/mod_mbox/httpd-dev/200512.mbox/%3C20051205091812.GA90189@uk.tiscali.com%3E (point 2) You replace the existing wait/waitpid call with wait4(). It's more efficient to do it there anyway. In our case it was more important to avoid touching the base code, which is why I moved this into suexec, which we had to customise for other reasons anyway. A quick google search suggests that maybe cgiwrap can do this: http://cgiwrap.sourceforge.net/changes.html "New in version 3.6.2: ... * Added support for reporting rusage/return code after executing script." But I've not used cgiwrap myself. Regards, Brian.