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:
admin 2026-08-08 14:30:51 +00:00
parent 98bd0d7d23
commit 6fd758bb1f
2 changed files with 40 additions and 6 deletions

View file

@ -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;
}} }}
}} }}
""") """)

View file

@ -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)