<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Terminus a Quo &#187; Apache</title>
	<atom:link href="http://abing.gotdns.com/posts/category/system-administration/apache/feed/" rel="self" type="application/rss+xml" />
	<link>http://abing.gotdns.com</link>
	<description>Because you can never have too many blogs on the Internet...</description>
	<lastBuildDate>Tue, 19 May 2009 00:23:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>WordPress: Error 404 When Publishing or Saving Post</title>
		<link>http://abing.gotdns.com/posts/2006/wordpress-error-404-when-publishing-or-saving-post/</link>
		<comments>http://abing.gotdns.com/posts/2006/wordpress-error-404-when-publishing-or-saving-post/#comments</comments>
		<pubDate>Wed, 05 Jul 2006 18:21:19 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[System Administration]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/2006/07/06/40/</guid>
		<description><![CDATA[If you have ever encountered an &#8220;Error 404&#8243; message when publishing or saving a post under WordPress. It would seem that WordPress will randomly generate this error, regardless of post length or whatever. You should consult your hosting provider if this is the case, it&#8217;s probably because your webserver is configured with mod_security enabled.

The Mysterious [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>If you have ever encountered an &#8220;Error 404&#8243; message when publishing or saving a post under WordPress. It would seem that WordPress will randomly generate this error, regardless of post length or whatever. You should consult your hosting provider if this is the case, it&#8217;s probably because your webserver is configured with mod_security enabled.</p>

<p><span id="more-40"></span></p>

<h3>The Mysterious Random 404</h3>

<p>I&#8217;ve been wrangling with these mysterious &#8220;Error 404&#8243; messages that I &#8220;randomly&#8221; get whenever I post an article on this blog. For instance, while editing the article [PHP4 and PHP5 Side-by-Side Installation on Breezy][php4php5], I was continuously plagued with this error. It turns out, after a lot of trial and error, that the problem is caused [by mod_security][mod_security]. After discovering this, I went out and [posted][wp_forum_post] on the WordPress forums. It turns out, a lot of WordPress users seem to be having this problem.</p>

<p>I posted on the forum about 3 months ago and eventually, I forgot about it. Until it bit me in the ass again today. I tried to update [PHP4 and PHP5 Side-by-Side Installation on Breezy][php4php5] today to point out that it also works under &#8220;Dapper&#8221;. There it was again &#8212; Error 404. The funny thing is, if I saved the unmodified article, I still get the Error 404. It was only about 3 months ago that I posted it, and it passed mod_security validation. So through the same trial and error process described below, I was able to update the article.</p>

<h3>mod_security</h3>

<p>mod_security works by intercepting requests to the webserver, be it a GET request or a POST request. When you post an article to WordPress by clicking &#8220;Save and Continue Editing&#8221;, &#8220;Save&#8221;, or &#8220;Publish&#8221;, a POST request is made to your server. This request is then intercepted by mod_security which does some analysis of the POST&#8217;ed data. Based on filtering rules set forth by your hosting provider, your post will either pass or fail to validate. If your POSTed data fails to validate, the default action would be to generate a 404 error.</p>

<h3>Working Around mod_security</h3>

<h4>Temporarily Disabling mod_security</h4>

<p>The best way to work around mod_security is to disable it while you are posting and <strong>enable</strong> it when you are done posting. If you are under virtual hosting like myself, you would be lucky if you are allowed to turn off mod_security via .htaccess. To check out if you are able to turn off mod_security this way, add<sup>[1][note1]</sup> the following lines to your .htaccess file:</p>

<pre><code>&lt;ifmodule mod_security.c&gt;
SecFilterEngine Off
SecFilterPost Off
&lt;/ifmodule&gt;
</code></pre>

<p>Upload your update .htaccess file back to your server. Then check if your configuration worked by visiting your home page. If you see your home page, then the above configuration works. Now you should be able to post anything without it being intercepted by mod_security. If the above configuration does not work (i.e., you get an &#8220;Internal Server Error&#8221; instead), you might want to try the next one. Remove the above configuration from your .htaccess and replace it with the following:</p>

<pre><code>&lt;ifmodule mod_env.c&gt;
SetEnv MODSEC_ENABLE Off
PassEnv MODSEC_ENABLE
&lt;/ifmodule&gt;
</code></pre>

<p>Upload your updated .htaccess file. Then visit your home page and make sure that it does not generate an &#8220;Internal Server Error&#8221;. Most of the time, the SetEnv directive does not cause an &#8220;Internal Server Error&#8221;. It only requires <code>FileInfo</code> permissions to use it in your .htaccess and most hosting providers allow <code>FileInfo</code> by default. Try posting the problematic post (i.e., the one that causes the 404 error) and see if it works. If it does not work<sup>[2][note2]</sup>, then you are out of luck and must resort to the &#8220;infernal HTML entities work-around&#8221;.</p>

<p>Let me stress the point that if either one of the the above configuration settings work for you, you should <strong>not</strong> make them permanent. Your hosting provider installed mod_security to protect the sites that they are hosting. If you leave mod_security disabled and your site gets broken into <img src='http://abing.gotdns.com/wp-includes/images/smilies/icon_confused.gif' alt=':?' class='wp-smiley' />  it will be <strong>your fault</strong>!</p>

<h4>Infernal HTML Entities</h4>

<p>So you&#8217;ve tried disabling mod_security and it did not work, what do you do now? Well, you can try working around mod_security by &#8220;fooling&#8221; it. As of mod_security version 1.9.x, it seems that HTML entities will pass through just fine. However, before you think of encoding your entire post into HTML entities <img src='http://abing.gotdns.com/wp-includes/images/smilies/icon_eek.gif' alt=':shock:' class='wp-smiley' />  you should keep in mind that mod_security filters only certain word combinations. You can ask your hosting provider what rules they use for mod_security, but I doubt that they will give you that information. If they do give it to you, you will need to decipher them. See the mod_security documentation for that.</p>

<p>Unless you are able to acquire the mod_security rules from your hosting provider and you are able to decipher them, your only option would be to discover those rules by trial and error. First save your troublesome article text into a file. Then post the contents of the file <em>paragraph by paragraph</em> (i.e., post the first paragraph, then the second one, so on&#8230;). When you encounter the 404 error on a certain paragraph, stop right there and post the first sentence of the offending paragraph. Continue posting the sentences of the offending paragraph until you hit the sentence that causes a 404 error. From there, you should post the sentence word by word until you find the word that causes the 404 error.</p>

<p>When you find the word that causes the 404 error, modify the word by encoding any of the characters in the word using HTML entitiesm you can use [this table][htmlentities] for reference. For example, I&#8217;ve found that through trial and error, my post triggers the 404 error when the word &#8220;curl&#8221; appears in the text along with other words. Using the table [here][htmlentities], I encode &#8216;c&#8217; into its HTML entity like so:</p>

<pre><code>&amp;#99;url
</code></pre>

<p>If you look up the character for the decimal value 99 in the [table][htmlentities], you will find that it&#8217;s the character &#8216;c&#8217;. Now, try posting the encoded text. You should now be able to post it without problems and you can continue with your trial and error or you can try posting the remainder of your text file after the encoded word and see if it gets posted without errors.</p>

<p>That&#8217;s it. Good luck and happy hunting!</p>

<p>NOTES:</p>

<p><a name="note1"><sup>1</sup></a> If you are using &#8220;pretty URLs&#8221; for WordPress, make sure you download your current .htaccess file and add the mod_security directives to it.</p>

<p><a name="note2"><sup>2</sup></a> In my case, using <code>SetEnv</code> did not work. I think it has something to do with my PHP installation. On the server hosting this blog, PHP is installed as a CGI binary. Even <code>PassEnv</code> does not seem to work.</p>

<p>[php4php5]: http://abing.gotdns.com/2006/03/14/9/ &#8220;Permanent link to PHP4 and PHP5 Side-by-Side Installation on Breezy&#8221;
[mod_security]: http://www.modsecurity.org/projects/modsecurity/apache/index.html &#8220;ModSecurity &#8211; ModSecurity for Apache&#8221;
[wp_forum_post]: http://wordpress.org/support/topic/61431/page/3 &#8220;WordPress Support Forums: 404 after save or publish a post&#8221;
[note1] #note1 &#8220;Note 1&#8243;
[note2] #note2 &#8220;Note 2&#8243;
[htmlentities]: http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/iso_table.html &#8220;ISO 8859-1 (Latin-1) Characters List&#8221;</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2006/wordpress-error-404-when-publishing-or-saving-post/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PHP4 and PHP5 Side-by-Side Installation on Breezy</title>
		<link>http://abing.gotdns.com/posts/2006/php4-and-php5-side-by-side-installation-on-breezy/</link>
		<comments>http://abing.gotdns.com/posts/2006/php4-and-php5-side-by-side-installation-on-breezy/#comments</comments>
		<pubDate>Tue, 14 Mar 2006 09:26:24 +0000</pubDate>
		<dc:creator>nimrod.abing</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Code and Consequences]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[System Administration]]></category>
		<category><![CDATA[Ubuntu Linux]]></category>

		<guid isPermaLink="false">http://abing.gotdns.com/2006/03/14/php4-and-php5-side-by-side-installation-on-breezy/</guid>
		<description><![CDATA[This how I got to install PHP4 and PHP5 under Ubuntu Breezy. This
should also work in other distributions which have at least two
different installation options for PHP. It is also possible for you to
install PHP4 or PHP5 from source1 if your distribution does not provide
with you options (i.e. installing the PHP4 or PHP5 package would
result [...]
<p>a</p>
]]></description>
			<content:encoded><![CDATA[<p>This how I got to install PHP4 and PHP5 under Ubuntu Breezy. This
should also work in other distributions which have at least two
different installation options for PHP. It is also possible for you to
install PHP4 or PHP5 from source<a href="#note1" title="Note 1"><sup>1</sup></a> if your distribution does not provide
with you options (i.e. installing the PHP4 or PHP5 package would
result in installing CLI, CGI, and Apache module versions).</p>

<p><em>Update July 6, 2006: This tutorial has been tested and is known to work under Ubuntu Linux 6.06 LTS (aka &#8220;Dapper Drake&#8221;).</em>
<span id="more-9"></span></p>

<p>Under Ubuntu (or Debian), there are three options:</p>

<ol>
<li><p>PHP is installed as an Apache (or Apache2) module</p></li>
<li><p>PHP is installed as a CGI binary</p></li>
<li><p>PHP is installed as a CLI binary</p></li>
</ol>

<p>The first two installation options are for Web-based applications. The
third option is used if you want to use PHP as a scripting language
for command line programs.</p>

<p>With a side-by-side installation, you can install one version of PHP
as an Apache module and the other version as a CGI binary. If you
like, you can also install them both as CGI binaries. It requires a
bit more work (at the moment) to have them both installed as an Apache
module since you would have to forgo your distribution&#8217;s package
management system and install PHP4 and PHP5 from source.</p>

<p>Your choice if installation is entirely up to you. You can choose from
one of the following setups:</p>

<p>A. PHP4 is installed as an Apache module; PHP5 is installed as a CGI
   binary</p>

<p>B. PHP5 is installed as an Apache module; PHP4 is installed
   as a CGI binary</p>

<p>C. both PHP4 and PHP5 are both installed installed
   as CGI binaries</p>

<p>The easiest route to take is to install these packages using
apt-get. For my setup, I chose setup A: PHP4 as an Apache module and
PHP5 as a CGI binary. This setup is ideal for virtual hosting
environments where you want your customers to have PHP4 as the default
PHP version and PHP5 as an available alternative.</p>

<p>To begin, install PHP4 as an Apache (or Apache2) module:</p>

<p>Apache 1.3.x:</p>

<pre><code>$ sudo apt-get install libapache-mod-php4
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>$ sudo apt-get install libapache2-mod-php4
</code></pre>

<p>That should install the core PHP4, which is next to useless without
some extensions:</p>

<pre><code>$ sudo apt-get install php4-<span>&#99;url</span> php4-domxml php4-gd php4-mcrypt php4-mhash php4-mysql php4-pgsql php4-sqlite php4-xslt
</code></pre>

<p>Once you have installed all the modules you need, check that you have
Apache or Apache2 up and running and verify that your configuration
was updated:</p>

<p>Apache 1.3.x:</p>

<pre><code>$ sudo kill -0 `cat &#47;var&#47;run/apache.pid` &#038;&#038; echo "Apache is running."
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>$ sudo kill -0 `cat &#47;var&#47;run/apache2.pid` &#038;&#038; echo "Apache is running."
</code></pre>

<p>You should see the message &#8220;Apache is running&#8221;. If you see an error
message instead, then you should try to start Apache first:</p>

<p>Apache 1.3.x:</p>

<pre><code>$ sudo invoke-rc.d apache start
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>$ sudo invoke-rc.d apache2 start
</code></pre>

<p>Once you have Apache up and running, check to see if you have
successfully configured PHP4, you can use the <code>HEAD</code> Perl program from
libwww-perl:</p>

<pre><code>$ HEAD http://localhost/ | grep PHP
Server: Apache/2.0.54 (Ubuntu) mod_fastcgi/2.4.2 PHP/4.4.0-3ubuntu2 mod_ssl/2.0.54 OpenSSL/0.9.7g mod_perl/2.0.1 Perl/v5.8.7
</code></pre>

<p>Or, you can use the <code><span>&#99;url</span></code> client from the <span>&#99;url</span> package:</p>

<pre><code>$ <span>&#99;url</span> --head http://localhost/ | grep PHP
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
Server: Apache/2.0.54 (Ubuntu) mod_fastcgi/2.4.2 PHP/4.4.0-3ubuntu2 mod_ssl/2.0.54 OpenSSL/0.9.7g mod_perl/2.0.1 Perl/v5.8.7
</code></pre>

<p>If you see output similar to the ones above (contains the text PHP)
then your setup is now working properly.</p>

<p>Next step is to install PHP5 as a CGI binary:</p>

<pre><code>$ sudo apt-get install php5-cgi
</code></pre>

<p>This will install all the packages needed to have a core PHP5
installation. Again this would be next to useless without the
extensions:</p>

<pre><code>$ sudo apt-get install php5-<span>&#99;url</span> php5-gd php5-mhash php5-mysql php5-pgsql php5-sqlite php5-&#120;mlrpc php5-xsl
</code></pre>

<p>Once you are done installing all the extensions you need, it&#8217;s time to
configure your Apache webserver:</p>

<p>Apache 1.3.x:</p>

<pre><code>$ sudo gedit /etc/apache/sites-enabled/default
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>$ sudo gedit /etc/apache2/sites-enabled/default
</code></pre>

<p>Add the following just before the line that says <code>&lt;/VirtualHost&gt;</code>:</p>

<pre><code>Action php5-script /cgi-bin/php5
AddHandler php5-script .php5
</code></pre>

<p>This will define a new content handler and default action for files with a <code>.php5</code>
extension. This directive will apply to your default virtual host.</p>

<p>Then restart Apache:</p>

<p>Apache 1.3.x:</p>

<pre><code>$ sudo invoke-rc.d apache restart
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>$ sudo invoke-rc.d apache2 restart
</code></pre>

<p>Try it out:</p>

<p>Apache 1.3.x:</p>

<pre><code>sudo gedit &#47;var&#47;www/apache-default/phpinfo.php5
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>sudo gedit &#47;var&#47;www/apache2-default/phpinfo.php5
</code></pre>

<p>Enter the following lines and save the resulting document:</p>

<pre><code>&lt;?php
phpinfo();
?&gt;
</code></pre>

<p>Then with your browser, open the URL <code>http://localhost/phpinfo.php5</code>:</p>

<pre><code>$ sensible-browser http://localhost/phpinfo.php5
</code></pre>

<p>If you see the auto-generated phpinfo page, then congratulations! You
now have PHP4 and PHP5 installed on your server.</p>

<p>If you want to use setup B, just exchange php4 and php5 in the
installation commands above and when you setup the <code>Action</code> and
<code>AddHandler</code> directive, you should use <code>.php4</code> instead of <code>.php5.</code></p>

<p>If you want to use setup B, do not install PHP4 as an Apache module as
instructed above. Instead install the CGI binary:</p>

<pre><code>$ sudo apt-get install php4-cgi
</code></pre>

<p>And then proceed to install the PHP4 modules. Then setup the <code>Action</code>
and AddHandler directives for PHP4:</p>

<pre><code>$ sudo gedit /etc/apache2/sites-enabled/default
</code></pre>

<p>Add the following just before the line that says :</p>

<pre><code>Action php4-script /cgi-bin/php5
AddHandler php4-script .php4
</code></pre>

<p>If you want the server to handle the .php extension as PHP4, add
another line:</p>

<pre><code>AddHandler php4-script .php
</code></pre>

<p>Restart Apache:</p>

<p>Apache 1.3.x:</p>

<pre><code>$ sudo invoke-rc.d apache restart
</code></pre>

<p>Apache 2.0.x:</p>

<pre><code>$ sudo invoke-rc.d apache2 restart
</code></pre>

<h2>PHP CGI Binary Installation and suExec with Apache2</h2>

<p>One of the great things when you have setup PHP to run as a CGI binary
with Apache 2 is that you get the capability to run it under
<a href="http://httpd.apache.org/docs/2.0/suexec.html" title="Apache 2.0 suExec">suExec</a>. What this means is that if your script requires write
privileges to a directory under the document root, you no longer have
to make that directory world writeable. If you use Smarty with caching
enabled, then you are probably familiar with this requirement.</p>

<p>suExec should already be installed when you installed Apache2, since
it comes in the apache2-common package. All you need to do is enable
it:</p>

<pre><code>$ cd /etc/apache2/mods-enabled
$ sudo ln -s /etc/apache2/mods-available/suexec.load .
</code></pre>

<p>Then start and stop Apache2 (force reload may not be enough to enable
it):</p>

<pre><code>$ sudo invoke-rc.d apache2 stop
$ sudo invoke-rc.d apache2 start
</code></pre>

<p>Check that Apache2 has indeed loaded suExec:</p>

<pre><code>$ cat &#47;var&#47;log/apache2/error.log|grep suexec
[Sat Dec 24 15:42:14 2005] [notice] suEXEC mechanism enabled (wrapper: /usr/lib/apache2/suexec2)
</code></pre>

<p>You should see something like the output above to indicate that suExec
is now properly installed. If not, check the output of the following
command:</p>

<pre><code>$ ls -l /usr/lib/apache2/suexec2
-rwsr-x---  1 root www-data 10332 2005-12-06 00:36 /usr/lib/apache2/suexec2
</code></pre>

<p>Note that the setuid bit must be set as above. If it is not, then:</p>

<pre><code>$ sudo chmod +s /usr/lib/apache2/suexec2
</code></pre>

<p>And stop and start Apache2 again. Check that you have suExec loaded
and if it is, then proceed with the following:</p>

<pre><code>$ cd &#47;var&#47;www
$ sudo cp /usr/lib/cgi-bin -r
$ sudo chown www-data:www-data cgi-bin -R
$ sudo chown www-data:www-data apache2-default -R
$ sudo gedit /etc/apache2/sites-enabled/default
</code></pre>

<p>Insert the following lines before the line that says <code>&lt;/VirtualHost&gt;</code>:</p>

<pre><code>&lt;IfModule mod_suexec.c&gt;
    SuexecUserGroup www-data www-data
&lt;/IfModule&gt;
</code></pre>

<p>Then restart Apache2:</p>

<pre><code>$ sudo invoke-rc.d apache2 restart
</code></pre>

<p>To test your new suExec setup, try the following:</p>

<pre><code>$ sudo gedit &#47;var&#47;www/apache2-default/suexectest.php5
</code></pre>

<p>Enter the following and save the resulting file:</p>

<pre><code>&lt;?php
$fp = fopen('example.txt', 'a+');

$hello = "Hello World!\n";

fwrite($fp, $hello, strlen($hello));

fclose($fp);
readfile('example.txt');
?&gt;
</code></pre>

<p>Then on the command line enter the following:</p>

<pre><code>$ sudo chown www-data:www-data &#47;var&#47;www/apache2-default/suexectest.php5
$ sensible-browser http://localhost/suexectest.php5
</code></pre>

<p>You should see the phrase <code>Hello World!</code> in your
browser window to confirm that suExec works.</p>

<p>Note that the following directives are used in a <code <VirtualHost</code>
container<a href="#note2" title="Note 2"><sup>2</sup></a>:</p>

<pre><code>SuexecUserGroup
Action
AddHandler
</code></pre>

<p>So this means if you tweak the parameters a bit, you can enable it for
other virtual hosts on your server. To enable suExec for a virtual
host, remember the following:</p>

<ol>
<li>The virtual host document root and </code><code>cgi-bin</code> must be under <code>&#47;var&#47;www/</code></li>
</ol>

<pre><code>&#47;var&#47;www/customer/html</code> and <code>&#47;var&#47;www/customer/cgi-bin
</code></pre>

<ol>
<li><p>The owner and group of the document root and cgi-bin directories
must be the same as the owner and group you set with
SuexecUserGroup for that virtual host.</p>

<p>e.g.: If you have SuexecUserGroup ucustomer1 gcustomer1, then:</p></li>
</ol>

<pre><code>$ sudo chown ucustomer1:gcustomer1 &#47;var&#47;www/customer -R
</code></pre>

<p>NOTES:</p>

<p><a name="note1"><sup>1</sup></a> Article is already in progress. I will post it here
as soon as I find the time (and energy) to finish it.</p>

<p><a name="note2"><sup>2</sup></a> You can also have the Action and AddHandler directives
in your .htaccess file to provide per-directory configuration. However, your virtual host
must be configured to <code>AllowOverride</code> at least <code>FileInfo</code>.</p>

<p>a</p>
]]></content:encoded>
			<wfw:commentRss>http://abing.gotdns.com/posts/2006/php4-and-php5-side-by-side-installation-on-breezy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
