You are here

Part III: Nginx (SSL end-point)

I use Nginx as a proxy to handle SSL/HTTPS request and change them into HTTP to run sites in HTTPS only but stile utilize varnish etc. First you have to setup Nginx and modify your Drupal installation, so it knows that it should generate links as HTTPS even though the request to it was HTTP.

Nginx

server {
  listen 443 ssl;

  server_name example.com;

  ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
  ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

  add_header Strict-Transport-Security max-age=15768000;

  location / {
    # Pass the request on to Varnish.
    proxy_pass http://example.localhost:6081;

    client_max_body_size 20M;

    # Pass a bunch of headers to the downstream server, so they'll know what's going on.
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Most web apps can be configured to read this header and understand that the current session is actually HTTPS.
    proxy_set_header X-Forwarded-Proto https;

    # We expect the downsteam servers to redirect to the right hostname, so don't do any rewrites here.
    proxy_redirect off;

    # We get a lot of traffic, so we'll need a lot buffers.
    proxy_buffers 256 4k;
  }
}

# Redirect all standard site URLs to the secure version.
server {
  listen 80;
  server_name example.com;
  return 301 https://example.com$request_uri;
}

Varnish

As you turn secure communication into in-secure on the server (or your local network) you should update varnish to only trust defined proxies. This is done by adding an acl with the upstream proxies in your VCL.

# List of upstream proxies we trust to set X-Forwarded-For correctly.
acl upstream_proxy {
  "127.0.0.1";
  "172.21.0.0"/24;
}

You should update the VCL to include the ACL first in the vcl_recv function.

# Make sure that the client ip is forward to the client.
  if (req.restarts == 0) {
    if (client.ip ~ upstream_proxy && req.http.x-forwarded-for) {
      set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
    }
    else {
      set req.http.X-Forwarded-For = client.ip;
    }
  }

Apache

Apache should not have the SSL module enabled, so it will not set the "X-Forwarded-Proto" header from the SSL proxy and Drupal will not be able to detect that it's behind a SSL Proxy. So you have to set the HTTPS flag in your vhost configuration file as shown below.

 SetEnvIf X-Forwarded-Proto https HTTPS=on

Drupal

In Drupal you should download and enable the sslproxy module and configure it, as show below in setttings.php (or "admin/config/sslproxy").

$conf['sslproxy_var'] = 'X-FORWARDED-PROTO';
$conf['sslproxy_var_value'] = 'https';

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.