无法通过fsockopen在PHP中建立TLS连接

Mar*_*ler 2 php ssl 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
}  
Run Code Online (Sandbox Code Playgroud)

输出只是(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
Run Code Online (Sandbox Code Playgroud)

并注册了以下流套接字传输:tcp,udp,unix,udg,ssl,sslv3,sslv2,tls.

端口从控制台工作作为telnet打开.

任何想法有什么不对或我至少可以获得更多的调试输出?

谢谢你,马库斯

Mar*_*c B 6

你的联系没有多大意义.通过使用TLS处理程序,您希望在任何数据发生之前建立TLS.但是端口25是标准SMTP,它只能在您最初通过未加密的常规连接进行连接建立TLS .建立初始连接后,您可以使用STARTTLS命令启用TLS 以告知SMTP服务器切换.

如果你想要从一开始就使用TLS,那么使用端口465,从一开始就是ssl/tls.


cra*_*pty 5

使用gmail,ssl连接端口从一开始就包含ssl,但是tls端口则是通过普通方式连接的,并且必须使用STARTTLS命令手动启动tls。我猜这是一样的。这是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);
Run Code Online (Sandbox Code Playgroud)