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

发布于 2024-11-24 07:24:31 字数 682 浏览 2 评论 0原文

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

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

谢谢, 马库斯

I'm trying since a couple of days to establish a TLS connection to a SMTP server in PHP via fsockopen() on my newly installed Ubuntu server. I#ve tried almost everything and googled for hours but still I didn't get it working.

The PHP code looks as follows:

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

The output is just (0), i.e., $errstr = null and $errno = 0.

OpenSSL is installed and enabled:

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.

The port is open as a telnet from the console works.

Any ideas what's wrong or how I could at least get some more debug output?

Thanks,
Markus

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风轻花落早 2024-12-01 07:24:31

对于 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);

With gmail, the ssl connection port had ssl from the get-go, but the tls port, you connected plain, and had to start tls manually with a STARTTLS command. I'm guessing this is the same. Here's and example to gmail so you can see what's going on. The EHLO command shows the STARTTLS command while if you start with ssl from the begining, it goes strait to the AUTH XOAUTH command list.

<?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);
淡写薰衣草的香 2024-12-01 07:24:31

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

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

Your connection doesn't make much sense. By using the TLS handler, you want TLS to be established BEFORE any data goes. But port 25 is standard SMTP, which can only establish TLS AFTER you've initially connected via an unencrypted regular connection. Once that initial connection is established, then you can enable TLS with the STARTTLS command to tell the SMTP server to switch over.

If you want TLS from the get-go, then use port 465, which is ssl/tls from the start.

北音执念 2024-12-01 07:24:31

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

If it works from the command line but not from within Apache then there is probably some difference between the PHP configuration: do a diff between /etc/php/apache2/php.ini and /etc/php/cli/php.ini and see what might have changed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文