The FreeBSD Diary

The FreeBSD Diary (TM)

Providing practical examples since 1998

If you buy from Amazon USA, please support us by using this link.
[ HOME | TOPICS | INDEX | WEB RESOURCES | BOOKS | CONTRIBUTE | SEARCH | FEEDBACK | FAQ | FORUMS ]
stunnel - another way to avoid plain text passwords --- by Mike Miller 16 November 2001
Need more help on this topic? Click here
This article has 14 comments
Show me similar articles

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.

Need more help on this topic? Click here
This article has 14 comments
Show me similar articles