簡體   English   中英

無法通過 fsockopen 在 PHP 中建立 TLS 連接

[英]Unable to establish TLS connection in PHP via fsockopen

幾天以來,我一直在嘗試通過我新安裝的 Ubuntu 服務器上的 fsockopen() 與 PHP 中的 SMTP 服務器建立 TLS 連接。 我幾乎嘗試了所有方法並搜索了幾個小時,但仍然無法正常工作。

PHP 代碼如下所示:

$fp = fsockopen("tls://smtp.xxxx.com", 25, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
 // some other stuff
}  

output 只是 (0),即 $errstr = null 和 $errno = 0。

OpenSSL 已安裝並啟用:

OpenSSL support: enabled
OpenSSL Library Version: OpenSSL 0.9.8o 01 Jun 2010
OpenSSL Header Version: OpenSSL 0.9.8o 01 Jun 2010

and the following stream socket transports are registered: tcp, udp, unix, udg, ssl, sslv3, sslv2, tls.

該端口在控制台的 telnet 工作時打開。

任何想法有什么問題或我如何至少可以得到更多的調試 output?

謝謝,馬庫斯

你的連接沒有多大意義。 通過使用 TLS 處理程序,您希望在任何數據傳輸之前建立 TLS。 但是端口 25 是標准的 SMTP,它只能在您最初通過未加密的常規連接進行連接建立 TLS。 建立初始連接后,您可以使用STARTTLS命令啟用 TLS,以告知 SMTP 服務器進行切換。

如果您從一開始就想要 TLS,請使用端口 465,從一開始就是 ssl/tls。

使用 gmail,ssl 連接端口從一開始就有 ssl,但是 tls 端口,您使用 STARTtTLS 命令手動連接,並且必須啟動。 我猜這是一樣的。 這是 gmail 的示例,因此您可以看到發生了什么。 EHLO 命令顯示 STARTTLS 命令,而如果您從一開始就以 ssl 開頭,它就會進入 AUTH XOAUTH 命令列表。

<?php
function get($socket,$length=1024){
    $send = '';
    $sr = fgets($socket,$length);
    while( $sr ){
        $send .= $sr;
        if( $sr[3] != '-' ){ break; }
        $sr = fgets($socket,$length);
    }
    return $send;
}
function put($socket,$cmd,$length=1024){
    fputs($socket,$cmd."\r\n",$length);
}
if (!($smtp = fsockopen("smtp.gmail.com", 587, $errno, $errstr, 15))) {
    die("Unable to connect");
}
echo "<pre>\n";
echo get($smtp); // should return a 220 if you want to check

$cmd = "EHLO ${_SERVER['HTTP_HOST']}";
echo $cmd."\r\n";
put($smtp,$cmd);
echo get($smtp); // 250

$cmd = "STARTTLS";
echo $cmd."\r\n";
put($smtp,$cmd);
echo get($smtp); // 220
if(false == stream_socket_enable_crypto($smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)){
    // fclose($smtp); // unsure if you need to close as I haven't run into a security fail at this point
    die("unable to start tls encryption");
}

$cmd = "EHLO ".$_SERVER['HTTP_HOST'];
echo $cmd;
put($smtp,$cmd);
echo get($smtp); // 250

$cmd = "QUIT";
echo $cmd."\r\n";
put($smtp,$cmd);
echo get($smtp);

echo "</pre>";

fclose($smtp);

如果它可以從命令行運行,但不能從 Apache 中運行,那么 PHP 配置之間可能存在一些差異:在/etc/php/apache2/php.ini/etc/php/cli/php.ini之間進行比較,然后查看可能發生了什么變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM