Skip to content

Commit 851241a

Browse files
author
刘河
committed
新功能+bug修复
1 parent bb882f3 commit 851241a

File tree

17 files changed

+385
-169
lines changed

17 files changed

+385
-169
lines changed

README.md

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# easyProxy
22
![](https://img.shields.io/github/stars/cnlh/easyProxy.svg) ![](https://img.shields.io/github/forks/cnlh/easyProxy.svg) ![](https://img.shields.io/github/license/cnlh/easyProxy.svg)
33

4-
easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**代理服务器。目前支持**tcp、udp流量转发**,可支持任何tcp、udp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面,内网dns解析等等……),此外还**支持内网http代理、内网socks5代理**,可实现在非内网环境下如同使用vpn一样访问内网资源和设备的效果,同时**支持socks5验证,snnapy压缩(节省带宽和流量)、站点保护、加密传输、多路复用**
4+
easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**代理服务器。目前支持**tcp、udp流量转发**,可支持任何tcp、udp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面,内网dns解析等等……),此外还**支持内网http代理、内网socks5代理**,可实现在非内网环境下如同使用vpn一样访问内网资源和设备的效果,同时**支持socks5验证,snnapy压缩(节省带宽和流量)、站点保护、加密传输、多路复用、host修改、自定义header**
55

66
目前市面上提供类似服务的有花生壳、TeamView、GoToMyCloud等等,但要使用第三方的公网服务器就必须为第三方付费,并且这些服务都有各种各样的限制,此外,由于数据包会流经第三方,因此对数据安全也是一大隐患。
77

@@ -36,6 +36,8 @@ easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**
3636
- [x] 支持TCP多路复用
3737
- [x] 支持同时开多条tcp、udp隧道等等,且只需要开一个客户端和服务端
3838
- [x] 支持一个服务端,多个客户端模式
39+
- [x] host修改支持
40+
- [x] 自定义设置header支持
3941

4042
## 目录
4143

@@ -49,7 +51,10 @@ easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**
4951
8. [站点密码保护](#站点保护)
5052
9. [加密传输](#加密传输)
5153
10. [TCP多路复用](#多路复用)
52-
11. [配置文件说明](#配置文件)
54+
11. [host修改](#host修改)
55+
12. [自定义header](#自定义header)
56+
13. [获取用户真实 IP](#获取用户真实 IP)
57+
5358

5459
## 安装
5560

@@ -62,20 +67,32 @@ easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**
6267
- 安装源码
6368
> go get github.com/cnlh/easyProxy
6469
- 编译
65-
> go build cmd/proxy_server.go
66-
> go build cmd/proxy_client.go
70+
> go build cmd/server/proxy_server.go
71+
72+
> go build cmd/client/proxy_client.go
6773
6874
## web管理模式
6975

7076
![image](https://github.com/cnlh/easyProxy/blob/master/image/web2.png?raw=true)
7177
### 介绍
7278

7379
可在网页上配置和管理各个tcp、udp隧道、内网站点代理等等,功能极为强大,操作也非常方便。
80+
### 服务端配置文件
81+
- /conf/app.conf
82+
83+
名称 | 含义
84+
---|---
85+
httpport | web管理端口
86+
password | web界面管理密码
87+
hostPort | 域名代理模式监听端口
88+
tcpport | 服务端客户端通信端口
7489

7590
**提示:使用web模式时,服务端执行文件必须在项目根目录,否则无法正确加载配置文件**
7691

7792
### 使用
7893

94+
95+
7996
**有两种模式:**
8097

8198
1、单客户端模式,所有的隧道流量均从这个单客户端转发。
@@ -84,13 +101,11 @@ easyProxy是一款轻量级、高性能、功能最为强大的**内网穿透**
84101
- 服务端
85102

86103
```
87-
./proxy_server -mode=webServer -tcpport=8284 -vkey=DKibZF5TXvic1g3kY
104+
./proxy_server -vkey=DKibZF5TXvic1g3kY
88105
```
89106
名称 | 含义
90107
---|---
91-
mode | 运行模式
92108
vkey | 验证密钥
93-
tcpport | 服务端与客户端通信端口
94109

95110

96111
- 客户端
@@ -100,20 +115,19 @@ tcpport | 服务端与客户端通信端口
100115
```
101116
- 配置
102117

103-
进入web界面,公网ip:web界面端口(默认8080),密码为123
118+
进入web界面,公网ip:web界面端口(默认8080),密码默认为123
104119

105120
2、多客户端模式,不同的隧道流量均从不同的客户端转发。
106121

107122

108123
- 服务端
109124

110125
```
111-
./proxy_server -mode=webServer -tcpport=8284
126+
./proxy_server
112127
```
113128
名称 | 含义
114129
---|---
115130
mode | 运行模式
116-
tcpport | 服务端与客户端通信端口
117131
- 客户端
118132

119133
进入web管理界面,有详细的命令
@@ -124,7 +138,6 @@ tcpport | 服务端与客户端通信端口
124138

125139

126140

127-
128141
## tcp隧道模式
129142

130143
### 场景及原理
@@ -354,16 +367,22 @@ easyProxy支持通过 HTTP Basic Auth 来保护你的 web 服务,使用户需
354367

355368
web管理中也可配置
356369

370+
## host修改
357371

358372

359-
## 配置文件
360-
- /conf/app.conf
373+
通常情况下本代理不会修改转发的任何数据。但有一些后端服务会根据 http 请求 header 中的 host 字段来展现不同的网站,例如 nginx 的虚拟主机服务,启用 host-header 的修改功能可以动态修改 http 请求中的 host 字段。该功能仅限于域名代理模式。
361374

362-
名称 | 含义
363-
---|---
364-
httpport | web管理端口
365-
password | web界面管理密码
366-
hostPort | 域名代理模式监听端口
375+
**使用方法:在web管理中设置**
376+
377+
## 自定义header
378+
379+
支持对header进行新增或者修改,以配合服务的需要
380+
381+
## 获取用户真实 IP
382+
383+
目前只有域名模式的代理支持这一功能,可以通过用户请求的 header 中的 X-Forwarded-For 和 X-Real-IP 来获取用户真实 IP。
384+
385+
**本代理前会在每一个请求中添加了这两个 header。**
367386

368387

369388
## 操作系统支持

bridge/bridge.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ func (s *Tunnel) cliProcess(c *utils.Conn) error {
9292
s.verifyError(c)
9393
return errors.New("验证错误")
9494
}
95-
log.Println("客户端连接成功: ", c.Conn.RemoteAddr())
9695
c.Conn.(*net.TCPConn).SetReadDeadline(time.Time{})
9796
//做一个判断 添加到对应的channel里面以供使用
9897
if flag, err := c.ReadFlag(); err != nil {
@@ -106,6 +105,7 @@ func (s *Tunnel) cliProcess(c *utils.Conn) error {
106105
func (s *Tunnel) typeDeal(typeVal string, c *utils.Conn, cFlag string) error {
107106
switch typeVal {
108107
case utils.WORK_MAIN:
108+
log.Println("客户端连接成功", c.Conn.RemoteAddr())
109109
s.addList(s.SignalList, c, cFlag)
110110
case utils.WORK_CHAN:
111111
s.addList(s.TunnelList, c, cFlag)
@@ -131,14 +131,13 @@ func (s *Tunnel) addList(m map[string]*list, c *utils.Conn, cFlag string) {
131131

132132
//新建隧道
133133
func (s *Tunnel) newChan(cFlag string) error {
134-
if err := s.wait(s.SignalList, cFlag); err != nil {
134+
var connPass *utils.Conn
135+
var err error
136+
retry:
137+
if connPass, err = s.waitAndPop(s.SignalList, cFlag); err != nil {
135138
return err
136139
}
137-
retry:
138-
connPass := s.SignalList[cFlag].Pop()
139-
_, err := connPass.Conn.Write([]byte("chan"))
140-
if err != nil {
141-
log.Println(err)
140+
if _, err = connPass.Conn.Write([]byte("chan")); err != nil {
142141
goto retry
143142
}
144143
s.SignalList[cFlag].Add(connPass)
@@ -152,10 +151,9 @@ func (s *Tunnel) GetTunnel(cFlag string, en, de int, crypt, mux bool) (c *utils.
152151
go s.newChan(cFlag)
153152
}
154153
retry:
155-
if err = s.wait(s.TunnelList, cFlag); err != nil {
154+
if c, err = s.waitAndPop(s.TunnelList, cFlag); err != nil {
156155
return
157156
}
158-
c = s.TunnelList[cFlag].Pop()
159157
if _, err = c.WriteTest(); err != nil {
160158
c.Close()
161159
goto retry
@@ -212,22 +210,26 @@ func (s *Tunnel) delClient(cFlag string, l map[string]*list) {
212210
}
213211

214212
//等待
215-
func (s *Tunnel) wait(m map[string]*list, cFlag string) error {
213+
func (s *Tunnel) waitAndPop(m map[string]*list, cFlag string) (c *utils.Conn, err error) {
216214
ticker := time.NewTicker(time.Millisecond * 100)
217215
stop := time.After(time.Second * 10)
218-
loop:
219216
for {
220217
select {
221218
case <-ticker.C:
222-
if _, ok := m[cFlag]; ok {
219+
s.lock.Lock()
220+
if v, ok := m[cFlag]; ok && v.Len() > 0 {
221+
c = v.Pop()
223222
ticker.Stop()
224-
break loop
223+
s.lock.Unlock()
224+
return
225225
}
226+
s.lock.Unlock()
226227
case <-stop:
227-
return errors.New("client key: " + cFlag + ",err: get client conn timeout")
228+
err = errors.New("client key: " + cFlag + ",err: get client conn timeout")
229+
return
228230
}
229231
}
230-
return nil
232+
return
231233
}
232234

233235
func (s *Tunnel) verify(vKeyMd5 string) bool {

client/client.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,5 @@ func Process(c *utils.Conn, typeStr, host string, en, de int, crypt, mux bool) {
122122
return
123123
}
124124
c.WriteSuccess()
125-
go utils.Relay(server, c.Conn, de, crypt, mux)
126-
utils.Relay(c.Conn, server, en, crypt, mux)
125+
utils.ReplayWaitGroup(c.Conn, server, en, de, crypt, mux)
127126
}

cmd/proxy_client/proxy_client.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ var (
1414

1515
func main() {
1616
flag.Parse()
17-
//go func() {
18-
// http.ListenAndServe("0.0.0.0:8899", nil)
19-
//}()
2017
stop := make(chan int)
2118
for _, v := range strings.Split(*verifyKey, ",") {
2219
log.Println("客户端启动,连接:", *serverAddr, " 验证令牌:", v)

cmd/proxy_server/proxy_server.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ package main
22

33
import (
44
"flag"
5+
"github.com/astaxie/beego"
56
"github.com/cnlh/easyProxy/server"
67
"github.com/cnlh/easyProxy/utils"
78
_ "github.com/cnlh/easyProxy/web/routers"
89
"log"
910
)
1011

1112
var (
12-
configPath = flag.String("config", "config.json", "配置文件路径")
13-
TcpPort = flag.Int("tcpport", 8284, "客户端与服务端通信端口")
13+
TcpPort = flag.Int("tcpport", 0, "客户端与服务端通信端口")
1414
httpPort = flag.Int("httpport", 8024, "对外监听的端口")
15-
rpMode = flag.String("mode", "client", "启动模式")
15+
rpMode = flag.String("mode", "webServer", "启动模式")
1616
tunnelTarget = flag.String("target", "10.1.50.203:80", "远程目标")
1717
VerifyKey = flag.String("vkey", "", "验证密钥")
1818
u = flag.String("u", "", "验证用户名(socks5和web)")
@@ -42,6 +42,15 @@ func main() {
4242
CompressEncode: 0,
4343
CompressDecode: 0,
4444
}
45+
if *TcpPort == 0 {
46+
p, err := beego.AppConfig.Int("tcpport")
47+
if err == nil && *rpMode == "webServer" {
48+
*TcpPort = p
49+
} else {
50+
*TcpPort = 8284
51+
}
52+
}
53+
log.SetFlags(log.Lshortfile)
4554
cnf.CompressDecode, cnf.CompressEncode = utils.GetCompressType(cnf.Compress)
4655
server.StartNewServer(*TcpPort, &cnf)
4756
}

conf/app.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ password=123
1111

1212
#http监听端口
1313
hostPort=80
14+
15+
##客户端与服务端通信端口
16+
tcpport=8284

conf/hosts.csv

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
b.proxy.com,127.0.0.1:82,o2430bnq22jgnmcl
2-
b.o.com,127.0.0.1:88,ts08z6vk5nc72fs8
3-
a.o.com,127.0.0.1:88,7n7bxc2bm1fyjfab
1+
a.o.com,127.0.0.1:8082,7hiixust68kbz33a,,www.baidu.com
2+
b.o.com,,7hiixust68kbz33a,,ab

0 commit comments

Comments
 (0)