2013-08-13 14 views
10

Tôi đang cố gắng tạo một máy chủ socket sử dụng stream_socket_server().Máy chủ socket PHP sử dụng ADH. Làm sao?

Kết nối bình thường hoạt động tốt, nhưng tôi muốn tạo một máy chủ mã hóa kết nối mà không cần chứng chỉ. Tôi biết rằng điều này có thể được thực hiện với mật mã ADH, và có, tôi biết nó về mặt lý thuyết kém an toàn hơn với một chứng chỉ ...

Lý do tôi làm cho máy chủ này ở nơi đầu tiên là giả lập một máy chủ khác mà khách hàng kết nối đến (trên this protocol, nếu bạn đang tự hỏi).

Máy khách được định cấu hình để yêu cầu chứng chỉ trước và dự phòng ADH - Tôi đã thử nghiệm với điều thực và kết nối mà không gặp sự cố, do đó sự cố xảy ra với máy chủ socket.

Mọi thứ tôi đã thử cho đến nay đã dẫn đến lỗi "lỗi bắt tay".

Một số cấu hình tôi đã cố gắng:

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

Tôi cũng đã cố gắng để điều chỉnh cho khách hàng vô điều kiện sử dụng ADH (như với ví dụ thứ hai ở trên), chỉ vì lợi ích của thử nghiệm, nhưng điều đó quá không thành công.

Điều này xảy ra với mọi phiên bản PHP mà tôi đã thử, phiên bản mới nhất trong số đó là 5.5.0.

Bất kỳ ý tưởng nào?

+0

thấy điều này có thể được giúp đỡ bạn http://christophh.net/2012/ 07/24/php-socket-programming/ – krishna

+0

@krishna Bài viết đó thậm chí không đề cập đến mã hóa, và cho rằng kết nối không được mã hóa hoạt động tốt, nó không giúp gì cả. –

Trả lời

5

Tôi sẽ sử dụng một công cụ như Wireshark để kiểm tra các bit đi qua dây để tôi có thể xác định chính xác những gì đang xảy ra sai với cái bắt tay. Nếu không có khả năng đó, bạn sẽ được bay (hoặc gỡ lỗi) bị mù.

Một khi bạn biết những gì đang xảy ra với cái bắt tay của bạn, bạn có thể tìm ra "lý do".

+0

Vì lý do nào đó, Wireshark không nắm bắt được lưu lượng truy cập từ máy tính của tôi. Đây là ngay cả khi tôi thay thế "127.0.0.1" bằng IP của máy tính (công khai) của tôi. Tôi sẽ cố gắng thiết lập một máy tính phụ và xem điều đó có thực hiện được không ... –

+0

Các byte thô có thể được xem tại đây https://gist.github.com/boenrobot/6331636 Theo cách Wireshark giải mã điều này - gói hello chỉ chứa mật mã ADH (như mong đợi cho thử nghiệm cụ thể này), và máy chủ trả lời với "lỗi bắt tay (40)". –

+0

Ồ, và trên máy khách, thông báo lỗi sau được hiển thị: "lỗi: 14094410: Thường trình SSL: SSL3_READ_BYTES: sslv3 cảnh báo lỗi bắt tay". (lẻ ...Tôi đang sử dụng TLS trên cả hai đồng nghiệp, không phải SSLv3) –

1

Trước tiên hãy kiểm tra xem SSL có được thiết lập chính xác trong máy chủ của bạn không? Run SSL Scanner tại dịch vụ. Tôi có một kịch bản thử nghiệm mà không làm việc ở tất cả, như các cuộc gọi OpenSSL không chạy mà không có một tập tin quan trọng. Đây không phải là câu trả lời, nhưng tôi thiếu thời gian để điều tra thêm ...

Bạn biết rằng ADH là mã hóa yếu? ~ hầu hết các khuyến cáo bảo mật khuyên bạn nên tắt nó đi. đọc chung về ADH http://wiki.openssl.org/index.php/Manual:Ciphers(1)

+0

Có. Như tôi đã nói ở trên cùng, tôi biết rằng ADH kém an toàn hơn so với kết nối với chứng chỉ và tôi đang cố tạo máy chủ làm mô hình trong thử nghiệm đơn vị chứ không phải để sử dụng "sản xuất". Máy chủ thực sự hỗ trợ ADH thay thế khi máy chủ không có chứng chỉ. Đối với SSLScan ... Tôi đã chạy [cổng Windows của SSLScan] (http://code.google.com/p/sslscan-win/) và sau khi điều chỉnh lại kịch bản thành stream_socket_accept() một lần nữa ngay cả khi thất bại, tôi xem tất cả mật mã là "Bị từ chối" với máy chủ gửi lại gói chính xác giống như đã lưu ý trước đó. –

+0

BTW, điều thú vị cần lưu ý ... với máy chủ thử nghiệm như trên, tôi chỉ nhận được mật mã TLSv1 và SSLv3 là "Bị từ chối" và SSLv2 là "Không thành công". Khi tôi đặt một tệp trống làm tùy chọn ngữ cảnh "local_cert", tôi cũng nhận được mật mã SSLv2 là "Bị từ chối". –

+0

trống địa phương cert ... Tôi mong chờ điều đó. Vì điều này được viết từ quan điểm bảo mật; một tệp trống giống như một chứng chỉ không hợp lệ từ chối mọi người. –

1

thấy điều này có thể giúp bạn

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

để biết thêm see this và thấy điều này cũng cho more

+0

Cảm ơn bạn đã cố gắng giúp đỡ, nhưng mã này - cũng như cả hai bài báo bạn liên kết đến - không hoàn toàn đối phó với mã hóa, đó là một phần có vấn đề trong toàn bộ câu hỏi. Các kết nối không được mã hóa hoạt động tốt, ngay cả khi không có phần mở rộng ổ cắm. Việc đề cập duy nhất của mã hóa trong toàn bộ điều là một đoạn trong bài viết Zend mà thậm chí không liên quan đến TLS mỗi se, và thậm chí không có một ví dụ cơ bản cho Mcrypt đã đề cập. –