My Low End VPS Server

Linux, Nginx, Mysql, PHP, Postfix+SASL, Dovecot, Spamassassin, chkrootkit, firewall, maildrop, rsnapshot

Originally posted by Raj Prakash on rajeshprajash.com. His site disappeared, so this is a mirror of the original document.

v0.05, 15 May 2011


This document describes how to setup a Debian Linux VPS to replace your standard shared hosting account.

 

This document started out as a bunch of scribbles on scrap paper as I built a Virtual Private Server (VPS) into a fully functioning internet server. It was notes on how I configured the server for the various pieces of the stack. The need for the server was identified when I wanted to migrate my cPanel Shared Hosting account at Hostgator to a low end VPS for more control and freedom to run whatever software I wanted. It was also a good opportunity to get back into Linux system configurations and serving web content. As a collateral benefit, but not as the main drive, I was able to save a few dollars a month in web hosting costs.


1. Introduction

1.1         Revision History

v0.01 – 16 March 2011 – Initial revision. All new content
v0.02 – 12 April 2011 – Revision 1
1. Section 2.3.1 : Added new smtpd_client_restrictions and smtpd_sender_restrictions and explained
2. Section 1.3 : Updated new links
3. Seciton 2.3.2 : Fixed opening braces in auth default for dovecot. Added note for why it’s important.
4. Section 2.3.2 : Bumped up login_max_processes_count from 3 to 4 based on experience.
5. Added new sections 2.5, 2.6. and 2.7.
6. Cleaned up sections 3 and 4.
v0.03 – 23 April 2011 – Revision 2
1. Updated Section 3 – Future Plans
2. Added new iptables section 2.8
3. Added new dropbear non-standard port section 2.9
4. Section 1.3 : Added new links
v0.04 – 13 May 2011 – Revision 3
1. Section 1.3 : Updated new links
2. Added new section 5 documenting rsnapshot backup scheme
3. Updated section 2.8 to warn about need for ipt_recent modules for this example firewall
4. Added new section 6 for future addition of files
5. Added new section 2.3.5 to document use of pflogsumm
v0.05 – 15 May 2011 – Revision 4
1. Section 1.3 : Updated new links
2. Added new section 5.2 for a backup MX
3. Renumbered Section 5.1 for rsnapshot

1.2 Disclaimer

Use the information in this document at your own risk. I disavow any potential liability for the contents of this document. Use of the concepts, examples, and/or other content of this document is entirely at your own risk.

All copyrights are owned by their owners, unless specifically noted otherwise. Use of a term in this document should not be regarded as affecting the validity of any trademark or service mark.

Naming of particular products or brands should not be seen as endorsements.

You are strongly recommended to take a backup of your system before major installation and backups at regular intervals.

 

This document is not intended to describe a secure internet server installation, only a barebones functioning one. It is still the responsibility of the reader to take this basic setup document to the next level and harden it against intruders.

1.3 Credits

In this version I have the pleasure of acknowledging LowEndAdmin : contact (at) lowendbox DOT com for his script.

In addition, all of the installation and configuration notes in this section were cribbed together from the following sites. As with any other section, I highly recommend that you thoroughly read these websites to understand what is happening in this section.

http://www.debianadmin.com/debian-mail-server-setup-with-postfix-dovecot-sasl-squirrel-mail.html
http://www.kloopy.com/344_Postfix__SASL2__unable_to_open_Berkeley_db
http://www.postfix.org/STANDARD_CONFIGURATION_README.html
http://www.postfix.org/VIRTUAL_README.html
http://www.postfix.org/SASL_README.html
http://townx.org/blog/elliot/simple_spamassassin_setup_with_postfix_and_dovecot_on_ubuntu_breezy
http://www.stevefortuna.com/postfix-maildrop-spam-folder/
http://howto.gumph.org/content/configure-spamassassin/
http://www.lowendbox.com/blog/wordpress-cheap-vps-lowendscript/
http://forums.serverbeach.com/showthread.php?7153-The-PTR-or-Reverse-DNS-record-and-why-it-is-important-(DISCUSSION)
http://www.chkrootkit.org
http://www.debianhelp.co.uk/schedulejobs.htm
http://wiki.apache.org/spamassassin/RuleUpdates
http://articles.slicehost.com/2010/4/30/ubuntu-lucid-setup-part-1
http://www.lowendtalk.com/questions/3706/iptables-recent-module-missing
http://oob.freeshell.org/nzwireless/firewall.html
http://www.debian-administration.org/articles/217
http://www.debian-administration.org/articles/152
http://poller.se/2010/12/rsnapshot-and-mysqldump/
http://linxnet.com/postfix_contrib.html
http://www.postfix.org/postconf.5.html#reject_unknown_client_hostname
http://www.pantz.org/software/postfix/setuppostfix.html
http://postfixmail.com/blog/index.php/built-in-content-filters-for-postfix/
http://www.cyberciti.biz/faq/postfix-backup-mx-server-anti-spam/
http://www.freespamfilter.org/forum/viewtopic.php?t=28
http://www.stocksy.co.uk/articles/Linux/postfix_as_a_backup_mx_host/

Any comments or suggestions can be mailed to my mail address on my little slice mailto:raj@rajeshprakash.com

2. The VPS Configuration

2.1 Strip down Debian

You’ve got a newly purchased VPS. Make sure to get a fresh install of Debian on your VPS. As noted in this post (http://www.lowendbox.com/blog/wordpress-cheap-vps-lowendscript/), stick with a 32-bit OS to get the best benefit in RAM usage. I highly recommend reading the entire blog post as many of the steps in this howto are harvested from that work.

 

After logging into the VPS as root, start by stopping as many pre-installed applications as possible by issuing the proper commands. In my specific case, I prefer to stop apache2, exim, as well as a few others before going on, so :

 

/etc/init.d/apache2 stop

/etc/init.d/exim4 stop

...

 

First thing I like to do is make sure I have my /etc/apt/sources.list for apt to a useful local mirror. I comment out whatever was in the default install and add a local mirror similar to the following. Please choose a local mirror to reduce bandwidth and to speed up your installations. Choose one from http://www.debian.org/mirror/list. Atlanta happens to be my local mirror. Also at the time of this tutorial, Lenny was the stable distribution. You can change that to whatever version of Debian you are using.

 

deb http://ftp.gtlib.gatech.edu/pub/debian lenny main contrib non-free

deb http://security.debian.org/debian-security lenny/updates main contrib non-free

deb http://volatile.debian.org/debian-volatile lenny/volatile main contrib non-free

 

Now run an apt-get update.

 

Next, grab LowEndAdmin’s script. Note that you may have to add the --no-check-certificate option to wget:

 

wget http://github.com/lowendbox/lowendscript/raw/master/setup-debian.sh

 

and issue the “system” command :

 

bash setup-debian.sh system

 

According to LowEndAdmin (hereafter referred to as LEA), this script does the following items. I highly recommend peeking at the bash script itself to convince yourself, don’t just take our word for it! Looking at the script source will help you troubleshoot any potential issues in the future.

 

         Installs dropbear to replace openssh. Invoked from xinetd.

         Installs inetutils-syslogd to replace rsyslog.

         Installs cron

         Removes some commonly bundled applications that should not be there in the first place for a minimal distro (apache2, sendmail, bind9, samba, nscd, etc).

 

I am not a big fan of the simple text editor vi, so I choose to use the simple text editor nano. I have the worst memory, so instead of using the find command to locate files, I like to use locate. These two applications are a personal preference, so you can opt to install them or not. Not installing these two will not affect the system at all. I’ll go ahead and install those:

 

apt-get install locate nano

updatedb

 

I also like to make sure that I have all the latest and greatest system libraries and supporting services possible before going forward, so at this point I like to do an upgrade and dist-upgrade. This is a standard package and system upgrade using Debian’s apt function. Further reading and information on this can be found at http://www.debian.org/doc/manuals/apt-howto/. See section 3.4 and section 3.5, specifically. Issue the following commands:

 

apt-get upgrade

apt-get dist-upgrade

 

In my particular installation, I have also disallowed logging into dropbear as the root user. It is a basic security measure, and is a simple change. Start by adding a new unix system user, and then doing the following configuration change:

 

adduser your_new_system_username

 

Edit /etc/xinetd.d/dropbear with your favorite editor and add -g to the server_args parameter.

 

Last but not least, it is important to me as a system administrator to make sure I am able to correlate system events in my “real” time. That is, if I can’t correlate the system time with my local time, how can I figure out when thing happen. Here’s an example, lets say you’re sleeping and you wake up and notice your VPS has been hacked. You log in, and check the logs. Your log timestamps say you had a DDOS followed by a brute force attack at 6:32AM system time. If you don’t know what timezone your system is set to, when the heck did that happen in your life time? Lets set our time zone to something we can recognize. From the command line, issue the following command and select your appropriate zone.

 

dpkg-reconfigure tzdata

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation.

2.2 Install the web server Nginx and PHP5

Issue the following commands using LEA’s script retrieved in Section 2.1:

 

bash setup-debian.sh nginx

bash setup-debian.sh php

 

Please note that at this point, you still don’t have any sites enabled. In my particular installation, I am using all virtual hosts, so for convenience the virtual host configuration example can be found here: http://wiki.nginx.org/VirtualHostExample.

 

Nginx is well documented and has a fairly complete wiki on configuration options on its website. For convenience, here is a link: http://wiki.nginx.org.

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server.

2.3 Install the mail server

2.3.1 Install Postfix and configure SASL Authentication

First lets get Postfix installed with the supporting packages for SASL authentication.

 

apt-get install postfix postfix-tls libsasl2-2 sasl2-bin libsasl2-modules

 

Debconf will ask you a few questions. Answer “Internet Site” and enter your hostname for the System Mail Name parameter.

 

Now lets prepare the system for saslauthdb. Note that saslauthd chroots (by default) to /var/spool/postfix for security. Thus, despite the authentication daemon thinking it's checking /etc/sasldb2 and this is where the saslpasswd2 creates the database, it's not there. You can simply copy /etc/sasldb2 to /var/spool/postfix/etc/sasldb2 and the problem will be fixed, or add your users to the saslauthdb database directly to the chrooted location as shows below.

 

rm -r /var/run/saslauthd/

mkdir -p /var/spool/postfix/var/run/saslauthd

ln -s /var/spool/postfix/var/run/saslauthd /var/run

chgrp sasl /var/spool/postfix/var/run/saslauthd

adduser postfix sasl

 

To add a user to the saslauthdb database, issue the following commands to the chrooted area:

 

saslpasswd2 -f /var/spool/postfix/etc/sasldb2 -u yourdomain.tld your_sasl_username

chown root:sasl /var/spool/postfix/etc/sasldb2

 

Note that the chown is only required the first time you create that database, but it’s good to keep the right ownership handy in case it gets screwed up.

 

Now lets tell Postfix to use SASL SMTP authentication. Pop open /etc/postfix/main.cf in your favorite editor and add these lines (modifying the smtp_sasl_local_domain parameter, of course):

 

smtpd_sasl_auth_enable = yes

smtpd_sasl_local_domain = yourdomain.tld

smtpd_recipient_restrictions = permit_mynetworks,permit_sasl_authenticated,reject_unauth_destination

smtpd_sasl_security_options = noanonymous

 

Now, restart your mailsystem and you’re ready for SASL!

 

/etc/init.d/postfix restart

 

Next step in the process is setting up Postfix to use virtual domains and real system users. With the approach described in this section, every hosted domain can have its own info etc. email address. However, it still uses UNIX system accounts for local mailbox deliveries.

 

Add these two lines to your /etc/postfix/main.cf

 

virtual_alias_domains = example.tld example2.tld ...other hosted domains...

virtual_alias_maps = hash:/etc/postfix/virtual

The virtual_alias_domains setting tells Postfix that example.tld is a so-called virtual alias domain. If you omit this setting then Postfix will reject mail (relay access denied) or will not be able to deliver it (mail for example.com loops back to myself).


The /etc/postfix/virtual file contains the virtual aliases where you can map your virtual domains. Here is an example exerpted from the Postfix documentation. Create your own with your own domains.

/etc/postfix/virtual:

postmaster@example.com postmaster
info@example.com joe
sales@example.com jane

Note, NEVER list a virtual alias domain name as a mydestination domain! Also note that virtual aliases can resolve to a local address or to a remote address, or both. They don't have to resolve to UNIX system accounts on your machine.

Execute the command "postmap /etc/postfix/virtual" after changing the virtual file, and execute the command "postfix reload" after changing the main.cf file. Running postmap is different than newaliases, so make sure you use postmap specifically. The command newaliases only rebuilds those postfix aliases identified in /etc/aliases

I don’t have a real reason to prefer Maildir over mbox mail formats aside from the fact that all the mailservers I’ve ever build use Maildir, so lets use that here too. Add the following line to your main.cf. This setting is important in my particular mail server setup as future sections rely on Maildir format. If you want to use mbox, you can omit the setting, but then you must adapt future settings for mbox.

home_mailbox = Maildir/

Obviously, you need to also configure postfix for the most basic settings, so change these two as well:


mydestination = yourhostname.yourdomain.tld

myhostname = yourhostname.yourdomain.tld

 

As a RAM memory savings, you can also cut down the number of children threads that saslauthdb starts with. The default is 5, but from a probability standpoint, my particular server setup does not need 5 concurrent authentication processes. Lets tell saslauthd to start at boot and also only load 1 thread.

 

Edit /etc/default/saslauthd and modify the following two parameters :

 

THREADS=1

START=YES

 

Now, just to make sure everything is loaded, restart postfix and saslauthdb by issuing these commands at the command line:

 

/etc/init.d/postfix restart

/etc/init.d/saslauthd restart

 

To test out the whole installation, follow some of the telnet instructions in the Postfix documentation: http://www.postfix.org/SASL_README.html#server_test.

 

Now, lets install some bare minimum spam prevention techniques to Postfix. We can perform some basic client and sender restriction checks to stop Postfix from queuing emails from IPs who appear on known spamming block lists, from those emailing from dynamic IPs, and from those who do not have fully qualified domain names as the sender. Add the following lines (or modify the existing lines) in your /etc/postfix/main.cf

 

smtpd_client_restrictions = permit_mynetworks,

permit_sasl_authenticated,

reject_rbl_client zen.spamhaus.org,

reject_rbl_client dnsbl.sorbs.net,

reject_rbl_client bl.spamcop.net,

reject_rbl_client cbl.abuseat.org,

reject_rbl_client combined.njabl.org

smtpd_sender_restrictions = reject_non_fqdn_sender

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server.

2.3.2 Install Dovecot IMAP Server

Issue the following command to go grab the latest Dovecot package from the repository :

 

apt-get install dovecot-imapd

 

Dovecot is very simple to configure and only requires 3 tweaks to make everything work nicely.

 

Tweak 1 : Open /etc/dovecot/dovecot.conf and make the following modifications to the two paramaters (uncomment them in the config file if you need to):

 

protocols = imap

disable_plaintext_auth = no

 

Tweak 2 : Now, look for the line that starts with auth default, and just before that line insert the lines below.

 

auth default {

mechanisms = plain login

passdb pam {

}

userdb passwd {

}

socket listen {

client {

path = /var/spool/postfix/private/auth

mode = 0660

user = postfix

group = postfix

}

}

}

 

Now, rename previous auth default to auth default2. If you dont rename this then dovecot server will give you error like multiple instances of auth default. Note that it is important to have the opening brace on the same line as the block title. Dovecot will cry if you don’t do this. For example, the opening brace must be on the same line as passdb pam or on the same line as socket listen.

 

Tweak 3 : To save RAM usage on the low end VPS, limit the number of processes Dovecot can spawn by modifying the following two parameters. The config file is well documented and so you can read about what these two parameters mean. From a statistics standpoint, the domains that I am hosting on my server are relatively low traffic and low frequency. The probability of multiple incoming connections to be processed concurrently is low. This is how I can get away with keeping the login process count low. If you have a higher load mail server, you can opt to bump up this value, but be prepared to lose more allocated RAM for the new child processes.

 

login_processes_count = 2

login_max_processes_count = 4

 

Now, just to make sure everything is loaded, restart Dovecot by issuing these commands at the command line:

 

/etc/init.d/dovecot restart

 

To test out the whole installation, follow some of the telnet instructions in the Dovecot documentation: http://wiki1.dovecot.org/TestInstallation or open your favorite IMAP client and point it to your server.

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server.

2.3.3 Install Spamassassin and integrate it with Postfix

At this point, you have a fully functioning SASL SMTP and IMAP server capable of hosting email for any number of virtual domains mapped to as many real system users (or forwarding users) as you like. That doesn’t mean, however, that your mail server is smart enough to reject the billions of spam messages that fly around the internet all day long. In this section, we install and integrate the very popular, mature, and widely-deployed open source project that serves as a spam mail filter. Grab the packages and setup the basic architecture from the command line:

 

apt-get install spamassassin spamc

groupadd spamd

useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd

mkdir /var/log/spamassassin

chown spamd:spamd /var/log/spamassassin

 

Now edit /etc/default/spamassassin so these options are set:

 

ENABLED=1

SAHOME="/var/log/spamassassin/"

OPTIONS="--create-prefs --max-children 1 --username spamd \

-H ${SAHOME} -s ${SAHOME}spamd.log"

 

The --max-children 1 option specifies the maximum number of children to spawn. Spamd will spawn that number of children, then sleep in the background until a child dies, wherein it will go and spawn a new child. Incoming connections can still occur if all of the children are busy, however those connections will be queued waiting for a free child. The minimum value is 1, the default value is 5.

 

Note that if you run too many servers for the amount of free RAM available, you run the danger of hurting performance by causing a high swap load as server processes are swapped in and out continually.

 

From a statistics standpoint, the domains that I am hosting on my server are relatively low traffic and low frequency. The probability of multiple spam mails coming in to be processed concurrently is low. This is how I can get away with keeping the max children low. If you have a higher load mail server, you can opt to bump up this value, but be prepared to lose another 15-20MB of allocated RAM for the new child process.

 

Now that the architecture is setup, and a few miscellaneous settings are set, lets integrate Spamassassin with Postfix.

 

Edit /etc/postfix/master.cf and add this line as the first line of the file. Replace XXX.XXX.XXX.XXX with your external IP where you will be receiving incoming email from. The "-o content_filter" line causes Postfix to add one content filter request record to each incoming mail message, with content "spamassassin". This record overrides the normal mail routing and causes mail to be given to the content filter instead.

 

XXX.XXX.XXX.XXX:smtp inet n - - - - smtpd

-o content_filter=spamassassin

127.0.0.1:smtp inet n - - - - smtpd

 

This makes Postfix pipe email to Spamassassin once it's been received and it uses IPs to specify that we run Spamasssin on incoming email from the external internet, but not on outgoing email sent from the localhost.

 

Then add this to the end of the same file to identify what the content filter identified above should do :

 

spamassassin unix - n n - - pipe

user=spamd argv=/usr/bin/spamc -f -e

/usr/sbin/sendmail -oi -f ${sender} ${recipient}

 

Now, just to make sure everything loaded, restart Postfix and Spamassassin by issuing these commands at the command line:

 

/etc/init.d/postfix restart

/etc/init.d/spamassassin restart

 

To test out the whole installation, follow some of the telnet instructions in the Spamassassin documentation: http://wiki.apache.org/spamassassin/TestingInstallation. Check the email headers when the email arrives to see all the Spamassassin magic!

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification!

2.3.4 Filtering Spam out of your INBOX with Maildrop

If you’re like me, then it’s not enough just to have Spamassassin rewrite the headers in your emails. You want to know, visually, that Spamassassin has done its job. To do that, Spamassassin can rewrite the message headers, as well as rewriting the email’s subject line. This way there is a clear indication that a message is spam.

 

There are many ways to do sieve or post delivery filtering, but the easiest way for me is to use maildrop for local delivery and filtering. Lets install maildrop, and tell it to deliver anything marked as spam (by Spamassassin’s header rewriting X-Spam-Flag) not to our INBOX, but to a Junk folder.

 

apt-get install maildrop

 

Open /etc/maildroprc with your favorite editor, uncomment the DEFAULT=”$HOME/Maildir” line and add the following to the end of the file:

 

# commands and variables for making the mail directories

maildirmake=/usr/bin/maildirmake

mkdir=/bin/mkdir

rmdir=/bin/rmdir

MAILDIR=$DEFAULT

 

# make the user's mail directory if it doesn't exist

`test -e $MAILDIR`

if ($RETURNCODE != 0)

{

`$mkdir -p $MAILDIR`

`$rmdir $MAILDIR`

`$maildirmake $MAILDIR`

}

 

# make the .Junk folder if it doesn't exist

JUNK_FOLDER=.Junk

_JUNK_DEST=$MAILDIR/$JUNK_FOLDER/

`test -d $_JUNK_DEST`

if ($RETURNCODE != 0 )

{

`$maildirmake $_JUNK_DEST`

#auto subscribe. the following works for courier-imap

`echo INBOX.Junk >> $MAILDIR/courierimapsubscribed`

}

 

# If the Spam-Flag is set, move the mail to the Junk folder

if (/^X-Spam-Flag:.*YES/)

{

exception

{

to $DEFAULT/.Junk/

}

}

 

Now, lets make sure that Postfix delivers the mail to maildrop instead of the default procmail. Open /etc/postfix/main.cf in your favorite editor and either modify the mailbox_command parameters, or comment the old one and add a new line, to identify maildrop as the new local delivery agent.

 

mailbox_command = /usr/bin/maildrop

 

Last but not least, lets get a visual indication that Spamassassin has done its job. Open /etc/spamassassin/local.cf in your favorite editor and uncomment and modify the following paramaters

 

rewrite_header Subject [SPAM]

report_safe 0

 

Now, just to make sure everything loaded, restart the entire mail system by issuing these commands at the command line:

 

/etc/init.d/postfix restart

/etc/init.d/spamassassin restart

/etc/init.d/saslauthdb restart

/etc/init.d/dovecot restart

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, and a mail sieve!

2.3.5 Mail Log Analysis

pflogsumm.pl is designed to provide an over-view of postfix activity, with just enough detail to give the administrator a "heads up" for potential trouble spots. Pflogsumm.pl was written using Perl 5.004 and requires the Date::Calc module. I have found it to be an invaluable tool in analysis of how the mail server is performing and what is going on behind the scenes once the mail server went live. Here is a quick and dirty way to get the output of pflogsumm to you on a nightly basis for analysis.

At the command line, move to your temp directory and download the latest production version from http://linxnet.com/postfix_contrib.html.

cd /tmp/
wget http://linxnet.com/downloads/pflogsumm-1.1.1.tar.gz
tar zxvf pflogsumm*.tar.gz
cp pflogsumm-1.1.1/pflogsumm.pl /usr/local/bin/
apt-get install libdate-calc-perl

Then run it manually once just to see what kind of output you get.

/usr/local/bin/pflogsumm.pl /var/log/mail

If you get useful information out of it, then add a note to cron for it to be emailed to you nightly.

0 2 * * * /usr/local/bin/pflogsumm.pl /var/log/mail | mail -s "mailserver Analysis" you@yourdomain.tld

Now clean up /tmp

rm –r /tmp/*

If you also need a Backup MX installation, go read Section 5.2 after testing your mail installation.

2.4 Installing the database engine Mysql

Issue the following command using LEA’s script retrieved in Section 2.1 above

 

bash setup-debian.sh mysql

 

This script installs mysql_server and mysql_client and configures mysql to disables InnoDB in accordance with the discussion here: http://www.lowendbox.com/blog/reducing-mysql-memory-usage-for-low-end-boxes/

 

The script also issues you a new mysql root password and conveniently saes it under ~/.my.cnf for your viewing pleasure. Good security practice is to go find the password, change it, and delete this file. You can do as you please depending on your situation.

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine.

2.5 Set your rDNS

While this is something you don’t do from within your new low end container, if you plan on running the mail server portion of this how-to, it’s a required step to do. Many mail servers nowadays do reverse DNS lookups to see if the IP you’re trying to send mail fro is really who your mail server is identifying itself as. Many ISPs and mail services (i.e. Gmail, Yahoo, AOL, etc) will now reject or defer emails from senders who fail the rDNS lookup. At the time of writing the initial revision of this document, AOL was deferring emails received from my mail server because I did not have my rDNS propagate yet.

Generally your hosting provider either sets the rDNS for you, or you go into your container control panel (i.e SolusVM, HyperVM, etc) and set it yourself. I’d start by looking through the FAQs or Knowledgebase at your hosting provider for how to set it up, or open up a ticket for them to set it for you.

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts.

2.6. Installing chkrootkit

Chkrootkit is listed in the "Top 100 Network Security Tools" survey, 2006 edition, released by Insecure.Org. This is a very simple tool, with a low system load utility, that can help look for basic root kits on a nightly basis with the help of cron.

Issue the following command at your command line :

apt-get install chkrootkit

 

Then open /etc/chkrootkit.conf in your favorite text editor and change the following parameter from false to true:

 

RUN_DAILY="false" to RUN_DAILY="true"

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts, that will check nightly for rootkits and email the findings to root.

2.7. Adding sa-update to cron

The goal of sa-update is to download new configuration files (rules, scores, etc,) so that SpamAssassin will use them to better catch spam and/or to avoid catching ham messages. The main reason to use sa-update is that the old method of disseminating rules, releasing a new version SpamAssassin, is a lengthy process that can take many months. Spam is rapidly changing, and new rules are often written in response. With sa-update, those rules can quickly (potentially within minutes) be distributed and the new spam caught. Simply put, sa-update allows rules to be distributed as they are developed, while full SpamAssassin releases can focus on bug fixes and new features.

 

For my systems, I like to make sure I update all my packages as frequently as possible to fix both security and configuration issues. So I like to make sure I keep my spam matching rules as new as I can. I use the scheduling utility cron to keep sa-update up to date.

 

Go to the command line, and as root, type the command ‘crontab –e’. This opens the crontab entries list for the root user. An example Crontab file Format or syntax would be like this:

 

* * * * * Command to be executed

- - - - -

| | | | |

| | | | +----- Day of week (0-6)

| | | +------- Month (1 - 12)

| | +--------- Day of month (1 - 31)

| +----------- Hour (0 - 23)

+------------- Min (0 - 59)

 

To do a nightly update of sa-update, simple add a new line item in root’s crontab list like the following. It will run the sa-update command each night at 2am. You can change the time to whatever time your server loading is normally the lowest. You don’t want to eat up valuable server processing resources when you’re at your statistical high demand time. Once you add the new entry, save and exit and you’re done.

0 2 * * * /usr/bin/sa-update

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts, that will check nightly for rootkits and run SpamAssassin’s sa-updater and email the results to root.

2.8. iptables Firewall

“iptables is a user space application program that allows a system administrator to configure the tables provided by the Linux kernel firewall (implemented as different Netfilter modules) and the chains and rules it stores. Different kernel modules and programs are currently used for different protocols; iptables applies to IPv4, ip6tables to IPv6, arptables to ARP, and ebtables for Ethernet frames.

Iptables requires elevated privileges to operate and must be executed by user root, otherwise it fails to function. On most Linux systems, iptables is installed as /usr/sbin/iptables and documented in its man page which can be opened using man iptables when installed. It may also be found in /sbin/iptables, but since iptables is not an "essential binary", but more like a service, the preferred location remains /usr/sbin.

iptables is also commonly used to inclusively refer to the kernel-level components. x_tables is the name of the kernel module carrying the shared code portion used by all four modules that also provides the API used for extensions; subsequently, Xtables is more or less used to refer to the entire firewall (v4,v6,arp,eb) architecture.” – Excerpted from http://en.wikipedia.org/wiki/Iptables

Lets start with a clean slate by flushing out any iptables rules that you may have remnant from previous tinkering or any default firewall oddities.

/sbin/iptables –F

 

Now, using your favorite text editor, edit or create the file /etc/iptables.up.rules

 

pico /etc/iptables.up.rules

 

Then enter the following text into that file making modifications to open up incoming ports as required for your setup. Make note to change the ports for the various services (including SSH) if you are running daemons on nonstandard ports.

 

*filter

 

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0

-A INPUT -i lo -j ACCEPT

-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

 

# Accepts all established inbound connections

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

 

# Allows all outbound traffic

-A OUTPUT -j ACCEPT

 

# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)

#-A INPUT -p tcp --dport 80 -j ACCEPT

#-A INPUT -p tcp --dport 443 -j ACCEPT

 

# Allows SMTP, POP, and IMAP connections from anywhere (the normal ports for mail)

#-A INPUT -p tcp --dport 25 -j ACCEPT

#-A INPUT -p tcp --dport 143 -j ACCEPT

#-A INPUT -p tcp --dport 110 -j ACCEPT

 

# Allows DNS from anywhere (the normal ports for nameserver)

#-A INPUT -p tcp --dport 53 -j ACCEPT

 

# Allows FTP connections from anywhere (the normal ports for ftp)

#-A INPUT -p tcp --dport 25 -j ACCEPT

 

# Allows SSH connections (only 4 attempts by an IP

# every 3 minutes, drop the rest to prevent SSH attacks)

-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource

-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 4 --name DEFAULT --rsource -j DROP

-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

 

# Allow ping

-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

 

# log iptables denied calls

-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

 

# Reject all other inbound - default deny unless explicitly allowed policy

-A INPUT -j REJECT

-A FORWARD -j REJECT

 

COMMIT

 

Now, you’ve just saved rules you want to use, but they are not in effect yet. To tell iptables to use your new rules, run the command:

 

/sbin/iptables-restore < /etc/iptables.up.rules

 

Although the rules are up and running, they are only active for the current session. If the VPS were to be rebooted they would be lost. Let's ensure they are restored on a reboot. We'll add a small script that the system will run when your network interfaces are started. Create a file using your favorite text editor (mine is pico):

 

pico /etc/network/if-pre-up.d/iptables

 

Add the following lines to the new file:

 

#!/bin/sh

/sbin/iptables-restore < /etc/iptables.up.rules

 

Save your changes, and then make the new script executable:

 

chmod +x /etc/network/if-pre-up.d/iptables

 

That should ensure that whenever your network interfaces are brought up (usually just at boot time), the firewall will be too.

 

One thing to note is that this iptables setup requires use of the iptables modules “recent”. As noted on LowEndTalk, not all VPS providers have the module recent loaded on the host node and so you may fail some of these iptables rules. To check if your box has the recent module loaded, execute the following command

 

cat /proc/net/ip_tables_matches

 

If you see the word “recent” in the list, then you’re good to go. If you do not, drop a ticket into your hosting provider to have it enabled on the host node.

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts, that will check nightly for rootkits and email the findings to root, with a fully functioning firewall.

2.9. Change dropbear listening port

By default dropbear and OpenSSH servers run on TCP port 22. Running SSH on a non-standard port is akin to re-locating the ignition key slot in a car to the trunk. Security though obscurity is not security, but it does foil robot scripts that are too stupid to see the extension cord running from the dash through the back seat. To take advantage of that stupidity, and to throw off impatient hackers that don’t run a port scan, we can run our dropbear instance on a non-standard port.

 

Open /etc/default/dropbear in your favorite text editor and change the following parameter replacing XXX with whatever port you want:

 

DROPBEAR_PORT=22 to DROPBEAR_PORT=XXX

 

Alternatively, if you run dropbear from xinetd you can edit /etc/xinetd.d/dropbear and change the port variable and add the type paramater. For example, (remember we added the –g to the server_args parameter back in Section 2.1)

 

service dropbear

{

socket_type = stream

only_from = 0.0.0.0

wait = no

user = root

protocol = tcp

server = /usr/sbin/dropbear

server_args = -i -g

disable = no

port = XXX

type = unlisted

}

 

A note of caution is that if you have followed the iptables tutorial in Section 2.8, be wary to make sure you make the adjoining change to your iptables rules to account for this port change. Another note is depending on your setup, adding port = XXX to /etc/xinetd.d/dropbear may not be enough. You also need to add a new parameter "type = unlisted". The xinetd man page says that the type paramater is required if this is a service not listed in a standard system file (like /etc/rpc for RPC services, or /etc/services for non-RPC services).

 

Now restart dropbear for the settings to take effect, and logoff and log back in to make sure it took effect.

 

/etc/init.d/dropbear restart

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts, that will check nightly for rootkits and email the findings to root, with a fully functioning firewall, running dropbear on a non-standard port.

3. Future Plans for this document

·         Adding a simple FTP server, proftpd

·         Adding in mailing list support, ecartis

·         Add new section to document install of simple, flat file, php webmail client hastymail2

·         Add section on how to mount remote samba shares to increase disk space

·         Reconfigure postfix to use submission port for relaying sasl authenticated emails

·         Reconfigure postfix to disallow sasl auth on smtp port

·         DenyHosts/fail2ban install (maybe replaced by iptables throttling)

·         Explain that outgoing mail is currently being spam checked for outgoing SASL clients

·         Postfix Content Filter for charset

·         Rewrite Reply-To Header for simple mailing lists

4. Scribbles for the author

/usr/lib/ecartis instead of /home/ecartis/ecartis

http://www.hzqbbc.com/blog/arch/2004/05/postfix_ecartis.html

http://baldric.net/mailman-with-postfix/

5. Backing up my VPS

5.1 rsnapshot

My VPS was humming along smoothly for a few months, and then I became aware that I have no backup plan if the container gets corrupted or the hosting company goes belly up. Holy cow, I’d have to do all of this work all again to setup the system AND rebuild all my sites/databases/email?!? I’m too much of an engineer to let that happen! Hmm … what do I need? I need a way to backup the content, config files, and databases. I’m also too inconsistent to reliably do it manually on any reasonable frequency, so I’d need it automated. Please welcome, rsnapshot!

 

rsnapshot’s website says, “snapshot is a filesystem snapshot utility for making backups of local and remote systems. Using rsync and hard links, it is possible to keep multiple, full backups instantly available. The disk space required is just a little more than the space of one full backup, plus incrementals. Depending on your configuration, it is quite possible to set up in just a few minutes. Files can be restored by the users who own them, without the root user getting involved. There are no tapes to change, so once it's set up, your backups can happen automatically untouched by human hands. And because rsnapshot only keeps a fixed (but configurable) number of snapshots, the amount of disk space used will not continuously grow. rsnapshot is written entirely in Perl. It should work on any reasonably modern UNIX compatible OS, including: Debian GNU/Linux, Red Hat Linux, Fedora Linux, SuSE Linux, Gentoo Linux, Slackware Linux, FreeBSD, OpenBSD, NetBSD, Solaris, Mac OS X, and even IRIX.”

 

To better explain this section, let me set the stage. I have multiple VPS geographically separated. I have a mailserver with RamHost.us in Kansas City, a webserver with Quickweb.co.nz in Phoenix, and a backupserver with Web-Wide-Hosting.co.nz somewhere on the west coast USA. With rsnapshot installed on backupserver, and rsync installed on mailserver and webserver, backupserver can make automated incremental backups of backupserver and mailserver. Even if you don’t have a dedicated backup server VPS, if you have a Linux system (or a windows system with cwRsync, http://www.stillnetstudios.com/2006/12/09/snapshot-backups-howto/) you can install rsnapshot and backup your VPS to that box. For example, you can even use rsnapshot or cwRsync to backup your VPS to your home PC.

 

First, make sure you have rsync on all the various VPS that you want backed up. For me, this is

 

apt-get install rsync

 

on mailserver and webserver.

 

Then setup password-less logins with dropbear between the VPS you want backed up, and whatever system the data will be backed up to. To do this, on the system where the data will be backed up to, create some RSA key pairs by issuing the ssh-keygen command as shown in this example extracted from http://www.debian-administration.org/articles/152. Do not specify a password.

 

skx@lappy:~$ ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/home/skx/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /home/skx/.ssh/id_rsa.

Your public key has been saved in /home/skx/.ssh/id_rsa.pub.

 

Now, you need to copy that new public key over to the VPS where the data is that you want backed up by issuing the following command.

 

ssh-copy-id -i ~/.ssh/id_rsa.pub root@vpswheredataistobebackedup

 

If you’re running dropbear on a non-standard port as described earlier this document, then you may need to do this instead, where 9210 is your dropbear port. Note those are single quotes, not back ticks.

 

ssh-copy-id -i ~/.ssh/id_rsa.pub '-p 9210 root@vpswheredataistobebackedup'

 

Also note that you don't need to use remote root logins unless the files you wish to backup are unreadable to ordinary users upon the machine you're backing up. Although it's fair to say if you're backing up /etc you'll almost certainly wish to do so as root; as otherwise important files such as /etc/shadow will not be readable to normal users.

 

Issuing the ssh-copy-id command will prompt you for the login password for the VPS where your data is that needs to be backed up, then copy the keyfile for you, creating the correct directory and fixing the permissions as necessary. Once this has been done you should be able to login remotely, and run commands, without being prompted for a password. Try it to make sure.

 

Now that the VPS that have data to be backed up are all prepared, lets prepare the system where the data is to be backed upto. As with any other Debian standard install, apt-get the package:

 

apt-get install rsnapshot

 

Simple enough! Ok, lets configure it. You’ll want to change as many paramaters as you like, but the minimum ones I changed in my setup are as follows.

 

First, I made sure all the paths to local system binaries are set properly under the section header, EXTERNAL PROGRAM DEPENDENCIES. If the standard utilities don’t work, then how can the entire setup work?

 

Second, I set the directory on the localhost where I want all the backups to reside by assigning a directory to the snapshot_root parameter. In my setup, I chose /home/backup/incremental :

 

snapshot_root /home/backup/incremental/

 

As described at the top of the default config file, rsnapshot requires tabs between elements, not just spaces. Also directories require a trailing slash : right: /home/ ; wrong: /home .

 

I wanted the most amounts of backups available, so I went ahead and enabled all available backup frequencies under the section header, BACKUP INTERVALS.

 

I like logging in case something goes screwy, so I set the log paramaters as follows. You can choose whatever you like.

 

verbose 4

loglevel 3

logfile /var/log/rsnapshot.log

 

Since I run dropbear on a non-standard port, I need to tell rsnapshot to try a different ssh port:

 

ssh_args -p 9210

 

Here comes the fun part. Now you need to tell rsnapshot what directories on mailserver and webserver to backup to /home/backup/incremental. I’ll post my actual entries and then explain how it works :

 

backup root@webserver:/etc/ webserver/

backup root@webserver:/var/log/ webserver/

backup root@webserver:/var/www/ webserver/

 

backup root@mailserver:/etc/ mailserver/

backup root@mailserver:/home/user1/Maildir/ mailserver/

backup root@mailserver:/var/spool/postfix/etc/ mailserver/

backup root@mailserver:/var/log/ mailserver/

 

backup_script /root/mysqlbackup.sh run unused0/

backup root@webserver:/tmp/mysqldump/ webserver/

backup_script /root/mysqlbackup.sh clean unused1/

 

In the first 3 lines, I tell rsnapshot to connect to webserver over ssh (port 9210 as described earlier) as the user root, and using rsync, compare the contents of /etc/ and /var/log/ and /var/www/ on webserver to the contents of the latest copies of /etc/ and /var/log/ and /var/www/ on the system where the backup is to reside. If there are any differences, copy them over to the system where the backup is to reside.

 

Same story for mailserver. It checks /etc/ and /home/user1/Maildir/ and /var/spool/postfix/etc/ and /var/log/ over on mailserver and compares it to the contents on the system where the backup is to reside. Any changes get copied over by rsnapshot.

 

I chose /etc/ because that is obviously where all the critical configuration files for the system are housed. I like to backup the logs in /var/log/ because if anything goes wrong, or the system is comprised and the logs altered by the hacker, or any other strange event you can think of, I have the logs to look at to figure out what happened. /var/spool/postfix/etc/ is the chrooted environment for postfix setup earlier this document, so I snag any miscellaneous configuration files or SASL specific databases from that directory. Finally, I backup all the websites being served up by nginx in /var/www. Very straight forward.

 

The last 3 lines are a bit trickier. I needed a way to backup the mysql database, while it’s running, without corrupting anything. That’s where mysqldump or mysqlhotcopy comes in. I took the example from Fredrik Poller here, http://poller.se/2010/12/rsnapshot-and-mysqldump/, and it’s shown to work nicely with a simple modification. Frederik’s example works, as is, when dropbear is running on port 22. I could not get his setup to work nicely when running dropbear on nonstandard ports. So instead of running Frederik’s script directly on the webserver as follows

 

backup_script /usr/bin/ssh root@webserver "/root/backup.sh run" unused0/

 

I had to run a local script to manually call ssh with the correct arguments.

 

backup_script /root/mysqlbackup.sh run unused0/

 

The contents of /root/mysqlbackup.sh on the system where the backup is to reside is as follows, where /root/mysqlbackup.sh on webserver is identical to Frederik’s example. Make sure to chmod 700 the file so that only root can access it.

 

#!/bin/bash

case $1 in

run)

/usr/bin/ssh -p 9210 webserver "/root/mysqlbackup.sh run"

;;

clean)

/usr/bin/ssh -p 9210 webserver "/root/mysqlbackup.sh clean"

;;

esac

 

The first of the last 3 lines in the rsnapshot.conf calls my local script to call Frederik’s script to get mysqldump to dump the mysql databases to /tmp/mysqldump on webserver, then the second of the last 3 lines in rsnapshot.conf makes rsnapshot copies over any incremental changes to the system where the backup is to reside, then the last line calls Frederik’s script again to clean up any files written to /tmp/mysqldump over on webserver so intruders or unwanted users can’t access them.

 

That’s it! Now rsnapshot is all configured. Make sure that rsnapshot is good to go by running :

 

rsnapshot configtest

 

If you get back “Syntax OK”, then you’re ready to do your first backup! If not, go back and check the tabbing. Remember that the config file is tab dependant.

 

When ready, issue this command :

 

rsnapshot hourly

 

If all goes well you'll receive your backup files beneath "backup_root"/hourly.0/, and any errors will be reported in the file /var/log/rsnapshot.log.

 

After a few days you'll notice that you have several new files such as:

 

sh-4.1# ls -lha

total 64K

drwxrwxr-x 16 root root 4.0K May 13 08:00 .

drwxrwxrwx 9 root root 4.0K Apr 28 11:47 ..

drwxr-xr-x 7 root root 4.0K May 12 04:03 daily.0

drwxr-xr-x 7 root root 4.0K May 11 04:03 daily.1

drwxr-xr-x 7 root root 4.0K May 10 04:03 daily.2

drwxr-xr-x 7 root root 4.0K May 9 04:03 daily.3

drwxr-xr-x 7 root root 4.0K May 8 04:03 daily.4

drwxr-xr-x 7 root root 4.0K May 7 04:04 daily.5

drwxr-xr-x 7 root root 4.0K May 6 04:03 daily.6

drwxr-xr-x 7 root root 4.0K May 13 08:03 hourly.0

drwxr-xr-x 7 root root 4.0K May 13 04:03 hourly.1

drwxr-xr-x 7 root root 4.0K May 13 00:03 hourly.2

drwxr-xr-x 7 root root 4.0K May 12 20:03 hourly.3

drwxr-xr-x 7 root root 4.0K May 12 16:03 hourly.4

drwxr-xr-x 7 root root 4.0K May 12 12:03 hourly.5

drwxr-xr-x 5 root root 4.0K May 1 04:16 weekly.0

 

These are the rotated backups which we've saved, the initial backups will be the largest - the later ones will only contain changes made since the previous run. To see this you can view the amount of disk space taken up by each backup with "rsnapshot du":

 

1.3G /home/backup/incremental/hourly.0/

11M /home/backup/incremental/hourly.1/

8.4M /home/backup/incremental/hourly.2/

11M /home/backup/incremental/hourly.3/

11M /home/backup/incremental/hourly.4/

11M /home/backup/incremental/hourly.5/

9.9M /home/backup/incremental/daily.0/

11M /home/backup/incremental/daily.1/

23M /home/backup/incremental/daily.2/

8.0M /home/backup/incremental/daily.3/

8.4M /home/backup/incremental/daily.4/

12M /home/backup/incremental/daily.5/

9.5M /home/backup/incremental/daily.6/

20M /home/backup/incremental/weekly.0/

1.4G total

 

If all of that worked, then you want to automate it so that you never have to worry about it again. Once again, cron is your friend! Go to the command line, and as root, type the command ‘crontab –e’. This opens the crontab entries list for the root user. Explanation of cron entries is further up in Section 2.7. Add these entries at the end of the file. Remember, you can run these at whatever time you like.

 

0 */4 * * * root /usr/bin/rsnapshot hourly

30 3 * * * root /usr/bin/rsnapshot daily

0 3 * * 1 root /usr/bin/rsnapshot weekly

30 2 1 * * root /usr/bin/rsnapshot monthly

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts, that will check nightly for rootkits and email the findings to root, with a fully functioning firewall, running dropbear on a non-standard port, and it’s fully backed up with no user intervention with rsnapshot.

5.2 Backup MX

I was wondering what would happen to incoming mail if mailserver went down for any appreciable amount of time. According to RFC2821, mail servers are supposed to try the lowest-numbered MX records first and fall back to higher-numbered MX in the event lower-numbered MX are unavailable. So we can setup a Postfix backup server, with a higher-numbered MX, to keep the messages in a queue waiting for mailserver to become available and then deliver to mailserver. This ensures that I do not lose any emails during the downtime and it’s automatically delivered upon restoration of connectivity.

 

However, spammers are known for connecting to backup MX to avoid anti-spam filters that may be running on the primary MX server. This also hides their real IP from my primary MX. This is well known issue. So as well as setting up the backup server to queue mail until mailserver comes back online, system designers urge us to keep the same or better spam filters measures on the backup as the primary. I’ll keep most of it, but skip installing Spamassassin to conserve RAM. I’ve found that rDNS checks, charset checks, and spamhaus.org RBL check kills off the vast majority of the spam, so no reason to run a 45MB Spamassassin for the stragglers that make I through.

 

Setting up Postfix as a backup MX is extremely simple. All you have to do is tell Postfix which domains to allow relaying for, and then tell Postfix specifically what addresses to allow relaying for. All other domains and addresses will be rejected. Here is the contents of my /etc/postfix/main.cf on my backup mx commented. It is very straightforward.

 

# Identify which domains to relay for

relay_domains = rajeshprakash.com

 

# Identify which addresses specifically to relay for

relay_recipient_maps = hash:/etc/postfix/relay_recipients

 

# Check the charset of the incoming message. If it is in any

# foreign charsets, reject it. I only understand English.

header_checks = pcre:/etc/postfix/header_checks

 

# Check various known spam pit falls and check the SpamHaus.org

# RBL for the incoming client.

 

smtpd_recipient_restrictions = permit_mynetworks,

reject_non_fqdn_hostname,

reject_non_fqdn_sender,

reject_non_fqdn_recipient,

reject_unauth_destination,

reject_unauth_pipelining,

reject_invalid_hostname,

reject_rbl_client zen.spamhaus.org

smtpd_helo_required = yes

disable_vrfy_command = yes

 

smtpd_data_restrictions =

reject_unauth_pipelining,

permit

 

# Check that the domain->address lookup and the address->domain

# lookup both return the same address. rDNS check.

 

smtpd_client_restrictions = reject_unknown_reverse_client_hostname

 

Create the file /etc/postfix/relay_recipients with the following example contents. Remember to postmap hash:/etc/postfix/relay_recipients after editing. This file tells postfix specifically which address to queue and deliver.

 

user1torelay@relaydomain.tld OK

user2torelay@relaydomain2.tld OK

user3torelay@relaydomain3.tld OK

 

Create the file /etc/postfix/header_checks with the following contents. No need to postmap pcre files. This is the file that will reject some common foreign charsets used by spammers.

 

#### Header checks file

#### Checks are done in order, top to bottom.

#### /etc/postfix/header_checks

 

#### non-RFC Compliance

/[^[:print:]]{7}/ REJECT RFC2047

/^.*=20[a-z]*=20[a-z]*=20[a-z]*=20[a-z]*/ REJECT RFC822

/(.*)?\{6,\}/ REJECT RFC822

/(.*)[X|x]\{3,\}/ REJECT RFC822

 

#### Unreadable NON-acsii un-printable text

/^Subject:.*=\?(GB2312|big5|euc-kr|ks_c_5601-1987|koi8)\?/ REJECT Unreadable

/^Content-Type:.*charset="?(GB2312|big5|euc-kr|ks_c_5601-1987|koi8|iso-2022-jp)/ REJECT Unreadable

 

#### Character Set Checks

/^(Content-Type:.*|\s+)charset\s*=\s*"?(Windows-1251)\?/ REJECT Bad Content Type

 

After all of that, restart postfix and you’re done!

 

/etc/init.d/postfix restart

 

Voila! You now have a stripped down, current, stable, bare minimum SSH security, Debian installation, with a functioning PHP5 enabled low memory footprint web server, with a SASL authenticating Postfix SMTP server, and a plaintext authenticating IMAP server, complete with spam mail identification, a spam mail sieve, and a functioning stripped down Mysql dB engine, with the proper rDNS set to allow sending mail to big mail hosts, that will check nightly for rootkits and email the findings to root, with a fully functioning firewall, running dropbear on a non-standard port, and it’s fully backed up with no user intervention with rsnapshot, and a backup MX in the event your primary mailserver goes down.

6. Example Config Files

Coming soon.