Using stunnel With Bilateral Authentication

Read Me First

Important: This page was written in 2002. I was contacted a couple of years ago by the author of stunnel, indicating that stunnel has evolved so much since then that as far as stunnel information goes, this page is essentially worse than useless. I don't use stunnel anymore so am unable to update it. I should probably remove this page entirely, but I can't quite bring myself to do it. So please don't rely on the information on this page.


stunnel provides "drop-in" SSL-secured connectivity between two hosts. It is most often used to retroactively secure an existing application when encryption and/or authentication were not part of the original design.

When neither the client nor the server support SSL encapsulation of a connection, stunnel can be used on both sides of the connection.

In its default configuration, stunnel does not perform authentication; it merely encrypts the channel without verifying the endpoints.

This document describes how to set up stunnel to use signed certificates to perform bilateral authentication. Under this scheme, both the client and the server provide sufficient credentials (in the form of SSL certificates signed by a mutually acceptable authority) to establish their identity.

Document Conventions

Black Text represents output from the software or prompts for information that will appear.

Green Text represents commands or information that (at least the first time) can be entered exactly as shown.

Red Text represents commands or information that must be customized to the particular situation before being entered. For example, WWWI should be changed to the name of your own organization.

Stunnel Security Limitations

stunnel has two significant limitations that affect its ability to perform bilateral authentication. The first is that there is no provision for encrypted keys. The second is that stunnel does not perform browser-style checking of the CN name field against the hostname of the connection. In combination, these limitations mean that if someone can access an stunnel key, they will not need a passphrase to decode it and that they can use that key from any connected host without regard for its hostname or IP address.

It is therefore vital to ensure that systems with stunnel keys are carefully secured and that the keys are stored with the most restrictive possible permissions.

This is not a strictly speaking a limitation of stunnel, but rather a difficulty HTTP-over-SSL has traditionally worked around by allowing the web server to prompt for a passphrase on startup, and by using browsers that compare the common name (CN) of a server's certificate to the hostname. Perhaps a future version of stunnel will offer an option to enable similar functionality.

Creating Certificates

  1. Create a non-encrypted private key for the client:

    YourPrompt&ht; openssl genrsa -out client.key 1024
    Generating RSA private key, 1024 bit long modulus
    e is 65537 (0x10001)

  2. Create a certificate signature request for the new client key:

    YourPrompt> openssl req -new -key client.key -out client.csr
    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]:US
    State or Province Name (full name) [Some-State]:Texas
    Locality Name (eg, city) []:Montgomery
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:WWWI
    Organizational Unit Name (eg, section) []:WWWI Stunnel Services
    Common Name (eg, YOUR name) []:WWWI Client
    Email Address []:.

    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:.
    An optional company name []:.

  3. Get the client.csr signed by your certificate authority. If you are self-signing certificates, the command would be similar to:

    YourPrompt> .../path/to/mod_ssl/pkg.contrib/ client.csr
    CA signing: client.csr -> client.crt:
    Using configuration from ca.config
    Enter PEM pass phrase:CAKeyPassPhrase
    Check that the request matches the signature
    Signature ok
    The Subjects Distinguished Name is as follows
    countryName :PRINTABLE:'US'
    stateOrProvinceName :PRINTABLE:'Texas'
    localityName :PRINTABLE:'Montgomery'
    organizationName :PRINTABLE:'WWWI'
    organizationalUnitName:PRINTABLE:'WWWI Stunnel Services'
    commonName :PRINTABLE:'WWWI Client'
    Certificate is to be certified until Feb 22 22:22:22 2003 GMT (365 days)
    Sign the certificate? [y/n]:y

    1 out of 1 certificate requests certified, commit? [y/n]y
    Write out database with 1 new entries
    Data Base Updated
    CA verifying: client.crt <-> CA cert
    client.crt: OK

  4. Construct an stunnel-client.pem file from the key and certificate as follows:

    [encoded key]
    -----END RSA PRIVATE KEY-----
    [encoded certificate]
    -----END CERTIFICATE-----

    There are no extra blank lines or extraneous text needed in this file.

  5. Copy the CA certificate (ca.crt) to stunnel-auth.pem.

  6. Install both stunnel-client.pem and stunnel-auth.pem on the client in the appropriate stunnel directory (the one specified by --with-pem-dir during configure, where the default stunnel.pem is installed).

  7. Repeat steps 1 through 5 for the server (server.key, server.csr, server.crt, stunnel-server.pem). The stunnel-auth.pem file will be the same for the server.

Running Stunnel

For this example, we will use mysql-3.23.X, which includes both client and server pieces and does not support native SSL connections.

  1. Start mysql on the server machine.

    YourPrompt> nohup mysqld --bind-address= --user=mysql &

    Binding to the localhost IP address ( ensures that other systems cannot gain unencrypted/unauthenticated access to MySQL.

  2. Start stunnel on the server machine.

    YourPrompt> stunnel -A /usr/local/stunnel/stunnel-auth.pem -v 2 -p /usr/local/stunnel/stunnel-server.pem -d -r localhost:3306

  3. Start stunnel on the client machine.

    YourPrompt> stunnel -A /usr/local/stunnel/stunnel-auth.pem -v 2 -p /usr/local/stunnel/stunnel-client.pem -c -d localhost:3306 -r

  4. Test the mysql client on the client machine.

    YourPrompt> mysql -h
    Welcome to the MySQL monitor. Commands end with ; or \g.
    Your MySQL connection id is 6615 to server version: 3.23.49

    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

    mysql> \q

    If problems occur with the mysql connection, check the stunnel log files or use -f to run stunnel in the foreground on each machine. It will provide information about any errors that occur in the certificate exchange process.

    It is important to remember that from the MySQL server, all connections will appear to be originating from localhost. MySQL's internal user/host/password tables must be configured appropriately. Also, the SSL certificate exchange process can be relatively time consuming compared to an SQL query. Therefore, connection pooling becomes more important as a tool to improve performance when security is implemented in this fashion.

Increasing Security

It is possible to further increase security by requiring stunnel to compare the certificate presented by its peer against a stored list of acceptable certificates. To take advantage of this feature:

  1. Change the '-v 2' parameter of each stunnel command line to '-v 3'.

  2. Add each system's certificate to the stunnel-auth.pem file of each system it will connect to.

This is particularly appropriate if the certificate authority being used also serves any other purpose that should not imply the ability to access the resource being secured.


Particular thanks go to the creators of stunnel, OpenSSL and MySQL for making such great products.

See also the general thanks and credits on the SSL page.


This document was written by Jeffrey D. Wheelhouse ( This is version 1.0.3, created February 22, 2002 and last updated on February 2, 2013 to indicate it is now almost but not quite completely wrong. Comments, suggestions, and corrections are welcomed via email. This document and its contents are placed into the public domain for unlimited use and distribution.

Home | Software | SSL | Stunnel