1

My nginx website is protected by IP range and I need to be on the premises or log in via vpn to see it:

geo $external_ip {
  192.168.0.0/16 0;
}
…
if ($external_ip) {
  return 302 https://www.different-site.com/info_explaining_to_log_in_via_vpn ;
}
…
# Normal location config for website

Now I access my website and I have forgotten to log in via the VPN. So I am being redirected to the info page that tells me nicely why I can't access the site and that I have to fire up my VPN client.

I do so. And now I reenter the URL to my website again, but the browser seems to remember the redirect and keeps returning the info page.

The same happens if I use a 307 status code.

After a while, the browser seems to forget that redirect and behaves as I expect again and shows me my site.

The same happens if I simply return 403, effectively discarding my info page. I did that because I thought it might be some cache statements. But also the default nginx 403 page seems to get remembered by the browser.

Is there a way how I can make the browser try to reload the orginal site with each try? I feel I am missing a vital brick of the puzzle.

Output of $ curl -I https://different-site.com/:

HTTP/2 302

server: nginx/1.10.3 (Ubuntu)
date: Mon, 11 May 2020 20:07:54 GMT
content-type: text/html
content-length: 170
location: different-site.com/info_explaining_to_log_in_via_vpn
pragma: no-cache
cache-control: no-cache

More information: The problem only exists in the browser that initially opened the connection without the vpn in place. Any other browser or a curl run after initiating the vpn succeeds.

More information (2): I am currently assuming that my browser is keeping a connection alive which is reused even once the VPN is started. That way, nginx still sees the old public IP and refuses access until that original connection is terminated. According to https://serverfault.com/questions/775617/force-nginx-to-close-connection, I cannot terminate the connection server side unless I disable keepalive completely, which I don't want for performance reasons. So it looks like there is no way forward. My next thought is to put something in front of nginx (haproxy?) which could determine a connection close depending on url.

pilz
  • 23
  • 5
  • Just a thought: Is it possible that firefox keeps the connection open due to the connection keepalive? Because I can make it work if I reload nginx… – pilz May 11 '20 at 19:05
  • What's output of `$ curl -I https://your-specific-url/` ? – anthumchris May 11 '20 at 19:13
  • `HTTP/2 302` `server: nginx/1.10.3 (Ubuntu)` `date: Mon, 11 May 2020 20:07:54 GMT` `content-type: text/html` `content-length: 170` `location: https://www.different-site.com/info_explaining_to_log_in_via_vpn` `pragma: no-cache` `cache-control: no-cache` Of course, without the vpn in place. – pilz May 11 '20 at 20:08

2 Answers2

0

Does it help to disable cache response headers?

add_header cache-control no-cache always;
add_header Last-Modified  "" always;
etag off;
if_modified_since off;

I've had this issue before when my server originally sent a 301 before I changed it to 302. You can also clear Chrome's DNS cache with chrome://net-internals/#dns, or try a private/incognito window in your browser. Firefox/Chrome dev tools let you disable the cache and should pick up the new Location header if you reload the URL:

enter image description here

anthumchris
  • 8,245
  • 2
  • 28
  • 53
  • Thank you! I added the two headers. Nginx wouldn't let me add the etag and if_modified_since, as they apparently are not allowed in the location block. Didn't make a difference. – pilz May 11 '20 at 19:05
  • Also, I can tick the "Disable cache" checkbox in the network tab of FF and it will still load the redirected page. Also clearing the cache in settings doesn't fix it. – pilz May 11 '20 at 19:08
0

Try Cache-Control: no-store instead.

From the documentation for no-cache:

The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it, therefore, you cannot use no-cache in-conjunction with immutable. If you mean to not store the response in any cache, use no-store instead. This directive is not effective in preventing caches from storing your response.

miknik
  • 5,748
  • 1
  • 10
  • 26
  • I tried that, both by setting no-cache and no-store and by setting only no-store alone. Both times the behaviour didn't change. – pilz May 12 '20 at 07:03