progress_man
@progress_man
php – it's my life

Почему не работает Workerman для wss соединения?

Есть вебсокет-демон на PHP 7.0 (реализован на Workerman). Кусок кода:

$worker = new Worker('websocket://my-domain.com:8084', [
    'ssl' => [
        'local_cert'  => '/etc/letsencrypt/live/my-domain.com/cert.pem',
        'local_pk'    => '/etc/letsencrypt/live/my-domain.com/privkey.pem',
        'verify_peer' => false,
    ]
]);
$worker->transport = 'ssl';
$worker->count = 1;
$worker->onConnect = function ($connection) { ... }

При разработке на локальном сервере использую самозаверенные SSL-сертификаты и все работает как нужно: клиент уверенно подключается к демону по wss. На рабочем сервере использую сертификаты Let's Encrypt.

И вот тут начинается странное: при попытке подключения клиента Workerman выбрасывает следующую ошибку
Error: stream_socket_enable_crypto(): SSL_R_NO_SHARED_CIPHER: no suitable shared cipher could be used.  This could be because the server is missing an SSL certificate (local_cert context option)

Подскажите, в чем может быть проблема?
  • Вопрос задан
  • 3764 просмотра
Решения вопроса 1
@makenow
В общем мучался-мучался, что я только не пробовал : )) В итоге всё оказалось очень просто: проблема в том, что сертификаты находятся "чертиде" /etc/letsencrypt/live/ и доступа к ним по сути у workerman нет, решение сделать линки на сертификаты и положить эти линки рядом со скриптом запуска.

пример:
sudo cp -l /etc/letsencrypt/live/my-domain.com/fullchain.pem /var/www/вашсайт/fullchain.pem

sudo cp -l /etc/letsencrypt/live/my-domain.com/privkey.pem /var/www/вашсайт/privkey.pem

и затем подключить

$context = array(
  'ssl' => array(
    'local_cert'  => __DIR__.'/fullchain.pem',
    'local_pk'    => __DIR__.'/privkey.pem',
    'verify_peer' => false,
  )
);

// Create a Websocket server
$ws_worker = new Worker("websocket://0.0.0.0:8084", $context);//0.0.0.0 - значит принимать соединения от любого ip
$ws_worker->transport = 'ssl';


и будет счастье :)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
ivankomolin
@ivankomolin
Черным по белому написано, что эта ошибка возможно из-за того что он не может найти на диске сертификат из свойства local_cert

Проверьте правильность путей до сертификатов

Если все указано верно, то посмотрите в сторону crypto_type.
Может быть выбран тот, которого не имеется на сервере.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы