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…”
( https://www.stunnel.org/docs.html )
In this post an overview of stunnel used in order to encrypt communications.
Reported as notes :
- stunnel base configuration (steps #4 and step #5)
- stunnel mutual authentication and test with browser (step #6)
#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

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 https://www.stunnel.org/downloads.html and compile with “classic” steps
./configure
make
make install
#3 configuration overview
Complete documentation about configuration can be found here : http://www.stunnel.org/docs.html
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
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/stunnel_client.pid
client = yes
[http]
accept = 127.0.0.1:1086
connect = 192.168.1.5:2086
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

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
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/stunnel_server.pid cert = /cert/stunnel-in.crt key = /cert/stunnel-np.key client = no [http] accept = 192.168.1.5:2086 connect = 127.0.0.1:1086
#6 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) :
- generate certificate for SOAP-Server and configure server to use it (e.g tomcat)
- import server certificate as exception/trusted in client (stunnel)
- generate certificate for SOAP-Client and configure client to use it (stunnel)
- 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)
#6.1.1 generate certificate of Tomcat server and import in keystoreFile
Simpler way for self-signed (quick start) : http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html
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 > serial.sr
openssl x509 -CA CA-tomcat-soap.crt -CAkey CA-tomcat-soap.key -CAserial serial.sr -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
- keystorePass=”password” keystoreFile=”/keystore/crtkeystore”
- 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).
- truststorePass=”password” truststoreFile=”/keystore/crtkeystore”
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"/>
</Host> </Engine> </Service>
#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).
(similar message with other Browser)
#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 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/stunnel_out.pid client = yes cert = /cert/personal-client.crt key = /cert/personal-client.key [http] accept = 127.0.0.1:18080 connect = 192.168.128.115:8284
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 127.0.0.1:36877 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)
Add Comment