基于Asyncio Streams的Python通道能否转发多TCP端口且不被软件察觉?
基于Asyncio Streams实现多TCP端口连接的透明转发
完全可以实现,核心是搭建一个透明代理中转层,用Asyncio Streams处理两端的连接和数据转发,让原客户端、服务器完全感知不到中间通道的存在。
核心实现思路
- 客户端侧中转:监听原服务器对外暴露的所有TCP端口,当原客户端发起连接时,将这个连接的流量转发到你的Asyncio Streams通道。
- 服务器侧中转:从通道接收转发请求,根据请求中的端口信息,建立与原服务器对应端口的连接,再将流量反向转发回去。
- 双向透传:中转层只负责原样转发字节流,不修改任何数据,保证原客户端和服务器的通信逻辑完全不受影响。
简化代码示例
客户端侧中转(对接原客户端)
这个程序会监听原服务器的多个端口,把客户端连接转发到通道服务器:
import asyncio async def bidirectional_forward(src_reader, dst_writer, reverse_reader, reverse_writer): """双向转发数据的核心函数""" async def pipe(reader, writer): try: while chunk := await reader.read(4096): writer.write(chunk) await writer.drain() except Exception: # 连接断开或出错时关闭两端 pass finally: writer.close() await writer.wait_closed() # 同时启动两个方向的数据转发 await asyncio.gather( pipe(src_reader, dst_writer), pipe(reverse_reader, reverse_writer) ) async def handle_client_connection(client_reader, client_writer): """处理原客户端的连接请求""" # 先获取当前监听的端口(用来告诉通道服务器要转发到原服务器的哪个端口) local_port = client_writer.get_extra_info('sockname')[1] # 连接到你的Asyncio Streams通道服务器 channel_reader, channel_writer = await asyncio.open_connection('通道服务器IP', 9000) # 先把要转发的目标端口发送给通道服务器(用2字节的大端序编码) channel_writer.write(local_port.to_bytes(2, byteorder='big')) await channel_writer.drain() # 开始双向转发数据 await bidirectional_forward(client_reader, channel_writer, channel_reader, client_writer) async def main(): # 原服务器对外的端口列表 target_ports = [8000, 8001, 8002] servers = [] # 逐个监听端口 for port in target_ports: server = await asyncio.start_server( handle_client_connection, '0.0.0.0', # 允许所有客户端连接 port ) servers.append(server) print(f"已监听端口 {port}") # 同时运行所有监听服务 async with asyncio.TaskGroup() as tg: for server in servers: tg.create_task(server.serve_forever()) if __name__ == "__main__": asyncio.run(main())
服务器侧中转(对接原服务器)
这个程序从通道接收请求,连接原服务器对应端口并转发流量:
import asyncio async def bidirectional_forward(src_reader, dst_writer, reverse_reader, reverse_writer): """复用双向转发函数""" async def pipe(reader, writer): try: while chunk := await reader.read(4096): writer.write(chunk) await writer.drain() except Exception: pass finally: writer.close() await writer.wait_closed() await asyncio.gather( pipe(src_reader, dst_writer), pipe(reverse_reader, reverse_writer) ) async def handle_channel_connection(channel_reader, channel_writer): """处理来自通道的转发请求""" # 先读取要转发到原服务器的端口 port_bytes = await channel_reader.read(2) if not port_bytes: channel_writer.close() await channel_writer.wait_closed() return target_port = int.from_bytes(port_bytes, byteorder='big') # 连接到原服务器的对应端口 try: server_reader, server_writer = await asyncio.open_connection('原服务器IP', target_port) except Exception: # 连接原服务器失败,关闭通道连接 channel_writer.close() await channel_writer.wait_closed() return # 开始双向转发数据 await bidirectional_forward(channel_reader, server_writer, server_reader, channel_writer) async def main(): # 启动通道服务器,监听指定端口 server = await asyncio.start_server( handle_channel_connection, '0.0.0.0', 9000 # 通道的监听端口 ) print("通道中转服务器已启动") async with server: await server.serve_forever() if __name__ == "__main__": asyncio.run(main())
关键注意事项
- 端口映射逻辑:示例中通过握手阶段传递端口号来确定转发目标,实际可以根据需求优化(比如固定端口映射表、动态协商等)。
- 透传完整性:确保所有TCP字节流原样转发,包括SYN、ACK等握手包,不要修改任何数据内容。
- 异常处理:补充完善连接断开、超时、连接失败等场景的错误处理,避免中转层崩溃影响所有连接。
- 性能优化:调整读取缓冲区大小(示例中用4096字节),根据实际流量情况适配,Asyncio的异步模型本身能较好处理高并发连接。
内容的提问来源于stack exchange,提问作者Bdfy
相关产品推荐
相关产品推荐

