NGINX configuration with SSL and redirect to non-www
Surprisingly this hasn’t been covered more thoroughly considering how many people are running NGINX as a reverse proxy for their back end CMS such as WordPress. This article will show you how to configure NGINX with SSL and redirect to non-www. If your WordPress installation is sitting behind a reverse proxy like NGINX, WordPress won’t be able to see the proper IP address of the client computer for your accurate statistics and reporting. Instead WordPress will show your reverse proxy instead of the correct client IP addresses. If you’re using Cloudflare then there are various plugins to fix that, for NGINX there is not. To show the correct client IP address in your backend logs, you’ll need to add the following at the top of wp-config.php:
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $xffaddrs = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']); $_SERVER['REMOTE_ADDR'] = $xffaddrs[0];
Here is what the top of your wp-config.php should look like after adding the headers:
<?php if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $xffaddrs = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']); $_SERVER['REMOTE_ADDR'] = $xffaddrs[0]; } /** * The base configurations of the WordPress. * * This file has the following configurations: MySQL settings, Table Prefix, * Secret Keys, WordPress Language, and ABSPATH. You can find more information * by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing * wp-config.php} Codex page. You can get the MySQL settings from your web host. * * This file is used by the wp-config.php creation script during the * installation. You don't have to use the web site, you can just copy this file * to "wp-config.php" and fill in the values. * * @package WordPress */ // ** MySQL settings - You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'yourusername'); /** MySQL database password */ define('DB_PASSWORD', 'yourpassword'); /** MySQL hostname */ define('DB_HOST', 'yourDBhost'); /** Database Charset to use in creating database tables. */ define('DB_CHARSET', 'utf8'); /** The Database Collate type. Don't change this if in doubt. */ define('DB_COLLATE', '');
My setup:
Nginx boilerplate
Just to mention that this configuration was built on top of h5bp’s Nginx HTTP server boilerplate configs. Very useful Nginx configuration template built with best practices in mind. So you will see file inclusion in main server block which only contains default Nginx settings, so don’t get confused. Anyway i recommend using this boilerplate for server configuration instead of writting your own.
SPDY networking protocol
Since you have SSL certificate i don’t see reason not to include SPDY protocol. It’s implementation exist in almost all browsers (Check out Caniuse), and hopefully it should get its implementation soon also on IE and Opera Mini. If you are feeling it is not yet the right time for SPDY, just remove spdy from configuration file.
Redirect all www connections to non-www
server { # Server host server_name www.domain.com; # Server ports listen 80; listen 443 ssl spdy; listen [::]:80; listen [::]:443 ssl spdy; # SSL Certificate ssl_certificate /path/to/certs/domain.com.crt; ssl_certificate_key /path/to/certs/domain.com.key.nopass; # Non-www redirect return 301 https://domain.com$request_uri; }
Redirect all HTTP to HTTPS
server { # Server host server_name domain.com; # Server port listen 80; listen [::]:80; return 301 https://domain.com$request_uri; }
Redirect subdomain to HTTPS
server { # Server host server_name sub.domain.com; # Server port listen 80; listen [::]:80; location / { return 301 https://sub.domain.com$request_uri; } # Server root folder root /path/to/your/application; # Custom locations and settings location ~ \.php$ { root /path/to/your/application; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /path/to/your/application$fastcgi_script_name; include fastcgi_params; } }
Main server block configuration
server{ # Server host server_name domain.com; # Server ports listen 443 ssl spdy; listen [::]:443 ssl spdy; # Server root folder root /path/to/your/application; # SSL certificate ssl_certificate /path/to/certs/domain.com.crt; ssl_certificate_key /path/to/certs/domain.com.key.nopass; # You may want to check [Cipher list](https://cipherli.st/) which provide Strong SSL Security for all modern browsers. (Thanks KnowledgePower Marketing) # SSL settings ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_prefer_server_ciphers on; #ssl_stapling on; #resolver 8.8.8.8; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; add_header Strict-Transport-Security 'max-age=604800'; # Include Nginx Boilerplate default settings include nginx-bp/bootstrap/example.conf; # Custom locations and settings location ~ \.php$ { root /path/to/your/application; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /path/to/your/application$fastcgi_script_name; include fastcgi_params; } }
Conclusion
I hope this post was useful for you, if you have some suggestions or corrections write them down in comments.
Source by Bojan