Skip to content

Commit 735d7b7

Browse files
committed
add: init
1 parent 3528375 commit 735d7b7

File tree

8 files changed

+206
-1
lines changed

8 files changed

+206
-1
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
server/go-proxy-server

README.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,33 @@
11
# tls-proxy-go
2-
基于 golang最简单的请求代理根据域名判断, 没有任何加密或者验证纯裸奔, 仅供测试用
2+
3+
基于 golang 最简单的请求代理, 根据域名分流, 没有任何加密或者验证纯裸奔, 仅供测试用
4+
5+
## tls 连接信息
6+
7+
```golang
8+
// 响应200字符串就代表 当客户端和目标服务器之间已经连接成功, 可以进行数据转发了
9+
// 借助 io.Copy 函数在客户端和目标服务器之间进行数据转发
10+
localConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
11+
12+
```
13+
14+
## 说明
15+
16+
- client 客户端运行在本机或软路由或路由器内
17+
- server 是服务端运行在 vps 上
18+
- test.xyz.crt 和 test.xyz.key 是 tls 证书, 随便在那个域名厂商申请或者 acme 免费的域名证书
19+
20+
目前如果程序内写死了 域名信息含 baidu 就走直连 ,如果是 google 就走代理, 应该仅支持 https 没试过 http
21+
没有释放连接,不确定会不会有问题
22+
## 运行
23+
24+
```sh
25+
go run main.go
26+
27+
```
28+
29+
## 编译至 linux
30+
31+
```sh
32+
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o go-proxy-server -trimpath -ldflags "-s -w -buildid=" main.go
33+
```

client/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module tls-proxy
2+
3+
go 1.21.3

client/main.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package main
2+
3+
import (
4+
"crypto/tls"
5+
"fmt"
6+
"io"
7+
"log"
8+
"net"
9+
"strings"
10+
)
11+
12+
var localPort = ":10805" // 本机监听端口
13+
var vpsServerAddr = "10.10.10.10:10888" // 远程vps 对应的地址和端口
14+
var vpsServerName = "test.xyz" // 证书对应的域名
15+
16+
func sendVps(message []byte, localConn net.Conn) {
17+
18+
config := &tls.Config{
19+
InsecureSkipVerify: false, // 跳过证书验证(在生产环境中不建议这样做)
20+
ServerName: vpsServerName, // 证书对应的域名
21+
}
22+
remoteConn, err := tls.Dial("tcp", vpsServerAddr, config)
23+
if err != nil {
24+
log.Println("连接到服务器时出错:", err)
25+
return
26+
}
27+
_, err = remoteConn.Write([]byte(message))
28+
if err != nil {
29+
log.Println("发送消息时出错:", err)
30+
return
31+
}
32+
log.Println("收到服务器响应了, 快点告诉客户端 200")
33+
// 发送 HTTP 200 响应给客户端(代表连接成功可以转发数据了)
34+
localConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
35+
// 启动 goroutine 开始互转
36+
go io.Copy(remoteConn, localConn) // 客户端数据 ==> 目标服务器
37+
go io.Copy(localConn, remoteConn) // 目标服务器 ==> 客户端数据
38+
39+
}
40+
41+
func main() {
42+
// 监听本地 10805
43+
localListener, err := net.Listen("tcp", localPort)
44+
if err != nil {
45+
log.Fatalf("Failed to listen on local port 10901: %v", err)
46+
}
47+
fmt.Println("开始监听" + localPort)
48+
for {
49+
// 接受本地连接
50+
localConn, err := localListener.Accept()
51+
if err != nil {
52+
log.Printf("Failed to accept local connection: %v", err)
53+
continue
54+
}
55+
// 读取本地请求中的目标地址(C 服务器地址)
56+
buf := make([]byte, 1024)
57+
n, err := localConn.Read(buf)
58+
if err != nil {
59+
log.Printf("Failed to read target address from local connection: %v", err)
60+
return
61+
}
62+
// 获取域名地址, 根据请求的域名进行区分
63+
addr := descAddr(string(buf[:n]))
64+
65+
if strings.Contains(addr, "baidu") {
66+
fmt.Println("本地直连==>", addr)
67+
handleConnectRequest(addr, localConn)
68+
}
69+
if strings.Contains(addr, "google") {
70+
fmt.Println("发送代理==>", addr)
71+
sendVps(buf, localConn)
72+
}
73+
}
74+
}
75+
76+
// 解析请求获取目标地址
77+
func descAddr(request string) string {
78+
lines := strings.Split(request, "\n")
79+
firstLine := strings.Split(lines[0], " ")
80+
if len(firstLine) != 3 {
81+
log.Println("无效的请求行")
82+
return ""
83+
}
84+
return firstLine[1]
85+
}
86+
87+
func handleConnectRequest(targetAddr string, localConn net.Conn) {
88+
// 连接到目标服务器
89+
remoteConn, err := net.Dial("tcp", targetAddr)
90+
if err != nil {
91+
log.Printf("连接到目标服务器 %s 时出错: %v", targetAddr, err)
92+
return
93+
}
94+
// 发送 HTTP 200 响应给客户端(代表连接成功可以转发数据了)
95+
localConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
96+
97+
// 启动 goroutine 开始互转
98+
go io.Copy(remoteConn, localConn) // 客户端数据 ==> 目标服务器
99+
go io.Copy(localConn, remoteConn) // 目标服务器 ==> 客户端数据
100+
}

server/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module tls-proxy-server
2+
3+
go 1.21.3

server/main.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"crypto/tls"
5+
"io"
6+
"log"
7+
"net"
8+
"strings"
9+
)
10+
11+
func main() {
12+
// 加载证书和私钥, 域名申请的免费 https 证书
13+
cert, err := tls.LoadX509KeyPair("./test.xyz.crt", "./test.xyz.key")
14+
if err != nil {
15+
log.Fatal("加载证书和私钥时出错:", err)
16+
}
17+
config := &tls.Config{Certificates: []tls.Certificate{cert}}
18+
listener, err := tls.Listen("tcp", ":10888", config)
19+
if err != nil {
20+
log.Fatal("监听端口时出错:", err)
21+
}
22+
log.Println("服务器已启动,等待客户端连接...")
23+
for {
24+
conn, err := listener.Accept()
25+
if err != nil {
26+
log.Println("接受连接时出错:", err)
27+
continue
28+
}
29+
go handleConnectRequest(conn)
30+
}
31+
}
32+
33+
func handleConnectRequest(localConn net.Conn) {
34+
buf := make([]byte, 1024)
35+
n, err := localConn.Read(buf)
36+
if err != nil {
37+
log.Println("读取数据时出错:", err)
38+
return
39+
}
40+
request := string(buf[:n])
41+
42+
// 解析请求获取目标地址
43+
lines := strings.Split(request, "\n")
44+
firstLine := strings.Split(lines[0], " ")
45+
if len(firstLine) != 3 {
46+
log.Println("无效的请求行")
47+
return
48+
}
49+
targetAddr := firstLine[1]
50+
log.Println("目标服务器", targetAddr)
51+
remoteConn, err := net.Dial("tcp", targetAddr)
52+
if err != nil {
53+
log.Printf("连接到目标服务器 %s 时出错: %v", targetAddr, err)
54+
return
55+
}
56+
// 开始转发
57+
go io.Copy(remoteConn, localConn) // 客户端数据 ==> 目标服务器
58+
go io.Copy(localConn, remoteConn) // 目标服务器 ==> 客户端数据
59+
60+
}

server/test.xyz.crt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-----BEGIN CERTIFICATE-----
2+
xxxxidhhhhhhhhssssxxxxxxxxxxxxxx
3+
-----END CERTIFICATE-----

server/test.xyz.key

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
xxxxxxxxxxxxxxxxxxxxxxxxx
3+
-----END RSA PRIVATE KEY-----

0 commit comments

Comments
 (0)