Every Linux server has OpenSSL installed. It handles your mail client, your SSH daemon, your package manager, your Python scripts — everything that touches cryptography leans on it. That’s exactly the problem.
When you compile NGINX or Angie against the system OpenSSL, you get the full Swiss Army knife edition: FIPS support, email signing (CMS), IP routing certificate extensions (RFC 3779), legacy ciphers that haven’t been relevant since the early 2000s, manpages, static analysis tools, the openssl command-line binary — all of it, loaded into a process whose only job is to terminate TLS connections and proxy web traffic as fast as possible.
So we built openssl-nginx: a dedicated OpenSSL 3.5 build compiled specifically for NGINX and Angie, with every compile flag tuned for the job of a modern webserver. Nothing more, nothing less.
Why a Dedicated OpenSSL Build for NGINX?
A general-purpose OpenSSL has to be safe for everyone. That means defaulting to the lowest common denominator — enabling things that might be needed by some use case somewhere, even if that use case is a 2003 Windows server. NGINX doesn’t have those constraints. It runs on modern Linux. It speaks modern TLS. It doesn’t need to sign emails or negotiate SSL 3.0 with a browser from 2004.
When you build for a specific purpose, you can make better choices. You can turn on things that genuinely matter, and ruthlessly cut everything that doesn’t. That’s what openssl-nginx does — and the result is a smaller attack surface, lower overhead, and a library you can actually reason about.
Performance Features Enabled in openssl-nginx
Kernel TLS Offload (kTLS)
This is the biggest win. Kernel TLS lets the Linux kernel handle TLS record encryption and decryption directly in kernel space, bypassing the usual round-trip where data has to be copied into userspace, encrypted, then copied back. When kTLS is active, NGINX can use sendfile() for encrypted traffic — meaning a file goes straight from disk to the network card without ever touching userspace memory.
The result is dramatically lower CPU usage for file serving and significantly better throughput on high-volume servers. kTLS has been in the kernel since version 4.13 and is stable since 5.x — but it only works if OpenSSL was compiled with kTLS support. We make sure it’s always on.
Faster Elliptic Curve Math (ec_nistp_64_gcc_128)
TLS 1.3 and TLS 1.2 ECDHE cipher suites rely heavily on elliptic curve point multiplication — specifically on curves like P-256 and P-384. These operations happen at the very start of every TLS handshake.
On 64-bit CPUs, OpenSSL can use an optimised implementation that uses 128-bit integers (a GCC extension) to do field arithmetic more efficiently. This is what ec_nistp_64_gcc_128 enables. Handshakes get measurably faster — something that matters significantly on servers processing tens of thousands of TLS connections per second. This flag is not on by default in a standard OpenSSL build. We turn it on.
Hardware Entropy via RDRAND
Generating cryptographically secure random numbers requires entropy. On a busy server that’s just started up — or inside a container with a thin view of the host’s entropy pool — the kernel’s RNG can be slow to seed. RDRAND is an x86 CPU instruction that reads random numbers directly from a hardware entropy source built into Intel and AMD processors.
With RDRAND enabled, OpenSSL pulls entropy from the CPU itself: fast, reliable, and unaffected by system load. TLS session keys and nonces are generated without stalling, and startup is snappier in containerized environments where the entropy pool is typically shallow.
TCP Fast Open
TCP Fast Open allows data to be sent in the initial SYN packet of a TCP handshake, eliminating one full round-trip for repeat connections. For TLS over TCP, this cuts latency on reconnects. NGINX supports TCP Fast Open natively, and OpenSSL needs to be built with awareness of it. We compile it in.
The OpenResty Session Yield Patch
This one is subtle but important for anyone running OpenResty (NGINX + LuaJIT) or any Lua-based NGINX setup. The patch adds a new return-reason code and a new wait-state to OpenSSL’s SSL state machine.
What it enables: when NGINX needs to look up a TLS session for session resumption, it can now yield back to the event loop instead of blocking. In a standard OpenSSL build, session lookup is synchronous — if you’re doing it from a Lua coroutine or an async Redis call, you either block the worker or need ugly workarounds. With this patch, the SSL handshake can pause mid-flight, let the event loop serve other requests, and resume once the session data is ready. OpenResty has shipped this patch for years. We bring it forward to OpenSSL 3.5.
What Gets Removed — and Why
A lean library isn’t just about what you add. It’s equally about what you remove.
Legacy Ciphers: IDEA, MDC-2, RC5
IDEA is a block cipher from 1991, patented until 2012, and supported by essentially nothing modern. RC5 is a Rivest cipher from the same era — obsolete and patent-encumbered. MDC-2 is a hash construction from the DES era. None of these belong in a modern TLS stack. Removing them shrinks the library and eliminates dead code paths that no legitimate client will ever trigger.
SSL 3.0
SSL 3.0 was deprecated in 2015 by RFC 7568 after the POODLE attack demonstrated it was fundamentally broken by design. No modern browser or client negotiates it. Keeping it in a webserver’s OpenSSL is pure attack surface — a footgun waiting to be misconfigured. We remove it entirely, not just disable it at runtime.
Windows CAPI Engine
The CAPI engine lets OpenSSL delegate certificate and key operations to the Windows Cryptographic API. We’re building for Linux. This is dead weight, compiled away.
TLS Record Compression
TLS compression has been disabled by default since the CRIME attack in 2012, and was formally dropped from TLS 1.3. NGINX has its own HTTP-level compression (gzip, brotli, zstd) that operates at the correct layer. Compressing at the TLS record layer is redundant on a modern stack and opens the door to CRIME-class side-channel attacks. Gone.
FIPS Module
FIPS 140 is a US government certification for cryptographic modules used in federal systems. The FIPS provider in OpenSSL adds overhead, complexity, and deliberate algorithm restrictions. If you need FIPS compliance, you need a different build — and you know it. For a high-performance webserver, FIPS support is overhead with no benefit. Removed.
CMS — Cryptographic Message Syntax
CMS is the standard underlying S/MIME email signing and encryption. NGINX does not sign emails. The CMS implementation is pure bloat in this context.
RFC 3779 Extensions
RFC 3779 defines X.509 certificate extensions used for BGP route origin validation (RPKI). That’s a routing infrastructure concern, not a webserver concern. Removed.
Binaries, Manpages, Docs, and Engines
The standard OpenSSL package ships the openssl command-line tool, manpages for every function, extensive documentation, and a legacy engines directory. None of these are needed by NGINX at runtime. openssl-nginx installs only the shared libraries and development headers. That’s it.
How openssl-nginx Coexists with System OpenSSL
There’s a practical challenge here: your system already has OpenSSL installed, and other packages depend on it. You can’t drop a different libssl.so.3 into /usr/lib — that would break everything that links against the system OpenSSL.
The solution is straightforward: we rename the libraries. openssl-nginx produces libssl-nginx.so and libcrypto-nginx.so instead of the standard names. NGINX and Angie are compiled to link against these renamed libraries, so they find our optimised build at runtime. The system OpenSSL is completely untouched.
This means openssl-nginx can run side-by-side with any OpenSSL version your distro ships — 1.1.x, 3.0.x, 3.2.x, anything — with zero conflicts. Headers live in their own subdirectory for the same reason. Everything is isolated by design.
The Four Debian Packages
The build produces four Debian packages:
- libssl-nginx — The SSL shared library, runtime dependency for NGINX and Angie
- libcrypto-nginx — The crypto shared library, runtime dependency
- libssl-nginx-dev — Static library and headers for compiling modules against it
- libcrypto-nginx-dev — Static library and headers for the crypto side
At runtime, NGINX and Angie need only the first two. The dev packages are for anything that needs to compile against this specific OpenSSL build — OpenResty, custom NGINX modules, or anything that calls the TLS API directly.
Why a Purpose-Built OpenSSL Matters
For a single low-traffic server, it probably doesn’t matter much. The system OpenSSL’s defaults are fine and your site will work.
But scale changes the math. When you’re terminating thousands of TLS connections per second, every wasted CPU cycle in a handshake is capacity not spent on real requests. Every unnecessary code path is a potential bug surface. Every legacy cipher that has no business being there is a misconfiguration waiting to happen.
More fundamentally: when a library does one job, you can reason about it. You know what it does and what it doesn’t. You can audit it. You can trust that nothing unexpected will be negotiated because the code for that negotiation simply isn’t there.
That’s the real value of openssl-nginx. Not just performance — clarity. A library that knows what it is.
openssl-nginx tracks the OpenSSL 3.5 branch and is built for Debian Bookworm, Trixie, Bullseye, Ubuntu Noble, Jammy, and Focal. It is available in our apt repositories alongside the matching Angie and NGINX packages.