diff --git a/sources/python/main.py b/sources/python/main.py index b49eb0b..4829643 100644 --- a/sources/python/main.py +++ b/sources/python/main.py @@ -200,6 +200,7 @@ def main(): print(f" [{n}] Delete a node"); ops['del'] = str(n); n += 1 print(f" [{n}] Status"); ops['status'] = str(n); n += 1 print(f" [{n}] Remote tunnel"); ops['tunnel'] = str(n); n += 1 + print(f" [{n}] Debug (tap proxy)"); ops['debug'] = str(n); n += 1 print(" [q] Quit") c = input("\nChoice: ").strip() @@ -224,6 +225,8 @@ def main(): container_status() elif c == ops.get('tunnel'): start_tunnel() + elif c == ops.get('debug'): + start_debug() elif c.lower() == "q": break @@ -385,3 +388,67 @@ def remove_menu(): if __name__ == "__main__": main() + +def start_debug(): + s = load_state().get("nodes", []) + if not s: print("No nodes."); return + print("\n─── Debug (Tap Proxy) ───") + for i, n in enumerate(s): + print(f" [{i+1}] {n['name']} (port {n.get('port','')})") + c = input("\nSelect node: ").strip() + if not c.isdigit(): return + idx = int(c) - 1 + if idx < 0 or idx >= len(s): return + n = s[idx] + port = str(n.get('port', '8081')) + + # Write tap proxy script + tap = f"""{BASE}/app/tap-proxy.py""" + with open(tap, "w") as f: + f.write(f'''#!/usr/bin/env python3 +import http.server, urllib.request, os +from datetime import datetime + +BACKEND = "http://{n.get('upstream_ip','127.0.0.1')}:{n.get('upstream_port','80')}" +LOG = "{BASE}/{n['name']}/tap-{{}}.log".format(datetime.now().strftime("%Y%m%d-%H%M%S")) + +class Tap(http.server.BaseHTTPRequestHandler): + def do_GET(self): self._tap('GET') + def do_POST(self): self._tap('POST') + def do_PUT(self): self._tap('PUT') + def _tap(self, method): + now = datetime.now().strftime('%H:%M:%S') + msg = f"\\n{'='*60}\\n[{now}] {method} {self.path}\\nClient: {self.client_address[0]}\\n" + for k,v in sorted(self.headers.items()): msg += f" {k}: {v}\\n" + body = self.rfile.read(int(self.headers.get('Content-Length',0))) if 'Content-Length' in self.headers else None + req = urllib.request.Request(f"{{BACKEND}}{{self.path}}", data=body, method=method) + for k,v in self.headers.items(): + if k.lower() not in ('host','connection'): req.add_header(k,v) + resp = urllib.request.urlopen(req, timeout=30) + msg += f"\\nRESPONSE: {resp.status}\\n" + for k,v in resp.getheaders(): msg += f" {k}: {v}\\n" + self.send_response(resp.status) + for k,v in resp.getheaders(): + if k.lower() not in ('transfer-encoding','connection'): self.send_header(k,v) + self.end_headers(); self.wfile.write(resp.read()) + with open(LOG, "a") as l: l.write(msg) + def log_message(self,*a): pass + +print(f"Tap proxy :{port} → {{BACKEND}}\\nLog: {{LOG}}\\nCtrl+C to stop") +http.server.HTTPServer(('0.0.0.0',{port}), Tap).serve_forever() +''') + os.chmod(tap, 0o755) + + # Stop container, start tap + print(f"\\nStopping wallarm-{n['name']}...") + run(f"docker stop wallarm-{n['name']} 2>/dev/null", timeout=10) + print(f"Starting tap proxy on port {port}...") + print(f"Log: {BASE}/{n['name']}/tap-*.log") + print("Press Ctrl+C to stop, container will restart automatically.") + try: + run(f"python3 {tap}", timeout=300) + except: + pass + finally: + print(f"\\nRestarting wallarm-{n['name']}...") + run(f"docker start wallarm-{n['name']} 2>/dev/null || bash {BASE}/{n['name']}/start.sh", timeout=30)