6

We are transitioning an existing drupal installation to run as a SSL-only site behind a SSL offloading proxy. Drupal itself has no SSL and is running on port 80 on apache.

We've got what we think is a pretty successful configuration:

On the nginx end of the world it looks like:

server {
    listen              80;
    server_name         staging.example.com;
    return              301 https://staging.example.com$request_uri;
}

server {
    listen                  443 ssl;
    server_name             staging.example.com;
    ssl_certificate         $chained_cert_path
    ssl_certificate_key     $private_key_path;

    location / {
        proxy_pass          http://$backend_ip;
        proxy_set_header    Host $host;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_set_header    X-Forwarded-By $server_addr:$server_port;
        proxy_set_header    X-Real-IP $remote_addr;
        proxy_redirect      http:// https://;
    }
}

And in the drupal site's config we are running:

// reverse proxy settings and such
$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array($proxy_ip);
$base_url = 'https://staging.example.com';

As I said this seems to be passing all tests, but my spidey sense is saying this was too easy and there is a fugly problem waiting somewhere in some part of drupal we don't understand well enough -- manually paving $base_url just isn't sitting right with me. Are there landmines here?

1 Answer 1

5

You don't have to indicate $base_url = 'https://staging.example.com'; , you can have something like this:

server {
    listen              80;
    server_name         staging.example.com;
    return              301 https://$host$request_uri;
}

server {
    listen                  443 ssl;
    server_name             staging.example.com;
    ssl_certificate         $chained_cert_path
    ssl_certificate_key     $private_key_path;

    location / {
        proxy_pass          http://$backend_ip;
        proxy_set_header    Host $host;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_set_header    X-Real-IP $remote_addr;
    }
}

and in your Drupal settings:

$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array($proxy_ip);

// from http://devblog.more-onion.com/using-drupal-behind-reverse-proxy
if (
  isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
  $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' &&
  !empty($conf['reverse_proxy']) &&
  in_array($_SERVER['REMOTE_ADDR'], $conf['reverse_proxy_addresses'])
) {
  $_SERVER['HTTPS'] = 'on';
  // This is hardcoded because there is no header specifying the original port.
  $_SERVER['SERVER_PORT'] = 443;
}
2
  • This does not work for me, Drupal still delivers http:// URLs for CSS and JS. I'm using Drupal 8. Jan 16, 2016 at 17:32
  • 1
    Just realized that in my settings.php I have to use $settings instead of $conf. Now it works! Jan 16, 2016 at 18:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.