Installing Custom OpenSSL and cURL for Legacy PHP

Submitted by Tom Thorp on Sunday, November 11, 2018 - 21:45
Modified on Monday, April 27, 2020 - 00:40
PHP Logo

(At time of writing, OpenSSL is at v1.1.1, and PHP is at v7.2.12 .)

Summary

As an IT Systems Administrator, I always keep on top of the latest security patches. Sometimes though, the result of updating operating system components can result in legacy applications/websites no longer working.
 
Such is the case with OpenSSL when SSL is used in legacy PHP websites. If you attempt to install a version of PHP prior to v7.0.0 with SSL support, then you will find that the current installed version of OpenSSL is incompatible. This is because
 
  • the version of PHP you have attempted to install, has not kept pace with the changes to OpenSSL, and
  • the version of PHP you are using is (or will be) approaching end-of-life.   
For example: for version 5.6.38 of PHP, OpenSSL will only work correctly with PHP using the following versions ( >= 0.9.6 ; < 1.1.0 )
 
As OpenSSL is a critical operating system application, there will be other applications installed that will rely on the latest release. From a security perspective, you'll want to limit any security holes (if there are any) just to legacy apps, till such time when you update your application. 
 
That been said, here is how to create a custom OpenSSL & cURL build to be used for a legacy PHP installation.
 

Preparation

In your home directory, create a build and a source directory. In the source directory, download the source repositories for OpenSSL and cURL. 
[Tom@localhost ~]$ wget -O php-5.6.40.tar.gz https://www.php.net/distributions/php-5.6.40.tar.gz
[Tom@localhost ~]$ tar -zxvf php-5.6.40.tar.gz
[Tom@localhost ~]$ mv php-5.6.40 php

[Tom@localhost ~]$ mkdir -p ./build
[Tom@localhost ~]$ mkdir -p ./src
[Tom@localhost ~]$ cd src
[Tom@localhost src]$ git clone https://github.com/curl/curl.git
[Tom@localhost src]$ git clone https://github.com/openssl/openssl.git
 

Build OpenSSL 1.0.0

From the OpenSSL directory we need to build a version of OpenSSL that will conform with the version of PHP that we will be running. In this case, we will be using version 1.0.0 as our example. 
[Tom@localhost src]$ cd openssl
[Tom@localhost openssl]$ git checkout OpenSSL_1_0_0-stable

// Make sure Build is clean before recompiling

[Tom@localhost openssl]$ make clean
[Tom@localhost openssl]$ make dclean

// Configure OpenSSL

[Tom@localhost openssl]$ ./config -fPIC shared --prefix=/home/tom/build

// Make OpenSSL & Install into Build Directory

[Tom@localhost openssl]$ make -j$(nproc)
[Tom@localhost openssl]$ make install
To verify that you have created the correct OpenSSL version in the Build directory, go to your Build directory and execute the following command : 
[Tom@localhost openssl]$ cd ~/build/bin
[Tom@localhost bin]$ ./openssl version 
OpenSSL 1.0.0u-dev xx XXX xxxx
[Tom@localhost bin]$
 

Build cURL with OpenSSL 1.0.0 support

Now that OpenSSL has been compiled and linked, we need to create a custom version of cURL with SSL support, in order for legacy applications and websites to download files securely via HTTPS . In order to do this, cURL needs to link the OpenSSL 1.0.0 libraries into its' Build. To do this, execute the following commands : 
[Tom@localhost bin]$ cd ~/src/curl

// Run buildconf to create the autoconf file (may require sudo access)

[Tom@localhost curl]$ ./buildconf

// Configure cURL to point to OpenSSL 1.0.0 libraries, and install to Build directory

[Tom@localhost curl]$ env PKG_CONFIG_PATH=/home/tom/build/lib/pkgconfig \
> ./configure --with-ssl --prefix=/home/tom/build

// Make & Install cURL to Build directory

[Tom@localhost curl]$ make -j$(nproc)
[Tom@localhost curl]$ make install
To verify that cURL has been installed in the Build directory, do the following :
[Tom@localhost curl]$ cd ~/build/bin
[Tom@localhost bin]$ ./curl -V 
curl 7.24.0 (x86_64-unknown-linux-gnu) libcurl/7.24.0 OpenSSL/1.0.0u zlib/1.2.11
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet tftp 
Features: IPv6 Largefile NTLM NTLM_WB SSL libz
[Tom@localhost bin]$
 As you can see in the version info, OpenSSL 1.0.0 has been correctly linked into cURL and https support is enabled. 
 

Build PHP From Source

Now that we have a customised version of cURL and OpenSSL at our disposal, it's time to compile our legacy version of PHP. In order to correctly link PHP, in the 'configure' command we have to tell PHP where our customised versions of OpenSSL and cURL live (in the Build directory). 
 
Here I will use a subset of the commands used in my 'configure' file. However I'll point out the critical parameters used.
// Generate autoconf files. May require sudo access. 
[Tom@localhost bin]$ cd ~/php
[Tom@localhost php]$ ./buildconf

// Configure PHP 5.6 to point to the Build directory containing OpenSSL & cURL

[Tom@localhost php]$ ./configure \
> --prefix=/opt/php56 \
> --with-config-file-path=/opt/php56/etc \
> --with-curl=/home/tom/build \
> --with-openssl-dir=/home/tom/build \
> --with-openssl=shared \
> --with-pdo-mysql \
> --with-fpm-user=apache \
> --with-fpm-group=apache \
> --with-libdir=lib64 \ ** Use if on 64 bit OS. Include softlink to lib directory
.
.
.

// Make & Install PHP 5.6

[Tom@localhost php]$ make clean
[Tom@localhost php]$ make -j$(nproc) -B
[Tom@localhost php]$ make install
Once you have PHP installed, you can test to see that the cURL extension is installed as part of the installation. 
 
Using your favorite editor, create the following PHP file and save it. 
<?php
echo '<pre>';
var_dump(curl_version());
echo '</pre>';
?>
Then, from the command prompt, execute the following command : 
[Tom@localhost php]$ /opt/php56/bin/php filename.php
If cURL is installed correctly, you should get an output similar to this :
array(9) {
  ["version_number"]=>
  int(464896)
  ["age"]=>
  int(3)
  ["features"]=>
  int(33309)
  ["ssl_version_number"]=>
  int(0)
  ["version"]=>
  string(6) "7.24.0"
  ["host"]=>
  string(24) "x86_64-unknown-linux-gnu"
  ["ssl_version"]=>
  string(14) "OpenSSL/1.0.0u"
  ["libz_version"]=>
  string(6) "1.2.11"
  ["protocols"]=>
  array(16) {
    [0]=>
    string(4) "dict"
    [1]=>
    string(4) "file"
    [2]=>
    string(3) "ftp"
    [3]=>
    string(4) "ftps"
    [4]=>
    string(6) "gopher"
    [5]=>
    string(4) "http"
    [6]=>
    string(5) "https"
    [7]=>
    string(4) "imap"
    [8]=>
    string(5) "imaps"
    [9]=>
    string(4) "pop3"
    [10]=>
    string(5) "pop3s"
    [11]=>
    string(4) "rtsp"
    [12]=>
    string(4) "smtp"
    [13]=>
    string(5) "smtps"
    [14]=>
    string(6) "telnet"
    [15]=>
    string(4) "tftp"
  }
}
 
Congratulations!! You've successfully installed a customised version of OpenSSL and cURL on your legacy version of PHP. 
 

Running Multiple PHP-FPM Linux Services

If you are running multiple PHP versions of PHP-FPM, do take special care that you don't add your custom build directory as part of ldconfig . The effect of adding your build directory in as part of ldconfig, will tell linux to look at your build directory first, before looking at the default installed drivers. As a result, the next time any other PHP-FPM services are restarted, it will pick up the drivers in your build directory that are incompatible, and will make that PHP-FPM service unstable.
 
To make sure your custom version of PHP doesn't interfere with your other PHP-FPM services, you have to add an over-ride into your PHP-FPM service. This will contain an environment variable that tells the service to use the drivers in this path. To effect this change, do the following :
 
systemctl edit php-fpm.service

// Add the following code into the editor

[Service]
Environment="LD_LIBRARY_PATH=<path to your openssl build directory>"

// Save, then type

systemctl daemon-reload

// followed by 

systemctl stop php-fpm.service 
systemctl start php-fpm.service

 

Amendment

After further testing, I discovered that OpenSSL PHP extension was not been created. This was because OpenSSL was not been compiled in PHP as a shared extension for other extensions to use (such as IMAP, cURL, etc.) . To resolve this issue :
 
  • In the configure parameters, add --with-openssl=shared as well as --with-openssl-dir=<your openssl build directory>.
  • After the build is complete, verify in your shared extensions directory, that 'openssl.so' exists.
  • Add in the [openssl] section of your php.ini file, the line 'extension=openssl.so'
 
 

About the author

Tom Thorp
Tom Thorp is an IT Consultant living in Miami on Queensland's Gold Coast. With over 30+ years working in the IT industry, Tom's experience is a broad canvas. The IT services Tom provides to his clients, includes :
 
Website development and hosting
Database Administration
Server Administration (Windows, Linux, Apple)
PABX Hosting and Administration
Helpdesk Support (end-user & technical).
  If you like any of my content, consider a donation via Crypto by clicking on one of the payment methods :
 
Categories
PHPOpenSSLcURLconfigurationlegacy