Nowheretobefound

  • Increase font size
  • Default font size
  • Decrease font size

Setting up a website

E-mail Print

Introduction

This page is for people who are going to use their Debian server as a web server. If you followed the instructions on installing the system you should have a working Apache/PHP/MySQL and a default website in /var/www.

Although that is a nice way to start you will have to do a little more if you want to host multiple websites (a.k.a. shared hosting). I've created scripts that do most of the task needed, but I'll walk you through the important stuff step by step.

 

One time settings

Default website

Once you start using host header names (multiple websites on a single IP address) the default website will stop working. So we might as well remove it from Apache's configuration.

rm /etc/apache2/sites-enabled/000-default

 

PHP settings

For my per-user settings I use a seperate directory.

mkdir /home/000-suphp

 

Log files

I prefer to have my logfiles rotated every night which makes it easier to generate statistics. This section shows how you can set up log ratation. Rotating the log files will also prevent them from taking too much disk space.

mcedit /etc/logrotate.d/websites

A new file should be created for you and you can add these lines.

# Log file rotation for Virtual hosts
/home/*/logs/*.log {
daily
nocompress
rotate 14
missingok
sharedscripts
postrotate
if [ -f /var/run/apache2.pid ]; then
/etc/init.d/apache2 restart > /dev/null
fi
endscript
}

This will make the logrotate script rename your log file every night from "web.log" to "web.log.X", where X is a counter. It will not use compression and it will keep 14 days worth of log files. After rotating all logs Apache will be restarted. The restart is done to make sure Apache logs to the new filename.

Finally I've changed the default time logrotate will run from 06:25 AM to 00:05 by editing cron.daily. You can use Webmin to make this change or you can simple edit /etc/crontab.

 

Adding a website

Creating a user account

In order to upload your files with FTP you will need a user account on the system. I prefer to name them after the domain name.

useradd -g www-data -s /bin/bash <domain_name>
passwd <domain_name>

 

Setting user quota

This command sets a 100MB quota for the selected user:

quotatool -u <domain_name> -b -l 102400 -v /

 

Creating directories

Next we create directories and set permissions.

mkdir /home/<domain_name>
cd /home/<domain_name>
mkdir beta safe tmp web
chown -R <domain_name>:www-data .
mkdir logs

Your web site will be in the "web" dir. PHP files with settings and passwords are better of in the "safe" dir. Apache will log to the log directory. The tmp dir is used for session files and partial uploads. I add the beta directory to house a test version of the website. So that the user can make changes to his website without the rest of the world watching over his shoulder.

 

Initializing database

Create default database and MySQL account for all new users.

mysql -e "CREATE DATABASE <domain_name>; GRANT ALL PRIVILEGES ON <domain_name>.* TO '<user_id>'@'localhost' IDENTIFIED BY '<password>';" -u root -p

This will create a database for the user. If you use the domain name for database name like I do, remember to convert dots to underscores. There can't be a dot in a database name. The new user will also be created.
To make accounts more restrictive you should allow only selected privileges instead of ALL.

 

Setting up apache

There is a directory to place new virtual sites called "sites-available". We will have to add a new file here for every website we want to host. And create a symlink to the file in "sites-enabled".

mcedit /etc/apache2/sites-available/<domain_name>

Here's what should be in this new file.

<VirtualHost private_ip_address>
ServerName your_domain_name.com
ServerAlias www.your_domain_name.com
DocumentRoot /home/your_domain_name.com/web/
TransferLog /home/your_domain_name.com/logs/web.log
suPHP_ConfigPath /home/000-suphp/your_domain_name.com/web
</VirtualHost>
<VirtualHost private_ip_address>
ServerName beta.your_domain_name.com
DocumentRoot /home/your_domain_name.com/beta/
TransferLog /home/your_domain_name.com/logs/beta.log
suPHP_ConfigPath /home/000-suphp/your_domain_name.com/beta
</VirtualHost>

Save your changes, create the link and reload apache.

ln -s /etc/apache2/sites-available/<domain_name> /etc/apache2/sites-enabled/<domain_name>
/etc/init.d/apache2 reload

 

To make it more secure we'll have to add a couple of PHP settings for this domain name.

mkdir /home/000-suphp/<domain_name> /home/000-suphp/<domain_name>/web /home/000-suphp/<domain_name>/beta

 

mcedit /home/000-suphp/<domain_name>/web/php.ini
; Lock users in their own home directory
open_basedir = /home/<domain_name>/
doc_root = /home/<domain_name>/web/
; Temporary files
upload_tmp_dir = /home/<domain_name>/tmp
session.save_path = /home/<domain_name>/tmp
; Disable $argc and $argv which aren't used by cgi
register_argc_argv = Off
; prevent displaying errors in the client browser
display_errors = Off
log_errors = On
error_log = /home/<domain_name>/logs/php.log

 

mcedit /home/000-suphp/<domain_name>/beta/php.ini
; Lock users in their own home directory
open_basedir = /home/<domain_name>/
doc_root = /home/<domain_name>/beta/
; Temporary files
upload_tmp_dir = /home/<domain_name>/tmp
session.save_path = /home/<domain_name>/tmp
; Disable $argc and $argv which aren't used by cgi
register_argc_argv = Off
; display errors in client browser on beta (development) website
display_errors = On
log_errors = Off
;error_log =

When all that is done you should be able to run PHP pages a bit more secure than in a default configuration.

 

Usefull information

Apache and htaccess

The web server we installed has a feature called AccessFileName. With it, clients can use ".htaccess" files to controle certain features and functionalities of the web server. By default there isn't much you can do with these files. You can however configure what can and can't be changed with htaccess. In the installation instructions we added the following lines to /etc/apache2/conf.d/default:

<Directory /home/*/web>
AllowOverride All
Options All -Indexes
</Directory>

This allows changing all supported configuration directives and enables all options except for showing directory indexes (most admins don't want people browsing the files in a public web directory). If you want a more restrictive setup have a look at the apache docs.

 

Securing a directory

In order to use HTTP Authentication we need to create two files. First a password file with username(s) and password(s) for whoever gets access to the resource. Secondly a .htaccess file inside the directory that needs to be secured.

Creating the first user:

htpasswd -c /home/<domain_name>/safe/.pwd myusername

To create more users omit the -c flag:

htpasswd /home/<domain_name>/safe/.pwd otherusername

Next we need to put the .htaccess file inside the directory that needs to be secured.

mcedit /home/<domain_name>/web/secure/.htaccess

It's content should look something like this:

AuthType Basic
AuthName "mydomain.com"
AuthUserFile /home/<domain_name>/safe/.pwd
Require valid-user

You can try it out by opening the secure directory in your browser: http://<domain_name>/secure/
It should ask you for a username/password.

 

Adding IP security

Say you want to put your website offline for maintenance. Using a htaccess file like this will redirect visitors to the specified page with the exeption of the people that have a listed IP address. Don't forget to create a nice placeholder page (offline.html).

# Initialize rewrite engine
RewriteEngine On
# Mike's office
RewriteCond %{REMOTE_ADDR} !^111.222.111.
# John at home
RewriteCond %{REMOTE_ADDR} !^123.123.123.123$
# Offline mode
RewriteCond %{REQUEST_URI} !^/offline.html
RewriteRule .* /offline.html [L]

In order to use the rewrite funcitons you may have to enable this module first. If it's not you'll get code 500 server errors!

ln -s /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load
/etc/init.d/apache2 reload

 

Another way is to completely block addresses. This is a more permanent method because it won't show a nice placeholder page. People that just get access denied are likely to not return... You can use this for intranet pages for example.

# IP Security
AuthName "No Public Access"
AuthType Basic
<Limit GET POST>
order deny,allow
deny from all
# Mike's office
allow from 111.222.111.0/26
# John at home
allow from 123.123.123.123
</Limit>