Stunnel FAQ

Configuration

What is the difference between server mode and client mode?

Server mode is the default. Stunnel accepts TLS connections and forwards the decrypted traffic to the service selected by connect, exec, or a supported protocol handler.

Client mode is enabled with client = yes. Stunnel accepts plaintext traffic, normally on a loopback address, and establishes TLS to the target named by connect.

[local-client]
client = yes
accept = 127.0.0.1:8080
connect = server.example.com:443
verifyChain = yes
CAfile = /etc/ssl/certs/ca-certificates.crt
checkHost = server.example.com
sni = server.example.com

The CA bundle path varies by operating system.

Why does stunnel start but not listen on a port?

A standalone service needs a named section and an accept option:

[service]
accept = 0.0.0.0:8443
connect = 127.0.0.1:8080

A configuration without a service section is interpreted as an inetd-style configuration, in which another process supplies an already accepted socket. Inetd mode is primarily for legacy integrations.

Also check that:

Use accept = :::8443 to listen on all IPv6 addresses. IPv4 behavior for an IPv6 listening socket is operating-system-dependent.

How do I check a configuration?

The current command-line interface has no separate check-only option. Run stunnel in the foreground during initial testing:

foreground = yes
debug = info

Then start it with the explicit configuration path:

stunnel /etc/stunnel/stunnel.conf

Stunnel reports syntax errors and failures while loading certificates, keys, cryptographic settings, or listening sockets. If initialization succeeds, it continues running; stop it with Ctrl+C.

Where is the configuration file?

The default is selected at build time and is shown by stunnel -version. Common locations are /etc/stunnel/stunnel.conf and /usr/local/etc/stunnel/stunnel.conf. An explicit path avoids ambiguity:

stunnel /path/to/stunnel.conf

On Windows, use the installer-selected configuration directory or pass the intended configuration file explicitly.

Can one stunnel process run several services?

Yes. Add one named section for each service. Service-level options remain in effect until the next section. Put global options before the first section.

The include = DIRECTORY option loads configuration fragments in ascending filename order. Names such as 00-global.conf, 01-imap.conf, and 02-smtp.conf make the order clear.

Which TLS versions and ciphers should I configure?

The defaults provided by current stunnel and OpenSSL releases are preferable for most deployments. For a new service, set only the required minimum TLS version:

sslVersionMin = TLSv1.2

Use TLSv1.3 when all peers support it. Use sslVersionMin and sslVersionMax rather than disabling individual versions with options.

The ciphers option controls TLS 1.2 and earlier. The ciphersuites option separately controls TLS 1.3. Changing either can reduce security or interoperability, so keep the defaults unless a documented policy requires otherwise. Run stunnel -version to see the defaults of the installed build and stunnel -options to list supported TLS options.

How do I use SNI?

In client mode, set sni to the remote DNS name when the server hosts multiple TLS services:

sni = server.example.com

SNI selects the virtual server; it does not verify its identity. Use verifyChain = yes and checkHost = server.example.com as well.

In server mode, stunnel can route TLS connections to secondary service sections according to the client's SNI name. See the sni option in man stunnel for the primary and secondary service syntax.

Authentication and certificates

Does every stunnel service need a certificate?

No.

The key option defaults to the value of cert, so it may be omitted when the certificate chain and private key are stored in the same file.

How should a client verify a server certificate?

Certificate-chain validation and server-identity validation are separate checks. Configure both:

verifyChain = yes
CAfile = /path/to/trusted-ca-bundle.pem
checkHost = server.example.com
sni = server.example.com

Use checkIP instead of checkHost when connecting by an IP address represented in the certificate. Do not rely on SNI alone: it sends a name but does not authenticate it.

CAfile, CApath, and, with OpenSSL 3.0 or later, CAstore provide trust anchors. The syntax and availability of CAstore URIs depend on the linked OpenSSL providers.

What is the difference between verifyChain and verifyPeer?

The numeric verify option is obsolete and should not be used in new configurations.

Why does certificate verification fail with "unable to get local issuer certificate"?

Usually either the peer did not send the required intermediate certificate or the local trust store does not contain the issuing CA.

For a server, configure cert with the leaf certificate followed by the required intermediate certificates. For a client, point CAfile, CApath, or CAstore at the intended trust anchors. Do not solve this error by disabling verification.

Useful OpenSSL diagnostics include:

openssl s_client -connect server.example.com:443 \
  -servername server.example.com \
  -verify_hostname server.example.com \
  -CAfile trusted-ca-bundle.pem
openssl verify -CAfile trusted-ca-bundle.pem \
  -untrusted intermediate-chain.pem server.crt

Why does checkHost or checkIP fail?

The expected identity must appear in the leaf certificate's Subject Alternative Name extension. DNS names belong in checkHost; IP addresses belong in checkIP. Wildcard certificates match only according to the OpenSSL hostname-verification rules.

Make sure the value describes the final TLS server, not a local stunnel listener, load balancer address, or HTTP proxy.

How can I tell whether a certificate matches its private key?

Compare hashes of their public keys:

openssl x509 -in server.crt -pubkey -noout | openssl sha256
openssl pkey -in server.key -pubout | openssl sha256

The hashes must match.

Why does stunnel reject the private-key file permissions?

A private key allows an attacker to impersonate the service. On Unix, restrict it to the account that loads it:

chmod 600 /etc/stunnel/private/server.key

Set the owner to match the startup model. Root ownership is appropriate when stunnel starts as root and drops privileges; a service that starts unprivileged needs ownership or group permissions for its service account. The process must be able to read the key before applying setuid or setgid. PSK files must likewise be neither world-readable nor world-writable.

Can stunnel use PKCS#12 files, hardware tokens, or system stores?

The cert option accepts PEM or P12 certificate files. Current builds can also use certificate and key URIs supplied by OpenSSL engines or providers. OpenSSL 3 provider support includes the provider and providerParameter global options; availability depends on how stunnel and OpenSSL were built.

Use stunnel -version to inspect the linked OpenSSL version and the engine, FIPS, and other compile-time capabilities reported by the build. Consult man stunnel and the provider documentation before deploying a hardware-backed key.

How do I reload a renewed certificate?

After replacing the certificate and key atomically, reload the configuration:

Review the log to confirm that the new certificate and key loaded successfully. Test renewal and reload procedures before the certificate expires.

Should I use a self-signed certificate?

Self-signed certificates are suitable for controlled testing and can be used for pinning. Every client must explicitly trust the certificate, and the certificate still needs correct Subject Alternative Name entries.

For public or broadly distributed services, use a certificate from an appropriate CA. Never disable certificate verification merely to make a self-signed certificate work.

Troubleshooting

What information should I collect before reporting a problem?

Include:

Start with debug = info. Use debug = debug (equivalent to debug = 7) only when requested by a stunnel developer or technical support; it is intentionally very verbose.

What does "wrong version number" or "unknown protocol" mean?

This usually means that one side expected TLS while the other sent plaintext. Check:

For STARTTLS-style services, use the appropriate protocol handler rather than connecting TLS directly to the plaintext protocol port.

Why does the TLS handshake fail after I changed the cipher configuration?

TLS 1.3 and earlier versions use separate settings:

The selected certificate type, TLS version limits, OpenSSL security level, and peer policy must also be compatible. Restore the defaults first, then make one policy change at a time. stunnel -version prints the active defaults.

Why can stunnel connect to the TLS peer but not pass application data?

TLS only protects the bytes; it does not make incompatible application protocols compatible. Verify that:

Capture traffic on the plaintext side only in a controlled environment because it may contain credentials or other sensitive data.

Why is a connection slow to start?

Common causes include DNS timeouts, an unreachable first connect target, OCSP delays, overloaded backends, and network packet loss.

Stunnel automatically uses delayed resolution when a target cannot be resolved at startup. Set delay = yes when DNS must always be deferred, such as with dynamic DNS. Note that delayed resolution uses priority failover.

Avoid changing socket options such as TCP_NODELAY until measurements identify a TCP buffering problem.

What does "too many open files" mean?

The process reached an operating-system resource limit. Each proxied connection consumes multiple file descriptors. Increase the service's file-descriptor limit and verify process, memory, and service-manager limits. On systemd, the relevant unit setting is commonly LimitNOFILE.

Do not set an unlimited TLS session cache merely to work around capacity issues; sessionCacheSize = 0 can permit a memory-exhaustion denial of service.

Why does stunnel fail after chroot or dropping privileges?

Paths and permissions change when chroot, setuid, or setgid is used. The jail may need copies of:

Paths documented as relative to the chroot must be written accordingly. Also remember that a process which has dropped privileges may be unable to rebind privileged ports during a reload.

Stunnel reports a random-number-generator error. What should I do?

Current OpenSSL releases normally obtain entropy from the operating system. Treat a failure as an operating-system, container, or OpenSSL initialization problem; do not seed the generator with arbitrary files or copied kernel data.

RNDfile and EGD remain available for unusual or legacy platforms. Use them only with a well-designed entropy source and follow the OpenSSL guidance for that platform.

Do TCP Wrappers still control access?

Not by default. libwrap defaults to no and is available only in builds compiled with that support. If a legacy deployment requires /etc/hosts.allow and /etc/hosts.deny, set libwrap = yes and confirm Auth:LIBWRAP appears in stunnel -version.

For new deployments, use the operating-system firewall, service-manager controls, network policy, and TLS client authentication.

Applications and protocols

Can stunnel protect any TCP service?

Usually, if the application uses one TCP connection and either:

Current protocol handlers include IMAP, LDAP, NNTP, PostgreSQL, POP3, SMTP, HTTP CONNECT, SOCKS, and HAProxy PROXY protocol, among others. Run man stunnel for the exact list in the installed version.

Protocols that open additional dynamic connections, depend on unusual out-of-band behavior, or embed network addresses may need application-aware gateways.

Can stunnel forward UDP?

Yes. Current stunnel versions support DTLS over UDP:

[dtls-service]
transport = udp
accept = 0.0.0.0:9443
connect = 127.0.0.1:9000
cert = /etc/stunnel/server-fullchain.pem
key = /etc/stunnel/private/server.key

Each datagram opens a logical connection within the service, so confirm that this behavior fits the application. Both endpoints must use compatible DTLS configurations; setting transport = udp does not convert an arbitrary TCP protocol into UDP or vice versa.

Can stunnel wrap FTP?

Not as a generic single tunnel. FTP opens separate, dynamically negotiated data connections. Use an FTP implementation with native TLS support or a protocol-aware gateway.

How do I use a STARTTLS-style protocol?

Set protocol to the application protocol so stunnel performs the plaintext negotiation before enabling TLS. For example, a client-side SMTP tunnel may use:

[smtp-submission]
client = yes
accept = 127.0.0.1:1025
connect = mail.example.com:587
protocol = smtp
protocolHost = client.example.com
verifyChain = yes
CAfile = /etc/ssl/certs/ca-certificates.crt
checkHost = mail.example.com
sni = mail.example.com

Do not set protocol when connecting to a port that expects TLS immediately, such as the usual implicit-TLS ports.

How do I connect through an HTTP proxy?

Use the client-side HTTP CONNECT handler. connect names the proxy, while protocolHost names the final TLS server:

[through-proxy]
client = yes
accept = 127.0.0.1:8443
connect = proxy.example.net:3128
protocol = connect
protocolHost = server.example.com:443
verifyChain = yes
CAfile = /etc/ssl/certs/ca-certificates.crt
checkHost = server.example.com
sni = server.example.com

If required, configure protocolUsername, protocolPassword, and protocolAuthentication. Protect configuration files containing credentials.

Can stunnel load-balance or fail over between backends?

Yes. Specify connect more than once:

[service]
accept = 0.0.0.0:8443
connect = backend1.example.com:8080
connect = backend2.example.com:8080
failover = rr
cert = /etc/stunnel/server-fullchain.pem
key = /etc/stunnel/private/server.key

Use failover = rr for round-robin distribution or failover = prio to prefer targets in configuration order.

How can the backend learn the original client address?

If the backend understands HAProxy PROXY protocol version 1, use protocol = proxy. Otherwise, selected Unix platforms support transparent = source, which requires elevated privileges and operating-system routing or firewall configuration.

Do not enable either mode unless the backend and network are configured to trust it. In particular, a backend must not accept forged PROXY headers from untrusted sources.

Can stunnel connect to a Unix-domain socket?

Yes, on Unix. An address parameter may be a TCP port, a host-and-port pair, or a Unix socket path. The stunnel account needs the appropriate filesystem permissions. Service-level setuid and setgid can set the owner and group of a Unix socket created by accept.

Operations and performance

How do I reload stunnel or rotate its log?

On Unix:

The chroot, foreground, pid, setgid, and setuid global options are not changed by a reload. Prefer the package's service-manager commands when available.

On Windows services, use stunnel -reload, stunnel -reopen, and stunnel -stop.

How does TLS session resumption work?

Session resumption avoids a full handshake on repeat connections. Current deployments normally use TLS session tickets, especially with TLS 1.3. Stunnel also has an internal session cache for session-ID-based resumption and can use sessiond for legacy clustered deployments.

Relevant options include sessionResume, sessionCacheSize, and sessionCacheTimeout. Keep the defaults unless measurements or cluster design justify a change. See sessiond before deploying the external cache.

How do I list available ciphers and curves?

The effective choices depend on both stunnel and the linked OpenSSL library:

stunnel -version
openssl ciphers -v
openssl ecparam -list_curves

TLS 1.3 ciphersuites may need a separate OpenSSL query depending on the OpenSSL release. The defaults printed by stunnel -version are the most useful starting point.

How can I delay DNS lookups until connection time?

Use:

delay = yes

This is useful for dynamic DNS or systems where DNS is unavailable during startup. Stunnel also engages delayed resolution automatically when a connect target cannot be resolved at startup. Delayed resolution implies priority failover.

Which ports should I use?

Use the port assigned to the application protocol when one exists, or a locally approved unassigned port for private deployments. Consult the current IANA Service Name and Transport Protocol Port Number Registry.

A registered port does not guarantee that a particular application uses implicit TLS, STARTTLS, TCP, or UDP. Confirm the protocol expected by both peers.

Where can I find the authoritative option syntax?

Use the documentation installed with the same build:

man stunnel
stunnel -help
stunnel -version
stunnel -options
stunnel -sockets

The manual reflects build-dependent features and should take precedence over examples written for older stunnel or OpenSSL releases.

Our supporters:
Go to the top