Hi Ian, A few years ago, the Red Hat/Fedora stunnel packaging was changed to use the system-wide crypto policy as the default cipher configuration: https://gitlab.com/redhat/centos-stream/rpms/stunnel/-/blob/c10s/stunnel-5.6... This third-party patch changes stunnel's default cipher list to PROFILE=SYSTEM. Since the system crypto policy enables finite-field DHE cipher suites, stunnel's existing code detects that DHE is available in your server-mode frontend sections and generates temporary 2048-bit DH parameters. The parameters are generated when the per-day worker starts and regenerated every 24 hours. The 100 ms poll() calls you are seeing come from a delay in stunnel's OpenSSL DH-generation progress callback. The delay is there to throttle CPU usage during DH parameter generation. Your explicit DHE-RSA-AES256-SHA settings in the backend sections are unrelated to this CPU usage, since those sections run in client mode and therefore do not generate DH parameters locally. Finite-field DHE cipher suites are generally not recommended for new TLS configurations in 2026. ECDHE, or TLS 1.3 key exchange, should normally be preferred. Your backend configuration appears to require DHE for compatibility with the legacy switches, but unless you also need DHE on the frontend connections, I would disable it there. Best regards, Mike On 8/23/26 17:25, Ian Pilcher via stunnel-users wrote:
I noticed that stunnel is constantly consuming 30% of one of my CPU cores. Looking at it with strace, I see that it is frequently (every 100 milliseconds?) waking up from a poll() system call, calling getpid() a couple of times and going back to sleep.
[pid 3498] poll([{fd=6, events=POLLIN|POLLRDHUP}], 1, 100) = 0 (Timeout) [pid 3498] getpid() = 3494 [pid 3498] getpid() = 3494 [pid 3498] poll([{fd=6, events=POLLIN|POLLRDHUP}], 1, 100) = 0 (Timeout) [pid 3498] getpid() = 3494 [pid 3498] getpid() = 3494 [pid 3498] poll([{fd=6, events=POLLIN|POLLRDHUP}], 1, 100) = 0 (Timeout) [pid 3498] getpid() = 3494 [pid 3498] getpid() = 3494 [pid 3498] poll([{fd=6, events=POLLIN|POLLRDHUP}], 1, 100) = 0 (Timeout) [pid 3498] getpid() = 3494 [pid 3498] getpid() = 3494
AFAICT, this is a pipe that stunnel is using to talk to itself (maybe to communicate between threads)?
# ls -l /proc/3498/fd total 0 lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 0 -> /dev/null lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 1 -> /dev/null lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 10 -> 'socket:[37674]' lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 11 -> 'socket:[37675]' lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 12 -> 'socket:[37676]' lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 2 -> /dev/null lr-x------. 1 stunnel stunnel 64 Aug 23 10:12 4 -> 'pipe:[38360]' l-wx------. 1 stunnel stunnel 64 Aug 23 10:12 5 -> 'pipe:[38360]' lr-x------. 1 stunnel stunnel 64 Aug 23 10:12 6 -> 'pipe:[38361]' l-wx------. 1 stunnel stunnel 64 Aug 23 10:12 7 -> 'pipe:[38361]' lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 8 -> 'socket:[37672]' lrwx------. 1 stunnel stunnel 64 Aug 23 10:12 9 -> 'socket:[37673]'
Is this expected behavior? Anything that can be done about it?
Environment: ============
stunnel 5.80 on x86_64-redhat-linux-gnu platform Compiled/running with OpenSSL 3.5.7 9 Jun 2026 Threading:PTHREAD Sockets:POLL,IPv6,SYSTEMD TLS:ENGINE,FIPS,OCSP,PSK,SNI,DTLS
Global options: fips = no RNDbytes = 1024 RNDfile = /dev/urandom RNDoverwrite = yes
Service-level options: ciphers = PROFILE=SYSTEM (with "fips = yes") ciphers = PROFILE=SYSTEM (with "fips = no") ciphersuites = TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256 (with TLSv1.3) curves = P-256:P-521:P-384 (with "fips = yes") curves = X25519MLKEM768:X25519:P-256:X448:P-521:P-384 (with "fips = no") debug = daemon.notice logId = sequential options = NO_SSLv2 options = NO_SSLv3 securityLevel = 2 sessionCacheSize = 1000 sessionCacheTimeout = 300 seconds stack = 131072 bytes TIMEOUTbusy = 300 seconds TIMEOUTclose = 60 seconds TIMEOUTconnect = 10 seconds TIMEOUTidle = 43200 seconds TIMEOUTocsp = 5 seconds verify = none
stunnel.conf: =============
debug = warning
[switch2-frontend] accept = 0.0.0.0:8402 CAfile = /etc/ipa/ca.crt cert = /etc/pki/tls/certs/stunnel/switch2.crt key = /tmp/keys/switch2.key connect = 127.255.255.254:8082
[switch2-backend] client = yes accept = 127.255.255.254:8082 connect = 172.31.4.2:443 verifyChain = yes checkHost = switch2.penurio.us CAfile = /etc/pki/tls/certs/stunnel/switch-ca.crt sslVersion = TLSv1 ciphers = DHE-RSA-AES256-SHA options = ALLOW_UNSAFE_LEGACY_RENEGOTIATION securityLevel = 0 OCSPrequire = no OCSPaia = no
[switch4-frontend] accept = 0.0.0.0:8404 CAfile = /etc/ipa/ca.crt cert = /etc/pki/tls/certs/stunnel/switch4.crt key = /tmp/keys/switch4.key connect = 127.255.255.254:8084
[switch4-backend] client = yes accept = 127.255.255.254:8084 connect = 172.31.4.7:443 verifyChain = yes checkHost = switch4.penurio.us CAfile = /etc/pki/tls/certs/stunnel/switch-ca.crt sslVersion = TLSv1 ciphers = DHE-RSA-AES256-SHA options = ALLOW_UNSAFE_LEGACY_RENEGOTIATION securityLevel = 0 OCSPrequire = no OCSPaia = no