Search code examples
phplinuxopensslphp-7.4ubuntu-22.04

How to compile PHP 7.4.33 correctly with OpenSSL 1.1.1 on Ubuntu 22.04


Ubuntu 22.04 includes OpenSSL 3 which is not compatible with PHP 7.4.33. Building PHP 7.4.33 from source in a custom path on Ubuntu 22.04 with SSL support results in SSL operation failed errors when using SSL features within PHP (i.e., a simple file_get_contents("https://google.com");).

We require a build in a custom path and docker/container is also not an option here.

Any assistance would be greatly appreciated!

# Install OpenSSL
wget https://www.openssl.org/source/openssl-1.1.1s.tar.gz;
tar xvf openssl-1.1.1s.tar.gz;
cd openssl-1.1.1s/;
./Configure --prefix=/opt/build --openssldir=/opt/build -fPIC -shared linux-x86_64 -Wl,--enable-new-dtags,-rpath,'$(LIBRPATH)';
make -j 8 && make install;
cd ../;

# Install PHP
wget https://www.php.net/distributions/php-7.4.33.tar.gz;
tar xf php-7.4.33.tar.gz;
cd php-7.4.33/;
export PKG_CONFIG_PATH=/opt/build/lib/pkgconfig;
./buildconf --force;
./configure --prefix=/opt/php \
--with-curl \
--with-openssl=/opt/build \
--with-openssl-dir=/opt/build;
make -j 8 && make install;

The above minimal build appears to compile successfully however running /opt/php/bin/php -r 'echo file_get_contents("https://google.com");' results in:

root@ubuntu2204:~/php-7.4.33# /opt/php/bin/php -r 'echo file_get_contents("https://google.com");'

Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in Command line code on line 1

Warning: file_get_contents(): Failed to enable crypto in Command line code on line 1

Warning: file_get_contents(https://google.com): failed to open stream: operation failed in Command line code on line 1

At the end of make i see the following warnings:

/usr/bin/ld: warning: libssl.so.3, needed by /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libcrypto.so.3, needed by /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcurl.so, may conflict with libcrypto.so.1.1
/usr/bin/ld: warning: libssl.so.3, needed by /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libcrypto.so.3, needed by /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcurl.so, may conflict with libcrypto.so.1.1
/usr/bin/ld: warning: libssl.so.3, needed by /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcurl.so, may conflict with libssl.so.1.1
/usr/bin/ld: warning: libcrypto.so.3, needed by /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcurl.so, may conflict with libcrypto.so.1.1

Additionally it seems that PHP is confused and using both OpenSSL 3.0.2 and OpenSSL 1.1.1s?

root@ubuntu2204:~/php-7.4.33# /opt/php/bin/php -i | grep OpenSSL
SSL Version => OpenSSL/3.0.2
OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 1.1.1s  1 Nov 2022
OpenSSL Header Version => OpenSSL 1.1.1s  1 Nov 2022
OpenSSL support => enabled

In addition, i have also tried building with curl and additional flags but this results in the same error.

# Install OpenSSL
wget https://www.openssl.org/source/openssl-1.1.1s.tar.gz;
tar xvf openssl-1.1.1s.tar.gz;
cd openssl-1.1.1s/;
./Configure --prefix=/opt/build --openssldir=/opt/build -fPIC -shared linux-x86_64 -Wl,--enable-new-dtags,-rpath,'/opt/build/lib';
make -j 8 && make install;
cd ../;

export CFLAGS="-I/opt/build/include/ -L/opt/build/lib -Wl,-rpath,/opt/build/lib -lssl -lcrypto"
export CXXFLAGS="-I/opt/build/include/ -L/opt/build/lib -Wl,-rpath,/opt/build/lib -lssl -lcrypto"

# Install Curl
wget http://curl.haxx.se/download/curl-7.58.0.tar.bz2
tar -xvjf curl-7.58.0.tar.bz2
cd curl-7.58.0
export PKG_CONFIG_PATH=/opt/build/lib/pkgconfig;
export LD_LIBRARY_PATH=/opt/build/lib;
./buildconf
./configure --prefix=/opt/build --with-ssl=/opt/build
make -j 8 && make install;
cd ../;

# Install PHP
wget https://www.php.net/distributions/php-7.4.33.tar.gz;
tar xf php-7.4.33.tar.gz;
cd php-7.4.33/;
export PKG_CONFIG_PATH=/opt/build/lib/pkgconfig;
export LD_LIBRARY_PATH=/opt/build/lib;
./buildconf --force;
PKG_CONFIG_PATH=/opt/build/lib/pkgconfig ./configure --prefix=/opt/php \
--with-curl=/opt/build \
--with-openssl=/opt/build
--with-libdir=/opt/build/lib;
make -j 8 && make install;

Solution

  • We've manage to identify the issue with some paid support from upwork. Hopefully this will help others. Just need to direct PHP to an openssl.cnf and the CA Certs path.

    1. Build OpenSSL
    wget https://www.openssl.org/source/openssl-1.1.1s.tar.gz;
    tar xvf openssl-1.1.1s.tar.gz;
    cd openssl-1.1.1s/;
    ./Configure --prefix=/opt/build --openssldir=/opt/build -fPIC -shared linux-x86_64;
    make -j 8 && make install;
    cd ../;
    
    1. Set pkgconfig and also set ENV for default openssl.cnf path
    export PKG_CONFIG_PATH=/opt/build/lib/pkgconfig
    export OPENSSL_CONF=/usr/lib/ssl/openssl.cnf;
    
    1. Build & Install PHP
    wget https://www.php.net/distributions/php-7.4.33.tar.gz;
    tar xf php-7.4.33.tar.gz;
    cd php-7.4.33/;
    ./buildconf --force;
    ./configure --prefix=/opt/php \
    --with-curl \
    --with-openssl=/opt/build;
    make -j 8 && make install;
    
    1. Copy php.ini-production into /opt/php/lib/:
    cp php.ini-production /opt/php/lib/php.ini;
    
    1. Configure php.ini openssl.capath to /usr/lib/ssl/certs
    sed -i 's/;openssl.capath=/openssl.capath=\/usr\/lib\/ssl\/certs\//g' /opt/php/lib/php.ini;
    
    1. Test that should result in HTML output
    /opt/php/bin/php -r 'echo file_get_contents("https://google.com");'