Installation Guide for a full-featured Debian server

Featured

Here is a collection of articles I wrote during the past year. Together they form a guide that will let you setup a full-featured Debian server. All of these tutorials are based on the recent work I did to setup my personal server on Debian Squeeze.

These articles are independent with each other, meaning you can pick the one your interested in to customize your server and ignore the others.

  1. Setup SMART monitoring tool for HDDs.
  2. Setup Nut to manage the UPS.
  3. Setup Duplicity and Amazon S3 for cloud-based backups.
  4. Setup Exim to relay mails via Gmail.
  5. Setup cron-apt to keep our distribution up to date.
  6. Add a fail2ban deamon.
  7. Setup Munin to monitor our machine.
  8. Basic setup of Nginx + PHP-FPM + MySQL web stack.
  9. Optimizing Nginx + PHP-FPM + MySQL for performances.
  10. Setup PHP APC op-code cache.
  11. Install haveged to get lots of entropy.
  12. Setup a WebDAVs server with Lighttpd.
  13. Setup Mailman + Nginx + Exim for mailing-lists.
  14. Mailman mailing-list migration and merging.

Mailman migration

Last week I detailed how I configured Mailman with Exim and Nginx on a Debian Squeeze. Here are some more notes on how I migrated my mailing lists from my old server (Lenny with Mailman 2.1.11) to the new Mailman installation (Squeeze with Mailman 2.1.13).

First, I remove the default mailman meta-list as I will retrieve the one from the old server:

$ /etc/init.d/mailman stop
$ rmlist -a mailman
$ /var/lib/mailman/bin/genaliases

Then I copy mailing-list data from the old server to the new:

$ rsync --progress -vrae "ssh -C" /var/lib/mailman/lists    root@new.example.com:/var/lib/mailman/
$ rsync --progress -vrae "ssh -C" /var/lib/mailman/archives root@new.example.com:/var/lib/mailman/
$ rsync --progress -vrae "ssh -C" /var/lib/mailman/data     root@new.example.com:/var/lib/mailman/

Back to our new server, fix some rights, check all lists are there, and run the automatic update:

$ chown -R list:list /var/lib/mailman/
$ /etc/init.d/mailman start
$ list_lists
$ /var/lib/mailman/bin/update

Now let Mailman check its databases and fix permission:

$ check_db -a -v
$ check_perms -f -v

At this point you may get this error in your /var/log/exim4/mainlog:

2011-09-13 10:06:09 failed to expand condition "${lookup{$local_part@$domain}lsearch{/var/lib/mailman/data/virtual-mailman}{1}{0}}" for mailman_router router: failed to open /var/lib/mailman/data/virtual-mailman for linear search: Permission denied (euid=101 egid=103)

This can be fixed with (source):

$ chgrp Debian-exim /var/lib/mailman/data/virtual-mailman

You may also encounter this error:

2011-09-13 10:06:09 H=mail-xxx-xxxx.google.com [209.85.000.000] F=<kevin@example.com> rejected RCPT <kev-test@lists.example.com>: Unrouteable address

In this case regenerating Mailman aliases should fix the issue:

$ /var/lib/mailman/bin/genaliases

By the way, to test that Exim is routing mails as expected, your can use the following command:

$ exim -bt kev-test@lists.example.com
R: system_aliases for kev-test@lists.example.com
R: mailman_router for kev-test@lists.example.com
kev-test@lists.example.com
  router = mailman_router, transport = mailman_transport

Last problem I had was mails did not reached my server. Everytime I send something from Gmail to a list, I got back error mails saying this:

Technical details of permanent failure:
Google tried to deliver your message, but it was rejected by the recipient domain. We recommend contacting the other email provider for further information about the cause of this error. The error that the other server returned was: 550 550 relay not permitted (state 14).

I fixed this issue by updating my SPF record on the example.com domain from:

v=spf1 a mx ~all

to:

v=spf1 a mx ptr ~all

How-to setup Mailman + Nginx + Exim on Debian Squeeze

Before going further, please take note that I start this tutorial assuming that you already have a minimal Exim setup running on your Debian machine.

Mailman

Now that you have the context, let’s proceed with Mailman install:

$ aptitude install mailman

During the installation, you’ll be prompted about the languages files you want Mailman web interface support. English is enough for me.

Now Mailman requires a meta-mailing-list from which it will send all mails related to subscription, reminders and all:

$ newlist mailman kevin@deldycke.com

You’ll then be prompted for a password.

After that, Mailman will provide you with a list of directives to add to /etc/aliases:

mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"

This update is not necessary, as Exim will handle them automatically.

You can now restart the Mailman server:

$ /etc/init.d/mailman start

Oh, and the first time you’ll run Mailman, do a start as above, not a restart, else you’ll end up with this error:

Restarting Mailman master qrunner: mailmanctl PID unreadable in: /var/run/mailman/mailman.pid
[Errno 2] No such file or directory: '/var/run/mailman/mailman.pid'
Is qrunner even running?

If everything is alright, you’ll receive a mail similar to this one:

Nginx

Now we have to configure our HTTP server to make the administration interface available from the web. If Apache is the recommended server to use with Mailman, Nginx is already running on my machine, so let’s use it instead.

First, as explained on Nginx wiki we need to install fcgiwrap:

$ aptitude install fcgiwrap

Then we have to create an Nginx configuration file dedicated to Mailman. Assuming we want all mailing-lists managed under the lists.example.com domain, here are the directives you have to put in a new /etc/nginx/sites-available/mailman file:

server {
  server_name lists.example.com;

  root /usr/lib/cgi-bin;

  location = / {
    rewrite ^ /mailman/listinfo permanent;
  }

  location / {
    rewrite ^ /mailman$uri;
  }

  location /mailman {
    include /etc/nginx/fastcgi_params;
    # Fastcgi socket
    fastcgi_pass  unix:/var/run/fcgiwrap.socket;
    # Disable gzip (it makes scripts feel slower since they have to complete
    # before getting gzipped)
    gzip off;
  }

  location /images/mailman {
    alias /var/lib/mailman/icons;
  }

  location /pipermail {
    alias /var/lib/mailman/archives/public;
    autoindex on;
  }
}

server {
  server_name *.lists.example.com .lists.example.org .lists.example.net;
  rewrite ^ http://lists.example.com$request_uri? permanent;
}

The configuration above is a mix between the one available on Nginx wiki and the /usr/share/doc/fcgiwrap/examples/nginx.conf example file that come with the Debian package.

All we have to do now is to activate the configuration above and restart our CGI and HTTP server:

$ ln -s /etc/nginx/sites-available/mailman /etc/nginx/sites-enabled/
$ /etc/init.d/fcgiwrap restart
$ /etc/init.d/nginx restart

If everything’s OK, going to http://lists.example.com will show you this:

Exim

Now we have to setup the MTA. All informations here are coming from the documentation you can find on your Debian system in /usr/share/doc/mailman/README.Exim4.Debian.gz.

First, we have to update /etc/mailman/mm_cfg.py (the global Mailman configuration file). We’ll aligned there the default URLs, hosts and MTA-related parameters:

--- /etc/mailman/mm_cfg.py.orig    2011-08-31 22:28:53.000000000 +0200
+++ /etc/mailman/mm_cfg.py 2011-09-07 22:43:41.000000000 +0200
@@ -57,16 +57,16 @@
 #-------------------------------------------------------------
 # If you change these, you have to configure your http server
 # accordingly (Alias and ScriptAlias directives in most httpds)
-DEFAULT_URL_PATTERN = 'http://%s/cgi-bin/mailman/'
-PRIVATE_ARCHIVE_URL = '/cgi-bin/mailman/private'
+DEFAULT_URL_PATTERN = 'http://%s/mailman/'
+PRIVATE_ARCHIVE_URL = '/mailman/private'
 IMAGE_LOGOS         = '/images/mailman/'

 #-------------------------------------------------------------
 # Default domain for email addresses of newly created MLs
-DEFAULT_EMAIL_HOST = 'server123.example.net'
+DEFAULT_EMAIL_HOST = 'lists.example.com'
 #-------------------------------------------------------------
 # Default host for web interface of newly created MLs
-DEFAULT_URL_HOST   = 'server123.example.net'
+DEFAULT_URL_HOST   = 'lists.example.com'
 #-------------------------------------------------------------
 # Required when setting any of its arguments.
 add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
@@ -94,7 +94,10 @@
 # Uncomment if you use Postfix virtual domains (but not
 # postfix-to-mailman.py), but be sure to see
 # /usr/share/doc/mailman/README.Debian first.
-# MTA='Postfix'
+MTA = 'Postfix'
+POSTFIX_ALIAS_CMD = '/bin/true'
+POSTFIX_MAP_CMD = 'chgrp Debian-exim'
+POSTFIX_STYLE_VIRTUAL_DOMAINS = ['lists.example.com']

 #-------------------------------------------------------------
 # Uncomment if you want to filter mail with SpamAssassin. For

Then we have to update the Exim configuration template. If like me you haven’t choose to split configuration into small files, here are the modifications you have to add to /etc/exim4/exim4.conf.template:

--- /etc/exim4/exim4.conf.template.orig 2011-09-07 23:34:53.000000000 +0200
+++ /etc/exim4/exim4.conf.template       2011-09-07 23:44:45.000000000 +0200
@@ -395,6 +395,21 @@
 ### end main/03_exim4-config_tlsoptions
 #####################################################
 #####################################################
+### main/04_local_mailman_macros
+#####################################################
+# Home dir for your Mailman installation -- aka Mailman's prefix
+# directory.
+MAILMAN_HOME=/var/lib/mailman
+MAILMAN_WRAP=MAILMAN_HOME/mail/mailman
+
+# User and group for Mailman, should match your --with-mail-gid
+# switch to Mailman's configure script.
+MAILMAN_USER=list
+MAILMAN_GROUP=daemon
+#####################################################
+### end main/04_local_mailman_macros
+#####################################################
+#####################################################
 ### main/90_exim4-config_log_selector
 #####################################################

@@ -1371,6 +1386,44 @@
 ### end router/900_exim4-config_local_user
 #####################################################
 #####################################################
+### router/970_local_mailman
+#####################################################
+# Messages get sent out with
+# envelope from "mailman-bounces@virtual_domain"
+# But mailman doesn't put such addresses
+# in the aliases. Recognise these here.
+mailman_workaround:
+  debug_print = "R: mailman_workaround for $local_part@$domain"
+  domains = +local_domains
+  require_files = MAILMAN_HOME/lists/$local_part/config.pck
+  driver = accept
+  local_parts = mailman
+  local_part_suffix_optional
+  local_part_suffix = -bounces : -bounces+* : \
+           -confirm+* : -join : -leave : \
+           -subscribe : -unsubscribe : \
+           -owner : -request : -admin : -loop
+  transport = mailman_transport
+  group = MAILMAN_GROUP
+
+# Mailman lists
+mailman_router:
+  debug_print = "R: mailman_router for $local_part@$domain"
+  domains = +local_domains
+  condition = ${lookup{$local_part@$domain}lsearch{MAILMAN_HOME/data/virtual-mailman}{1}{0}}
+  require_files = MAILMAN_HOME/lists/$local_part/config.pck
+  driver = accept
+  local_part_suffix_optional
+  local_part_suffix = -bounces : -bounces+* : \
+                      -confirm+* : -join : -leave : \
+                      -subscribe : -unsubscribe : \
+                      -owner : -request : -admin : -loop
+  transport = mailman_transport
+  group = MAILMAN_GROUP
+#####################################################
+### end router/970_local_mailman
+#####################################################
+#####################################################
 ### router/mmm_mail4root
 #####################################################

@@ -1689,6 +1742,25 @@
 ### end transport/35_exim4-config_address_directory
 #####################################################
 #####################################################
+### transport/40_local_mailman
+#####################################################
+mailman_transport:
+  debug_print = "T: mailman_transport for $local_part@$domain"
+  driver = pipe
+  command = MAILMAN_WRAP \
+            '${if def:local_part_suffix \
+                  {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
+                  {post}}' \
+            $local_part
+  current_directory = MAILMAN_HOME
+  home_directory = MAILMAN_HOME
+  user = MAILMAN_USER
+  group = MAILMAN_GROUP
+  freeze_exec_fail = true
+#####################################################
+### end transport/40_local_mailman
+#####################################################
+#####################################################
 ### retry/00_exim4-config_header
 #####################################################

Don’t apply this diff as-is, as the original file contain the modifications I previously made to let Exim use Gmail to send mails.

Then we have to update the Exim meta-configuration that is stored in /etc/exim4/update-exim4.conf.conf. There we specify our host (lists.example.com) and public IP address (123.456.78.90):

dc_eximconfig_configtype='smarthost'
dc_other_hostnames='lists.example.com'
dc_local_interfaces='127.0.0.1 ; ::1 ; 123.456.78.90'
dc_readhost='lists.example.com'
dc_relay_domains='lists.example.com'
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost='smtp.gmail.com:587'
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname='false'
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'

Finally, our hostname must be a FQDN, so we have to add it to /etc/hosts:

--- /etc/hosts.orig        2011-09-12 13:52:19.000000000 +0200
+++ /etc/hosts     2011-09-12 12:21:31.000000000 +0200
@@ -1,7 +1,7 @@
 # Do not remove the following line, or various programs
 # that require network functionality will fail.
 127.0.0.1      localhost.localdomain localhost
-123.456.78.90   server123.example.net
+123.456.78.90   server123.example.net lists.example.com
 # The following lines are desirable for IPv6 capable hosts
 #(added automatically by netbase upgrade)
 ::1     ip6-localhost ip6-loopback

Then we have to regenerate Exim’s configuration before restarting Mailman:

$ update-exim4.conf --verbose
$ /etc/init.d/exim4 restart
$ /etc/init.d/mailman restart

Testing

You can now test your setup by creating a test mailing-list:

$ newlist kev-test

Now subscribe some test users and play with this mailing-list.

By monitoring /var/log/mailman/error, you’ll maybe run into this error:

IOError: [Errno 13] Permission denied: '/var/lib/mailman/archives/private/kev-test.mbox/kev-test.mbox'

This can be easily fixed with:

$ chown -R list /var/lib/mailman/archives/private/

Once you’re convinced that Mailman is working as expected, you can remove your temporary test mailing-list, and regenerate aliases to clean things up:

$ rmlist -a  kev-test
$ /var/lib/mailman/bin/genaliases

Munin monitoring

Finally, if like me you use Munin to monitor your machine, then it’s a good idea to let it graph some Mailman usage:

$ wget http://exchange.munin-monitoring.org/plugins/mailman-queue-check/version/2/download --output-document=/usr/share/munin/plugins/mailman-queue-check
$ wget http://exchange.munin-monitoring.org/plugins/mailman_subscribers/version/3/download --output-document=/usr/share/munin/plugins/mailman_subscribers
$ ln -s /usr/share/munin/plugins/mailman-queue-check /etc/munin/plugins/
$ ln -s /usr/share/munin/plugins/mailman_subscribers /etc/munin/plugins/
$ echo "[mailman*]
user root
" > /etc/munin/plugin-conf.d/mailman
$ chmod 755 /usr/share/munin/plugins/mailman*
$ /etc/init.d/munin-node restart

Configuring Fail2Ban on Debian Squeeze

This always start with a package installation:

$ aptitude install fail2ban

Then I simply create a local configuration file where I’ll put all my custom config:

$ touch /etc/fail2ban/jail.local

Here is the content of that file:

[DEFAULT]
# Do not filter connexion from my apartment and from the server itself
ignoreip  = 127.0.0.1 88.123.123.123 91.123.123.123
# Ban for a week
bantime   = 604800
maxretry  = 3
destemail = kevin@deldycke.com
banaction = iptables-allports
action    = %(action_mwl)s

[ssh]
enabled  = true
port     = 22
maxretry = 2

[ssh-ddos]
enabled = true
port     = 22

[apache]
# Apache basic auth
enabled   = true
maxretry  = 3
# Ban for 1 hour
bantime   = 3600

[apache-noscript]
enabled = true

[apache-overflows]
enabled = true

[apache-badbots]
enabled  = true
filter   = apache-badbots
port     = http,https
action   = iptables-allports
logpath  = /var/log/apache*/*access.log
maxretry = 1

[apache-nohome]
enabled  = true
filter   = apache-nohome
port     = http,https
action   = iptables-allports
logpath  = /var/log/apache*/*access.log
maxretry = 1

[exim]
enabled  = true
filter   = exim
port     = smtp,ssmtp
action   = iptables-allports
logpath  = /var/log/exim*/rejectlog
maxretry = 1

[exim-relay]
enabled  = true
filter   = exim-relay
port     = smtp,ssmtp
action   = iptables-allports
logpath  = /var/log/exim*/rejectlog
maxretry = 1

While adjusting Fail2Ban, I was surprised by how sensitive this software is. It can just refuse to start without any notice in the log or on the command line. Even if its log_level variable is set to 4 (= DEBUG) in /etc/fail2ban/fail2ban.conf.

In such a case, a sure way to find the culprit is to use a brute force debugging method: first set all the enabled variable of your jail.local‘s sections to false. Then activate one section after another until Fail2Ban refuse to restart.

For me, the problem was that I forgot to add my custom exim-relay filter to Fail2Ban. So I fixed my issue by creating an empty file at /etc/fail2ban/filter.d/exim-relay.conf in which I pasted the following content:

# Based on default exim.conf filter by Cyril Jaquier
# Real life exemaple:
# 2009-07-02 08:16:42 H=118-167-129-21.dynamic.hinet.net (91.121.198.84) [118.167.129.21] F=<titieueue@hotmail.com> rejected RCPT <s2288@mail2000.com.tw>: relay not permitted

[Definition]

# Option:  failregex
# Notes.:  regex to match use of my exim mail server as a relay it does not
#          allow.
# Values:  TEXT
#
failregex = \[<HOST>\] .*(?:relay not permitted)

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Speaking of custom filters, here is one to filter DFind scans (file located at /etc/fail2ban/filter.d/apache-w00tw00t.conf):

# Based on http://howflow.com/tricks/block_w00tw00t_scan_hosts_with_fail2ban
# Real life exemaple:
# [Sat Jun 27 16:43:08 2009] [error] [client 94.23.57.77] client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /w00tw00t.at.ISC.SANS.DFind:)

[Definition]

# Option:  failregex
# Notes.:  regex to match the w00tw00t scan messages in the logfile.
# Values:  TEXT
failregex = ^.*\[client <HOST>\].*w00tw00t\.at\.ISC\.SANS\.DFind.*

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
ignoreregex =

And here is the corresponding section from my jail.local file:

[apache-w00tw00t]
enabled  = true
filter   = apache-w00tw00t
action   = iptables-allports
logpath  = /var/log/apache*/*error.log
maxretry = 1

How-to use GMail to send mails from Debian Squeeze

Here is quick guide on how I configured Exim 4 to let a Debian Squeeze server send mails through a GMail account. This article is just a rip-off of a tutorial I found on the web, which is itself an updated version of a Debian’s Wiki page.

Debian come with Exim (v4.72) pre-installed: it’s the default MTA on this distribution. There is absolutely no need to install extra packages. Let’s start right away by calling Exim’s configuration wizard:

$ dpkg-reconfigure exim4-config

Here are the options I choose in each step of the wizard:

  1. Choose Mail sent by smarthost; received via SMTP or fetchmail.
  2. System mail name: server.deldycke.com.
  3. IP adresses to listen on for incoming SMTP connections: 127.0.0.1 ; ::1 (which is the default proposed value).
  4. Other destinations for which mail is accepted: leave blank.
  5. Machines to relay mail for: leave blank.
  6. Machine handling outgoing mail for this host (smarthost): smtp.gmail.com::587.
  7. Hide local mail name in outgoing mail: No.
  8. Keep number of DNS-queries minimal (Dial-on-Demand): No.
  9. Mailboxes format: mbox.
  10. Split configuration into small files: No.

All these parameters you just answered are saved in the /etc/exim4/update-exim4.conf.conf:

# /etc/exim4/update-exim4.conf.conf
#
# Edit this file and /etc/mailname by hand and execute update-exim4.conf
# yourself or use 'dpkg-reconfigure exim4-config'
#
# Please note that this is _not_ a dpkg-conffile and that automatic changes
# to this file might happen. The code handling this will honor your local
# changes, so this is usually fine, but will break local schemes that mess
# around with multiple versions of the file.
#
# update-exim4.conf uses this file to determine variable values to generate
# exim configuration macros for the configuration file.
#
# Most settings found in here do have corresponding questions in the
# Debconf configuration, but not all of them.
#
# This is a Debian specific file

dc_eximconfig_configtype='smarthost'
dc_other_hostnames=''
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost=''
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost='smtp.gmail.com:587'
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname='false'
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'

Then I updated the /etc/exim4/exim4.conf.template to add proper handling of GMail SMTP server. Here are the differences between the untouched original exim4.conf.template file and my version:

--- /etc/exim4/exim4.conf.template-orig  2011-05-03 10:49:43.207938577 +0200
+++ /etc/exim4/exim4.conf.template       2011-05-03 10:52:26.235438776 +0200
@@ -1077,15 +1077,11 @@
 # domains, you'll need to copy the dnslookup_relay_to_domains router
 # here so that mail to relay_domains is handled separately.

-smarthost:
-  debug_print = "R: smarthost for $local_part@$domain"
-  driver = manualroute
-  domains = ! +local_domains
-  transport = remote_smtp_smarthost
-  route_list = * DCsmarthost byname
-  host_find_failed = defer
-  same_domain_copy_routing = yes
-  no_more
+send_via_gmail:
+       driver = manualroute
+       domains = ! +local_domains
+       transport = gmail_smtp
+       route_list = * smtp.gmail.com

 .endif

@@ -1632,6 +1628,12 @@
 # to a smarthost. The local host tries to authenticate.
 # This transport is used for smarthost and satellite configurations.

+gmail_smtp:
+       driver = smtp
+       port = 587
+       hosts_require_auth = $host_address
+       hosts_require_tls = $host_address
+
 remote_smtp_smarthost:
   debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
   driver = smtp
@@ -1759,6 +1761,11 @@

 begin authenticators

+gmail_login:
+       driver = plaintext
+       public_name = LOGIN
+       client_send = : system@deldycke.com : XXXXXXXXX
+

 #####################################################
 ### end auth/00_exim4-config_header
@@ -1999,27 +2006,27 @@
                    ^${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
 .endif

-login:
-  driver = plaintext
-  public_name = LOGIN
-.ifndef AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS
-  # Return empty string if not non-TLS AND looking up $host in passwd-file
-  # yields a non-empty string; fail otherwise.
-  client_send = "<; ${if and{\
-                          {!eq{$tls_cipher}{}}\
-                          {!eq{PASSWDLINE}{}}\
-                         }\
-                      {}fail}\
-                 ; ${extract{1}{::}{PASSWDLINE}}\
-                ; ${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
-.else
-  # Return empty string if looking up $host in passwd-file yields a
-  # non-empty string; fail otherwise.
-  client_send = "<; ${if !eq{PASSWDLINE}{}\
-                      {}fail}\
-                 ; ${extract{1}{::}{PASSWDLINE}}\
-                ; ${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
-.endif
+#login:
+#  driver = plaintext
+#  public_name = LOGIN
+#.ifndef AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS
+#  # Return empty string if not non-TLS AND looking up $host in passwd-file
+#  # yields a non-empty string; fail otherwise.
+#  client_send = "<; ${if and{\
+#                          {!eq{$tls_cipher}{}}\
+#                          {!eq{PASSWDLINE}{}}\
+#                         }\
+#                      {}fail}\
+#                 ; ${extract{1}{::}{PASSWDLINE}}\
+#               ; ${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
+#.else
+#  # Return empty string if looking up $host in passwd-file yields a
+#  # non-empty string; fail otherwise.
+#  client_send = "<; ${if !eq{PASSWDLINE}{}\
+#                      {}fail}\
+#                 ; ${extract{1}{::}{PASSWDLINE}}\
+#               ; ${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
+#.endif
 #####################################################
 ### end auth/30_exim4-config_examples
 #####################################################

Now all we have to do is to regenerate Exim’s configuration and restart the mail server:

$ update-exim4.conf
$ /etc/init.d/exim4 restart

You can then send a dummy email to test your mail system:

$ mail kevin@deldycke.com
Subject: This is an exim test
.
Cc:
Null message body; hope that's ok

And check in the log that everything’s fine:

$ tail -F /var/log/exim4/mainlog
2011-05-03 10:56:32 1QHBPE-0000ne-CW <= root@server.deldycke.com U=root P=local S=362
2011-05-03 10:56:36 1QHBPE-0000ne-CW => kevin@deldycke.com R=send_via_gmail T=gmail_smtp H=gmail-smtp-msa.l.google.com [209.85.227.109] X=TLS1.0:RSA_ARCFOUR_SHA1:16 DN="C=US,ST=California,L=Mountain View,O=Google Inc,CN=smtp.gmail.com"
2011-05-03 10:56:36 1QHBPE-0000ne-CW Completed