====== http://www.iodigitalsec.com/nginx-ssl-php5-fpm-on-debian-wheezy/|Nginx, SSL and php5-fpm on Debian Wheezy ====== To set up a LEMP server (Linux, Nginx, MySQL, PHP), minus the MySQL as it’s already installed on my VM host server, and plus SSL. Here’s the full setup tutorial on Debian Wheezy: ==== Step #1 – Installing the packages ==== apt-get install nginx-extras mysql-client apt-get install php5-fpm php5-gd php5-mysql php-apc php-pear php5-cli php5-common php5-curl php5-mcrypt php5-cgi php5-memcached MySQL can be installed into the mix with a simple: apt-get install mysql-server ==== Step #2 – Configure php5-fpm ==== Open ///etc/php5/fpm/php.ini// and set: cgi.fix_pathinfo=0 Now edit ///etc/php5/fpm/pool.d/www.conf// and ensure that the listen directive is set as follows: listen = /var/run/php5-fpm.sock This is already the case on Debian Wheezy, however may be set to 127.0.0.1 or other values on other versions. Lastly, restart php5-fpm with: /etc/init.d/php5-fpm restart ==== Step #3 – Configure Nginx and SSL ==== First, create a web content directory: mkdir /var/www Next, edit ///etc/nginx/sites-available/default// to set the first site’s configuration. The directives are reasonably self explanatory: server { listen 80; root /var/www; index index.php index.html index.htm; server_name my.test.server.com; location / { try_files $uri $uri/ /index.html; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www; } # pass the PHP scripts to FastCGI server listening on the php-fpm socket location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } I’ve extended this configuration to meet my requirements. My configuration is intended to: * Redirect all port HTTP requests to HTTPS * Serve HTTPS with a reasonable secure configuration and cipher suite * Enable the .php file extension, and pass PHP scripts to php5-fpm server { listen 80; server_name my.test.server.com; return 301 https://$server_name$request_uri; } # HTTPS server server { listen 443; root /var/www; index index.php index.html index.htm; server_name my.test.server.com; location / { try_files $uri $uri/ /index.html; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www; } # pass PHP to php5-fpm location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } ssl on; ssl_certificate /etc/ssl/test.chain.crt; ssl_certificate_key /etc/ssl/test.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK'; ssl_prefer_server_ciphers on; } Now whereas Apache2 has a SSLCertificateChainFile directive for specifying a certificate chain, Nginx does not. In this case, the server certificate and any chained certificates are all placed into a single file, starting with my server certificate, and followed by two certificates in the chain: -----BEGIN CERTIFICATE----- MIIFejCCBGKgAwIBAgIQTHWks9xOahzb+5+AyIO3jjANBgkqhkiG9w0BAQsFADCB (...) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv (...) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB (...) -----END CERTIFICATE----- An in depth SSL tester is provided by Qualys here: https://www.ssllabs.com/ssltest/ Now test the configuration and assuming no errors, restart Nginx: /etc/init.d/nginx configtest /etc/init.d/nginx restart Lastly, test that PHP is functioning as expected by editing ///var/www/index.php//: <?php$a = 5; $b = 10; echo "$a + $b = " . ($a+$b) . "<br />\n"; ?> Then access index.php. In my case, I’ve used curl to verify. If the code is interpreted and evaluated successfully, the output will show: {{http://www.iodigitalsec.com/wp-content/uploads/nginx-php-success-300x33.png?300x33|nginx-php-success}} If PHP has not been installed correctly, the script may be delivered as-is: {{http://www.iodigitalsec.com/wp-content/uploads/nginx-php-fail-300x64.png?300x64|nginx-php-fail}} In this case, go back and verify the installation and configuration as above, ensuring that Nginx and php5-fpm were both restarted after configuration changes were made.