如何在 PHP 5.6 中通过 php.ini 设置“verify_peer_name=false"SSL 上下文选项 [英] How to set 'verify_peer_name=false' SSL context option via php.ini in PHP 5.6

查看:60
本文介绍了如何在 PHP 5.6 中通过 php.ini 设置“verify_peer_name=false"SSL 上下文选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

案例:我想打开到 localhost 的 SSL 连接,而 SSL 证书是 FQDN 的问题.

The case: I would like to open SSL connection to localhost while SSL certificate was issues for FQDN.

问题:在行 (*) 中没有特殊处理,下面的程序失败并显示以下消息:

The problem: Without special handling in line (*) the program below fails with the following message:

PHP 警告:stream_socket_enable_crypto():对等证书 CN='myhost.com' 与 test.php 中的预期 CN='localhost' 不匹配

测试PHP程序:

$fp = stream_socket_client("tcp://localhost:993", $errno, $errstr, 30);

// (*) if commented, the program fails
//stream_context_set_option($fp, 'ssl', 'verify_peer_name', false); 

if (!$fp) {
        die("Unable to connect: $errstr ($errno)");
}
if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
        die("Failed to start SSL");
}
fwrite($fp, "USER god\r\n");
fwrite($fp, "PASS secret\r\n");
while ($motd = fgets($fp)) {
        echo $motd;
}
fclose($fp);

由于我有很多遗留代码,我很想通过仅对 php.ini(或 CLI)应用更改来获得解决方案,但不幸的是以下两种方法都不起作用:

As I have a lot of legacy code, I would love to have a solution by only applying changes to php.ini (or CLI), but unfortunately neither of below works:

php -d verify_peer_name=false test.php

php -d ssl.verify_peer_name=false test.php

想法?

参考文献:

推荐答案

TL;博士

cafilecapath 同时运行时配置SSL上下文选项verify_peer_nameverify_peer 只是SSL 上下文选项.

TL; DR

When cafile and capath are at the same time runtime configuration and SSL context options, verify_peer_name and verify_peer are only SSL context options.

所以后两个不能通过运行时配置指令进行修改.

So those later two can not be modified via runtime configuration directives.

我可以从下面复制的文档中理解混淆,但这两个段落实际上指的是 PHP 中的两个不同概念.

I can understand the confusion from the documentation reproduced here under, but those two paragraphs actually refer to two different concept in PHP.

可以通过设置在全局基础覆盖默认的 CA 包openssl.cafile 或 openssl.capath 配置设置,或在每个请求的基础上使用 cafile 或 capath 上下文选项.

The default CA bundle may be overridden on a global basis by setting either the openssl.cafile or openssl.capath configuration setting, or on a per request basis by using the cafile or capath context options.

虽然一般不推荐,但可以禁用对等证书验证请求通过设置 verify_peer上下文选项为 FALSE,并通过以下方式禁用对等名称验证将 verify_peer_name 上下文选项设置为 FALSE.

While not recommended in general, it is possible to disable peer certificate verification for a request by setting the verify_peer context option to FALSE, and to disable peer name validation by setting the verify_peer_name context option to FALSE.

链接到 PHP 手册源

首先请注意,文档本身在 openssl.cafileopenssl.capath在全球范围内基于每个请求,而 verify_peerverify_peer_name 仅用于请求.

First note that the documentation itself makes a clear difference between openssl.cafile and openssl.capath being on a global basis or on a per request basis versus verify_peer and verify_peer_name being for a request only.

所以这基本上意味着,当 openssl.cafileopenssl.capath 可以通过 php.ini 或通过 进行调整时>stream_context_set_option,另一方面 verify_peerverify_peer_name 只能通过 stream_context_set_option 访问.

So that basically means that, when openssl.cafile and openssl.capath can be adapted both via php.ini or via stream_context_set_option, on the other hand verify_peer and verify_peer_name are only accessible via stream_context_set_option.

PHP 源代码本身也证实了这一点,这里有几行表明 PHP 底层 C 语言正在从 php_stream_context_get_option 获取值仅.

This is also confirmed by PHP source code itself, here are some lines showing that PHP underlaying C language is getting the value from php_stream_context_get_option only.

must_verify_peer_name = GET_VER_OPT("verify_peer_name")
        ? zend_is_true(val)
        : sslsock->is_client;

链接到PHP github源代码/a>

Link to PHP github source code

为了清楚起见,这里是宏GET_VER_OPT

For clarity, here is the declaration of the macro GET_VER_OPT

#define GET_VER_OPT(name)               (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", name)) != NULL)

PHP github源代码链接

cafilecapath 实际上首先与 php_stream_context_get_option 值匹配时,如果它们是 NULL在上下文中,然后在 ini 配置中获取它们.

When cafile and capath are actually first matched against php_stream_context_get_option value, but then, if those are NULL in the context, they are then fetched in the ini configuration.

GET_VER_OPT_STRING("cafile", cafile);
GET_VER_OPT_STRING("capath", capath);

if (cafile == NULL) {
    cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0);
    cafile = strlen(cafile) ? cafile : NULL;
}

链接到PHP github源代码/a>

Link to PHP github source code

然后在完全相同的功能中稍微低一点:

Then a little lower in the exact same function:

if (capath == NULL) {
    capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0);
    capath = strlen(capath) ? capath : NULL;
}

链接到PHP github源代码/a>

Link to PHP github source code

为了清楚起见,这里是宏 GET_VER_OPT_STRING

For clarity, here is the declaration of the macro GET_VER_OPT_STRING

#define GET_VER_OPT_STRING(name, str)   if (GET_VER_OPT(name)) { convert_to_string_ex(val); str = Z_STRVAL_P(val); }

PHP github源代码链接

你也可以看到,当这两个值 openssl.capthopenssl.cafile 被定义为现有的ini 配置,后面的verify_peerverify_peer_name 无处可寻.

You can also see that, when those two value openssl.capth and openssl.cafile are defined as existing ini configuration, the later verify_peer and verify_peer_name are nowhere to be found.

很遗憾,正如文档所提示的那样,唯一的方法是通过 stream_context_set_option ( $stream_or_context , 'ssl' , 'verify_peer_name' , false )

So sadly the only way to go, as the documentation is prompting it, is to configure it for a request via stream_context_set_option ( $stream_or_context , 'ssl' , 'verify_peer_name' , false )

历史悠久:这是这两个 SSL 上下文选项的默认值.按照文档的提示,它们在 PHP 5.6.0 版中发生了变化:

In a long gone history: this was the default value of those two SSL context options. They changed in PHP version 5.6.0, as prompted by the documentation:

5.6.0 添加了 peer_fingerprint 和 verify_peer_name.verify_peer 默认更改为 TRUE.

5.6.0 Added peer_fingerprint and verify_peer_name. verify_peer default changed to TRUE.

PHP 文档链接

这意味着在从PHP <升级PHP后会出现这种问题.5.6.0 因此,通过坚持低于 5.6.0PHP 版本,这两个选项的默认值可以保持为 false;但是由于 PHP 的分支 5.*.* 现在 完全退出支持这不再是一个可行的选择.

Which means that this kind of issue can appear after upgrading PHP from PHP < 5.6.0 so, the default value of those two options could have been kept to false by sticking to a PHP version lower than 5.6.0; but since the branches 5.*.* of PHP are now totally out of support this is not a viable option anymore.

这篇关于如何在 PHP 5.6 中通过 php.ini 设置“verify_peer_name=false"SSL 上下文选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆