Stunnel on server and client

Task

Provide access from "wherever there is Internet" to some software. Encrypt traffic between the client and server parts of an application that does not know how to work through SSL. You also need to be able to restrict access to some users if necessary. For various reasons, the basic VPN implementations have disappeared. In the process of finding a solution, I came across Stunnel, which was perfect. In this article I will try to describe in detail the configuration process.

The article is for the most part composed of working notes in the appendage with claims for a tutorial, so please calmly relate to captains of the form - "The first thing we will do is update the system."

General view of the scheme of work:
Client software (windows)> Stunnel> Internet> Stunnel> Server software (linux)


System: Freshly installed ubuntu server 14.04 x64.

The application whose traffic you want to encrypt, I will not call. I will specify ssh instead. Ideal for the test, in my opinion.

Let's get started

The first thing we will do is update the system:

sudo apt-get update
sudo apt-get upgrade

Configure and enable ufw:

sudo ufw allow 22/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Install stunnel:

sudo apt-get install stunnel4

During installation, the following are created:
- user and group stunnel4;
- interesting directories to us:
  • / var / lib / stunnel4 here will be a chroot environment
  • / etc / stunnel any file in this directory ending in .conf will be considered a config
  • / usr / share / doc / stunnel4 / examples with an example config inside


We will carry out some preparatory activities.

Enable autorun. In the file / etc / default / stunnel4, replace ENABLED = 0 with ENABLED = 1:

sudo nano /etc/default/stunnel4

Create folders for client certificates. certs - allowed, crls - forbidden (revoked). About the certificates themselves a little later.

sudo mkdir /var/lib/stunnel4/certs
sudo mkdir /var/lib/stunnel4/crls

Create a log file and change the owner.

I do not consider logging in a place other than / var / log a good idea, but I could not get stunnel to write logs outside the environment.

sudo touch /var/lib/stunnel4/stunnel.log
sudo chown stunnel4:stunnel4 /var/lib/stunnel4/stunnel.log

I will use my config, but if it does not suit you, you can take an example in / usr / share / doc / stunnel4 / examples

Let's create a configuration file:

sudo nano /etc/stunnel/stunnel.conf

With the following contents:

; **************************************************************************
; * Global options                                                         *
; **************************************************************************
; Каталог chroot окружения.
chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
; Создается в окружении
pid = /stunnel4.pid
; Уровень болтливости
debug = 7
; Лог-файл
output = /stunnel.log
; Не использовать syslog
syslog = no
; **************************************************************************
; * Service defaults may also be specified in individual service sections  *
; **************************************************************************
; Сертификат/ключ сервера 
cert = /etc/stunnel/servercert.pem
key = /etc/stunnel/serverkey.pem
; Проверка сертификата. 0 - не проверять, 1 - проверять при наличии, 2 - проверять всегда, ...
verify = 2
; Каталог для разрешенных сертификатов. 
; Находится в окружении. Для каждого сертификата должна быть хэш-ссылка
CApath = /certs
; Каталог для запрещенных (отозванных) сертификатов. 
; Находится в окружении. Для каждого сертификата должна быть хэш-ссылка
CRLpath = /crls
; Не использвать SSLv2
options = NO_SSLv2
; **************************************************************************
; * Service definitions (remove all services for inetd mode)               *
; **************************************************************************
[ssh]
; Принимать соединения на интерфейс:порт или просто порт. Например accept = 192.168.0.1:443
accept = 443
; Отдавать приложению на интерфейс:порт или просто порт. Например connect = 127.0.0.1:22
connect = 22


Keys and certificates

Not a big digression. In our case, stunnel only checks the correctness of the certificate / key pair and the presence of the certificate in allowed or prohibited. A self-signed certificate is more than enough, both from the technical side (stunnel) and from the task. There is no reason to bother with your own CA or with the presence of the root certificate in the list of trusted ones on the client or server.

We need certificate / key pairs for the server and each client.

Using openssl, create a pair for the server:

sudo openssl req -nodes -new -days 365 -newkey rsa:1024 -x509 -keyout serverkey.pem -out servercert.pem

We answer the questions:

Generating a 1024 bit RSA private key
....................++++++
..............................++++++
writing new private key to 'serverkey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:MyProvince
Locality Name (eg, city) []:MyCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany
Organizational Unit Name (eg, section) []:IT dep
Common Name (e.g. server FQDN or YOUR name) []:server
Email Address []:

And move them to their destination:

sudo mv serverkey.pem /etc/stunnel/
sudo mv servercert.pem /etc/stunnel/

How and where to store client certificates with keys (with the exception of the certs and crls directories created earlier) is up to you. I will just create the clients directory in my user's home directory and will store them there for the first time.

Create a directory and go to it:

mkdir /home/myuser/clients
cd /home/myuser/clients

Create a pair for the client:

sudo openssl req -nodes -new -days 365 -newkey rsa:1024 -x509 -keyout clientkey.pem -out clientcert.pem

As when creating a certificate for the server, we answer questions. Common Name will be different for example client.

Create another pair:

sudo openssl req -nodes -new -days 365 -newkey rsa:1024 -x509 -keyout dnclientkey.pem -out dnclientcert.pem


Assume that clientcert.pem a client certificate to which access is allowed, and dnclientcert.pem a client certificate to which access is denied. We copy the certificates to the necessary directories.

sudo cp clientcert.pem /var/lib/stunnel4/certs
sudo cp dnclientcert.pem /var/lib/stunnel4/crls

For each certificate, you need to create hash links (Perhaps the "hash link" is not the correct name, but it conveys the essence very accurately). This can be done using the c_rehash utility from the openssl package. We will create a small script for these purposes.

nano /home/myuser/certlink.sh

With the following contents:

#!/bin/sh
#
# usage: certlink.sh filename [filename ...]
for CERTFILE in "$@"; do
  # Убедиться, что файл существует и это сертификат
  test -f "$CERTFILE" || continue
  HASH=$(openssl x509 -noout -hash -in "$CERTFILE")
  test -n "$HASH" || continue
  # использовать для ссылки наименьший итератор
  for ITER in 0 1 2 3 4 5 6 7 8 9; do
    test -f "${HASH}.${ITER}" && continue
    ln -s "$CERTFILE" "${HASH}.${ITER}"
    test -L "${HASH}.${ITER}" && break
  done
done

It may be more appropriate to place certlink.sh somewhere in / usr / bin. I have not started doing this yet. But the choice is yours.
Let's give the rights:

chmod +x /home/myuser/certlink.sh

Create links:

cd /var/lib/stunnel4/certs
sudo /home/myuser/certlink.sh clientcert.pem
cd /var/lib/stunnel4/crls
sudo /home/myuser/certlink.sh dnclientcert.pem


As a result, in directories, we should see links of the form 7469493f.0.

Run stunnel:

sudo /etc/init.d/stunnel4 start


Stunnel on the client

On the client we will use the stunnel version similar to the server one. On the server we have 4.53. Pick up from one of the mirrors .

If the direct link fails, you can find the version you need like this:

  • Go to stunnel.org in Downloads ;
  • In the Code Repositories section, select the mirror and proceed. For example usenix.org.uk ;
  • Go to archive ;
  • Then at 4.x ;
  • We pick up the necessary version.

We will not install the downloaded stunnel-4.53-installer.exe file, just unpack the contents into the stunnel4 directory. In the same directory, copy the certificate and the client key, and the server certificate.

Editing the stunnel.conf file. It looks like this for me:

debug = 7
; Пара сертификат/ключ клиента
cert = clientcert.pem
key = clientkey.pem
verify = 2
; Сертификат сервера
CAfile = servercert.pem
options = NO_SSLv2
[ssh]
client = yes
accept = 127.0.0.1:22
connect = 192.168.0.1:443

Here debug = 7 only at the time of debugging, then you can lower it to 3 or 4. There are also options for "silent mode" and hiding the tray icon, everything is in man'e.

We start stunnel.exe, and we try using putty to connect to 127.0.0.1. We are testing. You can try to connect with a forbidden certificate.

Useful materials



The instructions given here are fully operational. Retrieved 12/26/2014 Ubuntu 04/14/01, stunnel 4.53.

Currently I'm working on parsing stunnel logs with report output and automation of certificate creation / management. Since golang has been of interest to me recently, it will be implemented using it. If the material on this topic is interesting - let me know.

Also popular now: