How to shield a protocol and mutual authentication

According with stunnel site description :
The stunnel program is designed to work as an SSL encryption wrapper between remote client and local (inetd-startable) or remote server…
( )
In this post an overview of stunnel used in order to encrypt communications.
Reported as notes :

#1 Encrypt Communications overview

Encrypt has following advantages :

  •  Data protection :
    • from sniffing transmitted data (snoop/tcpdump)
  • Identification of the communicating parties (against man-in-the-middle) :
    • for example with mutual authentication client and server have to exchange their certificates
  • Message integrity :
    • message can’t be modified

Possibles approaches (as example HTTPS) :

Secure protocol Transport/Application Example : “SOAP Server” (or related container such as tomcat) implements directly HTTPS transport. Advantages : natively supported by the application
Disadvantages : not ever is applicable (e.g. source code not available in order to change protocol, framework limit…)
Protocol proxying Transport/System Example : use stunnel in order to wrap HTTP to HTTPS without change implementation of “SOAP Server” Advantages : simple to implement also if application (server/client) doesn’t support HTTPS
Disadvantages : one more component to manage (and monitoring) in your architecture. Limited protocols support
VPN Network   Advantages : at network level
Disadvantages : at network level 🙂 , point2point
Network Card  ?  TODO

In this post I’ll report my notes about “protocol proxing”.

#1.1 Protocol proxying

In some cases migration to secure protocol can’t be done due to software or infrastructure limit :
server/client doesn’t support natively the target protocol (HTTPS) … and it can’t be used a VPN. Typical use of stunnel is when you need to move from unsafe protocol (e.g. let me say HTTP) to secure version (e.g. in our example HTTPS) without change anything at application or network level. Stunnel is an additional software component which acts as proxy from not-secure to secure protocol and vice versa

Supported protocols by stunnel are (protocol that you can move to secure) :
cifs, connect (Based on RFC 2817), imap, nntp, pgsql, pop3, proxy, smtp

Stunnel type of deployments
Stunnel type of deployments

Please consider that SOAP is just an example here … in most cases (I mean with SOAP) you can turn on tomcat  HTTPS (on server side).
Above  diagram shows 3 different scenarios of deployment where is required to use stunnel.
Stunnel can be configured in two different mode:
client (client=yes) or server (client=no) mode based on traffic that you need to make safe and if remote service uses SSL or not.

#2 stunnel : installlation

Stunnel is generally included with most common distributions.
Anyway you can dowload it from and compile with “classic” steps

make install

#3 configuration overview

Complete documentation about configuration can be found here :
Simple basic configuration has the following file format (st.cfg):

debug = <debug_level>
output = <path_to_log_file>
pid = <path_to_pid_file>

; client mode (remote service uses SSL)
client = <yes|no>

verify = <level> ; verify peer certificate
           ; level 1 - verify peer certificate if present
           ; level 2 - verify peer certificate
           ; level 3 - verify peer with locally installed certificate
           ; default - no verify

[service_name]; indicating a start of a service definition.
  ; Each configuration section begins with service name in square brackets.
  ; The service name is used for libwrap (TCP Wrappers) access control and lets you 
  ; distinguish stunnel services in your log files.

;accept connections on specified host:port
accept = [host:]port
;connect to remote host:port
connect = [host:]port

Configuration file (st.cfg) can be specified as param in command line when start stunnel : stunnel st.cfg

#4 stunnel client mode YES

Stunnel acts such as a SSL client in order to connect to a SSL server :

  • Client doesn’t support HTTPS
  • Server supports HTTPS

stunnel client mode YES

In this scenario a client needs to talk with a remote server that implements a secure protocol.
Client doesn’t support secure protocol instead server is enabled to use SSL.

debug = 5
output = /var/log/stunnel_client.log
pid = /var/run/
client = yes

accept =
connect =

you might be interested in verify validuty of the remote certificate (server certificate) in this case you need to specify verify=2 (or 3) in configuration file.

#5 stunnel client mode NO

stunnel acts such as a SSL server :

  • Client supports HTTPS
  • Server doesn’t support HTTPS
 stunnel client mode NO
stunnel client mode NO

In this scenario the server (e.g. SOAP server) doesn’t export any secure protocol.
Client needs to talk using SSL: in this case stunnel,which acts as server on port 2086, has to provide valid certificate to client.

#5.1 generate server stunnel certificate

In this example we will use auto signed certificate (click here)
openssl genrsa -des3 -out stunnel-server.key 1024
openssl req -new -key stunnel-server.key -out stunnel-server.csr
openssl rsa -in stunnel-server.key -out stunnel-np.key
openssl x509 -req -days 3650 -in stunnel-server.csr -signkey stunnel-np.key -out stunnel-in.crt

(remove unwanted user permission)
chmod go-rw stunnel-*

#5.1.1 alternative and simpler way using stunnel

$ cd tools
$ make stunnel.pem

Configuration (specify server certificate) :

debug = 5
output = /var/log/stunnel_server.log
pid = /var/run/
cert = /cert/stunnel-in.crt
key = /cert/stunnel-np.key
client = no

accept =
connect =

#6 stunnel and mutual authentication

stunnel and mutual authentication
stunnel and mutual authentication

In this scenario client and server certify their identity with the exchanging of their respective certificates (step 2. and step 3. in image above “stunnel and mutual authentication“).
So certificates involved in this flow are two : one of client and one of server.
stunnel can be used if the client (or/and the server) doesn’t support mutual authentication.

Quick steps are (in case of self-signed certificate) :

  1. generate certificate for SOAP-Server and configure server to use it (e.g tomcat)
  2. import server certificate as exception/trusted in client (stunnel)
  3. generate certificate for SOAP-Client and configure client to use it (stunnel)
  4. import client certificate as exception/trusted in server (e.g. tomcat)

In our below example Tomcat is the server (that supports mutual authentication).

#6.1 Server Tomcat configuration (mutual authentication)

Tomcat configuration for mutual authentication (click here)

#6.1.1 generate certificate of Tomcat server and import in keystoreFile

Simpler way for self-signed (quick start) :

Alternative long option :

openssl genrsa -des3 -out CA-tomcat-server.key 1024
openssl req -new -key CA-tomcat-server.key -out CA-tomcat-server.csr
openssl rsa -in CA-tomcat-server.key -out CA-tomcat-soap.key
openssl x509 -req -days 3650 -in CA-tomcat-server.csr -signkey CA-tomcat-soap.key -out CA-tomcat-soap.crt

keytool -genkey -alias tomcat -keyalg RSA -keystore /keystore/crtkeystore
keytool -keystore /keystore/crtkeystore -alias tomcat -certreq -file tomcat.csr

echo 11061971 >

openssl x509 -CA CA-tomcat-soap.crt -CAkey CA-tomcat-soap.key -CAserial -req -in tomcat.csr -out tomcat.cer -days 3650
keytool -import -alias serverCA -file CA-tomcat-soap.crt -keystore /keystore/crtkeystore
keytool -import -alias tomcat -file tomcat.cer -keystore /keystore/crtkeystore

#6.1.2 configure Tomcat

In our example you have to activate mutual authentication on tomcat (server) with clientAuth=”true” in ./conf/server.xml
Moreover you have to specify two key stores :

  • key stores (server certificate)

      • keystorePass=”password” keystoreFile=”/keystore/crtkeystore”
        certificate that server has to send in step 2. (image above “stunnel and mutual authentication“) and generated in step #6.1.1
  • trust stores (client certificate to trust)

      • truststorePass=”password” truststoreFile=”/keystore/crtkeystore”
        Certificate, related to client, that server has to accept in step 3. (image above “stunnel and mutual authentication“)
        This is the client certificate and at this time we haven’t it yet … we will create and import it later (in step #6.2.a).

So basically configuration of Tomcat is :

<Service name="Tomcat-MA">
 <Connector port="8284" maxHttpHeaderSize="8192"
 SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS"
 keystorePass="password" keystoreFile="<PATH>/keystore/crtkeystore"
 truststorePass="password" truststoreFile="<PATH>/keystore/crtkeystore"
 maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
 enableLookups="false" acceptCount="100"
 connectionTimeout="20000" disableUploadTimeout="true" />

<!-- Define the top level container in our container hierarchy -->
 <Engine name="Catalina-ma" defaultHost="localhost" debug="0">

<!-- Define the default virtual host -->
  <Host name="localhost" debug="0" appBase="webapps-ma"
  unpackWARs="true" autoDeploy="true">

  <Valve className="org.apache.catalina.valves.AccessLogValve"
  directory="logs-public"  prefix="localhost_access_log."suffix=".txt"
  pattern="common" resolveHosts="false"/>


#6.2 Test server mutual authentication with a browser

In order to check Mutual authentication (if server is correctly configured in step #6.1) we can use a normal browser (pointing the target server URL). If  browser doesn’t have personal (client) certificate or server doesn’t recognise it then we hit this screenshot. So we need to import into the browser the client certificate (see below).

Firefox Error check connection
(similar message with other Browser)

Details for tests with FireFox (click here)
So we need to generate client certificate with following steps :

#6.2.a) Generete personal (client) client certificate

openssl genrsa -des3 -out personal-client.key 1024
openssl req -new -key personal-client.key -out personal-client.csr
openssl rsa -in personal-client.key -out personal-client-np.key
openssl x509 -req -days 3650 -in personal-client.csr -signkey personal-client-np.key -out personal-client.crt

#6.2.b) Import personal certificate in FireFox as pkcs12

openssl pkcs12 -export -inkey personal-client.key -in personal-client.crt -out personal-client.p12 -name "Client Certificate"

Import pkcs12 in Browser FireFox

Import pkcs12 in Browser FireFox with following steps :
1) Preferences, 1) Encryption, 2) View certificate , 3) Your Certificates, 4) Import -> you have to import personal-client.p12

#6.2.c) Import personal certificate in truststoreFile server Tomcat side :

personal-client.crt has to copied on Tomcat side and imported in keystone (see #6.1.2)

keytool -import -alias client -file /tmp/personal-client.crt -keystore /keystore/crtkeystor

Now server has to accept browser request

#6.3 Configure Stunnel (mutual authentication)

Now it’s time to configure stunnel which acts as Client.
Configuration :

debug = 5
output = /var/log/stunnel_out.log
pid = /var/run/
client = yes
cert = /cert/personal-client.crt
key = /cert/personal-client.key

accept =
connect =

In this case the client certificate/key:
cert = /cert/personal-client.crt
key = /cert/personal-client.key
are built in #6.2 (exactly 6.2.a) … click on toggle in order to open)

  you might be interested in verify remote certificate (server certificate) in this case you need to specify verify=2 (or 3) and import tomcat certificate on stunnel if it is self-signed.

  If this error occurs :

2013.05.30 16:48:25 LOG5[26676:1073809760]: http connected from
2013.05.30 16:48:25 LOG3[26676:1073809760]: SSL_connect: 14094416: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown

then certificate is unknown server side and you need to import in trust store as “trusted certificate” (see #6.1.2)

User Review
5 (2 votes)