There are times when the system-provided OpenSSL package just won’t cut it. Maybe you need a specific version for an application, you’re working toward FIPS 140-3 compliance, or you need features that aren’t compiled into the distro package. Whatever the reason, building OpenSSL 3.x from source on RHEL 10, Rocky Linux 10, or AlmaLinux 10 is straightforward if you follow the right steps.
This guide walks you through compiling and installing OpenSSL 3.x from source while keeping your system OpenSSL intact. We’ll install it side-by-side so nothing breaks, and you can point specific applications at your custom build.
Why Compile OpenSSL from Source?
RHEL 10 and its derivatives ship with OpenSSL 3.x in the base repositories. So why would you compile it yourself? A few common reasons:
- FIPS 140-3 compliance – You need the OpenSSL FIPS provider built with specific options for your compliance requirements.
- Custom builds – Your application requires OpenSSL compiled with non-default options (specific ciphers enabled or disabled, custom prefix paths, etc.).
- Version pinning – You need a specific OpenSSL release that differs from what the distro provides, for application compatibility or testing.
- Patching – You need to apply a security patch or custom patch before the distro packages catch up.
The key principle here is simple – never replace the system OpenSSL. Install your custom build to a separate prefix like /usr/local/ssl and configure applications to use it explicitly.
Step 1 – Check the Current OpenSSL Version
Before doing anything, check what version of OpenSSL is already installed on the system.
openssl version -a
You should see output similar to:
OpenSSL 3.2.x xx Mon 202x (Library: OpenSSL 3.2.x xx Mon 202x)
built on: ...
platform: linux-x86_64
...
Also confirm the installed RPM package:
rpm -q openssl openssl-libs
Take note of the version. This is the system OpenSSL that we will leave untouched throughout this guide.
Step 2 – Install Build Dependencies
You need a C compiler, Perl (OpenSSL’s build system uses it heavily), and a few other development tools.
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y perl-core perl-IPC-Cmd perl-FindBin perl-File-Compare perl-File-Copy zlib-devel
Verify that GCC and Perl are available:
gcc --version
perl --version
Both commands should return version information without errors. If either fails, double-check the package installation.
Step 3 – Download OpenSSL Source
Head to the official OpenSSL download page at https://www.openssl.org/source/ and grab the latest 3.x release. At the time of writing, OpenSSL 3.4.1 is the latest stable release in the 3.x branch.
cd /usr/local/src
sudo curl -LO https://www.openssl.org/source/openssl-3.4.1.tar.gz
Verify the download integrity using the SHA256 checksum published on the OpenSSL website:
sudo curl -LO https://www.openssl.org/source/openssl-3.4.1.tar.gz.sha256
sha256sum openssl-3.4.1.tar.gz
cat openssl-3.4.1.tar.gz.sha256
Compare the two hash values. They must match. If they don’t, re-download the file – do not proceed with a corrupted or tampered archive.
Extract the source:
sudo tar -xzf openssl-3.4.1.tar.gz
cd openssl-3.4.1
Step 4 – Configure the Build
OpenSSL uses a Perl-based configuration script. We’ll install to /usr/local/ssl to keep it completely separate from the system OpenSSL in /usr.
sudo ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib
Here’s what each option does:
--prefix=/usr/local/ssl– Install path for binaries, libraries, and headers.--openssldir=/usr/local/ssl– Location for OpenSSL configuration files and certificates directory.shared– Build shared libraries (.so files) in addition to static ones.zlib– Enable zlib compression support.
If you need FIPS support, add the enable-fips flag:
sudo ./config --prefix=/usr/local/ssl --openssldir=/usr/local/ssl shared zlib enable-fips
After configuration completes, verify it ran successfully by checking the exit code:
echo $?
A return value of 0 means the configuration succeeded.
Step 5 – Compile and Install
Now compile OpenSSL. The -j$(nproc) flag uses all available CPU cores to speed up the build.
sudo make -j$(nproc)
This will take a few minutes depending on your hardware. Once the build finishes, run the tests:
sudo make test
All tests should pass. If you see failures, check the output carefully – some test failures on specific platforms can be non-critical, but anything related to core crypto operations is a red flag.
Install the compiled binaries:
sudo make install
Verify the files are in place:
ls -la /usr/local/ssl/bin/openssl
ls -la /usr/local/ssl/lib64/libssl.so*
ls -la /usr/local/ssl/lib64/libcrypto.so*
You should see the binary and shared library files listed.
Step 6 – Update the Shared Library Cache
The system’s dynamic linker needs to know about the new shared libraries. Create a configuration file for ldconfig:
echo "/usr/local/ssl/lib64" | sudo tee /etc/ld.so.conf.d/openssl-custom.conf
sudo ldconfig
Verify the libraries are cached:
ldconfig -p | grep /usr/local/ssl
You should see entries for libssl.so and libcrypto.so pointing to /usr/local/ssl/lib64.
Step 7 – Verify the New OpenSSL Version
Check the version of your newly installed OpenSSL:
/usr/local/ssl/bin/openssl version -a
You should see the version you just compiled – OpenSSL 3.4.1 in our case. Also verify that the system OpenSSL is still intact:
/usr/bin/openssl version
This should show the original distro version. Both versions coexist without conflict.
Step 8 – Configure Applications to Use Custom OpenSSL
Your custom OpenSSL is installed, but no application will use it automatically – and that’s by design. Here are the common ways to point applications at your build.
Option A – Add to PATH for Shell Access
If you want the openssl command in your shell to use the custom version:
echo 'export PATH=/usr/local/ssl/bin:$PATH' | sudo tee /etc/profile.d/custom-openssl.sh
source /etc/profile.d/custom-openssl.sh
Verify:
which openssl
openssl version
Option B – Compile Applications Against Custom OpenSSL
When building software that needs to link against your custom OpenSSL, pass the paths during configuration. For example, when compiling Nginx:
./configure --with-openssl=/usr/local/src/openssl-3.4.1 --with-http_ssl_module
For applications that use pkg-config, set the PKG_CONFIG_PATH:
export PKG_CONFIG_PATH=/usr/local/ssl/lib64/pkgconfig:$PKG_CONFIG_PATH
pkg-config --modversion openssl
Option C – Use LD_LIBRARY_PATH for Specific Applications
To run a specific application with the custom OpenSSL libraries without affecting the whole system:
LD_LIBRARY_PATH=/usr/local/ssl/lib64 /path/to/your/application
Running Side-by-Side with System OpenSSL
This setup is designed for side-by-side operation from the start. Here’s a quick summary of what lives where:
| Component | System OpenSSL | Custom OpenSSL |
|---|---|---|
| Binary | /usr/bin/openssl | /usr/local/ssl/bin/openssl |
| Libraries | /usr/lib64/ | /usr/local/ssl/lib64/ |
| Headers | /usr/include/openssl/ | /usr/local/ssl/include/openssl/ |
| Config | /etc/pki/tls/ | /usr/local/ssl/ |
The system OpenSSL handles everything by default – DNF, SSH, system services, and all existing applications. Your custom build only gets used when you explicitly point an application at it. This is the safest approach and avoids breaking system tools that depend on the distro-provided OpenSSL.
Troubleshooting
configure fails with “Perl not found” or module errors
Make sure all required Perl modules are installed:
sudo dnf install -y perl-core perl-IPC-Cmd perl-FindBin perl-File-Compare perl-File-Copy
“openssl: error while loading shared libraries”
The dynamic linker can’t find the custom libraries. Make sure you ran ldconfig correctly:
cat /etc/ld.so.conf.d/openssl-custom.conf
sudo ldconfig
ldconfig -p | grep libssl
If the library path file is missing or empty, recreate it as shown in Step 6.
System tools break after installation
If system tools like dnf or ssh start failing, it usually means the system’s libssl.so or libcrypto.so symlinks got overwritten. Check what libraries they’re loading:
ldd /usr/bin/openssl
ldd /usr/bin/ssh
These should point to /usr/lib64/, not /usr/local/ssl/lib64/. If the ldconfig configuration is pulling in the custom libraries globally, you can remove the conf file and rely on explicit paths instead:
sudo rm /etc/ld.so.conf.d/openssl-custom.conf
sudo ldconfig
Then use LD_LIBRARY_PATH or -rpath at compile time for applications that need the custom build.
make test shows failures
Some test failures can occur due to missing system entropy or specific kernel configurations. Check if the failures are in optional tests or core crypto tests. You can review the test log:
cat /usr/local/src/openssl-3.4.1/test/recipes/*.t.log 2>/dev/null | head -100
If only non-critical tests fail (like some network-dependent tests), you can proceed. Core crypto test failures should be investigated before using the build in production.
FIPS provider not loading
If you compiled with enable-fips but the FIPS provider won’t load, install the FIPS module explicitly:
sudo /usr/local/ssl/bin/openssl fipsinstall -out /usr/local/ssl/fipsmodule.cnf -module /usr/local/ssl/lib64/ossl-modules/fips.so
Then update /usr/local/ssl/openssl.cnf to include the FIPS configuration. Check that the FIPS provider loads:
/usr/local/ssl/bin/openssl list -providers
Conclusion
You now have a custom OpenSSL 3.x build running alongside the system OpenSSL on RHEL 10, Rocky Linux 10, or AlmaLinux 10. The custom installation lives in /usr/local/ssl and won’t interfere with system packages or updates. Point your applications at it as needed, and remember to keep it updated when new OpenSSL releases come out – custom builds don’t get automatic security updates from your distro’s package manager.




















































