Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
@ -1,6 +1,9 @@
|
|||||||
proxy更新日志
|
proxy更新日志
|
||||||
v3.3
|
v3.3
|
||||||
1.修复了socks代理模式对证书文件的判断逻辑.
|
1.修复了socks代理模式对证书文件的判断逻辑.
|
||||||
|
2.增强了http代理,socks代理的ssh中转模式的稳定性.
|
||||||
|
3.socks代理tls,tcp模式新增了CMD_ASSOCIATE(udp)支持.socks代理ssh模式不支持udp.
|
||||||
|
4.修复了http代理某些情况下会崩溃的bug.
|
||||||
|
|
||||||
v3.2
|
v3.2
|
||||||
1.内网穿透功能server端-r参数增加了协议和key设置.
|
1.内网穿透功能server端-r参数增加了协议和key设置.
|
||||||
|
|||||||
@ -423,7 +423,9 @@ server连接到bridge的时候,如果同时有多个client连接到同一个brid
|
|||||||
`./proxy help socks`
|
`./proxy help socks`
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- SOCKS5增加用户名密码认证
|
- SOCKS5增加用户名密码认证?
|
||||||
|
- http,socks代理多个上级负载均衡?
|
||||||
|
- 欢迎加群反馈...
|
||||||
|
|
||||||
### 如何使用源码?
|
### 如何使用源码?
|
||||||
cd进入你的go src目录,然后git clone https://github.com/snail007/goproxy.git ./proxy 即可.
|
cd进入你的go src目录,然后git clone https://github.com/snail007/goproxy.git ./proxy 即可.
|
||||||
|
|||||||
10
config.go
10
config.go
@ -35,7 +35,7 @@ func initConfig() (err error) {
|
|||||||
//build srvice args
|
//build srvice args
|
||||||
app = kingpin.New("proxy", "happy with proxy")
|
app = kingpin.New("proxy", "happy with proxy")
|
||||||
app.Author("snail").Version(APP_VERSION)
|
app.Author("snail").Version(APP_VERSION)
|
||||||
|
debug := app.Flag("debug", "debug log output").Default("false").Bool()
|
||||||
//########http#########
|
//########http#########
|
||||||
http := app.Command("http", "proxy on http mode")
|
http := app.Command("http", "proxy on http mode")
|
||||||
httpArgs.Parent = http.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
httpArgs.Parent = http.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
@ -126,7 +126,13 @@ func initConfig() (err error) {
|
|||||||
socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
||||||
//parse args
|
//parse args
|
||||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
|
flags := log.Ldate
|
||||||
|
if *debug {
|
||||||
|
flags |= log.Lshortfile | log.Lmicroseconds
|
||||||
|
} else {
|
||||||
|
flags |= log.Ltime
|
||||||
|
}
|
||||||
|
log.SetFlags(flags)
|
||||||
poster()
|
poster()
|
||||||
//regist services and run service
|
//regist services and run service
|
||||||
services.Regist("http", services.NewHTTP(), httpArgs)
|
services.Regist("http", services.NewHTTP(), httpArgs)
|
||||||
|
|||||||
@ -6,7 +6,7 @@ fi
|
|||||||
mkdir /tmp/proxy
|
mkdir /tmp/proxy
|
||||||
cd /tmp/proxy
|
cd /tmp/proxy
|
||||||
wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_linux_amd64.tar.gz
|
wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_linux_amd64.tar.gz
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v3.2/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v3.3/proxy-linux-amd64.tar.gz
|
||||||
|
|
||||||
# install monexec
|
# install monexec
|
||||||
tar zxvf monexec_0.1.1_linux_amd64.tar.gz
|
tar zxvf monexec_0.1.1_linux_amd64.tar.gz
|
||||||
|
|||||||
2
main.go
2
main.go
@ -9,7 +9,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VERSION = "3.2"
|
const APP_VERSION = "3.3"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := initConfig()
|
err := initConfig()
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
VER="3.2"
|
VER="3.3"
|
||||||
RELEASE="release-${VER}"
|
RELEASE="release-${VER}"
|
||||||
rm -rf .cert
|
rm -rf .cert
|
||||||
mkdir .cert
|
mkdir .cert
|
||||||
|
|||||||
@ -20,6 +20,7 @@ type HTTP struct {
|
|||||||
checker utils.Checker
|
checker utils.Checker
|
||||||
basicAuth utils.BasicAuth
|
basicAuth utils.BasicAuth
|
||||||
sshClient *ssh.Client
|
sshClient *ssh.Client
|
||||||
|
lockChn chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTP() Service {
|
func NewHTTP() Service {
|
||||||
@ -28,6 +29,7 @@ func NewHTTP() Service {
|
|||||||
cfg: HTTPArgs{},
|
cfg: HTTPArgs{},
|
||||||
checker: utils.Checker{},
|
checker: utils.Checker{},
|
||||||
basicAuth: utils.BasicAuth{},
|
basicAuth: utils.BasicAuth{},
|
||||||
|
lockChn: make(chan bool, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *HTTP) CheckArgs() {
|
func (s *HTTP) CheckArgs() {
|
||||||
@ -115,7 +117,9 @@ func (s *HTTP) callback(inConn net.Conn) {
|
|||||||
log.Printf("http(s) conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
|
log.Printf("http(s) conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
req, err := utils.NewHTTPRequest(&inConn, 4096, s.IsBasicAuth(), &s.basicAuth)
|
var err interface{}
|
||||||
|
var req utils.HTTPRequest
|
||||||
|
req, err = utils.NewHTTPRequest(&inConn, 4096, s.IsBasicAuth(), &s.basicAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
log.Printf("decoder error , form %s, ERR:%s", err, inConn.RemoteAddr())
|
log.Printf("decoder error , form %s, ERR:%s", err, inConn.RemoteAddr())
|
||||||
@ -153,7 +157,7 @@ func (s *HTTP) callback(inConn net.Conn) {
|
|||||||
utils.CloseConn(&inConn)
|
utils.CloseConn(&inConn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *utils.HTTPRequest) (err error) {
|
func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *utils.HTTPRequest) (err interface{}) {
|
||||||
inAddr := (*inConn).RemoteAddr().String()
|
inAddr := (*inConn).RemoteAddr().String()
|
||||||
inLocalAddr := (*inConn).LocalAddr().String()
|
inLocalAddr := (*inConn).LocalAddr().String()
|
||||||
//防止死循环
|
//防止死循环
|
||||||
@ -208,18 +212,27 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HTTP) getSSHConn(host string) (outConn net.Conn, err error) {
|
func (s *HTTP) getSSHConn(host string) (outConn net.Conn, err interface{}) {
|
||||||
maxTryCount := 1
|
maxTryCount := 1
|
||||||
tryCount := 0
|
tryCount := 0
|
||||||
|
errchn := make(chan interface{}, 1)
|
||||||
RETRY:
|
RETRY:
|
||||||
if tryCount >= maxTryCount {
|
if tryCount >= maxTryCount {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
outConn, err = s.sshClient.Dial("tcp", host)
|
go func() {
|
||||||
//log.Printf("s.sshClient.Dial, host:%s)", host)
|
defer func() {
|
||||||
|
if err == nil {
|
||||||
|
errchn <- recover()
|
||||||
|
} else {
|
||||||
|
errchn <- nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
outConn, err = s.sshClient.Dial("tcp", host)
|
||||||
|
}()
|
||||||
|
err = <-errchn
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("connect ssh fail, ERR: %s, retrying...", err)
|
log.Printf("connect ssh fail, ERR: %s, retrying...", err)
|
||||||
s.sshClient.Close()
|
|
||||||
e := s.ConnectSSH()
|
e := s.ConnectSSH()
|
||||||
if e == nil {
|
if e == nil {
|
||||||
tryCount++
|
tryCount++
|
||||||
@ -232,14 +245,25 @@ RETRY:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *HTTP) ConnectSSH() (err error) {
|
func (s *HTTP) ConnectSSH() (err error) {
|
||||||
|
select {
|
||||||
|
case s.lockChn <- true:
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("can not connect at same time")
|
||||||
|
return
|
||||||
|
}
|
||||||
config := ssh.ClientConfig{
|
config := ssh.ClientConfig{
|
||||||
User: *s.cfg.SSHUser,
|
Timeout: time.Duration(*s.cfg.Timeout) * time.Millisecond,
|
||||||
Auth: []ssh.AuthMethod{s.cfg.SSHAuthMethod},
|
User: *s.cfg.SSHUser,
|
||||||
|
Auth: []ssh.AuthMethod{s.cfg.SSHAuthMethod},
|
||||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if s.sshClient != nil {
|
||||||
|
s.sshClient.Close()
|
||||||
|
}
|
||||||
s.sshClient, err = ssh.Dial("tcp", *s.cfg.Parent, &config)
|
s.sshClient, err = ssh.Dial("tcp", *s.cfg.Parent, &config)
|
||||||
|
<-s.lockChn
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *HTTP) InitOutConnPool() {
|
func (s *HTTP) InitOutConnPool() {
|
||||||
|
|||||||
@ -37,7 +37,7 @@ func NewSocks() Service {
|
|||||||
func (s *Socks) CheckArgs() {
|
func (s *Socks) CheckArgs() {
|
||||||
var err error
|
var err error
|
||||||
if *s.cfg.LocalType == "tls" {
|
if *s.cfg.LocalType == "tls" {
|
||||||
log.Println(*s.cfg.CertFile, *s.cfg.KeyFile)
|
//log.Println(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||||
}
|
}
|
||||||
if *s.cfg.Parent != "" {
|
if *s.cfg.Parent != "" {
|
||||||
@ -55,7 +55,6 @@ func (s *Socks) CheckArgs() {
|
|||||||
if *s.cfg.SSHKeyFile == "" && *s.cfg.SSHPassword == "" {
|
if *s.cfg.SSHKeyFile == "" && *s.cfg.SSHPassword == "" {
|
||||||
log.Fatalf("ssh password or key required")
|
log.Fatalf("ssh password or key required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *s.cfg.SSHPassword != "" {
|
if *s.cfg.SSHPassword != "" {
|
||||||
s.cfg.SSHAuthMethod = ssh.Password(*s.cfg.SSHPassword)
|
s.cfg.SSHAuthMethod = ssh.Password(*s.cfg.SSHPassword)
|
||||||
} else {
|
} else {
|
||||||
@ -85,6 +84,25 @@ func (s *Socks) InitService() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("init service fail, ERR: %s", err)
|
log.Fatalf("init service fail, ERR: %s", err)
|
||||||
}
|
}
|
||||||
|
go func() {
|
||||||
|
//循环检查ssh网络连通性
|
||||||
|
for {
|
||||||
|
conn, err := utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout*2)
|
||||||
|
if err != nil {
|
||||||
|
if s.sshClient != nil {
|
||||||
|
s.sshClient.Close()
|
||||||
|
if s.sshClient.Conn != nil {
|
||||||
|
s.sshClient.Conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("ssh offline, retrying...")
|
||||||
|
s.ConnectSSH()
|
||||||
|
} else {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
if *s.cfg.ParentType == "ssh" {
|
if *s.cfg.ParentType == "ssh" {
|
||||||
log.Println("warn: socks udp not suppored for ssh")
|
log.Println("warn: socks udp not suppored for ssh")
|
||||||
@ -133,17 +151,17 @@ func (s *Socks) UDPKey() []byte {
|
|||||||
return s.cfg.KeyBytes[:32]
|
return s.cfg.KeyBytes[:32]
|
||||||
}
|
}
|
||||||
func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
||||||
newB := b
|
rawB := b
|
||||||
var err error
|
var err error
|
||||||
if *s.cfg.LocalType == "tls" {
|
if *s.cfg.LocalType == "tls" {
|
||||||
//decode b
|
//decode b
|
||||||
newB, err = goaes.Decrypt(s.UDPKey(), b)
|
rawB, err = goaes.Decrypt(s.UDPKey(), b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("decrypt udp packet fail from %s", srcAddr.String())
|
log.Printf("decrypt udp packet fail from %s", srcAddr.String())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p, err := socks.ParseUDPPacket(newB)
|
p, err := socks.ParseUDPPacket(rawB)
|
||||||
log.Printf("udp revecived:%v", len(p.Data()))
|
log.Printf("udp revecived:%v", len(p.Data()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("parse udp packet fail, ERR:%s", err)
|
log.Printf("parse udp packet fail, ERR:%s", err)
|
||||||
@ -154,7 +172,7 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
//有上级代理,转发给上级
|
//有上级代理,转发给上级
|
||||||
if *s.cfg.ParentType == "tls" {
|
if *s.cfg.ParentType == "tls" {
|
||||||
//encode b
|
//encode b
|
||||||
newB, err = goaes.Encrypt(s.UDPKey(), newB)
|
rawB, err = goaes.Encrypt(s.UDPKey(), rawB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("encrypt udp data fail to %s", *s.cfg.Parent)
|
log.Printf("encrypt udp data fail to %s", *s.cfg.Parent)
|
||||||
return
|
return
|
||||||
@ -172,18 +190,20 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*2)))
|
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*2)))
|
||||||
_, err = conn.Write(newB)
|
_, err = conn.Write(rawB)
|
||||||
log.Printf("udp request:%v", len(newB))
|
log.Printf("udp request:%v", len(rawB))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
|
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.Printf("send udp packet to %s success", dstAddr.String())
|
//log.Printf("send udp packet to %s success", dstAddr.String())
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 10*1024)
|
||||||
length, _, err := conn.ReadFromUDP(buf)
|
length, _, err := conn.ReadFromUDP(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
|
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
respBody := buf[0:length]
|
respBody := buf[0:length]
|
||||||
@ -194,6 +214,7 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
respBody, err = goaes.Decrypt(s.UDPKey(), respBody)
|
respBody, err = goaes.Decrypt(s.UDPKey(), respBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("encrypt udp data fail to %s", *s.cfg.Parent)
|
log.Printf("encrypt udp data fail to %s", *s.cfg.Parent)
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,6 +222,7 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
d, err := goaes.Encrypt(s.UDPKey(), respBody)
|
d, err := goaes.Encrypt(s.UDPKey(), respBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("encrypt udp data fail from %s", dstAddr.String())
|
log.Printf("encrypt udp data fail from %s", dstAddr.String())
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.udpSC.UDPListener.WriteToUDP(d, srcAddr)
|
s.udpSC.UDPListener.WriteToUDP(d, srcAddr)
|
||||||
@ -223,33 +245,38 @@ func (s *Socks) udpCallback(b []byte, localAddr, srcAddr *net.UDPAddr) {
|
|||||||
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
|
log.Printf("connect to udp %s fail,ERR:%s", dstAddr.String(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*2)))
|
conn.SetDeadline(time.Now().Add(time.Millisecond * time.Duration(*s.cfg.Timeout*3)))
|
||||||
_, err = conn.Write(p.Data())
|
_, err = conn.Write(p.Data())
|
||||||
log.Printf("udp send:%v", len(p.Data()))
|
log.Printf("udp send:%v", len(p.Data()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
|
log.Printf("send udp packet to %s fail,ERR:%s", dstAddr.String(), err)
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("send udp packet to %s success", dstAddr.String())
|
//log.Printf("send udp packet to %s success", dstAddr.String())
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 10*1024)
|
||||||
length, _, err := conn.ReadFromUDP(buf)
|
length, _, err := conn.ReadFromUDP(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
|
log.Printf("read udp response from %s fail ,ERR:%s", dstAddr.String(), err)
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
respBody := buf[0:length]
|
respBody := buf[0:length]
|
||||||
|
//封装来自真实服务器的数据,返回给访问者
|
||||||
|
respPacket := p.NewReply(respBody)
|
||||||
//log.Printf("revecived udp packet from %s", dstAddr.String())
|
//log.Printf("revecived udp packet from %s", dstAddr.String())
|
||||||
if *s.cfg.LocalType == "tls" {
|
if *s.cfg.LocalType == "tls" {
|
||||||
d, err := goaes.Encrypt(s.UDPKey(), respBody)
|
d, err := goaes.Encrypt(s.UDPKey(), respPacket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("encrypt udp data fail from %s", dstAddr.String())
|
log.Printf("encrypt udp data fail from %s", dstAddr.String())
|
||||||
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.udpSC.UDPListener.WriteToUDP(d, srcAddr)
|
s.udpSC.UDPListener.WriteToUDP(d, srcAddr)
|
||||||
} else {
|
} else {
|
||||||
s.udpSC.UDPListener.WriteToUDP(respBody, srcAddr)
|
s.udpSC.UDPListener.WriteToUDP(respPacket, srcAddr)
|
||||||
}
|
}
|
||||||
log.Printf("udp reply:%v", len(respBody))
|
log.Printf("udp reply:%v", len(respPacket))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -304,18 +331,18 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
|
|||||||
}
|
}
|
||||||
func (s *Socks) proxyUDP(inConn *net.Conn, methodReq socks.MethodsRequest, request socks.Request) {
|
func (s *Socks) proxyUDP(inConn *net.Conn, methodReq socks.MethodsRequest, request socks.Request) {
|
||||||
if *s.cfg.ParentType == "ssh" {
|
if *s.cfg.ParentType == "ssh" {
|
||||||
|
utils.CloseConn(inConn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
host, _, _ := net.SplitHostPort((*inConn).LocalAddr().String())
|
host, _, _ := net.SplitHostPort((*inConn).LocalAddr().String())
|
||||||
_, port, _ := net.SplitHostPort(s.udpSC.UDPListener.LocalAddr().String())
|
_, port, _ := net.SplitHostPort(s.udpSC.UDPListener.LocalAddr().String())
|
||||||
// log.Printf("proxy udp on %s", net.JoinHostPort(host, port))
|
// log.Printf("proxy udp on %s", net.JoinHostPort(host, port))
|
||||||
request.UDPReply(socks.REP_SUCCESS, net.JoinHostPort(host, port))
|
request.UDPReply(socks.REP_SUCCESS, net.JoinHostPort(host, port))
|
||||||
// log.Printf("%v", request.NewReply(socks.REP_SUCCESS, net.JoinHostPort(host, port)))
|
|
||||||
}
|
}
|
||||||
func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, request socks.Request) {
|
func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, request socks.Request) {
|
||||||
var outConn net.Conn
|
var outConn net.Conn
|
||||||
defer utils.CloseConn(&outConn)
|
defer utils.CloseConn(&outConn)
|
||||||
var err error
|
var err interface{}
|
||||||
useProxy := true
|
useProxy := true
|
||||||
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())
|
||||||
@ -370,7 +397,8 @@ func (s *Socks) proxyTCP(inConn *net.Conn, methodReq socks.MethodsRequest, reque
|
|||||||
utils.CloseConn(inConn)
|
utils.CloseConn(inConn)
|
||||||
utils.CloseConn(&outConn)
|
utils.CloseConn(&outConn)
|
||||||
}
|
}
|
||||||
func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn net.Conn, err error) {
|
func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn net.Conn, err interface{}) {
|
||||||
|
errchn := make(chan interface{}, 1)
|
||||||
switch *s.cfg.ParentType {
|
switch *s.cfg.ParentType {
|
||||||
case "tls":
|
case "tls":
|
||||||
fallthrough
|
fallthrough
|
||||||
@ -413,7 +441,17 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
|
|||||||
if tryCount >= maxTryCount {
|
if tryCount >= maxTryCount {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
outConn, err = s.sshClient.Dial("tcp", host)
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if err == nil {
|
||||||
|
errchn <- recover()
|
||||||
|
} else {
|
||||||
|
errchn <- nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
outConn, err = s.sshClient.Dial("tcp", host)
|
||||||
|
}()
|
||||||
|
err = <-errchn
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("connect ssh fail, ERR: %s, retrying...", err)
|
log.Printf("connect ssh fail, ERR: %s, retrying...", err)
|
||||||
e := s.ConnectSSH()
|
e := s.ConnectSSH()
|
||||||
|
|||||||
@ -64,12 +64,15 @@ func (s *TunnelServerManager) Start(args interface{}) (err error) {
|
|||||||
CertBytes: s.cfg.CertBytes,
|
CertBytes: s.cfg.CertBytes,
|
||||||
KeyBytes: s.cfg.KeyBytes,
|
KeyBytes: s.cfg.KeyBytes,
|
||||||
Parent: s.cfg.Parent,
|
Parent: s.cfg.Parent,
|
||||||
|
CertFile: s.cfg.CertFile,
|
||||||
|
KeyFile: s.cfg.KeyFile,
|
||||||
Local: &local,
|
Local: &local,
|
||||||
IsUDP: &IsUDP,
|
IsUDP: &IsUDP,
|
||||||
Remote: &remote,
|
Remote: &remote,
|
||||||
Key: &KEY,
|
Key: &KEY,
|
||||||
Timeout: s.cfg.Timeout,
|
Timeout: s.cfg.Timeout,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -315,6 +315,24 @@ func Uniqueid() string {
|
|||||||
s := fmt.Sprintf("%d", src.Int63())
|
s := fmt.Sprintf("%d", src.Int63())
|
||||||
return s[len(s)-5:len(s)-1] + fmt.Sprintf("%d", uint64(time.Now().UnixNano()))[8:]
|
return s[len(s)-5:len(s)-1] + fmt.Sprintf("%d", uint64(time.Now().UnixNano()))[8:]
|
||||||
}
|
}
|
||||||
|
func SubStr(str string, start, end int) string {
|
||||||
|
if len(str) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if end >= len(str) {
|
||||||
|
end = len(str) - 1
|
||||||
|
}
|
||||||
|
return str[start:end]
|
||||||
|
}
|
||||||
|
func SubBytes(bytes []byte, start, end int) []byte {
|
||||||
|
if len(bytes) == 0 {
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
if end >= len(bytes) {
|
||||||
|
end = len(bytes) - 1
|
||||||
|
}
|
||||||
|
return bytes[start:end]
|
||||||
|
}
|
||||||
func TlsBytes(cert, key string) (certBytes, keyBytes []byte) {
|
func TlsBytes(cert, key string) (certBytes, keyBytes []byte) {
|
||||||
certBytes, err := ioutil.ReadFile(cert)
|
certBytes, err := ioutil.ReadFile(cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -242,6 +242,12 @@ func ParseUDPPacket(b []byte) (p UDPPacket, err error) {
|
|||||||
func (s *UDPPacket) Header() []byte {
|
func (s *UDPPacket) Header() []byte {
|
||||||
return s.header
|
return s.header
|
||||||
}
|
}
|
||||||
|
func (s *UDPPacket) NewReply(data []byte) []byte {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
buf.Write(s.header)
|
||||||
|
buf.Write(data)
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
func (s *UDPPacket) Host() string {
|
func (s *UDPPacket) Host() string {
|
||||||
return s.dstHost
|
return s.dstHost
|
||||||
}
|
}
|
||||||
|
|||||||
@ -256,13 +256,13 @@ func NewHTTPRequest(inConn *net.Conn, bufSize int, isBasicAuth bool, basicAuth *
|
|||||||
req.HeadBuf = buf[:len]
|
req.HeadBuf = buf[:len]
|
||||||
index := bytes.IndexByte(req.HeadBuf, '\n')
|
index := bytes.IndexByte(req.HeadBuf, '\n')
|
||||||
if index == -1 {
|
if index == -1 {
|
||||||
err = fmt.Errorf("http decoder data line err:%s", string(req.HeadBuf)[:50])
|
err = fmt.Errorf("http decoder data line err:%s", SubStr(string(req.HeadBuf), 0, 50))
|
||||||
CloseConn(inConn)
|
CloseConn(inConn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Sscanf(string(req.HeadBuf[:index]), "%s%s", &req.Method, &req.hostOrURL)
|
fmt.Sscanf(string(req.HeadBuf[:index]), "%s%s", &req.Method, &req.hostOrURL)
|
||||||
if req.Method == "" || req.hostOrURL == "" {
|
if req.Method == "" || req.hostOrURL == "" {
|
||||||
err = fmt.Errorf("http decoder data err:%s", string(req.HeadBuf)[:50])
|
err = fmt.Errorf("http decoder data err:%s", SubStr(string(req.HeadBuf), 0, 50))
|
||||||
CloseConn(inConn)
|
CloseConn(inConn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user