Skip to content

36huo/fls

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flare - 基于 ShadowTLS 的内网穿透工具

项目简介

Flare 是一个基于 ShadowTLS 协议实现的内网穿透工具。通过将流量伪装成正常的 TLS 握手,实现隐蔽的通信通道,支持 TCP 端口转发和 SOCKS5 代理功能。

架构设计

角色定义

  • fls (Server):部署在公网服务器,负责:

    • 监听 ShadowTLS 端口,接收 flc 连接
    • 提供 Web 管理界面(客户端/隧道/代理管理)
    • 监听远程端口(TCP 隧道/SOCKS5 代理)
    • 通过控制通道下发任务指令给 flc
    • 中继外部流量与 flc 之间的数据
  • flc (Client):部署在内网,负责:

    • 主动连接 fls 建立控制长连接
    • 接收 fls 下发的任务指令(隧道连接/代理连接)
    • 按需建立数据连接,转发到内网目标服务

双连接模式

Flare 采用控制与数据分离的设计:

  1. 控制连接(长连接):flc 启动时建立,用于注册身份、维持心跳、接收任务指令。
  2. 数据连接(按需建立):收到任务指令后,flc 新建连接连向 fls,专门用于实际业务数据转发。转发完成后断开,不影响控制连接。

优势:解耦控制指令与大数据流量,避免大流量阻塞控制通道;flc 无需预先知道隧道配置,完全由 fls 动态调度。

代码框架

flare/
├── bin/                  # 编译后的可执行文件
│   ├── flc / flc.exe     # Linux / Windows 客户端
│   └── fls / fls.exe     # Linux / Windows 服务端
├── flc/
│   └── main.go           # 客户端核心逻辑
├── fls/
│   ├── main.go           # 服务端核心逻辑
│   └── web/              # Web 管理界面模板
│       ├── static/       # CSS/JS 静态资源
│       └── views/        # HTML 模板
├── protocol/
│   └── protocol.go       # 通信协议定义(Frame/Message)
├── go.mod
└── go.sum

关键模块说明

  • protocol/protocol.go:定义通信帧结构(FrameHeader + Payload)和消息类型。
  • fls/main.go
    • Server 结构体:管理客户端、隧道、代理、连接池、数据库等状态。
    • runShadowTLS:启动 ShadowTLS 服务,接收 flc 连接。
    • handleControlConnection:处理 flc 注册、心跳、任务响应。
    • relayRemoteToClient:处理外部流量,下发任务给 flc,等待数据连接并中继。
    • handleSocks5Connection:处理 SOCKS5 代理握手,解析目标地址,下发任务。
    • loadDataFromDB:启动时从 SQLite 加载配置并恢复监听。
  • flc/main.go
    • Client 结构体:管理控制连接状态。
    • connectControl:建立并维持控制长连接。
    • handleControlMessages:接收并处理 fls 下发的任务指令。
    • handleTunnelConnect / handleProxyConnect:建立数据连接并转发到内网目标。

核心业务流程

1. flc 启动与注册

  1. flc 通过 ShadowTLS 协议连接 fls。
  2. 发送 MsgClientRegister 携带 ClientID。
  3. fls 验证 ClientID 是否存在于数据库,返回 MsgClientRegisterAck
  4. flc 进入心跳循环,等待任务指令。

2. TCP 隧道穿透

  1. 外部用户连接 fls 的远程监听端口。
  2. fls 查找隧道配置,获取关联的 ClientID 和内网目标地址。
  3. fls 通过控制通道发送 MsgTunnelConnect(携带 TunnelID + LocalAddr)。
  4. flc 收到指令,新建 ShadowTLS 数据连接连向 fls,发送 Frame 头(TunnelID)。
  5. flc 连接内网目标服务(LocalAddr)。
  6. fls 将外部连接与 flc 数据连接加入连接池,开始双向中继。

3. SOCKS5 代理

  1. 外部代理客户端连接 fls 的代理监听端口。
  2. fls 完成 SOCKS5 握手(支持无认证/密码认证),解析目标地址。
  3. fls 通过控制通道发送 MsgProxyConnect(携带 ProxyID + TargetAddr)。
  4. flc 收到指令,新建 ShadowTLS 数据连接连向 fls,发送 Frame 头(ProxyID)。
  5. flc 连接目标地址(TargetAddr)。
  6. fls 将代理连接与 flc 数据连接加入连接池,开始双向中继。

4. flc 重连处理

  1. flc 断开重连时,fls 检测到旧连接存在。
  2. fls 主动关闭旧连接,清理其残留的数据连接池。
  3. 新连接接管,恢复服务。
  4. 断开清理时增加 client.Conn == conn 判断,防止旧连接清理逻辑误杀新连接。

协议设计

Frame 结构

[ TunnelID (4 bytes) | DataLen (4 bytes) | Payload (DataLen bytes) ]
  • TunnelID = 0:控制通道消息。
  • TunnelID > 0:数据通道连接,标识所属隧道/代理。

消息类型

类型 方向 说明
MsgClientRegister flc -> fls 客户端注册
MsgClientRegisterAck fls -> flc 注册响应
MsgHeartbeat flc -> fls 心跳
MsgHeartbeatAck fls -> flc 心跳响应
MsgTunnelConnect fls -> flc 隧道连接任务(携带 TunnelID + LocalAddr)
MsgProxyConnect fls -> flc 代理连接任务(携带 ProxyID + TargetAddr)

编译与部署

编译命令

# Linux
GOOS=linux GOARCH=amd64 go build -o bin/fls ./fls
GOOS=linux GOARCH=amd64 go build -o bin/flc ./flc

# Windows
GOOS=windows GOARCH=amd64 go build -o bin/fls.exe ./fls
GOOS=windows GOARCH=amd64 go build -o bin/flc.exe ./flc

打包

rm -rf dist && mkdir -p dist/bin
cp bin/* dist/bin/
cp -r fls/web dist/
tar -czvf flare.tar.gz -C dist .

启动示例

# fls (公网)
./bin/fls -listen :4436 -tls cloud.tencent.com -web :8080 -web-password admin123

# flc (内网)
./bin/flc -server <公网IP>:4436 -password <分配的密码> -sni cloud.tencent.com -id <分配的ID>

开发注意事项

  1. WaitGroup 安全:双向中继使用 sync.Once 确保 closeBoth 只执行一次,防止重复关闭连接导致 panic。
  2. 连接池清理:flc 重连时必须清理旧连接池,但不删除 map 中的 key,确保监听端口继续正常工作。
  3. 数据库持久化:使用 gorm + sqlite(纯 Go 实现,无需 CGO)。结构体中 Conn net.Conn 必须加 gorm:"-" 标签。
  4. 日志标签:使用 [Main], [Control], [Relay], [Proxy], [Tunnel] 等标签区分模块,便于排查问题。
  5. Web 模板:前端文件位于 fls/web/,修改后重启 fls 生效。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors