0

Anytime I try to add a redirect in an NGINX config file I get this error so I basically avoid it, this is not really the way to proceed so I need to figure out why the heck I cant add redirects... It is mostly an issue when I need to redirect a site to use only HTTPS.

My current infrastructure consists of Nginx (8080) with Varnish(80), the server is hosting multiple other websites as virtualhosts and my configs are pretty much all the same. Please for the love of god someone educate me as to how I track this issue down, I understand servers but this is a real unicorn problem that keeps cropping up and Id like to use NGINX as my main webserver but this is really putting a spanner in the works. I I have set my Wordpress WP config to contain the proto header is sent by varnish. I have also set the site name to the https version within wordpress as well as changed every items url in the database to https so in theory everything should be https by default

if (isset($_SERVER["HTTP_X_FORWARDED_PROTO"] ) && "https" == $_SERVER["HTTP_X_FORWARDED_PROTO"] ) {
 $_SERVER["HTTPS"] = "on";
}

My HTTP 8080 :

server {
    listen 8080;
    server_name example.com www.example.com;
    index               index.html index.php;
    root                /var/www/example.com;
    port_in_redirect off;
    gzip                on;
    gzip_disable        "msie6";
    gzip_vary           on;
    gzip_proxied        any;
    gzip_comp_level     5;
    gzip_buffers        16 8k;
    gzip_http_version   1.0;
    gzip_types          text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript image/png image/gif image/jpeg application/javascript image/svg+xml;

    location = / {
        alias /var/www/example.com/;
        fastcgi_param  HTTPS on;
        try_files $uri $uri/ /index.php?$query_string;
    }

location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
    return 404;
    }
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass backend;
}


location ~ /\.ht {
    deny all;
}

return 301 https://www.example.com$request_uri;


}

My HTTPS Config:

server {

    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED';

    ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

}
2
  • Is varnish accepting HTTPS connections and forwarding them to 8080? Because your naked return statement will not work in that case. Your HTTPS config is empty (apart from ssl_* statements) which implies it isn't used. May 26, 2017 at 13:42
  • AFAIK Varnish doesn't support HTTPS at all.
    – AlexD
    May 26, 2017 at 17:19

1 Answer 1

2

You need to configure your SSL terminator as reverse proxy:

in your nginx ssl configuration, add this:

location / {
  proxy_pass  http://VARNISH-IP-ADDR-OR-HOSTNAME;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $remote_addr;
  proxy_set_header X-Forwarded-Proto https;
  proxy_set_header X-Nginx on;
  proxy_redirect     off;
}

Then, in your varnish vcl file

if ( req.http.X-Nginx != "on") {
      return (synth(750, ""));
}
...
sub vcl_synth {
  if (resp.status == 750) {
    set resp.status = 301;
    set resp.http.Location = "https://YOUR-SSL-FQDN" + req.url;
    return(deliver);
  }
}

Last: for wordpress, in wp-config.php add these lines:

define('FORCE_SSL_ADMIN', true);
$_SERVER['HTTPS']='on';

NOTE: I'm assuming your other varnish configuration is good and your nginx "8080" configuration is good for your php application.

1
  • 1
    For me it was sufficient to set $_SERVER['HTTPS']='on'; in wp-config.php. I'm using AWS ELB which terminates SSL on the ELB. Therefore nginx accepts the request on Port 80 (8080 after varnish) and it seems like wordpress was not able to deal with it until you explicitly tell PHP that the site already uses https...
    – Tim
    Jan 5, 2018 at 16:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .