php-fpm, nginx, https 502 error/white pages

I am having trouble with getting nginx and https to work.

I am running an up to date Arch Linux distro.

Here are my versions for nginx, php and mysql.

nginx 1.0.6-2

php-fpm 5.3.8-2

mysql 5.5.15-1

This is an excerpt from my log when an error message is generated, most of the time its a blank page.

2011/08/31 21:59:44 [error] 20483#0: *1 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 1.1.1.1, server: website, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm/php-fpm.sock:", host: "website"

This is my nginx.conf

This is my php-fpm.conf

This is my php.ini

This is my fastcgi.conf

I would really appreciate any help as I am unable to get https working.

One thing I did notice, if I remove:

fastcgi_param HTTPS on;

from the nginx.conf the page loads without any problems, but the websites are not properly being sent as https. So that is not a solution.

4 Replies

You have the following line in the "http" section.

include fastcgi.conf;

Copy and paste it just above the "HTTPS on" line. In fact, you'd better remove it from the "http" section and include it every time you define a PHP handler ("location ~ .php$"). You're supposed to do it that way. The DRY principle doesn't apply here.

According to the official wiki for the FastCGI module, "Directives set in current level clear any previously defined directives for the current level." It's OK to include common FastCGI parameters only once in the top section if you have no fastcgiparam line in any of the individual PHP handlers. But as soon as you add a custom fastcgiparam line, e.g. "HTTPS on", everything that was set in the top section gets ignored. Without those parameters, PHP-FPM can't even figure out which page it is supposed to serve.

By the way, your app is crappy if it can't detect SSL without "HTTPS on" which is a non-standard Apache-only feature. If you have any control over the code, make it fall back to $SERVER['SERVERPORT'] == 443 if it doesn't find an "HTTPS on" parameter, or even better, add an option to force SSL so that it can be used behind a reverse proxy.

Edit:

That worked perfectly :)

It was phpmyadmin that was giving me issues with the HTTPS detection.

It seems odd, but the pages seem to be loading very slowly when served over https.

Here is the config as it looks right now for each https.

    server {
        listen 1.1.1.1:443 ssl;
        server_name website www.website;
        access_log logs/website.access.log main;
        error_log logs/website.error.log error;
        keepalive_timeout 70;

        root /srv/http/website/public_html;
        index index.php index.html index.htm;

        location /gallery/ {
            auth_basic "Restricted";
            auth_basic_user_file /srv/http/website/htpasswd;
        }

        ssl_certificate /etc/ssl/private/website.pem;
        ssl_certificate_key /etc/ssl/private/website.key;
        ssl_session_timeout 5m;
        ssl_protocols SSLv2 SSLv3 TLSv1;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
            access_log off;
            expires max;
        }

        location ~ \.php$ {
            include fastcgi.conf;
            fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
            fastcgi_index index.php; 
            fastcgi_param HTTPS on;
        }
    }

I moved the keepalive so its set in each:

server {

}

Since https usually requires a higher keepalive than http.

Any thoughts why that might be ?

HTTPS is quite slow when you're connecting for the first time, but it should be nearly as fast as plain HTTP on subsequent requests. Especially if you're the only person who is using HTTPS on that server.

Your keepalive probably isn't helping because browsers tend to open several simultaneous connections to the same server, one for the page itself and a few more for various CSS, JS, and image files. In the absence of a session cache (see below), each of these connections would need to be renegotiated with a brand new SSL handshake. Several SSL handshakes per page = slow page load.

Here's my typical SSL configuration:

ssl_certificate /path/to/domain_name.crt;
ssl_certificate_key /path/to/domain_name.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!ADH:!MD5:!aNULL:!eNULL:!MEDIUM:!LOW:!EXP:!kEDH;
ssl_protocols SSLv3 TLSv1;
ssl_prefer_server_ciphers on;

This enables the session cache, so that you can use a previously negotiated key to speed up subsequent connections. (Session timeouts are more or less useless without a working session cache.) Note that "1m" here means 1MB of RAM, not 1 minute. There's no need to increase this value unless you're expecting hundreds of simultaneous visitors. The "5m" in the session timeout, on the other hand, means 5 minutes. You can increase this if you don't want to renegotiate keys every 5 minutes, but it probably won't have a huge impact on page load times.

My example also disables the insecure SSLv2 protocol, as well as a few weak ciphers. It also disables the extremely slow kEDH cipher, because that's probably overkill for accessing phpmyadmin on your tiny Linode.

If this doesn't help, use Chrome Developer Tools (built into Chrome) or Firebug (a Firefox extension) to see a graph of your page load timeline. This will tell you which elements are loading slowly.

That fixed it again :D

Awesome.

Really appreciate the help and I hope someone else finds this information useful as I don't think the information you gave is very easy to find :)

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct