I have a client who uses DreamHost for their Drupal powered web site. They are happy with their service overall, and intend to stay with them. The client is on Drupal 4.6. Although this article focuses on Drupal, much of it applies to about any PHP application you use.
One issue surfaced a short while ago, where randomly, where a string like ?PHPSESSID= would appear in the URLs while users are browsing, like http://example.com/node?PHPSESSID=7dd1d5d1471fa8be2fea8f163cce3257.
This string is a Session ID at the PHP level, and is known to appear when PHP is not setup properly.
Having the PHPSESSID in the URL is not only ugly, but also a security risk. If you visit a page from a certain web site that has PHPSESSID turned on, a malicious admin on the site you are visiting can gain your privileges on that certain site.
For these two reason, you do not want the PHPSESSID in your URLs.
Normally, the solution to this seems simple, and has several options:
Since Drupal 4.6, we had the appropriate init_set() parameters in the file at sites/yoursitedomain/settings.php that should modify the needed parameters for you automatically.
However, not all hosts allow that. So often, you need to put the following two lines in the .htaccess file, if your host is using PHP as an Apache module:
php_value session.use_only_cookies 1
php_value session.use_trans_sid 0
Using a local php.ini
To make things more complicated, some hosts use PHP as a CGI executable. Many use this as an suExec environment, such as that from suphp.org.
For PHP as CGI, you need to make the changes in a file called php.ini that has a slightly different format. The above parameters would look like this:
session.use_only_cookies = 1
session.use_trans_sid = 0
Using url_rewriter.tags Workaround
Some people have reported that setting the following parameter to an empty string fixes the PHPSESSID problem as well.
url_rewriter.tags = ''
Still, in some other hosts they do not allow overriding certain parameters, and hence you have to resort to compiling PHP on your own.
Patching Drupal 4.6
If you are running Drupal 4.6, you can apply this patch, which eliminates PHPSESSIDs in redirects.
Compiling PHP as CGI
Almost no host will allow you to compile PHP as an Apache module, but only as a CGI executable.
While this has its advantages, it can be slower and more resource intensive than PHP as a module. This is because Apache now has to do a fork() system call and create a separate process, and then destroy it, for each web page that is loaded in someone's browser. I know of two cases where DreamHost sent warning messages to clients who use PHP as CGI because of excessive CPU usage.
In the rest of this article, we will discuss how to rebuild PHP as a CGI executable on your account. Although this was done on DreamHost, much of it could be applied elsewhere.
Compiling PHP5 for Drupal on DreamHost
The process consists of several steps: downloading PHP source distribution, extracting PHP, identifying which config parameters to build with, doing the actual complie, copying the executable, creating a php.ini file, and testing the results.
These instructions assume several things are in place: That you are hosting on Linux or some other UNIX flavor. That you have Shell access via ssh. That you are not shy using the command line.
Downloading PHP Source
To download PHP source, visit the PHP.net web site, and click on download, then follow the instructions. Either use the wget command on your Linux hosting account, or download to your personal computer and upload to your account.
If you downloaded the bz2 format, then use the command:
tar xjvf php-5.xx.xx.tar.bz2
If you downloaded the gz format, then use the command:
tar xzvf php-5.xx.xx.tar.gz
You now have a directory that contains the PHP source.
Identifying Config Parameters
In order to have a starting point that is closest to what you were using, you have to use the phpinfo() function call to find out which config parameters were used to build PHP on your host.
To do so, create a file called phpinfo.php and place it in your hosting account in the same directory where the Drupal index.php file is. It should contain one line with the following in it:
<?php phpinfo(); ?>
Then, point your browser to http://example.com/phpinfo.php and read the output carefully to see the build options.
Creating the configure script
First change the directory to the php-5.xx.xx directory that you extracted PHP source into.
After you identify the config parameters, create a file in the same directory called compile.sh and put in it the following commands:
The actual config parameters used should be that most closely resemble what you found out from the pervious step.
The important part is to set a DIR= line, and have a --with-config-file-path=$DIR line.
To compile PHP, use the command:
Wait until you get a prompt with no errors reported.
Copying the PHP Executable
You now need to copy the PHP executable to a place where Apache can execute it for your .php files.
First, we create a directory, then we copy the files, as follows:
cp sapi/cgi/php ../example.com/cgi-bin/php.cgi
chmod 755 example.com/cgi-bin
chmod 755 example.com/cgi-bin/php.cgi
Modify the .htaccess file
DreamHost allows each user to have their own custom compiled PHP excecutable. In order to point to the correct one, you need to add the following two lines to your .htaccess file:
AddHandler custom-php .php
Action custom-php /cgi-bin/php.cgi
Not all hosts allow such override, so check with your host before you attempt this.
Creating a new local php.ini
You now have to create a php.ini file and place it in the DIR= location that was specified in a step above. The best strategy is to start with the php.ini file of your host (this is normally in /etc/php/cgi/php.ini or better yet, check the output from phpinfo.php above for the exact location).
At a minimum, the following parameters should be set as follows:
register_globals = Off
magic_quotes_gpc = Off
session.use_only_cookies = On
session.use_trans_sid = 0
Optionally, set the following parameters too. Note that the cookie_lifetime paramter is the duration to keep Drupal users logged in.
session.save_handler = user
session.cookie_lifetime = 604800
Verification and Testing
Now that you have done all the above, you need to make sure that it indeed works. To do this, point your browser to the phpinfo.php page (as per above instructions) and check the above four parameters. Make sure that they changed to the new values.
Of course, the final proof of the pudding is to eat it: access your site in the browser and see of the PHPSESSID is gone!
Problems and Troubleshooting
If you get Error 500 (Internal Server Error), then check the following:
- Your host may not allow the AddHandler directive in the .htaccess file.
- You did not set the correct permissions on the php.cgi executable, the etc directory, the etc/php.ini file, or the cgi-bin directory.
If your site is high traffic, the above may not help after all. Dreamhost, like some other hosting companies, monitor CPU resource usage. They may flag your account as using excessive CPU resources because CGI is inherently more CPU intensive than running as an Apache module. If running as an Apache module is not configurable to eliminate PHPSESSIDs, then you are left in a catch-22 situation where you are damned if you do, damned if you don't.
If you end up in this situation, you have to weigh your options: do you need to upgrade your hosting account? Do you need to go to dedicating hosting? Do you need a new hosting company?