<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.0.2" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>m1tk4</title>
	<link>http://mitka.us</link>
	<description>ääliö, älä lyö, ööliä läikkyy!</description>
	<pubDate>Sat, 08 Aug 2009 14:26:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.2</generator>
	<language>en</language>
			<item>
		<title>Apache2 MPM-itk on RHEL/CentOS</title>
		<link>http://mitka.us/articles/mpm-itk/</link>
		<comments>http://mitka.us/articles/mpm-itk/#comments</comments>
		<pubDate>Fri, 12 May 2006 03:27:32 +0000</pubDate>
		<dc:creator>mitka</dc:creator>
		
	<category>Uncategorized</category>
		<guid isPermaLink="false">http://blog.mitka.us/articles/mpm-itk/</guid>
		<description><![CDATA[When you have to host several web applications on the same server, with each new one you probably feel less and less comfortable with all of them running as apache or nobody. This problem gets even bigger when some of your applications need to be able to write files to locations where they can later [...]]]></description>
			<content:encoded><![CDATA[<p>When you have to host several web applications on the same server, with each new one you probably feel less and less comfortable with all of them running as <span style="font-style: italic">apache</span> or <span style="font-style: italic">nobody</span>. This problem gets even bigger when some of your applications need to be able to write files to locations where they can later be executed by a http call, or even to be able to rewrite the application&#8217;s executable files themselves (to update, upgrade or install various &#8220;plugins&#8221;, for example).</p>
<h3>suEXEC and What&#8217;s Wrong With It</h3>
<p>The traditional solution to this problem was a small utility called <a title="suEXEC" href="http://httpd.apache.org/docs/2.0/suexec.html">suEXEC</a> that ships with Apache. Here is how suEXEC works:</p>
<ol>
<li>You configure each virtual host to use its own user credentials, using SuexecUserGroup directive.</li>
<li>Apache runs as always, but whenever it&#8217;s the time to call a CGI script, instead of calling it directly, Apache starts suEXEC.</li>
<li>suEXEC checks around whether the request is &#8220;legit&#8221; and if it is, starts your CGI under the privileges specified in your SuexecUserGroup option. suEXEC can do it because it&#8217;s a <a href="http://en.wikipedia.org/wiki/Setuid">setuid</a> program. Apache can&#8217;t do it itself because in <a href="http://httpd.apache.org/docs/2.0/mod/prefork.html">pre-forked multiprocess mode</a> (which is the default for most Linux distributions) only the control process runs as <em>root </em>- all child processes run as <em>apache</em>.</li>
<li>your CGI program now runs not as <em>apache </em>or <em>nobody</em>, but as some other user.</li>
</ol>
<p>In its design, suEXEC favors security over flexibility, and that&#8217;s why it has several important shortcomings:</p>
<ul>
<li>The privilege change (setuid) is only done when CGI&#8217;s are executed. When we have to serve static files (.jpeg&#8217;s, for example) they still have to be readable by <em>apache</em> user.</li>
<li>You are limited to CGI interface when running your applications. In some cases, this means much lower performance - for example, since your PHP code is run through the CGI/CLI PHP executable and not mod_php Apache module, you can say good-bye to <a href="http://eaccelerator.net/">eAccelerator</a>, ionCube&#8217;s <a href="http://www.php-accelerator.co.uk/">PHPAccelerator</a> and the likes.</li>
<li>It does not solve the problem if your application is another Apache module. In addition to PHP/mod_php case, suEXEC won&#8217;t help you with mod_dav_svn (<a href="http://subversion.tigris.org/">Subversion</a>), for example.</li>
<li>Sometimes, you&#8217;ll find suEXEC&#8217;s security policy too restrictive. And it&#8217;s not just about being able to run your web applications as <em>root </em>(which, obviously, is not an option) - you typically can&#8217;t run anything with privileges of ANY of the system accounts (uid&lt;500). Your CGI and the directory it resides in can&#8217;t be writeable by any other user. Your CGI has to be under <em>/var/www</em> or in <em>/home//public_html</em> and so on.</li>
</ul>
<h3>suPHP and What&#8217;s Wrong With It</h3>
<p>Since PHP was mentioned several times already, here is another tool for isolating PHP applicaitons from each other: <a href="http://www.suphp.org">suPHP</a>. The difference is that PHP files are now executed with user privileges of the file owner - a bit more convenient and straightforward setup for PHP. You will often find suPHP used by shared hosting providers, it&#8217;s even one of the options in cPanel/WHM and there is an RPM available through Fedora Extras.</p>
<p>However, the list of our grievances with suEXEC applies to suPHP almost 100%. It&#8217;s still a CGI-based solution.</p>
<p>There are several of other options available, namely the:</p>
<h3>perchild  and Metux</h3>
<p><a href="http://httpd.apache.org/docs/2.0/mod/perchild.html">perchild</a> MPM is a<!--StartFragment --> &#8220;Multi-Processing Module allowing for daemon processes serving requests to be assigned a variety of different userids&#8221;. <a href="http://www.metux.de/mpm/en/?patpage=">Metux</a> MPM is a &#8220;project evolution from the perchild module&#8221;.</p>
<p>I haven&#8217;t had much experience with either (didn&#8217;t even try them, to be exact;) for one very simple reason - both of them are threaded and PHP and threaded Apache don&#8217;t mix. If you don&#8217;t have to run PHP applications (and all your other applications and libraries used are thread-safe) you can try them out. Unfortunately, it&#8217;s not an option for me.</p>
<h3>ITK MPM module</h3>
<p>The solution I found to be the best so far is  <a href="http://home.samfundet.no/~sesse/mpm-itk/">mpm-itk</a>. In short, here is how it works:</p>
<ol>
<li>It&#8217;s based on prefork MPM so like your regular Apache, it has a parent managing process and several child processes serving the requests.</li>
<li>Unlike the regular prefork model which has the managing process running as <em>root</em> and child processes as <em>apache/nobody</em>, ITK runs ALL processes as <em>root</em>.</li>
<li>Whenever a request is served by a child process, the child process determines what user credentials are needed for a particular VirtualHost (based on your config file, of course), then the child process sets effective user ID and group ID on itself to these credentials, completes the request and sets them back.</li>
</ol>
<p>What this means is this is next best thing to running a separate apache server per every user (and is actually better than that!). ALL your Apache modules still work (mod_php, mod_dav_svn, mod_python, etc.), they are restricted to a particular user specified in VirtualHost config and what&#8217;s best, your file READS in web applications are also confined to the privileges that specified user has.</p>
<p>Perfect!</p>
<p>Now, there&#8217;s gotta be some catch. And here it is (actually, two):</p>
<ul>
<li>Strictly speaking, even though all capabilities that root processes have are dropped in the child processes, the child processes are still running as root until the target user/group is determined - i.e. while the HTTP request is parsed. This means that if there is ever a vulnerability in request parsing, you have your vulnerable application with higher privileges than normal. This is somehow offset by the fact that it&#8217;s not your normal Apache anymore, and a lot of attacks based on stack overflow and expecting to find themselves inside a normal Apache code will probably just crash instead of executing their payload. Whether this is an affordable risk for you depends entirely on your application, sensitivity of your data and so on. I find it acceptable.</li>
<li>Second - it&#8217;s a patch, not a standard Apache feature, so some extra elbow grease is needed to get it working.</li>
</ul>
<p>While catch #1 is something we can&#8217;t do anything about, let&#8217;s work on catch #2.</p>
<h3>Building Apache2 RPMs With MPM-itk Support</h3>
<p>If you are like me, you like all your software packaged. I absolutely hate bash-based installers and <em>./configure - make - make install</em> bruhaha. RPM is there for a reason.</p>
<p>I also like distribution-specific patches to my applications - they typically are there for a reason, too. This reason is usually somebody having a problem with something, reporting it to RedHat/SuSE/(inser your favorite) and getting the stuff fixed. Losing distro-specific patches is not wise, to say the least.</p>
<p>What I often do with 3-rd party patches like MPM-itk is I <strong>re</strong>build &#8220;stock&#8221; RPMs using them, and that&#8217;s exactly what we are going to do now. My distribution of choice is <a href="http://www.redhat.com/rhel/">RedHat Enterprise Linux</a> (version 4 in this example), and it&#8217;s cheap twin brother, <a href="http://www.centos.org/">CentOS</a>. The directions are based on these 2 distributions, however your steps on SuSE/Mandriva should be very similar.</p>
<h3>The Ingredients</h3>
<p>We&#8217;ll  need:</p>
<ul>
<li>1 source httpd RPM. In our case, this will be httpd-2.0.52-22.ent.src.rpm for RHEL4 or httpd-2.0.52-22.ent.centos4.src.rpm for CentOS4</li>
<li>1 MPM-itk patch for it, either <a href="/filez/itk.RHEL.patch">itk.RHEL.patch</a> for RHEL4 or <a href="/filez/itk.CO4.patch">itk.CO4.patch</a> for CentOS4.</li>
</ul>
<p>Since you are getting the 2nd ingredient from me, I have to tell you what&#8217;s in it.</p>
<ul>
<li>both patches from <a href="http://home.samfundet.no/~sesse/mpm-itk/">http://home.samfundet.no/~sesse/mpm-itk/</a> ;</li>
<li>a small fix for <em>/etc/sysconfig/httpd</em> that adds <em>httpd.itk</em> as a possible alternative;</li>
<li>a small fix for <em>/etc/httpd/conf/httpd.conf </em>that adds default settings for MPM-itk mode - we copy all performance parameters from prefork&#8217;s defaults and make sure the default host runs as <em>apache/apache</em>, because otherwise it would run as <em>root</em>;</li>
<li>a little fix for PHP session files: in prefork mode, they are all saved to <em>/var/lib/php/session</em> - a directory owned by <em>apache</em> we can not use anymore, we have to use <em>/tmp</em>, like in good old times;</li>
<li>a small fix for RPM spec file to make it build, install and package <em>httpd.itk</em> in addition to prefork <em>httpd</em> and worker-based <em>httpd.worker</em></li>
</ul>
<p>That&#8217;s all. Now let&#8217;s get to building it.</p>
<h3>The Process</h3>
<p>Repeat after me:</p>
<p><code>I WILL NOT BUILD RPMS AS ROOT. EVER.</code></p>
<p>That is, if you don&#8217;t want to accidentally execute <em>rm -rf /</em> , otherwise referred to as &#8220;rite of passage&#8221; by Unix old-timers. Let&#8217;s log in as some other, regular user and do this:</p>
<p><code># cd
# mkdir src
# mkdir src/rpm
# mkdir src/rpm/BUILD src/rpm/RPMS/ src/rpm/SOURCES src/rpm/SPECS src/rpm/SRPMS
# echo -E %\_topdir /home/`whoami`/src &gt; .rpmmacros</code></p>
<p>Now we are ready for some RPM building. Let&#8217;s install our source RPM:</p>
<p><code># rpm -ivh httpd-2.0.52-22.ent.src.rpm
</code></p>
<p>patch it:</p>
<p><code># cp itk.RHEL.patch ~/src
# cd ~/src
# patch --strip=0 --backup --remove-empty-files --suffix=.itk
</code></p>
<p>and rebuild it:</p>
<p><code># rpmbuild -ba rpm/SPECS/httpd.spec</code></p>
<p>(example given for RHEL4, for CentOS4 build, replace the RPM name and patch name with the ones you need). If everything went well, your new httpd* RPMs are now in <em>rpm/RPMS/i386 </em>or <em>x86_64</em>. Grab them and install as usual.</p>
<h3>Switching to MPM-itk</h3>
<p>By default, these RPMs will still run Apache in &#8220;prefork&#8221; mode. To switch to mpm-itk mode,</p>
<ul>
<li>stop Apache <strong>(important!)</strong></li>
<li>edit <em>/etc/sysconfig/httpd:</em> uncomment (delete # in) the following line:<code>#HTTPD=/usr/sbin/httpd.itk</code></li>
<li>start Apache</li>
</ul>
<p>You can&#8217;t just edit <em>/etc/sysconfig/httpd</em> and restart httpd service - the httpd service script in sysv init  depends on this config file for starting and stopping httpd.</p>
<p>That&#8217;s it, you should be all set.</p>
<p>If you feel better at this time, you should probably send a &#8220;thank you&#8221; note to Steinar H. Gunderson (<a href="http://home.samfundet.no/~sesse/mpm-itk/">http://home.samfundet.no/~sesse/mpm-itk/</a>) who developed this great mod.
</p>
]]></content:encoded>
			<wfw:commentRSS>http://mitka.us/articles/mpm-itk/feed/</wfw:commentRSS>
		</item>
	</channel>
</rss>
