fix: apply WAF plugin team fixes — Host header, chunked encoding, no redirect follow
- nginx.conf: restore proxy_set_header for Host, X-Real-IP, X-Forwarded-For - tap-proxy: preserve Host header, handle chunked POST, don't follow redirects - Credits: zoraxy-waf plugin team
This commit is contained in:
parent
98bd0d7d23
commit
6fd758bb1f
2 changed files with 40 additions and 6 deletions
|
|
@ -103,7 +103,10 @@ server {{
|
||||||
|
|
||||||
location / {{
|
location / {{
|
||||||
proxy_pass http://{upstream};
|
proxy_pass http://{upstream};
|
||||||
# Headers pass through from ingress controller — no overwrite
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
""")
|
""")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Tap Proxy — logs HTTP headers. Usage: python3 tap-proxy.py <port> <backend_host:port> <log_dir>"""
|
"""Tap Proxy — logs HTTP headers. Usage: python3 tap-proxy.py <port> <backend_host:port> <log_dir>"""
|
||||||
import http.server, urllib.request, sys
|
import http.server, urllib.request, sys, socket
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8081
|
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8081
|
||||||
|
|
@ -8,6 +8,18 @@ BACKEND = sys.argv[2] if len(sys.argv) > 2 else "127.0.0.1:80"
|
||||||
LOG = (sys.argv[3] if len(sys.argv) > 3 else "/tmp") + "/tap-" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".log"
|
LOG = (sys.argv[3] if len(sys.argv) > 3 else "/tmp") + "/tap-" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".log"
|
||||||
BACKEND_URL = "http://" + BACKEND
|
BACKEND_URL = "http://" + BACKEND
|
||||||
|
|
||||||
|
# Don't follow redirects — preserve Set-Cookie
|
||||||
|
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||||
|
def http_error_302(self, req, fp, code, msg, headers):
|
||||||
|
fp.status, fp.reason = code, msg
|
||||||
|
return fp
|
||||||
|
http_error_301 = http_error_302
|
||||||
|
http_error_303 = http_error_302
|
||||||
|
http_error_307 = http_error_302
|
||||||
|
http_error_308 = http_error_302
|
||||||
|
|
||||||
|
_opener = urllib.request.build_opener(NoRedirect)
|
||||||
|
|
||||||
class Tap(http.server.BaseHTTPRequestHandler):
|
class Tap(http.server.BaseHTTPRequestHandler):
|
||||||
def do_GET(self): self._tap('GET')
|
def do_GET(self): self._tap('GET')
|
||||||
def do_POST(self): self._tap('POST')
|
def do_POST(self): self._tap('POST')
|
||||||
|
|
@ -21,15 +33,34 @@ class Tap(http.server.BaseHTTPRequestHandler):
|
||||||
for k, v in sorted(self.headers.items()):
|
for k, v in sorted(self.headers.items()):
|
||||||
msg += " " + k + ": " + v + "\n"
|
msg += " " + k + ": " + v + "\n"
|
||||||
|
|
||||||
body = self.rfile.read(int(self.headers.get('Content-Length', 0))) if 'Content-Length' in self.headers else None
|
# Handle chunked transfer-encoding
|
||||||
|
body = None
|
||||||
|
cl = self.headers.get('Content-Length')
|
||||||
|
te = self.headers.get('Transfer-Encoding', '').lower()
|
||||||
|
if cl:
|
||||||
|
body = self.rfile.read(int(cl))
|
||||||
|
elif 'chunked' in te:
|
||||||
|
body = b''
|
||||||
|
while True:
|
||||||
|
line = self.rfile.readline().strip()
|
||||||
|
if not line: continue
|
||||||
|
size = int(line, 16)
|
||||||
|
if size == 0: break
|
||||||
|
body += self.rfile.read(size)
|
||||||
|
self.rfile.readline()
|
||||||
|
while True:
|
||||||
|
line = self.rfile.readline().strip()
|
||||||
|
if not line: break
|
||||||
|
|
||||||
req = urllib.request.Request(BACKEND_URL + self.path, data=body, method=method)
|
req = urllib.request.Request(BACKEND_URL + self.path, data=body, method=method)
|
||||||
|
# Pass through all headers including Host
|
||||||
for k, v in self.headers.items():
|
for k, v in self.headers.items():
|
||||||
if k.lower() not in ('host', 'connection'):
|
if k.lower() not in ('connection',):
|
||||||
req.add_header(k, v)
|
req.add_header(k, v)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resp = urllib.request.urlopen(req, timeout=30)
|
resp = _opener.open(req, timeout=30)
|
||||||
msg += "\nRESPONSE: " + str(resp.status) + "\n"
|
msg += "\nRESPONSE: " + str(resp.status) + " " + str(resp.reason) + "\n"
|
||||||
for k, v in resp.getheaders():
|
for k, v in resp.getheaders():
|
||||||
msg += " " + k + ": " + v + "\n"
|
msg += " " + k + ": " + v + "\n"
|
||||||
self.send_response(resp.status)
|
self.send_response(resp.status)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue