Linode.com Forum Forum Index Linode.com Forum
Linode Community Forums
 


HowTo: Apache2, SuExec, PHP5 and FastCGI for Virtual Domains

Click here to go to the original topic
Goto page Previous  1, 2
 
       Linode.com Forum Forum Index -> Linux, Apache, Mysql and PHP (LAMP) Forum
Author Message
IntuititveNipple



Joined: 03 Dec 2007
Posts: 21

Posted: Tue Mar 18, 2008 8:21 pm    Post subject: Errors after package update  

If the site suddenly starts reporting 500 Server Error and /home/<user>/logs/error.log looks similar to this:
Code: [Wed Mar 19 00:31:38 2008] [warn] (104)Connection reset by peer: mod_fcgid: read data from fastcgi server error.
[Wed Mar 19 00:31:38 2008] [error] [client 1.2.3.4] Premature end of script headers: php-fcgi-wrapper

it is probable that your distribution has updated the apache2 package and replaced your /usr/lib/apache2/suexec file.

You can check by looking at the AP_DOC_ROOT it reports. It should be "/home":
Code: $ sudo /usr/lib/apache2/suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="www-data"
 -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=100
 -D AP_USERDIR_SUFFIX="public_html"
Oops - wrong!

You will need to download the source code for the installed version of apache2-common and follow the first article's instructions up until you've installed the corrected version to /usr/lib/apache2/suexec.

Those instructions start with:
Code: $ mkdir SourceCode
$ cd SourceCode
$ sudo  apt-get  build-dep apache2.2-common
Back to top  
cognitiveprocess



Joined: 10 Apr 2008
Posts: 1

Posted: Thu Apr 10, 2008 12:28 pm    Post subject: looking for someone to set this up for me  

Hello,

I am looking for someone to set up this configuration for me. I have a newly create linode. Right now the linode is Ubuntu 7.1, but I can change it to another distribution if necessary. I will need the VM configured to optimized to run Magento.

See here


http://www.magentocommerce.com/blog/comments/performance-is-key-notes-on-magentos-performance/
Back to top  
hybinet



Joined: 02 May 2008
Posts: 70

Posted: Mon Jul 14, 2008 7:42 pm    Post subject:  

I've been using your method for a while (with own modifications), but I wanted to automate it a bit more, and without using Virtualmin. Over the last several weeks, I managed to write up a script that does this job for me. I'm posting the entire script here, in case others might find it useful.

A few differences between this and IntuitiveNipple's method:

1) My script uses /var/www as default webroot, though this is easily customizable. If you want to use /home, you can do this without rebuilding suexec by binding /home to /var/www. If you rebuild suexec with a custom webroot, you may end up with a broken server after doing a routine apt-get upgrade. It happened to me!

2) IntuitiveNipple's setup only makes user files world unwritable, but it leaves them world readable. This could be a security issue, because some .php files contain your DB password! Of course, PHP has some built-in protections against this obvious problem, but it's better to use appropriate permissions in the first place. My script adds the Apache user to each and every user group created, so that no user file needs to be world readable.

3) My script automatically writes another script which generates Webalizer stats for each website. (You need to add this second script to your crontab for it to work.)

HOW TO USE

1) Make sure you're using the latest Debian or Ubuntu. If not, you may have to make modifications to the script below.

2) Copy the script below by dragging your mouse over it and hitting Control+C.

3) Paste it into an empty file on your server. Change the configuration settings to suit your needs.

4) Make that file executable (chmod 700) and owned by root.

5) Run the script. If all goes well, it'll ask you for a domain name, a username, and a password for that user. It'll also automatically reload Apache, so you're all set.

WARNING

1) Don't use my script on an existing vhost setup or with any other control panel (Virtualmin, ISPConfig, etc). If you do so, you're going to get a big mess for which I can't take responsibility. Only use my script on a new server (Linode).

2) If you're going to use /var/www as your web root, it's a good idea to edit /etc/apache2/sites-available/default and make the default document root something below /var/www, e.g. something like /var/www/apache2-default. Otherwise some people may be able to browse through the whole setup!

3) As with most free stuff on the Internet, this script comes with no guarantees. As simple as it is (only 260 lines including comments), it probably contains a number of bugs, and it may not work depending on your server setup. Proceed with caution. If you're a newbie, DON'T use this script. Instead go with a normal control panel such as Virtualmin or ISPConfig!

Code: #!/bin/bash

# Easy Website Creation Tool with SuExec and FastCGI, version 0.1.1
# Made by Kijin Sung (kijinbear@gmail.com)
# Based on http://www.linode.com/forums/viewtopic.php?t=2982
# With a few of my own modifications.

# Made for Ubuntu 8.04 LTS & Apache 2.2, free to port and modify.
# This script comes with no warranties whatsoever. Use at your own risk.
# If you don't understand what this script does, don't use it

# Notice: This script must always be run as root.

# ---------------- INTRODUCTION -------------------------------------
# -------------------------------------------------------------------

# Now run the following commands prior to first use:

# apt-get install apache2 apache2-mpm-worker libapache2-mod-fcgid
# apt-get install php5-cgi webalizer
# echo -e "\ncgi.fix_pathinfo = 1" >> /etc/php5/cgi/php.ini
# a2enmod actions
# a2enmod alias
# a2enmod auth
# a2enmod fcgid
# a2enmod include
# a2enmod mime
# a2enmod rewrite
# a2enmod suexec

# In Ubuntu (and probably also in most other Debian-based distributions),
# these commands will install the necessary packages, as well as making the requisite
# change to php-cgi configuration (which is actually just adding one line at the end).
# It'll also remove mpm-prefork and mod-php. We don't need these with our setup.
# If you get any errors here, fix them before proceeding.

# It is also highly recommended that you edit your ftp server's umask settings,
# so that new directories have 750 permissions and new files have 640 permissions.
# Under the settings used by this script, that is the maximum permissions required
# for the proper operation of most static and dynamic websites.
# If you use ProFTPd, edit /etc/proftpd/proftpd.conf
# and change the line "Umask 022 022" to "Umask 137 027".
# If you use vsftpd, edit /etc/vsftpd.conf
# and set the umask to 027.

# ---------------- USER CONFIGURATION -------------------------------
# -------------------------------------------------------------------

# You can set some parameters here.
# Make sure that these parameters fit your needs.

# dirbase is where all the virtual hosts will be created.
# Default value is "/var/www" which is Apache's default document root.
# Whatever you change it to, do NOT add a slash to the end of this variable!!!
# If you change it to something else, e.g. "/home", then you must take extra steps
# to make suexec work with a non-default document root.
# One simple way to do this is to bind /home to /var/www.

dirbase="/var/www"

# dirprefix is a word that will be attached to the front of all directory names.
# By default, this is left blank. It can be changed to something like "vhost_".

dirprefix=""

# dirpattern can be either "username" or "domain".
# If set to "username", directory names will follow user names, e.g. "example".
# If set to "domain", directory names will follow domain names, e.g. "example.com".

dirpattern="username"

# statscript is the location of the script that will automatically generate
# Webalizer reports. This file need not exist, as it will be created at first run.
# Make sure to add this script to root's crontab, by running "crontab -e" and
# adding the following line (which will generate reports at 4:00 AM every day):
# 00 04 * * * /root/ezstats.sh

statscript="/root/ezstats.sh"

# apacheuser is "www-data" by default.
# Most Debian-based distros will follow this pattern, but change it if necessary.

apacheuser="www-data"


# ---------------- COLLECT INFORMATION ------------------------------------
# -------------------------------------------------------------------------

echo "+------------------------------------------------------------------+"
echo "|  Easy Website Creation Tool with SuExec and FastCGI  ver. 0.1.1  |"
echo "+------------------------------------------------------------------+"

echo -n "Enter domain name (without www): "
read domn

echo -n "Enter new user name: "
read usrn


# ---------------- CREATE USER & GROUP ------------------------------------
# -------------------------------------------------------------------------

# Add user/group and ask for password.
# If username already exists, exit with error.
# Group is automatically created in Ubuntu, but let's check just in case.

useradd $usrn || exit 1
passwd $usrn
groupadd -f $usrn

# Add Apache user to the same group.
# This allows Apache to read files with 640 permissions.

usermod -G $usrn -a $apacheuser


# ---------------- CREATE USER DIRECTORY STRUCTURE ------------------------
# -------------------------------------------------------------------------

if [ "$dirpattern" == "username" ]; then
dirname="$usrn"
else
dirname="$domn"
fi

dirn="$dirbase/$dirprefix$dirname"
echo "Creating directory structure at $dirn"

mkdir $dirn
mkdir $dirn/cgi-bin
mkdir $dirn/cgi-bin/php5-fcgi-wrapper
mkdir $dirn/conf
mkdir $dirn/lib
mkdir $dirn/logs
mkdir $dirn/public_html
mkdir $dirn/public_html/stats
mkdir $dirn/tmp

# Set user's home directory.

usermod -d $dirn $usrn


# ---------------- CREATE CONFIG FILES ------------------------------------
# -------------------------------------------------------------------------

echo "Creating FastCGI configuration files"

# FastCGI wrapper
# This is the script that handles all .php files.

cat > $dirn/cgi-bin/php5-fcgi-wrapper/wrapper <<- _EOF1_
   #!/bin/sh
   export PHPRC=$dirn/conf
   export PHP_FCGI_CHILDREN=1
   export PHP_FCGI_MAX_REQUESTS=5000
   exec /usr/bin/php5-cgi
_EOF1_

# User's default php.ini

cat > $dirn/conf/php.ini <<- _EOF2_
   include_path = ".:$dirn/lib"
   open_basedir = "$dirn:/tmp"
_EOF2_

# Apache vhost config file
# I have enabled per vhost server-side includes and indexfiles.
# Per vhost logging is also enabled. (Also see Webalizer stats below)
# Change this if you want to use different options.

cat > /etc/apache2/sites-available/$domn <<- _EOF3_
   <VirtualHost *>

        SuexecUserGroup $usrn $usrn

        ServerName $domn
        ServerAlias www.$domn
        DocumentRoot "$dirn/public_html"
        ScriptAlias /cgi-bin/ $dirn/cgi-bin/

        <Directory $dirn/public_html>
                DirectoryIndex index.php index.shtml index.html index.htm
                Options -Indexes +IncludesNoExec
                AddType text/html .shtml
                AddOutputFilter INCLUDES .shtml
                Order allow,deny
                Allow from all
        </Directory>

        CustomLog /var/log/apache2/vhost_access.log combined
        CustomLog $dirn/logs/access.log combined
        ErrorLog $dirn/logs/error.log

        AddHandler php-fcgi .php
        Action php-fcgi /fcgi-bin/wrapper
        Alias /fcgi-bin/ $dirn/cgi-bin/php5-fcgi-wrapper/
        <Location /fcgi-bin/>
                SetHandler fcgid-script
                Options +ExecCGI
        </Location>
        ReWriteEngine On
        ReWriteRule ^/fcgi-bin/[^/]*$ / [PT]

   </VirtualHost>
_EOF3_

# Default html placeholder page

cat > $dirn/public_html/index.html <<- _EOF4_
   <html><head><title>New Website</title></head>
   <body><font face="Verdana" size="2"><br><center>
   This website is under construction.<br>
   Please check back later.
   </font></body></html>
_EOF4_


# ---------------- SET OWNERSHIP AND PERMISSION ---------------------------
# -------------------------------------------------------------------------

# Home directory must be owned by user, of course!

echo "Setting Permissions"
chown -R $usrn:$usrn $dirn

# Log directory must be owned by www-data.
# Otherwise Apache can't write logs to it.

chown www-data:$usrn $dirn/logs
touch $dirn/logs/access.log
touch $dirn/logs/error.log

# Never use permissions greater than 750 for directories
# or greater than 640 for files. This also applies to .php files.
# The only file that needs to be 750 is the FastCGI wrapper.
# The wrapper & php-cgi executes .php files for you, so
# .php files don't need to be executable themselves.

chmod -R 750 $dirn
chmod 640 $dirn/public_html/index.html
chmod 640 $dirn/conf/php.ini
chmod 640 $dirn/logs/*


# ---------------- SETUP WEBALIZER STATS ----------------------------------
# -------------------------------------------------------------------------

# The stat script must be owned and executed by root.
# You must add this script to crontab manually.

echo "webalizer -p -n $domn -o $dirn/public_html/stats $dirn/logs/access.log" >> $statscript
chown root $statscript
chmod 700 $statscript


# ---------------- RELOAD APACHE WEBSERVER --------------------------------
# -------------------------------------------------------------------------

a2ensite $domn
/etc/init.d/apache2 reload

echo "Done!"
Back to top  
CaptTofu



Joined: 02 Dec 2008
Posts: 1
Location: Sharon, NH

Posted: Tue Dec 02, 2008 1:35 pm    Post subject: Happiness.  

You're site is a great help. I'm a perl guy - I'm even the maintainer for DBD::mysql. I do like PHP though, and have been given the task lately of implementing PHP offerings at Lycos for Tripod.com users. I have been trying like mad to find a way to set open_basedir per user. We don't use UIDs/useraccounts on tripod. We have a big NFS directory, each user logged in has a directory. I want to limit what users can open with open_basedir to this directory. We're using fastcgi with a wrapper script, which works fine. I was trying to do:

exec /usr/bin/php-cgi -d open_basedir=$REDIRECT_site_root
Didn't work. It seemed to ignore -d. I would run php-cgi -d open_basedir=/path/to/user by command line and it worked, but in CGI mode, it didn't.

Then I saw on this wonderful site

open_basedir= ${HOME}/...

In the php.ini file. This made me realize I could do

open_basedir= ${REDIRECT_site_root}

Which works great!

Thanks mucho muchly!
Back to top  
 
       Linode.com Forum Forum Index -> Linux, Apache, Mysql and PHP (LAMP) Forum Goto page Previous  1, 2
Page 2 of 2