All posts by ptrost

Reverting or downgrade PHP 5.3 to 5.2 in Ubuntu Lucid Lynx 10.04

Original article from:

I’m adding it here because of a package addition and to save it for my use.

So, you upgraded to Ubuntu 10.04 but suddenly your old applications like Drupal do not work on PHP 5.3 anymore? What the hell?

Without asking why it doesn’t work because we would only loose time we want to go back to the version of PHP 5.2 where it does work!

Let us list all existing PHP packages to know what version we are running:
dpkg -l | grep php

So, now we are going to duplicate the existing sources.list and replace the lucid with karmic repos and saving it in sources.list.d
sed s/lucid/karmic/g /etc/apt/sources.list | sudo tee /etc/apt/sources.list.d/karmic.list

Create a file to be a little bit ahead of our apt-get system.
sudo nano /etc/apt/preferences.d/php
And insert the following text
Package: php5
Pin: release a=karmic
Pin-Priority: 991

Let’s update the system. (You might want to do it twice to be sure)
sudo apt-get update

Installing php5 Karmic Packages. Attention! Only replace packages that were installed when doing the first command (remember the grep we did in the first step?)
sudo apt-get install php5=5.2.10.dfsg.1-2ubuntu6 php5-dev=5.2.10.dfsg.1-2ubuntu6 php-pear=5.2.10.dfsg.1-2ubuntu6 php5-cgi=5.2.10.dfsg.1-2ubuntu6 php5-cli=5.2.10.dfsg.1-2ubuntu6 php5-common=5.2.10.dfsg.1-2ubuntu6 php5-curl=5.2.10.dfsg.1-2ubuntu6 php5-gd=5.2.10.dfsg.1-2ubuntu6 php5-mcrypt=5.2.10.dfsg.1-2ubuntu6 php5-mysql=5.2.10.dfsg.1-2ubuntu6 php5-pgsql=5.2.10.dfsg.1-2ubuntu6 libapache2-mod-php5=5.2.10.dfsg.1-2ubuntu6

To not have Ubuntu upgrade php, do the following:

echo "php5-common hold" | dpkg --set-selections
echo "php5-cgi hold" | dpkg --set-selections

Blocking countries other than the US in IPTables

Courtesy of Kyle!

Pulls all ISO country codes except for the US and populates iptables with ALL ranges in those countries automatically.

Setup a cron job (/etc/crontab) to run every week:

@weekly /usr/local/bin/

Put the in /usr/local/bin/ and chmod +x it.

The script first backups up the existing config to /backup/iptables-last.txt first. After it processes the country codes it then applies other static entries in a file I setup called:

This way, when it flushes and rebuilds the iptables rules based on the current iso codes, I don’t lose the addition of my other regular entries.

Create /usr/local/bin/ with the following code:

/sbin/iptables-save > /backup/iptables-last.txt

### Block all traffic from everywhere except the US. Use ISO code ###
ISO="af al dz aq br ar cn lb my ly lr la jp jm jo kz ke hk ml mx fm md mc mn ms ma mz mm nr na np nl an nc nz ni ne ng nu nf mp no om pk pw pa pg py pe ph pn pl pt pr qa re ro ru rw kn lc vc ws sm st sn sa sc sl sg sk si sb so za gs es lk sh pm sd sr sj sz se ch sy tw tj tz th tg tk to tt tn tr tm tc tv ug ua ae gb um uy uz vu ve vn vg vi wf eh ye yu zm zw ie in il ir hn"

### Set PATH ###

### No editing below ###

$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X

# create a dir
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT

# clean old rules

# create a new iptables list

for c  in $ISO
# local zone file

# get fresh zone file

# country specific log message
SPAMDROPMSG="$c Country Drop"

# get
BADIPS=$(egrep -v "^#|^$" $tDB)
for ipblock in $BADIPS
$IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
$IPT -A $SPAMLIST -s $ipblock -j DROP

# Drop everything

/sbin/iptables-restore < /etc/sysconfig/iptables-static-rules.conf

exit 0

Catching unsolicited bounces (backscatter) with SpamAssassin


The “Virus Bounce Ruleset” is a SpamAssassin ruleset to catch “backscatter”.

Backscatter is mail you didn’t ask to receive, generated by legitimate, non-spam-sending systems in response to spam. Here are some examples, [WWW] courtesy of Al Iverson:

  • Misdirected “undeliverable email” bounce messages from spam runs, from mail servers who “accept then bounce” instead of rejecting mail during the SMTP transaction.
  • Misdirected virus/worm “OMG your mail was infected!” email notifications from virus scanners.
  • Misdirected “please confirm your subscription” requests from mailing lists that allow email-based signup requests.
  • Out of office or vacation autoreplies and autoresponders.
  • Challenge requests from “Challenge/Response” anti-spam software. Maybe C/R software works great for you, but it generates significant backscatter to people you don’t know.

It used to be OK to send some of these types of mail — but no longer. Nowadays, due to the rise in backscatter caused by spammer/malware abuse, it is no longer considered good practice to “accept then bounce” mail from an SMTP session, or in any other way respond by mail to an unauthorized address of the mail’s senders.

How do I block it?

There’s a ruleset to block joe-job, virus-blowback, and spam-blowback bounce messages (a.k.a. “backscatter”), which is included in SpamAssassin 3.2.0. It provides the following rules:

  • __MY_SERVERS_FOUND: a whitelisted relay a la “whitelist_bounce_relays” was found
  • BOUNCE_MESSAGE: an MTA-generated bounce from a non-whitelisted relay, “message was undeliverable” etc.
  • CRBOUNCE_MESSAGE: Challenge-response bounce message from a non-whitelisted relay, eg. “please confirm your message was not spam”
  • VBOUNCE_MESSAGE: a virus-scanner-generated bounce from a non-whitelisted relay, e.g. “You sent a virus”

* ANY_BOUNCE_MESSAGE: any of the *BOUNCE_MESSAGE types above will also trigger this

__MY_SERVERS_FOUND inhibits the other 4 rules from firing.


If you are using SA 3.2.x, just enable the loadplugin Mail::SpamAssassin::Plugin::VBounce line in /etc/mail/spamassassin/v320.pre, and skip to the ‘whitelist_bounce_relays’ line in step 3 below.

If you are using SA 3.1.x, you can install the ruleset as follows:

1. Download [WWW] and [WWW]

2. Save both files to your /etc/mail/spamassassin directory.

3. Edit your and add a line like the following:


Replace with the hostname of the relay (or relays) that you send your outbound mail through.

This is used to ‘rescue’ legitimate bounce messages that were generated in response to mail you really *did* send. If a bounce message is found, and it contains one of these hostnames in a ‘Received’ header in the bounced message, it will not be marked as a blowback virus-bounce.

Note that if you do not add this line, the *BOUNCE_MESSAGE rules will never fire! You have to specify at least one whitelisted relay for it to operate.

4. Run spamassassin –lint and ensure it works.

5. Check a ‘sample vbounce’ mail, to ensure it marks blowback bounces as such:

spamassassin -Lt < sample-vbounce.txt
Content analysis details:   (2.6 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 0.0 NO_REAL_NAME           From: does not include a real name
 0.0 FORGED_RCVD_HELO       Received: contains a forged HELO
 0.1 BOUNCE_MESSAGE       MTA bounce message
 0.1 ANY_BOUNCE_MESSAGE   Message is some kind of bounce message

You should see the tests BOUNCE_MESSAGE and ANY_BOUNCE_MESSAGE appearing in the “Content analysis details” section.

6. Restart spamd, as usual, so that the ruleset is loaded.

7. Edit your procmailrc (or similar) to move messages that contain “ANY_BOUNCE_MESSAGE” in the “X-Spam-Status” header, to a “bounces” folder.

Or you can edit your file to add custom rules so that the unsolicited bounces are marked as spam:


If you run a hosting server, the problem with setting this globally is that you may have users who send outbound email from their ISP’s mail server instead of their domain mail server, and if they send to an invalid user, the bounce will then be marked as spam because it didn’t come from your outbound email server that you specified in whitelist_bounce_relays. If your users can customize a local SpamAssassin preferences file then that’s preferable as then they can put in custom scores like in the above to mark backscatter as spam. So in a shared hosting environment, don’t set any scores in, the default of 0.1 and 0.1 wil be fine.

If you don’t have per user preference files then the users who send mail through the domain mail server can create a local filter rule that takes anything with BOUNCE_MESSAGE or ANY_BOUNCE_MESSAGE in the body and move it to a local spam folder.

If upgrading from 3.1.x to 3.2.0, you need to delete and from /etc/mail/spamassassin, so that it doesn’t clash with the released version.

Further Steps

If you’re using Postfix, and volumes of backscatter at your mailserver are very high, you can also block incoming backscatter during the SMTP transaction. [WWW] This blog post describes how to do it.

What About My Own Bounces?

You might be worried that the VBounce ruleset will block bounces sent in response to your own mail. As long as the error conditions are flagged during the SMTP transaction (as they should be nowadays), and you’ve specified your own mailserver(s) in ‘whitelist_bounce_relays’, you’re fine.

Using PuTTY Without Password Prompting

PuTTY is a great SSH terminal progam for Windows. Using this tutorial you’ll be able to auto login to a remote server without being prompted for a username or password. Do NOT do this in a public machine.

1. Download PuTTY from

2. Install and then run PuTTYgen from the programs menu.

3. Select SSH2-DSA from the bottom and hit the Generate button. Move the mouse a bit and hit ctrl-c to copy the key.

4. Click on Save Private Key. Click Yes to save it without a passphrase. I would put it in your “My Documents” directory, but you can place it wherever. Make sure you save it with a .ppk extension.

5. Open the Pageant  program for the PuTTY menu. It will put in icon in the system tray. Right click on it and click on Add Keys. Now navigate to where you saved the key file, select it, and hit Open.

6. Lauch PuTTY and type in the hostname to connect to. Type the name again in the Saved Sessions. Then click on the Data option under Connections and put your username in the Auto-login field. Click on Session at the top then click Save to save the session.

7. Click Open and PuTTY will connect to the server and display “Using Username “<your user>”. Put in your password.

8. If you’ve never used SSH from your target server, you will now need to “ssh localhost” so your .ssh directory will be created and with the right permissions. If you had to ssh localhost, now type exit to get back to your original shell and cd into the .ssh dir.

9. Use your favorite text editor to create “authorized_keys2” and paste your key into it (right or middle mouse button).

10. Permissions on authorized_keys2 will probably be -rw-rw-r– so you will need to type “chmod g-w authorized_keys2” to remove group write access, otherwise authorized_keys2 will not be used by ssh.

11. Close your shell session and open PuTTY again. If you did this right then you will now be able to double click on your host and connect without being prompted for a username or password. Another option to open the host is to right click on the Pageant tray icon and click on Saved Sessions to open up a comonly access host.

12. You will now need to get the Pageant program launched upon Windows Startup so you don’t have to open it every time. This can be done by (at least in Vista) by going to the Start Orb, All Progams, PuTTY, right click on Pageant and select copy. Now scroll down and right click on Startup and click Open. Now right click in the empty white space and select Paste Shortcut.

13. You will probably want to start Pageant at windows startup and/or start pageant with your saved key loaded. To do so, right click on the Pageant shortcut, click on properties, then change the target to something like this – “C:\Program Files\PuTTY\pageant.exe” “C:\Documents and Settings\ptrost\My Documents\key.ppk”

14. The quickest way to retrieve the key if you want to add it to another server and it’s not in your copy/paste buffer) is to open up PuTTYgen again and click Load, then select your previously saved key file. Then you can right click in the public key box to select all then again to copy.

Using Bash through the WWW

This tip came from a friend of mine:

I thought you might find something I did useful.  It grants root shell access via a browser using xinetd.  Just DO NOT put it on a public box without securing the www.bash script first (firewall port 50000 through iptables, or acls in xinetd). It sets up an xinetd service on port 50000 and anything after the trailing slash is treated as a shell command.  So http://<SERVER_IP>:50000/ls generates a directory listing of the current directory.

The port can be changed to whatever port > 1024 you want to use.

1.) Add following line to the end of /etc/services
bashweb      50000/tcp                       # bashweb

2.) nano -w /etc/xinetd.d/bashweb
service bashweb
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/www.bash
log_on_failure += USERID
disable = no
port = 50000

3.) nano -w /usr/sbin/www.bash


read request

while /bin/true;
read header
[ "$header" == $'\r' ] && break;

url="${request#GET }"
url="${url% HTTP/*}"
url=`echo $url | sed 's/\///'`
#url=`echo $url | sed 's/%20/ /g'`
#echo $url;

x=`echo $url | sed "s/\/$//" | awk -F "/" '{print $1}'`
#### Change $y below to your desired password.
#### The URL then looks like this: http://<IP>:50000/PASSWORD/<COMMAND>

if [ $x = $y ]; then
url=`echo $url | sed "s/\/$//" | awk -F "/" '{print $2}'`
echo -e "HTTP/1.1 200 OK\r"
echo -e "Content-Type: text/plain; charset=us-ascii\r"
echo -e "\r"
echo -e "\r"
echo "nope"

4. Set executable permisson

chmod 700 /usr/sbin/www.bash

5.) Restart xinetd

service xinetd restart

Browse to http://<SERVER_IP>:50000/PASSWORD/ls -la
to test


Building a Poor Man’s Barracuda

This article will show you how to replicate most of the functionality of a Barracuda Spam Firewall. If you work at a company that has an IT budget, then by all means I recommend purchasing one of these devices. If your company has no budget or if you’re the adventurous learn it on your own type, then this bud’s, er, article’s for you.  The BSF has 12 layers that messages would be processed through as illustrated in the graphic below. I’ll show you how to replicate most of these steps using the Exim mail transport agent, the Spam Assassin spam filter, and a few plugins. This guide assumes you have a basic working knowledge of Linux, Exim, and Spam Assassin.  This setup has worked very well at the company I work for with users reporting only a handful of spam a day compared to 150 a day they were getting before making some of these changes.


I’m going to outline my steps slighly differently than on the Barracuda so you get a better idea of what steps is configured where. In my setup, the MX server does all the prefiltering and depends on the hosting server to do the final spam filtering which is user configurable. Because of this, my setup will be a bit different than yours or the BSF’s, but as the saying goes, YMMV.  For me, steps 7-12 are taken care of by an internal Plesk server. If you’re running CPanel, congratulations, you already run Exim as the MTA so you can do all this on the same machine.

Connection Management:

  • Step 1 – Network Denial of Service Protection
  • Step 2 – Exim Rate Control
  • Step 3 – IP Reputation Analysis
  • Step 4 – Recipient Verification
  • Step 5 – Sender Verification

Content Scanning:

  • Step 6 – Content (Virus and Spam) Scanning
  • Step 7 – Fingerprint Analysis
  • Step 8 – Intent Analysis
  • Step 9 – Image Analysis
  • Step 10 – Bayesian Analysis
  • Step 11 – Rule-Based Scoring
  • Step 12 – Custom Policy

As I mentioned before, I assume you already have a working Exim configuration. I would give you mine, but if you have any sense you would know that it wouldn’t be a drop in replacement, therefore I’ll show you what I changed in my Exim config and you can take it from there.

I can’t speak for other distro’s like Debian, but the supplied configuration for the Red Hat Exim RPM has 3 ACL’s (Access Control Lists) setup in exim.conf, they are:


Documentation of Exim’s built-in ACL’s can be found at

The first thing we need to do is to add 2 additional ACL’s so you can better see how incoming messages are processed through the MTA.

So, open your config and find this line – “acl_smtp_rcpt = acl_check_rcpt”. Now you want to add the following above it:

acl_smtp_connect = acl_check_connect
acl_smtp_helo = acl_check_helo

This will make it where you now have specific ACL sections to handle the start of the connection, the helo statement from the sender, and a section for conditions after the rcpt to is given. Specific details on using these ACL’s will be found in the steps below.

The text in bold type at the start of each step comes from the Barracuda Spam Firewall Email Filtering Whitepaper

Step 1: Network Denial of Service Protection

Built on a hardened and secure operating system, the Barracuda Spam Firewall receives email on behalf of the organization, insulating the organization’s email server from receiving direct Internet connections and the associated threats.


Step 2: Rate Control

Automated spam software can be used to send large amounts of email to a single email server. To protect the email infrastructure from these flood-based attacks, the Barracuda Spam Firewall counts the number of incoming connections from a particular IP address and throttles the connections once a particular threshold is exceeded.

Organizations that relay email through known servers or communicate frequently with known partners can and should add the IP addresses of those trusted relays and good email servers to the Rate Control exemption list.

There’s several things we can do to control the rate at which Exim accepts connections.

## Maximum amount of connections we want to accept
smtp_accept_max = 250
smtp_accept_queue_per_connection = 100
## Maximum connections per sending host to accept
smtp_accept_max_per_host = 5
smtp_connect_backlog = 50
smtp_receive_timeout = 15m

Now that you have some setting to limit the overall inflow of connections,  I also suggest putting in an SMTP banner delay to help stop ratware. In the code below, the “accept  delay – 15s” gives you the pause when accepting a new SMTP connection (banner delay). To make this work you will need to also use “smtp_enforce_sync = true”. Exim’s default is smtp_enforce_sync = true, but it doesn’t hurt to put it in anyway just in case some unlucky soul has to follow up your work later and wondering how you configured the server. If you have “smtp_enforce_sync = false”, then even with an accept delay in the connect ACL, what will happen is that your server will still wait 15s to put up the 220 response, but it will save the input from the sender in the meantime. With “smtp_enforce_sync = true”, Exim will drop the sender if they start spewing commands before getting the 220 response from you server. Put the following line under the other smtp lines you just stuck in:

smtp_enforce_sync = true

Exim has 2 facilities for rate limiting hosts. The first would rate limit on individual hosts connecting and is only going to be effective if they are sending to multiple recipients in a sngle session:

# Define list of IPs to not rate limit
hostlist ratelimit_allow = ${if exists {/etc/exim/ratelimit-allow} \

# Rate limit hosts NOT in the allow list
smtp_ratelimit_hosts = ! +ratelimit_allow

# Set the treshold, time delay, increase factor, and maximum delay
# (which should never be more than 5 min)

smtp_ratelimit_mail = 50,0.5s,1.05,3m

# Used to control the rate of acceptance of MAIL and RCPT commands
# in a single SMTP session, respectively

smtp_ratelimit_rcpt = 80,0.25s,1.015,3m

The second is in the ACL and is documented at This method is preferred since it will work on multiple hosts at once as well as the same host connecting again later.

Next, find the “begin_acl” statement in your exim.conf file and and add the following before “acl_check_rcpt:”.


accept  delay = 15s

# End acl_check_connect

Feel free to put whatever delay you want in your acl_check_connect, but keep in mind, Exim’s default timeout for sender verification checks is 30s, so if you put a longer delay than 20s in your connect, you run the risk of failing other servers’ sender verification checks to you.

Step 3: IP Reputation Analysis

  • Barracuda Reputation. Barracuda Reputation is maintained by Barracuda Central and includes a list of IP addresses of known, good senders as well as known spammers. Updates to the Barracuda IP Reputation database are delivered to the Barracuda Spam Firewall via Barracuda Energize Updates.
  • External block lists. The Barracuda Spam Firewall enables administrators to take advantage of external block lists which are also known as real-time block lists (RBLs) or DNS block lists (DNSBLs). Several organizations maintain external block lists, such as
  • Customer-defined policy for allowed IP addresses. The Barracuda Spam Firewall enables administrators to define a list of trusted email servers by IP address. By adding IP addresses to this list, administrators can avoid spam scanning of good email, both reducing processing requirements and eliminating the chances of false positives.
  • Customer-defined policy for blocked IP addresses. The Barracuda Spam Firewall also enables administrators to define a list of bad email senders. In some cases, administrators may choose to utilize the IP block lists to restrict specific email servers as a matter of policy rather than as a matter of spam protection.

I’m not sure what the BSF does for HELO checks, but I’m including HELO checks and DNS RBL (Real-time Block List) checks into one step, however the HELO checks will be in their own ACL and the RBL check will be done in acl_check_rcpt.

Now add the acl_check_helo section below to your exim.conf under “# End acl_check_connect”

The first deny message will stop senders issuing a HELO that is contained in the helo-deny statement. The second deny message says that the helo has to have a “.” in it. If it doesn’t then the message is rejected. That will also stop spammers from using HELO’s like “none”, or “localhost”


# Blacklist hosts (IPs) in this file
deny hosts = ${if exists {/etc/exim/blacklist-hosts} \

# Block senders that give a HELO that is in the helo-deny file
deny message = Your server with the IP $sender_host_address is \
configured incorrectly. Email has been blocked. (HELO Error)
condition = ${lookup {$sender_helo_name} lsearch{/etc/exim/helo-deny}{yes}{no}}
delay = 30s

# Block senders that give a HELO with a . in it. (none, local, localhost, etc..)
deny message = Your server with the IP $sender_host_address is \
configured incorrectly. Email has been blocked. (HELO Error)
condition = ${if match{$sender_helo_name}{\\.}{no}{yes}}
delay = 30s


# End acl_check_helo

The second ACL you added is the acl_check_helo which allows you to put in conditions to test for when the sending server issues a HELO or EHLO statement. Our check above is simple, it looks at “/etc/exim/helo-deny” and if the helo statement contains anything in the helo-deny file then the sender is rejected. I would put the following in the helo-deny file:

<IP of machine>
<Hostname of machine>

Now you can get really fancy and block any sender with an IP address as their HELO, however I have not researched this enough to find out if only ratware programs do this or if there would be legitimate sending software that would send an IP. Blocking senders giving their IP in a HELO might also not be RFC compliant. No sending host should ever connect to you and issue an helo with your own IP or server name, and every helo statement should have at least one “.” in the name (eg. “”, not just “google”).

You may now be wondering, “Why not do the RBL checks in acl_check_helo efore the sender even issues the RCPT command?”  That is a good question. My answer is that if you do the check earlier than acl_check_rcpt, like in acl_check_helo, you will be blocking IPs that are in the blacklist before you even know who they’re sending to. The purpose of waiting then is so that the RCPT will be logged just in case of problems.  For that matter, you *could* put the helo checks above into the acl_check_rcpt, however I feel that the checks are safe and will weed out ratware/spamware without generating false positives. YMMV, so if your experience shows that good mail is being rejected, then you’ll want to put helo checks in acl_check_rcpt.

Through trial and error, I’ve found the best RBLs to use are (BSF’s publicly available list),,,,, and All lists are publicly usable, however with SpamHaus if you run a commercial business you will need to pay. I recommend that if you have over 1000 user accounts, you should really go ahead and use rsync to copy down the lists so that way your MX server(s) are contacting your local RBL server instead of sending all those requests out to other servers on the internet. Setting up an RBL server is beyond the scope of this article, but you can use a program called rbldnsd to do it and can use instructions at the RBL providers to get started.

You will need to put the following somewhere in the acl_check_rcpt ACL. You probably already have something similar already but just need to change the dnslists. Let’s also put in  delay statement so that way blacklisted IPs trying to flood you will be slowed down. Depending on how many spam hit your server gets you may need to take out the delay statement.

deny message = Rejected message because $sender_host_address is in a black list \
at $dnslist_domain ($dnslist_text)
dnslists = \
delay = 30s

Next will be a No Reverse DNS check. We will be looking up the reverse PTR for the sending IP and if it doesn’t exist then you have 3 choices, you can send a “warn message” if you just want to accept the mail but put a header into the message so you can score it with Spam Assassin, you can “drop message” if you want to just outright reject any mail from a sending IP without a reverse, or you can “defer message” which will allow the originator time to fix the problem and have their server resend the message. I chose defer. Make sure you put this section in after the RBL checks, so that way you can DENY using the RBL checks the IPs that don’t have reverse PTR’s AND are in an RBL.

defer message = No Reverse DNS for $sender_host_address, \
please fix your reverse PTR -- for questions email <your abuse email address>
!local_parts = abuse : postmaster
condition = ${lookup dnsdb{defer_never,ptr=$sender_host_address}{0}{1}}

Step 4: Recipient Verification

Many spammers attack email infrastructures by harvesting email addresses. The Barracuda Spam Firewall verifies the validity of recipient email addresses through multiple techniques.

  • Protocol compliance. Similar to Sender Authentication, a recipient is first validated for being specified properly. An example of an enforcement policy includes, forcing RFC 821 compliance.
  • Custom policies. Organizations can define their policies based on allowed recipient email addresses for which spam scanning should be disabled. They can also define their own block lists based on email addresses. Note that allow lists override block lists.
  • LDAP recipient verification. Customers of Barracuda Spam Firewall models 300 and higher can choose to reject messages if the recipient email addresses do not appear in the LDAP directory.
  • SMTP recipient verification. By default, the Barracuda Spam Firewall rejects messages if the downstream mail server does not accept mail for that recipient.
  • Domain Keys. The Barracuda Spam Firewall enables administrators to inspect email messages for DomainKeys (DKIM) and take action when messages fail signature verifcation.

Now that the sender has given a proper HELO, they are not in a blacklist, and they have a reverse DNS PTR, now we need to see if the address they are sending to exists. So that you understand the importance of recipient verification, let me give you a quick example situation. Let’s say a spammer is blasting out garbage using the address Without recipient verification, what will happen is that your server will accept the message regardless of whether the recipient exists and try to deliver it. If  “” is sending to address “” and the jane address doesn’t exist, your server will then generate a mailerdaemon bounce and send it back to Unfortunately for the REAL, he is going to get a lot of these type of non-existent user messages. Exim will hold the connection open from the sender and contact your mail host to see if actually exists. If she does then the message will continue to be checked in Exim (we’re still only on step 4 now), but if does not exist, Exim will spit back a Recipient Verify Failed message to the sending host therefore  the real never gets a ‘fake bounceback message’

Here’s what you now need to put in in the ‘acl_check_rcpt’ section. You should already have something like the first 2 lines where Exim would reject a non existent user. We’re just going to add verification to it as well a a delay statement which will help stop dictionary attacks where a sender constantly tries names in alphabetical order. If that starts to happen we keep adding an incrementing delay. We’ll use acl_m9 in Step 6.

# log the recipient address so we can work with it later.
warn set acl_m9 = $acl_m9 $local_part@$domain

# The following section of the ACL is concerned with local parts that contain
# @ or % or ! or / or | or dots in unusual places.
deny domains = +local_domains
local_parts   = ^[.] : ^.*[‘@%!/|]

# Verify the recipient exists. If not then increment an incrementing delay to slow down dictionary attacks.
deny domains = +relay_to_domains
message = No Such User (${local_part}@${domain}), please check your spelling
log_message = Recipient Verify Failed
!verify = recipient/callout=30s,defer_ok
delay = ${eval:$rcpt_fail_count*10 + 20}s

Step 5: Sender Authentication

Declaring an invalid “from” address is a common practice by spammers. The Barracuda Spam
Firewall utilizes a number of techniques to both validate the sender as well as apply policy.

  • Protocol compliance. First and foremost, the sender is validated for being specified properly. Examples of enforcement policies include, forcing RFC 821 compliance or requiring fully-qualified domain names.
  • DNS lookup. To prevent senders from faking a “from” domain, a DNS lookup is performed on the sender domain to ensure that the domain exists.
  • Sender spoof protection. The Barracuda Spam Firewall has the option to prevent “spoofing” of an organization’s own domain by disallowing emails using that domain name to be sent from outside the organization. Note that sender spoof protection should not be enabled if the organization sends messages from outside their internal email infrastructure (e.g., in the case of marketing bulk-mail services).
  • Custom policies. Organizations can define their own allowed sender domains or email addresses. They can also define their own block lists based on sender domains or email addresses. Note that allow lists override block lists.
  • Sender policy framework (SPF). SPF is a proposed standard with growing momentum, designed to prevent spoofing of email domains. SPF provides a means for organizations to declare their known email servers in their DNS records so that email recipients can validate the identity of the sender domain based on the IP address of the sending email server. The Barracuda Spam Firewall enables email administrators to block or tag messages on failed SPF checks.

Yes I know, the BSF has Sender Authentication before Recipient Verification. I prefer doing a sender verify check AFTER the recipient verify check, because otherwise, you are checking to see if senders exist when they may be sending to non-existent users on your sysem (ie. dictionary attack). On my servers, very few messages are tagged as failing sender verify so reversing the order made sense. By reversing their order, we’re verifying that a recipient exists before we waste a call out to the sender’s MX to see if they exist.  Place this section BELOW the one above for the recipient verify.

warn message = X-SENDERVERIFY: <$sender_address> does not appear to be a valid sender address.
hosts = !+callout_exception_list
!verify = sender/callout=10s,maxwait=120s,defer_ok

The callout_exception_list would be a list of hosts that you know do not accept sender verify callouts ( is one of those).

hostlist callout_exception_list = /etc/exim/callout-exceptions

We used to do a deny insead of warn on the Sender Verify, however there are too many mailing lists and servers that send mail directly with an invalid address and that caused many emails to us about needing to whitelists hosts.  The better idea I think is to use ‘warn message’ so that way you are just putting a X-SENDERVERIFY header into the message that you can score later with Spam Assassin. That way if the sender doesn’t exist the recipient can just add their address to their whitelist.

Step 6: Virus Scanning

Virus Scanning takes precedence over all other Mail Scanning techniques and is applied even when mail passes through the Connection Management layers. As such, even email coming from “whitelisted” IP addresses, sender domains, sender email addresses or recipients are still scanned for viruses and blocked if a virus is detected.

This section will give you MIME checking, file extension blocking, virus scanning, and spam filtering. I used Clam Antivirus because it’s free and I’m familiar with it. You can certainly use whichever one you wish. What you’ll need to do is first uncomment these 2 lines in your Exim.conf:

#acl_smtp_mime = acl_check_mime
#acl_smtp_data = acl_check_content

Then add: (we’ll use spamd_address in the next step)

av_scanner = clamd: 3310
spamd_address = 783

To avoid permission problems, after you install clamd, edit /etc/clamd.conf and change the user from clamav to exim, then ‘chown exim /var/log/clamav’ , and ‘chmod g+w /var/log/clamav’. Now install clamav and you can then put freshclam  in a cronjob to kee the database up to date. I recommend every 2 hours:

0 */2 * * * root /usr/bin/freshclam 2>&1 >/dev/null

In the default Exim.conf on Red Hat systems, the malware scanning is done in acl_check_mime. When I enabled the malware scan I got ACL errors. What I would suggest is moving it to acl_check_content instead and leave only the file extension filtering in acl_check_mime.  Something like this:


# Decode MIME parts to disk. This will support virus scanners later.
warn decode = default

# File extension filtering.
deny message = This message has been rejected because it has \
a potentially executable attachment. This form of attachment \
has been used by recent viruses or other malware. If you \
meant to send this file then please package it up as a zip \
file and resend it.

condition = ${if match \
{${lc:$mime_filename}} \
{\N(\.reg|\.vbs|\.exe|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} \


# End acl_check_mime

Here we’ll log the recipient using the previously definted acl_m9 variable from acl_check_rcpt. This will make troubleshooting a bit easier if a user says they’re missing mail from a sender but don’t know the sender’s addess. We’ll use the last section for spam on the next step.


drop  message = Found MIME error ($demime_reason).
log_message = MIME ERROR FOUND
demime = *
condition = ${if >{$demime_errorlevel}{2}{1}{0}}

drop message = DISCARD X-Virus: $malware_name detected. Mail delivery avoided.
log_message = clamd $malware_name [$sender_host_address] F=<$sender_address> R=<$acl_m9>
demime = *
malware = *
condition = ${if <{$message_size}{2M}{1}{0}}

# Reject spam messages with score over 15, using an extra condition.
deny  message = This message scored $spam_score points. Go away spammer! R=<$acl_m9>
spam = nobody:true/defer_ok
condition = ${if >{$spam_score_int}{150}{1}{0}}


# End acl_check_content

The reason for ‘drop’ instead of  ‘deny’ is that a drop will immediately stop the SMTP transaction after the error is sent instead of waiting for the originator to disconnect.

Step 7: Custom Policy (User Specified Rules)

Administrators can choose to define their own policies, perhaps for compliance or governance reasons, which take precedence over spam blocking rules delivered to the system automatically through Barracuda Energize Updates. The Barracuda Spam Firewall enables administrators to set custom content filters based on the subject, message headers, message bodies and attachment file type. In general, administrators do not need to set their own filters for the purposes of blocking spam, as these forms of rules are delivered to Barracuda Spam Firewalls automatically through Barracuda Energize Updates.

I don’t have any custom rules setup. One thing you can do in this section is to setup another router in exim to deliver a copy of every message that passes all previous tests to an archive file/dir.

Step 8: Fingerprint Analysis

A message “fingerprint” is based on commonly used message components (e.g., an image) across many instances of spam. Fingerprint analysis is often as a useful mechanism to block future instances of spam once an early outbreak is identified. Engineers at Barracuda Central work around the clock to identify new spam fingerprints which are then updated on all Barracuda Spam Firewalls through hourly Barracuda Energize Updates.

There’s several different plugins for Spam Assassin that check against a database of messages reported as spam. We’ll be setting up DCC, Pyzor, and Razor

If you’re running  Red Hat or CentOS, Razor might be in your default repository, but DCC and Pyzor will not be and you’ll have to either download them manually or add in another yum repository. I found them in Atomic Rocket Turtle’s repository and when you install it you can select ‘N’ when asked if you want the Plesk part of it. You can get it with “wget -q -O – | sh”

DCC -Distributed Checksum Clearinghouses

Uncomment “loadplugin Mail::SpamAssassin::Plugin::DCC” in /etc/mail/spamassassin/v310.pre
Add these 2 lines to /etc/mail/spamassassin/

use_dcc 1
dcc_timeout 10

Pyzor – collaborative, networked system to detect and block spam using identifying digests of messages

Uncomment “loadplugin Mail::SpamAssassin::Plugin::Pyzor” in /etc/mail/spamassassin/v310.pre
Add these 2 lines to /etc/mail/spamassassin/

use_pyzor 1
pyzor_options --homedir /home/spamassassin/.pyzor

Now as the user that runs spamassassin (probably ‘spamassassin’) you need to run ‘pyzor discover‘ to write out the servers list.

Razor – distributed, collaborative, spam detection and filtering network

Uncomment “loadplugin Mail::SpamAssassin::Plugin::Razor2” in /etc/mail/spamassassin/v310.pre
Nothing needs to be added to for this.

Step 9: Intent Analysis

All spam messages have an “intent” – to get a user to reply to an email, visit a Web site or call a phone number. Intent analysis involves researching email addresses, Web links and phone numbers embedded in email messages to determine whether they are associated with legitimate entities. Frequently, Intent Analysis is the defense layer that catches phishing attacks. The Barracuda Spam Firewall features multiple forms of Intent Analysis.

  • Intent analysis. Markers of intent, such as URLs, are extracted and compared against a database maintained by Barracuda Central, and then delivered to the Barracuda Spam Firewall via hourly Barracuda Energize Updates.
  • Real-time intent analysis. For new domain names that may come into use, Real-Time Intent Analysis involves performing DNS lookups against known URL block lists.
  • Multilevel intent analysis. Use of free Web sites to redirect to known spammer Web sites is a growing practice used by spammers to hide or obfuscate their identity from mail scanning techniques such as Intent Analysis. Multilevel Intent Analysis involves inspecting the results of Web queries to URLs of well-known free Web sites for redirections to known spammer sites.

Intent analysis is done with the URIDNSBL plugin.  URIDNSBL looks up URLs found in the message against several DNS blocklists.

Uncomment “loadplugin Mail::SpamAssassin::Plugin::URIDNSBL” in /etc/mail/spamassassin/init.pre

Step 10: Image Analysis

Today, image spam represents about one third of all traffic on the Internet. While Fingerprint Analysis captures a significant percentage of images after they have been seen, the Barracuda Spam Firewall also uses Image Analysis techniques which protect against new image variants. These techniques include:

  • Optical character recognition (OCR). Embedding text in images is a popular spamming practice to avoid text processing in anti-spam engines. OCR enables the Barracuda Spam Firewall to analyze the text rendered inside the images.
  • Image processing. To mitigate attempts by spammers to foil OCR through speckling, shading or color manipulation, the Barracuda Spam Firewall also utilizes a number of lightweight image processing technologies to normalize the images prior to the OCR phase. More heavyweight image processing algorithms are utilized at Barracuda Central to quicklygenerate fingerprints that can be used by Barracuda Spam Firewalls to block messages.
  • Animated GIF analysis. In addition, the Barracuda Spam Firewall contains specialized algorithms for analyzing animated GIFs for suspect content.

The only thing I’ve found that will do image analysis is the Fuzzy OCR Spam Assassin Plugin available at

I am including this for the sake of  completeness but warn you that it is not production quality yet. Only the SVN version works with the Spam Assassin 3.2.x brach (3.2.5 is current). I know it works because I have tested it before and saw in the spam report that it scored messages based on the content of the image in the spam. I don’t feel comfortable using this in an environment with 30,000 users, however YMMV. If you are doing this for a lower volume or personal server then please give it a shot.

Step 11: Bayesian Analysis

Bayesian Analysis is a linguistic algorithm that profiles language used in both spam messages and legitimate email for any particular user or organization. To determine the likelihood that a new email is spam, Bayesian Analysis compares the words and phrases used in the new email against the corpus of previously identified email.

I am not going to cover the specific howto of setting up a global bayesian database here because it’s not applicable to my setup with Plesk. However, I have done this before easily. The problem I have with that type of setup is that you may have users categorizing mailing list messages and test messages as spam which are not spam, and this is going to skew the bayesian filter for the people who do receive messages with matching characteristics. Assuming you’re using an internal mail host that supports bayesian filtering then I would certainly suggest enabling it. It has brought my uncaught spam volume down to almost nothing.

Step 12: Rule-based Scoring

Beyond absolute blocks that a single filter can apply, the Barracuda Spam Firewall also includes a sophisticated scoring engine that weighs multiple factors where a single filter may result into restrictive policy. By combining multiple rules with known weightings, the Barracuda Spam Firewall can deliver a strong confidence interval for spam messages. The Barracuda Spam Firewall enables administrators to set global spam scores. Certain models of the Barracuda Spam Firewall also support per domain and per user thresholds.

Spam Assassin rules and scoring can be customized in the file. This is outside the scope of this article but plenty of information can be found with a google search. Depending on your setup your users may be able to put in rules into their own preference files to override system defaults.