![](/img/trans.png)
[英]php,mqtt: stream_socket_client(): unable to connect to <server><port>
[英]PHP stream_socket_client fails to connect
我正在嘗試通過php的stream_socket_client()命令聯系url,該命令失敗,沒有錯誤代碼或msg。 是否使用openssl,curl或其他? 該網站使用https,並且可以通過網絡瀏覽器正常運行。
當我直接致電openssl時,它會連接,但證書鏈顯示為hphppy。
root@drupal7 drupal7/includes# openssl s_client -connect test.cgps.org:443
CONNECTED(00000003)
Verify return code: 21 (unable to verify the first certificate)
一樣卷曲
curl https://test.cgps.org/?q=/admin/config/search/clean-urls/check
curl: (60) SSL certificate problem: unable to get local issuer certificate
因此,我認為我需要將中間證書安裝到Linux中,方法是將Apache使用的相同中間證書放入/ usr / local / share / ca-certificates並運行update-ca-certificates。
root@drupal7 drupal7/includes# update-ca-certificates
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
還是沒有運氣...
盡管評論中有聲明說PHP的steam_socket_client()
太低級,無法處理證書,但我知道它確實在乎,因為我發現它在標准位置缺少某些證書的系統上返回false
,在該位置提供流上下文(告訴它在哪里可以找到證書)阻止了這種情況的發生。
令人沮喪的是,在您修復此問題之前, $errno
可以保持為0,因此最好先使用其他工具檢查您的證書授權目錄。
curl
為了使curl
起作用,通常可以通過添加--verbose
標志來弄清楚發生了什么。 這應該告訴您正在使用哪個串聯的證書PEM文件(CAfile / cacert)和CA目錄(capath)(如果有)。 在輸出的頂部,您將獲得類似以下內容的信息:
[...]
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: /home2/wynddorg/private_html/trusted_roots
[...]
知道這些默認設置后,您就可以調整系統配置,或者簡單地添加--cacert <concatenated_cert_path>
標志或--capath <c_rehash'd_directory>
或兩者。
openssl s_client
使用s_client
比較麻煩。 您可能可以訪問其-trace
選項,具體取決於您的版本及其編譯方式,但是請嘗試:
strace -e open,stat openssl s_client -connect test.cgps.org:443 [-CApath <dir>]
# this trick provided by the amazing xemdetia in irc://freenode/%23%23openssl
在CONNECTED(00000003)
消息后大約5行,您應該看到一個open("...", O_RDONLY)
(或幾行),該行應該揭示正在使用哪些位置查找證書。
一旦知道缺少哪些證書,就可以按照此處所示下載它們,然后執行任何操作:
c_rehash
(可能需要root / sudo) 一旦可以使用openssl s_client
或curl
或同時使用二者,就可以指定相同的選項,如下所示:
$context = stream_context_create();
stream_context_set_option($context, 'ssl', 'cafile', <concatenated_cert_file_path>);
stream_context_set_option($context, 'ssl', 'capath', <c_rehashed_cert_dir_path>);
// You only really need to provide one of the two options above. Using capath is
// faster, but this only matters if you'll be making a huge number of
// connections.
$ssc = stream_socket_client(
'ssl://subdomain.example.com:443',
$errno,
$errstr,
30,
STREAM_CLIENT_CONNECT,
$context
);
if ($ssc) { /* ... */ }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.