Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
@ -1,6 +1,8 @@
|
|||||||
proxy更新日志
|
proxy更新日志
|
||||||
v3.4
|
v3.4
|
||||||
1.tcp代理增加了kcp协议传输数据.
|
1.tcp代理增加了kcp协议传输数据.
|
||||||
|
2.优化了死循环检查,增加了添加本地IP参数,当VPS在nat设备后面,
|
||||||
|
vps上网卡IP都是内网IP,这个时候可以通过-g参数添加vps的外网ip防止死循环.
|
||||||
|
|
||||||
v3.4
|
v3.4
|
||||||
1.socks5代理新增了用户名密码验证支持.
|
1.socks5代理新增了用户名密码验证支持.
|
||||||
|
|||||||
@ -41,6 +41,7 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
|
|||||||
- [环境](#使用教程)
|
- [环境](#使用教程)
|
||||||
- [使用配置文件](#使用配置文件)
|
- [使用配置文件](#使用配置文件)
|
||||||
- [生成通讯证书文件](#生成加密通讯需要的证书文件)
|
- [生成通讯证书文件](#生成加密通讯需要的证书文件)
|
||||||
|
- [安全建议](#安全建议)
|
||||||
|
|
||||||
### 手册目录
|
### 手册目录
|
||||||
- [1. HTTP代理](#1http代理)
|
- [1. HTTP代理](#1http代理)
|
||||||
@ -149,6 +150,11 @@ http,tcp,udp代理过程会和上级通讯,为了安全我们采用加密通讯,
|
|||||||
`./proxy keygen`
|
`./proxy keygen`
|
||||||
默认会在当前程序目录下面生成证书文件proxy.crt和key文件proxy.key。
|
默认会在当前程序目录下面生成证书文件proxy.crt和key文件proxy.key。
|
||||||
|
|
||||||
|
### 安全建议
|
||||||
|
当VPS在nat设备后面,vps上网卡IP都是内网IP,这个时候可以通过-g参数添加vps的外网ip防止死循环.
|
||||||
|
假设你的vps外网ip是23.23.23.23,下面命令通过-g参数设置23.23.23.23
|
||||||
|
`./proxy http -g "23.23.23.23"`
|
||||||
|
|
||||||
### 1.HTTP代理
|
### 1.HTTP代理
|
||||||
#### **1.1.普通HTTP代理**
|
#### **1.1.普通HTTP代理**
|
||||||
`./proxy http -t tcp -p "0.0.0.0:38080"`
|
`./proxy http -t tcp -p "0.0.0.0:38080"`
|
||||||
|
|||||||
@ -60,6 +60,7 @@ func initConfig() (err error) {
|
|||||||
httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
|
httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
|
||||||
httpArgs.KCPKey = http.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
httpArgs.KCPKey = http.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
||||||
httpArgs.KCPMethod = http.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
httpArgs.KCPMethod = http.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
||||||
|
httpArgs.LocalIPS = http.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
||||||
|
|
||||||
//########tcp#########
|
//########tcp#########
|
||||||
tcp := app.Command("tcp", "proxy on tcp mode")
|
tcp := app.Command("tcp", "proxy on tcp mode")
|
||||||
@ -134,6 +135,7 @@ func initConfig() (err error) {
|
|||||||
socksArgs.Auth = socks.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
|
socksArgs.Auth = socks.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
|
||||||
socksArgs.KCPKey = socks.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
socksArgs.KCPKey = socks.Flag("kcp-key", "key for kcp encrypt/decrypt data").Short('B').Default("encrypt").String()
|
||||||
socksArgs.KCPMethod = socks.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
socksArgs.KCPMethod = socks.Flag("kcp-method", "kcp encrypt/decrypt method").Short('M').Default("3des").String()
|
||||||
|
socksArgs.LocalIPS = socks.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
||||||
|
|
||||||
//parse args
|
//parse args
|
||||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
|
|||||||
@ -93,6 +93,7 @@ type HTTPArgs struct {
|
|||||||
SSHAuthMethod ssh.AuthMethod
|
SSHAuthMethod ssh.AuthMethod
|
||||||
KCPMethod *string
|
KCPMethod *string
|
||||||
KCPKey *string
|
KCPKey *string
|
||||||
|
LocalIPS *[]string
|
||||||
}
|
}
|
||||||
type UDPArgs struct {
|
type UDPArgs struct {
|
||||||
Parent *string
|
Parent *string
|
||||||
@ -132,6 +133,7 @@ type SocksArgs struct {
|
|||||||
KCPKey *string
|
KCPKey *string
|
||||||
UDPParent *string
|
UDPParent *string
|
||||||
UDPLocal *string
|
UDPLocal *string
|
||||||
|
LocalIPS *[]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *TCPArgs) Protocol() string {
|
func (a *TCPArgs) Protocol() string {
|
||||||
|
|||||||
@ -362,6 +362,9 @@ func (s *HTTP) IsDeadLoop(inLocalAddr string, host string) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
interfaceIPs, err := utils.GetAllInterfaceAddr()
|
interfaceIPs, err := utils.GetAllInterfaceAddr()
|
||||||
|
for _, ip := range *s.cfg.LocalIPS {
|
||||||
|
interfaceIPs = append(interfaceIPs, net.ParseIP(ip).To4())
|
||||||
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, localIP := range interfaceIPs {
|
for _, localIP := range interfaceIPs {
|
||||||
for _, outIP := range outIPs {
|
for _, outIP := range outIPs {
|
||||||
|
|||||||
@ -167,6 +167,11 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
log.Printf("parse udp packet fail, ERR:%s", err)
|
log.Printf("parse udp packet fail, ERR:%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
//防止死循环
|
||||||
|
if s.IsDeadLoop((*localAddr).String(), p.Host()) {
|
||||||
|
log.Printf("dead loop detected , %s", p.Host())
|
||||||
|
return
|
||||||
|
}
|
||||||
//log.Printf("##########udp to -> %s:%s###########", p.Host(), p.Port())
|
//log.Printf("##########udp to -> %s:%s###########", p.Host(), p.Port())
|
||||||
if *s.cfg.Parent != "" {
|
if *s.cfg.Parent != "" {
|
||||||
//有上级代理,转发给上级
|
//有上级代理,转发给上级
|
||||||
@ -398,6 +403,13 @@ func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
|
|||||||
useProxy := true
|
useProxy := true
|
||||||
tryCount := 0
|
tryCount := 0
|
||||||
maxTryCount := 5
|
maxTryCount := 5
|
||||||
|
//防止死循环
|
||||||
|
if s.IsDeadLoop((*inConn).LocalAddr().String(), request.Host()) {
|
||||||
|
utils.CloseConn(inConn)
|
||||||
|
log.Printf("dead loop detected , %s", request.Host())
|
||||||
|
utils.CloseConn(inConn)
|
||||||
|
return
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
if *s.cfg.Always {
|
if *s.cfg.Always {
|
||||||
outConn, err = s.getOutConn(methodReq.Bytes(), request.Bytes(), request.Addr())
|
outConn, err = s.getOutConn(methodReq.Bytes(), request.Bytes(), request.Addr())
|
||||||
@ -568,3 +580,38 @@ func (s *Socks) InitBasicAuth() (err error) {
|
|||||||
func (s *Socks) IsBasicAuth() bool {
|
func (s *Socks) IsBasicAuth() bool {
|
||||||
return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0
|
return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0
|
||||||
}
|
}
|
||||||
|
func (s *Socks) IsDeadLoop(inLocalAddr string, host string) bool {
|
||||||
|
inIP, inPort, err := net.SplitHostPort(inLocalAddr)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
outDomain, outPort, err := net.SplitHostPort(host)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if inPort == outPort {
|
||||||
|
var outIPs []net.IP
|
||||||
|
outIPs, err = net.LookupIP(outDomain)
|
||||||
|
if err == nil {
|
||||||
|
for _, ip := range outIPs {
|
||||||
|
if ip.String() == inIP {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interfaceIPs, err := utils.GetAllInterfaceAddr()
|
||||||
|
for _, ip := range *s.cfg.LocalIPS {
|
||||||
|
interfaceIPs = append(interfaceIPs, net.ParseIP(ip).To4())
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
for _, localIP := range interfaceIPs {
|
||||||
|
for _, outIP := range outIPs {
|
||||||
|
if localIP.Equal(outIP) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user