PHP-сервер сокетов, использующий ADH. Как?

Я пытаюсь создать сервер сокетов, используя stream_socket_server().

Обычные соединения работают нормально, но я хочу создать сервер, который шифрует соединение без сертификата. Я знаю, что это можно сделать с помощью шифрования ADH, и да, я знаю, что это теоретически менее безопасно, чем с сертификатом...

Причина, по которой я делаю этот сервер в первую очередь, заключается в том, чтобы высмеять другой сервер, к которому клиент подключается (через этот протокол, если вам интересно).

Клиент настроен на то, чтобы сначала спросить о сертификате и отступить к ADH - я протестировал его с реальной вещью, и он подключается без проблем, поэтому проблема связана с сервером сокета.

Все, что я пробовал до сих пор, привело к ошибке "сбоя рукопожатия".

Некоторые из настроек, которые я пробовал:

<?php
$server = stream_socket_server(
        "tls://127.0.0.1:6667",
        $errorno,
        $errstr,
        STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
        stream_context_create(
            array('ssl' => array('ciphers' => 'ADH'))
        )
    );
?>

<?php
$server = stream_socket_server(
        "tls://127.0.0.1:6667",
        $errorno,
        $errstr,
        STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
        stream_context_create(
            array('ssl' => array('ciphers' => '-COMPLEMENTOFALL ADH'))
        )
    );
?>

Я также попытался настроить клиента на безусловное использование ADH (как и во втором примере выше), просто для тестирования, но это тоже не удается.

Это происходит с каждой версией PHP, которую я пробовал, последней из которых является 5.5.0.

Любые идеи?

Ответ 1

Я бы использовал такой инструмент, как Wireshark, чтобы проверить бит, проходящий по проводу, чтобы я мог точно определить, что происходит с рукопожатием. Без этой способности вы будете лететь (или отлаживать) вслепую.

Как только вы узнаете, что происходит с вашим рукопожатием, вы можете выяснить, почему.

Ответ 2

Во-первых, проверьте правильность настройки SSL на вашем сервере? Запустите SSL-сканер в сервисе. У меня есть тест script, который не работает вообще, поскольку вызовы OpenSSL не запускаются без файла ключа. Это не ответ, но мне не хватает времени для дальнейшего расследования...

Вы знаете, что ADH - это слабое шифрование? ~ Большинство рекомендаций по безопасности рекомендуют отключить его. Общее чтение на ADH http://wiki.openssl.org/index.php/Manual:Ciphers(1)

Ответ 3

см. это может помочь вам

<?php
// PHP SOCKET SERVER
error_reporting(E_ERROR);
// Configuration variables
$host = "127.0.0.1";
$port = 4041;
$max = 20;
$client = array();

// No timeouts, flush content immediatly
set_time_limit(0);
ob_implicit_flush();

// Server functions
function rLog($msg){
             $msg = "[".date('Y-m-d H:i:s')."] ".$msg;
             print($msg."\n");

}
// Create socket
$sock = socket_create(AF_INET,SOCK_STREAM,0) or die("[".date('Y-m-d H:i:s')."] Could not create socket\n");
// Bind to socket
socket_bind($sock,$host,$port) or die("[".date('Y-m-d H:i:s')."] Could not bind to socket\n");
// Start listening
socket_listen($sock) or die("[".date('Y-m-d H:i:s')."] Could not set up socket listener\n");

rLog("Server started at ".$host.":".$port);
// Server loop
while(true){
             socket_set_block($sock);
             // Setup clients listen socket for reading
             $read[0] = $sock;
             for($i = 0;$i<$max;$i++){
                          if($client[$i]['sock'] != null)
                                       $read[$i+1] = $client[$i]['sock'];
             }
             // Set up a blocking call to socket_select()
             $ready = socket_select($read,$write = NULL, $except = NULL, $tv_sec = NULL);
             // If a new connection is being made add it to the clients array
             if(in_array($sock,$read)){
                          for($i = 0;$i<$max;$i++){
                                       if($client[$i]['sock']==null){
                                                    if(($client[$i]['sock'] = socket_accept($sock))<0){
                                                                 rLog("socket_accept() failed: ".socket_strerror($client[$i]['sock']));
                                                    }else{
                                                                 rLog("Client #".$i." connected");
                                                    }
                                                    break;
                                       }elseif($i == $max - 1){
                                                    rLog("Too many clients");
                                       }
                          }
                          if(--$ready <= 0)
                          continue;
             }
             for($i=0;$i<$max;$i++){
                          if(in_array($client[$i]['sock'],$read)){
                                       $input = socket_read($client[$i]['sock'],1024);
                                       if($input==null){
                                                    unset($client[$i]);
                                       }
                                       $n = trim($input);
                                       $com = split(" ",$n);
                                       if($n=="EXIT"){
                                                    if($client[$i]['sock']!=null){
                                                                 // Disconnect requested
                                                                 socket_close($client[$i]['sock']);
                                                                 unset($client[$i]['sock']);
                                                                 rLog("Disconnected(2) client #".$i);
                                                                 for($p=0;$p<count($client);$p++){
                                                                              socket_write($client[$p]['sock'],"DISC ".$i.chr(0));
                                                                 }
                                                                 if($i == $adm){
                                                                              $adm = -1;
                                                                 }
                                                    }
                                       }elseif($n=="TERM"){
                                                    // Server termination requested
                                                    socket_close($sock);
                                                    rLog("Terminated server (requested by client #".$i.")");
                                                    exit();
                                       }elseif($input){
                                                    // Strip whitespaces and write back to user
                                                    // Respond to commands
                                                    /*$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
                                                    socket_write($client[$i]['sock'],$output);*/
                                                    if($n=="PING"){
                                                                 socket_write($client[$i]['sock'],"PONG".chr(0));
                                                    }
                                                    if($n=="<policy-file-request/>"){
                                                                 rLog("Client #".$i." requested a policy file...");
                                                                 $cdmp="<?xml version=\"1.0\" encoding=\"UTF-8\"?><cross-domain-policy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd\"><allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\" /><site-control permitted-cross-domain-policies=\"master-only\" /></cross-domain-policy>";
                                                                 socket_write($client[$i]['sock'],$cdmp.chr(0));
                                                                 socket_close($client[$i]['sock']);
                                                                 unset($client[$i]);
                                                                 $cdmp="";
                                                    }
                                       }
                          }else{
                                       //if($client[$i]['sock']!=null){
                                                    // Close the socket
                                                    //socket_close($client[$i]['sock']);
                                                    //unset($client[$i]);
                                                    //rLog("Disconnected(1) client #".$i);
                                       //}
                          }
             }
}
// Close the master sockets
socket_close($sock);
?>

для более см. это и см. это также для больше