To give as basic of a rundown as possible, I have 2 servers running. One server is apache running on 80, the other is a recaptcha server daemon I've created in golang running over 29999. I have an application running that monitors all events coming across the host, and if any kind of "shun worthy" traffic hits the box. It will shun your ip via an ipset add <set> <ip>
, and it will add a nat prerouting rules on 80 and 443 with the target IP to redirect them to port 29999. Using 1.1.1.1 for example
-A RECAPTCHA-PREROUTE -s 1.1.1.1/32 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 29999
-A RECAPTCHA-PREROUTE -s 1.1.1.1/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 29999
Fast forward a bit: Im trying to hit port 80 (im shunned). I get redirected correctly to my daemon. I solve the recaptcha, the recaptcha properly dials out to the daemon, the daemon properly removes the prerouting firewall rules for the IP, and removes them from the ipset. After the "unshun" the Golang daemon does a http.Redirect(w, req, "/", 200)
with the intention of sending you to https://example.com/ , BUT instead, it sends me right back to the recaptcha daemon running on 29999, even though I can open a separate browser(edge gag), and it will take me straight to the intended endpoint on the separate browser. With that in mind, if I would have run the initial request on edge, its behavior would reflect the other browsers. A colleague of mine and I are convinced that its some kind of weird caching issue in the browser that we are missing proper handling for, but we have since then exhausted most of the possible solutions that we could find on the internet, such as proper caching headers being served, and adding meta tags to the html document.
ex):
Golang
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "0")
HTML
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'>
One more interesting thing to note is, after you get redirected incorrectly to the recaptcha daemon page after the unshun/firewall removal. If you push ctrl r on the browser UI about ~20-50 times. You will eventually stop getting the recaptcha page, and it will properly hit the intended server endpoint. Also if you clear your browsers cache, it will immediately take you to the correct page as well. (which is why we feel this is some obscure caching issue.
CodePudding user response:
Thanks to JimB who responded in the comments, I found a solution to the issue. He was correct in stating that I hadn't closed the connection out properly.
All I had to do was add a close header w.Header().Set("Connection", "close")
and a defer req.Body.Close()
. req being the handlers *http.Request