Course: Sitellite Server Administration
1. Syllabus
Course instructor
| Name | John Luxford |
| 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
- Syllabus
- Course instructor
- Difficulty and prerequisites
- Course description
- Course objectives
- Course outline
- Installing Sitellite
- Prerequisites
- Apache 1.3
- PHP 4.3
- MySQL 4.0
- Configuring PHP
- mod_php and CLI
- Configuring Sitellite
- Basic installation
- The config file
- Unix filesystem permissions
- The scheduler
- Prerequisites
- Optimizing the environment
- Optimizing Apache
- Optimizing PHP
- Optimizing MySQL
- Using the Sitellite Control Panel
- Sitellite Roles and Teams
- Roles vs. Teams vs. Users
- Adding Teams, Roles and Users
- Exporting to HTML
- Sitellite Roles and Teams
- Backing up the web site
- Components to consider
- Scheduling backups
- Security considerations
- Operating system
- Apache
- PHP
- MySQL
- Sitellite
- How to get help
- Sitellite.org
- 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:
- cache
- inc/app/cms/data
- inc/conf/auth
- inc/data
- inc/html
- pix
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:
- Eliminate unused modules, which reduces the amount of stuff loaded into the web server.
- Recompile it with modules loaded statically instead of dynamically. This doesn't always work out, however.
- Turning .htaccess off and putting any .htaccess directives directly into the main Apache configuration file(s).
- Compiling Apache with architecture specific optimizations at compile-time.
- Optimizing the number of starting processes and the min/max processes based on how much traffic your web site sees.
- Reducing the KeepAlive time of dynamic scripts can also help.
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:
- Users each belong to one team and have one role.
- The role of a user defines what permissions they have.
- A user's individual settings can also limit which documents they can access based on the team that owns each document.
- Permissions are based on resources (ie. a collection of documents), access levels (ie. public/private), document statuses (ie. draft/approved), and team ownership.
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
- The complete Sitellite documentation:
http://www.sitellite.org/index/docs - Community forum:
http://www.sitellite.org/index/siteforum-app
Simian.ca
- Simian contact information:
http://www.simian.ca/index/contact - Technical support page:
http://www.simian.ca/index/support
Copyright © 2008 Simian Systems Inc.
All rights reserved.