如何使用PHP

时间:2017-09-06 21:25:45

标签: php ssl ibm-mq

我想使用PHP应用程序(脚本)中的SSL身份验证连接到WebSphere MQ Queue。

  • 队列管理器版本为7.0或7.5
  • MQ客户端版本为8.0
  • PHP版本为7.0(泊坞窗)
  • 使用PHP mqseries pecl extension v0.15(带自定义修复程序)

到目前为止,我能够在没有SSL连接的情况下进行连接。

以下是我到目前为止所要完成的步骤:

  • 我已经安装了适用于Linux的WebSphere MQ Client v8(在我的情况下是CentOS)
  • 我已经下载了mqseries php扩展的PECL 0.15版本。 (作为扩展中的一个小错误,我不得不重新编译它以使其正常工作。我曾经在MQGET上遇到分段错误。)
  • 我将mqseries.so链接到php并启用了扩展程序。

我成功(没有SSL)

  1. 连接到队列管理器
  2. 打开队列进行阅读
  3. 在队列中获取消息
  4. 关闭连接
  5. 当我将脚本中的USE_SSL设置为true时,我收到错误代码2393,意思是“An MQCONN or MQCONNX call was issued with SSL configuration options specified, but an error occurred during the initialization of the SSL environment.”此错误消息非常通用,并没有帮我确定问题所在

    MQ_KEYSTORE设置为/path/to/my/key,我的文件名为key.kdb,并且与documentation

    建议的key.sth处于同一级别MQ_SSL_CIPHER_SPEC

    脚本中的MQ_CHANNEL_SSL与指定的???的队列管理器上指定的相同。多次检查。这些不是与{JMS连接一起使用的Cipher Suite

    安全缓存已在队列管理器上刷新。

    在服务器端,我检查了队列管理器的错误日志,但似乎没有看到我的频道名称。我说“似乎”因为有很多噪音而且该地段有一些amqssslc频道名称。所以我觉得它由于某种原因没有到达队列管理器。

    我还使用MQ Client安装bin文件夹中的“MQ_PORT”命令来测试我的ssl配置。我得到的错误与使用PHP脚本相同。

    我还使用WireShark在相应的<?php // Constants defined here $options = [ 'Version' => MQSERIES_MQCNO_VERSION_4, 'Options' => MQSERIES_MQCNO_STANDARD_BINDING, 'MQCD' => [ 'Version' => 7, 'ChannelName' => MQ_CHANNEL, 'ConnectionName' => sprintf('%s(%s)', MQ_HOST, MQ_PORT), 'TransportType' => MQSERIES_MQXPT_TCP, ] ]; if (USE_SSL) { $options['MQSCO'] = [ 'KeyRepository' => MQ_KEYSTORE ]; $options['MQCD']['ChannelName'] = MQ_CHANNEL_SSL; $options['MQCD']['SSLCipherSpec'] = MQ_SSL_CIPHER_SPEC; } mqseries_connx(MQ_QUEUE_MANAGER, $options, $conn, $comp_code, $reason ); $mqods2 = [ 'ObjectType' => MQSERIES_MQOT_Q, 'ObjectName' => MQ_QUEUE ]; mqseries_open($conn, $mqods2, MQSERIES_MQOO_INPUT_AS_Q_DEF | MQSERIES_MQOO_FAIL_IF_QUIESCING, $obj, $comp_code, $reason); $gmd = []; $gmo = [ 'Options' => MQSERIES_MQGMO_FAIL_IF_QUIESCING | MQSERIES_MQGMO_WAIT, 'WaitInterval' => 3000 ]; $msg = ""; $data_length = ""; for ($i = 0; $i < 1000; $i++) { mqseries_get($conn, $obj, $gmd, $gmo, 10000, $msg, $data_length, $comp_code, $reason); if ($reason === 2033) { printf("No more messages to process\n"); break; } // Business logic } mqseries_disc($conn, $comp_code, $reason); ?> 上嗅探数据包。包的内容包含证书信息。所以有一些看起来像SSL握手的东西。

    我现在已经没有关于如何调试案例的想法了。有没有人知道接下来要检查什么?我的MQ客户端安装上是否有连接日志,我应该检查?

    以下是connection using SSL in PHP

    的示例

    这是我的MQ脚本的简化版本(我删除了输出)。出于安全目的,未公开某些常量。

    所有MQSERIES_ *常量都在扩展名

    中定义

    所有MQ_ *都是用于测试我的脚本的硬编码参数,但它们的定义不会出现在脚本摘录中。

    For queue managers and clients respectively, the following sources are searched in sequence for a non-empty value. The first non-empty value determines the certificate label. The certificate label must exist in the key repository. If no matching certificate in the correct case and format is found that matches a label, an error occurs and the SSL or TLS handshake fails.

    更新

    使用我不知道的客户端日志。我们终于发现我们的服务器没有使用正确的证书。服务器的证书实际上是自签名的,因此不授予我们访问权限,因为我们的.kdb文件没有它的公钥。我们将服务器自己的公钥添加到.kdb文件中,使该步骤成功。

    正如JoshMC的评论所示,对于我们的下一个问题,我们怀疑密钥库文件中的标签是错误的。我们没有从.kdb文件中指定特定标签。来自docsThe certificate label cannot contain spaces.

    它还声明“ibmwebspheremq<user_that_runs_the_php_process>”。

    明天我将再次尝试使用正确的标签命名并发送特定的标签名称。我将尝试查看名称约定ikeycmd是否确实影响了有效性。

    更新2

    终于成功了。正如JoshMC所提到的,私钥需要具有特定标签ibmwebspheremq。我还没有尝试过CertificateLabel。我可能会在下周深入研究它。

    首先,我们使用ibm的GUI(ikeyman)生成.kdb文件。但是我们发现它有很多错误。例如,它使用相同的标签(证书中自动生成的标签)导入两次私钥。无法编辑标签名称(因此存在连接问题)。为了解决这个问题,我们使用命令行工具java com.ibm.gsk.ikeyman.ikeycmd,它基本上在命令行上提供相同的功能(减去错误)。要运行该命令,您需要IBM jre(未验证,需要签出)并将其作为{{1}}运行。从这里开始,IBM网站上有一整套关于如何创建证书,重命名标签,检查详细信息等的文档。很多很有趣!

1 个答案:

答案 0 :(得分:1)

使用完整的IBM MQ客户端安装,客户端错误将记录到目录:/var/mqm/errors

如果有任何错误将被记录到文件AMQERR01.LOG(这将以另外两个以0203结尾的文件进行轮换。如果错误是MQ不期望的内容它还可能会创建一个以.FDC结尾的文件以及其他详细信息。

如果在客户端发送频道名称之前的频道协商期间连接失败,队列管理器将记录频道名称???。如果队列管理器使用v7.5或更低版本的IBM MQ,则在TLS握手完成之前不会交换通道名称。

随着v8及更高版本的客户端连接到v8及更高版本的队列管理器,MQ将使用TLS SNI在TLS协商期间交换通道名称,但是我不确定MQ是否也已被增强以记录此通道名称在先前版本中的位置已记录???。请注意,即使在v8及更高版本中,IBM MQ Classes for Java和IBM MQ Classes for JMS客户端也不支持SNI功能,并且在TLS握手完成之前不会发送通道名称。

检查您的客户key.kdb是否有私钥。 MQ使用三种方法来识别要使用的私钥。

  1. 使用MQ Client v7.5及更早版本,私钥的标签必须为:

    ibmwebspheremq<user_that_runs_the_php_process>
    
  2. 使用MQ客户端v7.5及更早版本,另一种方法是将私钥设置为默认证书,并确保在执行程序的环境中设置以下环境变量。请注意,这也适用于8.0.0.7/9.0.0.1,但我更喜欢下一个方法。

     AMQ_SSL_ALLOW_DEFAULT_CERT=1
    
  3. 使用MQ Client v8及更高版本,您可以在CertificateLabel=anylabelvalue的{​​{1}}节中使用SSL。示例如下:

    mqclient.ini

    IBM MQ v8 KC页面中记录了SSL: CertificateLabel=anylabelvalue 设置&#34; SSL stanza of the client configuration file&#34;。

    CertificateLabel的模板可以从mqclient.ini复制并放在应用程序执行的同一目录中。该位置也可以通过环境变量指定,如果未设置该变量且未在应用程序执行的同一目录中找到该文件,MQ将查看该文件的其他几个位置。 IBM MQ v8 KC页面记录了MQ查找此文件的各种方式&#34; Location of the client configuration file&#34;