27

OS: Ubuntu 12.04 64-bit

PHP version: 5.4.6-2~precise+1

When I test an https page I am writing through the built-in webserver (php5 -S localhost:8000), Firefox (16.0.1) says "Problem loading: The connection was interrupted", while the terminal tells me "::1:37026 Invalid request (Unsupported SSL request)".

phpinfo() tells me:

  • Registered Stream Socket Transports: tcp, udp, unix, udg, ssl, sslv3, tls
  • [curl] SSL: Yes
  • SSL Version: OpenSSL/1.0.1
  • openssl:

    OpenSSL support: enabled

    OpenSSL Library Version OpenSSL 1.0.1 14 Mar 2012

    OpenSSL Header Version OpenSSL 1.0.1 14 Mar 2012

Yes, http pages work just fine.

Any ideas?

Pacerier
  • 86,231
  • 106
  • 366
  • 634
EMartins
  • 477
  • 1
  • 5
  • 13

4 Answers4

49

See the manual section on the built-in webserver shim:
http://php.net/manual/en/features.commandline.webserver.php

It doesn't support SSL encryption. It's for plain HTTP requests. The openssl extension and function support is unrelated. It does not accept requests or send responses over the stream wrappers.

If you want SSL to run over it, try a stunnel wrapper:

php -S localhost:8000 &   
stunnel3 -d 443 -r 8080  

It's just for toying anyway.

Mr. Lance E Sloan
  • 3,297
  • 5
  • 35
  • 50
mario
  • 144,265
  • 20
  • 237
  • 291
  • 1
    Where does one find the version of stunnel that takes these options? According to the documentation on stunnel.org, the application available there doesn't take the "-d" or "-r" options. – Mr. Lance E Sloan Jun 24 '14 at 19:56
  • 1
    Use [stunnel3](http://man.devl.cz/man/8/stunnel3). It seems `stunnel4` runs primarily as daemon / via iptables and requires a config file instead. – mario Jun 24 '14 at 20:21
  • Oh, I see... The stunnel3 Perl program located here: https://www.stunnel.org/downloads/stunnel3 (Which is also included in the distribution.) Thanks for the clarification. – Mr. Lance E Sloan Jun 25 '14 at 14:03
  • @mario, Is `stunnel` your recommendation, or is it a recommendation from php.net? – Pacerier Mar 15 '15 at 18:17
  • 2
    @Pacerier It's still the easiest option to set up. For testing [mitmproxy](http://mitmproxy.org/) might be a nice alternative. And for long-lived setups Tinyproxy or just plain Apache+mod_proxy for forwarding HTTPs to PHPs http server even. – mario Mar 15 '15 at 19:11
  • @mario, Is `stunnel` your recommendation, or is it a recommendation from php.net? – Pacerier Mar 19 '15 at 15:17
  • @Pacerier It's my recommendation. Question reason? – mario Mar 19 '15 at 15:24
  • @mario, To know if it's notable enough. – Pacerier Mar 19 '15 at 19:09
  • 7
    Re the code above (php -S localhost:8000 &; stunnel3 -d 443 -r 8080) The stunnel3 command appears to redirect port 443 https request to port 8080, and the php command appears to serve requests to port 8000. Should the stunnel3 command redirect to port 8000 instead? – MgFrobozz Aug 09 '16 at 15:49
  • 5
    I had to: 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 – Jacek Kobus May 11 '18 at 12:01
10

It's been three years since the last update; here's how I got it working in 2021 on macOS (as an extension to mario's answer):

# 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

Modify stunnel.conf so it looks like this: (all other options can be deleted)

; **************************************************************************
; * 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

This accepts HTTPS / SSL at port 443 and connects to a local webserver running at port 8000, using stunnel's default bogus cert at /usr/local/etc/stunnel/stunnel.pem. Log level is info and log outputs are written to /usr/local/var/log/stunnel.log.

Start stunnel:

brew services start stunnel # Different for Linux

Start the webserver:

php -S localhost:8000

Now you can visit https://localhost:443 to visit your webserver: screenshot

There should be a cert error and you'll have to click through a browser warning but that gets you to the point where you can hit your localhost with HTTPS requests, for development.

Max Fang
  • 101
  • 1
  • 3
  • 4
    Lifesaver of an answer, thank you. Small addition: For m1 / Apple Silicon Macs the stunnel config file seems to be located under `/opt/homebrew/etc/stunnel`. – timotgl Jun 14 '22 at 12:02
2

I've been learning nginx and Laravel recently, and this error has came up many times. It's hard to diagnose because you need to align nginx with Laravel and also the SSL settings in your operating system at the same time (assuming you are making a self-signed cert).

If you are on Windows, it is even more difficult because you have to fight unix carriage returns when dealing with SSL certs. Sometimes you can go through the steps correctly, but you get ruined by cert validation issues. I find the trick is to make the certs in Ubuntu or Mac and email them to yourself, or use the linux subsystem.

In my case, I kept running into an issue where I declare HTTPS somewhere but php artisan serve only works on HTTP.

I just caused this Invalid request (Unsupported SSL request) error again after SSL was hooked up fine. It turned out to be that I was using Axios to make a POST request to https://. Changing it to POST http:// fixed it.

My recommendation to anyone would be to take a look at where and how HTTP/HTTPS is being used.

The textbook definition is probably something like php artisan serve only works over HTTP but requires underlying SSL layer.

agm1984
  • 15,500
  • 6
  • 89
  • 113
1

Use Ngrok

  1. Expose your server's port like so: ngrok http <server port>

  2. Browse with the ngrok's secure public address (the one with https).

Note: Though it works like a charm, it seems an overkill since it requires internet and would appreciate better recommendations.

Drk
  • 425
  • 2
  • 12