使用Varnish和nginx时redirect非httpsstream量

我正在使用Stunnel,Varnish和nginx与nodejs应用程序,并且在将非https页面( http://manager.domain.com )redirect到它们各自的https页面( https://manager.domain。 com )。 我只是卡在一个redirect循环,因为所有的stream量首先通过清漆。 这个设置的主要原因是使用ssl的套接字。

Stunnel侦听端口443.它终止SSL连接,并将stream量传递给端口80上的Varnish。Varnish侦听端口80,并根据需要拆分81上的Nginx和3000上的Node.js之间的其他stream量.Nginx侦听端口81.它服务静态文件和其他非Node.js页面。

这里是nginx conf文件

upstream nodejs { server 127.0.0.1:3000; server 127.0.0.1:3000; } server { listen 81; server_name www.domain.net; rewrite ^(.*) http://domain.com$1 permanent; } server { listen 81; server_name manager.domain.com; rewrite ^(.*) https://manager.domain.com$1 permanent; } server { listen 81; server_name domain.com manager.domain.com help.domain.com; access_log /srv/www/domain.com/logs/access.log timed; error_log /srv/www/domain.com/logs/error.log info; root /srv/www/domain.com/public; #everything else location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://nodejs/; proxy_redirect off; } gzip on; gzip_comp_level 6; gzip_proxied any; gzip_min_length 1000; gzip_disable "MSIE [1-6]\." gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; } 

这里的任何地方是清漆configuration文件

 backend default { .host = "127.0.0.1"; .port = "81"; .connect_timeout = 5s; .first_byte_timeout = 30s; .between_bytes_timeout = 60s; .max_connections = 800; } backend nodejs { .host = "127.0.0.1"; .port = "3000"; .connect_timeout = 1s; .first_byte_timeout = 2s; .between_bytes_timeout = 60s; .max_connections = 800; } sub vcl_recv { set req.backend = default; set req.grace = 120s; #set the correct IP so my backends don't log all requests as coming from Varnish if (req.restarts == 0) { if (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; } } #remove port, so that hostname is normalized set req.http.Host = regsub(req.http.Host, ":[0-9]+", ""); #Removed: code for purging #part of Varnish's default config if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.request != "GET" && req.request != "HEAD") { return (pass); } #pipe websocket connections directly to Node.js if (req.http.Upgrade ~ "(?i)websocket") { set req.backend = nodejs; return (pipe); } #do not cache large static files if (req.url ~ "\.(avi|flv|mp(e?)g|mp4|mp3|gz|tgz|bz2|tbz|ogg)$") { return(pass); } #general URL manipulation and cookie removal #lines 60-109 from https://github.com/mattiasgeniar/varnish-3.0-configuration-templates/blob/d86d6c1d7d3d0ddaf92019dd5ef5ce66c9e53700/default.vcl if(req.http.Host ~"^(www\.)?domain.com"){ #Removed: Redirect for URL normalization using error 701 # Requests made to this path, relate to websockets - pass does not seem to work (even for XHR polling) if (req.url ~ "^/socket.io/") { set req.backend = nodejs; return (pipe); } #My other PHP/MySQL sites get included here, each in its own block } # part of Varnish's default config if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (lookup); } sub vcl_pipe { #we need to copy the upgrade header if (req.http.upgrade) { set bereq.http.upgrade = req.http.upgrade; } #closing the connection is necessary for some applications – I haven't had any issues with websockets keeping the line below uncommented #set bereq.http.Connection = "close"; return (pipe); } sub vcl_pass { return (pass); } sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (hash); } sub vcl_hit { return (deliver); } sub vcl_miss { return (fetch); } sub vcl_fetch { if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") { /* * Mark as "Hit-For-Pass" for the next 2 minutes */ set beresp.ttl = 120 s; return (hit_for_pass); } return (deliver); } sub vcl_deliver { return (deliver); } sub vcl_error { set obj.http.Content-Type = "text/html; charset=utf-8"; set obj.http.Retry-After = "5"; synthetic {" <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>"} + obj.status + " " + obj.response + {"</title> </head> <body> <h1>Error "} + obj.status + " " + obj.response + {"</h1> <p>"} + obj.response + {"</p> <h3>Guru Meditation:</h3> <p>XID: "} + req.xid + {"</p> <hr> <p>Varnish cache server</p> </body> </html> "}; return (deliver); } sub vcl_init { return (ok); } sub vcl_fini { return (ok); } 

在端口81上有两个server模块,其中manager.domain.comconfiguration为主机头–nginx无法知道请求是否通过stunnel,所以第一个获胜并且总是发生redirect。

我build议让Varnish根据请求是否来自stunnel来做redirect(检查请求的client.ip – 127.0.0.1表示它来自stunnel),或者让varnish用标头标记来自stunnel的请求,以便nginx可以决定如何处理它们。