Stunnel Security for Oracle

Oracle has integrated modern Transport Layer Security (TLS) network encryption into its eponymous database product, and TLS usage no longer requires the Advanced Security option beginning with the 10.2 database release. Legacy configurations lacking TLS exchange encrypted passwords, but the session payload is transmitted in clear text and is intercepted easily by anyone with control over the intermediate network. Databases holding sensitive content should avoid clear-text traffic configurations.

It is possible to use the stunnel utility to wrap the Oracle Transparent Network Substrate (TNS) Listener "invisibly" with TLS encryption as an isolated process, and this configuration appears to be compatible both with Oracle's sqlplus command-line utility and with database links that are used for distributed transactions between multiple database instances. There are several benefits to stunnel over the TNS Listener's native TLS implementation:

  • The stunnel utility can be far less expensive. Older Oracle database releases required the Advanced Security option to use TLS, which is licensed at $15,000 per CPU according to the latest pricing, but TLS is now included with Standard Edition SE2.

  • The stunnel utility and the associated dependent libraries (that is, OpenSSL) are patched far more often, and updates can be applied immediately with no database "bounce" if stunnel is used in an "inetd" configuration. Oracle issued eight total patched versions of OpenSSL in 2015 for Oracle Linux 7. Database patches are issued only four times per year at regular quarterly intervals and require instance bounces/outages. An urgent SSL/TLS update will have lengthy delays when implemented as a database patch (due in part to an overabundance of caution by most DBAs), but will be far easier to apply as a simple OS utility patch with no downtime. For this reason, security-sensitive code that may require immediate updates should be kept out of the database server whenever possible. The stunnel utility meets this requirement very well.

  • The stunnel utility can run as a separate user and group inside a "chroot jail" that has limited visibility to the rest of the system. Oracle's server TLS implementation runs with the full privilege of the TNS Listener. A compromise of the TLS engine can be drastically less dangerous if it is confined within a chroot() jail. Privilege separation and chroot() are well-recognized security techniques, and many security-sensitive installations likely will disable listener TLS for this reason alone.

Let's proceed with adding stunnel TLS services to Oracle.

Server Configuration

I am assuming that the reader is familiar with Oracle databases and the procedures to start up an instance and the TLS Listener. For reference, let's assume that a database SID "mydb" is running, and an example listener dæmon is launched on the IP address with the following commands:

export ORACLE_SID=mydb ORACLE_HOME=~oracle/Ora12c/db

$ORACLE_HOME/bin/lsnrctl start

The listener will generate a startup message similar to the output below:

LSNRCTL for Linux: Version - Production on
 ↪19-FEB-2016 13:18:55

Copyright (c) 1991, 2014, Oracle.  All rights reserved.

Starting /home/oracle/Ora12c/db/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version - Production
System parameter file is /home/oracle/Ora12c/db/network/
Log messages written to /home/oracle/Ora12c/diag/tnslsnr/

Alias             LISTENER
Version           TNSLSNR for Linux: Version - Production
Start Date        19-FEB-2016 13:18:55
Uptime            0 days 0 hr. 0 min. 0 sec
Trace Level       off
Security          ON: Local OS Authentication
SNMP              OFF
Parameter File    /home/oracle/Ora12c/db/network/admin/listener.ora
Listener Log File /home/oracle/Ora12c/diag/tnslsnr/HOSTNAME/listener/
Listening Endpoints Summary...
Services Summary...
Service "mydb" has 1 instance(s).
  Instance "mydb", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully

It is important that the listener not engage in "port redirection" of clients to separate server ports (most commonly seen in MTS/Shared Server). Any feature causing the TNS Listener to engage in such activity must be disabled.

To configure stunnel, the root user must create a keypair for TLS. This keypair can be "signed" by a Certificate Authority (CA) if desired—this is conventionally useful for Web site encryption (HTTPS) since the lack of a recognized CA signature will trigger browser security warnings. Oracle clients can verify server keys only when signed by a recognized CA, which is addressed in the final section of this article. To obtained signed keys, follow the instructions on the stunnel Web site. Otherwise, for more informal use, a self-signed key can be generated with the following commands:

cd /etc/pki/tls/certs
make stunnel.pem

The process of key generation will ask a number of questions:

Generating a 2048 bit RSA private key
writing new private key to '/tmp/openssl.hXP3gW'
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) [XX]:US
State or Province Name (full name) []:IL
Locality Name (eg, city) [Default City]:Chicago
Organization Name (eg, company) [Default Company Ltd]:ACME Corporation
Organizational Unit Name (eg, section) []:Widget Division
Common Name (eg, your name or your server's hostname) []:darkstar
Email Address []

The key produced above will be set for expiration in 365 days from the day it was created. If you would like to generate a key with a longer life, you can call OpenSSL directly:

openssl req -new -x509 -days 3650 -nodes \
        -out stunnel.pem -keyout stunnel.pem

The key will look something like this:

# cat /etc/pki/tls/certs/stunnel.pem

The PRIVATE KEY section above is the most sensitive portion of the file; ensure that it is not seen or copied by anyone that you do not trust, and any recordings on backup media should be encrypted. The BEGIN CERTIFICATE section is presented to TLS clients (that is, sqlplus) when they connect to stunnel.

It is likely wise to compute custom primes for the Diffie-Hellman key exchange algorithm, following guidance from the stunnel manual page:

openssl dhparam 2048 >> stunnel.pem

The previous command will add another section to your stunnel.pem file for high-security Diffie-Hellman primes:


The Oracle TNS Listener conventionally runs at port 1521. In this exercise, let's run Oracle TLS services at port 1522, which has the current service name:

# grep 1522 /etc/services
ricardo-lm   1522/tcp      # Ricardo North America License
                           # Manager
ricardo-lm   1522/udp      # Ricardo North America License
                           # Manager

Place the following file to control stunnel for the "ricardo" service (alter the IP address to the location of your TNS Listener):

# cat /etc/stunnel/ricardo.conf
sslVersion      =       TLSv1.2
        options =       NO_SSLv3
        options =       NO_SSLv2
        options =       SINGLE_DH_USE
        options =       SINGLE_ECDH_USE
        options =       CIPHER_SERVER_PREFERENCE
        cert    =       /etc/pki/tls/certs/stunnel.pem
        FIPS    =       no
        debug   =       6
        syslog  =       yes
        chroot  =       /var/empty
        setuid  =       nobody
        setgid  =       nobody
        connect =

; best-practice ciphers:

Note above that you are configuring TLS for best-practice encryption with the highest quality protocols and ciphers. The Oracle clients appear compatible with these settings. Note that Michal Trojnara, the author of stunnel, does "not recommend using DH ciphersuites in the hardened set. ECDH ciphersuites are much more secure and much faster - RFC 7525 should be considered outdated after the recent attacks on DH." On the other hand, there have been recent questions of software patents on Elliptic Curve, although Sun/Oracle contributed the ECC implementation in OpenSSL and used great care to avoid patented methods. Red Hat/Fedora went further in enabling only the Suite B subset of NIST ECC curves for protection from Certicom (whether this is a sufficient courtroom defense against CryptoPeak is another matter). Beyond that, in my previous coverage of the Stribika SSH Guide [see "Cipher Security: How to Harden TLS and SSH" by Charles Fisher, September 2015], I wrote that the author is "...advising against the use of NIST elliptic curves because they are notoriously hard to implement correctly. So much so, that I wonder if it's intentional. Any simple implementation will seem to work but leak secrets through side channels. Disabling them doesn't seem to cause a problem; clients either have Curve25519 too, or they have good enough DH support." Trojnara has responded that the question of "side-channel attacks on ECDHE is pure nonsense, since by definition (the last 'E' stands for 'ephemeral'), there is no persistent secret here an attacker might retrieve with [any available] side-channel attacks." In any case, Hynek Schlawack's Web site on the subject has not endorsed one over the other so far, while his silence on the growing questions behind Diffie-Hellman key exchange is somewhat unsettling. Your legal environment and encryption stance will decide your cipher string.

Use the following systemd unit files to configure stunnel for inetd-style operation (if you aren't using an OS based on systemd, see my previous articles for a discussion of [x]inetd):

# cat /etc/systemd/system/ricardo.socket
Description=oracle stunnel

# cat /etc/systemd/system/ricardo@.service
Description=oracle stunnel service
ExecStart=-/usr/bin/stunnel /etc/stunnel/ricardo.conf

Assuming that the above unit files are in place, connections on 1522 can be enabled both at boot and for the present environment with these commands:

systemctl start ricardo.socket

systemctl enable ricardo.socket

The enable command will place systemd's startup link:

Created symlink from
/etc/systemd/system/ to

It might be useful to telnet to port 1522, as stunnel will print informative error messages to standard output in case of trouble. The most practical telnet client is likely BusyBox.

Remote connections to port 1522 might be blocked by your Linux firewall. The root user can permit them to pass to stunnel with the following:

iptables -I INPUT -p tcp --dport 1522 --syn -j ACCEPT

The TNS Listener can be instructed to restrict the origin of sessions, and it can be used to ban clear-text traffic completely by adding your IP equivalent to the following fragment of the $ORACLE_HOME/network/admin/sqlnet.ora file on the server:


Perform this modification after all testing is successful, and note that any configured clients using the TNS Listener will be shut down if and when the configuration is thus restricted.

It is likely wise to use a stunnel binary provided by Oracle Corporation, but the versions that it provides are rather old. If you can load stunnel version 5, you can omit the NO_SSL options shown above. However, the Oracle version 4 stunnel binaries are somewhat more likely to be tolerated in a critical support situation involving Oracle. On the other hand, commercial support from definitely prefers version 5. If support is an important factor, the experience and availability of the use of both versions will be helpful.

Special thanks to Michal Trojnara, the author of stunnel, for his helpful comments on this article and work in stunnel development. Commercial support, licensing and consulting for stunnel is available from his organization; please see this page for his latest release.

Database Client

Using the sqlplus client utility that is bundled with a local database server, a TLS session can be established through the stunnel that was previously configured on the remote server. Doing so requires a new client key that is stored in a "wallet", which is created below.

Use the following commands to configure the local sqlplus:

export ORACLE_SID=yourdb ORACLE_HOME=/home/oracle/Ora12c/db
mkdir /home/oracle/wallet
$ORACLE_HOME/bin/orapki wallet create -wallet /home/oracle/wallet \
        -pwd SECRET123 -auto_login_local
$ORACLE_HOME/bin/orapki wallet add -wallet /home/oracle/wallet \
        -pwd SECRET123 -dn "CN=%yourdb%" -keysize 2048 \
        -self_signed -validity 3650

The output of both calls to the orapki utility above should be this banner:

Oracle PKI Tool : Version
Copyright (c) 2004, 2014, Oracle and/or its affiliates. All
rights reserved.

Directives also must be placed to find the new wallet repository—add the following to your sqlnet.ora file:

$ cat $ORACLE_HOME/network/admin/sqlnet.ora

   (SOURCE =
     (METHOD = FILE)
       (DIRECTORY = /home/oracle/wallet)


Finally, call sqlplus with a database account and a connect descriptor that invokes the TLS port at 1522 (note that the newlines within the single quotes are optional and are included here for clarity):

$ORACLE_HOME/bin/sqlplus RemoteUser@'(description=

Assuming success, enter the password for your RemoteUser account, then issue an SQL command:

SQL*Plus: Release Production on Fri Feb 19 13:26:56 2016

Copyright (c) 1982, 2014, Oracle.  All rights reserved.

Enter password:
Last Successful login time: Fri Feb 19 2016 13:15:54 -06:00

Connected to:
Oracle Database 12c Enterprise Edition Release - 64bit
With the Partitioning, OLAP, Advanced Analytics and Real
Application Testing options



A few points to consider:

  • Changing protocol=tcps to protocol=tcp and further modifying port=1521 above will log in with a clear-text session (if your firewall and listener allow access).

  • The host= clause above can reference a DNS hostname instead of an IP address if that is more convenient.

  • The TWO_TASK environment variable can be set with the contents within the single quotation marks above. If this is done, then sqlplus will connect silently to the remote server as if it was local.

  • The connect descriptor definition within the single quotation marks above would likely be moved into your TNSNAMES.ORA or network TNS resolution method (ldap, onames).

  • The wallet is not required on the server—this functionality is handled by stunnel. The Oracle client needs the wallet if the client's TLS implementation will be used. It is possible to configure stunnel in client mode, then dispense with wallets on both sides.

  • While the sqlplus session is active, a stunnel process will appear on the server (be cautious of NPROC or other kernel limits):

    # ps -ef | grep stunnel
    nobody   16810     1  0 13:26 ?        00:00:00 /usr/bin/stunnel

Database Link

With two or more Oracle database servers, sessions and transactions can be initiated between them to gather and modify data in "two-phase commits". Linkages between accounts and servers are established with the command below (if you have moved tcps hosts into your TNSNAMES.ORA, you can reference them here also):

 CONNECT TO RemoteUser
 USING '(description=

Database link created.

Once the link is established, remote tables can be suffixed by the link name (which can be joined to other local or remote tables):



Server Verification

It may be necessary for keys to be verified on either side of the connection to assure authorized use. The native Oracle TLS implementation requires all keys subject to verification to be signed by a recognized CA (the CA's public keys may need to be added to the certificate store used by Oracle).

Note that stunnel also can verify keys and act as a client as well as a server. The stunnel verification options are much more flexible than Oracle's, and if CA signatures are not desired but TLS verification is mandated, then Oracle's TLS should be disabled entirely.

In the examples below, let's assume that the server's public key has a CA signature. To extract that public key, the following awk pattern is useful:

        /etc/pki/tls/certs/stunnel.pem > /tmp/pkey

Move the /tmp/pkey file to the client, then load it into the wallet:

$ORACLE_HOME/bin/orapki wallet add -wallet /home/oracle/wallet \
        -pwd SECRET123 -trusted_cert -cert /tmp/pkey

After loading the key, verify that it is now present in the wallet:

$ORACLE_HOME/bin/orapki wallet display -wallet /home/oracle/wallet \
        -pwd SECRET123

The key should appear in the Trusted Certificates section:

Oracle PKI Tool : Version
Copyright (c) 2004, 2014, Oracle and/or its affiliates. All
rights reserved.

Requested Certificates:
User Certificates:
Subject:        CN=%yourdb%
Trusted Certificates:
 ↪Division,O=ACME Corporation,L=Chicago,ST=IL,C=US
Subject:        CN=%yourdb%

The client can verify the server keys with the SSL_SERVER_CERT_DN clause in the TNS descriptor:

$ORACLE_HOME/bin/sqlplus fishecj@'(description=
 (security=(SSL_SERVER_CERT_DN="CN=,OU=Widget Division,
↪O=ACME Corporation,L=Chicago,ST=IL,C=US")

If the CA signature is not recognized, the sqlplus login will fail with the following:

ORA-29024: Certificate validation failure

Additionally, stunnel will record the following in /var/log/secure:

LOG7: SSL alert (read): fatal: unknown CA
LOG3: SSL_accept: 14094418: error:14094418:SSL
routines:SSL3_READ_BYTES:tlsv1 alert unknown ca

Such errors indicate that the CA is not properly loaded into the bundle used by the database.


Oracle database security has received pointed criticism through the years and releases, which has slowly improved the architecture and closed exploitable weaknesses. For many, these improvements are inadequate in both speed and scope. In such cases, stunnel is a valuable tool for authentication, isolation and privacy of critical data within Oracle.

Other Articles by Charles Fisher

"Cipher Security: How to Harden TLS and SSH", LJ, September 2015.

"Infinite BusyBox with systemd", LJ, March 2015.

"Strengthening Diffie-Hellman in SSH and TLS",, October 29, 2015.

"Secure File Transfer", LJ, January 2016.

Load Disqus comments