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.


server {
  listen 443 ssl;


  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;
  return 301$request_uri;


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 {

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


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