Я написал небольшой SIP-клиент для специальной цели. В основном он подключается к порту 5060 с помощью функции fsockopen()
$fp = fsockopen("10.0.0.1", 5060, $errno, $errstr, 30);
а затем в основном считывает и записывает SIP-команды, используя fread()
и fwrite()
.
Теперь мой оператор службы SIP хочет, чтобы клиенты использовали SIPS, который в основном SIP через TLS. Я потратил много времени на поиск информации о том, как подключиться к порту с помощью TLS с помощью PHP, но без каких-либо успехов. По-видимому, fsockopen()
поддерживает TLS до степени, но когда я заменил выше:
$fp = fsockopen("tls://10.0.0.1", 5061, $errno, $errstr, 10);
Я ничего не получаю. Я могу подключиться к серверу из своей оболочки с помощью клиента OpenSSL:
$ openssl s_client -connect 10.0.0.1:5061
И я могу общаться с сервером SIP через это соединение без проблем. Поддержка OpenSSL скомпилирована в PHP.
Моя проблема в том, что я не могу настроить соединение TLS с сервером на PHP. На некоторых форумах я заметил, что в более старых версиях PHP можно было создать и использовать контекст SSL с помощью fsockopen()
но, видимо, больше нет, так как я получаю сообщение об ошибке слишком много параметров.
Я также попытался использовать stream_context_create()
с stream_context_set_option()
но у меня нет ответов с сервера:
$context = stream_context_create(); $result=stream_context_set_option($context, 'ssl', 'verify_peer', 'TRUE'); $result=stream_context_set_option($context, 'ssl', 'cafile', 'cert.cer'); $result=stream_context_set_option($context, 'ssl', 'verify_depth', '5'); $fp = stream_socket_client('tls://'.$host.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
но я до сих пор не могу получить никаких ответов или ошибок с сервера. Каков рекомендуемый и рабочий способ использования TLS в PHP?
Я думаю, что некоторые из ваших вариантов неверны для проверки самоподписанных сертификатов; для его работы должно быть достаточно:
$context = stream_context_create([ 'ssl' => [ 'verify_peer' => true, 'allow_self_signed' => true, 'local_cert' => 'cert.cer', ], ]);
Этого достаточно, чтобы открыть TLS-соединение:
$context = stream_context_create(); $fp = stream_socket_client('tls://'.$host.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context)
если сертификаты находятся на их месте. Если это не так, следуйте инструкциям, связанным с Filippos.
Вам также потребуется установить соответствующие сертификаты для работы TLS. Проверьте этот вопрос SO на примере того, как использовать файлы ключей с обычными соединениями TLS.
Кроме того, проверьте спецификации SIPS в RFC 5630 .
Я только что столкнулся с этой ошибкой, отлаживая здесь и там проблему подключения или проблему с прокси-сервером, наконец нашел виновника … и решение было установить расширение php-pecl-crypto.
Моя машина – centos 7, используя remi-repo для PHP