diff --git a/core/agent_daemon.sh b/core/agent_daemon.sh index 9945bf8..dc5064a 100755 --- a/core/agent_daemon.sh +++ b/core/agent_daemon.sh @@ -126,6 +126,18 @@ if os.path.exists('/opt/ip_sentinel/config.conf'): class AgentHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): + # ========================================================== + # 【核心加固】打破遥测盲区:请求一旦触达协议栈,在任何校验前强行审计 + # ========================================================== + try: + log_dir = '/opt/ip_sentinel/logs' + os.makedirs(log_dir, exist_ok=True) + ts = time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime()) + with open(f'{log_dir}/agent.log', 'a', encoding='utf-8') as f: + f.write(f"[{ts}] [TELEMETRY] Connection received from {self.client_address} -> Path: {self.path}\n") + except Exception: + pass + # [权限校验] 路径解析与 HMAC-SHA256 动态签名核验 parsed = urllib.parse.urlparse(self.path) req_path = parsed.path @@ -484,55 +496,79 @@ fi pass import socket +import threading + # ---------------------------------------------------------- -# [核心架构] 多线程非阻塞 Socket 模型 (抵抗 Slowloris 及阻塞攻击) +# [核心架构大跃迁: v4.3.2 双轨解耦监听防线] # ---------------------------------------------------------- -class DualStackServer(socketserver.ThreadingMixIn, socketserver.TCPServer): +class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer): allow_reuse_address = True + +class ThreadedServerV6(ThreadedServer): + """专属 IPv6 隔离监听器,强行物理隔绝 IPv4 混杂空间,彻底阻断 EADDRINUSE 冲突""" + address_family = socket.AF_INET6 def server_bind(self): - # [核心魔改] 强行解除 Linux/Unix 的 IPv6 独占锁 - # 实现一个 Socket 对象同时接管 IPv4 (0.0.0.0) 和 IPv6 (::) 的全域监听防漏接机制 - if self.address_family == socket.AF_INET6: - try: - self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) - except Exception: - pass + try: + self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) + except Exception: + pass super().server_bind() -# [v4.2.2 终极架构] 彻底抛弃配置文件的 IP 束缚,强行探测系统底层的双栈能力 -bind_addr = "::" -address_family = socket.AF_INET6 -try: - # 探针:如果机器是纯 IPv4 (连内核级的 IPv6 模块都没有被加载),强绑 :: 会引发 OSError,此时自动降维 - s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) - s.close() -except OSError: - bind_addr = "0.0.0.0" - address_family = socket.AF_INET +def main(): + import ssl + cert_path = '/opt/ip_sentinel/core/cert.pem' + key_path = '/opt/ip_sentinel/core/key.pem' + + context = None + if os.path.exists(cert_path) and os.path.exists(key_path): + try: + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.load_cert_chain(certfile=cert_path, keyfile=key_path) + except Exception as e: + print(f"SSL Context creation failed: {e}") -DualStackServer.address_family = address_family -httpd = DualStackServer((bind_addr, PORT), AgentHandler) + servers = [] -# ---------------------------------------------------------- -# [加密通信] 强制全网挂载 TLS 加密隧道上下文 -# ---------------------------------------------------------- -import ssl -cert_path = '/opt/ip_sentinel/core/cert.pem' -key_path = '/opt/ip_sentinel/core/key.pem' - -if os.path.exists(cert_path) and os.path.exists(key_path): + # 1. 尝试挂载 IPv4 独立对空雷达 try: - context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - context.load_cert_chain(certfile=cert_path, keyfile=key_path) - httpd.socket = context.wrap_socket(httpd.socket, server_side=True) + ThreadedServer.address_family = socket.AF_INET + srv_v4 = ThreadedServer(("0.0.0.0", PORT), AgentHandler) + if context: + srv_v4.socket = context.wrap_socket(srv_v4.socket, server_side=True) + servers.append(srv_v4) + print(f"📡 IPv4 Vector Socket binding established on 0.0.0.0:{PORT}") except Exception as e: - print(f"SSL 隧道构建失败,退化为 HTTP: {e}") + print(f"⚠️ IPv4 Socket binding failed: {e}") -try: - httpd.serve_forever() -except Exception as e: - sys.exit(1) + # 2. 尝试挂载 IPv6 独立对空雷达 (强制隔离 IPv4) + try: + srv_v6 = ThreadedServerV6(("::", PORT), AgentHandler) + if context: + srv_v6.socket = context.wrap_socket(srv_v6.socket, server_side=True) + servers.append(srv_v6) + print(f"📡 IPv6 Vector Socket binding established on [::]:{PORT}") + except Exception as e: + print(f"⚠️ IPv6 Socket binding failed: {e}") + + if not servers: + print("❌ [FATAL] Dual-Stack Network Radar completely localized binding failed!") + sys.exit(1) + + # 3. 跨线程异步并发激活所有对空信道 + for srv in servers: + t = threading.Thread(target=srv.serve_forever, daemon=True) + t.start() + + # 4. 主守护线程,使用简单的时间挂起 + try: + while True: + time.sleep(3600) + except KeyboardInterrupt: + sys.exit(0) + +if __name__ == '__main__': + main() EOF -echo "🚀 [Agent] 正在启动 Webhook 监听服务 (端口: $AGENT_PORT)..." +echo "🚀 [Agent] 正在启动双轨独立 Webhook 监听引擎 (端口: $AGENT_PORT)..." exec python3 "${INSTALL_DIR}/core/webhook.py" "$AGENT_PORT" \ No newline at end of file