diff --git a/proxy/README.md b/proxy/README.md new file mode 100644 index 0000000..53dfebe --- /dev/null +++ b/proxy/README.md @@ -0,0 +1,103 @@ +# 内网代理方案使用说明 + +## 问题描述 +- **A设备(当前设备)**:可以监听端口,但无法访问内网网站 +- **B设备(局域网设备)**:可以访问内网网站,但无法监听端口 + +## 解决方案 +通过反向代理方式实现访问: +1. **A设备**:运行代理服务器,监听端口接收用户请求和B设备连接 +2. **B设备**:主动连接到A设备,负责转发请求到内网网站 + +## 文件结构 +``` +proxy/ +├── proxy_server.py # 运行在A设备上 +├── proxy_client.py # 运行在B设备上 +└── README.md # 使用说明 +``` + +## 使用步骤 + +### 第一步:在A设备(当前设备)上启动代理服务器 + +```bash +python proxy_server.py +``` + +输出示例: +``` +A设备代理服务器已启动,监听端口 8080 +等待B设备连接和用户请求... +``` + +记录A设备的IP地址(假设为 `192.168.1.50`) + +### 第二步:在B设备上运行客户端程序 + +```bash +python proxy_client.py 192.168.1.50 8080 +``` + +输出示例: +``` +成功连接到A设备: 192.168.1.50:8080 +准备转发请求到: superstar.geelytravel.com:443 +``` + +### 第三步:在A设备上访问内网网站 + +**方式一:设置浏览器代理** +1. 打开浏览器设置 +2. 设置HTTP/HTTPS代理为:`localhost:8080` +3. 访问:`https://superstar.geelytravel.com` + +**方式二:使用curl测试** +```bash +curl -x http://localhost:8080 https://superstar.geelytravel.com +``` + +## 工作原理 +``` +用户浏览器 → A设备(监听端口8080) → B设备 → 内网网站 + ↑ | + └────────────────────┘ + 响应返回路径 +``` + +## 配置说明 + +### A设备(proxy_server.py) +```python +TARGET_HOST = 'superstar.geelytravel.com' # 目标内网网站 +TARGET_PORT = 443 # HTTPS端口 +LISTEN_PORT = 8080 # A设备监听端口 +``` + +### B设备(proxy_client.py) +```python +TARGET_HOST = 'superstar.geelytravel.com' # 目标内网网站 +TARGET_PORT = 443 # HTTPS端口 +``` + +## 注意事项 + +1. 确保两台设备在同一局域网内 +2. A设备的防火墙需要允许端口 `8080` 的入站连接 +3. B设备需要能正常访问目标内网网站 +4. 启动顺序:先启动A设备的服务器,再启动B设备的客户端 + +## 故障排除 + +**B设备无法连接到A设备:** +- 检查A设备的IP地址是否正确 +- 检查A设备的防火墙设置 +- 确保A设备的代理服务器已启动 + +**网站无法访问:** +- 检查B设备是否能直接访问目标网站 +- 检查网络连接是否正常 + +**连接不稳定:** +- 检查网络稳定性 +- 考虑增加超时重试机制 diff --git a/proxy/proxy_client.py b/proxy/proxy_client.py new file mode 100644 index 0000000..c3630a3 --- /dev/null +++ b/proxy/proxy_client.py @@ -0,0 +1,80 @@ +import socket +import threading +import sys + +TARGET_HOST = 'superstar.geelytravel.com' +TARGET_PORT = 443 + +def handle_request(sock): + """处理从A设备收到的请求,转发到目标网站""" + try: + # 接收来自A设备的请求 + request = b"" + while True: + data = sock.recv(4096) + if not data: + break + request += data + if b"\r\n\r\n" in request: + break + + if not request: + return + + # 连接到目标网站 + target_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + target_sock.connect((TARGET_HOST, TARGET_PORT)) + + # 发送请求 + target_sock.send(request) + + # 接收响应并转发回A设备 + while True: + response = target_sock.recv(4096) + if not response: + break + sock.send(response) + + target_sock.close() + except Exception as e: + print(f"处理请求出错: {e}") + try: + sock.send(b"HTTP/1.1 500 Internal Server Error\r\n\r\n") + except: + pass + +def connect_to_a_device(a_host, a_port): + """连接到A设备""" + while True: + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.connect((a_host, a_port)) + print(f"成功连接到A设备: {a_host}:{a_port}") + print(f"准备转发请求到: {TARGET_HOST}:{TARGET_PORT}") + + handle_request(sock) + + sock.close() + print("与A设备的连接已断开") + except ConnectionRefusedError: + print(f"A设备未就绪,重试中...") + import time + time.sleep(3) + except Exception as e: + print(f"连接出错: {e}") + import time + time.sleep(3) + +def main(): + if len(sys.argv) < 3: + print("用法: python proxy_client.py ") + print("示例: python proxy_client.py 192.168.1.50 8080") + sys.exit(1) + + a_host = sys.argv[1] + a_port = int(sys.argv[2]) + + connect_to_a_device(a_host, a_port) + +if __name__ == '__main__': + main() diff --git a/proxy/proxy_manager.py b/proxy/proxy_manager.py new file mode 100644 index 0000000..4f151f1 --- /dev/null +++ b/proxy/proxy_manager.py @@ -0,0 +1,112 @@ +import sys +import winreg + +def get_current_proxy(): + """获取当前系统代理设置""" + try: + internet_settings = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', + 0, + winreg.KEY_READ + ) + proxy_server, _ = winreg.QueryValueEx(internet_settings, 'ProxyServer') + proxy_enable, _ = winreg.QueryValueEx(internet_settings, 'ProxyEnable') + winreg.CloseKey(internet_settings) + return { + 'enabled': bool(proxy_enable), + 'server': proxy_server + } + except FileNotFoundError: + return {'enabled': False, 'server': ''} + except Exception as e: + print(f"获取代理设置失败: {e}") + return {'enabled': False, 'server': ''} + +def set_proxy(proxy_host, proxy_port): + """设置系统代理""" + try: + internet_settings = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', + 0, + winreg.KEY_ALL_ACCESS + ) + + proxy_server = f'{proxy_host}:{proxy_port}' + winreg.SetValueEx(internet_settings, 'ProxyServer', 0, winreg.REG_SZ, proxy_server) + winreg.SetValueEx(internet_settings, 'ProxyEnable', 0, winreg.REG_DWORD, 1) + winreg.CloseKey(internet_settings) + + print(f"✅ 系统代理已设置为: {proxy_server}") + return True + except Exception as e: + print(f"❌ 设置代理失败: {e}") + return False + +def unset_proxy(): + """取消系统代理""" + try: + internet_settings = winreg.OpenKey( + winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings', + 0, + winreg.KEY_ALL_ACCESS + ) + + winreg.SetValueEx(internet_settings, 'ProxyEnable', 0, winreg.REG_DWORD, 0) + winreg.CloseKey(internet_settings) + + print("✅ 系统代理已取消") + return True + except Exception as e: + print(f"❌ 取消代理失败: {e}") + return False + +def show_status(): + """显示当前代理状态""" + proxy = get_current_proxy() + print("\n当前代理状态:") + print(f" 代理已启用: {'是' if proxy['enabled'] else '否'}") + if proxy['enabled']: + print(f" 代理服务器: {proxy['server']}") + print() + +def main(): + if len(sys.argv) < 2: + print("=" * 50) + print(" Windows系统代理管理脚本") + print("=" * 50) + print("用法:") + print(f" {sys.argv[0]} status - 查看当前代理状态") + print(f" {sys.argv[0]} set - 设置代理服务器") + print(f" {sys.argv[0]} unset - 取消代理设置") + print(f" {sys.argv[0]} localhost - 快速设置为 localhost:8080") + print("\n示例:") + print(f" {sys.argv[0]} set 192.168.1.50 8080") + print(f" {sys.argv[0]} localhost") + print(f" {sys.argv[0]} unset") + print("=" * 50) + return + + command = sys.argv[1].lower() + + if command == 'status': + show_status() + elif command == 'set': + if len(sys.argv) < 4: + print("❌ 参数不足,请提供代理服务器地址和端口") + print(f" 示例: {sys.argv[0]} set 192.168.1.50 8080") + return + proxy_host = sys.argv[2] + proxy_port = sys.argv[3] + set_proxy(proxy_host, proxy_port) + elif command == 'unset': + unset_proxy() + elif command == 'localhost': + set_proxy('localhost', '8080') + else: + print(f"❌ 未知命令: {command}") + +if __name__ == '__main__': + main() diff --git a/proxy/proxy_server.py b/proxy/proxy_server.py new file mode 100644 index 0000000..1d9e916 --- /dev/null +++ b/proxy/proxy_server.py @@ -0,0 +1,86 @@ +import socket +import threading +import select + +TARGET_HOST = 'superstar.geelytravel.com' +TARGET_PORT = 443 +LISTEN_PORT = 8080 + +b_device_socket = None +client_socket = None + +def handle_b_device(conn): + """处理B设备的连接""" + global b_device_socket + b_device_socket = conn + print(f"B设备已连接: {conn.getpeername()}") + + try: + while True: + data = conn.recv(4096) + if not data: + print("B设备断开连接") + b_device_socket = None + break + + if client_socket: + try: + client_socket.send(data) + except: + pass + except Exception as e: + print(f"B设备连接出错: {e}") + b_device_socket = None + +def handle_client(conn): + """处理用户请求""" + global client_socket + client_socket = conn + print(f"用户连接: {conn.getpeername()}") + + try: + while True: + data = conn.recv(4096) + if not data: + print("用户断开连接") + client_socket = None + break + + if b_device_socket: + try: + b_device_socket.send(data) + except: + conn.send(b"HTTP/1.1 503 Service Unavailable\r\n\r\nB设备未连接") + break + else: + conn.send(b"HTTP/1.1 503 Service Unavailable\r\n\r\nB设备未连接") + break + except Exception as e: + print(f"用户连接出错: {e}") + client_socket = None + +def run_server(): + server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + server.bind(('0.0.0.0', LISTEN_PORT)) + server.listen(5) + + print(f"A设备代理服务器已启动,监听端口 {LISTEN_PORT}") + print(f"等待B设备连接和用户请求...") + + while True: + conn, addr = server.accept() + print(f"新连接: {addr}") + + # 判断是B设备还是用户(简单判断:先连接的是B设备) + if b_device_socket is None: + # 第一个连接作为B设备 + t = threading.Thread(target=handle_b_device, args=(conn,)) + t.start() + else: + # 后续连接作为用户 + t = threading.Thread(target=handle_client, args=(conn,)) + t.start() + +if __name__ == '__main__': + run_server()