TCP反向代理:将局域网内部的TCP/HTTP服务暴露在公网上
TCP反向代理将局域网内部的TCP/HTTP服务暴露在公网上在现代网络环境中许多服务运行在局域网内部例如开发测试服务器、内网Web应用、数据库或自定义TCP服务。但有时我们需要从公网访问这些服务比如远程调试、演示给客户或实现跨网络通信。直接暴露局域网服务到公网面临IP地址不足、防火墙限制和安全性问题。TCP反向代理技术提供了一种优雅的解决方案它允许公网用户通过一个中间代理服务器访问内网服务而无需直接暴露内网节点。本文将深入剖析TCP反向代理的原理并提供两个可运行的代码示例分别实现一个简单的TCP反向代理和一个基于HTTP的反向代理。我们将使用Python来实现因为其简洁性和广泛的库支持。### 反向代理的核心原理反向代理Reverse Proxy位于客户端和目标服务器之间。对于客户端来说反向代理就像是目标服务器对于目标服务器来说反向代理就像是客户端。在TCP层面反向代理的工作流程如下1.公网监听代理服务器在公网IP上监听一个端口例如8080。2.连接转发当公网客户端连接到代理端口时代理服务器创建一个新的TCP连接到内网目标服务器例如192.168.1.100:80。3.数据中继代理服务器在两个连接之间双向转发数据。它读取来自客户端的字节写入到内网服务器连接反之亦然。这种模式的关键在于内网服务器不需要公网IP只需要能够主动连接到代理服务器或代理服务器能连接它。常见的实现方式包括端口转发如iptables和专用代理工具如ngrok、frp。下面我们手动实现一个简单的TCP反向代理。### 实现一个TCP反向代理首先我们创建一个基础的TCP反向代理。它监听公网端口并将所有传入连接转发到指定的内网地址。我们将使用Python的socket和selectors模块来实现高效的I/O多路复用。pythonimport socketimport selectorsimport sysclass TCPReverseProxy: def __init__(self, listen_host, listen_port, target_host, target_port): self.listen_host listen_host self.listen_port listen_port self.target_host target_host self.target_port target_port self.selector selectors.DefaultSelector() # 使用默认选择器Linux下为epoll def start(self): # 创建监听socket server_sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_sock.bind((self.listen_host, self.listen_port)) server_sock.listen(100) server_sock.setblocking(False) # 非阻塞模式 # 注册监听socket到选择器处理新连接 self.selector.register(server_sock, selectors.EVENT_READ, self.accept_connection) print(f代理服务器启动监听 {self.listen_host}:{self.listen_port}) print(f转发目标 {self.target_host}:{self.target_port}) try: while True: events self.selector.select(timeoutNone) # 阻塞等待事件 for key, mask in events: callback key.data # 回调函数 callback(key.fileobj, mask) except KeyboardInterrupt: print(代理服务器关闭) finally: self.selector.close() def accept_connection(self, server_sock, mask): 接受客户端连接并建立到内网服务器的连接 client_sock, addr server_sock.accept() print(f接受来自 {addr} 的连接) client_sock.setblocking(False) # 创建到内网服务器的连接 target_sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: target_sock.connect((self.target_host, self.target_port)) target_sock.setblocking(False) except Exception as e: print(f连接目标服务器失败: {e}) client_sock.close() return # 注册两个socket到选择器用于双向数据转发 self.selector.register(client_sock, selectors.EVENT_READ, self.forward_to_target) self.selector.register(target_sock, selectors.EVENT_READ, self.forward_to_client) def forward_to_target(self, sock, mask): 从客户端读取数据转发到目标服务器 self._forward_data(sock, 客户端, 目标服务器) def forward_to_client(self, sock, mask): 从目标服务器读取数据转发到客户端 self._forward_data(sock, 目标服务器, 客户端) def _forward_data(self, from_sock, from_name, to_name): 通用的数据转发函数 try: data from_sock.recv(4096) # 读取数据 if data: # 查找对应的目标socket即配对的另一个socket # 这里简化处理通过选择器中的文件对象查找 other_sock None for key in self.selector.get_map().values(): if key.fileobj ! from_sock and key.fileobj.fileno() ! from_sock.fileno(): # 需要更精确的配对逻辑这里仅作演示 other_sock key.fileobj break if other_sock and data: other_sock.send(data) # 转发数据 print(f转发 {len(data)} 字节从 {from_name} 到 {to_name}) else: # 连接关闭清理资源 self._cleanup(from_sock) except Exception as e: print(f转发错误: {e}) self._cleanup(from_sock) def _cleanup(self, sock): 关闭socket并取消注册 try: self.selector.unregister(sock) sock.close() except: passif __name__ __main__: # 使用示例监听本机8080转发到内网192.168.1.100:80 proxy TCPReverseProxy(0.0.0.0, 8080, 192.168.1.100, 80) proxy.start()代码说明- 使用selectors模块实现非阻塞I/O可高效处理多个并发连接。-accept_connection处理新连接并同时建立到内网服务器的TCP连接。- 数据转发通过注册EVENT_READ事件当数据到达时调用对应的转发函数。- 注意上述代码中的配对逻辑简化了仅用于演示实际生产环境需要维护一个字典来映射客户端和服务器socket对。### 实现一个HTTP反向代理对于HTTP服务反向代理需要处理更复杂的场景如HTTP头部修改、负载均衡、缓存等。下面我们实现一个简单的HTTP反向代理它解析HTTP请求转发到内网服务器并返回响应。pythonimport socketimport selectorsimport sysclass HTTPReverseProxy: def __init__(self, listen_host, listen_port, target_host, target_port): self.listen_host listen_host self.listen_port listen_port self.target_host target_host self.target_port target_port self.selector selectors.DefaultSelector() def start(self): server_sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_sock.bind((self.listen_host, self.listen_port)) server_sock.listen(100) server_sock.setblocking(False) self.selector.register(server_sock, selectors.EVENT_READ, self.accept_connection) print(fHTTP反向代理启动监听 {self.listen_host}:{self.listen_port}) print(f转发到 {self.target_host}:{self.target_port}) try: while True: events self.selector.select(timeoutNone) for key, mask in events: callback key.data callback(key.fileobj, mask) except KeyboardInterrupt: print(代理关闭) finally: self.selector.close() def accept_connection(self, server_sock, mask): client_sock, addr server_sock.accept() print(f接受HTTP连接来自 {addr}) client_sock.setblocking(False) # 创建到内网HTTP服务器的连接 target_sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: target_sock.connect((self.target_host, self.target_port)) target_sock.setblocking(False) except Exception as e: print(f连接目标失败: {e}) client_sock.close() return # 保存配对信息 self.connections[client_sock] target_sock self.connections[target_sock] client_sock # 注册读事件开始转发 self.selector.register(client_sock, selectors.EVENT_READ, self.forward) self.selector.register(target_sock, selectors.EVENT_READ, self.forward) def forward(self, sock, mask): 转发数据并修改HTTP头部可选 other_sock self.connections.get(sock) if not other_sock: self._cleanup(sock) return try: data sock.recv(4096) if data: # 如果是客户端发来的请求可以修改Host头部 if sock in self.connections and self.connections[sock] is not None: # 这里简单示例打印请求信息实际可修改头部 print(f收到HTTP数据: {len(data)} 字节) other_sock.send(data) else: self._cleanup(sock) self._cleanup(other_sock) except Exception as e: print(f转发错误: {e}) self._cleanup(sock) self._cleanup(other_sock) def _cleanup(self, sock): try: self.selector.unregister(sock) sock.close() if sock in self.connections: del self.connections[sock] except: passif __name__ __main__: # 示例监听8080转发到内网192.168.1.100:80 proxy HTTPReverseProxy(0.0.0.0, 8080, 192.168.1.100, 80) proxy.connections {} # 初始化连接字典 proxy.start()代码说明- 与TCP反向代理类似但增加了connections字典来精确配对客户端和服务器socket。- 实际HTTP代理通常需要修改请求头部如添加X-Forwarded-For、修改Host这里仅做数据转发演示。- 此代理可以处理简单的HTTP请求但无法处理分块传输、WebSocket等高级特性。### 安全性与部署考虑在实际部署中TCP反向代理需要关注以下几点1.加密传输使用TLS/SSL对代理通道加密防止数据泄露。2.访问控制在代理层添加IP白名单或认证机制。3.连接超时设置空闲超时防止资源占用。4.日志监控记录连接信息便于故障排查。对于生产环境建议使用成熟的工具如Nginx支持TCP和HTTP反向代理、HAProxy或专业的反向代理服务如ngrok。### 总结TCP反向代理是实现内网服务公网暴露的核心技术。本文深入剖析了其原理代理服务器在公网监听将客户端连接转发到内网服务器并在两者间双向中继数据。我们提供了两个可运行的Python代码示例一个基础的TCP反向代理和一个HTTP反向代理演示了如何使用socket和selectors实现高效转发。这些示例展示了反向代理的基本工作流程但实际生产环境还需要考虑加密、安全性、性能优化等因素。通过理解这些原理你可以灵活地构建自定义的反向代理解决方案或更好地使用现有工具来暴露内网服务。

相关新闻

C++性能优化实战:从算法到并发,构建系统化优化方法论

C++性能优化实战:从算法到并发,构建系统化优化方法论

1. 项目概述:为什么我们需要一场性能优化的“擂台”?在C的世界里,性能优化从来都不是一个可有可无的选修课,而是每一位严肃开发者必须面对的必修课。无论是开发高频交易系统、游戏引擎、数据库内核,还是嵌入式设备驱动…

2026/7/27 13:16:44阅读更多 →
3步实现开源语音识别:用FunASR构建实时字幕无障碍服务

3步实现开源语音识别:用FunASR构建实时字幕无障碍服务

3步实现开源语音识别:用FunASR构建实时字幕无障碍服务 【免费下载链接】FunASR Open-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving. 项目地…

2026/7/27 13:14:44阅读更多 →
从48V到800V:TI BMS芯片如何应对高压电池管理挑战?

从48V到800V:TI BMS芯片如何应对高压电池管理挑战?

1. 项目概述:为什么BMS是电动汽车的“神经中枢”?如果你拆开一辆电动汽车的电池包,除了密密麻麻的电芯,最核心的“大脑”就是电池管理系统。它干的活,远不止是看看电池还有多少电那么简单。你可以把它想象成一个全天候…

2026/7/27 13:14:44阅读更多 →
OpenAI/Anthropic游说限制中国开源模型,黄仁勋马斯克公开反对

OpenAI/Anthropic游说限制中国开源模型,黄仁勋马斯克公开反对

OpenAI和Anthropic跑去华盛顿,想让美国封掉中国的开源模型 7月26日,《纽约时报》爆出一条消息:OpenAI和Anthropic正在华盛顿游说监管机构,要求限制中国开源AI模型的发展。 他们给出的理由是:某些AI模型"过于危险…

2026/7/27 14:34:56阅读更多 →
Minecraft附魔破解终极指南:3步掌握经验种子破解技巧

Minecraft附魔破解终极指南:3步掌握经验种子破解技巧

Minecraft附魔破解终极指南:3步掌握经验种子破解技巧 【免费下载链接】EnchantmentCracker Cracking the XP seed in Minecraft and choosing your enchantments 项目地址: https://gitcode.com/gh_mirrors/en/EnchantmentCracker 你是否厌倦了在Minecraft中…

2026/7/27 14:34:56阅读更多 →
PyGlove扩展开发:如何自定义符号化类型与进化算子

PyGlove扩展开发:如何自定义符号化类型与进化算子

PyGlove扩展开发:如何自定义符号化类型与进化算子 【免费下载链接】pyglove Manipulating Python Programs 项目地址: https://gitcode.com/gh_mirrors/py/pyglove PyGlove是一个强大的Python程序操作库,允许开发者通过符号化编程和进化算法轻松定…

2026/7/27 14:34:56阅读更多 →
BiliBiliToolPro终极指南:全面解析B站自动化任务工具

BiliBiliToolPro终极指南:全面解析B站自动化任务工具

BiliBiliToolPro终极指南:全面解析B站自动化任务工具 【免费下载链接】BiliBiliToolPro B 站(bilibili)自动任务工具,支持docker、青龙、k8s等多种部署方式。全面拥抱AI。敏感肌也能用。 项目地址: https://gitcode.com/GitHub_…

2026/7/27 14:34:56阅读更多 →
深度学习在数学公式识别中的创新应用

深度学习在数学公式识别中的创新应用

1. 项目概述:数学公式识别的技术挑战与创新 数学公式识别一直是计算机视觉领域最具挑战性的任务之一。与普通OCR(光学字符识别)不同,数学公式具有复杂的二维空间结构,包含上下标、分式、根号等特殊符号排列。传统基于规…

2026/7/27 14:34:56阅读更多 →
pgwire在生产环境中的应用:案例分析与最佳实践

pgwire在生产环境中的应用:案例分析与最佳实践

pgwire在生产环境中的应用:案例分析与最佳实践 【免费下载链接】pgwire PostgreSQL wire protocol implemented as a rust library. 项目地址: https://gitcode.com/gh_mirrors/pg/pgwire pgwire是一个用Rust实现的PostgreSQL wire协议库,它为开发…

2026/7/27 14:32:56阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/27 1:14:34阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/27 1:14:52阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/27 1:14:56阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:24阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:24阅读更多 →
2007-2023年各市区县生态文明建设示范区DID

2007-2023年各市区县生态文明建设示范区DID

数据简介 自改革开放以来,我国依赖高投入、高资源消耗和高污染等传统发展模式实现了经济短期内的快速增长, 然而这也导致了严重的生态环境危机。因此,国家有力于推动企业高质量经济发展,协同生态保护的方针,从而从201…

2026/7/27 0:00:24阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/25 23:03:25阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/26 19:05:21阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/26 19:05:21阅读更多 →