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

时间:2011-07-15 14:04:41

标签: 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
}  

输出只是(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

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

端口是从控制台工作的telnet打开的。

任何想法有什么问题,或者我至少可以获得更多的调试输出?

谢谢, 马库斯

3 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:5)

使用gmail,ssl连接端口有来自get-go的ssl,但是tls端口,你连接了plain,并且必须使用STARTTLS命令手动启动。我猜这是一样的。以下是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);

答案 2 :(得分:0)

如果它可以从命令行运行,但不能从Apache内部运行,那么PHP配置之间可能存在一些差异:在/etc/php/apache2/php.ini/etc/php/cli/php.ini之间进行差异,看看可能发生了哪些变化。