Gentoo Apache 2.2 update and 403 errors

September 22nd, 2007 by Sjan Evardsson

After upgrading my entire system, moving from Apache 2.0.x to 2.2.6 I ran into an interesting problem (actually, a couple.) Some of the configurations have moved, and things that used to be in the Gentoo dist httpd.conf have been broken out into config files in the /etc/apache2/modules.d/ directory. So, copying my old vhosts file in was not a good idea. And doing a merge of the old and new httpd.conf files was also a mistake. Once I figured out that I had the Listen 80 directive in one file and Listen 192.168.1.10:80 in another I understood why it failed to start. So, I fixed all the configs to match the new setup, and tried again. It started up just fine, and seemed okay, until I tried to connect. I kept getting 403 errors.

I went through the standard checks, checking the file permissions, .htaccess settings, and so on, to no avail. A quick Google search pointed me to the fix from Victor Trac. He found the offending bit in the new broken out config in /etc/apache2/modules.d/00_default_settings.conf where it contains:

<Directory />
        Options FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
</Directory>

The fix is either to change that to Allow from all and define Deny where needed in each virtual host or to override it in every virtual host. Since I tend to set up my hosts with the idea that the server allows everything and it is up to the host to deny where needed I chose the first option, reloaded Apache and everything is sweet again.

Edit:

I found I was having an error with the RewriteRules after switching from Apache 2.0.x to 2.2.x - I found the fix on the Gentoo forums, which required adding an extra RewriteCond line in the .htaccess file.

The old .htaccess: and the new:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress

and the new:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !\.php$
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress

Technorati Tags: , ,

Apache 2.2.6, PHP 5.2.4 and MySQL 5.0.45 on OS X

September 17th, 2007 by Sjan Evardsson

I got tired of looking for a way to replace the Apache/PHP that Apple packages with OS X (without breaking anything else in the process) so I decided to install Apache 2.2 and PHP5 in their own location to avoid stepping on the Apple package toes.

Since I do a great deal of development again MySQL I needed to install that as well, and figured that I would probably need the GD functionality as well so I grabbed libjpeg and libpng to make those work as well. This is the step-by-step.

(Props to James Pelow and his article from last year, from which I borrowed the configure command lines and configuration modifications, as well as the idea of installing the whole mess in /apache2.)

Download the latest MySQL (I used the package version) from MySQL.

Installation is straightforward following the same methods as any other Mac installer.

Download and install libjpeg and libpng - from Ethan Tira-Thompson (this is also in a Mac installer which contains both libraries in one installer).

Download the latest Apache httpd server (Unix source) from Apache

in the terminal:

tar -xzvf httpd-2.2.6.tar.gz && cd httpd-2.2.6

./configure

--prefix=/apache2

--enable-module=most

--enable-shared=max

make

sudo make install

sudo mkdir /apache2/php

Download the latest PHP from PHP

tar -xzvf php-5.2.4.tar.gz && cd php-5.2.4

./configure

--prefix=/apache2/php

--with-zlib

--with-xml

--with-ldap=/usr

--enable-cli

--with-zlib-dir=/usr

--enable-exif

--enable-ftp

--enable-mbstring

--enable-mbregex

--enable-dbx

--enable-sockets

--with-iodbc=/usr

--with-curl=/usr

--with-mysql=/usr/local/mysql

--with-gd

--with-jpeg-dir=/usr/local

--with-png-dir=/usr/local
--with-apxs2=/apache2/bin/apxsmake

sudo make install

sudo cp php.ini-dist /apache2/php/lib/php.ini

Now to make your Apache2.2 a little more ‘Mac’ - you can point it at the Mac web shared files folder, change the user and group and change the location for user files to match the Mac folder system.

Edit httpd.conf (I use nano, you can use any flat text editor like nano, pico, vi, emacs or even BBedit)

sudo nano -w /apache2/conf/httpd.conf

The changes to httpd.conf I made:
I changed

User daemon
Group daemon

to

User www
Group www

and

DocumentRoot "/apache2/htdocs"

to

DocumentRoot "/Library/WebServer/Documents"

and

<Directory "/apache2/htdocs">

to

<Directory "/Library/WebServer/Documents">

and added

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

DirectoryIndex index.html index.php

Edit httpd-userdir.conf

sudo nano -w /apache2/conf/extra/httpd-userdir.conf

The changes to httpd-userdir.conf I made:
I changed

UserDir public_html

to

UserDir Sites

To start and stop the server:
MySQL comes with a Preference Pane that allows you to start and stop it there. To start and stop Apache you need to first make sure that the default Apache shipped with OS X is stopped.

sudo /apache2/bin/apachectl start
sudo /apache2/bin/apachectl stop

I only ran into one issue, when trying to start the server I ran against the following error message (and no running server, of course):

httpd: Syntax error on line 53 of /apache2/conf/httpd.conf:
Cannot load /apache2/modules/libphp5.so into server:
Library not loaded: /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib
Referenced from: /apache2/modules/libphp5.son  Reason: image not found

To fix this I did the following:

cd /usr/local/mysql/lib
sudo mkdir /usr/local/mysql/lib/mysql

for i in `ls ./l*`; do sudo ln -sf /usr/local/mysql/lib/$i /usr/local/mysql/lib/mysql/$i; done

This creates soft links in the directory that libphp5.so is looking for the MySQL libraries.

Then it started right up! Wheee! (I did a quick test by dropping PhpMyAdmin into the /Library/WebServer/Documents folder and browsed to it - the whole Apache/PHP/MySQL is working correctly)

Technorati Tags: , , ,

Useful custom 403 and 404 error pages with PHP

June 11th, 2007 by Sjan Evardsson

While this is certainly nothing new, it seems to be too often overlooked. Apache allows an ErrorDocument Directive in the configuration that will point at a custom document. Using this can have some benefits to the user and to the site administrator.

While Apache allows for error documents located at a remote URL (ie anything starting with http://) this causes Apache to send a redirect to the browser, even if the document resides on the same server. This is not a good idea, as the documentation points out.

This has several implications, the most important being that the client will not receive the original error status code, but instead will receive a redirect status code. This in turn can confuse web robots and other clients which try to determine if a URL is valid using the status code. In addition, if you use a remote URL in an ErrorDocument 401, the client will not know to prompt the user for a password since it will not receive the 401 status code. Therefore, if you use an ErrorDocument 401 directive then it must refer to a local document.

Using a local document for handling errors, however, gives you the ability to override the default Apache messages, which are often replaced by the browser with their own, internal error messages (MSIE, I’m talking about you.) Besides giving you the ability to match the error page to your site, you can use some simple PHP to make it more informative for both the end user and the site admin. Instead of just saying “File so-and-so doesn’t exist, sorry” you can make a page that allows the user to send a message to the admin. If you wish, you can have the page automatically mail the information, although that can quickly lead to hundreds of emails as users mis-type urls, spiders follow old links, and scripts search your LAMP site for IIS vulnerabilities. Trust me on that one, it’s a bad idea that won’t outlive the weekend.

With that in mind here a couple samples that you can build from.

Sample 403 error page:

  1. <?php
  2. print "<html>
  3. <head>
  4. <title>Sample 403 Error Document</title>
  5. </head>
  6. <body>"
  7. $server = $_SERVER[‘SERVER_NAME’];
  8. $uri = $_SERVER[‘REQUEST_URI’];
  9. $bad_link = $server.$uri;
  10. // Note that the referer cannot be completely trusted
  11. // as some agents either do not set a referer or allow
  12. // the user to modify the referer at will. It is, however,
  13. // often useful for troubleshooting.
  14. $referer = $_SERVER[‘HTTP_REFERER’];
  15. $remote = $_SERVER[‘REMOTE_ADDR’];
  16. print "<h1>403: Forbidden</h1>
  17. <p>&nbsp;</p>";
  18. if ($uri == ‘/403/403.php’) {
  19.         print "<p>You have reached the custom 403 error page for mysite.com. Was it everything you were hoping for?</p>";
  20. }
  21. else if (substr($uri, -1, 1) == ‘/’) {
  22.     print "<p>Sorry, this directory cannot be browsed.</p>
  23.     <p>If you received this message by clicking on a link on this website, please <a href=\"mailto:webmaster@mysite.com?subject=403: Bad Directory Link&body=$bad_link from $referer\">report it to the webmaster</a>.</p>";
  24. }
  25. else {
  26.     print "<p>You have attempted to access a resource (<?=$uri?>) for which you do not have the proper authorization or which is not available from your location.</p>
  27.     <p>If you received this message by clicking on a link on this website, please <a href=\"mailto:webmaster@mysite.com?subject=403 Error&body=$bad_link from $referer reached by $remote\">report it to the webmaster</a>.</p>";
  28. }
  29. print "</body>
  30. </html>
  31. ";
  32. ?>

Sample 404 error page:

  1. <?php
  2. print "<html>
  3. <head>
  4. <title>Sample 403 Error Document</title>
  5. </head>
  6. <body>"
  7. $server = $_SERVER[‘SERVER_NAME’];
  8. $uri = $_SERVER[‘REQUEST_URI’];
  9. $bad_link = $server.$uri;
  10. // Note that the referer cannot be completely trusted
  11. // as some agents either do not set a referer or allow
  12. // the user to modify the referer at will. It is, however,
  13. // often useful for troubleshooting.
  14. $referer = $_SERVER[‘HTTP_REFERER’];
  15. print "<h1>404: File Not Found</h1>
  16. <p>&nbsp;</p>";
  17. if ($uri == ‘/404/404.php’) {
  18.     print "<p>You have reached the custom 404 error page for mysite.com. Was it everything you were hoping for?</p>";
  19. }
  20. else {
  21.     print "<p>Sorry, that file (<?=$uri?>) does not seem to exist.</p>
  22.     <p>If you received this message by clicking on a link on this website, please <a href=\"mailto:webmaster@mysite.com?subject=Bad Link&body=$bad_link from $referer\">report it to the webmaster</a>.</p>";
  23. }
  24. print "</body>
  25. </html>
  26. ";
  27. ?>

Of course you would make sure the styles, links, mailtos, site name, etc are right for your site, but this gives you an idea.

Technorati Tags: , ,

Getting the latest and greatest

April 8th, 2007 by Sjan Evardsson

I love (almost) everything about my new Mac. From a hardware standpoint I am ecstatic. The operating system is very nice (although I wish I could have waited until 10.5 so I could have multiple desktops like every other *nix variant.) The bundled tools are, for the most part, useful and usable - with one exception: the versions of Apache and PHP included.

Sure, there are plenty of people out there hosting on Apache 1.3.x and still plenty more using PHP 4.x - but I’m not one of them. At the very least I need to have a working Apache 2.0.x and PHP 5.x so I can test before deploying on my production server. There are plenty of guides online to add Apache 2.x and/or PHP5, but nothing on replacing the defaults. While I am all ok with testing on multiple versions, the multiple versions I would rather test on would be 2.0.x as default and 2.2.x as the upgradeability testbed.

I’m sure there is a way to do this, I just have to find it …

Technorati Tags: , ,

Apache 2.2 is out

February 4th, 2006 by Sjan Evardsson

I realize I am a little late in posting this, but Apache have announced the release of Apache 2.2. From a quick look at the release notes it looks like they have gotten the cache handlers working and stable, including a cache cleaning portion.

Now the question is, do I stick with 2.0.5x or I do I jump on the 2.2 train?