What is Stunnel and how do you configure it?

What is Stunnel and how do you configure it?

Open source Published on 4 mins Last updated

At Loadbalancer.org we love open source. It exposes us to great software such as Stunnel. And, if you're using our load balancer appliance, you may well want to use it to add TLS encryption to your service, without the need for any code changes.

Here I'll explain how you can use Stunnel to secure not only your web servers, but also any TCP-based service.

What is Stunnel?

Stunnel is a piece of software that has the unique ability to "wrap" various services in TLS, offering an additional layer of encryption and functionality. It listens on the port specified in its configuration file, encrypts the communication with the client, and forwards the data to the original daemon listening on its usual port.

As such, Stunnel's architecture is finely tuned for security, portability, and scalability, making it an ideal choice for large-scale deployments. And, while its utility extends beyond this, many users leverage Stunnel for SSL/TLS termination on our Loadbalancer.org appliance.

Stunnel v NGINX reverse proxy

For what it's worth, if you're wondering whether you should consider using NGINX instead as your TLS-terminating reverse proxy, here are a few points to consider:

When to use Stunnel

  • Pros: Lightweight for basic needs, good for non-HTTP protocols.
  • Cons: Doesn't provide load balancing capabilities, but can also be used as a client.

When to use NGINX

  • Pros: A high performance web server with strong TLS termination, offering caching, and load-balancing
  • Cons: It requires more resources.

Where does that leave you?

My suggestion would be to choose Stunnel for basic TLS termination with few apps and limited resources. Less is more, after all!

And choose NGINX for most web servers where TLS termination is needed alongside features like caching and load balancing.

It also depends on which software you're more accustomed to, as well as which works better for what you need to achieve.

Anyway. For the purposes of this blog I'm going to assume you're using Stunnel...

Getting started with Stunnel software

The first step towards Stunnel configuration involves installing Stunnel on your server. You can download Stunnel here if you don't already have it.

Next, follow these steps (note, that the installation process may differ depending on your Linux distribution):

# RHEL and derivatives

yum install stunnel

# Debian and derivatives

apt install stunnel

# Alpine Linux

apk add stunnel

After the installation, you should then be able to locate the Stunnel configuration at:

/etc/stunnel/stunnel.conf

Stunnel configuration

Stunnel configuration requires you to edit the text file to include some general configurations, as well as the configuration for particular services.

Global configuration options

I recommend that you drop root privileges if Stunnel is started by the root user:

setuid = stunnel

setgid = stunnel

If it's enabled, A PID file is then created inside the chroot jail:

pid = /var/run/stunnel.pid

Debugging and logging options such as these can also be useful for troubleshooting:

foreground = yes

debug = info

output = /var/log/stunnel.log

If you need to enable support for the insecure SSLv3 protocol, then use this (although very few people should need this anymore):

options = -NO_SSLv3

Stunnel example services

Here are some example pop3s, ssmtp, and HTTPS services...

pop3s

[pop3s]

accept = 995

connect = 127.0.0.1:110

cert = /etc/stunnel/stunnel.pem

ssmtp

[ssmtp]

accept = 465

connect = 127.0.0.1:25

cert = /etc/stunnel/stunnel.pem

HTTPS

[https]

ciphers=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

accept = 443

connect = 127.0.0.1:80

cert = /etc/stunnel/stunnel.pem

TIMEOUTclose = 0

Alternatively, here's a slightly more interesting example.....

MySQL-over-TLS encapsulation connecting the Unix socket

[mysql]

cert = /etc/stunnel/stunnel.pem

accept = 3307

connect = /run/mysqld/mysqld.sock

Don't forget your SSL/TLS certificate

To use Stunnel on your server, you'll need an SSL certificate. For anyone confused about how to do this in Linux, check out this blog: How to create an SSL certificate in Linux.

This could be a self-signed certificate or one obtained from providers like Let's Encrypt. In the examples shown above, a self-signed certificate and private key are used. They also require a PEM file, which should contain the server certificate as well as the key.

Alternatively, you can provide the certificate and the key in separate files, like so:

cert = /etc/stunnel/server.crt

key = /etc/stunnel/server.key

Bonus section! How to configure SSH over TLS with Stunnel

Here is another example of a more “exotic” Stunnel configuration. Most people, and rightly so, will ask “but why?” -“Well, because we can!”

In seriousness, it has a few real-life uses. You can expose your SSH server via port 443 if the firewall blocks port 22. It allows you to use mTLS as a method of limiting access to the SSH server, which might be useful if you use mTLS for other services already. You can block access to all the services by revoking a single certificate.

Also, so-called security by obscurity. You can “hide” your SSH server on the post 443 that your web server already uses and use SNIs to determine if the client should be seeing the website or perhaps should be given an SSH prompt.

Unlike the previous examples, SSH does not support TLS natively, which means we need to use a proxy to be able to connect to such service. Luckily, Stunnel can be configured in client mode, which means it can serve that purpose.

Client configuration

The below example uses a domain of the remote SSH server.

[ssh-client]

client = yes

accept = 127.0.0.1:2222

connect = ssh.example.com:443

Server configuration

The below example shows how to use SNI in order to make both your web and SSH server available on port 443 at the same time:

[webserver]

ciphers=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

accept = 443

connect = 127.0.0.1:80

cert = /etc/stunnel/stunnel.pem

TIMEOUTclose = 0

[ssh]

sni = webserver:ssh.example.org

accept = 443

connect = 127.0.0.1:80

cert = /etc/loadbalancer.org/certs/server.pem

And that's it!

I hope the Stunnel configurations I've outlined are useful to you, and help you safeguard your network communications.

We've seen how Stunnel works as a versatile solution for securing non-TLS services, offering encryption for various protocols with minimal effort, making it a valuable tool for your arsenal.

In the meantime, if you have any questions, feel free to drop me a message in the comments below.

Want to try it for yourself?

Spin up an ADC in minutes and give it a go!