from here

Installing Postfix

Package installation

First thing we are going to do is to install Postfix as our MTA (Mail Transfer Agent), providing an email relay to transport email from the internet to your existing email server, and while doing so, allowing all the other little pieces we install later on to put their grubby fingers on those emails to make sure there are no nasty cooties or cans o’ spam in them. I will not spend a lot of time writing how to configure your firewall, how MX records work and the such. If you dare to follow this HOWTO (are you mad???) you will have a pretty good understanding of that stuff (I hope!!!) and have everything already setup so that your MX record points to your public IP and your routing makes sure that port 25 traffic reaches the shiny new SpamCrunch box. So, let’s get #! Postfix’d:

sudo apt-get install postfix

Isn’t it wonderful to have access to those great ubuntu repositories while running a lean mean, shiny, black #! CrunchBang machine?

As I have to admit to being a total Postfix n00b, I took a lot of pointers for configuration files from this HOWTO which was very helpful, even though it was written for a FC4 installation, so much of the CLI commands, file locations and such are completely useless to us, the general configuration still applies, and you probably know your system well enough to figure it out. I try to give as much #! CrunchBang specific info as I can.

The beauty of installing Postfix that way is that it automagically sets up all the users and groups and such for us, so we will not have to do any of that. It also starts Postfix at boot time. It will also present you with a setup routine, which we will not use for our purpose, but rather finish without any automatic configuration.

Postfix configuration

Let’s start by configuring Postfix’s services. This is done in the /etc/postfix/ file. This is a rather funny looking config file as it is setup like a table. There is not much we have to change in this file, aside from adding the following too lines right under the line that begins with pickup:

  -o content_filter=<br />  -o receive_override_options=no_header_body_checks<br />

Make sure you indent them with a single tab – I think it is supposed to be that way, or at least it works that way ;-) All that does is tell Postfix that local messages are not subject to Postfix’s internal filtering. There is more to configure in here down the road, but for now we just want to make sure that we have basic relay functionality and test that – once that is working we can move on.

The is a pretty powerful configuration file. There is so much that you can be done and controlled by it, and it can become quite complex. The best place to get information about the parameters and syntax is the Postfix website that has detailed information. For now I am just providing you with the information to create a VERY simple Postfix configuration. Add as many RBL services or other parameters as you want, but you might want to keep it somewhat simple at least until all is up and running and go from there. At this point there will be no in your /etc/postfix/ directory – remember, we told the config program to not configure anything, so we have to make one:

sudo joe /etc/postfix/

This will open your new favorite editor (joe!) with a new, emtpy file. To begin with, I used the following (Let’s use Contoso’s evil twin, Monstroso as an example here – you will need to replace all domain names and such with the correct values for your purpose!):


myhostname =<br />mydomain =<br />myorigin =<br />mydestination =<br />local_recipient_maps =<br />mynetworks =<br /><span class="search_hit">relay</span>_domains =<br />message_size_limit = 10485760<br />transport_maps = hash:/etc/postfix/transport<br />smtpd_helo_required = yes<br />disable_vrfy_command = yes<br />virtual_alias_maps = hash:/etc/postfix/virtual<br />alias_maps = hash:/etc/aliases<br />smtpd_client_restrictions = check_client_access hash:/etc/postfix/client_access, reject_rbl_client, reject_rbl_client<br />smtpd_helo_restrictions = check_helo_access hash:/etc/postfix/helo_access, reject_invalid_hostname<br />smtpd_sender_restrictions = check_sender_access hash:/etc/postfix/sender_access, reject_unknown_sender_domain<br />smtpd_recipient_restrictions = reject_unknown_recipient_domain, permit_mynetworks, reject_unauth_destination, check_recipient_access hash:/etc/postfix/recipient_access<br />smtpd_data_restrictions =  reject_unauth_pipelining<br />

Let me give you some of the highlights about the less self-explanatory items, just so no one can accuse me of witchcraft…

mydestination =

This is blank as we are not in the mail-delivery, but mail-relay business. Guess it is better that way, otherwise we would have to increase our prices every other month or so 😛 Basically we are telling Postfix to not deliver any mail to local mailboxes.

mynetworks =

It’s pretty important that we put something here. Normally this would be used if the server also sends outgoing email and would limit the destination networks. Were we to leave it empty, our server would be a most excellent open relay for everyone to send heaps of cans of spam through it. So because we are “only” using Postfix as a relay, we’ll add our own IP (or something else thats harmless and in our network) here. That way no one can relay anything through our server.

The lines with the restrictions are pretty self explanatory and more information is available at – yea, you guessed it right – the Postfix web site. Something that you might have seen is that there are a bunch of hash files referenced. Needless to say, we do not have these files yet, so we will have to create them. Fortunately Postfix comes with the nifty little command postmap that allows us to compile text files into Postfix-readable .db hash files, and as you can see by the references, we have to create a bunch of them.

Once we have our saved and get back to the command line, type (for much of this I just assume that you are in /etc/postfix/)

sudo joe /etc/postfix/transport

to create a new text file with the name transport. For our purpose all we need to add is one line:      smtp:[]

which tells our server to relay messages for via smtp to the IP of our mail server that hosts the actual mailboxes. You can add as many lines as you wish for more domains/servers. Do I have to tell you every time that you have to replace the weird stuff with your values? Nah, I think by now you know…you do, right? When you have that file saved, exit joe and enter

sudo postmap transport

and the command will create a Postfix-digestable file named transport.db. You don’t believe me? Well go check! It’s there! I’m telling ya, it’s almost magic!

Now we need the virtual file. This contains the mappings of certain required email addresses which might not really exist as mailboxes on our mail server. For some of them it might make sense to create them, others might be better off delivered somewhere else – your call. So, same procedure as last year, Mrs. Sophie, create a new file /etc/postfix/virtual with the following content (yes, you DO have to change the content to make it work for you – if you want me to do THAT part for you as well, you have to pay me big bucks!)

root<br />postmaster<br />abuse<br />virus<br />spam<br />

…and once again, save, exit, make hash file:

sudo postmap virtual

Are you really checking again if the file is really there??? Don’t believe me, huh? I am the same way though, and more than once found that I had a tybo typo and screwed something up, so I won’t blame you…not yet at least…NEXT!

Let’s create the /etc/postfix/client_access. This file basically allows you to whitelist or blacklist servers. Right now the file is most likely empty, unless you have WL/BL from another system. The syntax is simple: OK<br /> REJECT

You get the idea – there are more parameters you can use in here, might want to check that Postfix website for them! Don’t forget to make a hash out of that:

sudo postmap client_access

will do that for you once again!

There are some more, so here it goes in short:

/etc/postfix/helo_access           REJECT<br />         REJECT<br />localhost               REJECT

Means we reject SMTP helo’s from our own domain, because that would allow someone to pretend they are us (no idea why someone would want that, but spammers are funny people!). We also reject helo’s from our own public IP as well as from localhost. Dont forget to…

sudo postmap helo_access

to make the hash file!


Mine is actually empty at this point, but you would be able to ok a sender’s email address even if it is in one of the blacklists you are using ( OK) or reject it when it is not with REJECT. Because we specify it in the configuration, just go ahead and create the file for now and save it empty. The postmap command

sudo postmap sender_access

will create a hash file even from an empty text file.


This one only contains one single line for my purpose, but could potentially contain multiple domains. It specifies the domains for which emails are sent on for further processing by ClamAV, SpamAssassin and so on.      OK

Dont forget to save and compile to a hash with

sudo postmap recipient_access

Hmmmmm…I have that funny feeling that this is pretty much it!!! Can it really be??? Postfix configuration for now done and we can fire up Postfix??? (Go and grab your hardhats, just in case it blows…)

Starting and Testing Postfix

Launching Postfix

I know you can’t wait to find out if you finally managed to break that system…so, go ahead…do it…don’t say you have not been warned!

postfix start

DUCK and COVER!!!!!

Huh? Back at the command prompt? ORLY??? No Errors????? How you do that???? Must have had an awesome HOWTO to follow!!! *g*

Testing the Relay

Let’s see if we can get some mail relayed to the email server, and hopefully it will end up in your mailbox (that by now already sports an entry for your new email address, right?). I am not sure how familiar you are with SMTP commands, but this just a nice way to ensure the very basics are functioning correctly and we will be able to see any error messages right away instead of waiting for a mail to be bounced back. So let’s connect to the new server!

telnet 25

Naturally you replace the server‘s name with it’s IP or however else it might be able to be reached in your network, or if you choose to, outside of it. The 25 is just the port for telnet to use, which is the standard SMTP port, but you know that already. If all goes well we can celebrate the first success if the server responds with

220 ESMTP Postfix

This would mean that our server is alive, and at least willing to listen to whatever you might have to say – if it will actually allow you to send mail, or even like your name to begin with, is a completely different story. So, let’s see how far we get…

helo (use your IP)

Basically just saying hello to the server, telling it who you are – and no, it’s not a typo, THIS helo has only one “l” ;-) If all goes well, and your server has manners, it will respond with


Tell the server who the email is from:

mail from: (use some external email address you probably have 10!)

And it will let you know if it likes that address…

250 Ok

Where you want to send the email to:

rcpt to:

And again the server should tell you if it likes your command by replying with

250 Ok

Now that we have this out of the way, let’s create the actual email. Typing


will make the server respond with

354 End data with .

to let us know we can now create our email and when we are done to end with then a period followed by once more.

So we create an email as follows:

subject: This is a mail <span class="search_hit">relay</span> test <-- or whatever else you want the subject to be<br />TESTING...123 TESTING... <-- this is your body text<br />    <--Simply press <ENTER><br />.   <--Type a period<br />    <--and another <ENTER> to let the <span class="search_hit">server</span> know we are done!

The server should reply with

250 Ok: queued as {a random number will appear here…}

Now we quit our SMTP session with the server by typing…can you guess it…


…and we receive a friendly

221 Bye

from our well mannered server. At this point, if all goes well, you should have a new email in your mailbox! If not…well, you are on your own concerning the information I can give within this HOWTO – but there are TONS of resources on the interwebz, and I know how good you are googling all kinds of things ;-) Should you have problems at this point, fix them – no need to continue if the basic functionality does not work. And, you might want to remember the SMTP commands above – comes in really handy when you need to send an email and have nothing but some terminal that knows telnet and a connection to the net available ;-)

If everything works, congratulations! No, not to you! To me!!! After all this HOWTO seems to be written unbelievably well and super-easy to follow as even you were able to do so! Ok, ok, I will take it back a notch. Grab another coffee and kick back for a moment before we move on to amavisd-new.

Installing amavisd-new


Amavisd-new is kind of the glue that puts all the pieces together – it grabs mail from postfix, sends it to the assassin to “kill” off any spam, then over to the clam(av) to make sure there are no cooties in the emails, a couple more steps to make sure all the viagra and other beautiful offers do not even reach your mailbox (unless you want to get them, that is!) and then hands them back to postfix for relay to your server in our case.

As so often in this HOWTO, this is another time when I am just happy to use the ubuntu repo’s in #! – packages are setup and preconfigured very well, so after installing amavisd-new, there is not terribly much left for us to do. Let’s get it onto our system by running:

sudo apt-get install amavisd-new


You’ll find the configuration files at /etc/amavis/conf.d In the current version of amavisd-new the config files are split up into sections. the file /etc/amavis/conf.d/50-user can be used to add user specific configuration and overrides the other files. For our purpose we make the following adjustments (ok, you do – I already done it…):

To activate spam and virus checking within amavisd-new, we need to edit /etc/amavis/conf.d/15-content_filter_mode and make sure the two lines in there are not commented out:

use strict;<br /><br /># You can modify this file to re-enable SPAM checking through spamassassin<br /># and to re-enable antivirus checking.<br /><br />#<br /># Default antivirus checking mode<br /># Uncomment the two lines below to enable it back<br />#<br /><br />@bypass_virus_checks_maps = (<br />   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);<br /><br /><br />#<br /># Default SPAM checking mode<br /># Uncomment the two lines below to enable it back<br />#<br /><br />@bypass_spam_checks_maps = (<br />   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);<br /><br />1;  # ensure a defined return<br /><br />

Now we move on to /etc/amavis/conf.d/20-debian_defaults and make sure to tell amavisd_new what to do with emails that are spam or have the nasties on them (these are my settings, you may want to adjust!):

$final_virus_destiny      = D_DISCARD;  # (data not lost, see virus quarantine)<br />$final_banned_destiny     = D_DISCARD;   # D_REJECT when front-end MTA<br />$final_spam_destiny       = D_DISCARD;<br />$final_bad_header_destiny = D_PASS;     # False-positive prone (for spam)<br /><br />$virus_admin = "postmaster\@$mydomain"; # due to D_DISCARD default<br />

Postfix, meet amavisd-new!

Once we went and poured over all the configuration files and tweaked what we wanted, it is time to make sure that we introduce the cutie amavisd-new to our gentleman Postfix. To do that, we need to make some more changes to /etc/postfix/ Go to the bottom of the file and append the following lines:

smtp-amavis  unix    -    -    y    -    4    smtp<br /> -o smtp_data_done_timeout=1200<br /> -o smtp_send_xforward_command=yes<br /> -o disable_dns_lookups=yes<br />

Most importantly this will tell Postfix to send all email via smtp towards amavisd-new, so “she” can do her thing (or better thingS) to every single email that comes in…you know, Lysol and such… The number “4” in the first line specifies how many little server-processes will be started to process mail. Four seems to be a pretty good balance between performance and speed for most applications, unless you are in a 10,000 mailbox environment – then you might want to revisit that.

Right after that we add: inet    n    -    y    -    -    smtpd<br /> -o content_filter=<br /> -o local_recipient_maps=<br /> -o <span class="search_hit">relay</span>_recipient_maps=<br /> -o smtpd_restriction_classes=<br /> -o smtpd_helo_restrictions=<br /> -o smtpd_sender_restrictions=<br /> -o smtpd_recipient_restrictions=permit_mynetworks,reject<br /> -o mynetworks=<br /> -o strict_rfc821_envelopes=yes<br /> -o smtpd_error_sleep_time=0<br /> -o smtpd_soft_error_limit=1001<br /> -o smtpd_hard_error_limit=1000<br /> -o receive_override_options=no_header_body_checks<br />

This introduces amavisd-new as an external program to Postfix and sets up port 10025 to communicate the findings back to it. As for the rest of the settings, feel free to consult that wonderful Postfix site, should you want to make changes or tweak the configuration from mine.

One more tiny change to /etc/postfix/ and amavisd-new is pretty much set for our purpose:

content_filter = smtp-amavis:[localhost]:10024

Add this line anywhere in the file – it tells Postfix to use Port 10024 to talk to amavisd-new on the local machine.

And there you go! Amavisd-new is configured and ready to send our emails through the paces to make sure only what we really want ends up in our mailbox! That was easy! Our trusty ubuntu package install also made sure that amavisd-new starts automagically at boot so you can relax for a little now!

Installing Spam Assassin

Installing the Package

Ready for a quickie? Or better, quickies? Ummmmmm….no, not what your mind was already thinking again! I know you! You better watch out, because ceiling cat is watching you! All I wanted to say is that piecing together and configuring the rest of the CrunchSpam relay is painless and quick, and again, mostly so because ubuntu does a fairly good job with their repositories and install scripts. Let’s get SpamAssassin installed with

sudo apt-get install spamassassin

Once that is done we need some additional Perl stuff – I admit, I have no clue what I am doing with this, but I can google and read and follow directions very well *g*. So to make it all work I ran:

perl -MCPAN -e shell

Basically I got a bunch of text, upgrade warnings and so on, the default responses by hitting ENTER seem to have made all the right decisions and in no time I was able to move on to type and run

install Digest::SHA1

after which you have to exit by typing

quit <enter>

Configuring SpamAssassin

Because SpamAssassin will receive email from the internet, we have to add our public IP that receives the email to it’s configuration. This is done in /etc/spamassassin/, where you would add all IP’s that appear in your MX records as trusted as well as internal networks by adding as many of these lines as you need:

trusted_networks<br /><br />internal_networks<br />

Uh…yea, that’s pretty much it! We will get back to the file above and some others in the same directory when we install Razor and Pyzor, but for SpamAssassin itself, all is set and done!

Installing Razor

First off, let’s grab it from the repositories, and by now I am sure you know what I am going to say…

sudo apt-get install razor

Before we go any further, you need to make sure that tcp port 2703 is open through your firewall for the CrunchSpam relay, otherwise the next step will fail. Razor needs this port to communicate with it’s servers to identify spam. If you do not feel comfortable with that, it the system will work without Razor (or Pyzor for that matter), just not as good. Once you ensured that you can communicate on that port, we’ll check if we can connect to the Razor servers and autoconfigure:

razor-admin -d -create

If all went well and you configured your firewall correctly you should receive razor-admin finished successfully to tell you all is set and you can move on to enter

razor-admin -register

to register our relay with the Razor network. Again, our obedient spam-slave should reply with small voice razor-admin finished successfully. If any of these steps fail, check your firewall, if all is good there, just run them again, sometimes it’s just a temporary connectivity issue. Once we finished successful, let’s move on to edit Razor’s configuration in the file /etc/razor/razor-agent.conf Replace the line

debuglevel             = 3


debuglevel             = 0

and append the file with

razorhome = /etc/amavis/.razor

which tells Razor that it’s files can be found in the directory above. We need to now move the files that our spam-slave Razor already created by default in the root directory, to their new home by running

cp -r /root/.razor/ /etc/amavis/

before shooting off another command so Razor too reconfigures itself to use the new location:

razor-admin -d -create -home=/etc/amavis/.razor

Another small voiced razor-admin finished successfully should confirm the reconfiguration was successful. Spamassassin has a configuration file at /etc/spamassassin/v310.pre which activates the plugins to be used, but it should already have an uncommented entry for

loadplugin Mail::SpamAssassin::Plugin::Razor2

in it, as that would be the default Spamassassin installation from the repo’s – then again, can’t hurt to check it just to make sure. You also might want to come back to this file when we are all done to disable plugins we might not be using. With that, Razor is ready to go!

Installing Pyzor

Installing Pyzor is just as easy as pretty much all the packages we installed so far. Pyzor is much like Razor an anti-spam server community and also needs a port open to work properly, this time UDP port 24441. Once that is set and done, start with

sudo apt-get install pyzor

to get everything setup on your system, then run

pyzor discover

to connect to the pyzor servers and to create a file named servers in the /root/.pyzor/ directory. Because Amavis will need to have access to this file as well, we’ll copy it to the .pyzor directory that we create first

mkdir /etc/amavis/.pyzor

then copy it with

cp /root/.pyzor/<span class="search_hit">server</span>s /etc/amavis/.pyzor/

to check if all is working well we can enter

su amavis -c 'pyzor ping'

which will use the amavis user to run a check on the availability and response of the Pyzor servers. If Pyzor is just as obedient as Razor was it will respond with your IP address followed by (200, ‘OK’)

This concludes our SpamAssassin configuration, and because it is later in the day now, we do not have to feel bad any longer if we long for a cold brew of our choice or other alcoholic beverage to celebrate – then again, it always is 5 o’clock somewhere, after all.

Installing ClamAV Anti Virus

Yes, Ladies and Gentlemen (if there are any, and if you are still with me at this point…), we have the finish line in our sights. Let’s get ClamAV installed to clean all the nasty little cooties off of our emails! C’mon, you know what I am going to say, right?

sudo apt-get install clamav

Yes, thats right – once more we are pulling a wonderfully preconfigured package from the repositories!

Right after that we can dive into the few things we have to do to make sure that the “clam” does not only sit on our computer and look pretty, but actually does something for us, but to allow it to do so, we need to make sure that the clamav user is in the amavis group and vice versa:

sudo adduser clamav amavis<br />sudo adduser amavis clamav

Now let us use our favorite new friend Joe to edit ClamAV demon’s configuration:

joe /etc/clamav/clamd.conf

There will be a line that has Example on it – either comment it out or delete it completely, as clamd won’t even run while that is in there. The line AllowSupplementaryGroups true should be in there and not commented out.
Just to make sure that amavisd-new came preconfigured the way we need it to (can’t trust anyone these days!), let’s check to see if it is set up to send email over to ClamAV to receive a clean bill of health by opening /etc/amavisd/conf.d/15-av_scanners in our favorite text editor (which I am sure is Joe by now…) and ensure that the section about ClamAV looks like this:

 ###<br /> ['ClamAV-clamd',<br />   \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.ctl"],<br />   qr/\bOK$/, qr/\bFOUND$/,<br />   qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],<br />

And you know, that is pretty much all for ClamAV, before we are moving on to some minor last configuration changes