Setting up Stunnel for secure communication on CentOS 5 and 6

Posted 15/03/2015 12:03

Sometimes you need to secure communication for an internet service that does not support TLS functionality. For example, I needed to perform secure file synchronization over the Internet using rsync, but it does not support TLS. I didn't want to use SSH tunneling as that requires additional security lockdown to prevent the remote user from running shell commands.

To solve this problem the tool Stunnel provides an encrypted TCP tunnel back to your un-encrypted service.

So the flow of communication would be as follows:

rsync client -> stunnel on client machine -> encrypted TLS link -> stunnel on server machine -> rsync server

My requirements for this project are as follows:

  • Support CentOS 5 and 6 clients (server would be running on CentOS 6)
  • Use at least TLSv1, but support TLSv1.1 and TLSv1.2 if client OS supports it
  • Disable SSLv3
  • Disable RC4 cipher

Installing Stunnel

The version of Stunnel that comes with CentOS 5 and 6 does not support TLSv1.1 or TLSv1.2. So straight off the bat I needed to build the latest Stunnel into an RPM. The SPEC file to do this is here. It works with both CentOS 5 and CentOS 6, although CentOS 5's OpenSSL library does not support higher than TLSv1.

To install Stunnel:

yum install stunnel

Configure a Certificate Authority

Using the EasyRSA tool from the OpenVPN project you can create your own Certificate Authority (CA).

Download the latest from EasyRSA Releases and unpack into /root.

cd /root
wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.0-rc2/EasyRSA-3.0.0-rc2.tgz
tar zxvf EasyRSA-3.0.0-rc2.tgz

Now create your new CA.

cd EasyRSA-3.0.0-rc2
./easyrsa init-pki
./easyrsa build-ca

Configure Stunnel Server

First lets create a certificate for this server. You will need to enter the password you set for your CA key in the previous step.

./easyrsa build-server-full {your server hostname} nopass

Now copy the CA cert, server key and server cert into /etc/stunnel and secure the permissions on the private key file.

cp pki/ca.crt /etc/stunnel/
cp pki/private/{your server hostname}.key /etc/stunnel/
cp pki/issued/{your server hostname}.crt /etc/stunnel/
chmod 600 /etc/stunnel/*.key

Now create /etc/stunnel/stunnel.conf file containing:

client = no
foreground = yes
syslog = yes
debug = 6

[rsyncd]
accept = :::1873
connect = 127.0.0.1:873
cert = /etc/stunnel/stunnel.pem
CAfile = /etc/stunnel/ca.crt
cert = /etc/stunnel/{your server hostname}.crt
key = /etc/stunnel/{your server hostname}.key
ciphers = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PS
sslVersion = all
options = NO_SSLv2
options = NO_SSLv3
options = CIPHER_SERVER_PREFERENCE

The config file specifies a list of ciphers that are currently deemed secure using Mozilla's SSL Config Generator. Although at time of reading this list may have changed.

You should now be able to start stunnel in the foreground for testing by running:

stunnel

Use your favorite process manager (upstart, supervisord etc to run the program in the background).

Configure Stunnel Client

On your client machine install stunnel and copy the ca.crt file into /etc/stunnel, then create the stunnel.conf file:
client = yes
foreground = yes

[rsyncd]
accept = :::873
connect = {your server hostname}:1873
CAfile = /etc/stunnel/ca.crt
sslVersion = all
options = NO_SSLv2
options = NO_SSLv3
verify = 2

You should now be able to start stunnel in the foreground for testing by running:

stunnel

To test this is working try connecting rsync to 127.0.0.1 and it should copy the files from the remote server.