Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
@ -3,6 +3,9 @@ v3.2
|
||||
1.内网穿透功能server端-r参数增加了协议和key设置.
|
||||
2.手册增加了对-r参数的详细说明.
|
||||
3.修复了普通模式也检查证书文件的bug.
|
||||
4.增加了Socks5支持,目前只支持TCP协议,不支持UDP协议.
|
||||
5.Socks5上级代理支持ssh中转,linux服务器不需要任何服务端,本地一个proxy即可开心上网.
|
||||
6.http(s)代理增加了ssh中转支持,linux服务器不需要任何服务端,本地一个proxy即可开心上网.
|
||||
|
||||
v3.1
|
||||
1.优化了内网穿透功能,bridge,client和server只需要启动一个即可。
|
||||
|
||||
80
README.md
80
README.md
@ -11,8 +11,9 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp代理服务器,支
|
||||
- 智能HTTP代理,会自动判断访问的网站是否屏蔽,如果被屏蔽那么就会使用上级代理(前提是配置了上级代理)访问网站;如果访问的网站没有被屏蔽,为了加速访问,代理会直接访问网站,不使用上级代理.
|
||||
- 域名黑白名单,更加自由的控制网站的访问方式。
|
||||
- 跨平台性,无论你是widows,linux,还是mac,甚至是树莓派,都可以很好的运行proxy.
|
||||
- 多协议支持,支持HTTP,TCP,UDP,Websocket代理.
|
||||
- 多协议支持,支持HTTP(S),TCP,UDP,Websocket,SOCKS5代理.
|
||||
- 支持内网穿透,协议支持TCP和UDP.
|
||||
- HTTP(S),SOCKS5代理支持SSH中转,上级Linux服务器不需要任何服务端,本地一个proxy即可开心上网.
|
||||
|
||||
### Why need these?
|
||||
- 当由于安全因素或者限制,我们不能顺畅的访问我们在其它地方的服务,我们可以通过多个相连的proxy节点建立起一个安全的隧道,顺畅的访问我们的服务.
|
||||
@ -24,7 +25,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp代理服务器,支
|
||||
- ...
|
||||
|
||||
### 手册目录
|
||||
本页是最新v3.1手册,其他版本手册请点击下面链接查看.
|
||||
本页是最新v3.2手册,其他版本手册请点击下面链接查看.
|
||||
- [v3.1手册](https://github.com/snail007/goproxy/tree/v3.1)
|
||||
- [v3.0手册](https://github.com/snail007/goproxy/tree/v3.0)
|
||||
- [v2.x手册](https://github.com/snail007/goproxy/tree/v2.2)
|
||||
|
||||
@ -91,8 +93,9 @@ http,tcp,udp代理过程会和上级通讯,为了安全我们采用加密通讯,
|
||||
**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`
|
||||
默认关闭了连接池,如果要加快访问速度,-L可以开启连接池,10就是连接池大小,0为关闭,
|
||||
开启连接池在网络不好的情况下,稳定不是很好.
|
||||
`./proxy http -t tcp -p "0.0.0.0:8090" -T tcp -P "22.22.22.22:8080" -L 10`
|
||||
我们还可以指定网站域名的黑白名单文件,一行一个域名,怕匹配规则是最右批评匹配,比如: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`
|
||||
|
||||
@ -129,7 +132,19 @@ http,tcp,udp代理过程会和上级通讯,为了安全我们采用加密通讯,
|
||||
默认情况下,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.查看帮助**
|
||||
**1.7.HTTP(S)通过SSH中转**
|
||||
说明:ssh中转的原理是利用了ssh的转发功能,就是你连接上ssh之后,可以通过ssh代理访问目标地址.
|
||||
假设有:vps
|
||||
- IP是2.2.2.2, ssh端口是22, ssh用户名是:user, ssh用户密码是:demo
|
||||
- 用户user的ssh私钥名称是user.key
|
||||
***1.7.1 ssh用户名和密码的方式***
|
||||
本地HTTP(S)代理28080端口,执行:
|
||||
`./proxy http -T ssh -P "2.2.2.2:22" -u user -A demo -t tcp -p ":28080"`
|
||||
***1.7.2 ssh用户名和密钥的方式***
|
||||
本地HTTP(S)代理28080端口,执行:
|
||||
`./proxy http -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
||||
|
||||
**1.8.查看帮助**
|
||||
`./proxy help http`
|
||||
|
||||
|
||||
@ -352,9 +367,62 @@ server连接到bridge的时候,如果同时有多个client连接到同一个brid
|
||||
`./proxy help tserver`
|
||||
`./proxy help tserver`
|
||||
|
||||
### 5.SOCKS5代理
|
||||
提示:SOCKS5代理,只支持TCP协议,不支持UDP协议,不支持用户名密码认证.
|
||||
**5.1.普通SOCKS5代理**
|
||||
`./proxy socks -t tcp -p "0.0.0.0:38080"`
|
||||
|
||||
**5.2.普通二级SOCKS5代理**
|
||||
使用本地端口8090,假设上级SOCKS5代理是`22.22.22.22:8080`
|
||||
`./proxy socks -t tcp -p "0.0.0.0:8090" -T tcp -P "22.22.22.22:8080" `
|
||||
我们还可以指定网站域名的黑白名单文件,一行一个域名,怕匹配规则是最右批评匹配,比如:baidu.com,匹配的是*.*.baidu.com,黑名单的域名域名直接走上级代理,白名单的域名不走上级代理.
|
||||
`./proxy socks -p "0.0.0.0:8090" -T tcp -P "22.22.22.22:8080" -b blocked.txt -d direct.txt`
|
||||
|
||||
**5.3.SOCKS二级代理(加密)**
|
||||
一级SOCKS代理(VPS,IP:22.22.22.22)
|
||||
`./proxy socks -t tls -p ":38080" -C proxy.crt -K proxy.key`
|
||||
|
||||
二级SOCKS代理(本地Linux)
|
||||
`./proxy socks -t tcp -p ":8080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
那么访问本地的8080端口就是访问VPS上面的代理端口38080.
|
||||
|
||||
二级SOCKS代理(本地windows)
|
||||
`./proxy.exe socks -t tcp -p ":8080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
然后设置你的windos系统中,需要通过代理上网的程序的代理为socks5模式,地址为:127.0.0.1,端口为:8080,程序即可通过加密通道通过vps上网。
|
||||
|
||||
**5.4.SOCKS三级代理(加密)**
|
||||
一级SOCKS代理VPS_01,IP:22.22.22.22
|
||||
`./proxy socks -t tls -p ":38080" -C proxy.crt -K proxy.key`
|
||||
二级SOCKS代理VPS_02,IP:33.33.33.33
|
||||
`./proxy socks -t tls -p ":28080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
三级SOCKS代理(本地)
|
||||
`./proxy socks -t tcp -p ":8080" -T tls -P "33.33.33.33:28080" -C proxy.crt -K proxy.key`
|
||||
那么访问本地的8080端口就是访问一级SOCKS代理上面的代理端口38080.
|
||||
|
||||
**5.5.SOCKS代理流量强制走上级SOCKS代理**
|
||||
默认情况下,proxy会智能判断一个网站域名是否无法访问,如果无法访问才走上级SOCKS代理.通过--always可以使全部SOCKS代理流量强制走上级SOCKS代理.
|
||||
`./proxy socks --always -t tls -p ":28080" -T tls -P "22.22.22.22:38080" -C proxy.crt -K proxy.key`
|
||||
|
||||
**5.6.SOCKS通过SSH中转**
|
||||
说明:ssh中转的原理是利用了ssh的转发功能,就是你连接上ssh之后,可以通过ssh代理访问目标地址.
|
||||
假设有:vps
|
||||
- IP是2.2.2.2, ssh端口是22, ssh用户名是:user, ssh用户密码是:demo
|
||||
- 用户user的ssh私钥名称是user.key
|
||||
***5.6.1 ssh用户名和密码的方式***
|
||||
本地SOCKS5代理28080端口,执行:
|
||||
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -A demo -t tcp -p ":28080"`
|
||||
***5.6.2 ssh用户名和密钥的方式***
|
||||
本地SOCKS5代理28080端口,执行:
|
||||
`./proxy socks -T ssh -P "2.2.2.2:22" -u user -S user.key -t tcp -p ":28080"`
|
||||
|
||||
那么访问本地的28080端口就是通过VPS访问目标地址.
|
||||
|
||||
**5.7.查看帮助**
|
||||
`./proxy help socks`
|
||||
|
||||
### TODO
|
||||
- socks5代理支持.
|
||||
- SOCKS5增加用户名密码认证
|
||||
|
||||
### 如何使用源码?
|
||||
cd进入你的go src目录,然后git clone https://github.com/snail007/goproxy.git ./proxy 即可.
|
||||
编译直接:go build
|
||||
|
||||
86
config.go
86
config.go
@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"proxy/services"
|
||||
@ -24,7 +23,7 @@ func initConfig() (err error) {
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
args := services.Args{}
|
||||
|
||||
//define args
|
||||
tcpArgs := services.TCPArgs{}
|
||||
httpArgs := services.HTTPArgs{}
|
||||
@ -32,18 +31,18 @@ func initConfig() (err error) {
|
||||
tunnelClientArgs := services.TunnelClientArgs{}
|
||||
tunnelBridgeArgs := services.TunnelBridgeArgs{}
|
||||
udpArgs := services.UDPArgs{}
|
||||
|
||||
socksArgs := services.SocksArgs{}
|
||||
//build srvice args
|
||||
app = kingpin.New("proxy", "happy with proxy")
|
||||
app.Author("snail").Version(APP_VERSION)
|
||||
args.Parent = app.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||
certTLS := app.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
keyTLS := app.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
|
||||
//########http#########
|
||||
http := app.Command("http", "proxy on http mode")
|
||||
httpArgs.LocalType = http.Flag("local-type", "parent protocol type <tls|tcp>").Default("tcp").Short('t').Enum("tls", "tcp")
|
||||
httpArgs.ParentType = http.Flag("parent-type", "parent protocol type <tls|tcp>").Short('T').Enum("tls", "tcp")
|
||||
httpArgs.Parent = http.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||
httpArgs.CertFile = http.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
httpArgs.KeyFile = http.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
httpArgs.LocalType = http.Flag("local-type", "local protocol type <tls|tcp>").Default("tcp").Short('t').Enum("tls", "tcp")
|
||||
httpArgs.ParentType = http.Flag("parent-type", "parent protocol type <tls|tcp|ssh>").Short('T').Enum("tls", "tcp", "ssh")
|
||||
httpArgs.Always = http.Flag("always", "always use parent proxy").Default("false").Bool()
|
||||
httpArgs.Timeout = http.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
|
||||
httpArgs.HTTPTimeout = http.Flag("http-timeout", "check domain if blocked , http request timeout milliseconds when connect to host").Default("3000").Int()
|
||||
@ -55,9 +54,16 @@ func initConfig() (err error) {
|
||||
httpArgs.PoolSize = http.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
httpArgs.CheckParentInterval = http.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
|
||||
httpArgs.Local = http.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
httpArgs.SSHUser = http.Flag("ssh-user", "user for ssh").Short('u').Default("").String()
|
||||
httpArgs.SSHKeyFile = http.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String()
|
||||
httpArgs.SSHKeyFileSalt = http.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String()
|
||||
httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
|
||||
|
||||
//########tcp#########
|
||||
tcp := app.Command("tcp", "proxy on tcp mode")
|
||||
tcpArgs.Parent = tcp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||
tcpArgs.CertFile = tcp.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
tcpArgs.KeyFile = tcp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
tcpArgs.Timeout = tcp.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('t').Default("2000").Int()
|
||||
tcpArgs.ParentType = tcp.Flag("parent-type", "parent protocol type <tls|tcp|udp>").Short('T').Enum("tls", "tcp", "udp")
|
||||
tcpArgs.IsTLS = tcp.Flag("tls", "proxy on tls mode").Default("false").Bool()
|
||||
@ -67,6 +73,9 @@ func initConfig() (err error) {
|
||||
|
||||
//########udp#########
|
||||
udp := app.Command("udp", "proxy on udp mode")
|
||||
udpArgs.Parent = udp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||
udpArgs.CertFile = udp.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
udpArgs.KeyFile = udp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
udpArgs.Timeout = udp.Flag("timeout", "tcp timeout milliseconds when connect to parent proxy").Short('t').Default("2000").Int()
|
||||
udpArgs.ParentType = udp.Flag("parent-type", "parent protocol type <tls|tcp|udp>").Short('T').Enum("tls", "tcp", "udp")
|
||||
udpArgs.PoolSize = udp.Flag("pool-size", "conn pool size , which connect to parent proxy, zero: means turn off pool").Short('L').Default("0").Int()
|
||||
@ -75,6 +84,9 @@ func initConfig() (err error) {
|
||||
|
||||
//########tunnel-server#########
|
||||
tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
|
||||
tunnelServerArgs.Parent = tunnelServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||
tunnelServerArgs.CertFile = tunnelServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
tunnelServerArgs.KeyFile = tunnelServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
tunnelServerArgs.Timeout = tunnelServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
||||
tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool()
|
||||
tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String()
|
||||
@ -82,35 +94,39 @@ func initConfig() (err error) {
|
||||
|
||||
//########tunnel-client#########
|
||||
tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
|
||||
tunnelClientArgs.Parent = tunnelClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||
tunnelClientArgs.CertFile = tunnelClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
tunnelClientArgs.KeyFile = tunnelClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
tunnelClientArgs.Timeout = tunnelClient.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
||||
tunnelClientArgs.Key = tunnelClient.Flag("k", "key same with server").Default("default").String()
|
||||
|
||||
//########tunnel-bridge#########
|
||||
tunnelBridge := app.Command("tbridge", "proxy on tunnel bridge mode")
|
||||
tunnelBridgeArgs.CertFile = tunnelBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
tunnelBridgeArgs.KeyFile = tunnelBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
tunnelBridgeArgs.Timeout = tunnelBridge.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
|
||||
tunnelBridgeArgs.Local = tunnelBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
|
||||
//########ssh#########
|
||||
socks := app.Command("socks", "proxy on ssh mode")
|
||||
socksArgs.Parent = socks.Flag("parent", "parent ssh address, such as: \"23.32.32.19:22\"").Default("").Short('P').String()
|
||||
socksArgs.ParentType = socks.Flag("parent-type", "parent protocol type <tls|tcp|ssh>").Default("tcp").Short('T').Enum("tls", "tcp", "ssh")
|
||||
socksArgs.LocalType = socks.Flag("local-type", "local protocol type <tls|tcp>").Default("tcp").Short('t').Enum("tls", "tcp")
|
||||
socksArgs.Local = socks.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||
socksArgs.CertFile = socks.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||
socksArgs.KeyFile = socks.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||
socksArgs.SSHUser = socks.Flag("ssh-user", "user for ssh").Short('u').Default("").String()
|
||||
socksArgs.SSHKeyFile = socks.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String()
|
||||
socksArgs.SSHKeyFileSalt = socks.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String()
|
||||
socksArgs.SSHPassword = socks.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
|
||||
socksArgs.Always = socks.Flag("always", "always use parent proxy").Default("false").Bool()
|
||||
socksArgs.Timeout = socks.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
|
||||
socksArgs.Interval = socks.Flag("interval", "check domain if blocked every interval seconds").Default("10").Int()
|
||||
socksArgs.Blocked = socks.Flag("blocked", "blocked domain file , one domain each line").Default("blocked").Short('b').String()
|
||||
socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
|
||||
//parse args
|
||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||
|
||||
if *httpArgs.ParentType == "tls" ||
|
||||
*tcpArgs.ParentType == "tls" ||
|
||||
*udpArgs.ParentType == "tls" ||
|
||||
*httpArgs.LocalType == "tls" ||
|
||||
*tcpArgs.IsTLS ||
|
||||
serviceName == "tserver" ||
|
||||
serviceName == "tclient" ||
|
||||
serviceName == "tbridge" {
|
||||
args.CertBytes, args.KeyBytes = tlsBytes(*certTLS, *keyTLS)
|
||||
}
|
||||
|
||||
//common args
|
||||
httpArgs.Args = args
|
||||
tcpArgs.Args = args
|
||||
udpArgs.Args = args
|
||||
tunnelBridgeArgs.Args = args
|
||||
tunnelClientArgs.Args = args
|
||||
tunnelServerArgs.Args = args
|
||||
|
||||
poster()
|
||||
//regist services and run service
|
||||
services.Regist("http", services.NewHTTP(), httpArgs)
|
||||
@ -119,9 +135,10 @@ func initConfig() (err error) {
|
||||
services.Regist("tserver", services.NewTunnelServerManager(), tunnelServerArgs)
|
||||
services.Regist("tclient", services.NewTunnelClient(), tunnelClientArgs)
|
||||
services.Regist("tbridge", services.NewTunnelBridge(), tunnelBridgeArgs)
|
||||
services.Regist("socks", services.NewSocks(), socksArgs)
|
||||
service, err = services.Run(serviceName)
|
||||
if err != nil {
|
||||
log.Fatalf("run service [%s] fail, ERR:%s", service, err)
|
||||
log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -138,16 +155,3 @@ func poster() {
|
||||
|
||||
v%s`+" by snail , blog : http://www.host900.com/\n\n", APP_VERSION)
|
||||
}
|
||||
func tlsBytes(cert, key string) (certBytes, keyBytes []byte) {
|
||||
certBytes, err := ioutil.ReadFile(cert)
|
||||
if err != nil {
|
||||
log.Fatalf("err : %s", err)
|
||||
return
|
||||
}
|
||||
keyBytes, err = ioutil.ReadFile(key)
|
||||
if err != nil {
|
||||
log.Fatalf("err : %s", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package services
|
||||
|
||||
import "golang.org/x/crypto/ssh"
|
||||
|
||||
// tcp := app.Command("tcp", "proxy on tcp mode")
|
||||
// t := tcp.Flag("tcp-timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
|
||||
|
||||
@ -13,32 +15,43 @@ const (
|
||||
CONN_CLIENT = uint8(3)
|
||||
)
|
||||
|
||||
type Args struct {
|
||||
type TunnelServerArgs struct {
|
||||
Parent *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
}
|
||||
type TunnelServerArgs struct {
|
||||
Args
|
||||
Local *string
|
||||
IsUDP *bool
|
||||
Key *string
|
||||
Remote *string
|
||||
Timeout *int
|
||||
Route *[]string
|
||||
Local *string
|
||||
IsUDP *bool
|
||||
Key *string
|
||||
Remote *string
|
||||
Timeout *int
|
||||
Route *[]string
|
||||
}
|
||||
type TunnelClientArgs struct {
|
||||
Args
|
||||
Key *string
|
||||
Timeout *int
|
||||
Parent *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Key *string
|
||||
Timeout *int
|
||||
}
|
||||
type TunnelBridgeArgs struct {
|
||||
Args
|
||||
Local *string
|
||||
Timeout *int
|
||||
Parent *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Local *string
|
||||
Timeout *int
|
||||
}
|
||||
type TCPArgs struct {
|
||||
Args
|
||||
Parent *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Local *string
|
||||
ParentType *string
|
||||
IsTLS *bool
|
||||
@ -48,7 +61,11 @@ type TCPArgs struct {
|
||||
}
|
||||
|
||||
type HTTPArgs struct {
|
||||
Args
|
||||
Parent *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Local *string
|
||||
Always *bool
|
||||
HTTPTimeout *int
|
||||
@ -62,15 +79,46 @@ type HTTPArgs struct {
|
||||
Timeout *int
|
||||
PoolSize *int
|
||||
CheckParentInterval *int
|
||||
SSHKeyFile *string
|
||||
SSHKeyFileSalt *string
|
||||
SSHPassword *string
|
||||
SSHUser *string
|
||||
SSHKeyBytes []byte
|
||||
SSHAuthMethod ssh.AuthMethod
|
||||
}
|
||||
type UDPArgs struct {
|
||||
Args
|
||||
Parent *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
Local *string
|
||||
ParentType *string
|
||||
Timeout *int
|
||||
PoolSize *int
|
||||
CheckParentInterval *int
|
||||
}
|
||||
type SocksArgs struct {
|
||||
Parent *string
|
||||
ParentType *string
|
||||
Local *string
|
||||
LocalType *string
|
||||
CertFile *string
|
||||
KeyFile *string
|
||||
CertBytes []byte
|
||||
KeyBytes []byte
|
||||
SSHKeyFile *string
|
||||
SSHKeyFileSalt *string
|
||||
SSHPassword *string
|
||||
SSHUser *string
|
||||
SSHKeyBytes []byte
|
||||
SSHAuthMethod ssh.AuthMethod
|
||||
Timeout *int
|
||||
Always *bool
|
||||
Interval *int
|
||||
Blocked *string
|
||||
Direct *string
|
||||
}
|
||||
|
||||
func (a *TCPArgs) Protocol() string {
|
||||
if *a.IsTLS {
|
||||
|
||||
104
services/http.go
104
services/http.go
@ -3,11 +3,15 @@ package services
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"proxy/utils"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type HTTP struct {
|
||||
@ -15,6 +19,7 @@ type HTTP struct {
|
||||
cfg HTTPArgs
|
||||
checker utils.Checker
|
||||
basicAuth utils.BasicAuth
|
||||
sshClient *ssh.Client
|
||||
}
|
||||
|
||||
func NewHTTP() Service {
|
||||
@ -26,15 +31,52 @@ func NewHTTP() Service {
|
||||
}
|
||||
}
|
||||
func (s *HTTP) CheckArgs() {
|
||||
var err error
|
||||
if *s.cfg.Parent != "" && *s.cfg.ParentType == "" {
|
||||
log.Fatalf("parent type unkown,use -T <tls|tcp>")
|
||||
}
|
||||
if *s.cfg.ParentType == "tls" || *s.cfg.LocalType == "tls" {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
if *s.cfg.ParentType == "ssh" {
|
||||
if *s.cfg.SSHUser == "" {
|
||||
log.Fatalf("ssh user required")
|
||||
}
|
||||
if *s.cfg.SSHKeyFile == "" && *s.cfg.SSHPassword == "" {
|
||||
log.Fatalf("ssh password or key required")
|
||||
}
|
||||
|
||||
if *s.cfg.SSHPassword != "" {
|
||||
s.cfg.SSHAuthMethod = ssh.Password(*s.cfg.SSHPassword)
|
||||
} else {
|
||||
var SSHSigner ssh.Signer
|
||||
s.cfg.SSHKeyBytes, err = ioutil.ReadFile(*s.cfg.SSHKeyFile)
|
||||
if err != nil {
|
||||
log.Fatalf("read key file ERR: %s", err)
|
||||
}
|
||||
if *s.cfg.SSHKeyFileSalt != "" {
|
||||
SSHSigner, err = ssh.ParsePrivateKeyWithPassphrase(s.cfg.SSHKeyBytes, []byte(*s.cfg.SSHKeyFileSalt))
|
||||
} else {
|
||||
SSHSigner, err = ssh.ParsePrivateKey(s.cfg.SSHKeyBytes)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("parse ssh private key fail,ERR: %s", err)
|
||||
}
|
||||
s.cfg.SSHAuthMethod = ssh.PublicKeys(SSHSigner)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (s *HTTP) InitService() {
|
||||
s.InitBasicAuth()
|
||||
if *s.cfg.Parent != "" {
|
||||
s.checker = utils.NewChecker(*s.cfg.HTTPTimeout, int64(*s.cfg.Interval), *s.cfg.Blocked, *s.cfg.Direct)
|
||||
}
|
||||
if *s.cfg.ParentType == "ssh" {
|
||||
err := s.ConnectSSH()
|
||||
if err != nil {
|
||||
log.Fatalf("init service fail, ERR: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (s *HTTP) StopService() {
|
||||
if s.outPool.Pool != nil {
|
||||
@ -99,8 +141,9 @@ func (s *HTTP) callback(inConn net.Conn) {
|
||||
//log.Printf("blocked ? : %v, %s , fail:%d ,success:%d", useProxy, address, n, m)
|
||||
}
|
||||
log.Printf("use proxy : %v, %s", useProxy, address)
|
||||
//os.Exit(0)
|
||||
|
||||
err = s.OutToTCP(useProxy, address, &inConn, &req)
|
||||
|
||||
if err != nil {
|
||||
if *s.cfg.Parent == "" {
|
||||
log.Printf("connect to %s fail, ERR:%s", address, err)
|
||||
@ -122,9 +165,13 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
|
||||
var outConn net.Conn
|
||||
var _outConn interface{}
|
||||
if useProxy {
|
||||
_outConn, err = s.outPool.Pool.Get()
|
||||
if err == nil {
|
||||
outConn = _outConn.(net.Conn)
|
||||
if *s.cfg.ParentType == "ssh" {
|
||||
outConn, err = s.getSSHConn(address)
|
||||
} else {
|
||||
_outConn, err = s.outPool.Pool.Get()
|
||||
if err == nil {
|
||||
outConn = _outConn.(net.Conn)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
outConn, err = utils.ConnectHost(address, *s.cfg.Timeout)
|
||||
@ -138,20 +185,61 @@ func (s *HTTP) OutToTCP(useProxy bool, address string, inConn *net.Conn, req *ut
|
||||
outAddr := outConn.RemoteAddr().String()
|
||||
outLocalAddr := outConn.LocalAddr().String()
|
||||
|
||||
if req.IsHTTPS() && !useProxy {
|
||||
req.HTTPSReply()
|
||||
if req.IsHTTPS() && (!useProxy || *s.cfg.ParentType == "ssh") {
|
||||
//https无上级或者上级非代理,proxy需要响应connect请求,并直连目标
|
||||
err = req.HTTPSReply()
|
||||
} else {
|
||||
outConn.Write(req.HeadBuf)
|
||||
//https或者http,上级是代理,proxy需要转发
|
||||
_, err = outConn.Write(req.HeadBuf)
|
||||
if err != nil {
|
||||
log.Printf("write to %s , err:%s", *s.cfg.Parent, err)
|
||||
utils.CloseConn(inConn)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
utils.IoBind((*inConn), outConn, func(err error) {
|
||||
log.Printf("conn %s - %s - %s - %s released [%s]", inAddr, inLocalAddr, outLocalAddr, outAddr, req.Host)
|
||||
utils.CloseConn(inConn)
|
||||
utils.CloseConn(&outConn)
|
||||
}, func(n int, d bool) {}, 0)
|
||||
log.Printf("conn %s - %s - %s - %s connected [%s]", inAddr, inLocalAddr, outLocalAddr, outAddr, req.Host)
|
||||
|
||||
return
|
||||
}
|
||||
func (s *HTTP) OutToUDP(inConn *net.Conn) (err error) {
|
||||
|
||||
func (s *HTTP) getSSHConn(host string) (outConn net.Conn, err error) {
|
||||
maxTryCount := 1
|
||||
tryCount := 0
|
||||
RETRY:
|
||||
if tryCount >= maxTryCount {
|
||||
return
|
||||
}
|
||||
outConn, err = s.sshClient.Dial("tcp", host)
|
||||
//log.Printf("s.sshClient.Dial, host:%s)", host)
|
||||
if err != nil {
|
||||
log.Printf("connect ssh fail, ERR: %s, retrying...", err)
|
||||
s.sshClient.Close()
|
||||
e := s.ConnectSSH()
|
||||
if e == nil {
|
||||
tryCount++
|
||||
time.Sleep(time.Second * 3)
|
||||
goto RETRY
|
||||
} else {
|
||||
err = e
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *HTTP) ConnectSSH() (err error) {
|
||||
config := ssh.ClientConfig{
|
||||
User: *s.cfg.SSHUser,
|
||||
Auth: []ssh.AuthMethod{s.cfg.SSHAuthMethod},
|
||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
s.sshClient, err = ssh.Dial("tcp", *s.cfg.Parent, &config)
|
||||
return
|
||||
}
|
||||
func (s *HTTP) InitOutConnPool() {
|
||||
|
||||
303
services/socks.go
Normal file
303
services/socks.go
Normal file
@ -0,0 +1,303 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"proxy/utils"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type Socks struct {
|
||||
cfg SocksArgs
|
||||
checker utils.Checker
|
||||
basicAuth utils.BasicAuth
|
||||
sshClient *ssh.Client
|
||||
}
|
||||
|
||||
func NewSocks() Service {
|
||||
return &Socks{
|
||||
cfg: SocksArgs{},
|
||||
checker: utils.Checker{},
|
||||
basicAuth: utils.BasicAuth{},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Socks) CheckArgs() {
|
||||
var err error
|
||||
if *s.cfg.Parent != "" {
|
||||
if *s.cfg.ParentType == "" {
|
||||
log.Fatalf("parent type unkown,use -T <tls|tcp|ssh>")
|
||||
}
|
||||
if *s.cfg.ParentType == "tls" || *s.cfg.LocalType == "tls" {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
if *s.cfg.ParentType == "ssh" {
|
||||
if *s.cfg.SSHUser == "" {
|
||||
log.Fatalf("ssh user required")
|
||||
}
|
||||
if *s.cfg.SSHKeyFile == "" && *s.cfg.SSHPassword == "" {
|
||||
log.Fatalf("ssh password or key required")
|
||||
}
|
||||
|
||||
if *s.cfg.SSHPassword != "" {
|
||||
s.cfg.SSHAuthMethod = ssh.Password(*s.cfg.SSHPassword)
|
||||
} else {
|
||||
var SSHSigner ssh.Signer
|
||||
s.cfg.SSHKeyBytes, err = ioutil.ReadFile(*s.cfg.SSHKeyFile)
|
||||
if err != nil {
|
||||
log.Fatalf("read key file ERR: %s", err)
|
||||
}
|
||||
if *s.cfg.SSHKeyFileSalt != "" {
|
||||
SSHSigner, err = ssh.ParsePrivateKeyWithPassphrase(s.cfg.SSHKeyBytes, []byte(*s.cfg.SSHKeyFileSalt))
|
||||
} else {
|
||||
SSHSigner, err = ssh.ParsePrivateKey(s.cfg.SSHKeyBytes)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("parse ssh private key fail,ERR: %s", err)
|
||||
}
|
||||
s.cfg.SSHAuthMethod = ssh.PublicKeys(SSHSigner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func (s *Socks) InitService() {
|
||||
s.checker = utils.NewChecker(*s.cfg.Timeout, int64(*s.cfg.Interval), *s.cfg.Blocked, *s.cfg.Direct)
|
||||
if *s.cfg.ParentType == "ssh" {
|
||||
err := s.ConnectSSH()
|
||||
if err != nil {
|
||||
log.Fatalf("init service fail, ERR: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (s *Socks) StopService() {
|
||||
if s.sshClient != nil {
|
||||
s.sshClient.Close()
|
||||
}
|
||||
}
|
||||
func (s *Socks) Start(args interface{}) (err error) {
|
||||
//start()
|
||||
s.cfg = args.(SocksArgs)
|
||||
s.CheckArgs()
|
||||
s.InitService()
|
||||
if *s.cfg.Parent != "" {
|
||||
log.Printf("use %s parent %s", *s.cfg.ParentType, *s.cfg.Parent)
|
||||
}
|
||||
sc := utils.NewServerChannelHost(*s.cfg.Local)
|
||||
if *s.cfg.LocalType == TYPE_TCP {
|
||||
err = sc.ListenTCP(s.callback)
|
||||
} else {
|
||||
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
log.Printf("%s socks proxy on %s", *s.cfg.LocalType, (*sc.Listener).Addr())
|
||||
return
|
||||
}
|
||||
func (s *Socks) Clean() {
|
||||
s.StopService()
|
||||
}
|
||||
func (s *Socks) callback(inConn net.Conn) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
//log.Printf("socks conn handler crashed with err : %s \nstack: %s", err, string(debug.Stack()))
|
||||
}
|
||||
utils.CloseConn(&inConn)
|
||||
}()
|
||||
var outConn net.Conn
|
||||
defer utils.CloseConn(&outConn)
|
||||
|
||||
var b [1024]byte
|
||||
n, err := inConn.Read(b[:])
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
log.Printf("read request data fail,ERR: %s", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var reqBytes = b[:n]
|
||||
//log.Printf("% x", b[:n])
|
||||
|
||||
//reply
|
||||
n, err = inConn.Write([]byte{0x05, 0x00})
|
||||
if err != nil {
|
||||
log.Printf("reply answer data fail,ERR: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
//read answer
|
||||
n, err = inConn.Read(b[:])
|
||||
if err != nil {
|
||||
log.Printf("read answer data fail,ERR: %s", err)
|
||||
return
|
||||
}
|
||||
var headBytes = b[:n]
|
||||
// log.Printf("% x", b[:n])
|
||||
var addr string
|
||||
switch b[3] {
|
||||
case 0x01:
|
||||
sip := sockIP{}
|
||||
if err := binary.Read(bytes.NewReader(b[4:n]), binary.BigEndian, &sip); err != nil {
|
||||
log.Printf("read ip fail,ERR: %s", err)
|
||||
return
|
||||
}
|
||||
addr = sip.toAddr()
|
||||
case 0x03:
|
||||
host := string(b[5 : n-2])
|
||||
var port uint16
|
||||
err = binary.Read(bytes.NewReader(b[n-2:n]), binary.BigEndian, &port)
|
||||
if err != nil {
|
||||
log.Printf("read domain fail,ERR: %s", err)
|
||||
return
|
||||
}
|
||||
addr = fmt.Sprintf("%s:%d", host, port)
|
||||
}
|
||||
useProxy := true
|
||||
if *s.cfg.Always {
|
||||
outConn, err = s.getOutConn(reqBytes, headBytes, addr)
|
||||
} else {
|
||||
if *s.cfg.Parent != "" {
|
||||
s.checker.Add(addr, true, "", "", nil)
|
||||
useProxy, _, _ = s.checker.IsBlocked(addr)
|
||||
if useProxy {
|
||||
outConn, err = s.getOutConn(reqBytes, headBytes, addr)
|
||||
} else {
|
||||
outConn, err = utils.ConnectHost(addr, *s.cfg.Timeout)
|
||||
}
|
||||
} else {
|
||||
outConn, err = utils.ConnectHost(addr, *s.cfg.Timeout)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("get out conn fail,%s", err)
|
||||
inConn.Write([]byte{0x05, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
||||
return
|
||||
}
|
||||
log.Printf("use proxy %v : %s", useProxy, addr)
|
||||
|
||||
inConn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
||||
|
||||
inAddr := inConn.RemoteAddr().String()
|
||||
inLocalAddr := inConn.LocalAddr().String()
|
||||
|
||||
log.Printf("conn %s - %s connected [%s]", inAddr, inLocalAddr, addr)
|
||||
// utils.IoBind(outConn, inConn, func(err error) {
|
||||
// log.Printf("conn %s - %s released [%s]", inAddr, inLocalAddr, addr)
|
||||
|
||||
// }, func(i int, b bool) {}, 0)
|
||||
var bind = func() (err interface{}) {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
if err = recover(); err != nil {
|
||||
log.Printf("bind crashed %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer func() {
|
||||
if err == nil {
|
||||
if err = recover(); err != nil {
|
||||
log.Printf("bind crashed %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
_, err = io.Copy(outConn, inConn)
|
||||
}()
|
||||
_, err = io.Copy(inConn, outConn)
|
||||
return
|
||||
}
|
||||
bind()
|
||||
log.Printf("conn %s - %s released [%s]", inAddr, inLocalAddr, addr)
|
||||
utils.CloseConn(&inConn)
|
||||
utils.CloseConn(&outConn)
|
||||
}
|
||||
func (s *Socks) getOutConn(reqBytes, headBytes []byte, host string) (outConn net.Conn, err error) {
|
||||
switch *s.cfg.ParentType {
|
||||
case "tls":
|
||||
fallthrough
|
||||
case "tcp":
|
||||
if *s.cfg.ParentType == "tls" {
|
||||
var _outConn tls.Conn
|
||||
_outConn, err = utils.TlsConnectHost(*s.cfg.Parent, *s.cfg.Timeout, s.cfg.CertBytes, s.cfg.KeyBytes)
|
||||
outConn = net.Conn(&_outConn)
|
||||
} else {
|
||||
outConn, err = utils.ConnectHost(*s.cfg.Parent, *s.cfg.Timeout)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var buf = make([]byte, 1024)
|
||||
//var n int
|
||||
_, err = outConn.Write(reqBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = outConn.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
//resp := buf[:n]
|
||||
//log.Printf("resp:%v", resp)
|
||||
|
||||
outConn.Write(headBytes)
|
||||
_, err = outConn.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
//result := buf[:n]
|
||||
//log.Printf("result:%v", result)
|
||||
|
||||
case "ssh":
|
||||
maxTryCount := 1
|
||||
tryCount := 0
|
||||
RETRY:
|
||||
if tryCount >= maxTryCount {
|
||||
return
|
||||
}
|
||||
outConn, err = s.sshClient.Dial("tcp", host)
|
||||
if err != nil {
|
||||
log.Printf("connect ssh fail, ERR: %s, retrying...", err)
|
||||
s.sshClient.Close()
|
||||
e := s.ConnectSSH()
|
||||
if e == nil {
|
||||
tryCount++
|
||||
time.Sleep(time.Second * 3)
|
||||
goto RETRY
|
||||
} else {
|
||||
err = e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
func (s *Socks) ConnectSSH() (err error) {
|
||||
config := ssh.ClientConfig{
|
||||
User: *s.cfg.SSHUser,
|
||||
Auth: []ssh.AuthMethod{s.cfg.SSHAuthMethod},
|
||||
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
s.sshClient, err = ssh.Dial("tcp", *s.cfg.Parent, &config)
|
||||
return
|
||||
}
|
||||
|
||||
type sockIP struct {
|
||||
A, B, C, D byte
|
||||
PORT uint16
|
||||
}
|
||||
|
||||
func (ip sockIP) toAddr() string {
|
||||
return fmt.Sprintf("%d.%d.%d.%d:%d", ip.A, ip.B, ip.C, ip.D, ip.PORT)
|
||||
}
|
||||
@ -31,6 +31,9 @@ func (s *TCP) CheckArgs() {
|
||||
if *s.cfg.ParentType == "" {
|
||||
log.Fatalf("parent type unkown,use -T <tls|tcp>")
|
||||
}
|
||||
if *s.cfg.ParentType == "tls" || *s.cfg.IsTLS {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
}
|
||||
func (s *TCP) InitService() {
|
||||
s.InitOutConnPool()
|
||||
|
||||
@ -33,10 +33,10 @@ func (s *TunnelBridge) InitService() {
|
||||
|
||||
}
|
||||
func (s *TunnelBridge) CheckArgs() {
|
||||
if s.cfg.CertBytes == nil || s.cfg.KeyBytes == nil {
|
||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||
log.Fatalf("cert and key file required")
|
||||
}
|
||||
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
func (s *TunnelBridge) StopService() {
|
||||
|
||||
|
||||
@ -31,9 +31,10 @@ func (s *TunnelClient) CheckArgs() {
|
||||
} else {
|
||||
log.Fatalf("parent required")
|
||||
}
|
||||
if s.cfg.CertBytes == nil || s.cfg.KeyBytes == nil {
|
||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||
log.Fatalf("cert and key file required")
|
||||
}
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
func (s *TunnelClient) StopService() {
|
||||
}
|
||||
|
||||
@ -61,12 +61,14 @@ func (s *TunnelServerManager) Start(args interface{}) (err error) {
|
||||
remote = fmt.Sprintf("127.0.0.1%s", remote)
|
||||
}
|
||||
err = server.Start(TunnelServerArgs{
|
||||
Args: s.cfg.Args,
|
||||
Local: &local,
|
||||
IsUDP: &IsUDP,
|
||||
Remote: &remote,
|
||||
Key: &KEY,
|
||||
Timeout: s.cfg.Timeout,
|
||||
CertBytes: s.cfg.CertBytes,
|
||||
KeyBytes: s.cfg.KeyBytes,
|
||||
Parent: s.cfg.Parent,
|
||||
Local: &local,
|
||||
IsUDP: &IsUDP,
|
||||
Remote: &remote,
|
||||
Key: &KEY,
|
||||
Timeout: s.cfg.Timeout,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
@ -97,9 +99,10 @@ func (s *TunnelServer) CheckArgs() {
|
||||
if *s.cfg.Remote == "" {
|
||||
log.Fatalf("remote required")
|
||||
}
|
||||
if s.cfg.CertBytes == nil || s.cfg.KeyBytes == nil {
|
||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||
log.Fatalf("cert and key file required")
|
||||
}
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
func (s *TunnelServer) StopService() {
|
||||
}
|
||||
|
||||
@ -34,6 +34,9 @@ func (s *UDP) CheckArgs() {
|
||||
if *s.cfg.ParentType == "" {
|
||||
log.Fatalf("parent type unkown,use -T <tls|tcp>")
|
||||
}
|
||||
if *s.cfg.ParentType == "tls" {
|
||||
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||
}
|
||||
}
|
||||
func (s *UDP) InitService() {
|
||||
if *s.cfg.ParentType != TYPE_UDP {
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
@ -311,6 +312,19 @@ func Uniqueid() string {
|
||||
s := fmt.Sprintf("%d", src.Int63())
|
||||
return s[len(s)-5:len(s)-1] + fmt.Sprintf("%d", uint64(time.Now().UnixNano()))[8:]
|
||||
}
|
||||
func TlsBytes(cert, key string) (certBytes, keyBytes []byte) {
|
||||
certBytes, err := ioutil.ReadFile(cert)
|
||||
if err != nil {
|
||||
log.Fatalf("err : %s", err)
|
||||
return
|
||||
}
|
||||
keyBytes, err = ioutil.ReadFile(key)
|
||||
if err != nil {
|
||||
log.Fatalf("err : %s", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// type sockaddr struct {
|
||||
// family uint16
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type ServerChannel struct {
|
||||
@ -24,6 +25,17 @@ func NewServerChannel(ip string, port int) ServerChannel {
|
||||
},
|
||||
}
|
||||
}
|
||||
func NewServerChannelHost(host string) ServerChannel {
|
||||
h, port, _ := net.SplitHostPort(host)
|
||||
p, _ := strconv.Atoi(port)
|
||||
return ServerChannel{
|
||||
ip: h,
|
||||
port: p,
|
||||
errAcceptHandler: func(err error) {
|
||||
log.Printf("accept error , ERR:%s", err)
|
||||
},
|
||||
}
|
||||
}
|
||||
func (sc *ServerChannel) SetErrAcceptHandler(fn func(err error)) {
|
||||
sc.errAcceptHandler = fn
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user