LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Linux Answers > Networking
User Name
Password

Notices


By DavidPhillips at 2003-09-14 23:32
HOWTO Setup a Secure Relaying Email Server

Introduction

This HOWTO is intended to offer a secure Email server solution using your server of choice and also your Email client of choice. Virtually any client and server will work with this setup as long as they can connect to localhost. Some servers have their own built in authentication mechanism and may not need this method of securing authentication.

Retrieving email

When a client retrieves Email a connection is made to the server where the user has an account using POP or IMAP. The server must authenticate the user to know what Email is theirs.


Sending Email

Email clients establish a connection to a server using SMTP. The server will receive the Email and it will be routed to the users mailbox that it is addressed to. If the address is on another server the server will relay the Email to the server that has the users mailbox. Most SMTP servers have no authentication and simply relay Email for any user that has an ip-address in the ISP's block of addresses. Some will relay for anyone, they are known as open relays and are famous for relaying spam.

Securing Email retrieval

We are going to use SSL over secure ports. This will ensure that the connection is encrypted when the users password is sent and data is transfered. We are also going to require a client certificate to establish a connection In addition to the normal user login. An attempt to guess a username and password is useless against this setup without the client certificate.

SMTP Incoming Email

Our SMTP server needs to have two ports to connect to. The unsecure port will be open for incoming Email. We cannot restrict incoming Email mainly because we do not know who is going to send Email to our users or where the sender will be located. Our main concern is that the recipient has an account on our system. If the Email address is valid for one of our users the message is routed to their mailbox. We do not want to run an open relay server over the internet, so we will only accept Email for user accounts on the system through the unsecure port.
Secure SMTP relays

Our users who are out roaming around on the Internet may not be able to relay Email if we run a closed relay server because they will only be able to send Email to other user accounts on the server. This is why we need a secure port. We can route our users who connect to the secure port through an SSL wrapper tunnel to the localhost port 25. This way our server will allow their Email to be relayed to any destination. Our users can be at any location and still be able to relay Email through our server. Most servers are configured to only relay for localhost by default, be sure yours is setup this way. Our server listening to localhost port 25 does not care who is sending the Email it only cares who it's addressed to. We need to use an authentication method so that only our users are able to connect to the server through the secure port to prevent unauthorized use. We are going to do this with stunnel using client certificates.

Email protocols and related ports
Code:
Unsecure ports

POP3            110
IMAP            143
SMTP             25

Secure ports

POP3S           995
IMAPS           993
SMTPS           465
Using stunnel

The SSL wrapper provided by stunnel will provide a secure connection to be routed locally to the server daemons.

The stunnel packages can be downloaded from www.stunnel.org
OpenSSL can be downloaded from www.openssl.org
For rpms check www.rpmfind.net

Install them following the documentation that comes with the version you are installing. Your server also needs the mail server daemons installed.

Check regularly for security bugs in stunnel, OpenSSL, and the servers you are using and update accordingly.

Setup the servers in xinetd

Contents of the /etc/xinetd.d/pop3s script.
Code:
service pop3s
{
        disable = no
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/sbin/stunnel
        server_args     = -v3 -l/usr/sbin/ipop3d
        log_on_success  += HOST DURATION
        log_on_failure  += HOST
}
Contents of the /etc/xinetd.d/imaps script.
Code:
service imaps
{
        disable = no
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/sbin/stunnel
        server_args     = -v3 -l/usr/sbin/imapd
        log_on_success  += HOST DURATION
        log_on_failure  += HOST
}
Contents of the /etc/xinetd.d/smtps script.
Code:
service smtps
{
        disable = no
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/sbin/stunnel
        server_args     = -v3 -rlocalhost:25
        log_on_success  += HOST DURATION
        log_on_failure  += HOST
}
Using chkconfig

If you have the chkconfig utility you can use it to enable and start the servers.
Code:
/sbin/chkconfig pop3s on
/sbin/chkconfig imaps on
/sbin/chkconfig smtps on
Without chkconfig you can manually restart xinetd and the servers will start.
Code:
/sbin/service xinetd restart
Or use your distros specific method of restarting xinetd.


Using inetd.conf

If you have inetd instead of xinetd the inetd.conf file uses one line command strings to start the servers.
Code:
imaps stream tcp nowait root /usr/sbin/stunnel -v3 -l/usr/sbin/imapd
pop3s stream tcp nowait root /usr/sbin/stunnel -v3 -l/usr/sbin/ipop3d
smtps stream tcp nowait root /usr/sbin/stunnel -v3 -rlocalhost:25
Using startup scripts to run in daemon mode

If you want to use your startup scripts to run the servers in daemon mode instead of xinetd you can use these commands.
Code:
/usr/sbin/stunnel -d993 -v3 -l/usr/sbin/imapd
/usr/sbin/stunnel -d995 -v3 -l/usr/sbin/ipop3d
/usr/sbin/stunnel -d465 -v3 -rlocalhost:25
You can put the commands in your rc.local file or startup scripts.

Checking the server

Once the services are configured and started we can check to be sure they are running with netstat.
Code:
/bin/netstat -tp
Proto Recv-Q Send-Q Local Address       Foreign Address                      State                 PID/Program name
  tcp      0      0       *:imaps                   *:*                     LISTEN                     15396/xinetd
  tcp      0      0       *:pop3s                   *:*                     LISTEN                     15396/xinetd
  tcp      0      0       *:smtps                   *:*                     LISTEN                     15396/xinetd
Listed among any other servers running on tcp ports we can see our servers listed and also see that they are run by xinetd. The services should also be listed in your /etc/services file.

Firewalls

It will also be necessary to allow connections to the servers through your firewall. This is only a basic example of how to allow the connections from the Internet or external network. Be sure you have a good firewall in place to only allow the required connections. This is not by any means a complete firewall script.

Code:
$IPTABLES -N tcp_packets
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 465 -j ACCEPT
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 993 -j ACCEPT
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 995 -j ACCEPT
$IPTABLES -A tcp_packets -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A tcp_packets -p TCP -s 0/0 -j DROP
Test your rules with this command. In addition to the other rules you should see our server rules are allowing connections to the required ports.
Code:
/sbin/iptables -L
ACCEPT     tcp  --  anywhere             anywhere           tcp dpt:smtps
ACCEPT     tcp  --  anywhere             anywhere           tcp dpt:imaps
ACCEPT     tcp  --  anywhere             anywhere           tcp dpt:pop3s
You can test the server firewall online from this site. Client connections and how it works

The users connecting to our server on port 465 will be connecting to the server as if they were logged in locally on the system, and will be allowed to relay mail anywhere. For our purpose we will use a single client certificate. The server will only allow a connection if the certificate on the server matches or clients certificate. Individual certificates could also be used if you desire.

Most Email clients will support our POP3S and or IMAPS connections by simply configuring them to do so. SMTPS will vary widely amoung different clients requiring special types of certificates to be distributed and supported. Due to the many options for Email clients we are going to support all of them with a single certificate.


By using stunnel on the client to handle the secure connection your Email client will be configured to connect to localhost:port.
Code:
Client                                              Stunnel                              Server

localhost:pop3                                   < - pop3s - >                           localhost:pop3
localhost:imap                                   < - imaps - >                           localhost:imap
localhost:smtp                                   < - smtps - >                           localhost:smtp
Both client and server will have an internal local connection to the stunnel service and all communication externally will be done using SSL encryption. The POP and IMAP servers have their own authentication The SMTP server is not going to need authentication as we will be using the client certificate to verify the clients. Incoming Email from sources other than our users will come in through the normal SMTP connection to port 25 where relay will be denied, and only mail for our users will be accepted.

There are many options when it comes to client server negotiation, we are going to use a single client certificate for all clients to authenticate. The certificate will be verified by the server and if successful a connection to localhost will be allowed. Otherwise the connection is denied. A user connecting to POP or IMAP will need a certificate as well as their username and password.

Client Certificates

Our client certificate is going to be created on the server and distributed to clients. When a new certificate is to be used we can mail it out over our secure Email system. All Email that is sent to and from our users is encrypted so it's fairly safe to send the certificates through the Email system. Email coming in from or going out to a non-user is sent plain text. This is mainly due to the fact that not every server uses encryption. For this reason certificates should be only sent via secure Email or some other secure form of delivery. Our server can support multiple certificates, therefore an old certificate can still be accepted during an upgrade for a period of time and then it can be removed from the server.

Creating the client certificate

Openssl comes with the tools necessary to make client certificates, we are now going to create a client certificate on our server.
Code:
cd /usr/share/ssl/certs
make stunnel.pem
The Makefile script runs openssl like this.
Code:
umask 77 ; \
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
/usr/bin/openssl req -newkey rsa:1024 -keyout $$PEM1 -nodes -x509 -days 365 -out $$PEM2 ; \
cat $$PEM1 >  $@ ; \
echo ""    >> $@ ; \
cat $$PEM2 >> $@ ; \
The output is a key and certificate in one file.

Installing the certificate on the server

The certificate name will need to match it's hash value.
Code:
/usr/share/ssl/misc/c_hash stunnel.pem
3acde456.0 => stunnel.pem
Another method for getting the hash value.
Code:
openssl x509 -hash -noout -in stunnel.pem
3acde456
The output is the required filename, be sure to add the .0 at the end.
We will also protect the certificate by making it only readable by root.
Code:
mkdir /usr/share/ssl/trusted
chown root.root stunnel.pem
chmod 600 stunnel.pem
cp stunnel.pem /usr/share/ssl/trusted/3acde456.0

The Linux Client

If you don't have stunnel or OpenSSL on the client install it as mentioned in the server setup.

Place the client certificate in /usr/share/ssl/private and name it after the server. Protect it as we did for the servers copy.
Code:
chown root.root /usr/share/ssl/private/myserver.pem
chmod 600 /usr/share/ssl/private/myserver.pem
We need a config file in /etc/stunnel that we are going to name after the server.
Code:
/etc/stunnel/myserver.conf

client = yes
debug = debug
cert = /usr/share/ssl/private/myserver.pem
[pop3s]
accept = localhost:110
connect = myserver.com:995
[imaps]
accept = localhost:143
delay = yes
connect = myserver.com:993
[smtps]
accept = localhost:25
connect = myserver.com:465
Other servers running on the client

These are the local ports we need available.
Code:
POP  110
IMAP 143
SMTP  25
Any services running on the client that are connected to these ports will interfere with our client. Check to see if they are running and stop them if they are.

Code:
/sbin/chkconfig imap off
/sbin/chkconfig ipop3d off
/sbin/chkconfig sendmail off
/sbin/service sendmail stop
Or use your distros method to shut them down.

If you are running a server on the client then you probably have no use for this anyway. You could look into masquerading.
If you have no other choice then you can use other open ports and use an Email client that will let you change to that local port, most of them will.


Starting the Client Service

You can place the command in your startup scripts, make an initd script, or run it manually. As long as it's running when we need to send or retrieve Email using our server.
Code:
/usr/sbin/stunnel /etc/stunnel/myserver.conf
The Windows Client

Stunnel Win32 and OpenSSL binaries are freely available and are covered under the GNU GPL.
Check for the latest releases.The stunnel-4.04.exe may have a .dll extension on it, if so change it to stunnel-4.04.exe.
  • File List
    stunnel-4.04.exe
    libssl32.dll
    libeay32.dll
    myserver.conf
    myserver.pem
Create the file myserver.conf
Code:
client = yes
debug = debug
cert = myserver.pem
[pop3s]
accept = localhost:110
connect = myserver.com:995
[imaps]
accept = localhost:143
delay = yes
connect = myserver.com:993
[smtps]
accept = localhost:25
connect = myserver.com:465
If you use notepad it may append .txt to the filename by default, use double quotes around the filename to prevent this.
Code:
"myserver.conf"
Put the client certificate in the programs run folder or path stated in the config file.

The .dll files can either be in a folder together where the program will be run, your system32 folder or somewhere in the path.

On Win95 versions the program can be started using the Startup folder. On NT versions we will run it as a service. It needs to be started on boot to be available for the Email client.

Setup stunnel on NT

Create a shortcut to the .exe file. Edit the shortcut command line to read "stunnel-4.04.exe -install" and run the shortcut. The service will then be installed remove the shortcut.
Open your services management console, and start the "stunnel" service.

Setting up your Clients Email program

Create an account on the client program with an approiate name like "Super Cool Email Server".
Use the following settings, with exception of the mailserver name these are default settings.

Code:
Outgoing mailserver = localhost
Use password = no
Use encryption = no
Type = SMTP
Port = 25


[POP]
Incoming mailserver = localhost
Use encryption = no
Type = POP
Port = 110

[IMAP]
Incoming mailserver = localhost
Use encryption = no
Type = IMAP
Port = 143
On the server and Linux client you can monitor connections using tail.

Check your /etc/syslogd.conf file for the location of your log files
Code:
cat /etc/syslog.conf | grep authpriv.*
authpriv.*                                              /var/log/secure
We will relay some mail through the server from one of our clients and monitor it on the server.
Code:
tail -f /var/log/secure

Sep 11 03:48:37 myserver xinetd[17994]: START: smtps pid=20849 from=555.555.555.555
Sep 11 03:48:37 myserver stunnel[20849]: Using 'localhost.25' as tcpwrapper service name
Sep 11 03:48:37 myserver stunnel[20849]: Peer certificate location /usr/share/ssl/trusted
Sep 11 03:48:37 myserver stunnel[20849]: stunnel 3.22 on i386-redhat-linux-gnu PTHREAD+LIBWRAP with OpenSSL 
Sep 11 03:48:37 myserver stunnel[20849]: localhost.25 connected from 555.555.555.555:33799
Sep 11 03:48:37 myserver stunnel[20849]: VERIFY OK: depth=0, /C=MyCountry/ST=MyState/L=MyCity/O=MyCompany/OU=MyDivision/CN=server.com/Email=admin@server.com
Sep 11 03:48:38 myserver stunnel[20849]: Connection closed: 273 bytes sent to SSL, 442 bytes sent to socket
Sep 11 03:48:38 myserver xinetd[17994]: EXIT: smtps pid=20849 duration=1(sec)
Looks good, the certificate was used and verified. We can check the mail logs to see that relay was allowed.
Code:
Tail -f /var/log/maillog

Sep 10 22:48:37 myserver postfix/smtpd[20850]: connect from localhost[127.0.0.1]
Sep 10 22:48:37 myserver postfix/smtpd[20850]: E4E8014171: client=localhost[127.0.0.1]
Sep 10 22:48:37 myserver postfix/cleanup[20851]: E4E8014171: message-id=<1063252073.32687.2.camel@myclient.isp.com>
Sep 10 22:48:38 myserver postfix/nqmgr[19590]: E4E8014171: from=<myclient@myserver.com>, size=334, nrcpt=1 (queue active)
Sep 10 22:48:38 myserver postfix/smtpd[20850]: disconnect from localhost[127.0.0.1]
Sep 10 22:48:38 myserver postfix/smtp[20852]: E4E8014171: to=<someone@somewhere.com>, relay=some.server.com[111.111.111.111], delay=1, status=sent (250 ok ; id=2003091103480301200t8k5ie)
That's it, Enjoy!

by lenlutz on Thu, 2003-10-02 12:35
i followed this, as closely as i was able, but, had a few problems:

when i ran /bin/netstat -tp
i got nothing like what was shown

when i ran /usr/sbin/stunnel /etc/stunnel/myserver.conf
i got

Either -r, -l (or -L) option must be used

Try 'stunnel -h' for more information.

ive been really tryiing to get this to work...
using redhat 8.0

any help, is greatly apprciated... im not a newbie to unix, and
not all that new to linux, though i sure am haing some mail problems....

by DavidPhillips on Sun, 2003-10-05 11:41
what do you get when running netstat on the server?

The -t is a filter to show only tcp, -p displays the pid of the program with the connection.

you could try netstat -lp
Code:
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   
tcp        0      0 *:imaps                 *:*                     LISTEN      1117/xinetd


stunnel needs the -r or -l as used on the server to tell it how to connect. The config file contains the needed information. Be sure that the config file is correct and that the user running stunnel can access it.

I run stunnel as root

Code:
ls -l /etc/stunnel
total 4
-rw-------    1 root     root         278 Oct  5 11:14 www.conf
Code:
cat /etc/stunnel/www.conf

client = yes
debug = debug
cert = /usr/share/ssl/private/www.pem
[pop3s]
accept = localhost:110
connect = mail.dcphillips.net:995
[imaps]
accept = localhost:143
delay = yes
connect = mail.dcphillips.net:993
[smtps]
accept = localhost:25
connect =mail.dcphillips.net:465

your logs should tell you if stunnel has a problem starting, check /var/log/messages for more info on the problem.



by linuxnube on Mon, 2003-10-27 21:21
As for the windows client goes, how does this work with antivirus software that is also intercepting mail sent from the client on localhost, in order to scan outgoing mail for viruses?

-KS

by DavidPhillips on Mon, 2003-10-27 22:22
No problem as far as I have tested.

I have "Norton AV 2002" set to scan email, I also have it set to display a progress indicator when I send mail. The progress screen comes up and shows the scan as expected.


I would expect other scanners to work as expected also.

by linuxnube on Tue, 2003-11-04 15:13

by DavidPhillips on Tue, 2003-11-04 17:08
yes linuxnube it will work. the .dll files for openssl are found at stunnel.org in the download area, that's all you need on the client unless you intend to create certificates on the client. Then you would need to install openssl.

by romel on Mon, 2003-12-15 14:37
Can I setup "exim 4" mail server at "debian gnu linux 3.0" by following these instructions....I want to setp a secure mail server at debian and also a scanner for it's incoming and outgoing email....

by DavidPhillips on Mon, 2003-12-15 19:02
This document covers setting up a secure tunnel to transfer mail over. You can use it to secure any mailserver you wish.

It does not cover mailserver installation or configuration.

by romel on Tue, 2003-12-16 15:12
thanks...Now I understand...

by J_Szucs on Thu, 2004-01-01 14:22
According to the Article, one should setup stunnel and ssl on the client, too, to connect to e.g. a secure smtp server.

Fortunately, it is not so. I tested the setup and found that the mail client of Mozilla 1.5 can perfecly use the smtps server even if you do not have stunnel on the client! In my case I had a https server with client-server authentication using stunnel on the server, and, based on that setup, it took me not more than a minute to setup the new, smtps service.

Stunnel and Mozilla rock!

Thanks for the tip!


  



All times are GMT -5. The time now is 12:27 PM.

Main Menu
Advertisement
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration