Building Sendmail / Qpopper with TLS support.



Goal:

To provide the option or force users to encrypt all traffic over the Internet for mail traffic including POP/SMTP. As per RFC this is a clear text principle. Using TLS (SSL) technology that has recently been implemented in POP and SMTP daemons it provides the option to have full encryption and even certificate validation based on keys. Also SMTP to SMTP service can use this technology so end to end can be fully encrypted.

TLS mechanism
SPF stuff

Requirements:

At freshmeat.net you can lookup great other sendmail tools and add ons as any other nice Linux tools. Most of it are GNU and free/shareware. Its a great resource just try it.

Start with compiling openssl and use ./configure to configure the package and make / make install to build and install

Once openssl is installed its time to build certificates. The easy way is to run a script like:

#!/bin/sh
#
#
/bin/rm /usr/local/ssl/private/CAkey.pem
/bin/rm /usr/local/ssl/private/CAcert.pem
/bin/rm /usr/local/ssl/certs/*
/bin/rm /usr/local/ssl/MyKey.pem
/bin/rm /usr/local/ssl/MyReq.pem
/bin/rm /usr/local/ssl/MyCert.pem
/bin/rm /usr/local/ssl/index.txt
/bin/rm /usr/local/ssl/serial
/bin/touch /usr/local/ssl/index.txt
/bin/touch /usr/local/ssl/serial
echo 01 > /usr/local/ssl/serial
#
#
echo $RANDFILE
#
#
/usr/local/ssl/bin/openssl genrsa -out /usr/local/ssl/private/CAkey.pem -rand Randomdata 1024
#
/usr/local/ssl/bin/openssl req -new -x509 -days 730 -key /usr/local/ssl/private/CAkey.pem -out /usr/local/ssl/private/CAcert.pem
#
/usr/local/ssl/bin/openssl x509 -in /usr/local/ssl/private/CAcert.pem -text | more
#
/bin/cp /usr/local/ssl/private/CAcert.pem /usr/local/ssl/certs/00.pem
#
cd /usr/local/ssl/certs
#
/bin/ln -s 00.pem `/usr/local/ssl/bin/openssl x509 -hash -noout -in 00.pem`.0
#
/usr/local/ssl/bin/openssl genrsa -out /usr/local/ssl/MyKey.pem -rand Randomdata 1024
#
/usr/local/ssl/bin/openssl req -new -key /usr/local/ssl/MyKey.pem -out /usr/local/ssl/MyReq.pem
#
/usr/local/ssl/bin/openssl ca -name CA_default -keyfile /usr/local/ssl/private/CAkey.pem -in /usr/local/ssl/MyReq.pem -out /usr/local/ssl/MyCert.pem -outdir /usr/local/ssl/certs
#
# /bin/ln -s 0a.pem `/usr/local/ssl/bin/openssl x509 -in 0a.pem -hash -noout`.0
#

Ensure the directories do exist otherwise the simple script above will fail. The remove options are for testing the different options that are available depending on your openssl.conf. Also use encryption up to 1024 and not higher as it could result in errors.

A good document to refer is http://www.informatik.hu-berlin.de/~bell/Doku/Open-ssl/, which is in German but provides good documented info. Also http://www.sendmail.org/~ca/email/starttls.html is worthwhile checking. Another option is http://www.asp.ogi.edu/people/paja/linux/sendmail/ or you could try this one although its in German. Also http://www.linuxjournal.com/article.php?sid=4823 might be of interest too.

Now its time to install sasl. Just unpack the package and run ./configure and make / make install. Depending on the auth mechanism you need maybe to add or remove options. See ./configure -help for detailed info.

Once SASL is installed create a file:

/usr/local/lib/sasl/Sendmail.conf

This should contain

pwcheck_method: sasldb

For a stand alone database. If you use a standalone database make sure you fill it wih the tool saslpasswd. You can list the users and the type of validation used with sasldblistusers !
Or

pwcheck_method: shadow

To use the shadow password system. If sasldb is used ensure you created users with saslpasswd and check with sasldblistusers

pwcheck_method: pam

This will use the auth_pam if this is set active on your server. Ensure the PAM method is implemented well and check if all is operational.

Now its time to compile sendmail. Before you do you need to build your m4 file in:
xxxx/sendmail-8.12.x/devtools/Site/site.config.m4

This file should look like:
APPENDDEF(`confMAPDEF',`-DMAP_REGEX')                                           Have regular expression enabled
APPENDDEF(`confENVDEF',`-DSASL -DHASURANDOMDEV')                                Have sasl and Enable /dev/urandom
APPENDDEF(`confINCDIRS', `-I/usr/local/ssl/include')                            SSL
APPENDDEF(`confLIBDIRS', `-L/usr/local/ssl/lib')                                SSL
APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS -DMILTER')                        Use STARTTLS and MILTER 
APPENDDEF(`conf_sendmail_LIBS', `-lsasl -lssl -lcrypto -L/usr/local/ssl/lib')   Crypto libs
This will be linked into the build of sendmail.
Mind that the ` and ' are in place !

Also you need to set your sendmail.cf file as in xxxx/sendmail-8.12.x/cf/cf

Make a mc file like in:



divert(-1)
#
# Copyright (c) 1983 Eric P. Allman
# Copyright (c) 1988, 1993
#       The Regents of the University of California.  All rights reserved.
#
divert(0)
VERSIONID(`@(#)sendmail.mc      8.12.x (Linux) 20020406')
OSTYPE(linux)dnl
LOCAL_CONFIG
FEATURE(masquerade_envelope)dnl
Cwxxxxxx.thisdomain.com
FEATURE(use_cw_file)dnl
FEATURE(use_ct_file)dnl
FEATURE(nouucp, `reject')dnl
FEATURE(`virtusertable')dnl
FEATURE(`mailertable')dnl
FEATURE(`no_default_msa')dnl
FEATURE(`access_db', `hash -o -T /etc/mail/access')dnl
FEATURE(redirect)dnl
FEATURE(`always_add_domain')dnl
FEATURE(`dnsbl', `relays.osirusoft.com', `Rejected - see http://relays.osirusoft.com/')dnl
FEATURE(`dnsbl', `list.dsbl.org', `Rejected - see http://www.dsbl.org/')dnl
FEATURE(`smrsh', `/usr/sbin/smrsh')dnl
MASQUERADE_AS(thisdomain.com)dnl
define(`CERT_DIR', `MAIL_SETTINGS_DIR`'certs')dnl
define(`confCACERT_PATH', `CERT_DIR')dnl
define(`confCACERT', `CERT_DIR/CAcert.pem')dnl
define(`confSERVER_CERT', `CERT_DIR/MYcert.pem')dnl
define(`confSERVER_KEY', `CERT_DIR/MYkey.pem')dnl
define(`confCLIENT_CERT', `CERT_DIR/MYcert.pem')dnl
define(`confCLIENT_KEY', `CERT_DIR/MYkey.pem')dnl
dnl define(`confLOG_LEVEL', 14)dnl
MAILER_DEFINITIONS
MAILER(local)dnl
MAILER(smtp)dnl
TRUST_AUTH_MECH(`DIGEST-MD5 PLAIN LOGIN')dnl
define(`confAUTH_MECHANISMS',`DIGEST-MD5 PLAIN LOGIN')dnl
define(`confDEF_AUTH_INFO',`/etc/mail/auth-info')dnl
define(`confMAX_MESSAGE_SIZE',10000000)dnl
define(`confAUTO_REBUILT',false)dnl
define(`confME_TOO', True)dnl
define(`confNO_RCPT_ACTION', `add-apparently-to')dnl
define(`confEIGHT_BIT_HANDLING', pass)dnl
define(`confDEF_CHAR_SET', ISO-8859-15) 
define(`confMAX_HEADER_LENGTH',32K)dnl
define(`confMAX_MIME_HEADER_LENGTH',512)dnl
define(`confMAX_RCPTS_PER_MESSAGE',50)dnl
define(`confMAX_DAEMON_CHILDREN',30)dnl
define(`confSMTP_LOGIN_MSG',$j Maildeamon at $b)dnl
define(`confDELIVERY_MODE', `queue')dnl
define(`confPRIVACY_FLAGS',`goaway,restrictmailq,restrictqrun,noreceipts,nobodyreturn,restrictexpand,noetrn')dnl
define(`confFORWARD_PATH', `$z/.forward.$w+$h:$z/.forward+$h:$z/.forward.$w:$z/.forward')dnl
define(`confSAFE_QUEUE', `True')dnl
define(`confRRT_IMPLIES_DSN', `false')dnl
define(`MILTER', 1)dnl
INPUT_MAIL_FILTER(`cvgfilter', `S=local:/downloads/milter-tools/cvgfilter/cvgfilter.sock,T=S:10m;R:10m;E:10m')dnl
INPUT_MAIL_FILTER(`mailspy', `S=local:/downloads/milter-tools/mailspy/mailspy.sock, F=T')dnl
INPUT_MAIL_FILTER(`mimedefang', `S=local:/open/mimedefang.sock, F=T, T=S:60s;R:60s;E:5m')dnl
#
#
LOCAL_CONFIG
KParseSubjectSpace regex -a .*[ ]{6,}.
KParseSubject regex -a -f ^(ADV?[: ]|.*viagra.*)$
Kchkfrm regex -a@REJ hahaha@sexyfun.net
Kcheckaddress regex -a@MATCH (@.*[0-9]{2,}.*\..*) 
#
LOCAL_RULESETS
HSubject:	$>+CheckSubject
SCheckSubject
R$*		$: $(ParseSubject $&{currHeader} $:  $)
R$*		$: $(ParseSubjectSpace $&{currHeader} $:  $)
R		$@ OK
R$*		$#error $: 553 This is Spam $&f#
#
#
HFrom:		$>CheckFromHeader
SCheckFromHeader
R$*		$: $(chkfrm $1 $)
R@REJ		$#error $: 553 Some virus detected
#
#
SLocal_check_mail 
# check address against various regex checks 
R$*		$: $>Parse0 $>canonify $1 
R$+		$: $(checkaddress $1 $) 
R@MATCH		$#error $: 553 SpamFilter: See http://www.wsrcc.com/spam/
#
#
In this file mind the ` and ' to be placed well otherwise errors will pop up and occur.

To compile this ensure you are in the dir xxxx/sendmail-8.12.x/cf/cf and execute:

/usr/bin/m4 ../m4/cf.m4 xxxxxx.mc > sendmail.cf

This will build your config file to be used. Copy the sendmail.cf to /etc/mail also ensure other files are here that are needed as in :


-rw-r--r--    1 root     root        45056 Jun 27 21:22 access.db
-rw-r--r--    1 root     root        23756 Jun 27 21:22 access.txt
-rwx------    1 root     root           66 Jan  5 21:36 access.update
-rw-r--r--    1 root     root         3052 Jun 20 15:55 aliases
-rw-r--r--    1 root     root        24576 Jun 20 15:55 aliases.db
drwx------    2 root     root         4096 Jun 13 14:08 certs
-r--r--r--    1 bin      bin          5555 Jun 18 17:32 helpfile
-rw-r--r--    1 root     root           45 Jan  5 21:40 local-host-names
-rw-r--r--    1 root     root         4096 Jun 13 16:48 mailertable.db
-rw-r--r--    1 root     root            0 Jan  5 21:34 mailertable.txt
-rw-r--r--    1 root     root           31 May 30 11:00 relay-domains
-rw-r--r--    1 root     root        56126 Jun 18 17:06 sendmail.cf
-rw-r--r--    1 root     root           45 Mar 24  2000 sendmail.cw
-rwx------    1 root     root          299 Jan  5 23:03 sendmail.restart
-rw-r--r--    1 root     root        38631 Jun 13 17:06 submit.cf
-rw-r--r--    1 root     root           13 Jun 13 16:47 trusted-users
-rw-r--r--    1 root     root         4096 Jun 13 16:48 virtusertable.db
-rw-r--r--    1 root     root            0 Jan  5 21:35 virtusertable.txt

Ensure you do the same for the submit.cf file. Add the entries you would like in the .mc file and run it through the m4 tool as you did with the first file.

Sendmail.restart is a script that will update the files needed :

#!/bin/sh
#
/usr/sbin/makemap hash /etc/mail/access.db < /etc/mail/access.txt
/usr/sbin/makemap hash /etc/mail/virtusertable < /etc/mail/virtusertable.txt
/usr/sbin/makemap hash /etc/mail/mailertable < /etc/mail/mailertable.txt
#
/usr/bin/newaliases
#
/bin/kill -1 head -n 1 /var/run/sendmail.pid
#

Ensure your certificates are copied and renamed well according your configuration files !!!!!

If you use /etc/mail/certs ensure the rights are set well as if they are not the STARTTLS service will not startup properly and an error will be in the syslog. Ensure you have the right settings in syslog.conf. See bottom of this page.

drw-------   2 root     mail         4096 May 29 15:43 certs/

and in certs :

-rw-------   1 root     root         1289 May 29 13:33 CAcert.pem
-rw-------   1 root     root          887 May 29 13:33 CAkey.pem
-rw-------   1 root     root         3737 May 29 13:31 MYcert.pem
-rw-------   1 root     root          887 May 29 13:32 MYkey.pem
-rw-------   1 root     root          708 May 29 13:32 MYreq.pem

This way its safe and it will work. Other rights on the certs directory will result in no TLS server to be available after the last test with telnet localhost 25 STARTTLS will be not an option.

Now its time to setup the sendmail binary

Ensure you have added a user called smmsp this is needed for sendmail 8.12.s and above. Also a group called smmsp needs to be created.

Use ./Build -c to compile and ./Build install to install the binaries.

If all is installed try:

sendmail -bv -d0.4 root

It should report back STARTTLS being used.
Version 8.12.x
 Compiled with: LOG MATCHGECOS MIME7TO8 MIME8TO7 NAMED_BIND NETINET
                NETUNIX NEWDB PIPELINING SASL SCANF STARTTLS USERDB XDEBUG
Another tool to test it is :

sendmail -bs -O LogLevel=14 as described earlier but since 8.12.x it does not seem to work anymore.
Best is to simply start sendmail with fi sendmail -db -q15m and do a telnet localhost 25

sendmail -bd -q15m
root@xxxxxx:/downloads/cyrus-sasl-1.5.27#telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 xxxxxx.thisdomain.com ESMTP Sendmail 8.12.x/8.12.x; Wed, 29 Jun 2001 14:44:46 +0200
> ehlo o
250-xxxxxx.thisdomain.com Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 10000000
250-DSN
250-ETRN
250-AUTH DIGEST-MD5 PLAIN LOGIN    <<<<<<<********
250-STARTTLS   <<<<<<< *******
250-DELIVERBY
250 HELP
> quit
This means all should be done well. > is what you type in.

People running Neomail have to be carefull I was not able to get it to run yet using the new security setup of sendmail V12. In the old way sendmail was set as follows :

-r-sr-xr-x    1 root     root      1306839 Jun 18 17:32 /usr/sbin/sendmail
After you run ./Build install it will look like :
-r-xr-sr-x    1 root     smmsp     1281641 Jul 25 10:08 /usr/sbin/sendmail

For me only using the old way I was able to use neomail to its full extend. Meaning :

chown root.root /usr/sbin/sendmail
chmod 4555 /usr/sbin/sendmail

This should be oke again. If someone was able to get it to run properly with the new settings please let me know and I will add it into this small howto.

Now its time to unpack qpopper and install it. To do so create a user qpopper or any other user that will be used as user by qpopper. Configure with fi :

./configure --enable-specialauth --enable-apop=/etc/pop.auth --enable-popuid=qpopper --enable-log-login \
                   --enable-standalone --with-openssl=/usr/local/ssl --enable-timing
If all is on one line remove the '\' as this is only to interpeter the double line !

Now make and make install. Create a file /etc/popauth use popauth -init to create the database and use popauth -user username password to add. To view all users popauth -list ALL

Now a config file needs to be created located fi in /etc/mail/certs/qpop.conf

set tls-support = stls
set tls-server-cert-file = /etc/mail/certs/all

The file all is a combination of the private key plus the auth key. Ensure the directory where it is located, as the file should be owned by root and secured by 'chmod' to 600.

Just cat the file CAkey.pem to all as in

cat CAkey.pem > all

and append CAcert.pem as in

cat CAcert.pem >> all

Start qpopper with popper -l1 -p2 -f /etc/mail/certs/qpop.conf or any other switches you prefer.

If you want qpopper to start from Inetd take out the --enable-standalone in the configure command and place the above start string in the inetd.conf.

Now try Eudora/M$ outlook and enable SSL / TLS check by sending and receiving. If you sign the keys your selves than ensure you add your certificate to the list in Eudora just select the user go to properties and select last SSL info. First try a logon and after that add the certificate to the database. It should also be possible to get Sendmail to allow relay based upon a certificate but that is something I never got to work. If someone had any success here please let me know so I can try and add it here also as there is no clear documentation to be found anywhere yet about that issue.

With openssl x509 -noout -in CAcert.pem -text one can find the information to add to the access.txt as in :
CERTIssuer:/C={country code}/ST={province}/L={city}/O={organisation}/OU={department}/CN={webname}/Email={email} RELAY

Unfortunately it still brings out a verify=NO. Help would be appriciated ! Somehow Eudora does not send the CA ??

Another resource for configuring Qpopper can be found here.

Syslog

For testing ensure you have
*.warn                                          /usr/adm/syslog
in your syslog.conf to see more info for debugging purposes.

This should supply you with TLS support for SMTP (port 25) and POP (port 110)..

Some help on Milter options can be found here. Keep in mind you might need to recompile PERL to support threads.
Another good place to find tools and addons is here.

Also for Qmail there is a TLS patch that works quite well. We tested a Sendmail <=> Qmail link succesfully. The patch can be located on this website. Its runs without the need for the CA file as is required within sendmail.

If you notice any errors on this page or you have cool things to add please mail me jeepeegids.nl.



SASL2 implementation information
Email header information