stream_socket_client(): SSL operation failed with code 1.
by admin on Mar.06, 2024, under News
We recently came across the following error message:
stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:error:0A000410:SSL routines::sslv3 alert handshake failurestream_socket_client(): Failed to enable cryptostream_socket_client(): Unable to connect to ssl://wpwax.com:443 (Unknown error)
The relevant part here is SSLv3. If we do some research we quickly find, that:
SSLv3 has several flaws. An attacker can cause connection failures and they can trigger the use of SSL 3.0 to exploit vulnerabilities like POODLE. Attackers can perform man-in-the-middle attacks and observe the encryption traffic between your website and its visitors.
So how can we fix this issue? Let’s check the OpenSSL version used by our PHP installation. We may do so either by accessing the server via SSH (if we do have SSH access) and run the following command:
openssl version OpenSSL 3.0.11 19 Sep 2023 (Library: OpenSSL 3.0.11 19 Sep 2023)
If we don’t have SSH access to the server, we may still write a PHP script with the following content to find the OpenSSL version:
<?php phpinfo(); ?>
In the likely event that we receive a current OpenSSL version (currently 3.x), this version will no longer provide support for the outdated SSLv3 protocol. We are now faced with the problem that we have, for example, a PHP version 8.2 with OpenSSL 3.0, but we want a PHP version 8.2 using OpenSSL 1.1.1 (which still supports SSLv3).
Let’s start with compiling OpenSSL 1.1.1f from source and installing it to /usr/local/openssl-1.1.1f directory (without touching the system’s 3.0 installation):
apt install build-essential checkinstall zlib1g-dev wget https://www.openssl.org/source/openssl-1.1.1f.tar.gz tar -xf openssl-1.1.1f.tar.gz cd openssl-1.1.1f ./config --prefix=/usr/local/openssl-1.1.1f --openssldir=/usr/local/openssl-1.1.1f shared zlib make make install
The next step is building PHP 8.2 from source and installing it to /usr/local/php-8.2.0 directory (without touching the system’s 8.2 installation):
apt install libonig-dev apt install libcurl4 libcurl4-openssl-dev apt install sqlite3 libsqlite3-dev apt install build-essential pkg-config libxml2-dev wget https://www.php.net/distributions/php-8.2.0.tar.gz tar -xf php-8.2.0.tar.gz cd php-8.2.0 export PKG_CONFIG_PATH=/usr/local/openssl-1.1.1f/lib/pkgconfig ./configure --prefix=/usr/local/php-8.2.0 \ --with-config-file-path=/etc/php/8.2/fpm \ --with-config-file-scan-dir=/etc/php/8.2/fpm/conf.d \ --with-openssl=/usr/local/openssl-1.1.1f \ --enable-mbstring \ --with-curl \ --with-openssl \ --enable-bcmath \ --enable-json \ --enable-xml \ --enable-session \ --enable-ctype \ --enable-tokenizer \ --with-pdo-mysql \ --with-zlib \ --enable-simplexml \ --enable-dom \ --enable-fpm \ --with-fpm-user=www-data \ --with-fpm-group=www-data make make install
This will build PHP along with all the modules configured in /etc/php/8.2/fpm, thus making it compatible with the PHP installation already found on the system (as we’d like to build a drop-in-replacement for that).
So far so good. The next step is stopping the system’s PHP installation and starting our source-built version instead:
systemctl stop php8.2-fpm.service cd /usr/local/php-8.2.0/sbin/ ./php-fpm
We may now proceed with activating the plugin and since this PHP installation now uses OpenSSL 1.1.1f, it actually should work. After all of this is done we’ll opt back to using the PHP version installed via a package manager again:
pkill -9 php-fpm systemctl start php8.2-fpm.service