Как подключиться к очереди WebSphere MQ с использованием аутентификации SSL в Stack Overflow

Я хочу подключиться к WebSphere MQ Queue, используя SSL-аутентификацию из PHP-приложения (скрипта).

  • Версия диспетчера очереди 7.0 или 7.5
  • Версия клиента MQ 8.0
  • Версия PHP 7.0 (докер)
  • Использование PHP mqseries pecl расширение v0.15 (с пользовательскими исправлениями)

До сих пор я смог подключиться без SSL-соединения.

Вот шаги, которые я должен сделать до сих пор:

  • Я установил WebSphere MQ Client v8 для Linux (CentOS в моем случае)
  • Я скачал версию PECL 0.15 расширения mqseries php. (Там, как небольшая ошибка в расширении, мне пришлось перекомпилировать его, чтобы заставить его работать должным образом. Я использовал, чтобы получить ошибку сегментации в MQGET).
  • Я связал mqseries.so с php и включил расширение.

Я успешно (без SSL)

  1. Подключиться к администратору очередей
  2. Откройте очередь для чтения
  3. Получать сообщения в очереди
  4. Закрыть соединение

Когда я установил USE_SSL в моем сценарии к истине я получаю код ошибки 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 и имеет на том же уровне key.sth как предполагает это документация

MQ_SSL_CIPHER_SPEC в сценарии совпадает с указанным в администраторе очередей для указанного MQ_CHANNEL_SSL, Проверено несколько раз. Это НЕ Cipher Suite используется с соединениями JMS

Кэш безопасности обновлен в администраторе очередей.

На стороне сервера я проверил журналы ошибок для администратора очередей и, похоже, не увидел название моего канала. Я говорю «кажется», потому что было много шума и было несколько ??? Название канала в лоте. Поэтому я чувствую, что по какой-то причине он не дошел до администратора очередей.

Я также использовалamqssslc«Команда найдена в папке bin установки MQ Client, чтобы проверить мою конфигурацию ssl. Я получаю ту же ошибку, что и скрипт PHP.

Я также использовал WireShark, чтобы прослушивать пакеты на соответствующих MQ_PORT, Содержимое пакетов содержало информацию о сертификате. Так что происходит что-то вроде рукопожатия SSL.

У меня сейчас нет идей относительно того, как отладить дело. У кого-нибудь есть идеи, что проверять дальше? Есть ли в моей установке MQ Client журналы подключений, которые я должен проверить?

Вот пример соединение с использованием SSL в PHP

Вот упрощенная версия моего сценария MQ (я удалил выводы). Некоторые из констант не раскрываются в целях безопасности.

Все константы MQSERIES_ * определены в расширении

Все MQ_ * являются жестко закодированными параметрами для тестирования моего скрипта, но их определение не появляется в отрывке скрипта.

<?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);

?>

ОБНОВИТЬ

Использование клиентских журналов, которые я не знал, существовал. Мы наконец узнали, что наш сервер не использовал надлежащий сертификат. Сертификат сервера на самом деле был самоподписанным, поэтому нам не был предоставлен доступ, потому что наш файл .kdb не имел своего открытого ключа. Мы добавили собственный открытый ключ сервера в файл .kdb, чтобы этот шаг удался.

Как указано в комментариях JoshMC, для нашей следующей проблемы мы подозреваем, что в файле хранилища ключей неправильная метка. Мы не указали конкретную метку из файла .kdb. От документы «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.«

И это также утверждает, что «The certificate label cannot contain spaces.».

Завтра я попробую еще раз с правильным именованием этикетки и отправкой конкретного имени этикетки. Я постараюсь увидеть, если название конвенции ibmwebspheremq<user_that_runs_the_php_process> на самом деле влияет на действительность.

ОБНОВЛЕНИЕ 2

Наконец-то все получилось. Как упоминал JoshMC, закрытый ключ должен иметь специальную метку ibmwebspheremq. Я еще не пробовал CertificateLabel. Я мог бы копаться в этом на следующей неделе.

Сначала мы использовали GUI (ikeyman) из ibm для генерации файла .kdb. Но мы узнали, что в нем довольно много ошибок. Например, он дважды импортирует закрытый ключ с одинаковой меткой (автоматически сгенерированная метка из сертификата). Редактирование названия метки было невозможно (отсюда и проблемы с подключением). Для решения этой части мы использовали инструмент командной строки ikeycmd это в основном предлагает те же функции в командной строке (за исключением ошибок). Для запуска команды вам понадобится IBM jre (не проверено, необходимо извлечь) и запустите его как java com.ibm.gsk.ikeyman.ikeycmd, Отсюда на веб-сайте IBM целый мир документации о том, как создать сертификат, переименовать метки, проверить детали и т. Д. Много и много веселья!

1

Решение

При полной установке клиента IBM MQ ошибки на стороне клиента будут записываться в каталог: /var/mqm/errors

Ошибки, если таковые имеются, будут записаны в файл AMQERR01.LOG (вращается с двумя другими файлами, оканчивающимися на 02 а также 03, Если ошибка является чем-то, чего MQ не ожидает, он может также создать файл, который заканчивается .FDC с дополнительными деталями.


Диспетчер очереди запишет название канала ??? если соединение не удалось во время согласования канала до того, как клиент отправит имя канала. Если IBM MQ администратор очередей использует версию 7.5 или ниже, имя канала не будет изменено до тех пор, пока не будет завершено квитирование TLS.

С v8 и более поздними клиентами, подключающимися к v8 и более поздними администраторами очередей, MQ будет использовать TLS SNI для обмена именем канала во время согласования TLS, однако я не уверен, что MQ также был улучшен для регистрации этого имени канала, где в предыдущих версиях он регистрировался ???, Обратите внимание, что IBM MQ Classes для Java и IBM MQ Classes для JMS-клиента даже в v8 и более поздних версиях не поддерживают функцию 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 в SSL строфа из mqclient.ini, Пример ниже:

    SSL:
    CertificateLabel=anylabelvalue
    

    CertificateLabel настройка задокументирована на странице IBM MQ v8 KC «SSL
    раздел файла конфигурации клиента
    ».

    Шаблон для mqclient.ini можно скопировать из /var/mqm/mqclient.ini и помещается в тот же каталог, где выполняется приложение. Расположение можно также указать с помощью переменной среды, и MQ будет искать файл в нескольких других местах, если переменная не задана, и не найдет его в том же каталоге, где выполняется приложение. Различные способы, которыми MQ будет искать этот файл, описаны на странице IBM MQ v8 KC «Расположение файла конфигурации клиента«

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]