OpenVPN 2.2.x and iOS 9.3.x No Routing over VPN

Whilst going through the process of renewing certificates, and the recent updates for OpenVPN and iOS, I discovered that traffic was no longer being routed over the tunnel. There are a number of postings blaming changes that Apple have made in relation to IPv6. I’m unsure, but the fix was to alter the client.ovpn file to use an IP address in the remote directive instead of a DNS name.

e.g.

client
dev tun
proto udp
remote 1.2.3.4 1194
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
cipher AES-256-CBC # AES
comp-lzo
verb 3
;mute 20
<ca>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
</key>
<dh>
-----BEGIN DH PARAMETERS-----
-----END DH PARAMETERS-----
</dh>

I hope this helps someone.

Creating a Thawte CSR and then installing the SSL Certificate on Cisco IOS

This brief note covers getting an SSL certificate registered with Thawte onto a Cisco router running IOS.

1. Create the Trustpoint

This binds the SSL cert to the CA (Certificate Authority) which in this case is Thawte.  The subject is where you will specify all the usual bits you need in the cert. Also ensure that fqdn defined and is that same as the common name. If you don’t the name of the router will be used instead.

Router# conf t
Router(config)# crypto pki trustpoint thawte.com
Router(ca-trustpoint)# enroll terminal
Router(ca-trustpoint)# serial-number none
Router(ca-trustpoint)# fqdn hostname.domain.com
Router(ca-trustpoint)# ip-address none
Router(ca-trustpoint)# subject-name CN=hostname.domain.com,O=Organisation, OU=Department,L=Location,ST=State,C=Country
Router(ca-trustpoint)# revocation-check none
Router(ca-trustpoint)# end
Router# wr mem

Note the ‘subject-name’ is all on one line – due to the width of this page and spaces it is wrapping.

2. Authenticate the CA with the trustpoint

This means loading Thawte’s Premium signing certificate into the router.

It took quite a while to locate Thawte’s Premium Signing Certificate from their website so there is nothing to stop you cut’n’pasting from this post.

If you wish to get your own copy then you can download the complete set from http://www.thawte.com/roots/. Accept their terms (assuming you do) then download and unpack the zip file.

The file you need is : Thawte SSLWEB Server Rootsthawte Premium Server CAThawte Premium Server CA.pem

It is really important you get the right CA Certificate file on your router. Unfortunately the process won’t fail until you try and import your new certificate if you get the wrong one !!!!

Open the file in a text editor and you can then cut and paste at the appropriate time.

Router# conf t
Router(config)# crypto pki authenticate thawte.com
Enter the base 64 encoded CA certificate.
End with a blank line or the word "quit" on a line by itself
-----BEGIN CERTIFICATE-----
MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
-----END CERTIFICATE-----
quit
Certificate has the following attributes:
Fingerprint MD5: 069F6979 16669002 1B8C8CA2 C3076F3A
Fingerprint SHA1: 627F8D78 27656399 D27D7F90 44C9FEB3 F33EFA9A
% Do you accept this certificate? [yes/no]: yes
Trustpoint CA certificate accepted.
% Certificate successfully imported
Router(config)# end
Router(config)# wr mem

You can now check this certificate

Router#show crypto pki certificate
CA Certificate
 Status: Available
 Certificate Serial Number: 0x1
 Certificate Usage: General Purpose
 Issuer:
 e=premium-server@thawte.com
 cn=Thawte Premium Server CA
 ou=Certification Services Division
 o=Thawte Consulting cc
 l=Cape Town
 st=Western Cape
 c=ZA
 Subject:
 e=premium-server@thawte.com
 cn=Thawte Premium Server CA
 ou=Certification Services Division
 o=Thawte Consulting cc
 l=Cape Town
 st=Western Cape
 c=ZA
 Validity Date:
 start date: 01:00:00 BST Aug 1 1996
 end   date: 23:59:59 GMT Dec 31 2020
 Associated Trustpoints: thawte.com

3. Generate CSR – Begin Certificate enrollment.

This starts the process of getting your own certificate by generating a CSR or Certificate Request.

Router# conf t
Router(config)# crypto pki enroll thawte.com
% Start certificate enrollment ..
% The subject name in the certificate will include: CN=hostname.domain.com,O=Organisation,OU=Department,L=Location,ST=State,C=Country
% The subject name in the certificate will include: hostname.domain.com
Display Certificate Request to terminal? [yes/no]: yes
Certificate Request follows:
MIICDjCCAXcCAQAwgawxCzAJBgNVBAYTAkdCMQ8wDQYDVQQIEwZMb25kb24xDzAN
BgNVBAcTBkxvbmRvbjEcMBoGA1UECxMTQWNjb3VudHMgRGVwYXJ0bWVudDEdMBsG
A1UEChMUT3VyIfsjkfjsdkfhksdjfklssdfsdfsdfdsfdsWQxGzAZBgNVBAMTEnNzbHZwbi5wb2Jv
eC5jby51azEhMB8GCSqGSIb3DQEJAhYSc3NsdnBuLnBvYm94LmNvLnVrMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzlVpHnVWmZK+krq6J/R3fQwf9kceyLB8u
iis91j5EON4pMvVcKiCpJDa+kGLTSzalmKERHO4Tz6Nm53HLmCo3JGGkox+Pnv7C
oVlZu23ukAZmF0/fzfsaJkrDeWWagsDgdFseee+ffDse4XfbWVnIVqYGoWtyxdGQm3vSJ
569/tKQV5QIDAQABoCEwHwYJKoZIhvcNAQkOMRIwEDAOBgNVHQ8BAf8EBAMCBaAw
DQYJKoZIhvcNAQEEBQADgYEApaSo522bW34bcGgA5zr1uuoi2IUyV+1IBb3K+teG
RtUyrw1Z+4aVhBlsi1kSoVoLdKiUTAr5IwtEEO6pVq2uxxYvia7D1g24R5m8JN1h
HgafrfnnAvtP8EFH//0XLrdWVAUL25KtMpqjhJricWsc62CnbCiGPb/AsmaIJcBe
hxQ=
---End - This line not part of the certificate request---
Redisplay enrollment request? [yes/no]: no
Router(config)# end
Router# wr mem

Now cut out the CSR the router has generated and send it to Thawte.

4. Import Certificate

Once you have received your certificate back from Thawte you need to import it into the router.

Router# conf t
Router(config)# crypto pki import thawte.com certificate

Enter the base 64 encoded certificate.
End with a blank line or the word "quit" on a line by itself
-----BEGIN CERTIFICATE-----
MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
-----END CERTIFICATE-----
quit
Certificate has the following attributes:
 Fingerprint MD5: 069F6979 16669002 1B8C8CA2 C3076F3A
 Fingerprint SHA1: 627F8D78 27656399 D27D7F90 44C9FEB3 F33EFA9A

% Do you accept this certificate? [yes/no]: yes
Trustpoint CA certificate accepted.
% Certificate successfully imported
Router(config)# end
Router# wr mem

An you should find you have your certificate registered on your router for use as required secure website or ssl vpn.

RENEWALS:

Unless Thawte’s CA Certificate has expired or changed – it presently expires in 2020 – you only need to go through enrolment. Also your certificate will only be effected when you import the replacement.

So to renew a certificate go back to step 3 and run enrolment.

Update: Please note that in IOS Cisco are in the process of changing the command ‘crypto ca’ to ‘crypto pki’ these are presently interchangable. The commands in this note are in the new style but you could just as easily have typed ‘crypto ca trustpoint thawte.com’ for example. The config however seems to show the new format.

Using sftp on a non-standard port

Just a quick note about sftp.

It makes good security sense to change the ssh port on servers that are Internet accessable. To take advantage of this using ssh is quite straight forward as their is a parameter -p to support this eg:

ssh -p 3432 mick@mickvaites.com

Unfortunately the same is not true for sftp (secure file transfer). To achieve the same result with sftp we need to use specify an option of “Port 3432” eg:

sftp -o "Port 3432" mick@mickvaites.com

Once done log it as you would normally.

SSH Escape commands

Note to self:

These are the ssh escape commands from within an ssh connected session.

%~?
Supported escape sequences:
 ~.  - terminate connection (and any multiplexed sessions)
 ~B  - send a BREAK to the remote system
 ~C  - open a command line
 ~R  - Request rekey (SSH protocol 2 only)
 ~^Z - suspend ssh
 ~#  - list forwarded connections
 ~&  - background ssh (when waiting for connections to terminate)
 ~?  - this message
 ~~  - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

The ~ (tilda) is normally accessed by keying [shift] + [`]

To pull up the list as above send a Tilda + Question Mark ~?

Skinny CCIE IP Nat Problem [not]resolved

As mentioned in my profile I am studying for my CCIE Voice Lab exam. Well I have been plagued by a problem with phones not registering when using Rented Lab Kit and physical IP phones in my home POD.

My POD is connected to the Rented Lab Equipment over an encrypted link that is also NAT’d.

podtolabconnectivity

One of the guys from Cisco who was also studying for the exam recommended sticking to IOS 12.4 mainline. As the issue shouldn’t exist within these IOS train. Unfortuately I use a Cisco 1801 router for my connection to the Internet and there is no IOS 12.4 mainline available for it. After some experimentation I discovered that with some of the special releases solved this problem but also created others. Which basically meant keeping 4 different versions of IOS on the routers flash and switching between them depending on what I am doing.

I have just run Wireshark on a PC attached to the back of one of the phones that wasn’t registering and pulled a capture. What appears to be happening is that :

1. The phone issues a SKINNY SoftKeyTemplateReqMessage.
2. There then follows three TCP Retransmissions of SoftKeyTemptateReqMessage
3. A Skinny KeepAliveMessage
4. Two more TCP Retransmissions of SoftKeyTemplateReqMessage
5. The connection is reset.

It’s like these TCP packets are not getting through to the server which is very reminisent of an MTU/Fragmentation problem.

I’ve done some more digging in the Cisco advisories and stumbled across the following :

http://www.cisco.com/en/US/products/products_security_advisory09186a0080a0148e.shtml

This advisory indicates that in IOS Version 12.4(6)T NAT SKINNY fragmentation support was introduced. It advises that there is a vunerability in relation to memory allocation. Which can manifest as a DoS expoitation.

Wondering whether the issue advised was related to the issue I have. Considering I also have introduced Crypto into the mix.  The workaround is to disable Skinny NAT ALG support on port 2000.

Router(config)# no ip nat service skinny tcp port 2000

I’ve got some additional digging to do but on the face. Once this is done smart inspection of the SKINNY packet isn’t performed by the router so it’ neccessary to also open UDP ports for the voice calls to proceed.

So you can have the phones registering correctly – but no audio path.

I have subsequently gone back to IOS version 12.4-15.XY5.

Router#show hardw
Cisco IOS Software, C180X Software (C180X-ADVIPSERVICESK9-M), Version 12.4(15)XY5, RELEASE SOFTWARE (fc3)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2008 by Cisco Systems, Inc.
Compiled Thu 18-Dec-08 18:44 by prod_rel_team

ROM: System Bootstrap, Version 12.3(8r)YH8, RELEASE SOFTWARE (fc2)

Router uptime is 10 hours, 45 minutes
System returned to ROM by reload at 04:02:37 BST Thu May 7 2009
System restarted at 04:03:25 BST Thu May 7 2009
System image file is "flash:c180x-advipservicesk9-mz.124-15.XY5.bin"

This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.

Cisco 1801 (MPC8500) processor (revision 0x400) with 105472K/25600K bytes of memory.
Processor board ID FCZ1048121H, with hardware revision 0000

9 FastEthernet interfaces
1 ISDN Basic Rate interface
1 ATM interface
125952K bytes of ATA CompactFlash (Read/Write)
Configuration register is 0x2102

Updated 30/06/2009

Web Tunnelling over SSH

Not new information but all the same useful for either secure traffic or bypassing web cache restrictions.

First example is a socks proxy to allow you to secure web traffic over a wifi link or just avoiding web caching filters.

From unix, linux, *BSD or MacOSX type in :

ssh -N name@ssh_server -D 9999

or from windows download plink.exe from http://www.chiark.greenend.org.uk/~sgtatham/putty/ (putty.exe is also a must). The command from windows is :

plink -N -D 9999 name@ssh_server

What this does it to open an encrypted tunnel with an entry point of Localhost:9999.

Once the connection is established you then configure your web browser to use a socks proxy of Localhost port 9999. You web traffic will be tunneled over an encrypted link to the server ssh_server.

An additional security step you can use from Firefox is to get the dns resolution of the site done at the remote end instead of locally. In this way you can browse intra-net web sites over the SSH link.

For Firefox in the about:config page change network.proxy.socks_remote_dns to true

Man in the middle – ARP Poisoning on OSX

At the core of all investigation in relation to a networks is the need to sniff packets. If you have a switch with SPAN port capabilities then you can listen in from where ever you wish. However if for whatever reason this is not practical a network wiretap may be the answer.

From the PC under windows the proverbial Swiss army knife would be “Cain & Able” but on the unix front ettercap is your tool of choice.

My platform is current OSX so I have added notes of pulling down the MacPorts (see previous post for installing the environment).

To install ettercap :

sudo port install ettercap

Assuming that the default gateway on the network is 192.168.2.1 then to tap all traffic heading leaving the local LAN try the following :

sudo ettercap -T -M arp:remote /192.168.2.1/ /192.168.2.2-99/

Because you are running ettercap as root it will alter the permissions of the devices you’ll monitor from. So you need to change the permissins back so that for example Wireshark can open them. To open these devices up for Wireshark try the following:

chmod 666 /dev/bfp*

Now if you fire up Wireshark you will be able to select the relavent interface and sniff the traffic.

I found that applying an initial filter to ignore duplicate IP address messages make the view a little clearer.

Mick

Dynamic Dns on FreeBSD using Bind9

I was looking to install some remote services to my server connected to my home ADSL line. The problem I have is that I have got a dynamic IP address with my DSL line. After trying a number of the public services with varying degrees of sucess and flexibility I decided to build my own solution.

Our companies DNS servers run Bind9 and also the server I run at home also runs Bind9 which means that could use the supplied dns update service with encryption.

Three things are required to achieve this :

1. Method of getting your public IP address
2. Adding a dynamic zone to a dns server (bind9) capable of receiving secure updates
3. Scripting at the ADSL site to tie it all together.

Step 1 – Getting public IP address

There are a number of ways of achieving this – for me I setup a script to return my IP address on our companies servers. Script as follows :

<?
// getipaddress.php
if( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] )) {
    $my_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $my_ip =  $_SERVER['REMOTE_ADDR'];
}
echo $my_ip;
?>

Step 2 – Adding dynamic Zone

First you need to create a key for the zone on your DNS server :

cd /var/named/etc/namedb/
dnssec-keygen -b 512 -a HMAC-MD5 -n HOST dynamic.com

This will generate two files with names like :

Kdynamic.com.+157+34532.key
Kdynamic.com.+157+34532.private

Create the zone file dynamic.com in the dynamic folder

$ORIGIN   dynamic.com.
$TTL      3600           ; 1 hour
@         IN SOA ns.domain.com. hostmaster.domain.com. (
            2009042001   ; Serial
            900          ; refresh (15 mins)
            600          ; retry (10 mins)
            86400        ; expire (1 day)
            3600         ; min (1 hour)
            )
            NS      ns.domain.com.
$TTL      600            ; 10 mins

Add the keys and define the new zone by editing the named.conf file. For this you will need to open the .key file created using dnssec-keygen.

key "dynamic.com" { algorithm hmac-md5; secret "<key from .key file>"; };
zone "dynamic.com" {
    type master;
    file "dynamic/dynamic.com";
    allow-update { key dynamic.com; };
};

Step 3 – Scripting on the client server tying it all together

Securely transfer the two generated key/private files to you home server and place them in the folder /etc/namedb

You need to ensure you have installed the CURL library with OpenSSL support. The following script is one I use to send the updates:

#!/usr/local/bin/php -q
<?
$hostname = "dynamic.com";
$keyfile = "Kdynamic.com.+157+34532.key";
$auto_update_delay = 3600;                      // 1 Hour
$userpwd = "Username:Password";
$dns_server = "100.100.100.100";
$url = "https://myserver.com/getipaddress.php?hostname=".$hostname;
$datfile = "/home/scripts/".$hostname.".nsupdate";
$nsupdate = "/usr/bin/nsupdate -k /var/named/etc/namedb/".$keyfile;

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL,$url );
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch, CURLOPT_TIMEOUT, 30 );
curl_setopt( $ch, CURLOPT_USERPWD, $userpwd );

$response = curl_exec( $ch );
if ( curl_errno($ch) ) {
        print curl_error($ch)."n";
        exit;
} else {
        $ipaddress = curl_exec($ch);
}
if( $ipaddress == "" ) {
        echo "No ip address returnedn";
        exit;
} if ( strlen( $ipaddress ) > 15 ) {
        echo "We got garbagen";
        exit;
}
$cmds = "server ".$dns_server."n".
        "update delete ".$hostname."n".
        "update add ".$hostname." 600 A ".$ipaddress."n".
        "sendn";

$update = TRUE;
if( file_exists( $datfile )) {
        $fp = fopen( $datfile, "r" );
        if( $fp ) {
                $info = fstat( $fp );
                if( $info['ctime'] + $auto_update_delay < time()) {
                        $update = TRUE;
                } else {
                        $saved_cmds = fread( $fp, 1024 );
                        if( $cmds == $saved_cmds ) {
                                $update = FALSE;
                        }
                }
                fclose( $fp );
        }
}
if( $update == TRUE ) {
        $fp = fopen( $datfile, "w" );
        fputs( $fp, $cmds );
        fclose( $fp );
        $cli = $nsupdate." < ".$datfile;
        system( $cli );
        echo $cli."n";

        echo "Updated DNS - ".$hostname." = ".$ipaddress."n";
} else {
        echo "No change DNS - ".$hostname." = ".$ipaddress."n";
}

?>

I have called this script setipaddress.php and I have added it to my crontab and run this every two minutes.

Mick

Implementing Greylisting on FreeBSD

There are a number of ways of tackling spam coming into an ISPs mail servers each with it’s own issues.

1. Sender Verification.

Prior to an email being allowed to enter your mail server; the mail server associated with the senders domain is looked up and a “ring back” is attempted to see if the mail server would accept a reply. The idea here being that if a you receive and email and need to bounce it, you need to know that the sender really exists on the service they say they exist on.

2. Dropping protocol violators

When a connection is made to your mail server you would expect connections to follow the SMTP protocol in a way you would expect. So for example if a connection came in from a mail server to one of you inbound only MX’s and it advised you it was one of your own servers then it’s likely to be bogus. You can be very pedantic ensuring for example that the dns forward and reverse entries match. Or you can ensure that a correctly formatted HELO/EHLO message is found for example. The problem with these is that you cannot afford too many false possitives if you have paying customers expecting to receive their email.

3. Realtime black lists

One of the most successful solutions we have deployed is RBL’s particularly SPAMHaus and SpamCop. Unfortunately we were still allowing a considerable amount of spam through.

4. SpamAssassin

We found SpamAssissin to be problematic on two fronts. Firstly you had to teach it by receiving spam in the first place and secondly it hasn’t been very scaleable. I have looked at slowing the queues down so as not to overwhelm the Spam Assissin processes but this just delays email too much.

Whilst looking around for a solution to this issue I started to investigate GreyListing which appears to have two flavours.

1. Trusting a mail server to send email unless it sends too much in which case start delaying it.

2. Initially advise the inbound mail server you are too busy. Then if they come back between 5mins and 12 hours later assume they are okay and then let them in.

Since spam is really only successful by sending literally thousands (if not more) messages through in the shortest possible time. Then it doesn’t match the normal pattern of an email server. Which will try to send some email and if not successful will be more that happy to try again say every 15 mins, expanding to several hours.

Due to the robustness of the I/O in the BSD kernel I had elected to go with FreeBSD instead of Linux. And I managed to piece together a very simple Grey Listing solution that is exceptionally scaleable 2 – 4 millions inbound connections per server per day, and has proven to be very effective.

The solution consists of a number of quite simple steps:

1. Edit the /etc/rc.conf adding the following lines :

pf_enable="YES"
pflog_enable="YES"
pf_rules="/etc/pf.conf"

obspamd_enable="YES"
# options em1 in this case refers to the interface used to allow multiple boxes to communicate.
obspamd_flags="-v -G5:13:864 -y em1 -Y em1"
obspamlogd_enable="YES"

2. Install the application spamd from /usr/ports/mail/spamd as follows :

cd /usr/ports/mail/spamd
make install distclean

3. Create the file /etc/pf.conf – this is the firewall config to contain the following :

## MACROS
EXT_IF="em0"
PUBLIC_TCP_PORTS="{ 25 }"

## TABLES
table <spamd-white> persist
table <spamd-mywhite> persist file "/var/db/spamd_whitelist.txt"
## GLOBAL OPTIONS
set skip on lo0
set skip on em1  - change this to your internal interface if you have one
## TRAFFIC NORMALISATION
scrub in on $EXT_IF all fragment reassemble
scrub out on $EXT_IF all fragment reassemble random-id no-df

## TRANSLATION RULES
rdr pass inet proto tcp from <spamd-mywhite> to $EXT_IF port smtp -> 127.0.0.1 port smtp
rdr pass inet proto tcp from <spamd-white> to $EXT_IF port smtp -> 127.0.0.1 port smtp
rdr pass inet proto tcp from any to $EXT_IF port smtp -> 127.0.0.1 port spamd

## FILTER RULES
block in log on $EXT_IF all
pass in quick on $EXT_IF proto tcp from any to $EXT_IF port $PUBLIC_TCP_PORTS synproxy state
pass in quick on $EXT_IF proto icmp to $EXT_IF keep state
pass out quick on $EXT_IF proto { tcp udp icmp } all modulate state

4. Create the file /var/db/spamd_whitelist.txt to contain safe senders :

#eg:
10.0.0.0/8
172.168.0.0/12
192.168.0.0/16

5. Edit /usr/local/etc/spamd/spamd.conf adding fixed white and blacklists :

all:
:uatraps:nixspam:whitelist:

# University of Alberta greytrap hits
# Addresses stay in it for 24 hours from time they misbehave.
uatraps:
:black:
:msg="Your address %A has sent mail to a ualberta.ca spamtrapn
within the last 24 hours":
:method=http:
:file=www.openbsd.org/spamd/traplist.gz

# Nixspam recent sources list.
# Mirrored from http://www.heise.de/ix/nixspam
nixspam:
:black:
:msg="Your address %A is in the nixspam listn
See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":
:method=http:
:file=www.openbsd.org/spamd/nixspam.gz
# Whitelists are done like this, and must be added to "all" after each
# blacklist from which you want the addresses in the whitelist removed.
#
whitelist:
:white:
:method=file:
:file=/var/db/spamd_whitelist.txt:

6. Add cronjob to update spamd :

crontab -e

38 * * * *    /usr/local/sbin/spamd-setup > /dev/null 2>&1

(each server is configured at a slightly different hourly offset)

7. Amend your mail software to only listen on ip address 127.0.0.1

8. Reboot the server.

Ensure you have access to the console of the server just in case you have got you pf.conf file wrong and there by locking yourself out.

To monitor how things are going spamdb is your friend. Without parameters is will dump the current list of GREY/WHITELISTED entries and with the -a parameter it will add another address (I haven’t managed to add a network range this way to do that I needed to edit the whitelist file in /var/db).

To see how things are going :

mymx1# spamdb | cut -b 1-4 | sort | uniq -c
1200642 GREY
200318 WHIT

This shows you how many addresses are grey and how many are whitelisted.

The other command to know if pfctl a few examples of command options are as follows but it is a whole subject in it’s own right.

pfctl -t spamd-white -T show

will list the addresses in the whitelist table.

pfctl -sa

will list all the current information on what the packet filter is up to.

pfctl -sr

will list the rules

Good luck

Mick