stunnel – another way to avoid plain text passwords
This article was written by Mike Miller and reviewed by Robert Hough and Jim C. Nasby.
Plain text passwords are the worst! I run a personal mail server on a public network.
Every time I check my email from the office I’m sending out my password in plain text!
It’s incredibly easy for someone to set up a sniffer on the network and steal my
password. I needed a way to secure the connection between my client email program
and the mail server.
stunnel gave me the solution I was looking for. It wraps easily around any
existing tcp application. Perfect for my pop3 headache. So what is stunnel? If you
read /usr/ports/security/stunnel/pkg-descr
you’ll find:
The stunnel program is designed to work as SSL encryption wrapper between remote client and local (inetd-startable) or remote server. The concept is that having non-SSL aware daemons running on your system you can easily setup them to communicate with clients over secure SSL channel. stunnel can be used to add SSL functionality to commonly used inetd daemons like POP-2, POP-3 and IMAP servers without any changes in the programs' code.
NOTE: If you upgrade from v3 to v4, the the stunnel invocation has changed! The program no longer accepts
command-line options, but is controlled by a config file instead.
Please refer to the stunnel(8) manual page for more information.
See Upgrading to stunnel 4 for more information.
Installing stunnel
First thing to do is install stunnel. So off to the ports.
monkey# cd /usr/ports
monkey# make search key=stunnel
stunnel turns up in the security category.
monkey# cd /usr/ports/security/stunnel
monkey# make install
Towards the end of the installation, stunnel prompts me to make
a certificate file. I’m going to do this manually later, so for now I just
press ENTER at each of the prompts.
Now that stunnel is installed, it seems like a good time to read through
man stunnel.
Creating a Certificate with OpenSSL
OpenSSL is installed by default on my 4.3 install, but if you have an older version
of FreeBSD you may need to install OpenSSL from the ports first.
I’m going to create an SSL certificate to be used by stunnel when incoming
connections come in. If you’ve created certificates before for Apache, this
will be quite familiar.
monkey# openssl req -new -out mail.pem -keyout mail.pem -nodes -x509 -days 365
-----
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:Ontario
Locality Name (eg, city) []:Toronto
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Monkey Business Inc.
Organizational Unit Name (eg, section) []:Wrench Research Division
Common Name (eg, YOUR name) []:mail.monkeysinc.org
Email Address []:postmaster@monkeysinc.org
What have I just done here? I’ve asked openssl to generate a private key, and a
certificate file to along with it. Both of these are put into the mail.pem
file.
The -x509 states that I’m not requesting a certificate, but generating
one myself. -nodes prevents the certificate from being encrypted with a
key. If I didn’t include this, a passphrase would be necessary in order to decrypt and
read the certificate file. -days indicates that the certificate will expire
in 365 days, at which time I’ll need to create a new one.
I’m going to secure the certificate file so it can’t be read by anyone but root
and put it in a memorable place like /etc.
monkey# chown root:wheel mail.pem
monkey# chmod 600 mail.pem
monkey# mv ./mail.pem /etc/mail.pem
Configuring stunnel
Time to implement stunnel. It’s a good time to take a look at the rest of the man
page in stunnel if you haven’t done so, including the OPTIONS.
I’m going to need to take a look at my current inetd.conf configuration to see
what changes I’m going to need to make. This is my current line for pop3 connections.
pop3 stream tcp nowait root /usr/local/libexec/qpopper qpopper -s
To implement secured pop3 access, I’m going to add the following new line.
Note the use of ‘pop3s’ instead of ‘pop3’. If you take a look in your
/etc/services
file you should find that the pop3s service runs
on port 995. If it’s not there, add it yourself and save the change.
pop3s stream tcp nowait root /usr/local/sbin/stunnel qpopper -p /etc/mail.pem -l /usr/local/libexec/qpopper qpopper -s
Any incoming connections to the pop3s port will start up stunnel, which in turn
reads in our certificate file and runs my qpopper mail server.
Last step is to reload inetd with a quick killall -HUP inetd
and I
should be set.
Testing stunnel
First I make sure my pop3 server is still accessible on the standard pop3 port.
monkey# telnet mail.monkeysinc.org 110
Trying 127.0.0.1...
Connected to mail.monkeysinc.org.
Escape character is '^]'.
+OK Qpopper (version 4.0.3) at mail.monkeysinc.org starting.
user jimmy
+OK Password required for jimmy.
pass jimmy
+OK jimmy has 0 visible messages (0 hidden) in 0 octets.
list
+OK 0 visible messages (0 octets)
.
quit
+OK Pop server at mail.monkeysinc.org signing off.
Connection closed by foreign host.
OK everything looks like it’s working ok, now let’s try connecting on the pop3s port.
monkey# telnet mail.monkeysinc.org 995
Trying 127.0.0.1...
Connected to mail.monkeysinc.org.
Escape character is '^]'.
user jimmy
Connection closed by foreign host.
Dropped connection! Of course, I have to tunnel the client connection through stunnel
as well. stunnel can run as a daemon, redirecting incoming connections to a server
running under stunnel. To start the stunnel daemon I’ll do the following.
monkey# stunnel -c -d localhost:110 -r mail.monkeysinc.org:995
Now any connections coming in on port 110 of localhost will be redirected to
mail.monkeysinc.org on port 995 with stunnel doing all the talking on both
ends, keeping the conversation secure.
Let’s try connecting again, but this time to port 110 on localhost.
monkey# telnet localhost 110
Trying 127.0.0.1...
Connected to mail.monkeysinc.org.
Escape character is '^]'.
+OK Qpopper (version 4.0.3) at mail.monkeysinc.org starting.
user jimmy
+OK Password required for jimmy.
pass jimmy
+OK jimmy has 0 visible messages (0 hidden) in 0 octets.
list
+OK 0 visible messages (0 octets)
.
quit
+OK Pop server at mail.monkeysinc.org signing off.
Connection closed by foreign host.
Hey! That’s great. Now any pop3 clients running on that box can connect securely
to my pop3 server. I just change the pop3 server addresses in the configuration
to connect to “localhost” instead of “mail.monkeysinc.org”.
Some mail clients have native support for SSL connections, like Microsoft’s
Outlook Express. Just look under the Account Properties -> Advanced tab and check
the “Use SSL” box under the pop3 port setting.
Setting up the remote end
Reviwer Jim C. Nasby had these recommendations for configuration of the remote end of an
stunnel.
I think it would be useful to include a script for /usr/local/etc/rc.d. Here’s a script I use
for setting up the remote end:
$ cat /usr/local/etc/rc.d/stunnel.sh
#!/bin/sh
#
# A sample stunnel startup script written by martti.kuparinen@ericsson.com
#
# $FreeBSD: ports/security/stunnel/files/stunnel.sh,v 1.1 2000/07/07 19:27:27 steve Exp $
## Where is the program
STUNNEL="/usr/local/sbin/stunnel"case "$1" in
start)
${STUNNEL} -d 6660 -c -N ircs-out -r irc.distributed.net:994
#${STUNNEL} -d 993 -r localhost:imap -p /usr/local/etc/stunnel.pem
#${STUNNEL} -d 995 -r localhost:pop3 -p /usr/local/etc/stunnel.pem
;;stop)
killall `basename ${STUNNEL}`
;;*)
echo ""
echo "Usage: `basename $0` { start | stop }"
echo ""
;;
esac
You can obviously tell where I commented out the default imap and pop3
listeners. From what I’ve seen, stunnel is pretty slow when run
from inetd.