Course: Sitellite Server Administration

1. Syllabus

Course instructor

Name John Luxford
Email lux@simian.ca
Web Site http://www.simian.ca/

Difficulty level and prerequisites

This course assumes a comfortable level of familiarity with any of the major Unix operating systems (Linux, BSD, Mac OS X, Solaris, etc.), and is intended for systems administration professionals.

Course description

An introduction and overview to installing, configuring, and maintaining the Sitellite Content Management System (CMS).

Course objective

To familiarize the student with the various components of the Sitellite CMS, how to install, configure, and maintain them, as well how to manage the Sitellite CMS configuration itself.

Course outline

  1. Syllabus
    1. Course instructor
    2. Difficulty and prerequisites
    3. Course description
    4. Course objectives
    5. Course outline
  2. Installing Sitellite
    1. Prerequisites
      1. Apache 1.3
      2. PHP 4.3
      3. MySQL 4.0
    2. Configuring PHP
      1. mod_php and CLI
    3. Configuring Sitellite
      1. Basic installation
      2. The config file
      3. Unix filesystem permissions
      4. The scheduler
  3. Optimizing the environment
    1. Optimizing Apache
    2. Optimizing PHP
    3. Optimizing MySQL
  4. Using the Sitellite Control Panel
    1. Sitellite Roles and Teams
      1. Roles vs. Teams vs. Users
      2. Adding Teams, Roles and Users
    2. Exporting to HTML
  5. Backing up the web site
    1. Components to consider
    2. Scheduling backups
  6. Security considerations
    1. Operating system
    2. Apache
    3. PHP
    4. MySQL
    5. Sitellite
  7. How to get help
    1. Sitellite.org
    2. Simian.ca

2. Installing Sitellite

Prerequisites

Apache 1.3 or 2.0

The differences between the two versions are that some compiling and configuration options have changed. The one specifically related to Sitellite is that Apache 2 requires a new "AcceptPathInfo" setting set to "On".

The other setting that can affect Sitellite is the "AllowOverride" setting. Usually, we simply recommend it be set to "All", which gives us more options in the .htaccess files used by Sitellite. However, we'll also be looking at the possibility of inlining the .htaccess settings into the main Apache configuration and turning .htaccess off completely, which I've seen improve the performance of Apache by up to 20%.

PHP 4.3

PHP 5 is out, but it is very new and has some big changes that cause most programs written for PHP 4 to break. We're looking to support PHP 5 in Sitellite version 5, but for now we should stick with 4.3.

The key to the PHP installation is that it be installed as both an Apache module (ie. mod_php) not as a CGI binary, and also as a command-line utility. This last option is the default since 4.3, so we shouldn't have to worry about that. Usually all we need to do is add the following switch to the "configure" line when compiling PHP:

./configure --with-apxs=/usr/local/apache/bin/apxs

MySQL 3.23 or 4.0

The main difference between MySQL 3 and 4 is MySQL 4.0's new query caching feature, which can drastically speed up common queries by moving their results into RAM until the database tables involved are changed.

Configuring Sitellite

Basic installation

A basic Sitellite installation begins with unzipping the Sitellite tarball into the document root of the web site, and copying its contents, including the .htaccess file (which is often missed), into the document root.

From there, the MySQL database tables need to be created. If the database and database user also need to be created, you can say:

mysql -p -u root
(enter password)
mysql> create database DBNAME;
mysql> grant all on DBNAME.* to USER@localhost identified by 'PASS';
mysql> flush privileges;
mysql> quit

Then you can create the database tables with:

mysql -p -u USER DBNAME < install/install-mysql.sql
(enter password)

The config file

Next, we need to tell Sitellite about the database, and also configure any other options as well. The Sitellite configuration file is named "inc/conf/config.ini.php" and is an INI-formatted file.

The database section looks like this (plus some comments in the real file explaining each field):

[Database]

connection_name	= mysqlweb
driver			= MySQL
hostname		= localhost
database		= DBNAME
username		= USER
password		= PASS
persistent		= 0

Enter the appropriate values into these fields and your installation should be up and running. Make sure to put double-quotes around the password value if it contains non-ascii characters, and it's usually a good idea to leave the persistent value set to 0.

Another value of interest in the configuration file is the following:

default_template_set = "default"

Usually a new template set is created based on the default for new sites to separate their own design from the original source of Sitellite. If that's the case, make sure to change this value in your configuration as well.

The last part of the configuration is the [Cache] section. The values we're interested in here are usually just "duration" and "cacheable". A typical duration value is 3600, which is 1 hour specified in seconds. The "cacheable" field will depend on which pages of your site can be cached, which is different for many sites.

In general, if a page doesn't change constantly, and it doesn't have any user login or dynamic capabilities in it, it's safe for caching. On most sites, if you can cache the main index page and the top-level index pages for each section, then you're caching over 50% of your traffic already. An example configuration such as this for a web site with two main subsections "products" and "services" might look like this:

cacheable = "/,/index,/index/index,/index/products,/index/services"

Another good way to determine which pages to cache is to run the site without caching initially for a day or two, then check SiteTracker to see which pages people are visiting the most. This is also a good idea to do from time to time, as changes to the site can change which pages people are most interested in.

Unix filesystem permissions

The web server directory itself and all of the files in it need to be readable by the user that Apache runs as (usually "nobody"). PHP files need to also have the executable flag set. For specific functionality in Sitellite, the following directories can also be made writeable by the Apache user:

If this is done, it should be done recursively to affect all of the existing files in each of these directories.

The scheduler

Sitellite has a "scheduler" utility that can be used in conjunction with cron, or called manually, to run tasks in Sitellite from the command-line. This is done with the following commands:

cd /PATH/TO/SITELLITE
php -f index scheduler-app task_name

To put this into cron, it might look like this:

0 0 * * * cd /PATH/TO/SITELLITE; php -f index scheduler-app sitesearch

This example would re-index the web site nightly at midnight for the search utility.

3. Optimizing the environment

Optimizing Apache

There are many ways to improve the performance of Apache. A few of these include:

Generally, inlining .htaccess options is probably the easiest of these to do, and can yield a noticeable performance boost as well. To do this, simply create a new <Directory> block for each .htaccess file, for example:

<Directory /PATH/TO/SITELLITE>
	<Files index>
		ForceType application/x-httpd-php
	</Files>
	<Files sitellite>
		ForceType application/x-httpd-php
	</Files>
	DirectoryIndex index index.html index.php
	AddType text/html .tpl
	php_flag short_open_tag off
</Directory>

<Directory /PATH/TO/SITELLITE/inc/data>
	Order allow,deny
	deny from all
</Directory>

Optimizing PHP

The best way to optimize PHP is to install a code-level cache, which doesn't affect the way PHP scripts function at all, but can improve the performance of PHP code by several hundred percent in many cases, by moving it to RAM instead of reading it from the server's hard drive for every page request.

The easiest code caching extension to install is probably APC, the Alternative PHP Cache. First, make sure the directory "/usr/local/lib/php/extensions/no-debug-non-zts-20020429" exists. Often the last two folders are missing. This is where extension .so (shared object) files are stored. Then, from the command-line, enter:

pecl install apc

This should do the rest for you except for one last step. In the file "/usr/local/lib/php.ini" (if it's missing, simply create a blank new one), add the following line:

extension="apc.so"

Then restart Apache and you should have APC cache installed and running.

Optimizing MySQL

Probably the biggest optimization you can make to MySQL is to enable MySQL 4.0's new query caching capabilities. To do this, simply enter the following into your "/etc/my.cnf" file:

[mysqld]

query-cache-size=32M

There are other options as well, but this is the main one which sets the amount of RAM the query cache can use.

One thing to make sure is that, if you haven't set the other MySQL options in the my.cnf file, that they don't default to something other than they should. MySQL does this sometimes when an installation isn't put into the default location. If this happens, you can simply add the necessary fields, for example:

[mysqld]

basedir=/opt/mysql
datadir=/opt/mysql/data
socket=/tmp/mysql.sock
query-cache-size=32M

[mysql.server]

basedir=/opt/mysql
datadir=/opt/mysql/data
pid-file=/opt/mysql/data/YOUR.HOST.NAME.pid
socket=/tmp/mysql.sock

[mysqld_safe]

pid-file=/opt/mysql/data/YOUR.HOST.NAME.pid

4. Using the Sitellite Control Panel

When you log into Sitellite, you are by default presented with the Web View editing mode. In the top bar, clicking on the Control Panel link brings you to the control panel. From here, users have access to additional content, add-ons, and user management (based on their permissions). We'll be looking at one add-on today as well as user management.

Sitellite Roles and Teams

Roles vs. Teams vs. Users

Here's how Sitellite's permissions work:

Adding Teams, Roles and Users

Adding any of these is done from the "Admin" pane in the Control Panel.

Exporting to HTML

Under the "Tools" pane in the Control Panel, select "SitePublisher" from the list. The SitePublisher allows you to publish the entire web site as a static HTML web site at any time. You simply enter the path to the directory to write the files to, which of course must be writeable by the Apache user, and then click "Publish". This can be repeated as many times as you want, making it possible to use Sitellite to edit content, but to publish an otherwise static web site from it.

Note: SitePublisher is a new module available in the upcoming Sitellite 4.2

5. Backing up the web site

Components to consider

The main components to consider when backing up a Sitellite installation are the database and the files. So packaging up a backup requires first that you back up the MySQL database to a file that can be zipped up with the rest of them.

Scheduling backups

A sample backup script might be as follows:

cd /PATH/TO/SITELLITE
mysqldump --password='PASS' -u USER DBNAME > backup.sql
tar -cf backup.tar .htaccess *
gzip backup.tar
cp backup.tar.gz /PATH/TO/BACKUPS
rm -Rf backup.sql backup.tar.gz

6. Security considerations

Operating system

Security at the operating system level consists of the following general areas:

Keeping the system up to date

This simply means applying patches provided by your operating system vendor. Appropriate preparations should always be done first to ensure that patches don't break running applications and services.

Keeping installed software up to date

Software providers will provide updates and security patches from time to time, which should be applied to the server regularly.

Controlling access to the server

There are several ways to restrict access ot the server. For starters, services that are not in use should be disabled. Services that are in use usually allow you to control who has access to them. For example, you may want to restrict MySQL access to the server itself only, if it only needs to be accessed by the web applications themselves. Or if you do need remote MySQL access, you can enable it on a per-IP basis.

The other way of controlling access is by using a firewall. A firewall can be a good secondary way of ensuring that services that shouldn't be accessible are indeed inaccessible.

Apache

Apache is a highly configurable web server, which can make it a challenge to secure. The general rule of thumb in configuring Apache is to turn off any features you don't need. For example, if you're not using WebDAV for anything, it is a good idea to not only disable the mod_dav extension, but to simply not install it at all. And if all your applications are in PHP, then there's no need to also enable CGI support. This way, there are less places a potential security flaw can occur.

Another option that can add a little security-through-obscurity (STO) to your environment is to hide the fact that you're using Apache. You can do this by not specifying your web server at all, or by specifying a different web server altogether (ie. lying). While it's not something to depend upon in and of itself, STO is a good idea as an extra measure of defense. STO makes it more difficult for potential hackers to accurately profile your web site. Profiling a site is the process of discovering and documenting everything they can find out about your server environment so that they can go back and formulate an attack plan.

To hide your web server from web clients, see the following settings in the Apache documentation:

http://httpd.apache.org/docs/mod/core.html#serversignature
http://httpd.apache.org/docs/mod/core.html#servertokens

Another way to hide Apache, and often to improve web application usability, is to provide custom error handlers. For example, to use Sitellite to handle errors, use the following configuration setting:

ErrorDocument 403 /index/myapp-error-action?code=403
ErrorDocument 404 /index/myapp-error-action?code=404
# etc.
http://httpd.apache.org/docs/mod/core.html#errordocument

Another Apache security consideration is encryption. Ordinary HTTP web site requests are sent across numerous relays on the Internet with no prevention of any one of those relays from snooping in on your communication. Configuring Apache's mod_ssl module to enable Secure Socket Layer (SSL) support allows you to encrypt communication sent between your browser and the server, preventing the possibility of snooping (or at least making it much more difficult). For more info, check out the official mod_ssl web site:

http://www.modssl.org/

It's also a good idea to disable directory listings, so that directories without index files show a 403 Forbidden notice instead of a list of available files. This can be changed via the following setting:

http://httpd.apache.org/docs/mod/core.html#options

For example:

Options -Indexes

Additional Apache security tips are available here:

http://httpd.apache.org/docs/misc/security_tips.html

PHP

The PHP scripting environment itself has several features that should be configured to ensure optimum security. PHP's configuration options are specified in the php.ini file. These settings include:

register_globals = off

This setting has been turned off by default now as of PHP 4.2.0, and for good reason. This setting tells PHP to make each CGI parameter a global variable in the script, which makes it very easy to make assumptions about global-level variables in your PHP scripts. Some older PHP scripts still require this setting to be turned on, however my recommendation in these cases is to look for an alternate, better-written equivalent to those applications.

expose_php = off

This stops PHP from identifying itself, just like we did with Apache.

open_basedir = /usr/local/apache/htdocs

This allows you to restrict which files are accessible to PHP scripts. Note that it can have side effects, for example file uploads defaulting to /tmp won't be accessible to the move_uploaded_file() function.

Beyond these settings however, the onus of security in a PHP application falls on the programmers themselves. A web application environment is only as secure as the code running on top of it. Some references for writing more secure PHP code include:

http://www.devshed.com/c/a/PHP/PHP-Security-Mistakes/
http://www.developer.com/lang/article.php/918141
http://www.onlamp.com/pub/a/php/2003/07/31/php_foundations.html

For more information, about PHP security considerations, see:

http://www.php.net/manual/en/security.php

MySQL

The general principles of limiting access to applications and services on the server are one of the key MySQL security consideration. This is done in two ways with MySQL.

First is ensuring that MySQL only responds to the client machines that you want it to. For example, if you wanted MySQL to be accessible only to clients on the same machine as the server itself, you could add this line to my.cnf:

bind-address = 127.0.0.1

Second, you should carefully control MySQL login accounts. For example, make sure the MySQL root user has a password assigned by typing:

mysql -u root

If you are not rejected, you need to set the root password. Additionally, you can restrict user accounts based on hostname and which database(s) they can access. For more info, see:

http://dev.mysql.com/doc/mysql/en/Default_privileges.html
http://dev.mysql.com/doc/mysql/en/Privilege_system.html

Another added security measure is to change the port that MySQL listens on. You can do this in the my.cnf file by specifying an alternate port in the line:

port = 3306

A second MySQL security consideration is to ensure that MySQL is running as the recommended "mysql" system user, and not as "root". This is similar to Apache running as "nobody", and is a common security precaution used to prevent server-side daemons from becoming loopholes for hackers to gain access to the rest of the server.

For complete MySQL security information, see:

http://dev.mysql.com/doc/mysql/en/Security.html

Sitellite

First, let's tell Sitellite to stop identifying itself like we did with Apache and PHP. To do this, change the value "send_version_header" in inc/conf/config.ini.php to the following:

send_version_header = off

Next, an added security measure on a deployed server (but a bad idea on a development/testing server), is to turn off error reporting completely. To do this, change the "error_reporting" value in inc/conf/config.ini.php to:

error_reporting = "E_NONE"

File Ownership

A general rule for managing file ownership is to grant only as much ownership as necessary, and no more. For example, if you need permission to write to the cache and inc/data directories of your Sitellite installation, don't simply execute a "chmod -Rf 777 *" from the web server root.

7. How to get help

Sitellite.org

Simian.ca


Copyright © 2008 Simian Systems Inc.
All rights reserved.