1

I have the following stack:

(redirect http to https =>) https nginx -> varnish -> nginx http -> php5-fpm

When I open my.url.com I get instantly redirected to https://127.0.0.1

Without varnish, nginx,ssl,php5-fpm (php 5.5) works just fine...

I think it is related to my varnish configuration because almost the same stack is running with a different CMS (TYPO3 Neos) and a different varnish config just fine... (settings for nginx are almost the same, just some slight adaptions like static rewrites)

I'm grateful for your ideas and feedback on this!

my nginx config:

# redirect non-www - http  and other domains to www - https
server {
        listen  80; ## listen for ipv4; this line is default and implied
        server_name domain.com some.other.tld;
        return 301 https://www.domain.com$request_uri;
}

# redirect non-www to www - https
server {
        listen 443 ssl; ## listen for ipv4; this line is default and implied
        server_name domain.com;

        # Add default ssl config
        include /etc/nginx/server-config/nginx-ssl.conf;

        # Define the certificates for this vhost
        ssl_certificate /etc/ssl/private/my-webserver.cert;
        ssl_certificate_key /etc/ssl/private/my-webserver.key;
        ssl_trusted_certificate /etc/ssl/private/ocsp-trusted-certificate.pem;

    return 301 https://www.domain.com$request_uri;
}

#
# HTTPS server - live - proxy for varnish
#
server {
        listen 443 ssl spdy;
        server_name www.domain.com;

        access_log /var/log/nginx/www.access;
        error_log /var/log/nginx/www.error error;

        keepalive_timeout 70;

        client_max_body_size 2G;

        # Add default ssl config        
        include /etc/nginx/server-config/nginx-ssl.conf;

        # Define the certificates for this vhost
        ssl_certificate /etc/ssl/private/my-webserver.cert;
        ssl_certificate_key /etc/ssl/private/my-webserver.key;
        ssl_trusted_certificate /etc/ssl/private/ocsp-trusted-certificate.pem;

        # Proxy Pass to Varnish
        # Add headers to recognize SSL
        location / {
            proxy_pass  http://127.0.0.1:6081;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-Port 443;
            proxy_set_header X-Secure on;
        }
}


#
# HTTP server - live for varnish
#
server {
        listen 8000;
        server_name www.domain.com;

        access_log /var/log/nginx/www.access;
        error_log /var/log/nginx/www.error error;

        root /var/www/production/current/src;
        index index.html index.php;

        client_max_body_size 2G;

        set_real_ip_from   127.0.0.1;
        real_ip_header     X-Forwarded-For;
        real_ip_recursive on;

        # Add trailing slash to */wp-admin requests.
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;

        include /etc/nginx/server-config/nginx-static-resources.conf;

        include /etc/nginx/server-config/nginx-global-restriction-additional.conf;

        try_files $uri $uri/ /index.php?$args;

        location ~ \.php$ {
           fastcgi_split_path_info ^(.+?\.php)(/.*)$;
            if (!-f $document_root$fastcgi_script_name) {
                return 404;
            }
            # This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)

            include fastcgi_params;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;

            # Neccessary only with defined error page
            #fastcgi_intercept_errors on;

            fastcgi_read_timeout 600s;

            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
        }
}

And my varnish config:

vcl 4.0;
backend default {
        .host = "localhost";
        .port = "8000";
        .connect_timeout = 600s;
        .first_byte_timeout = 600s;
        .between_bytes_timeout = 600s;
        .max_connections = 800;
}

# Only allow purging from specific IPs
acl purge {
    "localhost";
    "127.0.0.1";    
}

# This function is used when a request is send by a HTTP client (Browser) 
sub vcl_recv {
    # Allow purging from ACL
    if (req.method == "PURGE") {
        # If not allowed then a error 405 is returned
        if (!client.ip ~ purge) {
            return(synth(405, "This IP is not allowed to send PURGE requests."));
        }   
        # If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()
        return (purge);
    }

    # Post requests will not be cached
    if (req.http.Authorization || req.method == "POST") {
        return (pass);
    }

    # --- Wordpress specific configuration

    # Did not cache the RSS feed
    if (req.url ~ "/feed") {
        return (pass);
    }

    # Blitz hack
        if (req.url ~ "/mu-.*") {
                return (pass);
        }


    # Did not cache the admin and login pages
    if (req.url ~ "/wp-(login|admin)") {
        return (pass);
    }

    # Remove the "has_js" cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");

    # Remove any Google Analytics based cookies
    set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");

    # Remove the Quant Capital cookies (added by some plugin, all __qca)
    set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");

    # Remove the wp-settings-1 cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

    # Remove the wp-settings-time-1 cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");

    # Remove the wp test cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

    # Are there cookies left with only spaces or that are empty?
    if (req.http.cookie ~ "^ *$") {
            unset req.http.cookie;
    }

    # Cache the following files extensions 
    if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {
        unset req.http.cookie;
    }

    # Normalize Accept-Encoding header and compression
    # https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
    if (req.http.Accept-Encoding) {
        # Do no compress compressed files...
        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
                unset req.http.Accept-Encoding;
        } elsif (req.http.Accept-Encoding ~ "gzip") {
                set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
                set req.http.Accept-Encoding = "deflate";
        } else {
            unset req.http.Accept-Encoding;
        }
    }

    # Check the cookies for wordpress-specific items
    if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
        return (pass);
    }
    if (!req.http.cookie) {
        unset req.http.cookie;
    }

    # --- End of Wordpress specific configuration

    # Did not cache HTTP authentication and HTTP Cookie
    if (req.http.Authorization || req.http.Cookie) {
        # Not cacheable by default
        return (pass);
    }

    # Cache all others requests
    return (hash);
}

sub vcl_pipe {
    return (pipe);
}

sub vcl_pass {
    return (fetch);
}

# The data on which the hashing will take place
sub vcl_hash {

    hash_data(req.url);

    if (req.http.host) {
            hash_data(req.http.host);
    } else {
            hash_data(server.ip);
    }

    # If the client supports compression, keep that in a different cache
        if (req.http.Accept-Encoding) {
            hash_data(req.http.Accept-Encoding);
    }

    return (lookup);
}

# This function is used when a request is sent by our backend (Nginx server)
sub vcl_backend_response {
    # Remove some headers we never want to see
#   unset beresp.http.Server;
#   unset beresp.http.X-Powered-By;

    # ignore max-age=0
    if (beresp.ttl < 120s) {
            set beresp.ttl = 120s;
            unset beresp.http.Cache-Control;
    }


    # For static content strip all backend cookies
    if (bereq.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico") {
        unset beresp.http.cookie;
    }

    # Only allow cookies to be set if we're in admin area
    if (beresp.http.Set-Cookie && bereq.url !~ "^/wp-(login|admin)") {
            unset beresp.http.Set-Cookie;
        }

    # don't cache response to posted requests or those with basic auth
    if ( bereq.method == "POST" || bereq.http.Authorization ) {
            set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
        }

        # don't cache search results
    if ( bereq.url ~ "\?s=" ){
        set beresp.uncacheable = true;
                set beresp.ttl = 120s;
                return (deliver);
    }

    # only cache status ok
    if ( beresp.status != 200 ) {
        set beresp.uncacheable = true;
                set beresp.ttl = 120s;
                return (deliver);
    }

    # A TTL of 24h
    set beresp.ttl = 24h;

    # Define the default grace period to serve cached content
    set beresp.grace = 60s;

    return (deliver);
}

# The routine when we deliver the HTTP request to the user
# Last chance to modify headers that are sent to the client
sub vcl_deliver {
    if (obj.hits > 0) { 
        set resp.http.X-Cache = "cached";
    } else {
        set resp.http.x-Cache = "uncached";
    }

    # Remove some headers: PHP version
    #unset resp.http.X-Powered-By;

    # Remove some headers: Apache version & OS
    #unset resp.http.Server;

    # Remove some heanders: Varnish
    #unset resp.http.Via;
    #unset resp.http.X-Varnish;

    return (deliver);
}

sub vcl_init {
    return (ok);
}

sub vcl_fini {
    return (ok);
}

(I wanted to see the headers for testing purpose)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.