Lead Image © Petr Vaclavek, 123RF.com

Lead Image © Petr Vaclavek, 123RF.com

Secure your data channel with stunnel

Confidential

Article from ADMIN 56/2020
By
Stunnel provides a TLS wrapper with extensive configuration options to secure your data over insecure wireless networks.

Transmitting confidential data over an insecure connection is not a good idea and should always be avoided, but what do you do if a service does not offer a secure communication channel, and no VPN is available?

Everyone will be familiar with the following situation: You are sitting comfortably in a cafe or hotel, registered on the local WiFi network, and happily browsing the Internet. However, you might not want other users of the same wireless network to be able to track your Internet usage behavior. Worse still, you come across a service that requires you to enter sensitive data, such as login credentials, but does not provide data protection through a secure TLS connection. Unfortunately, such cases can still be found in 2020. So what now?

Most Linux distributions offer the stunnel package, a TLS wrapper that lets you build a tunnel between two endpoints. The tool can operate in both client and server modes.

Preparing the Tunnel

After you have downloaded and installed the stunnel package from the distribution repository [1], you need to install the /etc/stunnel/stunnel.conf configuration file. If this is not available, sample configurations can usually be found in the documentation directory, /usr/share/doc/stunnel*/. The example in Listing 1 shows a very simple configuration that uses stunnel as a plain vanilla TLS client.

Listing 1

Stunnel as a TLS Client

; global settings
sslVersion = TLSv1.2
chroot = /var/run/stunnel
setuid = nobody
setgid = nobody
pid = /stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
CAfile = /etc/pki/tls/certs/roots.pem
verifyChain = yes
   
[gmail-smtp]
client = yes
accept = 127.0.0.1:1234
connect = smtp.gmail.com:465
checkHost = smtp.gmail.com
OCSPaia = yes

This example creates a TLS tunnel between the local computer and the Google SMTP server on port 465. On accessing the tunnel, the server's certificate chain is verified with CA certificates from the /etc/pki/tls/certs/roots.pem file. When a connection to local port 1234 on the local computer is opened, data enters the tunnel and comes out on the Google SMTP server at the other end (Listing 2).

Listing 2

Connection to a Local Port

telnet 127.0.0.1 1234
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 smtp.gmail.com ESMTP x20sm3297437wrg.52 - gsmtp
   
HELP
   
214 2.0.0 https://www.google.com/search?btnI=RFC+5321 x20sm3297437wrg.52 - gsmtp
   
QUIT
   
221 2.0.0 closing connection x20sm3297437wrg.52 - gsmtp
Connection closed by foreign host.

Things become interesting, of course, if you need to access a service that does not offer a secure connection of its own. In this case, stunnel can be operated in server mode on a secure network (e.g., on an enterprise computer to establish a tunnel endpoint there). To illustrate this scenario, the next example simply opens a connection to Google's SMTP server via port 25. Communication on this port is usually in plain text. Two stunnel instances are now required. The first instance again runs as a client on the laptop (Listing 3), and the second instance on a remote computer (Listing 4) within a secure network.

Listing 3

Client Configuration in stunnel.conf

; global settings
sslVersion = TLSv1.2
chroot = /var/run/stunnel
setuid = nobody
setgid = nobody
pid = /stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
CAfile = /etc/stunnel/stunnel.crt
verifyChain = yes
[gmail-smtp]
client = yes
accept = 127.0.0.1:1234
connect = server.example.com:1234

Listing 4

Server Configuration in stunnel.conf

; global settings
sslVersion = TLSv1.2
chroot = /var/run/stunnel
setuid = nobody
setgid = nobody
pid = /stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
cert = /etc/stunnel/stunnel.pem
CAfile = /etc/pki/tls/certs/roots.pem
verifyChain = yes
[gmail-smtp-server]
client = no
accept = 1234
connect = smtp.gmail.com:25

If you now establish a connection to local port 1234 on the client, a tunnel to the stunnel server instance is set to port 1234 on the server.example.com host. Within this tunnel, communication is secured with TLS v1.2. This host, then, establishes a connection to the target system – in this case smtp.gmail.com – over insecure port 25. In this example, it is simply a matter of protecting the client's communication on the local network (Listing 5).

Listing 5

Client Communication

telnet 127.0.0.1 1234
   
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 smtp.gmail.com ESMTP z19sm6017985wmi.7 - gsmtp
   
HELP
   
214 2.0.0 https://www.google.com/search? btnI&q=RFC+5321 z19sm6017985wmi.7 - gsmtp
KE:

stunnel Certificates

The configuration refers to an X.509 certificate in several places. On the server, you can integrate the certificate and verify the server certificate by typing

cert = /etc/stunnel/stunnel.pem
CAfile = /etc/stunnel/stunnel.crt

on the client. The certificate is used to encrypt the communication and to authenticate the stunnel server instance. For test purposes, you can create a certificate with the commands in Listing 6. In this example, the private key and the certificate are stored together in /etc/stunnel/stunnel.pem. Therefore, you need to adjust the permissions for this file restrictively.

Listing 6

Creating a Certificate

openssl genrsa -out /etc/stunnel/stunnel.key 4096
openssl req -new -x509 -key /etc/stunnel/stunnel.key -out /etc/stunnel/stunnel.crt -days 365
cat /etc/stunnel/stunnel.key /etc/stunnel/stunnel.crt > /etc/stunnel/stunnel.pem
chmod 440 /etc/stunnel/stunnel.pem

In production environments, of course, a certificate signed by a certificate authority (CA) should be used. To generate a corresponding certificate signing request (CSR), use the command:

openssl req -new -sha256 -key /etc/stunnel/stunnel.key -out /etc/stunnel/stunnel.csr

Once you have received the signed certificate back from the CA, you integrate it on the server as usual with the cert statement. On the server, use CAfile to specify the certificate from the CA to verify the server's certificate chain correctly.

Also interesting to note is that stunnel v5.09 allows you to authenticate a client with a preshared key (PSK), which means you can use access control to determine who is allowed to use the tunnel. On the server, add the following two statements to the tunnel configuration:

ciphers = PSK
PSKsecrets = /etc/stunnel/psk.txt

On the client, define the file in which the authentication keys are stored:

PSKsecrets = /etc/stunnel/psk-client1.txt

On the server, the file /etc/stunnel/psk.txt must contain all keys of all clients; an example can be seen in Listing 7.

Listing 7

Example /etc/stunnel/psk.txt

client1:Wf44zFw33FeMxCqobcA13lb28IgizxyZJOUoUsZGlkk
client2:q0eL78zFrbnESW6c/F0qit5MNCpS8IBgyh1BdXiyyuI
client3:zkq8eT31Nib3IHWfp0yyu15BCW52VMbY8+LhVUt3ylA

The client uses the appropriate password in the /etc/stunnel/psk-client1.txt file:

client1:Wf44zFw33FeMxCqobcA13lb28IgizxyZJOUoUsZGlkk

The recommendation is that when multiple clients are used, they use different keys. In this way, if one key is compromised, you do not need to change all the client configurations.

Conclusions

On public WiFi networks, stunnel is useful for protecting your data traffic from overly inquisitive users on the same network. In principle, however, the tool can also be operated on any other network to secure services that are not TLS-capable.

Infos

  1. stunnel downloads: https://www.stunnel.org/downloads.html

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus