124 lines
2.7 KiB
Plaintext
124 lines
2.7 KiB
Plaintext
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
"golang.org/x/net/proxy"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
)
|
|
|
|
const (
|
|
localAddr = "127.0.0.1:1080" // 本地监听地址
|
|
remoteAddr = "jpgmo101-cdn-route.couldflare-cdn.com:443"
|
|
username = "mrwdfNTD8M79LCukCieldrqZWqs="
|
|
password = "exaxgqkKkd0TAMrCxeonWg=="
|
|
)
|
|
|
|
func main() {
|
|
listener, err := net.Listen("tcp", localAddr)
|
|
if err != nil {
|
|
log.Fatalf("无法启动本地监听: %v", err)
|
|
}
|
|
defer listener.Close()
|
|
|
|
fmt.Printf("SOCKS5 代理服务器正在监听 %s\n", localAddr)
|
|
|
|
for {
|
|
client, err := listener.Accept()
|
|
if err != nil {
|
|
log.Printf("接受连接错误: %v", err)
|
|
continue
|
|
}
|
|
go handleConnection(client)
|
|
}
|
|
}
|
|
|
|
func handleConnection(client net.Conn) {
|
|
defer client.Close()
|
|
|
|
// 创建到远程服务器的认证信息
|
|
auth := proxy.Auth{
|
|
User: username,
|
|
Password: password,
|
|
}
|
|
|
|
// 连接远程服务器
|
|
dialer, err := proxy.SOCKS5("tcp", remoteAddr, &auth, proxy.Direct)
|
|
if err != nil {
|
|
log.Printf("创建代理连接失败: %v", err)
|
|
return
|
|
}
|
|
|
|
// 处理 SOCKS5 协议
|
|
if err := handleSocks5(client, dialer); err != nil {
|
|
log.Printf("处理 SOCKS5 协议失败: %v", err)
|
|
}
|
|
}
|
|
|
|
func handleSocks5(client net.Conn, dialer proxy.Dialer) error {
|
|
// SOCKS5 握手
|
|
buf := make([]byte, 2)
|
|
if _, err := client.Read(buf); err != nil {
|
|
return fmt.Errorf("读取版本标识符失败: %v", err)
|
|
}
|
|
|
|
// 检查是否是 SOCKS5
|
|
if buf[0] != 0x05 {
|
|
return fmt.Errorf("不支持的 SOCKS 版本: %d", buf[0])
|
|
}
|
|
|
|
// 不需要认证
|
|
client.Write([]byte{0x05, 0x00})
|
|
|
|
// 读取请求
|
|
buf = make([]byte, 4)
|
|
if _, err := client.Read(buf); err != nil {
|
|
return fmt.Errorf("读取请求失败: %v", err)
|
|
}
|
|
|
|
// 获取目标地址
|
|
var targetAddr string
|
|
switch buf[3] {
|
|
case 0x01: // IPv4
|
|
addr := make([]byte, 4)
|
|
client.Read(addr)
|
|
targetAddr = net.IP(addr).String()
|
|
case 0x03: // 域名
|
|
var length byte
|
|
client.Read([]byte{length})
|
|
addr := make([]byte, length)
|
|
client.Read(addr)
|
|
targetAddr = string(addr)
|
|
case 0x04: // IPv6
|
|
addr := make([]byte, 16)
|
|
client.Read(addr)
|
|
targetAddr = net.IP(addr).String()
|
|
}
|
|
|
|
// 读取端口
|
|
var port uint16
|
|
binary.Read(client, binary.BigEndian, &port)
|
|
targetAddr = fmt.Sprintf("%s:%d", targetAddr, port)
|
|
|
|
// 连接目标服务器
|
|
target, err := dialer.Dial("tcp", targetAddr)
|
|
if err != nil {
|
|
client.Write([]byte{0x05, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
|
return fmt.Errorf("连接目标服务器失败: %v", err)
|
|
}
|
|
defer target.Close()
|
|
|
|
// 发送成功响应
|
|
client.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
|
|
|
// 开始转发数据
|
|
go func() {
|
|
io.Copy(target, client)
|
|
}()
|
|
io.Copy(client, target)
|
|
|
|
return nil
|
|
}
|