Postfix/SASL/TLS HowTo for Debian Sid and Sarge

I”m going to split this Mini HowTo in two parts, server and client. I hope this way is much more clear. With this config, TLS support is optional. If TLS is not used, password will sent encrypted, but body mail and headers won”t, so anyone sniffing in a network could read it (unless the body is GPG encrypted, of course). It depends on your paranoia level to also want to enable TLS or not.

This HowTo has been written for Postfix and SASL present in Sarge. Current versions are postfix 2.1.4 and cyrus-sasl 2.1.18

This HowTo is somehow based in the more comprehensive, but RedHat centric, Patrick Koetter HowTo.
Anyway, I recommend you to also read it, as it can give you more hints about your configuration, or other things that can be done with this stuff.

I also recommend you to install postfix-doc package, and read around the docs it ships, in both html/ dirs in postfix/ and postfix-tls/

If you want to use PAM instead of a different user:passwd database, as described in this document, this mail can help you on setting things up.

1. Server (SMTP)

1.1. Packages

For the server part, you need to install these packages:

  • postfix-tls (even if you don”t want to enable TLS, this is the package with SASL support)
  • libsasl2-modules
  • sasl2-bin
  • openssl (only needed for TLS support. Probably you have it already installed on your system)

1.2. Configuring Postfix for SASL

I suppose here that you have a configured Postfix,
which delivers your mails properly, and it even relays mails for
clients in your own network. This configuration is made at installation
time by package postinst scripts, asking you some questions, so it
shouldn”t be very difficult for you to reach here.

For enabling SASL support in Postfix, you have to add the following lines to your /etc/postfix/main.cf file:

# SASL SUPPORT FOR CLIENTS
#
# The following options set parameters needed by Postfix to enable
# Cyrus-SASL support for authentication of mail clients.
#
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
...
smtpd_recipient_restrictions = permit_sasl_authenticated,
 permit_mynetworks,
 reject_unauth_destination

1.3. Configuring SASL

First, you have to create /etc/postfix/sasl/smtpd.conf file and put there the following lines:

pwcheck_method: auxprop
mech_list: digest-md5 cram-md5

This tells Postfix that we want to use SASL DB to store user:passwd pairs and that he must only expose digest-md5 and cram-md5
methods for authentication. I have chosen this configuration as this
allows using a different user:passwd for SMTP than for normal login in
the server (if any), and also it only uses digest-md5 and cram-md5 for authentication, which are encrypted methods, so you won”t need TLS for protecting it. Of course, you can also use saslauthd instead of sasldb (even against PAM or shadow, as user:passwd database) and login or plain, but those methods send passwd in clear, so using TLS could be considered mandatory. Even, SASL can refuse to authenticate using methods that send the password in clear, if no encryption layer is present.

Now we have to create the database. For that we must use /usr/sbin/saslpasswd2. This command creates the file /etc/sasldb2 which will contain all user:passwd pairs.

Before using the command, we need to get information we defined when we configured Postfix, the value of the realm. This value is set in smtpd_sasl_local_domain parameter in main.cf

[root@example.com]# egrep myhostname /etc/postfix/main.cf
smtpd_sasl_local_domain = $myhostname
myhostname = mail.example.com

So, in this case, mail.example.com is what we need to pass to SASL as realm when adding users. The command for making that is this:

[root@example.com]# saslpasswd2 -c -u mail.example.com -a smtpauth test

This creates user test, for task smtpauth. If you need more information read man saslpasswd2.

The file created is owned by root and nobody else has access. We will handle this by changing the file group to sasl and adding postfix user to sasl/etc/group. group in

IMPORTANT: As Postfix in Debian runs in a chroot jail out-of-the-box, we also need to make the file we have just created available in the chroot. For that we must copy that file to /var/spool/postfix/etc/, with the same permissions as before. If one day we upgrade the file in /etc and forget to upgrade the file in the chroot, Postfix will tell us in syslog.

Please check you have created the user correctly with sasldblistusers2.

[root@example root]# sasldblistusers2
test@mail.example.com: userPassword

With this, server should use advertise AUTH for clients. Reload Postfix so the changes in configuration are loaded.

[root@mail root]# /etc/init.d/postfix reload

And read what appears in /var/log/syslog

You can check that Postfix is advertising correct AUTH methods following the next steps:

[root@mail root]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is ''^]''.
220 mail.example.com ESMTP Postfix (Debian/GNU)
EHLO client.example.com
250-mail.example.com
250-PIPELINING
250-SIZE 20480000
250-ETRN
250-AUTH DIGEST-MD5 CRAM-MD5
250-AUTH=DIGEST-MD5 CRAM-MD5
250-XVERP
250 8BITMIME
QUIT
221 Bye
Connection closed by foreign host.

If you want your server to be able to deliver mail to other servers
requesting authentication, as your ISP server, you need to add to your
server’’s config files the client part of this document. Remember that
in such situation, your server is acting as a client.

1.3. Configuring TLS (optional)

For configuring TLS, you have to add to /etc/postfix/main.cf the following lines:

## TLS
#
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/postfix-key.pem
smtpd_tls_cert_file = /etc/postfix/postfix-cert.pem
smtpd_tls_CAfile = /etc/postfix/cacert.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom

Note that smtpd_tls_auth_only = yes is completely
optional. If you set it, any client which don”t use TLS will be allowed
to AUTH against the server. It’’s a good idea to set it if every client
is going to use TLS, but if you”re not sure, and as we”re encrypting
the password anyhow, you can leave this option unset.

Now you need to get these three certificates and keys. Here I”m
going to tell you how to be your own CA, and sign your own
certificates. Of course you can also ask for a certificate (and pay it)
from any commercial CA.But for a server of your own, being you own CA
is a good option. This will also allow you to issue certificates for
other services as https, imaps, …

First it’’s needed to edit the openssl config file, /etc/ssl/openssl.cnf. In this file you have to set proper defaults, in variables with _default appended. This will save you for writing a lot when creating the certificates. The most important variables are:

countryName_default          = ES
stateOrProvinceName_default  = Madrid
localityName_default         = Madrid
0.organizationName_default   = tribulaciones.org
organizationalUnitName_default  = admin

Once we have edited this, we can create our own CA. There are two scripts shipped with openssl package to help us on doing this, /usr/lib/ssl/misc/CA.pl and /usr/lib/ssl/misc/CA.sh. Both serve the same purpose, being one made in Perl and the other in Bash script language. In this HowTo we”re going to use CA.sh,
as it’’s a bit easier to understand for people who don”t know Perl, and
we”re going to make a little modification to it in the next step below.

For creating your own CA certificate, you only have to issue the next command:

[root@example:/etc/ssl]# /usr/lib/ssl/misc/CA.sh -newca
CA certificate filename (or enter to create)

Making CA certificate ...
Generating a 1024 bit RSA private key
.++++++
...++++++
writing new private key to ''./demoCA/private/./cakey.pem''
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ''.'', the field will be left blank.
-----
Country Name (2 letter code) [ES]:
State or Province Name (full name) [Madrid]:
Locality Name (eg, city) [Madrid]:
Organization Name (eg, company) [example.com]:
Organizational Unit Name (eg, section) [admin]:
Common Name (eg, YOUR name) []:Example Certficate Authority
Email Address []:admin@example.com

As you can see, defaults we set before are being used now for certificate creation. It’’s important to note here that Common Name
it is not here admin’’s or CEO’’s name, but the name of the Certificate
Authority, so please type there something appropiate. Don”t put there
either your computer fqdn, as this can mislead you when you create a
certificate for some service in that computer.

Now, your CA certificate lives in /etc/ssl/demoCA/cacert.pem, being the

private key for that CA /etc/ssl/demoCA/private/cakey.pem

Now we need to generate the server certificate. By default, those
certificates are encrypted, protected by a password. This is nice when
you take it along with you and it gets lost. But if you don”t take it
with you and cannot being lost (of course your computer can be
compromised and your certificate stolen, but then you have more
problems too) that the certificate is password protected can be
problematic for the availability of your service. Anytime you restart
your server or service, it needs to reload the certificate, and for
that it asks for the password, which means the service will hang
waiting for somebody to type it at the command prompt. This can be a
real pain if you don”t have physical access to the computer being
restarted or you”re not around when that happens. By not having
password in the certificate, the service can read it without needed
human intervention.

As by default certificates are created password protected, we need to tweak CA.sh to serve our purposes. Basically we need to pass -nodes option when we create and we sign the certificate. For that, we”re going to copy package provided CA.sh and patch it.

[root@example:/etc/ssl]# cp /usr/lib/ssl/misc/CA.sh CA-nodes.sh
[root@example:/etc/ssl]# patch -p3 < CA.patch

Where CA.patch must be the following file:

--- /usr/lib/ssl/misc/CA.sh     2004-07-26 18:36:34.000000000 +0200
+++ /etc/ssl/CA-nodes.sh        2004-08-06 14:20:57.000000000 +0200
@@ -49,13 +49,13 @@
     ;;
 -newcert)
     # create a certificate
-    $REQ -new -x509 -keyout newreq.pem -out newreq.pem $DAYS
+    $REQ -new -nodes -x509 -keyout newreq.pem -out newreq.pem $DAYS
     RET=$?
     echo "Certificate (and private key) is in newreq.pem"
     ;;
 -newreq)
     # create a certificate request
-    $REQ -new -keyout newreq.pem -out newreq.pem $DAYS
+    $REQ -new -nodes -keyout newreq.pem -out newreq.pem $DAYS
     RET=$?
     echo "Request (and private key) is in newreq.pem"
     ;;

Once we have this tool adapted to our needs, we can create our server certificate:

[root@example:/etc/ssl]# ./CA-nodes.sh -newreq
Generating a 1024 bit RSA private key
...........++++++
....................................................++++++
writing new private key to ''newreq.pem''
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ''.'', the field will be left blank.
-----
Country Name (2 letter code) [ES]:
State or Province Name (full name) [Madrid]:
Locality Name (eg, city) [Madrid]:
Organization Name (eg, company) [example.com]:
Organizational Unit Name (eg, section) [admin]:
Common Name (eg, YOUR name) []:smtp.example.com
Email Address []:postmaster@example.com
Request (and private key) is in newreq.pem

As you can notice now, Common Name is set to our server fqdn. This is needed as clients connecting to our server will check that domain name and the value in Common Name match.

And now we have to sign the certificate we have just created.

[root@example:/etc/ssl]# ./CA-nodes.sh -sign

Finally we have to copy all these certificates we have created to their proper places in /etc/postfix directory.

[root@example:/etc/ssl]# cp demoCA/cacert.pem /etc/postfix
[root@example:/etc/ssl]# cp newreq.pem /etc/postfix/postfix-key.pem
[root@example:/etc/ssl]# cp newcert.pem /etc/postfix/postfix-cert.pem
[root@example:/etc/ssl]# cd /etc/postfix

[root@example:/etc/postfix]# chown root.root postfix-key.pem ; chmod 400 postfix-key.pem

Reload Postfix, and look at the logs. No error should be printed out.

If you want your server to use also TLS when acting as a client to
other servers (i.e. when relaying mail), you need to add the stuff
described in the TLS for client part of this document to your server’’s
main.cf file. Remember that in such situation your server is now acting as a client.

2. Client

2.1. Packages

The client need these packages installed, with the same comments than for the server:

  • postfix-tls
  • libsasl2-modules
  • openssl

2.2. Configuring client Postfix for SASL

We”re going to configure Postfix so it can use SASL for authenicating agains servers asking for that. As before, I suppose here that you have your client’’s Postfix configured correctly, and uses our mail.example.com server as a relayhost.

The lines that need to be added to /etc/postfix/main.cf are:

# SASL for client side
#
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options =

The file /etc/postfix/sasl_passwd is where we are going to store our user:passwd pairs. This is a text file like this:

[root@mail postfix]# cat /etc/postfix/sasl_passwd
mail.example.com      test:testpass

As you can see this file is plain text, so you have to secure this
file a bit. We change ownership and permission to root and r/w only.

[root@mail postfix]# chown root:root /etc/postfix/sasl_passwd && chmod 600 /etc/postfix/sasl_passwd
[root@mail postfix]# ls -l /etc/postfix/sasl_passwd
-rw-------    1 root     root           32  2004-08-03 11:50 /etc/postfix/sasl_passwd

Now we have to create the sasl_passwd DB file, which is the hash table for the clear text file. We create that file with postmap command.

[root@mail postfix]# postmap hash:/etc/postfix/sasl_passwd

After this, there will be a new file called sasl_passwd.db in /etc/postfix directory.

If you change sasl_passwd file, don”t forget to run postmap. Postfix will tell you that both files are not in sync in logs.

Now you can reload Postfix
and check that everything works fine, and you can send mails to your
server, and that it delivers and relays them without problem. If you
are getting something like “No worthy mechs found”, please make sure you have installed libsasl2-modules package.

NOTE: If you have set smtpd_tls_auth_only = yes

in the server side, you need to enable TLS in the client too, as no
AUTH method will be advertised to the client unless it also uses TLS.

2.3. Configuring TLS for the client

That’’s quite simple, if you don”t want your client to issue a certificate. You only have to add the following line to /etc/postfix/main.cf

# Use TLS client side
smtp_use_tls = yes

If we want also the client to issue a certificate, these lines are needed:

smtp_tls_key_file = /etc/postfix/postfix-key.pem
smtp_tls_cert_file = /etc/postfix/postfix-cert.pem
smtp_tls_CAfile = /etc/postfix/cacert.pem

Note that those are just the same lines that we added for TLS server side, but they are named smtp_* instead of smtpd_*. This is what makes the difference in Postfix between the server and client side.

For creating client certificate we can follow the same steps
described for server certificate, but now we don”t need to create a new
CA; we can use the CA we have created for our server to sign the new
certificate.

Meta

Search



Free web hostingWeb hosting