As a weekend project I setup Aegir 0.3RC1 on a VPS (see the bottom of this page for links to VPS hosts).
I have to take my hat off to Adrian and the rest of the Aegir team - it's amazing. So I wanted to write up the installation procedure in a way that makes it as easy as possible for others to try out...
Setup the LAMP stack
The best route to setup the stack in the first place is to use an appliance from Turnkey Linux - they offer a LAMP stack which has much of the configuration done.
Download the appliance here: http://www.turnkeylinux.org/appliances/lamp
Follow though their setup instructions. Otherwise ensure you have a LAMP server setup with similar specifications - eg
Ubuntu 8.04 Hardy.
Configure the OS
Login to the server as root, and then follow these instructions to do the remaining configuration and some basic hardening for security...
Set locale
For me, this is en_GB, but set your choice of locale:
sudo locale-gen en_GB.UTF-8
sudo /usr/sbin/update-locale LANG=en_GB.UTF-8 Not a security measure, but worth doing, especially before we do the upgrades etc.
Update and upgrade
sudo apt-get update
sudo apt-get upgrade This is just an initial update/upgrade. On an ongoing basis, Turnkey linux is set to automatically install new OS updates. For info see this page:
http://www.turnkeylinux.org/docs/automatic-security-updates
Now add some basic things:
sudo apt-get install build-essential
sudo apt-get install wget
sudo apt-get install aptitude apt-utils
sudo apt-get install cvs subversion
sudo apt-get install php5-cli php5-gd php-pear
sudo apt-get install openssh-serverWe need a mail transfer agent for the server to communicate with the outside world...
sudo apt-get install postfix select the option 'internet site' when prompted.
More info on postfix is at:
https://help.ubuntu.com/8.04/serverguide/C/postfix.html
http://www.scalix.com/wiki/index.php?title=HowTos/Complete_Postfix
Sendmail can be used as well, but is regarded by some as less secure.
To configure postfix for using googlemail as the smtp server, use this:
http://prantran.blogspot.com/2007/01/getting-postfix-to-work-on-ubuntu-w...
Restrict access to root user
First, change the passwordpasswd
And make this a secure password. Record it somewhere safe.
Then add another user (this can be anything you like, I've set it as 'onlyme' here. Don't make it something obvious like 'admin'):useradd onlyme
Then set the password for this user:passwd onlyme
Make this a secure password, different from the root login
Grant this user sudo rights:visudo
Use the arrow keys to go to the last line. Press 'a' to add a line. Type:onlyme ALL=(ALL) ALL
Hit Esc. Type ':'. type 'wq' and hit ENTER.
Then we want to prevent the root user from being able to login directly:sudo vim /etc/ssh/sshd_config
and set the settings in file to be as follows (don't remove any other existing settings, just change or add to make the following):
Port 9876
PermitRootLogin no
X11Forwarding no
UseDNS no
UsePAM yes
PasswordAuthentication yes
AllowUsers onlyme Note that the Port setting is to change the SSH/SFTP port from 22. I've used 9876 to illustrate this, but you can choose something else. This port should then be set in the settings of your SFTP programme to access the server.
Then reload ssh/etc/init.d/ssh reload
Now logout of your shell session and ftp programme. Try to login again as root. It shouldn't work.
Log in now using the new onlyme user and the onlyme password.
If you need to have root authority in the future, simply issue the su - command in a bash shell and enter the root password. It's just that you can't login directly as root.
Su - to the root user now.
Firewall
Install the iptables firewall (it may turn out to be there already, so this won't do anything)sudo apt-get install iptables
Open ports should be kept to 80 and 443 (http and https) and 9876 (our custom SSH port) on the external network card. On the internal loopback 3306 also needs to be allowed for MySQL. On outbound allow only port 53 UDP (for DNS) and 80 TCP (for access to updates etc via HTTP). Close down other ports unless absolutely necessary. Set any firewall to drop packets rather than reject them.
Ubuntu has a layer ontop of iptables called UFW, making setting up a basic firewall easier, which we'll enable and configure...
sudo apt-get install ufw
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 9876/tcp
sudo ufw logging on
sudo ufw enable
sudo ufw status This sets up a default deny (DROP) firewall for incoming connections, with all outbound connections allowed with connections tracking.
The ufw framework is capable of doing anything that iptables can do. This is achieved by using several sets of rules files, which are nothing more than iptables-restore compatible text files. Fine-tuning ufw and/or adding additional iptables commands not offered via the ufw command is a matter of editing various text files:
* /etc/default/ufw: high level configuration, such as default policies, IPv6 support and kernel modules to use
* /etc/ufw/before[6].rules: rules in these files are evaluated before any rules added via the ufw command
* /etc/ufw/after[6].rules: rules in these files are evaluated after any rules added via the ufw command
If you do edit any of the above files, activate the new settings with:
sudo ufw disable
sudo ufw enable More Info on UFW:
https://help.ubuntu.com/8.04/serverguide/C/firewall.html
https://wiki.ubuntu.com/UbuntuFirewall
Configure Apache
Users and Groups
One of the first things to ensure is that Apache does not run as root because if Apache is cracked then an attacker could get control of the root account.
To test what user and group apache is running as, type:ps auwwfx | grep apache
does the first column on the lines say 'www-data'? If so this section is okay, move on.
If it says 'root' you need to do the following:
Add the user and group:groupadd www-datauseradd -g www-data www-datavim /etc/apache2/envvars (that's env vars together)
In this file, set the APACHE_RUN_USER and GROUP to 'www-data'.
Do a reload to effect the change:/etc/init.d/apache2 reload
Permission to serve files
sudo vim /etc/apache2/apache2.conf
Make sure the following are set:ServerTokens ProdServerSignature Off
Do a reload to effect the change:/etc/init.d/apache2 reload
Enable/Disable some Apache Modules
Some modules aren't needed, so we can disable them for performance and security:
a2dismod cgi
a2dismod autoindex And some modules we'd like to enable.
a2enmod deflatea2enmod rewritea2enmod vhost_alias
Now restart apache/etc/init.d/apache2 restart
Advanced things to consider for the future:
Install mod_security (http://www.modsecurity.org/)
Install mod_chroot (http://core.segfault.pl/~hobbit/mod_chroot/)
Configure PHP
Get the path to sendmail
Issue the command:postconf -d sendmail_path
Note down this path.
Edit PHP.ini
All changes need to be performed in both:/etc/php5/apache2/php.ini
and/etc/php5/cli/php.ini
Change the settings in these files to read as follows:
safe_mode = Off
expose_php = Off
memory_limit = 128m
display_errors = Off
log_errors = On
error_log = /var/log/php/php.log (or php_cli.log)
sendmail_path = /usr/sbin/sendmail -t -iwhere the sendmail_path is actually the path you noted down above, but keep the -t and -i switches.
Edit Apache/PHP settings
In /etc/apache2/mods-enabled/php5.conf add:AddType application/x-httpd-php .inc .module .class
so it becomes something like:
<IfModule mod_php5.c>
AddType application/x-httpd-php .php .phtml .php3
AddType application/x-httpd-php .inc .module .class
AddType application/x-httpd-php-source .phps
</IfModule>the addition of these additional filetypes to be handled as php scripts means the code of those types of files can't be directly downloaded from webroot folders, revealing site code, passwords etc.
Setup log files
Then
mkdir /var/log/php
touch /var/log/php/php.log
touch /var/log/php/php_cli.log
chown -R www-data:www-data /var/log/php
chmod -R 0755 /var/log/php To make sure that the log files exist and can be written to.
Log files should then be checked regularly to look for problems!
Restart Apache
/etc/init.d/apache2 restart
Configure MySQL
Edit MySQL configuration file
sudo vim /etc/mysql/my.cnfIn the [mysqld] section add this:
set-variable=local-infile=0 check that
user = mysql If this is not set then mysql is set to run as root which is dangerous. A new user needs to be setup, given limited privileges (inc access to the mysql directories) and then specified here. Ubuntu usually has this set by default.
Change Root password and username
Now type
mysql -u root -p It will prompt for a password, this is the original root password from when the server was setup, and will show in the vps control panel if setup via a vps image. In more basic settings you may just need to press return here.
We'll change this password now:
mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password'); make a note of this new password.
Now we're changing the 'root' username to 'onlyme' which makes it harder to do brute force dictionary attacks on the password:
mysql> use mysql;
mysql> update user set user="onlyme" where user="root";
mysql> flush privileges; Check for crud
SHOW DATABASES;
On a clean install if there are any databases other than mysql or information_schema then delete them - eg test databases.
SHOW GRANTS;
This will show which users have which permissions on the system. Get rid of defaults, demo users etc.
Type exit to log out of mysql.
Remove History
Now we remove the content of the mysql history file in which all executed SQL commands are stored inc passwords in plain text.
cat /dev/null > ~/.mysql_history Installing Aegir
Ladies and Gentlemen, it's time for tonight's main attraction - Aegir 0.3RC1...
Other sources of help
There is a screencast here: http://www.developmentseed.org/blog/2009/may/20/aegir-scratch-installing....
Although it's for the previous version, it is worth watching before following the instructions below.
These instructions are for Aegir 0.3 RC1.
Basic documentation for this release is here: http://groups.drupal.org/aegir/0.3-RC1
and the readme.txt (slightly outdated) is here: http://cvs.drupal.org/viewvc.py/drupal/contributions/profiles/hostmaster...
The Aegir Group, for updated info is here: http://groups.drupal.org/aegir-hosting-system
Create a user for aegir to operate as
sudo adduser aegir --home /var/aegir &&
su - aegir This will create a new user, asking you to provide a password. Just press enter for anything else it asks you for. This will then log you in as a new user.
For those unfamiliar with shell use, after the && press return, and then type the next line and press return again.
Preparations
Setup CVS repository...
export CVSROOT=:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib
cvs login Download Drush and Provision
cvs -z6 co -d drush -r DRUPAL-6--2-0 contributions/modules/drush
mkdir ~/.drush
cvs -z6 co -d .drush/provision -r DRUPAL-6--0-3-RC1 contributions/modules/provision At this point we need to gain superuser priveleges to execute the next few commands, so we logout of the aegir session...
logout
chmod u+x /var/aegir/drush/drush
ln -s /var/aegir/drush/drush /usr/bin/drush
su - aegirWe're now back as the aegir user.
Test that the drush setup is working:
drush This should list all available drush commands. check that it includes the 'provision' commands. If this doesn't work as expected troubleshooting is needed... check the permissions of the directories and drush file. Try
/var/aegir/drush/drush. If that works, then there's a problem with the symlink.
If all is working with drush, let's move on to the next step.
Setup Drupal codebase
We start by checking out the latest drupal 6 release (currently 6.13)...
cd /var
export CVSROOT=:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal
cvs login
cvs co -d aegir/drupal-6.x -r DRUPAL-6-13 drupal Get Hostmaster install profile
cd aegir/drupal-6.x/profiles
export CVSROOT=:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib
cvs login
cvs -z6 co -d hostmaster -r DRUPAL-6--0-3-RC1 contributions/profiles/hostmaster
mkdir -p hostmaster/modules
mkdir -p hostmaster/themes
cvs -z6 co -d hostmaster/modules/hosting -r DRUPAL-6--0-3-RC1 contributions/modules/hosting
cvs -z6 co -d hostmaster/themes/eldir -rDRUPAL-6--0-3-RC1 contributions/themes/eldir
drush dl admin_menu --destination=/var/aegir/drupal-6.x/profiles/hostmaster/modules Configure Apache
Now we'll copy across a file template (with the filename changed from aegir.example.com to the domain name of our aegir install)...
mkdir -p ~/config/vhost.d
cp hostmaster/apache2.conf.txt ~/config/vhost.d/aegir.example.com Edit this file as you wish, but you must ensure the servername, documentroot and directory are all correct for the codebase. So:
vim ~config/vhost.d/aegir.example.com
Next, we'll create some other useful directories...
mkdir /var/aegir/backups
mkdir /var/aegir/platforms
cp /var/aegir/drupal-6.x/sites/default/default.settings.php /var/aegir/drupal-6.x/sites/default/settings.php
chmod 777 /var/aegir/drupal-6.x/sites/default/settings.php
mkdir /var/aegir/drupal-6.x/sites/default/files
chmod 777 /var/aegir/drupal-6.x/sites/default/files
mkdir /var/aegir/drupal-6.x/sites/all/modules
chmod 777 /var/aegir/drupal-6.x/sites/all/modules
mkdir /var/aegir/drupal-6.x/sites/all/themes
chmod 777 /var/aegir/drupal-6.x/sites/all/themes And then...
logout So we're now back as root. Next we add the aegir user to the www-data group.
sudo adduser aegir www-data Now we want to edit apache's main httpd.conf filesudo vim /etc/apache2/httpd.conf
To add the following line at the end:Include /var/aegir/config/vhost.d/*
Now we want to configure sudo to allow aegir user permission to restart apache:sudo visudo
Use the arrow keys to go to the last line. Press 'a' to add a line. Type:aegir ALL=NOPASSWD: /usr/sbin/apache2ctl
Hit Esc. Type ':'. type 'wq' and hit ENTER.
Configure MySQL
We'll now setup the necessary users and database in MySQL:
mysql -uonlyme -p
mysql> CREATE DATABASE hostmaster
mysql> GRANT ALL ON hostmaster.* TO 'hostmaster'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'aegir'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql> exit Run the installer
First, restart apache:sudo /etc/init.d/apache2 restart
Then in a browser, go to http://aegir.example.com where you setup the aegir instance on DNS etc.
Hosting setup
Setup the database with the hostmaster details we setup earlier.
The setup will ask you to enter the path to drush.php. This is:/var/aegir/drush/drush.php
The configuration path is:/var/aegir/config
And the backup path is:/var/aegir/backups
We've already done the step of adding the line to httpd.conf.
On the Database page, enter the details for the aegir database user.
At some point during the install you'll be prompted to enter a drush command to run the hosting setup...
su - aegir
cd /var/aegir/drupal-6.x
/var/aegir/drush/drush.php hosting setup Configure Aegir
Aegir is now installed, and you can configure it with your preferred settings. Have a browse around. Read the wiki and other posts on here: http://groups.drupal.org/aegir-hosting-system to find out what you can do with it. Prepare to be excited (if you're a geek)!
Adding New Platforms
Platforms are the codebases that Aegir can build sites from, such as drupal-5.10, drupal-6.13, acquia-drupal etc. You can also add new platforms to the system as follows:
cd /var
drush dl drupal-6.13 or checkout the latest acquia code via subversion:
(including the '.' at the end)
or get something like the ProsePoint distro, by visiting their website at http://www.prosepoint.org, seeing what the download URL is, and calling it via wget:
wget http://launchpad.net/prosepoint/trunk/0.23/+download/prosepoint-0.23.tar...
tar -zxvf prosepoint-0.23.tar.gz
rm prosepoint-0.23.tar.gz Or you could upload code via sftp.
I choose to store all codebases in the /var/aegir/platforms directory.
And then select 'create new content' and 'add platform' in Aegir.
Getting Support
Hopefully all is working well for you now. Remember that this is just a release candidate so there may be a few bugs to iron out. If you find one, the very first thing to do is visit the project pages of the main Aegir projects:
http://drupal.org/project/drush
http://drupal.org/project/provision
http://drupal.org/project/hostmaster
http://drupal.org/project/hosting
USE THE SEARCH BOX on the left hand side of the page to look for tickets that might relate to your issue. Otherwise click on the number of open issues to go to the issue page and browse for possible similar tickets.
Only when you cannot find a similar ticket should you open a new ticket - but read these guidelines first: http://groups.drupal.org/node/21890
VPS links
I use VPS.net myself, and am very pleased with it so far. They're based in both the UK and USA.
You can go to their webpage direct using: http://www.vps.net.
Or, if you wish, you can use this affiliate link, which means I'll earn some money from them, at no extra cost to you, if you end up being happy with them, and so staying with them for a while. If you do use it, thanks.
Other good VPS hosts I hear positive things about as well are:
http://www.linode.com
http://www.slicehost.com
But I don't have personal experience of them.
** Addendum from a reader (not the author of this fine document) on SSHD security & configuration
There are two schools of thought regarding changing the SSH port from the standard 22: The first says moving it to another port is more secure, because it’s not where the bad guys expect it to be. The other says that a port scan will reveal it anyhow, and thus may draw special attention from the bad guys. I personally fall into the latter camp.
Regardless, one way to harden any SSH system is to use public key encryption and completely disable the password-response challenge mechanism. Password-response is usually very weak, whereas public key is always strong. This allows passwordless connections, but you can still require a password entry on the client machine prior to connecting, if desired, by adding a password to the private key; this simply means a password will be required before the private key is used to authenticate, via public key, with the remote server. The password is not used to authenticate with the remote server. To disable password-response, add/change these lines (from those previously listed):
PasswordAuthentication no
GSSAPIAuthentication no
UsePAM noNote: If you wish to allow root login, add:
PermitRootLogin without-passwordotherwise set it to:
PermitRootLogin noAlso, if you have a fixed IP, you can further restrict access so connections are only accepted from only certain IP addresses:
AllowUsers 111.222.333.444 111.222.333.555Note: The firewall could also be used to add stealth to the SSH port if all access is from fixed IP addresses.
Don’t forget to add the public key to ~/.ssh/authorized_keys for each account on the server you will be SSHing into. File permissions should be set to 0400 (i.e. only allow read by owner).