openSSL 不适用于 PHP 内置网络服务器
Posted
技术标签:
【中文标题】openSSL 不适用于 PHP 内置网络服务器【英文标题】:openSSL not working with PHP built-in webserver 【发布时间】:2012-10-08 10:18:06 【问题描述】:操作系统: Ubuntu 12.04 64 位
PHP版本: 5.4.6-2~precise+1
当我通过内置网络服务器 (php5 -S localhost:8000) 测试 https 页面时,Firefox (16.0.1) 说“加载问题:连接中断”,而终端告诉我“ ::1:37026 无效请求(不支持的 SSL 请求)”。
phpinfo() 告诉我:
注册流套接字传输:tcp、udp、unix、udg、ssl、sslv3、 tls [卷曲] SSL:是的 SSL 版本:OpenSSL/1.0.1openssl:
OpenSSL 支持:启用
OpenSSL 库版本 OpenSSL 1.0.1 2012 年 3 月 14 日
OpenSSL 标头版本 OpenSSL 1.0.1 2012 年 3 月 14 日
是的,http 页面可以正常工作。
有什么想法吗?
【问题讨论】:
应该会出现ServerFault。 不完全是你想要的,但你可以试试 ngrok ***.com/a/23243958/632951 【参考方案1】:请参阅内置网络服务器 shim 的手册部分:http://php.net/manual/en/features.commandline.webserver.php
它不支持 SSL 加密。它适用于普通的 HTTP 请求。 openssl
扩展和功能支持无关。它不接受请求或通过流包装器发送响应。
如果您希望 SSL 在其上运行,请尝试使用 stunnel
包装器:
php -S localhost:8000 &
stunnel3 -d 443 -r 8080
反正就是玩玩。
【讨论】:
在哪里可以找到采用这些选项的 stunnel 版本?根据 stunnel.org 上的文档,那里可用的应用程序不采用“-d”或“-r”选项。 使用stunnel3。似乎stunnel4
主要作为守护进程/通过 iptables 运行,并且需要一个配置文件。
@Pacerier 它仍然是最简单的设置选项。对于测试mitmproxy 可能是一个不错的选择。对于长期存在的设置,Tinyproxy 或只是简单的 Apache+mod_proxy 甚至可以将 HTTPs 转发到 PHPs http 服务器。
重新上面的代码(php -S localhost:8000 &; stunnel3 -d 443 -r 8080) stunnel3命令好像把443端口的https请求重定向到8080端口,php命令好像服务请求到 8000 端口。stunnel3 命令是否应该重定向到 8000 端口?
我不得不:openssl req -new -x509 -days 365 -nodes -out stunnel.pem -keyout stunnel.pem && sudo mv stunnel.pem /etc/stunnel && sudo stunnel3 -p /etc /stunnel/stunnel.pem -d 443 -r 8000【参考方案2】:
距离上次更新已经三年了;以下是我如何在 2021 年在 macOS 上运行它(作为 mario 答案的扩展):
# Install stunnel
brew install stunnel
# Find the configuration directory
cd /usr/local/etc/stunnel
# Copy the sample conf file to actual conf file
cp stunnel.conf-sample stunnel.conf
# Edit conf
vim stunnel.conf
修改 stunnel.conf
使其看起来像这样:
(其他选项都可以删除)
; **************************************************************************
; * Global options *
; **************************************************************************
; Debugging stuff (may be useful for troubleshooting)
; Enable foreground = yes to make stunnel work with Homebrew services
foreground = yes
debug = info
output = /usr/local/var/log/stunnel.log
; **************************************************************************
; * Service definitions (remove all services for inetd mode) *
; **************************************************************************
; ***************************************** Example TLS server mode services
; TLS front-end to a web server
[https]
accept = 443
connect = 8000
cert = /usr/local/etc/stunnel/stunnel.pem
; "TIMEOUTclose = 0" is a workaround for a design flaw in Microsoft SChannel
; Microsoft implementations do not use TLS close-notify alert and thus they
; are vulnerable to truncation attacks
;TIMEOUTclose = 0
这在端口 443 接受 HTTPS / SSL 并连接到在端口 8000 上运行的本地网络服务器,使用 stunnel 的默认伪造证书/usr/local/etc/stunnel/stunnel.pem
。日志级别为info
,日志输出写入/usr/local/var/log/stunnel.log
。
启动通道:
brew services start stunnel # Different for Linux
启动网络服务器:
php -S localhost:8000
现在您可以访问https://localhost:443
访问您的网络服务器:screenshot
应该有一个证书错误,您必须单击浏览器警告,但这会让您可以使用 HTTPS 请求访问您的本地主机,以进行开发。
【讨论】:
【参考方案3】:我最近一直在学习nginx和Laravel,这个错误出现了很多次。很难诊断,因为您需要同时将 nginx 与 Laravel 以及操作系统中的 SSL 设置对齐(假设您正在制作自签名证书)。
如果您在 Windows 上,则更加困难,因为在处理 SSL 证书时,您必须与 unix 回车作斗争。有时你可以正确地完成这些步骤,但你会被证书验证问题毁掉。我发现诀窍是在 Ubuntu 或 Mac 中制作证书并将它们通过电子邮件发送给自己,或者使用 linux 子系统。
就我而言,我一直遇到一个问题,我在某处声明了 HTTPS,但 php artisan serve
仅适用于 HTTP。
我刚刚在 SSL 连接正常后再次引发了这个 Invalid request (Unsupported SSL request)
错误。原来是我使用Axios
向https://
发出POST 请求。将其更改为 POST http://
已修复。
我对任何人的建议是查看在何处以及如何使用 HTTP/HTTPS。
教科书的定义可能类似于php artisan serve
,仅适用于 HTTP,但需要底层 SSL 层。
【讨论】:
【参考方案4】:使用Ngrok
像这样公开你的服务器端口:
ngrok http <server port>
使用 ngrok 的安全公共地址(带有 https 的地址)浏览。
注意:虽然它的作用就像一个魅力,但它似乎有点矫枉过正,因为它需要互联网并且希望得到更好的建议。
【讨论】:
以上是关于openSSL 不适用于 PHP 内置网络服务器的主要内容,如果未能解决你的问题,请参考以下文章