149 lines
4.1 KiB
Markdown
149 lines
4.1 KiB
Markdown
# SNI 代理
|
||
|
||
这是一个基于 Go 语言实现的 SNI 代理,支持 TLS 分片功能和多种域名匹配方法。
|
||
|
||
## 功能特点
|
||
|
||
- 直接使用 SNI 域名作为目标地址
|
||
- 支持多种 DNS 协议解析域名(UDP/TCP/DoT/DoH/DoQ)
|
||
- 支持 TLS 分片(可配置分片大小范围)
|
||
- 多种域名匹配方式:
|
||
- 正则表达式匹配
|
||
- 后缀匹配
|
||
- 关键词匹配
|
||
- 完善的超时控制和连接管理
|
||
- 基于配置文件的灵活配置
|
||
|
||
## 安装
|
||
|
||
### 从源码构建
|
||
|
||
```bash
|
||
# 克隆仓库
|
||
git clone https://github.com/yourusername/SNI_Proxy.git
|
||
cd SNI_Proxy
|
||
|
||
# 安装依赖
|
||
go mod tidy
|
||
|
||
# 构建
|
||
go build -o sni_proxy
|
||
```
|
||
|
||
## 使用方法
|
||
|
||
1. 创建配置文件 `config.yaml`(参考示例配置文件)
|
||
2. 运行代理服务器:
|
||
|
||
```bash
|
||
./sni_proxy -config config.yaml
|
||
```
|
||
|
||
## 配置文件说明
|
||
|
||
配置文件使用 YAML 格式,包含以下主要部分:
|
||
|
||
```yaml
|
||
# 监听地址
|
||
listen: "0.0.0.0:443"
|
||
|
||
# 默认目标端口
|
||
default_port: 443
|
||
|
||
# DNS解析器配置
|
||
dns:
|
||
protocol: "udp" # 支持 udp, tcp, dot, doh, doq
|
||
server: "8.8.8.8:53" # DNS服务器地址
|
||
timeout: 5 # 超时时间(秒)
|
||
|
||
# 超时配置
|
||
timeout:
|
||
connect: 10 # 连接超时(秒)
|
||
read: 30 # 读取超时(秒)
|
||
write: 5 # 写入超时(秒)
|
||
idle: 60 # 空闲超时(秒)
|
||
lifetime: 300 # 连接最大生命周期(秒)
|
||
|
||
# 日志级别: debug, info, warn, error
|
||
log_level: "info"
|
||
|
||
# 最大并发连接数
|
||
max_conns: 1000
|
||
|
||
# 代理规则
|
||
rules:
|
||
# 规则示例
|
||
- domains:
|
||
- type: regexp # 支持 regexp, suffix, keyword
|
||
value: "^api\\.example\\.com$"
|
||
port: 443 # 目标端口
|
||
fragment:
|
||
enabled: true # 是否启用 TLS 分片
|
||
min_size: 100 # 最小分片大小
|
||
max_size: 500 # 最大分片大小
|
||
```
|
||
|
||
### 工作原理
|
||
|
||
1. 代理服务器接收客户端的 TLS 连接
|
||
2. 从 ClientHello 消息中提取 SNI(服务器名称指示)
|
||
3. 根据配置的规则匹配 SNI 域名
|
||
4. 使用配置的 DNS 解析器将 SNI 域名解析为 IP 地址
|
||
5. 使用解析得到的 IP 地址和配置的端口连接到目标服务器
|
||
6. 将客户端的请求转发到目标服务器,可选择进行 TLS 分片
|
||
|
||
### 域名匹配方式
|
||
|
||
1. **正则表达式匹配** (`regexp`):使用正则表达式匹配域名
|
||
2. **后缀匹配** (`suffix`):匹配指定后缀的域名
|
||
3. **关键词匹配** (`keyword`):匹配包含指定关键词的域名
|
||
|
||
### DNS 解析器配置
|
||
|
||
- `protocol`: DNS 协议类型,支持以下选项:
|
||
- `udp`: 标准 UDP DNS(默认)
|
||
- `tcp`: 标准 TCP DNS
|
||
- `dot`: DNS over TLS
|
||
- `doh`: DNS over HTTPS
|
||
- `doq`: DNS over QUIC(目前不支持)
|
||
- `server`: DNS 服务器地址,格式为 `IP:端口`
|
||
- `timeout`: DNS 查询超时时间(秒)
|
||
|
||
### 超时和连接管理配置
|
||
|
||
- `timeout`: 超时配置
|
||
- `connect`: 连接目标服务器的超时时间(秒)
|
||
- `read`: 读取数据的超时时间(秒)
|
||
- `write`: 写入数据的超时时间(秒)
|
||
- `idle`: 空闲连接的超时时间(秒)
|
||
- `lifetime`: 连接的最大生命周期(秒)
|
||
- `log_level`: 日志级别,支持 debug、info、warn、error
|
||
- `max_conns`: 最大并发连接数,超过此数量的新连接将被拒绝
|
||
|
||
### TLS 分片配置
|
||
|
||
- `enabled`: 是否启用 TLS 分片
|
||
- `min_size`: 最小分片大小(字节)
|
||
- `max_size`: 最大分片大小(字节)
|
||
|
||
## 性能优化
|
||
|
||
为了避免进程卡死和资源泄漏,本代理实现了以下优化:
|
||
|
||
1. **完善的超时控制**:为每个连接阶段设置合理的超时时间
|
||
2. **连接生命周期管理**:限制连接的最大生存时间
|
||
3. **连接数量限制**:防止过多连接导致资源耗尽
|
||
4. **空闲连接清理**:定期清理空闲连接
|
||
5. **错误处理优化**:优化常见网络错误的处理方式
|
||
6. **资源使用监控**:定期记录连接统计信息
|
||
|
||
## 注意事项
|
||
|
||
- 本程序需要以 root 权限运行才能监听 443 端口
|
||
- 确保目标服务器地址可达
|
||
- 正则表达式需要使用有效的 Go 语言正则表达式语法
|
||
- 适当调整超时和连接管理参数,以适应不同的网络环境
|
||
|
||
## 许可证
|
||
|
||
MIT |