Files
SMANAGE/php/test-nc-public.py
T

82 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""test-nc-public.py - 模拟 frpc 行为:发 PROXY v1 + TLS ClientHello SNI=nc.gvsds.com 到 127.0.0.1:10443"""
import socket
import ssl
import time
import sys
HOST = "127.0.0.1"
PORT = 10443
SNI = "nc.gvsds.com"
PROXY_SRC_IP = "8.8.8.8" # 模拟客户端公网 IP
PROXY_SRC_PORT = 54321
def build_proxy_v1_header(src_ip, src_port, dst_ip, dst_port):
return f"PROXY TCP4 {src_ip} {dst_ip} {src_port} {dst_port}\r\n".encode("ascii")
def main():
# 1) 裸 TCP 到 10443
raw = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
raw.settimeout(180)
raw.connect((HOST, PORT))
# 2) 发 PROXY v1 header
proxy_hdr = build_proxy_v1_header(PROXY_SRC_IP, PROXY_SRC_PORT, HOST, PORT)
print(f" -> PROXY header: {proxy_hdr!r}")
raw.sendall(proxy_hdr)
# 3) 包 TLS
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
ctx.set_alpn_protocols(["http/1.1"]) # 强制 http/1.1,避免 h2 frame 复杂度
s = ctx.wrap_socket(raw, server_hostname=SNI)
print(f" TLS SNI: {SNI}, ALPN: {s.selected_alpn_protocol()}")
# 4) 发 HTTP/1.1(绕开 h2 SETTINGS frame 复杂度)
req = (
f"GET /login HTTP/1.1\r\n"
f"Host: {SNI}\r\n"
f"User-Agent: test-nc-public/1.0\r\n"
f"Accept: */*\r\n"
f"Connection: close\r\n"
f"\r\n"
).encode("ascii")
t0 = time.time()
s.sendall(req)
print(f" -> sent {len(req)} bytes request")
# 5) 读响应
chunks = []
while True:
try:
data = s.recv(65536)
except socket.timeout:
print(" [timeout 30s]")
break
if not data:
break
chunks.append(data)
s.close()
elapsed = time.time() - t0
body = b"".join(chunks)
head, _, body = body.partition(b"\r\n\r\n")
status_line = head.split(b"\r\n", 1)[0].decode("latin-1", errors="replace")
print(f" Status: {status_line}")
print(f" Body size: {len(body)} bytes")
print(f" Elapsed: {elapsed:.2f}s")
print(f" Body preview (前 500 字符):")
text = body[:500].decode("utf-8", errors="replace")
for line in text.splitlines()[:15]:
print(f" {line}")
return 0 if b"200 OK" in head or b"302" in head else 1
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as e:
print(f" EXCEPTION: {type(e).__name__}: {e}")
sys.exit(2)