stream_socket_client always returns FALSE

I couldn’t get this working on fly.io, is it blocked ?

$read = stream_socket_client("ssl://".$orignalParse.":".$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);
if ($read === FALSE) throw new Exception("stream_socket_client returned FALSE");

I don’t really know what this is doing (haven’t done any socket stuff in PHP myself), but if I’m reading this correctly (accepting an inbound connection?), requests into the apps aren’t using SSL by the time they reach the code. The fly-proxy “terminates” the SSL connection, sending non-ssl traffic to the application.

If that’s making an OUTGOING connection, then I think it should work - to my knowledge, no outbound traffic is blocked.

I’m trying to run this function.

I don’t think Fly is blocking either the PHP function or the outbound network connection. It may be that the hostname cannot be resolved or the host is unreachable. What do $errno and $errstr contain?

1 Like

This worked for me when doing a quick test on a VM I created recently (https://dumptests.fly.dev/ssl.php)

File ssl.php:

<?php

function getCertDetails($domain) {
	$url = "https://".$domain;
    $orignalParse = parse_url($url, PHP_URL_HOST);
    $port=parse_url($url, PHP_URL_PORT);
    if (!$port) $port=443;

    $get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE, 'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true)));


    $read = stream_socket_client("ssl://".$orignalParse.":".$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);


    $cert = stream_context_get_params($read);


    $certInfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate'], true);
    if (empty($certInfo)) return false;

    $certExpiry=strtotime(date('Y-m-d', $certInfo['validTo_time_t'])." 00:00:00");
    $now=strtotime(date('Y-m-d', time())." 00:00:00");
    $certInfo['validLeft']=floor(($certExpiry-$now)/86400);
    return $certInfo;
}

var_dump(getCertDetails('fly.io'));

Looks like on failure you can check the $errno, $errstr variables (maybe hack that function up a bit to see what it returns in your case).

["error","stream_socket_client returned FALSE : errno = 32708, errstr = Unable to find the socket transport \"ssl\" - did you forget to enable it when you configured PHP?"]

I tend not to use the official PHP base images because they get a bit weird.

This sounds like SSL support (openssl) isn’t installed into the base container / compiled in with PHP.

So your PHP is missing SSL support. Fixing this will depend on the OS/distro that the container image is based on, but usually installing the php-openssl package will do the trick.

Can you paste your Dockerfile here ?

This is what I have :

FROM php:8.2.1-apache

RUN sed -i 's/http:\/\/deb.debian.org/http:\/\/mirrors.aliyun.com/g' /etc/apt/sources.list \
    && apt-get update \
    && apt-get install -y libssl-dev \
    && docker-php-ext-install openssl

RUN mkdir myProject
WORKDIR myProject
COPY . .
EXPOSE 8080

ENTRYPOINT ["php", "index.php"]

I’ve removed Dockerfile and put this in the toml file :

[build]
  builder = "paketobuildpacks/builder:base"
  buildpacks = [
    "paketobuildpacks/php-web"
  ]

[[processes]]
  type = "web"
  command = "php -S 0.0.0.0:$PORT -c /etc/php/conf.d/php.ini /app/public/index.php"
  healthcheck = "curl -f http://localhost/ || exit 1"

[[config.mounts]]
  source = "php.ini"
  destination = "/etc/php/conf.d/php.ini"

But now I get

Error You specified a process for '{"command"=>"php -S 0.0.0.0:$PORT -c /etc/php/conf.d/php.ini /app/public/index.php", "healthcheck"=>"curl -f http://localhost/ || exit 1", "type"=>"web"}' but it does not have a command defined. Double check the syntax for the [processes] section of your fly.toml https://fly.io/docs/reference/configuration/#the-processes-section

My php.ini contains only extension=openssl

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.