2

几天以来,我一直在尝试通过我新安装的 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 工作时打开。

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

谢谢,马库斯

4

3 回答 3

5

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

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

于 2011-07-15T14:11:06.687 回答
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);
于 2011-12-18T11:46:37.230 回答
0

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

于 2011-07-15T14:22:09.073 回答