Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
97
README.md
97
README.md
@ -1,32 +1,83 @@
|
||||
<img src="https://github.com/snail007/goproxy/blob/master/docs/images/logo.jpg?raw=true" width="200"/>
|
||||
Proxy是golang实现的高性能http,https,websocket,tcp代理服务器.
|
||||
Proxy是golang实现的高性能http,https,websocket,tcp,udp代理服务器,支持正向代理和反响代理(即:内网穿透).
|
||||
<hr/>
|
||||
|
||||
[](https://github.com/snail007/goproxy/) []() [](https://github.com/snail007/goproxy/releases) [](https://github.com/snail007/goproxy/releases)
|
||||
|
||||
**1.开始代理,使用本地端口38080.**
|
||||
`./proxy -p 38080`
|
||||
**2.作为二级代理,使用本地端口8090,假设上级http代理是`22.22.22.22:8080`**
|
||||
`./proxy -P "22.22.22.22:8080" -p 8090`
|
||||
**3.生成加密通讯需要的证书和密钥**
|
||||
### 0.生成加密通讯需要的证书文件
|
||||
http,tcp,udp代理过程会和上级通讯,为了安全我们采用加密通讯,当然可以选择不加密通信通讯,本教程所有和上级通讯都采用加密,需要证书文件.
|
||||
在linux上并安装了openssl命令,可以直接通过下面的命令生成证书和key文件.
|
||||
`./proxy keygen`
|
||||
会在当前目录下面生成一个证书文件proxy.crt和key文件proxy.key。
|
||||
**4.一级和二级代理加密通讯.**
|
||||
一级代理(VPS,IP:22.22.22.22)
|
||||
`./proxy -x -p 38080 -c proxy.crt -k proxy.key`
|
||||
二级代理(本地)
|
||||
`./proxy -X -P "22.22.22.22:38080" -p 8080 -c proxy.crt -k proxy.key`
|
||||
默认会使用程序相同目录下面的证书文件proxy.crt和key文件proxy.key。
|
||||
### 1.HTTP代理
|
||||
**1.1.普通HTTP代理**
|
||||
`./proxy http -t tcp -p "0.0.0.0:38080"`
|
||||
**1.2.普通二级HTTP代理,使用本地端口8090,假设上级HTTP代理是`22.22.22.22:8080`**
|
||||
`./proxy http -t tcp -p "0.0.0.0:8090" -T tcp -P "22.22.22.22:8080" `
|
||||
默认开启了连接池,如果为了网络情况很好,-L可以关闭连接池,0就是连接池大小,0为关闭.
|
||||
`./proxy http -t tcp -p "0.0.0.0:8090" -T tcp -P "22.22.22.22:8080" -L 0`
|
||||
我们还可以指定网站域名的黑白名单文件,一行一个域名,怕匹配规则是最右批评匹配,比如:baidu.com,匹配的是*.*.baidu.com,黑名单的域名域名直接走上级代理,白名单的域名不走上级代理.
|
||||
`./proxy http -p "0.0.0.0:8090" -T tcp -P "22.22.22.22:8080" -b blocked.txt -d direct.txt`
|
||||
**1.3.HTTP二级代理(加密)**
|
||||
一级HTTP代理(VPS,IP:22.22.22.22)
|
||||
`./proxy http -t tls -p ":38080" -C proxy.crt -K proxy.key`
|
||||
二级HTTP代理(本地)
|
||||
`./proxy http -t tcp -p ":8080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
那么访问本地的8080端口就是访问VPS上面的代理端口38080.
|
||||
**5.TCP隧道**
|
||||
VPS,IP:22.22.22.22
|
||||
`./proxy --tcp -P "127.0.0.1:22" -x -p 22022 -c proxy.crt -k proxy.key`
|
||||
本地
|
||||
`./proxy --tcp -X -P "22.22.22.22:22022" -p 12222 -c proxy.crt -k proxy.key`
|
||||
那么服务本地的12222端口就是通过加密隧道安全的访问vps的本地22端口.
|
||||
|
||||
[图文教程](docs/faststart.md)
|
||||
|
||||
**1.4.HTTP三级代理(加密)**
|
||||
一级HTTP代理VPS_01,IP:22.22.22.22
|
||||
`./proxy http -t tls -p ":38080" -C proxy.crt -K proxy.key`
|
||||
二级HTTP代理VPS_02,IP:33.33.33.33
|
||||
`./proxy http -t tls -p ":28080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
三级HTTP代理(本地)
|
||||
`./proxy http -t tcp -p ":8080" -T tls -P "33.33.33.33:28080" -C proxy.crt -K proxy.key`
|
||||
那么访问本地的8080端口就是访问一级HTTP代理上面的代理端口38080.
|
||||
**1.5.Basic认证**
|
||||
对于代理HTTP协议我们可以basic进行Basic认证,认证的用户名和密码可以在命令行指定
|
||||
`./proxy http -t tcp -p ":33080" -a "user1:pass1" -a "user2:pass2"`
|
||||
多个用户,重复-a参数即可.
|
||||
也可以放在文件中,格式是一行一个"用户名:密码",然后用-F指定.
|
||||
`./proxy http -t tcp -p ":33080" -F auth-file.txt`
|
||||
如果没有-a或-F参数,就是关闭Basic认证.
|
||||
**1.6.HTTP代理流量强制走上级HTTP代理**
|
||||
默认情况下,proxy会智能判断一个网站域名是否无法访问,如果无法访问才走上级HTTP代理.通过--always可以使全部HTTP代理流量强制走上级HTTP代理.
|
||||
`./proxy http --always -t tls -p ":28080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
**1.7.查看帮助**
|
||||
`./proxy help http`
|
||||
[图文教程](docs/faststart_v3.md)
|
||||
### 2.TCP代理
|
||||
**1.普通一级TCP代理**
|
||||
本地执行:
|
||||
`./proxy tcp -p ":33080" -T tcp -P "192.168.22.33:22" -L 0`
|
||||
那么访问本地33080端口就是访问192.168.22.33的22端口.
|
||||
**2.普通二级TCP代理**
|
||||
VPS(IP:22.22.22.33)执行:
|
||||
`./proxy tcp -p ":33080" -T tcp -P "127.0.0.1:8080" -L 0`
|
||||
本地执行:
|
||||
`./proxy tcp -p ":23080" -T tcp -P "22.22.22.33:33080"`
|
||||
那么访问本地23080端口就是访问22.22.22.33的8080端口.
|
||||
**3.普通三级TCP代理**
|
||||
一级TCP代理VPS_01,IP:22.22.22.22
|
||||
`./proxy tcp -p ":38080" -T tcp -P "66.66.66.66:8080"`
|
||||
二级TCP代理VPS_02,IP:33.33.33.33
|
||||
`./proxy tcp -p ":28080" -T tcp -P "22.22.22.22:38080"`
|
||||
三级TCP代理(本地)
|
||||
`./proxy tcp -p ":8080" -T tcp -P "33.33.33.33:28080"`
|
||||
那么访问本地8080端口就是通过加密TCP隧道访问66.66.66.66的8080端口.
|
||||
**4.加密二级TCP代理**
|
||||
VPS(IP:22.22.22.33)执行:
|
||||
`./proxy tcp --tls -p ":33080" -T tcp -P "127.0.0.1:8080" -L 0 -C proxy.crt -K proxy.key`
|
||||
本地执行:
|
||||
`./proxy tcp -p ":23080" -T tls -P "22.22.22.33:33080" -C proxy.crt -K proxy.key`
|
||||
那么访问本地23080端口就是通过加密TCP隧道访问22.22.22.33的8080端口.
|
||||
**5.加密三级TCP代理**
|
||||
一级TCP代理VPS_01,IP:22.22.22.22
|
||||
`./proxy tcp --tls -p ":38080" -T tcp -P "66.66.66.66:8080" -C proxy.crt -K proxy.key`
|
||||
二级TCP代理VPS_02,IP:33.33.33.33
|
||||
`./proxy tcp --tls -p ":28080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
三级TCP代理(本地)
|
||||
`./proxy tcp -p ":8080" -T tls -P "33.33.33.33:28080" -C proxy.crt -K proxy.key`
|
||||
那么访问本地8080端口就是通过加密TCP隧道访问66.66.66.66的8080端口.
|
||||
**1.x.查看帮助**
|
||||
`./proxy help tcp`
|
||||
### Features
|
||||
- 程序本身可以作为一级代理,如果设置了上级代理那么可以作为二级代理,乃至N级代理.
|
||||
- 如果程序不是一级代理,而且上级代理也是本程序,那么可以加密和上级代理之间的通讯,采用底层tls高强度加密,安全无特征.
|
||||
|
||||
@ -128,7 +128,7 @@ func (s *TunnelClient) ServeUDP() {
|
||||
utils.CloseConn(&inConn)
|
||||
break
|
||||
}
|
||||
log.Printf("udp packet revecived:%s,%v", srcAddr, body)
|
||||
//log.Printf("udp packet revecived:%s,%v", srcAddr, body)
|
||||
go s.processUDPPacket(&inConn, srcAddr, body)
|
||||
}
|
||||
}
|
||||
@ -152,7 +152,7 @@ func (s *TunnelClient) processUDPPacket(inConn *net.Conn, srcAddr string, body [
|
||||
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
|
||||
return
|
||||
}
|
||||
//log.Debugf("send udp packet to %s success", dstAddr.String())
|
||||
//log.Printf("send udp packet to %s success", dstAddr.String())
|
||||
buf := make([]byte, 512)
|
||||
len, _, err := conn.ReadFromUDP(buf)
|
||||
if err != nil {
|
||||
@ -160,14 +160,14 @@ func (s *TunnelClient) processUDPPacket(inConn *net.Conn, srcAddr string, body [
|
||||
return
|
||||
}
|
||||
respBody := buf[0:len]
|
||||
//log.Debugf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
|
||||
//log.Printf("revecived udp packet from %s , %v", dstAddr.String(), respBody)
|
||||
_, err = (*inConn).Write(utils.UDPPacket(srcAddr, respBody))
|
||||
if err != nil {
|
||||
log.Printf("send udp response fail ,ERR:%s", err)
|
||||
utils.CloseConn(inConn)
|
||||
return
|
||||
}
|
||||
log.Printf("send udp response success ,from:%s", dstAddr.String())
|
||||
//log.Printf("send udp response success ,from:%s", dstAddr.String())
|
||||
}
|
||||
func (s *TunnelClient) ServeConn() {
|
||||
var inConn, outConn net.Conn
|
||||
|
||||
@ -175,7 +175,7 @@ func (s *TunnelServer) UDPConnDeamon() {
|
||||
log.Printf("parse revecived udp packet fail, err: %s", err)
|
||||
continue
|
||||
}
|
||||
log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
|
||||
//log.Printf("udp packet revecived over parent , local:%s", srcAddrFromConn)
|
||||
_srcAddr := strings.Split(srcAddrFromConn, ":")
|
||||
if len(_srcAddr) != 2 {
|
||||
log.Printf("parse revecived udp packet fail, addr error : %s", srcAddrFromConn)
|
||||
@ -188,7 +188,7 @@ func (s *TunnelServer) UDPConnDeamon() {
|
||||
log.Printf("udp response to local %s fail,ERR:%s", srcAddrFromConn, err)
|
||||
continue
|
||||
}
|
||||
log.Printf("udp response to local %s success", srcAddrFromConn)
|
||||
//log.Printf("udp response to local %s success", srcAddrFromConn)
|
||||
}
|
||||
}(outConn)
|
||||
break
|
||||
@ -203,7 +203,7 @@ func (s *TunnelServer) UDPConnDeamon() {
|
||||
log.Printf("write udp packet to %s fail ,flush err:%s", *s.cfg.Parent, err)
|
||||
goto RETRY
|
||||
}
|
||||
log.Printf("write packet %v", *item.packet)
|
||||
//log.Printf("write packet %v", *item.packet)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user