带 SNI 的本地 HTTPS 服务器

Local HTTPS server with SNI

有大量关于 cURL 和 SSL 的可用信息,但关于编写服务器的信息却不多。我有一个用 PHP 编写的小型本地服务器,我想启用 TLS/SSL。我的服务器在安全连接时崩溃时遇到问题。我只收到错误 "PHP Warning: stream_socket_accept(): Failed to enable crypto"。我有一个没有 TLS 的相同服务器 运行,它工作正常。我知道这是证书,或者连接 to/reading 证书。但是,我不确定这是否是关于我如何生成证书、如何将它们加入 PEM 或其他方面的错误。此外,对于我们的域,我在下面的代码中都使用了 *.domain.tld ,在创建证书时也使用了本地名称。

此外,Web 浏览器中显示的证书显示 127.0.0.1 证书而不是本地主机(或其他域)证书,无论请求的域如何。那是因为 127.0.0.1 被设置为本地证书吗?关于证书——这是我当前用于创建要在服务器上使用的 .pem 文件的代码:

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

apache.crt apache.key > joined.pem

服务器代码的基本形式是:

<?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;

还有一件事,要设置什么密码才能取悦所有主流浏览器,Chrome 似乎有自己的规则。

知道我在这里遗漏了什么吗?

我的问题是在证书创建期间没有设置 SAN。 link https://serverfault.com/questions/880804/can-not-get-rid-of-neterr-cert-common-name-invalid-error-in-chrome-with-self 纠正了我的问题。