Hello,
I'm really hoping someone can help me figure this out. Been trying to get this right for about a month now. Here is my setup:
Internet --HTTPS--> ReverseProxy (Nginx) --HTTP--> Nginx
I have read through: https://www.drupal.org/node/313145 and have done my best to understand. Here are the key configurations in each stage:
ReverseProxy (Nginx) SSL Termination:
# -*- mode: nginx; mode: flyspell-prog; ispell-current-dictionary: american -*-
### Configuration for example.com.
## Return (no rewrite) server block.
## http://staging.example.com --> https://www.staging.example.com
server {
listen 80; # IPv4
server_name staging.example.com;
return 301 https://www.staging.example.com$request_uri;
} # server domain return.
## Return (no rewrite) server block.
## http://www.staging.example.com --> https://www.staging.example.com
server {
listen 80; # IPv4
server_name www.staging.example.com;
return 301 https://www.staging.example.com$request_uri;
} # server domain return.
## Return (no rewrite) server block.
## https://staging.example.com --> https://www.staging.example.com
server {
listen 443; # IPv4
server_name staging.example.com;
ssl_certificate /etc/nginx/ssl/certs/examplessl.crt;
ssl_certificate_key /etc/nginx/ssl/private/example.key;
## Access and error logs.
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
return 301 https://www.staging.example.com$request_uri;
} # server domain return.
## Return (no rewrite) server block.
## https://www.staging.example.com
server {
listen 443 ssl;
server_name www.staging.example.com;
#limit_conn arbeit 32;
ssl_certificate /etc/nginx/ssl/certs/examplessl.crt;
ssl_certificate_key /etc/nginx/ssl/private/example.key;
## Access and error logs.
access_log /var/log/nginx/examplessl.com_access.log;
error_log /var/log/nginx/examplessl.com_error.log;
## Keep alive timeout set to a greater value for SSL/TLS.
keepalive_timeout 75 75;
## Strict Transport Security header for enhanced security. See
## http://www.chromium.org/sts. I've set it to 2 hours; set it to
## whichever age you want.
add_header Strict-Transport-Security "max-age=7200";
## Uncomment if you're proxying to Apache for handling PHP.
#proxy_http_version 1.0; # keep alive to the Apache upstream
## See the blacklist.conf file at the parent dir: /etc/nginx.
## Deny access based on the User-Agent header.
#if ($bad_bot) {
#return 444;
#}
## Deny access based on the Referer header.
#if ($bad_referer) {
#return 444;
#}
## Protection against illegal HTTP methods. Out of the box only HEAD,
## GET and POST are allowed.
#if ($not_allowed_method) {
#return 405;
#}
# Helpful maybe?
# http://serverfault.com/questions/413230/login-to-drupal-fails-with-nginx-and-proxy-pass-but-works-when-accessing-drupal
#
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
#proxy_set_header Host $http_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;
#proxy_set_header HTTP_USING_HTTPS 1;
#proxy_set_header X_FORWARDED_HOST staging.example.com;
}
}
then, in settings.php:
$conf['reverse_proxy'] = TRUE;
/**
* Specify every reverse proxy IP address in your environment.
* This setting is required if $conf['reverse_proxy'] is TRUE.
*/
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
/**
* Set this value if your proxy server sends the client IP in a header
* other than X-Forwarded-For.
*/
#$conf['reverse_proxy_header'] = 'HTTP_X_CLUSTER_CLIENT_IP';
/**
* From http://drupal.stackexchange.com/questions/102091/drupal-behind-a-ssl-offloading-reverse-proxy-is-this-config-correct
*
*/
// 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;
}
Finally, in my Nginx configuration (I use perusio's config):
## HTTP server.
server {
listen 8080; # IPv4
## Replace the IPv6 address by your own address. The address below
## was stolen from the wikipedia page on IPv6.
#listen [fe80::202:b3ff:fe1e:8330]:80 ipv6only=on;
server_name www.staging.example.com;
limit_conn arbeit 32;
## Access and error logs.
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
## See the blacklist.conf file at the parent dir: /etc/nginx.
## Deny access based on the User-Agent header.
if ($bad_bot) {
return 444;
}
## Deny access based on the Referer header.
if ($bad_referer) {
return 444;
}
## Protection against illegal HTTP methods. Out of the box only HEAD,
## GET and POST are allowed.
if ($not_allowed_method) {
return 405;
}
## Filesystem root of the site and index.
root /var/www/html/examplestaging;
index index.php;
## If you're using a Nginx version greater or equal to 1.1.4 then
## you can use keep alive connections to the upstream be it
## FastCGI or Apache. If that's not the case comment out the line below.
fastcgi_keep_conn on; # keep alive to the FCGI upstream
## Uncomment if you're proxying to Apache for handling PHP.
#proxy_http_version 1.1; # keep alive to the Apache upstream
################################################################
### Generic configuration: for most Drupal 7 sites.
################################################################
include apps/drupal/drupal.conf;
################################################################
### Configuration for Drupal 7 sites to serve URIs that need
### to be **escaped**
################################################################
#include apps/drupal/drupal_escaped.conf;
#################################################################
### Configuration for Drupal 7 sites that use boost.
#################################################################
#include apps/drupal/drupal_boost.conf;
#################################################################
### Configuration for Drupal 7 sites that use boost if having
### to serve URIs that need to be **escaped**
#################################################################
#include apps/drupal/drupal_boost_escaped.conf;
#################################################################
### Configuration for updating the site via update.php and running
### cron externally. If you don't use drush for running cron use
### the configuration below.
#################################################################
#include apps/drupal/drupal_cron_update.conf;
################################################################
### Installation handling. This should be commented out after
### installation if on an already installed site there's no need
### to touch it. If on a yet to be installed site. Uncomment the
### line below and comment out after installation. Note that
### there's a basic auth in front as secondary ligne of defense.
################################################################
#include apps/drupal/drupal_install.conf;
#################################################################
### Support for upload progress bar. Configurations differ for
### Drupal 6 and Drupal 7.
#################################################################
include apps/drupal/drupal_upload_progress.conf;
## Including the php-fpm status and ping pages config.
## Uncomment to enable if you're running php-fpm.
include php_fpm_status_vhost.conf;
## Including the Nginx stub status page for having stats about
## Nginx activity: http://wiki.nginx.org/HttpStubStatusModule.
include nginx_status_vhost.conf;
} # HTTP server
And in my specific drupal.conf nginx configuration (this is the important configuration to support HTTPRL, CDN, and Advanced Aggregation):
###
### HTTPRL standard support.
###
location ^~ /httprl_async_function_callback {
location ~* ^/httprl_async_function_callback {
access_log off;
limit_conn arbeit 96;
add_header X-Header "HTTPRL 2.0";
set $nocache_details "Skip";
try_files $uri @drupal;
}
}
###
### HTTPRL test mode support.
###
location ^~ /admin/httprl-test {
location ~* ^/admin/httprl-test {
access_log off;
limit_conn arbeit 96;
add_header X-Header "HTTPRL 2.1";
set $nocache_details "Skip";
try_files $uri @drupal;
}
}
###
### CDN Far Future expiration support.
###
location ^~ /cdn/farfuture/ {
tcp_nodelay off;
access_log off;
log_not_found off;
etag off;
limit_conn arbeit 96;
gzip_http_version 1.0;
if_modified_since exact;
location ~* ^/cdn/farfuture/.+\.(?:css|js|jpe?g|gif|png|ico|bmp|svg|swf|pdf|docx?|xlsx?|pptx?|tiff?|txt|rtf|class|otf|ttf|woff|eot|less)$ {
expires max;
add_header Access-Control-Allow-Origin *;
add_header X-Header "CDN Far Future Generator 1.0";
add_header Cache-Control "no-transform, public";
add_header Last-Modified "Wed, 20 Jan 1988 04:20:42 GMT";
rewrite ^/cdn/farfuture/[^/]+/[^/]+/(.+)$ /$1 break;
try_files $uri @drupal;
}
location ~* ^/cdn/farfuture/ {
expires epoch;
add_header Access-Control-Allow-Origin *;
add_header X-Header "CDN Far Future Generator 1.1";
add_header Cache-Control "private, must-revalidate, proxy-revalidate";
rewrite ^/cdn/farfuture/[^/]+/[^/]+/(.+)$ /$1 break;
try_files $uri @drupal;
}
try_files $uri @drupal;
}
##
## Advanced Aggregation module CSS
##
## http://drupal.org/project/advagg.
##
location ^~ /sites/default/files/advagg_css/ {
expires max;
add_header ETag '';
add_header Last-Modified 'Wed, 20 Jan 1988 04:20:42 GMT';
add_header Accept-Ranges '';
add_header Access-Control-Allow-Origin *;
#location ~* /sites/default/files/advagg_css/css__[[:alnum:]]+\.css$ {
location ~* /sites/default/files/advagg_css/css__[[:alnum:]-_]+\.css$ {
#location ~* /sites/default/files/advagg_css/css[_]*[[:alnum:]]+.css$ {
access_log off;
try_files $uri @drupal;
}
}
##
## Advanced Aggregation module JS
##
## http://drupal.org/project/advagg.
##
location ^~ /sites/default/files/advagg_js/ {
expires max;
add_header ETag '';
add_header Last-Modified 'Wed, 20 Jan 1988 04:20:42 GMT';
add_header Accept-Ranges '';
add_header Access-Control-Allow-Origin *;
#location ~* /sites/default/files/advagg_js/js__[[:alnum:]]+\.js$ {
location ~* /sites/default/files/advagg_js/js__[[:alnum:]-_]+\.js$ {
#location ~* /sites/default/files/advagg_js/js[_]*[[:alnum:]]+.js$ {
access_log off;
try_files $uri @drupal;
}
}
You may notice there are a variety of commented out lines, due to the variety of issue queues I have read through and attempted to get this working correctly. I have read and reread these a dozen times:
https://www.drupal.org/node/2062547 (i did remove try_files $uri @drupal;, but this made things return 404 completely and broke everything)
https://www.drupal.org/node/1431668 (ensured I am running latest dev branch to fix this)
Ultimately, with this exact configuration, I always receive a code 200; screenshots attached of the warning.
If anyone has any pointers or suggestions, I am all ears because I just can't seem to get this right.
| Comment | File | Size | Author |
|---|---|---|---|
| #1 | Screen Shot 2014-11-22 at 1.55.10 PM.png | 309.02 KB | cthshabel |
| #1 | Screen Shot 2014-11-22 at 1.54.57 PM.png | 312.93 KB | cthshabel |
Comments
Comment #1
cthshabel commentedComment #2
mikeytown2 commentedAny luck on this?
Everything seems to be working except that nginx is returning a 200. This can be an issue (not forwarding the status code from PHP) since you can have multiple requests coming in for the same file and advagg sends out a 307 redirect to try again if that request was not the first one.
Comment #3
mikeytown2 commentedClosing this issue due to lack of feedback.
Comment #4
cthshabel commentedJust adding a note for anyone, the errors went away when upgrading to PHP 5.6 on the Ubuntu server I was using. Verified Advanced Aggregation is working; however, the status report still shows gzip errors due to the proxy configuration and AdvAgg not seeing the gzip files are being created in the default/files directory. New issue is posted here.