HOWTO: Secure POP3/SMTP/IMAP over SSL

martinfst

Verified User
Joined
Jun 4, 2005
Messages
6
Location
Netherlands
HOWTO create a secure transmission layer for POP3 and SMTP (and IMAP)?

While switching from ISP, I not only switched from the Debian platform, but I also switched to RedHat Enterprise 3 WS. And the new box included DirectAdmin as a control panel. I have never used a CP before, so I had to find my way in DA. I like the looks of DA, but it imposes some limits on the underlying tools and utilities, which made me struggle for a while. E.g. I used Postfix as my MTA and used Courrier as my POP3 server. Both were configured to run over TLS/SSL connections, to ensure a safe connection and preventing the possibility of sniffing clear text passwords. And that's what I wanted on my new RHEL box as well.

But, DirectAdmin supports only Exim and vm-pop3d, which posed both a learning curve as well as some limitations. My new box did not have Spamassassin and no ClamAV, both essential to my setup. So I installed and configured both on my server. The only limitation I haven't solved yet is the fact that Exim/DirectAdmin does not support the maildir format, but relies on the rather the old mbox single file setup. Anyway, I used the forums at http://www.directadmin.com/forum/, as well as some Google searches to find the way to make Exim use ClamAV and Spamassassin. Mayby I'll write a howto on how I did that later.


Now that I solved these basic issues for my MTA, I wanted to secure my transport layers.

vm-pop3d is very basic and has almost no configuration options and certainly not the possibility for native support of SSL. So it became clear that I needed "stunnel" to create a secure SSL tunnel between the server and the POP/IMAP client. And of course I used Openssl to create self signed certificates. Here's what I did:

I created a certificate for my mail.domain.tld:

[root@zeus tmp]# openssl req -newkey rsa:1024 -keyout mail.domain.tld.tmp.pem -nodes -x509 -days 365 -out mail.domain.tld.tmp2.pem
Generating a 1024 bit RSA private key
...........................++++++
.................++++++
writing new private key to 'mail.domain.tld.tmp.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) [GB]:NL
State or Province Name (full name) [Berkshire]:<Your input>
Locality Name (eg, city) [Newbury]:<Your input>
Organization Name (eg, company) [My Company Ltd]:<Your input>
Organizational Unit Name (eg, section) []:<Your input>
Common Name (eg, your name or your server's hostname) []:mail.domain.tld
Email Address []: [email protected]
[root@zeus tmp]#

After entering the required data (replace domain.tld and <Your input> with your own details) this will create two files, mail.domain.tld.tmp.pem, a key file without a password and your certificate file mail.domain.tld.tmp2.pem. In order to create something useable by stunnel, I combined these two in one file:

[root@zeus tmp]# cat mail.domain.tld.tmp.pem > mail.domain.tld.pem && echo "" >> mail.domain.tld.pem && cat mail.domain.tld.tmp2.pem >> mail.domain.tld.pem

Move the file mail.domain.tld.pem to the directory /etc/stunnel/

[root@zeus tmp]# mv mail.domain.tld.pem /etc/stunnel/


Next step is to edit the stunnel.conf configuration file to define on which ports and/or IP addresses stunnel is supposed to listen on. Use your favorite text editor, which for me is 'vi'. The entries I created:

# stunnel configuration file
# Copyright by Martin Vernooij - 2005

cert = /etc/stunnel/mail.domain.tld.pem
pid = /var/run/stunnel/run/stunnel.pid
setuid = nobody
setgid = nobody

# Workaround for Eudora bug
options = DONT_INSERT_EMPTY_FRAGMENTS

# Some debugging stuff
debug = 3
output = /var/log/stunnel.log

# Some performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

# Service-level configuration

[pop3s]
accept = nnn.nnn.nnn.nnn:995
connect = 110

[imaps]
accept = nnn.nnn.nnn.nnn:993
connect = 143

[smtps]
accept = nnn.nnn.nnn.nnn:465
connect = 25

Replace nnn with the IP address you want stunnel to listen on. If you want to accept these connections on every IP address on the server, just remove everything before the port number. Beware that you have to make sure the user 'nobody' has write permissions in the directories used. stunnel will delete and create the pid file and it will try to open-extend-for-write the logfile. If you want, you can even 'chroot' stunnel, but that requires some extensive checking of which files stunnel needs and which you need to bring into the chroot-jail. The documentation of stunnel is not very helpfull for this. It only specifies /etc/hosts.allow and /etc/hosts.deny, but my tests show that's not enough. I'm still working on getting this chroot environment setup right.

Finally you need to start stunnel to make it listen to the SSL ports. Make sure if you have a firewall running (like e.g. iptables), that the required ports are allowed to accept connections.

[root@zeus tmp]# stunnel /etc/stunnel/stunnel.conf

This should start stunnel in deamon mode and running as user 'nobody'. To make sure stunnel is started whenever the server reboots, add this line to /etc/rc.d/rc.local or some other suitable location which is processed during boot time. Finally configure you mail client like Thurderbird (or MS Outlook or alikes) to use a secure SSL connection. So the mail client should state for POP3 it will use port 995 and for SMTP port 465, both SSL. And now you can sent e-mails over an encrypted connection, whithout having to fear someone sniffs your password. Beware, there is no guarantee no-one can read your e-mail! While hopping over several MTA's and while the receiptient is downloading his/her mail, it's very likely this will be done un-encrypted. If you want to further secure your mail, you should use personal certificates to sign your e-mails with your local mail client. How to do that is a completely different story.

Used tools/versions:
Redhat enterprise Linux 3
stunnel 4.04 on i386-redhat-linux-gnu PTHREAD+LIBWRAP with OpenSSL 0.9.7a Feb 19 2003
openssl 0.9.7.a
vm-pop3d POP3 Server Version 1.1.7e


Suggestions and comments are always welcome. You can reach me at martin dot vernooij at tiempo dot nl. Just remove the spaces at replace the acronyms ;-)
 
Tested it on RH 8.0 server.

Had to recompile stunnel from source, but let's just say, it was needed :D

It's working great, however Outlook Express keeps saying the cert is invalid, Outlook however tends to shut up :cool:
 
it's probably a good idea to:
1) run stunnel as an stunnel user (I installed it from FreeBSD ports and this user/group is already created), not nobody
2) beforing moving mail.domain.tld.pem to (/usr/local/)/etc/stunnel/
# chown root:stunnel mail.domain.tld.pem
# chmod 640 mail.domain.tld.pem

or change stunnel with nobody if you really want to run it as nobody

just remember that apache probably will use that user too... and this user will need to have write access to the .pid file
so any user (if you are running PHP as apache module) will be able to change that file
 
work fine on freeBSD :)
Here is the guide how I made it.

1. install stunnel from port
#cd /usr/ports/security/stunnel
#make install
(user/group stunnel will be added)

2. make cert and config file
#cd /usr/local/etc/stunnel
#openssl req -newkey rsa:1024 -keyout mail.tmp.pem -nodes -x509 -days 365 -out mail.tmp2.pem
(input your info)

#cat mail.tmp.pem > mail.pem && echo "" >> mail.pem && cat mail.tmp2.pem >> mail.pem

#nano stunnel.conf
--- File begin (dont type this line) ----
cert = /usr/local/etc/stunnel/mail.pem
chroot = /var/run/stunnel
setuid = stunnel
setgid = stunnel
pid = /stunnel.pid

# Workaround for Eudora bug
options = DONT_INSERT_EMPTY_FRAGMENTS

# Some debugging stuff
debug = 3
output = /var/log/stunnel.log

# Some performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

# Service-level configuration

[pop3s]
accept = nnn.nnn.nnn.nnn:995
connect = 110

[imaps]
accept = nnn.nnn.nnn.nnn:993
connect = 143

[smtps]
accept = nnn.nnn.nnn.nnn:465
connect = 25
--- File end (dont type this line) ----

3. Set files permission
#chown root:stunnel /usr/local/etc/stunnel/*
#chmod 440 /usr/local/etc/stunnel/*
#mkdir /var/run/stunnel
#chown stunnel:stunnel /var/run/stunnel
#chmod 750 /var/run/stunnel

4. Fix stunnel.sh
#nano /usr/local/etc/rc.d/stunnel.sh
replace pid variable
/var/run/${name}.pid
with
/var/run/${name}/${name}.pid

5. To enable stunnel at boot time
add stunnel_enable="YES" to /etc/rc.conf

Now runit
#/usr/local/etc/rc.d/stunnel.sh start
Check if it work
#/usr/local/etc/rc.d/stunnel.sh status
if not
Check /var/log/stunnel.log for details
 
Hi Martin,

I have several domains on my box with different Ips. Is it possible to SSL protect every mail.domain.tld? If so, how can I achieve this?

Thanks for your support...

Best regards.

Olivier
 
Wow, old topic kicked back up. Didn't remember ever posting in this topic, but heh :D

By default stunnel should bind to all IP's. But with only one certificate. So the certs will be wrong for the rest.


If you want all domains to have their own certificate, you'll have to switch to 1 stunnel process per domain with 1 valid certificate. Wouldn't recommend this for production use in shared hosting environment though.

Don't have any other idea's on how to realise something like that in any other way.
 
i just found out that is you configure you secure smtp like this.

you will create an open relay because exim automaticly acceps localhost.

When using smtp on port 25 is asks for authentication but with ssmtp is doesn't.


how can we fix this?
 
xsion said:
i just found out that is you configure you secure smtp like this.

you will create an open relay because exim automaticly acceps localhost.

When using smtp on port 25 is asks for authentication but with ssmtp is doesn't.


how can we fix this?

The thing is that you need Exim to automatically accept localhost for mail delivery for the DirectAdmin mails to your own email box.

So the solution is turn off stunnel's ssmtp and use Exim's ssmtp/TLS ability so that Exim can see that the incoming connection is NOT from the localhost.

Meaning, you should comment out this line in stunnel.conf:
Code:
#[smtps]
#accept = nnn.nnn.nnn.nnn:465
#connect = 25

Then go to the exim.conf and specify the following lines (where the crt and keys are your certificates and keys respectively):
Code:
tls_certificate = /etc/httpd/conf/ssl.crt/server.crt
tls_privatekey  = /etc/httpd/conf/ssl.key/server.key

tls_advertise_hosts = *
This will give you the TLS ability, which is a plain SMTP port 25 connection followed by an encrypted connection on the SMTP command STARTTLS.

If you need it to act on the legacy SSL over port 465 method where an encrypted connection starts first then SMTP commands, then you need to add the following line on exim.conf:
Code:
tls_on_connect_ports = 465
daemon_smtp_ports = 25 : 465

I hope this helps.
 
work fine on freeBSD :)
Here is the guide how I made it.

1. install stunnel from port
#cd /usr/ports/security/stunnel
#make install
(user/group stunnel will be added)

2. make cert and config file
#cd /usr/local/etc/stunnel
#openssl req -newkey rsa:1024 -keyout mail.tmp.pem -nodes -x509 -days 365 -out mail.tmp2.pem
(input your info)

#cat mail.tmp.pem > mail.pem && echo "" >> mail.pem && cat mail.tmp2.pem >> mail.pem

#nano stunnel.conf
--- File begin (dont type this line) ----
cert = /usr/local/etc/stunnel/mail.pem
chroot = /var/run/stunnel
setuid = stunnel
setgid = stunnel
pid = /stunnel.pid

# Workaround for Eudora bug
options = DONT_INSERT_EMPTY_FRAGMENTS

# Some debugging stuff
debug = 3
output = /var/log/stunnel.log

# Some performance tunings
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1

# Service-level configuration

[pop3s]
accept = nnn.nnn.nnn.nnn:995
connect = 110

[imaps]
accept = nnn.nnn.nnn.nnn:993
connect = 143

[smtps]
accept = nnn.nnn.nnn.nnn:465
connect = 25
--- File end (dont type this line) ----

3. Set files permission
#chown root:stunnel /usr/local/etc/stunnel/*
#chmod 440 /usr/local/etc/stunnel/*
#mkdir /var/run/stunnel
#chown stunnel:stunnel /var/run/stunnel
#chmod 750 /var/run/stunnel

4. Fix stunnel.sh
#nano /usr/local/etc/rc.d/stunnel.sh
replace pid variable
/var/run/${name}.pid
with
/var/run/${name}/${name}.pid

5. To enable stunnel at boot time
add stunnel_enable="YES" to /etc/rc.conf

Now runit
#/usr/local/etc/rc.d/stunnel.sh start
Check if it work
#/usr/local/etc/rc.d/stunnel.sh status
if not
Check /var/log/stunnel.log for details

Hello!


I am installing it, but have problems.

After connect to pop3/smtp have error in stunnel.log:
error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number

Any have solution?

FreeBSD-6.2
stunnel-4.20
 
Last edited:
stunnel log error

2008.10.23 10:38:47 LOG3[38011:134656000]: Error binding pop3s to 61.xx.xx.xx:995
2008.10.23 10:38:47 LOG3[38011:134656000]: bind: Address already in use (48)
 
Back
Top