Recently I moved my websites to a virtual private server (VPS / VDS) from Memset. Rather than pay an extra £7.50/month for cPanel, I decided to configure it myself. This is my notes about what I did. It’s not designed to be a guide for everyone, but someone may find it useful…
Prerequisites
The server was set up with Debian Lenny (5.0.4), with minimal software installed. I was given the root password, with no user accounts set up.
Set the hostname
The default hostname with Memset is XXX.miniservers.com. I changed that to my own domain name.
hostname precipuus.net echo "precipuus.net" > /etc/hostname echo "precipuus.net" > /etc/mailname
Check Debian is up-to-date
apt-get update apt-get upgrade
Prevent accidental shutdowns
Just in case I accidentally type shutdown in the wrong window like Steve did here!
apt-get install molly-guard
Set the timezone
dpkg-reconfigure tzdata
Install NTP client to automatically keep the time accurate
apt-get install ntp
Clear the message of the day
> /etc/motd
Install Vim (text editor)
apt-get install vim vim-common vim-doc vim-scripts ctags
Install sudo
apt-get install sudo visudo
Change the Defaults line to make it use the root password not the user password, and not bother with the security lecture:
Defaults env_reset,rootpw,!lecture
Add this to allow anyone in the sudo group to use it (as long as they know the root password):
%sudo ALL=(ALL) ALL
Create a user account
Now we have sudo set up, create and switch to a normal user account:
adduser dave usermod -aG sudo dave su dave
Note: The rest of the commands in this post are run as dave, not root.
Add keep-alive to SSH server
I found my SSH connection would time out occasionally when I left it open for a while, so I set up keep-alive:
sudo vim /etc/ssh/sshd_config
Add this to the end:
ClientAliveInterval 300
And then reload the configuration:
sudo /etc/init.d/ssh reload
Install Bazaar 2.0 (version control)
The current version of Bazaar in Lenny is 1.5, so I had to get 2.0 from backports, and the corresponding bzrtools from testing. First, add the two repositories to apt:
sudo vim /etc/apt/sources.list
Add these to the end:
# Testing - for bzrtools 2.0 deb http://ftp.us.debian.org/debian testing main contrib non-free deb-src http://ftp.us.debian.org/debian testing main contrib non-free # Backports - for bzr 2.0 deb http://www.mirrorservice.org/sites/backports.org/ lenny-backports main contrib non-free
Now make sure it doesn’t automatically upgrade packages using these repositories:
sudo vim /etc/apt/preferences
Package: * Pin: release a=stable Pin-Priority: 700 Package: * Pin: release a=lenny-backports Pin-Priority: 675 Package: * Pin: release a=testing Pin-Priority: 650 Package: * Pin: release a=unstable Pin-Priority: 600
And also increase the cache limit to fit the new data in:
sudo vim /etc/apt/apt.conf
Add these to the start of the file (leaving the Memset proxy section alone):
APT::Default-Release "stable"; APT::Cache-Limit 125829120;
Now install Bazaar:
sudo apt-get update sudo apt-get install debian-backports-keyring sudo apt-get install -t lenny-backports bzr sudo apt-get install -t testing bzrtools sudo apt-get autoremove
At this point I was able to set up my standard Linux config files, which I keep in a Bazaar repository.
Install Apache (web server), MySQL (database server), PHP
sudo apt-get remove apache sudo apt-get install apache2 php5 php5-cli php5-mysql php5-mcrypt php5-gd mysql-server sudo a2enmod expires rewrite sudo /etc/init.d/apache2 restart
I keep all my sites and related config files in /home/sites/:
cd /home/ sudo mkdir sites sudo chown dave:dave sites cd sites/ mkdir -p conf template/conf template/htdocs template/logs
This is my server-wide configuration file:
vim conf/httpd.conf
# Common
ServerAdmin XXXXXXXXX@precipuus.net
ServerName precipuus.net
UseCanonicalName off
# Restrict any other directories... just in case
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
# All sites
<Directory /home/sites/>
Options FollowSymLinks
IndexOptions +FancyIndexing +FoldersFirst +IgnoreCase +SuppressColumnSorting
IndexOptions +SuppressDescription +SuppressLastModified +SuppressSize +TrackModified
AllowOverride All
php_flag display_errors off
php_flag log_errors on
php_value error_reporting 28671
# 6143 = E_ALL
# 28671 = E_ALL | E_RECOVERABLE_ERROR | E_DEPRECATED
</Directory>
To install it:
sudo ln -s /home/sites/conf/httpd.conf /etc/apache2/conf.d/global-settings
Now create a template for the rest of the site configuration files:
touch template/conf/email-aliases.conf vim template/conf/httpd.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /home/sites/example.com/htdocs/
ErrorLog /home/sites/example.com/logs/error.log
#CustomLog /home/sites/example.com/logs/access.log combined
</VirtualHost>
<Directory /home/sites/example.com/>
# Per-directory config goes here
</Directory>
Now create the default site:
cp -r template default vim default/conf/httpd.conf
<VirtualHost *:80>
# Note: No ServerName or ServerAlias for the default site
DocumentRoot /home/sites/default/htdocs/
ErrorLog /home/sites/default/logs/error.log
#CustomLog /home/sites/default/logs/access.log combined
</VirtualHost>
<Directory /home/sites/default/>
# Per-directory config goes here
</Directory>
And replace the default Apache default site configuration:
sudo mv /etc/apache2/sites-available/default{,.dist}
sudo ln -s /home/sites/default/conf/httpd.conf /etc/apache2/sites-available/default
To create additional sites:
cd /home/sites/ cp -r template dave-miller.com sed -i 's/example.com/dave-miller.com/g' dave-miller.com/conf/httpd.conf sudo ln -s /home/sites/dave-miller.com/conf/httpd.conf /etc/apache2/sites-available/dave-miller.com sudo a2ensite dave-miller.com
And finally reload Apache so that all takes effect:
sudo /etc/init.d/apache2 reload
Install Exim (mail server)
I set up Exim to forward mail from my various domains to my Google Mail account. Since it’s just forwarding everything, there’s no user accounts and no anti-spam/anti-virus.
sudo apt-get remove postfix sudo apt-get install exim4-daemon-heavy
Note: I’m not sure if -heavy is required, or if the -light version would do.
It then asks a number of questions:
- General type: Internet site
- System mail name: precipuus.net
- IP addresses: blank
- Other destinations: leave as default
- Domains to relay for: blank
- Machines to relay for: blank
- Split configuration into small files? Yes
- Root and postmaster mail recipient: dave
Next, I originally set up greylisting. I later removed it because the added delay wasn’t worth it for the limited amount of spam I actually get, which Google Mail filters out anyway. But this is how to set it up:
sudo apt-get install greylistd sudo greylistd-setup-exim4 add -netmask=24
Create a directory for the per-domain forwarding files:
sudo mkdir /etc/exim4/virtual
Tell Exim to accept the domains listed in that directory for local delivery / forwarding:
sudo vim /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
Change this line:
domainlist local_domains = MAIN_LOCAL_DOMAINS
To this:
domainlist local_domains = MAIN_LOCAL_DOMAINS : dsearch;/etc/exim4/virtual
Now set up a router to tell Exim to use these files for forwarding:
sudo vim /etc/exim4/conf.d/router/350_local-virtual_aliases
forced_virtual_aliases:
driver = redirect
allow_defer
allow_fail
local_parts = postmaster : abuse
data = $local_part
retry_use_local_part
pipe_transport = address_pipe
file_transport = address_file
no_more
virtual_aliases:
driver = redirect
allow_defer
allow_fail
domains = dsearch;/etc/exim4/virtual
local_part_suffix = +*
local_part_suffix_optional
data = ${expand:${lookup{$local_part}lsearch*@{/etc/exim4/virtual/$domain}}}
retry_use_local_part
pipe_transport = address_pipe
file_transport = address_file
no_more
Note: The first section forwards abuse@ and postmaster@ for all domains to the equivalent local addresses.
Check root / abuse / postmaster emails are all forwarded to me:
sudo vim /etc/aliases
It should contain the following lines, among others:
postmaster: root abuse: root root: dave
Now forward all these emails to my main email address, but keep a copy locally in case forwarding is broken:
echo "dave, XXXXXX@googlemail.com" > ~/.forward
Now restart Exim with the new configuration:
sudo /etc/init.d/exim4 restart
Set up the forwarding file for each domain:
sudo vim /etc/exim4/virtual/dave-miller.com
example: example@somewhere.com bounce: :fail: blackhole: :blackhole: *: catchall@somewhere.com
Finally, install Mutt to read email at the command line:
sudo apt-get install mutt
Set up SFTP with chroot jail for normal users
First, SFTP requires that all parent directories of the jail root are owned and only writable by root:
sudo chown root:root /home sudo chmod 755 /home sudo mkdir /home/jail
Create a group for jailed SFTP users:
sudo addgroup sftponly
Configure SSH:
sudo vim /etc/ssh/sshd_config
Remove or comment out this line (by adding a # to the start of it):
Subsystem sftp /usr/lib/openssh/sftp-server
Add this instead:
Subsystem sftp internal-sftp
Match Group sftponly
ChrootDirectory /home/jail/%u
AllowTCPForwarding no
X11Forwarding no
ForceCommand internal-sftp
Restart SSH server:
sudo /etc/init.d/ssh restart
Now create users to be jailed:
sudo adduser jason sudo usermod -aG sftponly jason sudo chmod 750 /home/jason sudo mkdir /home/jail/jason sudo mkdir /home/jail/jason/etc sudo mkdir /home/jail/jason/private sudo mkdir /home/jail/jason/example.com sudo su -c "sed -n '/^\(root\|jason\|www-data\):/p' /etc/passwd > /home/jail/jason/etc/passwd" sudo su -c "sed -n '/^\(root\|jason\|www-data\):/p' /etc/group > /home/jail/jason/etc/group"
And set up any directories inside the jail to point to the directories outside the jail:
sudo vim /etc/fstab
Add this to the end:
/home/jason /home/jail/jason/private none bind 0 0 /home/www/example.com /home/jail/jason/example.com none bind 0 0
Then tell it to mount the directories now:
sudo mount -a
Comments
1. Steve
Sssh nobody was supposed to notice my mistake ;)
Posted on 21st February 2010 at 12:50pm.