How to install and configure stunnel on Ubuntu

Overview

We all know how awesome stunnel is, but setting it up properly on Ubuntu (and on most other distros, really), can be a little tricky.

This post is dedicated to show you how to properly install and configure this magnificent piece of software on Ubuntu.

For this, I’ll be using Ubuntu 18.04 Server. There is a good chance however that the same procedure (maybe with slight adjustments), could work on other Ubuntu versions (or even other distros) as well. Please share your results with me so I can update this post.

Installing stunnel

This part should be simple enough. We’ll be using Ubuntu’s own repository:

sudo sh -c 'apt-get update && apt-get install stunnel4'

The installation process also comes with its own stunnel4 user, init script, and logrotate config (which we’ll take advantage of soon).

Moreover, couple of scripts are included in the package to deal with the ppp connections (to handle ppp status changes gracefully by restarting the stunnel process).

stunnel - manual mode

stunnel can be manually called with the config file as its argument and it will work.

For example, assuming the file is located at /etc/stunnel/stunnel.conf, the following command would run it:1

sudo stunnel /etc/stunnel/stunnel.conf

Note that in this example, we are running stunnel as root. stunnel can be run as a non-root user (assuming that it doesn’t try to write anything to privileged places2, or open some privileged ports), but there is a better way to do it:

The recommended way to run stunnel, is to run it as root and then make it drop its privilege using setuid/setgid.

That way, you get the best of both worlds (being able to initially use privileged operations (e.g., opening <1024 port), and then dropping the privilege later on).

stunnel - init mode

If we want to take full advantage of functionalities provided by the stunnel package, all the conf files should be placed in /etc/stunnel, and have .conf extension3 .

After this, and with some tweaks, the provided init script will spawn a separate stunnel instance for each .conf file on startup.

According to the stunnel author, with the planned introduction of a control interface (conceptually similar to apache2ctl), running separate processes for each *.conf will become obsolete.

You should use a single file called stunnel.conf and add include = @sysconfdir@/stunnel/conf.d in that instead.

While at the time of writing, spawning different instances of stunnel for each conf file it is still supported, it appears that in most cases it might not be necessary. A single stunnel instance could be used to provide both client and server functionalities for different services at the same time. How cool is that?

The rest of this article assumes we are using a single stunnel.conf file. But I will give you the information necessary to be able to make the init script to spawn multiple instances if its required (as there are couple of global options which can only be set once per instance).

conf file format

We’re going to use a config file called stunnel.conf, placed in /etc/stunnel/.

This is your typical stunnel config file and should adhere to the stunnel conf file format.

But to make the stunnel play nicely with the init script, there are couple of rules that you should follow while making the conf file:

foreground

No foreground option should be used when you want to use the built-in init script.

setuid/setgid

A dedicated user called stunnel4, is already created by the package and ready to use. Use that as your setuid/setgid parameter.

pid

For the init script to work properly, each instance should have a separate pid file located in /var/run/stunnel4/.

For a single instance, set it to /var/run/stunnel4/stunnel.pid.

output

It is possible to save the stunnel output messages to the disk.

/var/log/stunnel4/ is the place dedicated to save stunnel output files. The specified file should have a .log extension.

Needed logrotate script is already in place to take care of archiving and deleting old log files in that folder.

Each instance should be set to use a different output file. Use /var/log/stunnel4/stunnel.log for your default instance4.

conf file sample

Here, I will provide you with a sample file for reference:

pid = /var/run/stunnel4/stunnel.pid
output = /var/log/stunnel4/stunnel.log

setuid = stunnel4
setgid = stunnel4

# https://www.stunnel.org/faq.html
socket = r:TCP_NODELAY=1
socket = l:TCP_NODELAY=1

debug = 4

[yahoo_imaps-client]
client = yes
accept = 127.0.0.1:143
connect = imap.mail.yahoo.com:993
# This requires ca-certificates package
CApath = /etc/ssl/certs/
verifyChain = yes
checkHost = imap.mail.yahoo.com

[ssh_tls-server]
accept = 2222
connect = 127.0.0.1:22
PSKsecrets = /etc/stunnel/stunnel.secrets

Setting defaults

/etc/default/stunnel, is what glues everything together. At the very least, you need to set the “ENABLED” value to “1” in that file to enable stunnel init script.

Each of the settings with their description are listed below:

ENABLED=0
Set this to 1 to enable stunnel init script to run on startup.
FILES="/etc/stunnel/*.conf"
The location and file extensions of conf files used by the stunnel init script.
OPTIONS=""
Extra options to be passed to the stunnel instances by the init script.
RLIMITS=""
You may set some limits on the stunnel instances. See the file's inline comment as well as Bash manual for more detail
PPP_RESTART=0
Set this to 1 to enable ppp restart scripts (restarts stunnel instances upon ppp connections status change).

Testing the instance

Now you are ready to the test the service:

  1. First ensure that the service is stopped by issuing:5
sudo systemctl stop stunnel4.service
  1. Start the service:
sudo systemctl start stunnel4.service
  1. Check the status of the service (here you should see the stunnel instance(s) being active, along with couple of last log messages):
systemctl status stunnel4.service
-
● stunnel4.service - LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons)
   Loaded: loaded (/etc/init.d/stunnel4; generated)
   Active: active (running) since Fri 2019-03-29 01:10:00 UTC; 2s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 1840 ExecStart=/etc/init.d/stunnel4 start (code=exited, status=0/SUCCESS)
    Tasks: 4 (limit: 4915)
   CGroup: /system.slice/stunnel4.service
           ├─1785 /usr/bin/stunnel4 /etc/stunnel/stunnel.conf
           └─1865 /usr/bin/stunnel4 /etc/stunnel/stunnel_2.conf
-
Mar 29 01:10:00 server systemd[1]: Starting LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons)...
Mar 29 01:10:00 server stunnel4[1840]: Starting TLS tunnels: /etc/stunnel/stunnel.conf: started /etc/stunnel/stunnel_2.conf: started
Mar 29 01:10:00 server systemd[1]: Started LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons).
  1. Ensure the service is enabled on startup:
sudo systemctl enable stunnel4.service

And that’s about it. Enjoy using stunnel!

As always, I would love to know your thoughts on this article. Please Share them with me below.


  1. That’s also the default stunnel conf path. So you could have just run stunnel with no argument in this case. ↩︎

  2. By default (at least in Ubuntu), stunnel writes a pid file in /var/run/stunnel4.pid. You can disable this by including “pid =” (a pid without any argument) in the conf file. ↩︎

  3. as we’ll see later, this default location (and extension) can be adjusted. ↩︎

  4. It seems to be possible to share the same log file between different instances, but I’m not certain if it’s officially supported. ↩︎

  5. This step might be necessary after setting the ENABLED=1 option in /etc/default/stunnel ↩︎

Hamy
Hamy
a sysadmin in the wind
comments powered by Disqus

Related