The Perfect SpamSnake - Ubuntu 8.04 LTS - Page 03
2 DNS Server
apt-get install bind9
For security reasons we want to run BIND chrooted so we have to do the following steps:
Edit the file /etc/default/bind9 so that the daemon will run as the unprivileged user bind, chrooted to /var/lib/named. Modify the line: OPTIONS="-u bind" so that it reads OPTIONS="-u bind -t /var/lib/named":
OPTIONS="-u bind -t /var/lib/named"
Create the necessary directories under /var/lib:
mkdir -p /var/lib/named/etc
Then move the config directory from /etc to /var/lib/named/etc:
mv /etc/bind /var/lib/named/etc
Create a symlink to the new config directory from the old location (to avoid problems when bind gets updated in the future):
ln -s /var/lib/named/etc/bind /etc/bind
Make null and random devices, and fix permissions of the directories:
mknod /var/lib/named/dev/null c 1 3
We need to modify /etc/default/syslogd so that we can still get important messages logged to the system logs. Modify the line: SYSLOGD="" so that it reads SYSLOGD="-a /var/lib/named/dev/log":
Restart the logging daemon:
Start up BIND, and check /var/log/syslog for errors:
In order to install MySQL, we run
apt-get install mysql-server mysql-client libmysqlclient15-dev
You will be asked to provide a password for the MySQL root user - this password is valid for the user root@localhost as well as email@example.com, so we don't have to specify a MySQL root password manually later on (as was the case with previous Ubuntu versions):
New password for the MySQL "root" user: <-- yourrootsqlpassword
We want MySQL to listen on all interfaces, not just localhost, therefore we edit /etc/mysql/my.cnf and comment out the line bind-address = 127.0.0.1:
Then we restart MySQL:
Now check that networking is enabled. Run
netstat -tap | grep mysql
The output should look like this:
tcp 0 0 *:mysql *.* LISTEN 5286/mysqld
4 Apache with PHP5 and Ruby
Now we install Apache:
apt-get install apache2 apache2-doc apache2-mpm-prefork apache2-utils libexpat1 ssl-cert
Next we install PHP5 and Ruby (both as Apache modules):
apt-get install libapache2-mod-php5 libapache2-mod-ruby php5 php5-common php5-curl php5-dev php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-mysql php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-sqlite php5-tidy php5-xmlrpc php5-xsl
You will be asked the following question:
Continue installing libc-client without Maildir support? <-- Yes
Next we edit /etc/apache2/mods-available/dir.conf and change the following:
DirectoryIndex index.html index.htm index.shtml index.cgi index.php index.php3 index.pl index.xhtml
Now we have to enable some Apache modules (SSL, rewrite, suexec, and include):
Reload the Apache configuration:
4.1 Fix for Imagick
Because of a bug that causes the following error, the below must be done as a workaround:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20060613/imagick.so' - libWand.so.9: cannot open shared object file: No such file or directory in Unknown on line 0
apt-get remove php5-imagick
apt-get install libmagick9-dev
pecl install imagick
Edit /etc/php5/apache2/php.ini and add the following:
5 Synchronize the System Clock
It is a good idea to synchronize the system clock with an NTP (network time protocol) server over the internet. Simply run
apt-get install ntp ntpdate
and your system time will always be in sync.
6 Setting up Postfix
apt-get install postfix postfix-pcre postfix-mysql postfix-ldap cabextract lha unrar razor pyzor spamassassin
You will be asked two questions. Answer as follows:
General type of mail configuration: <-- Internet Site
6.1 Edit master.cf
BTW watch for the two Postfix configuration files, both located in the /etc/postfix folder. More than one admin has gotten confused between master.cf and main.cf!
First back up the current master.cf:
cp /etc/postfix/master.cf /etc/postfix/master.cf-orig
We need to add two items below the pickup service type. The pickup service "picks up" local mail (local meaning "on this machine") and delivers it. This is a way to bypass content filtering for mail generated by this machine.
Add this just below the 'pickup' service type:
-o content_filter= -o receive_override_options=no_header_body_checks
It should look like this when you are done:
pickup fifo n - - 60 1 pickup -o content_filter= -o receive_override_options=no_header_body_checks
6.2 Edit main.cf
First we need to backup the main.cf file.
cp /etc/postfix/main.cf /etc/postfix/main.cf-orig
We simply need to make a correction to the default setting here:
postconf -e "alias_maps = hash:/etc/aliases"
Create the aliases file:
Since our system will be configured not to store any local mails, this will be ignored.
The domain name that mail created on this machine appears to come from. For example, if cron sends mail to "firstname.lastname@example.org" it will appear to come from "email@example.com".
postconf -e "myorigin = example.com"
Obviously, in the above, and all the following commands, replace my example parameters, like "example.com", with your own specific values.
The fully-qualified domain name (FQDN) of the machine running the Postfix system.
postconf -e "myhostname = server1.example.com"
These are the machines I trust, and will relay mail for, to any destination. If you will be dealing with multiple internal mail servers, and/or want to allow several machines and/or subnets to relay through this server (careful!), just add them to this parameter in CIDR format and seperate the networks like this:
postconf -e "mynetworks = 127.0.0.0/8, 192.168.0.0/24"
The 127.0.0.0/8 is there to allow the local server to send, you need to at least put this one in.
18.104.22.168 outbound trusted relay IP
If you'd like your SpamSnake to handle outgoing emails as well, be sure to add your local network to the list e.g. 192.168.0.0/24 172.16.0.0/16. If your mailserver is 172.16.5.20 and you only want to trust only that IP, add 172.16.5.20/32. You just have to setup your mailserver to relay (smarthost) to your SpamSnake.
Maximum size email that Postfix will let in the "front door".
postconf -e "message_size_limit = 10485760"
The above allows email up to 10MB, the value is in bytes (10*1024*1024). Mail larger than this may possibly get bypassed by the anti-virus scanner (ClamAV). You could increase this if you also configure ClamAV to scan files larger than 10MB. If you allow messages larger than 10MB, keep an eye on RAM.
Return an error message for local delivery attempts.
postconf -e "local_transport = error:No local mail delivery"
An empty mydestination tells Postfix this machine is not the final destination.
postconf -e "mydestination = "
An empty local_recipient_maps tells Postfix there are no local mailboxes.
postconf -e "local_recipient_maps = "
Our spamfilter must be able to receive mail for postmaster@yourIP. Reportedly, some things actually expect this ability to exist. We will also allow mail to abuse@yourIP. Since we do not allow local mail delivery, mail addressed to our spamfilter's IP address will get rejected with an error message. Setting up virtual_alias_maps allows email to these two accounts to be forwarded to an inside address. Make sure your Exchange server is set up to receive messages addressed to "root", "postmaster" and "abuse".
Set up a reference to the virtual file:
postconf -e "virtual_alias_maps = hash:/etc/postfix/virtual"
Then edit the virtual file:
Add these lines to the top of the virtual file:
postmaster firstname.lastname@example.org abuse email@example.com root firstname.lastname@example.org
Save and exit the file, then create the binary file that Postfix will use:
We are going to build a table of every single user in every single domain that we accept mail for.
Set up a reference to a file we will create to store the data:
postconf -e "relay_recipient_maps = hash:/etc/postfix/relay_recipients"
Then edit relay_recipients:
For the moment, we are going to accept mail for all users in our domain(s) so enter each domain you accept mail for in the following format:
@example.com OK @example2.com OK
Then create the binary file that Postfix will use:
The entries above are temporary. They are wildcards that allow mail to your domains. You MUST remove the entries above at some point in the near future and replace them with every single one of your valid recipients' email addresses. When you are ready to enter each user individually in the relay_recipients file, you would first remove (or comment out) the data above that allows mail to all users in the domain, and then list each user individually in the form:
email@example.com OK firstname.lastname@example.org OK
Tells Postfix where to look for a transport file. We use the transport file to tell Postfix where to forward valid mail for our domain(s). Setting up transport is similar to setting up relay_recipients.
Create a reference to it in main.cf:
postconf -e "transport_maps = hash:/etc/postfix/transport"
Then edit transport:
Add 1 new line for each domain for which you will be handling mail, similar to the example below. The IP address is that of whatever server is the final destination of messages addressed to our domain(s) (our Exchange server). It does not matter where you place these items in the file, but I like to put them at the top.
example.com smtp:[192.168.0.x] example2.com smtp:[192.168.0.x]
Include the brackets on these lines!. You can also use FQDN hostname instead of an IP address (i.e. smtp:[exchange1.example.com]).
Now to create the binary file Postfix will use:
What destination domains (and subdomains thereof) this system will relay mail for.
postconf -e "relay_domains = hash:/etc/postfix/relay_domains"
Add 1 new line for each domain for which you will be handling mail, similar to the example below:
example.com OK example2.com OK
This file currently has a very similar format to relay_recipients do not mistake the two. This file cannot have '@' in front of the domain name. Just thought I'd mention it, some very smart people have been known to have done this...
Then create the binary file Postfix will use: