IPtables packet tagging

Posted by Nick L
Jun 02 2012

Problem: I want the kids machines to use OpenDNS, I want other machines to use regular DNS. I also have internal DNS which I want all machines to be able to use.

In the past I have used the following iptables rules (in the nat table) to enforce the kids machines to use OpenDNS:

-A PREROUTING -i $LAN -p tcp --dport $DNS -s 192.168.x.x -j DNAT --to-destination $OPENDNS
-A PREROUTING -i $LAN -p udp --dport $DNS -s 192.168.x.x -j DNAT --to-destination $OPENDNS
-A POSTROUTING -o $WAN -p tcp --dport $DNS --dst $OPENDNS -j MASQUERADE
-A POSTROUTING -o $WAN -p udp --dport $DNS --dst $OPENDNS -j MASQUERADE

These work great, but prevent the machines using the internal DNS, which makes it awkward for those machines to use internal services.

One solution might be to scrap the rules, and be able to configure dnsmasq to forward DNS to different servers for different hosts. Unfortunately it doesn't support that, and besides, I want to ensure that a machine cannot be reconfigured to point to an alternate DNS.

The Plan

What I'd like to do is have requests made to the local dnsmasq, and then subsequent requests made from dnsmasq to either go to the configured nameserver, or OpenDNS, depending on who made the original request.


Recent versions of dnsmasq support the conntrack extension. This feature allows packets to be tagged by iptables, and then dnsmasq will apply that tag to all subsequent requests that are made as a result of the original request.

  1. Inbound DNS request received from kids machine
  2. IPTables detects request, and tags packet
  3. DNS request is handled by dnsmasq
  4. If dnsmasq has no answer, it makes an onward request to the configured external DNS server...however it preserves the tag on the packet
  5. Iptables sees the tag on the outbound DNS request, and redirect the request to OpenDNS

The Rules

These rules are applied to the mangle table

-A PREROUTING -j CONNMARK --restore-mark
#For each kids machine, if a packet is not marked, and its a DNS request, mark it with KIDS_DNS
-A PREROUTING -p tcp -m mark --mark 0 --dport $DNS -s 192.168.x.x -j MARK --set-mark 99
-A PREROUTING -p udp -m mark --mark 0 --dport $DNS -s 192.168.x.x -j MARK --set-mark 99

These rules are applied to the nat table

-A OUTPUT -m mark --mark 99 -p tcp --dport $DNS -j DNAT --to-destination $OPENDNS
-A OUTPUT -m mark --mark 99 -p udp --dport $DNS -j DNAT --to-destination $OPENDNS

dnsmasq must be configured with the --conntrack option


L2TP VPN with Racoon and OpenLT2P

Posted by Nick L
Feb 12 2012

The openl2tp.org project allows Linux server admins to configure their server to accept VPN requests from windows boxes, and other clients supporting l2tp.

l2tp is desirable since its built into WindowXP (and all newer versions), so it should be possible for the average windows user to configure one of these VPNs up.

Typically VPN security may be username/password based but it is also possible to configure it with a certificate.

L2TP itself does not seem to offer any intrinsic security, it simply provides the tunneling facility to place the Windows box on the same network as the server. Security is provided by IPSec.

The following HOWTO is based upon information gleaned from the openl2tp quick start guide and other sources on the web, and about 3 days of grit an determination.

Stuff you will need

  1. A kernel built with L2TP support (CONFIG_L2TP)
  2. A kernel built with PPP support (CONFIG_PPP)
  3. A kernel built with PPP over L2TP support (CONFIG_PPPOL2TP)
  4. ippoold - This is referenced on the openl2tp page, you can get it from Sourceforge . It allows you to provide hosts with IP addresses from a pool
  5. pppd should be installed (It does not run as a service though)
  6. openl2tp packages - I built them from source for the armel arch.


We need to configure racoon to accept IPSec connections from our external windows host. Racoon supports authentication via certificate or pre-shared key. I am doing this via a preshared key since I want the solution to be usable from remote-sites where I dont have the ability/privilege to install a certificate. Currently I am supporting windows XP (however provision is there for other versions of windows, just currently untested). Once the IPSec channel is in place, the L2TP tunnel is negotiated over UDP port 1701. For L2TP the IPSec is entirely optional, and can be configured tested independently. Remember though without IPSec all comms are in the clear so you only want to tst this on the LAN.

Build and install the Debian package

The openl2tp package is not available for the debian armel platform. Building it is as simple as downloading the source and running dpkg-buildpackage from the unpacked directory. You may be required to install some build dependancies. You will need to install ppp, and both the debs generated. You will also need to enable ipsec support....

You will also have to build an ippool package. I needed to mess around with the init script to get it load, just look an the openl2tp one. I also had to make a change so it loaded configuration to start with. Depending of the version of pppd installed, you may also need to move the ippool.so into the appropriate ppp directory after installation

#cp /usr/lib/pppd/2.4.4/ippool.so /usr/lib/pppd/2.4.5/ippool.so

   log_begin_msg "Starting ippoold..."
   start-stop-daemon --start --quiet --exec $DAEMON
   log_end_msg $?
   /usr/bin/ippoolconfig $(cat /etc/ippool.conf)

The changes to the above should be incorporated into the debian package at some point....

openl2tp Configuration

Tell openl2tp we are using it with ipsec


OPENL2TPD_ARGS="-p ipsec.so"

Configure l2tp to use only port 1701, configre the allowed authentication types, and set up the IP addresses, include the ippool that will be used


tunnel profile modify profile_name=default \

ppp profile modify profile_name=default \
         use_radius=no \
         auth_pap=no \
         auth_chap=yes \
         auth_mschapv1=no \
         auth_mschapv2=no \
         auth_eap=no \
         auth_none=no \
         dns_ipaddr_pri=192.168.x.x \
         wins_ipaddr_pri=192.168.x.x \
         local_ipaddr=192.168.x.x \
         ip_pool_name=default \

We also need to config the ippool to assign an address to the connection host. I am allows up-to 10 hosts in my pool. They are getting addresses on my 192.168.x.x. LAN


pool create pool_name=default first_addr=192.168.x.Y num_addrs=10

We also need to configure our PPP chap password so that the VPN user can authenticate. This is where you configure the usernames and passwords for your VPN users. The *'s indicate we do not care about the IP addresses, it will just match on the username.

Be sure to have the correct permissions on this file, otherwise all users will be able to see the passwords


# Secrets for authentication using CHAP
# client	server	secret		IP addresses
username	*	my_password	*

With all of the above configuration in place it should be possible to make and authenticate L2TP connections to the server.....at this point they willl not be encrypted!

Racoon Configuration

Racoon is used to secure the connection using IPsec. Once the IPsec connection is set up, racoon us ised to add a policy between the hosts (generate_policy on;) which ensures all comms is secured


path pre_shared_key "/etc/racoon/psk.txt";
listen { 
isakmp N.N.N.N;
isakmp_natt N.N.N.N[4500];

padding { maximum_length 20; # maximum padding length. randomize off; # enable randomize length. strict_check off; # enable strict check. exclusive_tail off; # extract last one octet. }
remote anonymous { exchange_mode main, aggressive; doi ipsec_doi; situation identity_only; nat_traversal on; initial_contact off; passive on; nonce_size 16; proposal_check obey; generate_policy on; send_cr off; send_cert off; proposal { # Win7 pararmeters. encryption_algorithm 3des; hash_algorithm sha1; authentication_method pre_shared_key; dh_group modp1024; } proposal { # WinXP pararmeters. encryption_algorithm 3des; hash_algorithm md5; authentication_method pre_shared_key; dh_group modp1024; } proposal { # Linux clients encryption_algorithm aes; hash_algorithm sha1; authentication_method pre_shared_key; dh_group modp1024; } } sainfo anonymous { lifetime time 1 hour; encryption_algorithm aes, 3des; authentication_algorithm hmac_sha1, hmac_md5; compression_algorithm deflate; }


We are happy for this password to be used for all connections so using a '*' as the match

* some_other_password


I think this is to ensure that all L2TP comms are done only over IPsec, hence securing that connection.

   spdadd N.N.N.N/32[1701] udp -P in ipsec 

spdadd[1701] udp -P out ipsec

Windows configuration

On Windows you should add a VPN connection, and then edit its properties. On the security tab click IPSec settings and enter your pre-shared key. Configure the hostname of the server, and you should be good to go.

Categories: Debian, LinkStation, Linux

Blocking SSH Dictionary Attacks

Posted by Nick L
Dec 24 2010

If you've ever bothered looking at your system logs, you may have noticed repeated (automated) attempts from hosts attempting to gain SSH access to your box, using seemingly random (predictable/common) usernames, and perhaps some default passwords.

Dec 20 06:24:10 router sshd[18755]: Failed password for invalid user patrick from port 53485 ssh2
Dec 20 06:24:15 router sshd[18767]: Failed password for invalid user patrick from port 53683 ssh2
Dec 20 06:24:45 router sshd[18795]: Failed password for invalid user rolo from port 55169 ssh2
Dec 20 06:24:50 router sshd[18797]: Failed password for invalid user iceuser from port 55357 ssh2
Dec 21 05:37:23 router sshd[13305]: Failed password for invalid user user from port 56622 ssh2
Dec 21 05:37:28 router sshd[13307]: Failed password for invalid user admin from port 56746 ssh2
Dec 21 05:37:43 router sshd[13313]: Failed password for invalid user soni from port 57111 ssh2
Dec 21 05:37:55 router sshd[13319]: Failed password for invalid user soni from port 57362 ssh2
Dec 21 05:38:15 router sshd[13347]: Failed password for invalid user test from port 57875 ssh2
Dec 21 05:38:21 router sshd[13349]: Failed password for invalid user admin from port 57993 ssh2
Dec 21 05:38:27 router sshd[13351]: Failed password for invalid user admin from port 58133 ssh2
Dec 21 05:38:44 router sshd[13359]: Failed password for invalid user test from port 58534 ssh2
Dec 21 05:38:49 router sshd[13361]: Failed password for invalid user testuser from port 58670 ssh2
Dec 21 05:38:55 router sshd[13364]: Failed password for invalid user test123 from port 58792 ssh2
Dec 21 05:39:01 router sshd[13366]: Failed password for invalid user toor from port 58927 ssh2
Dec 21 05:39:21 router sshd[13392]: Failed password for invalid user user from port 59440 ssh2
Dec 21 05:39:26 router sshd[13394]: Failed password for invalid user admin from port 59556 ssh2
Dec 21 05:39:32 router sshd[13396]: Failed password for invalid user test from port 59665 ssh2

In the past I have always ignored these since using strong passwords, limiting users with shell access, and not exposing usernames to the outside world should provide a adequate protection. As the numbers of users on my systems has increased, and I as an admin have chosen convenient (sometimes not very obscure usernames), and left it up to users to determine their passwords, I have become more concerned about this type of attack.

Common Approaches

The obvious way to block this kind of attack is to block access to the server from the host machine, via its IP address.

As far as I can tell, their are two main approaches to blocking this kind of attack:

  1. iptables recent module - See here 
  2. Retrospective syslog monitoring - See here

The iptables solution is pretty cool, its kernel level, so a very low overhead, however it cannot differentiate between genuine (successfull) connections and illicit attempts. Depending on your threshold, you can quite easily lock yourself out of your own server (by making a number of sequential SSH connections), or allowing more attempts than you are comfortable with to prevent the previous issue.

Monitoring syslog is a more accurate solution, from the perspective of detecting whether a connection was legitimate or not, however processing log files can be expensive on high load systems, and will either require additional daemons to be run, or be run out of cron, which may mean that the attack is finished by the time the IP is blocked.

An alternative approach - rsyslog

Newer distributions come with a new syslog daemon, rsyslog, which offers some very powerful features we can use:

  1. On-the-fly message filtering
  2. Shell-script execution

We can use these features to perform similar function to the retrospective syslog monitoring, however it can be done in real-time, and without such a hefty overhead of additional daemons, and parsing the whole log file on each invocation.

Configuration of rsyslog is a bit tricky, but since its configuration format supports conventional BSD syslog notation, and a couple of other rsyslog extension formats that have been developed over the years.

First thing to note is I already have a firewall blacklist feature on my gateway, so I already have a script to call to perform the blacklist. It just requires an IP address.

For the SSH blocking, I am going to wrap this script up in another shell script, that is able to handle incorrect passwords for valid users in a slightly more gracious way...it gives you 2 chances to get your password right, before the IP is blocked. Attempts to login as an invalid user cause instant blacklist of the IP.

My wrapper script is '/usr/local/bin/sshLoginFail'

It takes two parameters - the source IP of the attempted connection, and the username for the login attempt (if its a valid username for the system)

First thing to do is define a couple of rsyslog templates which can extract the required information for the script parameters out of the log message.

The syslog messages are formatted as follows, and we need to extract the information highlighted:

  Failed password for root from port 51920 ssh2
  Invalid user oracle from

The %msg% token contains the message being processed. The first template is a regex that will extract the IP address from the 'Invalid user' message. The second uses field extraction to extract the username and the IP address.

#Invalid user - We only care about the IP address, - use a regex because there could be spaces in the username
#which would confuse us
$template SSHInvalidUser,"%msg:R,ERE,1,DFLT:from ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})--end%"

#Valid user, wrong password, extract both, to pass to our script
$template SSHValidUserFailedPassword,"%msg:F,32:7% %msg:F,32:5%"

These template are used to create the command-line parameters with which to call our script, we now need to determine when were are processing a message that needs to trigger our script.

There are two mechanisms available in rsyslog, Property-based filters and Expression-based filters. Both will do the job, but with the Expression-based filters, you can explicitly select messages that have come from sshd.

The property-based filters are commented out, but left in for completeness

#Hit on messages that come out of SSHD - ignore the Failed password for invalid user message, - Invalid user is enough
#:msg,contains,"Invalid user " ^/usr/local/bin/sshLoginFail;SSHInvalidUser
#:msg,contains,"Failed password for invalid user " ~
#:msg,contains,"Failed password for " ^/usr/local/bin/sshLoginFail;SSHValidUserFailedPassword

#Same as above but using Expression-based filters, which should be more efficient and accurate, since they will match based on facility
#and application
if $syslogfacility-text == 'auth' and $app-name == 'sshd' and $msg contains 'Invalid user ' then ^/usr/local/bin/sshLoginFail;SSHInvalidUser
if $syslogfacility-text == 'auth' and $app-name == 'sshd' and $msg contains 'Failed password for ' and not ($msg contains 'Failed password for invalid user ') then ^/usr/local/bin/sshLoginFail;SSHValidUserFailedPassword

Categories: Linux

N900 Sent Items

Posted by Nick L
Jun 20 2010

Probably the only thing about the N900 that I have found really annoying is the lack of support for the 'Standard' IMAP Sent Items feature. You know the one, where your sent mail goes after you send it.

On the N900 the email application (modest), has a local sent items folder, and it is possible to manually move the items (in bulk) to the IMAP sent items folder, but what a pain.

Anyway, since I have now got fully working server-side filtering (Sieve) I decided it should be possible to solve this problem, server-side.

Since all my outgoing mail goes via Exim, on my own server, I can work out that its being sent from the N900 (I have a different 'from' address). So I can get exim to deliver a copy of the mail to myself. Then I can get Sieve to deliver the mail to my Sent Items.

First I need to add a system filter to exim:

I add the following line to /etc/exim4/conf.d/main/02_exim4-config_options


Exim will now evaluate the rules in /etc/exim4/system.filter before routing the mail.

Create a rule:

if $sender_address is "n900_from_address@wherever.com" then unseen deliver some_local_user@here.com endif

Then add a Sieve rule:

if envelope :is "from" "n900_from_address@wherever.com" { fileinto :flags ["\\Seen"] "INBOX.Sent"; stop; }

Categories: Debian, Linux

Exim + Dovecot + Sieve + Avelsieve

Posted by Nick L
Jun 19 2010

One of the problems (and best things) with using IMAP is that you really need to have you email rules and filters server side if you intend to use more than one client.

Sieve Avelsieve , and a Thunderbird plugin .

Since the LinkStation is already short of memory and CPU I've been thinking of re-vamping the e-mail handling for quite a while.

The current configuration uses exim & courier (IMAP and POP3). I have wanted to get rid of POP3 entirely, but the lack of server-side rules made that undesirable (I don't like the idea of client-side rules, very inefficient with large messages).

Exim and Courier are currently tied together, since SMTP user authentication is currently done through the courier-authdaemon (yet another unnecessary process).

The plan is as follows:

  1. Remove the tie between Exim and Courier, this will involve making Exim authenticate using PAM.
  2. Convert users mailboxes from Courier format to Dovecot (this is only required for users with mail in their Maildir.
  3. Install and Configure Dovecot IMAP, POP3 IMAPS, and POP3S
  4. Have exim perform its local delivery using the Dovecot Local Delivery Agent (LDA)
  5. Configure Sieve
  6. Install & Configure Avelsieve

Step 1.

PAM authentication for Exim.

It turns out that the exim-heavy Debian package is already built with PAM support, so we dont have too much to do.

Create a file /etc/pam.d/exim

#%PAM-1.0 @include common-auth @include common-account @include common-session

Add Debian-exim to the shadow group

adduser Debian-exim shadow

Create the auth configuration for Exim. I am using Exim split configuration, so the configuration should go in /etc/exim4/conf.d/auth . I removed the previous auth files leaving only 00_exim4-config_header . Create a file 30_exim4-config_pam_auth .

# /etc/exim4/conf.d/auth/30_exim4-config_pam_auth login: driver = plaintext public_name = LOGIN server_prompts = "Username:: : Password::" server_condition = "${if pam{$1:$2}{1}{0}}" server_set_id = $1 .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS server_advertise_condition = ${if eq{$tls_cipher}{}{}{*}} .endif

The server is configured only to offer LOGIN authentication when the connection is encrypted, otherwise we'll have cleartext passwords flying all over the 'net.

Step 2.

Although Maildir is some kind of standard, it seems the IMAP and POP servers keep control files with the directory. If the Maildir contains mails (read or unread), it needs to be converted to work with Dovecot, otherwise the mail client will download all the mail again, and wont have a record of which mail is read and unread etc.

This process did not seem to work 100%, Thunderbird still insisted on downloading a bunch of mails, however for the most part everything was fine, and no mail was lost.

Other ideas for converting the Maildir are to copy all mails locally (to local folders in Thunderbird), recreate the Maildir, and then copy them back from Thunderbird, after Dovecot has been upgraded. The Dovecot Wiki has a number of pages on migration.

I used this script , following the instructions from here .

Step 3.

Dovecot configuration is pretty easy. The Debian packages come pre-configured with pretty much everything ready to go.

The basic Dovecot config (all comments removed) looks like this:

protocols = imap imaps pop3 pop3s

listen = * disable_plaintext_auth = no shutdown_clients = yes log_timestamp = "%Y-%m-%d %H:%M:%S "
ssl = yes ssl_cert_file = /etc/ssl/certs/CERT.crt ssl_key_file = /etc/ssl/private/PRIVATE.key
mail_location = maildir:~/Maildir
namespace private { prefix = INBOX. separator = . inbox = yes }
mail_privileged_group = mail
protocol imap { } protocol pop3 { pop3_uidl_format = %08Xu%08Xv }
protocol lda { postmaster_address = postmaster }
auth default { mechanisms = plain passdb pam { args = dovecot } userdb passwd { } user = root


It looks like we are allowing plaintext authentication....we are, however our firewall blocks the non-TLS ports from the outside world, so a plain-text password should only ever be passed on the LAN.

Step 4.

As it happens, everything should be up-and-running just fine now. Mail can be delivered, and collected, however the main thrust of this exercise is to get us into a state where we can run have Sieve rules running against received mails. The Dovecot Sieve implementation is a plugin to deliver , the Dovecot Local Delivery Agent. This means that we need to tell exim to use this program to perform local delivery.

Once again Debian make this particularly easy for us:

First create the config for exim:


dovecot_delivery: driver = pipe command = /usr/lib/dovecot/deliver message_prefix = message_suffix = log_output delivery_date_add envelope_to_add return_path_add #group = mail #mode = 0660 temp_errors = 64 : 69 : 70: 71 : 72 : 73 : 74 : 75 : 78

This defines the transport for the delivery, now we just tell exim to use this transport, edit /etc/exim4/update-exim4.conf.conf and change the dc_localdelivery setting:


Be sure to restart exim after making these changes.

At this point end-to-end functionality should be tested. Everything should be working as before.

Step 5.

After completing this step we should have 2 pieces of new functionality.

  1. Dovecot deliver should evaluate Sieve scripts during mail delivery
  2. The Dovecot daemon should listen on port 4190 for Managesieve requests, which allows us to update Sieve scripts remotely

We need to make a couple of modifications to the Dovecot configuration, dovecot.conf .

Modify the protocols line

protocols = imap imaps pop3 pop3s managesieve

This enables the managesieve protocol in Dovecot, however by default Dovecot seems to listen on port 2000. This will most likely be changed in a future versions, since IANA have assigned the port now according to this .

Add the following section to the Dovecot configuration, the make it listen on 4190:

protocol managesieve { listen = localhost:4190 }

Since I am planning only to allow script editing via Avelsieve, I have chosen to only have this listen on localhost, Change 'localhost' to a '*' for all interfaces, but you may want to confirm that the connection is such that you are not passing passwords in cleartext across the net.

Now we need to configure the Dovecot LDA to run sieve scripts:

protocol lda { postmaster_address = postmaster mail_plugins = sieve }

And configure the delivery plugin itself:

plugin { sieve=~/.dovecot.sieve sieve_dir=~/sieve }

See the Dovecot Sieve page for all of the options.

You should be able to check its working using the sieve-connect util, but thats far too much like hard work, we'll use Avelsieve.

Step 6.

Avelsieve is a plugin for SquirrelMail. The last release was over a year ago now, so I dont know how active the development is, but it looks promising enough. There is a Debian package in unstable, which seems to have everything configured.

I had to make one other modification to my system, but that may just be because of the way I am configured...

The Avelsieve client makes use of the Scriptaculous JS library, which although was installed by the Debian package, I needed to make a symlink at the root of my web server to ensure these files were loadable via HTTP.

# cd <WEBROOT>

# ln -s /usr/share/javascript/

Job Done!

Categories: Debian, Linux

NVIDIA driver in Sid

Posted by Nick L
Jun 13 2010

After updating debian sid, the propriatary NVIDIA driver no longer loads. Its because the kernel is now built with 'nouveau' support.

nouveau is an open source kernel driver for the nVidia cards. Its not quite as fully featured as the propriatary one, and since I want the 3d support, I'm stuck.


echo 'blacklist nouveau' >> /etc/modprobe.d/blacklist.conf

To prevent the nouveax module being loaded at boot

Categories: Debian

QR Code

Posted by Nick L
Jun 01 2010



Cross compiling SpamAssassin Rules

Posted by Nick L
May 30 2010

sa-compile should speed up SpamAssassin, by pre-compiling rules into Native code.

Seem like you run sa-compile once, and the debian cron job takes care of re-running sa-compile whenever the rules are updated.

Trouble for me is that the load on the NAS of the compile took it down.

Since I have the cross compilers on my desktop PC, I figured it should be possible to build the native rules there, and distribute them to all the NAS drives.

Cross compile packages installed

acid:~# dpkg --get-selections | grep -e gnueabi -e armel

binutils-arm-linux-gnueabi install cpp-4.4-arm-linux-gnueabi install gcc-4.4-arm-linux-gnueabi install gcc-4.4-arm-linux-gnueabi-base install gcc-4.4-base-armel-cross install libc6-armel-cross install libc6-dev-armel-cross install libgcc1-armel-cross install libgomp1-armel-cross install

Compile the rules into some directory

export PERL_MM_OPT="CC=arm-linux-gnueabi-gcc LD=arm-linux-gnueabi-gcc AR=arm-linux-gnueabi-ar"

sa-compile --updatedir /root/sa-updates

I'll probably use a combination of scp and incrond to distribute the rules

Categories: Debian, LinkStation, Linux

SpamAssassin timeout issue

Posted by Nick L
May 30 2010

Just been suffering from an odd SpamAssassin timeout issue. Some mails were taking forever to scan. Timing out (and being allowed thru, as per config). Running them through

spamassassin -D < blah.msg

had them scanned in about 60 secs.

Running with

spamc -c < blah.msg

was timing out after 10 minutes. strace showed the spamc client was never receiving the response from spamd, and running spamd in debug mode I could see the scan finishing after about 1 minute

Anyway, turns out default in Debian is to run the scan over port TCP/IP 783, I found changing it to a UNIX domain socket fixed the issue.

/etc/default/spamassassin OPTIONS="--create-prefs --max-children 4 --helper-home-dir --socketpath=/var/run/spamd.sock"
/etc/exim4/sa-exim.conf SAspamcSockPath: /var/run/spamd.sock #SAspamcHost: #SAspamcPort: 783

That scan now completes in under 60 secs.

Categories: Debian, Linux