-->

Local HTTPS server with SNI

2019-08-19 23:56发布

问题:

There is a ton of information available about cURL and SSL, but not so much is out there about writing a server. I have a small local server written in PHP that I would like to have TLS/SSL enabled. I am having issues with my server crashing upon secure connections. I am only receiving the error, "PHP Warning: stream_socket_accept(): Failed to enable crypto". I have an identical server running without TLS, and it is working fine. I have an idea it is the certificates, or the connection to/reading the certificates. However, I am not sure if it is an error on how I generated the certificates, how I have them joined to PEM, or something else. Also, for our domains, I've used *.domain.tld in both the code below, as well as the local name in the cert creation.

Furthermore, the certificates shown in the web browser show the 127.0.0.1 cert and not the localhost (or other domains) certificates regardless of the domain requested. Is that because the 127.0.0.1 is set as the local cert? About the certificates- this is my current code for creating the .pem file to use on the server:

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout apache.key -out apache.crt

apache.crt apache.key > joined.pem

A basic rendition of the server code is:

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;

$ctx = stream_context_create(['ssl' => [
    'local_cert' => "{path}/Websites/127.0.0.1/certs/joined.pem",
    'SNI_server_certs' => [
        "127.0.0.1" => "{path}/Websites/127.0.0.1/certs/joined.pem",
        "localhost" => "{path}//Websites/localhost/certs/joined.pem",
    ]
]]);
stream_context_set_option($ctx, 'ssl', 'ssl_method', 'STREAM_CRYPTO_METHOD_TLSv23_SERVER');
stream_context_set_option($ctx, 'ssl', 'allow_self_signed', true);
stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
stream_context_set_option($ctx, 'ssl', 'ciphers', "HIGH");


$socket = stream_socket_server("tls://127.0.0.1:8443", $errno, $errstr, $flags, $ctx);


while ( $client = stream_socket_accept($socket, "-1", $clientIP)):

    $msg = fread($client, 8192);

    $resp = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n<h1>Hi, you are secured.<br>{$msg}";
    fwrite($client,$resp );
    fclose($client);        

endwhile;

One more thing, what is the proper cipher to set for appeasing all of the major browsers out there, Chrome seems to play by its own rules.

Any ideas what I am missing here?

回答1:

My issue was not setting SANs during the certificate creation. The link https://serverfault.com/questions/880804/can-not-get-rid-of-neterr-cert-common-name-invalid-error-in-chrome-with-self corrected my issues.



标签: ssl openssl sni