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:

ComponentSystem OpenSSLCustom 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.

LEAVE A REPLY

Please enter your comment!
Please enter your name here