Stunnel
Stunnel is a free and open-source multi-platform proxy software designed to provide universal TLS/SSL tunnel encryption, enabling the addition of TLS protection to arbitrary TCP connections between existing clients and servers without requiring any modifications to the applications' source code. Initially released on February 10, 1998, the latest stable version is 5.76, released on October 18, 2025.[1][2][3]
Developed by Michał Trojnara, Stunnel functions as an encryption wrapper that secures communications for non-TLS-aware programs, such as POP3, IMAP, or other inetd-startable services, by listening on specified ports, encrypting incoming traffic, and forwarding it to the target server.[1][4]
It relies on the OpenSSL library for cryptographic operations, supporting a variety of algorithms compiled into OpenSSL, and includes features like FIPS 140-2 validation through the OpenSSL FIPS Provider for compliance in regulated environments.[1][5]
Licensed under the GNU General Public License version 2 or later with an OpenSSL exception to permit dynamic linking, Stunnel is optimized for security, portability across Unix-like systems and Windows, and scalability, including load-balancing capabilities for high-traffic deployments.[1]
Widely used in enterprise settings for retrofitting encryption to legacy protocols, it offers commercial support options alongside community resources, making it a reliable choice for enhancing network security without architectural overhauls.[1][6]
Overview and History
Purpose and Functionality
Stunnel is an open-source proxy designed to add TLS encryption functionality to existing clients and servers without requiring any changes to the programs' code. It achieves this by creating encrypted tunnels for arbitrary TCP connections, leveraging the OpenSSL library for cryptographic operations. This allows Stunnel to support a wide range of cryptographic algorithms as compiled into the OpenSSL library, ensuring compatibility with modern security standards.[1][1]
As an encryption wrapper, Stunnel operates by intercepting unencrypted traffic on a specified local port, encapsulating it within a TLS-secured connection, and forwarding it to a remote server. Conversely, on the receiving end, it can decrypt incoming TLS traffic and relay the plaintext to the target service. This intermediary role enables seamless integration of encryption into network communications without altering underlying applications.[7][8]
Stunnel plays a key role in securing legacy or non-TLS protocols, such as SMTP and IMAP, by allowing them to operate over protected channels that would otherwise expose sensitive data to interception. For instance, it can wrap these protocols in TLS to facilitate secure email retrieval and transmission in environments where native support is absent. This capability is particularly valuable for maintaining compatibility with older systems while enforcing encryption.[7]
Stunnel supports two primary operational modes: client-side, where it encrypts outgoing connections from a local application to a remote endpoint, and server-side, where it decrypts incoming connections before passing them to a local service. These modes can be configured independently, providing flexibility for diverse deployment scenarios such as securing inbound services or initiating outbound secure tunnels.[9]
Development Timeline
Stunnel was developed as a personal project by Polish programmer Michał Trojnara, who has remained its sole primary author since its inception.[1] The project began in early 1998, with the initial version 0.1 released on February 10, 1998, as a basic testing skeleton for SSL encryption wrapping of TCP connections.[2] The first public stable release, version 3.0, followed on April 19, 1999, introducing features such as client mode and peer certificate verification.[2] From the outset, Stunnel has been distributed under the GNU General Public License version 2 or later, with an exception for compatibility with the OpenSSL library.[1]
The software's major version progression reflects a steady evolution from foundational SSL tunneling capabilities to enhanced security and compatibility features. Version 4.00, released on August 30, 2002, marked a significant overhaul, supporting OpenSSL 0.9.6g and adding standalone server mode improvements.[2] Subsequent releases in the 4.x series incorporated key advancements, including IPv6 support in version 4.06 on December 26, 2004; session caching in 4.15 on March 11, 2006; FIPS 140-2 compliance in 4.21 on October 27, 2007; and compression via zlib in 4.51 on January 9, 2012.[2] The transition to version 5.00 on March 6, 2014, introduced support for OpenSSL 1.0.1 and improved thread safety, with ongoing updates integrating newer OpenSSL engines for cryptographic operations.[2]
Notable developments in the mid-2000s and beyond emphasized integration with OpenSSL engines for hardware acceleration and the addition of session caching and compression to optimize performance without expanding into a multi-contributor community project.[1] Trojnara has retained full control over the codebase, ensuring consistent design focused on reliability and minimal dependencies.[1]
As of 2025, Stunnel remains actively maintained by Trojnara, with the latest stable release, version 5.76, issued on October 18, 2025, featuring security bugfixes and OpenSSL 3.5.4 integration.[2] Commercial support options are available, including tiered plans with response times up to a 24/7 helpline for enterprise users, alongside free community resources like mailing lists.[10]
Technical Features
Core Capabilities
Stunnel employs multiple threading models to ensure portability across diverse operating systems and environments. It supports PTHREAD for POSIX-compliant systems, providing efficient multithreading on Unix-like platforms; FORK for traditional Unix environments, leveraging process forking for concurrency; UCONTEXT for user-level threading, which avoids kernel dependencies for lighter-weight operations; and WIN32 threads for native Windows integration.[11]
To enhance performance and scalability, Stunnel incorporates load balancing mechanisms using round-robin and priority-based strategies, distributing connections across multiple backend servers to prevent bottlenecks. It also features external session caching, which allows clusters to share TLS session data and reduce the computational overhead of repeated handshakes, particularly beneficial in high-traffic scenarios where resumed sessions can achieve up to 4,700 connections per second on a single core. Additionally, data compression is supported to optimize bandwidth usage in constrained networks, though it trades some CPU cycles for reduced transmission sizes.[11][12]
Advanced proxy behaviors in Stunnel include transparent proxy mode, available on select platforms, which intercepts traffic without requiring client modifications by binding to local addresses. A delayed DNS resolver handles intermittent connectivity, such as in dial-up or dynamic IP setups, by postponing name resolution until necessary. Furthermore, the server supports graceful reloading of configuration and log files, enabling updates without interrupting active connections.[11]
For integration, Stunnel leverages OpenSSL engines, including the CAPI engine for utilizing Microsoft CryptoAPI on Windows, allowing hardware-accelerated cryptography where available. It handles UTF-8 encoding in configuration and log files for international compatibility, and implements ident-based access control to restrict connections based on user identification protocols.[11]
Stunnel supports a wide range of operating systems, with tailored features for Unix-like environments and Windows. On Unix-like systems such as Linux, BSD, and Solaris, it integrates with security mechanisms including chroot for process isolation, setuid and setgid for privilege dropping, and libwrap (TCP Wrappers) for access control based on hostnames or IP addresses.[11][13] On Windows, Stunnel provides a graphical user interface (GUI) for configuration and monitoring, operates in service mode for background execution, and supports cached storage of peer certificate chains to facilitate certificate verification without repeated disk access.[11][13]
In terms of network capabilities, Stunnel offers full IPv6 support for both client and server connections, enabling seamless operation in dual-stack environments. It also handles Unix domain sockets for local inter-process communication, supports systemd socket activation for on-demand service startup, and includes pseudo-terminal (PTY) allocation to enable interactive sessions over encrypted tunnels.[11][13]
Stunnel includes built-in protocol negotiation wrappers to transparently add TLS encryption to various application-layer protocols without modifying client or server code. These wrappers handle initial handshakes for protocols such as CIFS (for Samba file sharing), CONNECT (for HTTP proxies), IMAP (email retrieval), NNTP (Usenet news), PostgreSQL (database connections), POP3 (email download), PROXY (HAProxy protocol), SMTP (email submission), and SOCKS versions 4, 4a, and 5 (general proxying). Additionally, it can redirect connections to TLS upon authentication failures for certain protocols, ensuring secure fallback.[11][13][7]
For operational controls, Stunnel integrates with syslog on Unix-like systems for standardized logging, acts as an EGD (Entropy Gathering Daemon) client to gather random data for cryptographic operations, and functions as protocol-specific gateways that proxy traffic while preserving original protocol semantics.[11][13]
Installation and Configuration
Installation Methods
Stunnel requires the OpenSSL library as a mandatory dependency, with version 1.1.0 or newer recommended for compatibility with modern cryptographic features.[9] An optional dependency is libwrap for integration with TCP wrappers to control access based on host rules.[9]
For Unix-like systems, Stunnel can be compiled from source by downloading the latest tarball, such as stunnel-5.76.tar.gz, from the official website.[14] After extracting the archive, ensure OpenSSL is installed, then run ./configure to prepare the build environment (which checks for optional libwrap), followed by make to compile and make install to deploy the binaries, typically to /usr/local.[9]
Stunnel is available through popular package managers on various platforms. On Debian and Ubuntu systems, install it using sudo apt install stunnel4, which provides the stunnel4 package containing the daemon and utilities. For Red Hat Enterprise Linux (RHEL) and CentOS, use sudo dnf install stunnel (or sudo yum install stunnel on older versions) to obtain the package from the base repositories.[15] On macOS, Homebrew users can install it with brew install stunnel, which handles dependencies like OpenSSL automatically.[16]
On Windows, download and run the official 64-bit MSI installer, such as stunnel-5.76-win64-installer.exe, from the Stunnel website; this bundle includes the OpenSSL FIPS Provider for Federal Information Processing Standards compliance.[14] After installation, register Stunnel as a Windows service by executing stunnel.exe -install from an administrator command prompt in the installation directory.[9]
To verify the installation, run stunnel -[version](/page/Version) from the command line, which displays the Stunnel build version, compilation flags, and linked OpenSSL details, including FIPS mode support if applicable.[9] The default configuration file is located at /etc/stunnel/stunnel.conf on Unix-like systems or in the installation directory on Windows.[9]
Configuration Syntax and Options
Stunnel's configuration is managed through a single primary file, typically named stunnel.conf, which follows an INI-style format consisting of global options at the top followed by one or more service sections enclosed in square brackets, such as [service_name]. This structure allows for modular definition of multiple TLS-encrypted services within the same file, with each service section inheriting global options unless overridden. The configuration parser supports case-insensitive keys but requires exact matching for section names and values.[7][17]
Global options control overall behavior and are placed before any service sections; examples include debug = 7 to set the logging verbosity level (where 7 enables detailed debugging output) and output = /path/to/logfile to specify a custom log file location instead of standard output. The pid = /var/run/stunnel.pid directive designates the file where the process ID is stored, facilitating management tasks like restarts or signals on Unix-like systems. These options apply universally unless a service section redefines them.[7][17]
Service sections define individual TLS tunnels and must include at minimum an accept directive for incoming connections and a connect directive for outgoing ones. The accept = [host:]port option specifies the local address and port where Stunnel listens for unencrypted connections, such as accept = 127.0.0.1:8080, while connect = remote_host:remote_port routes encrypted traffic to the backend server, for instance connect = [example.com](/page/Example.com):443. For server-mode operation, cert = /path/to/cert.pem provides the path to the server's certificate chain file, and key = /path/to/key.pem specifies the corresponding private key file, which can be omitted if included in the certificate file. In client mode, activated by client = yes, these services initiate outbound TLS connections, often paired with verify = 2 to enforce validation of the peer's full certificate chain against trusted certificate authorities.[7][17]
Cipher suite restrictions are configured via ciphers = cipher_list in service sections, allowing selection of secure protocols such as ciphers = HIGH:!aNULL to permit only high-strength ciphers while excluding anonymous ones, applicable to TLS versions 1.2 and earlier. For TLS 1.3 (supported with OpenSSL 1.1.1+), use the ciphersuites option to specify allowed cipher suites, such as ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256.[7] For enhanced security in peer authentication, the verify level can range from 0 (none) to 4 (require and verify chain), with level 2 being a common choice for strict chain validation without hostname checking. Protocol-specific behaviors, such as protocol = smtp for SMTP STARTTLS negotiation, can be set per service to handle application-layer handshakes.[7]
Advanced configuration supports modularity through include = /directory/for/includes, which recursively loads additional .conf files from the specified directory, enabling separation of global and service-specific settings across multiple files. Process management options like pid ensure proper daemon handling, while logging can be directed with output to a file or syslog facility. Syntax rules include line-based comments prefixed with ; or #, and quoted strings for values containing spaces, such as cert = "/path with spaces/cert.pem". Configuration reloading is achieved on Unix systems by sending a SIGHUP signal to the running process, updating most options without interruption except for immutable ones like chroot or user/group settings; on Windows, the -reload command-line option serves a similar purpose for NT services.[7][17]
Applications and Examples
Common Use Cases
Stunnel is frequently employed to secure email protocols by encapsulating unencrypted SMTP traffic on port 25 within a TLS-encrypted tunnel on submission port 465, thereby protecting sensitive credentials and message content from interception during transmission.[7] This approach is particularly useful for legacy mail servers that do not natively support STARTTLS, allowing administrators to enforce encryption without modifying the underlying SMTP daemon.[18] Similarly, Stunnel can wrap IMAP and POP3 connections for older servers, enabling secure retrieval of emails over public networks by listening on standard TLS ports like 993 for IMAP and 995 for POP3.[7]
In database environments, Stunnel serves as a frontend proxy to encrypt connections to PostgreSQL servers, especially when client applications lack built-in SSL support, ensuring data-in-transit protection for queries and authentication.[19] By configuring Stunnel with the protocol = pgsql option, it handles the TLS handshake and forwards decrypted traffic to the database on port 5432, mitigating risks from unencrypted wire exposure in distributed setups.[7]
For legacy applications, Stunnel facilitates secure tunneling to outdated services such as older IMAP/POP3 servers or CIFS/SMB file shares, allowing encrypted access over insecure networks without requiring protocol updates to the backend systems.[7] In CIFS scenarios, it proxies SMB traffic on port 445, encrypting file transfers between clients and Samba servers to prevent eavesdropping on shared resources.[20]
Load-balanced deployments leverage Stunnel's round-robin failover capabilities to distribute incoming encrypted traffic across multiple backend servers, enhancing high availability for services like web proxies or API endpoints.[11] This setup accepts TLS connections on a single frontend port and alternates connections to backend hosts, providing fault tolerance while maintaining end-to-end encryption.
As a firewall proxy, Stunnel integrates with libwrap (TCP wrappers) to enforce access controls based on client IP or hostname before decrypting and forwarding traffic, combining encryption with granular security policies at network gateways.[9] This configuration is common in restricted environments where Stunnel acts as a secure intermediary, rejecting unauthorized connections via hosts.allow/hosts.deny rules while tunneling approved sessions.[7]
Sample Configurations
Stunnel configuration files are typically structured with global options followed by service-specific sections enclosed in square brackets. These examples illustrate practical setups for common scenarios, drawing from official templates provided in the Stunnel distribution.[17][21]
For providing SMTPS service on port 465 using implicit TLS, a server-mode section can be defined as follows. This configuration accepts incoming TLS connections on the standard SMTPS port and forwards the decrypted traffic to a local unencrypted SMTP service on port 25, using a server certificate for encryption.
[ssmtp]
accept = 465
connect = 127.0.0.1:25
cert = server.pem
[ssmtp]
accept = 465
connect = 127.0.0.1:25
cert = server.pem
[imap-client]
client = yes
accept = 127.0.0.1:1143
connect = mail.example.com:993
verifyChain = yes
[imap-client]
client = yes
accept = 127.0.0.1:1143
connect = mail.example.com:993
verifyChain = yes
Here, client = yes activates client-mode operation, and verifyChain = yes ensures the remote server's certificate chain is validated against trusted authorities, enhancing security during the handshake.[17][22]
To implement load balancing across multiple backend servers, multiple connect directives can be specified within a single service section, with the default failover = prio behavior distributing connections in priority order (first connect target preferred until failure, then fallback). This is useful for high-availability setups, such as proxying HTTP traffic.
[http-proxy]
accept = 8080
cert = server.pem
connect = backend1.example.com:80
connect = backend2.example.com:80
failover = prio
[http-proxy]
accept = 8080
cert = server.pem
connect = backend1.example.com:80
connect = backend2.example.com:80
failover = prio
The round-robin alternative (failover = [rr](/page/R&R)) can be used instead for even distribution, but priority mode prioritizes the listed order for weighted or sequential load handling.[22]
On Windows, Stunnel can be installed and managed as a service via its graphical installer, which prompts for private key passphrases during setup and allows editing configurations through a GUI interface. A sample HTTPS forwarding service, suitable for this environment, terminates TLS on port 443 and forwards to a local HTTP server, including a timeout adjustment to mitigate truncation issues in Microsoft SChannel implementations.
[https]
accept = 443
connect = 127.0.0.1:80
cert = server.pem
TIMEOUTclose = 0
[https]
accept = 443
connect = 127.0.0.1:80
cert = server.pem
TIMEOUTclose = 0
The TIMEOUTclose = 0 option prevents premature closure without a TLS close-notify alert, addressing a known vulnerability in Windows SSL/TLS handling. The GUI facilitates passphrase entry for encrypted keys without exposing them in plain text.[21]
For resilient connection handling in unstable networks, global or per-service options can enable retries on failure and delay DNS resolutions. These directives promote automatic recovery without manual intervention.
; Global options
retry = yes
delay = yes
; Global options
retry = yes
delay = yes
The retry = yes setting attempts reconnection after disruptions, while delay = yes postpones DNS lookups for dynamic hostnames until connection time, reducing resolution errors.[22]
Security and Maintenance
Encryption and Authentication
Stunnel relies on the OpenSSL library as its cryptographic backend to implement TLS and SSL protocols, with support for TLS 1.2 and higher being mandatory in configurations using OpenSSL 3.0 or later, while TLS 1.3 is fully supported when using OpenSSL 1.1.1 or newer.[7] This integration enables Stunnel to handle encryption for arbitrary TCP connections without requiring modifications to the underlying applications. Additionally, Stunnel supports Pre-Shared Key (PSK) authentication for both clients and servers, X.509 digital certificates for public-key cryptography, and revocation checking through Certificate Revocation Lists (CRL) and Online Certificate Status Protocol (OCSP) via OpenSSL's capabilities.[23][7]
For key exchange, Stunnel enforces Perfect Forward Secrecy (PFS) using Diffie-Hellman (DH) and Elliptic Curve Diffie-Hellman (ECDH) parameters, with 2048-bit DH parameters hardcoded or autogenerated temporarily every 24 hours in versions 5.18 and later.[7] Cipher suites are customizable through the ciphers option for TLS 1.2 and below, and ciphersuites for TLS 1.3, with defaults excluding weak options such as NULL authentication or export-grade ciphers to ensure robust security; for example, suites like TLS_AES_256_GCM_SHA384 are prioritized for TLS 1.3.[7] ECDH curves, such as X25519 or P-256, can be specified via the curves option, aligning with OpenSSL's supported elliptic curves.[7]
Authentication in Stunnel centers on server-side certificate presentation, which is mandatory unless PSK is employed, using X.509 certificates in PEM format stored in files like cert.pem and key.pem.[23][9] Client certificate verification is optional and configurable across four levels: level 0 disables verification; level 1 verifies the peer certificate chain only if presented; level 2 requires verification of the full chain against trusted CAs specified in CAfile; and level 3 extends this to check the end-entity (leaf) certificate's CRL status.[7] Level 4, while supported in earlier versions for specific pinning scenarios, is handled through options like verifyPeer in modern setups for certificate validation without full chain checks.[7][24] Server Name Indication (SNI) is supported for virtual hosting multiple domains on a single IP address, allowing selection of appropriate certificates based on the client's requested hostname.[7]
Stunnel achieves FIPS 140-2 compliance by activating the OpenSSL FIPS Provider through the fips = yes configuration option, which restricts operations to approved algorithms and requires a FIPS-capable OpenSSL build; this provider holds NIST validation certificate #4282, ensuring adherence to federal cryptographic standards.[7][5]
Certificate management in Stunnel accommodates both self-signed certificates, generated via OpenSSL commands like make cert or manual creation, and CA-issued certificates obtained through Certificate Signing Requests (CSRs) submitted to trusted authorities.[9] Passphrase-protected private keys are supported but can be converted to unprotected format using openssl rsa -in key.pem -out key-unprotected.pem for automation; certificate chains, including intermediate CAs, are handled by appending them to the primary certificate file in PEM format.[9][25]
Vulnerabilities and Best Practices
Stunnel, relying on OpenSSL for its cryptographic operations, has been affected by several OpenSSL-dependent vulnerabilities, including the Heartbleed bug (CVE-2014-0160), a critical information disclosure flaw in the TLS heartbeat extension that allowed attackers to read up to 64 KB of server memory, potentially exposing private keys and sensitive data; this impacted Stunnel versions prior to 5.01, which was released on April 8, 2014, to incorporate OpenSSL 1.0.1g and mitigate the issue.[2] Another notable OpenSSL-related vulnerability was CVE-2014-0016, a private key leakage due to improper pseudo-random number generator (PRNG) state updates in fork-threaded environments, affecting Stunnel versions before 5.00, with version 5.00 released in March 2014 addressing the issue through enhanced PRNG handling.[2][26] Stunnel-specific bugs have been rarer but significant, such as the buffer overflow in NTLM authentication during CONNECT protocol negotiation (CVE-2013-1762), which could lead to remote code execution and was fixed in version 4.55 in March 2013, with the fix carried forward into the 5.x series. More recent Stunnel-specific issues include CVE-2021-20230, an authentication bypass with the "redirect" option, fixed in version 5.56 in October 2021.[2][27]
Common deployment risks stem primarily from configuration errors rather than inherent flaws. Insufficient certificate verification levels, such as using verify = 0 or 1, can enable man-in-the-middle (MITM) attacks by accepting untrusted or self-signed certificates without chain validation.[17] Failure to restrict cipher suites may allow weak algorithms like those vulnerable to attacks such as BEAST or Lucky Thirteen, particularly if legacy SSLv2 or SSLv3 protocols are not explicitly disabled via options like NO_SSLv2 and NO_SSLv3.[8] Unthrottled connection handling without rate limiting can expose Stunnel to denial-of-service (DoS) attacks, as seen in older issues like CVE-2002-1563 involving signal race conditions, though modern versions incorporate better resource management.[27]
To mitigate these risks, administrators should always deploy the latest version of Stunnel, such as 5.76 released on October 18, 2025, which includes updates to OpenSSL 3.5.4 for ongoing security patches; as of November 2025, beta version 5.77 is available for testing.[3][2][14] Enable strict peer authentication with verify = 3 or higher combined with verifyChain = yes to enforce full certificate chain validation, and activate OCSP stapling using OCSPaia = yes for real-time revocation checks without external queries.[17] Restrict listening and connection endpoints to specific IP addresses via accept and connect directives to minimize exposure, and configure cipher restrictions to prioritize modern suites like TLS 1.3 with cipher = ECDHE-ECDSA-AES256-GCM-SHA384 or equivalent, while disabling insecure protocols.[8]
For maintenance, automate Certificate Revocation List (CRL) and OCSP updates to ensure timely invalidation of compromised certificates, and test FIPS 140-2 compliance mode (fips = yes) in a staging environment before production use to verify adherence to federal cryptographic standards.[17] On Unix-like systems, implement privilege separation by enabling chroot = /var/run/stunnel to confine the process and setuid = nobody / setgid = nogroup to drop root privileges post-startup, avoiding execution as root entirely.[8] Regular monitoring of logs (e.g., via output = /var/log/stunnel.log) is essential to detect anomalies like handshake failures or unauthorized access attempts.
Auditing Stunnel deployments involves tools such as openssl s_client -connect [localhost](/page/Localhost):port -servername example.com to simulate connections and verify TLS negotiation, certificate validity, and cipher usage. Integrate with system monitoring solutions to alert on certificate expiration or unusual traffic patterns, ensuring proactive security maintenance.[9]