Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4681ff3827 | ||
|
|
cff92faf06 | ||
|
|
890daf5489 | ||
|
|
182bdeb766 | ||
|
|
a4a953b167 | ||
|
|
ff37b7e18c | ||
|
|
7aa0e78c15 | ||
|
|
d798807693 | ||
|
|
35b78c2da6 | ||
|
|
66a4291c97 | ||
|
|
e89a965aff | ||
|
|
85a9f10be4 | ||
|
|
8bc6e0ffec | ||
|
|
98fc0ade4a | ||
|
|
f5626c21f7 | ||
|
|
b5a76c7ff2 | ||
|
|
612bae4c93 | ||
|
|
e45bf338cb | ||
|
|
577261806c | ||
|
|
8842097bd4 | ||
|
|
a4b14dd0bd | ||
|
|
94f0142c7d |
11
CHANGELOG
11
CHANGELOG
@ -1,4 +1,15 @@
|
|||||||
proxy更新日志
|
proxy更新日志
|
||||||
|
v3.8
|
||||||
|
1.增加了日志输出到文件--log参数,比如: --log proxy.log,日志就会输出到proxy.log方便排除问题.
|
||||||
|
|
||||||
|
v3.7
|
||||||
|
1.修复了socks代理不能正常和上级代理通讯的问题.
|
||||||
|
|
||||||
|
|
||||||
|
v3.6
|
||||||
|
1.http(s),socks代理,集成了外部HTTP API认证,可以通过外部API对用户名和密码进行认证.
|
||||||
|
2.手册http(s),socks代理认证部分增加了集成外部HTTP API认证的使用说明.
|
||||||
|
|
||||||
v3.5
|
v3.5
|
||||||
1.优化了kcp参数,速度有所提升.
|
1.优化了kcp参数,速度有所提升.
|
||||||
2.修复了socks无法正常工作的问题.
|
2.修复了socks无法正常工作的问题.
|
||||||
|
|||||||
47
README.md
47
README.md
@ -14,7 +14,8 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
|
|||||||
- 多协议支持,支持HTTP(S),TCP,UDP,Websocket,SOCKS5代理.
|
- 多协议支持,支持HTTP(S),TCP,UDP,Websocket,SOCKS5代理.
|
||||||
- 支持内网穿透,协议支持TCP和UDP.
|
- 支持内网穿透,协议支持TCP和UDP.
|
||||||
- SSH中转,HTTP(S),SOCKS5代理支持SSH中转,上级Linux服务器不需要任何服务端,本地一个proxy即可开心上网.
|
- SSH中转,HTTP(S),SOCKS5代理支持SSH中转,上级Linux服务器不需要任何服务端,本地一个proxy即可开心上网.
|
||||||
- 支持[KCP](https://github.com/xtaci/kcp-go)协议,HTTP(S),SOCKS5代理支持KCP协议传输数据,降低延迟,提升浏览体验.
|
- [KCP](https://github.com/xtaci/kcp-go)协议支持,HTTP(S),SOCKS5代理支持KCP协议传输数据,降低延迟,提升浏览体验.
|
||||||
|
- 集成外部API,HTTP(S),SOCKS5代理认证功能可以与外部HTTP API集成,可以方便的通过外部系统控制代理用户.
|
||||||
|
|
||||||
### Why need these?
|
### Why need these?
|
||||||
- 当由于某某原因,我们不能访问我们在其它地方的服务,我们可以通过多个相连的proxy节点建立起一个安全的隧道访问我们的服务.
|
- 当由于某某原因,我们不能访问我们在其它地方的服务,我们可以通过多个相连的proxy节点建立起一个安全的隧道访问我们的服务.
|
||||||
@ -26,13 +27,18 @@ Proxy是golang实现的高性能http,https,websocket,tcp,udp,socks5代理服务
|
|||||||
- ...
|
- ...
|
||||||
|
|
||||||
|
|
||||||
本页是v3.4手册,其他版本手册请点击下面链接查看.
|
本页是v3.6-v3.7手册,其他版本手册请点击下面链接查看.
|
||||||
|
- [v3.5手册](https://github.com/snail007/goproxy/tree/v3.5)
|
||||||
|
- [v3.4手册](https://github.com/snail007/goproxy/tree/v3.4)
|
||||||
- [v3.3手册](https://github.com/snail007/goproxy/tree/v3.3)
|
- [v3.3手册](https://github.com/snail007/goproxy/tree/v3.3)
|
||||||
- [v3.2手册](https://github.com/snail007/goproxy/tree/v3.2)
|
- [v3.2手册](https://github.com/snail007/goproxy/tree/v3.2)
|
||||||
- [v3.1手册](https://github.com/snail007/goproxy/tree/v3.1)
|
- [v3.1手册](https://github.com/snail007/goproxy/tree/v3.1)
|
||||||
- [v3.0手册](https://github.com/snail007/goproxy/tree/v3.0)
|
- [v3.0手册](https://github.com/snail007/goproxy/tree/v3.0)
|
||||||
- [v2.x手册](https://github.com/snail007/goproxy/tree/v2.2)
|
- [v2.x手册](https://github.com/snail007/goproxy/tree/v2.2)
|
||||||
|
|
||||||
|
### 怎么找到组织?
|
||||||
|
[点击加入交流组织](https://gitter.im/go-proxy/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
|
||||||
|
|
||||||
### 安装
|
### 安装
|
||||||
1. [快速安装](#自动安装)
|
1. [快速安装](#自动安装)
|
||||||
1. [手动安装](#手动安装)
|
1. [手动安装](#手动安装)
|
||||||
@ -117,7 +123,7 @@ wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_li
|
|||||||
下载地址:https://github.com/snail007/goproxy/releases
|
下载地址:https://github.com/snail007/goproxy/releases
|
||||||
```shell
|
```shell
|
||||||
cd /root/proxy/
|
cd /root/proxy/
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v3.4/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v3.8/proxy-linux-amd64.tar.gz
|
||||||
```
|
```
|
||||||
#### **3.下载自动安装脚本**
|
#### **3.下载自动安装脚本**
|
||||||
```shell
|
```shell
|
||||||
@ -203,7 +209,21 @@ http,tcp,udp代理过程会和上级通讯,为了安全我们采用加密通讯,
|
|||||||
多个用户,重复-a参数即可.
|
多个用户,重复-a参数即可.
|
||||||
也可以放在文件中,格式是一行一个"用户名:密码",然后用-F指定.
|
也可以放在文件中,格式是一行一个"用户名:密码",然后用-F指定.
|
||||||
`./proxy http -t tcp -p ":33080" -F auth-file.txt`
|
`./proxy http -t tcp -p ":33080" -F auth-file.txt`
|
||||||
如果没有-a或-F参数,就是关闭Basic认证.
|
|
||||||
|
另外,http(s)代理还集成了外部HTTP API认证,我们可以通过--auth-url参数指定一个http url接口地址,
|
||||||
|
然后有用户连接的时候,proxy会GET方式请求这url,带上下面四个参数,如果返回HTTP状态码204,代表认证成功
|
||||||
|
其它情况认为认证失败.
|
||||||
|
比如:
|
||||||
|
`./proxy http -t tcp -p ":33080" --auth-url "http://test.com/auth.php"`
|
||||||
|
用户连接的时候,proxy会GET方式请求这url("http://test.com/auth.php"),
|
||||||
|
带上user,pass,ip,target四个参数:
|
||||||
|
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}&target={TARGET}
|
||||||
|
user:用户名
|
||||||
|
pass:密码
|
||||||
|
ip:用户的IP,比如:192.168.1.200
|
||||||
|
target:用户访问的URL,比如:http://demo.com:80/1.html或https://www.baidu.com:80
|
||||||
|
|
||||||
|
如果没有-a或-F或--auth-url参数,就是关闭Basic认证.
|
||||||
|
|
||||||
#### **1.6.HTTP代理流量强制走上级HTTP代理**
|
#### **1.6.HTTP代理流量强制走上级HTTP代理**
|
||||||
默认情况下,proxy会智能判断一个网站域名是否无法访问,如果无法访问才走上级HTTP代理.通过--always可以使全部HTTP代理流量强制走上级HTTP代理.
|
默认情况下,proxy会智能判断一个网站域名是否无法访问,如果无法访问才走上级HTTP代理.通过--always可以使全部HTTP代理流量强制走上级HTTP代理.
|
||||||
@ -383,7 +403,7 @@ VPS(IP:22.22.22.33)执行:
|
|||||||
`./proxy tserver --udp -r ":53@:53" -P "127.0.0.1:33080" -C proxy.crt -K proxy.key`
|
`./proxy tserver --udp -r ":53@:53" -P "127.0.0.1:33080" -C proxy.crt -K proxy.key`
|
||||||
|
|
||||||
1. 在公司机器A上面执行
|
1. 在公司机器A上面执行
|
||||||
`./proxy tclient --udp -P "22.22.22.22:33080" -C proxy.crt -K proxy.key`
|
`./proxy tclient -P "22.22.22.22:33080" -C proxy.crt -K proxy.key`
|
||||||
|
|
||||||
1. 完成
|
1. 完成
|
||||||
|
|
||||||
@ -510,7 +530,20 @@ server连接到bridge的时候,如果同时有多个client连接到同一个brid
|
|||||||
多个用户,重复-a参数即可.
|
多个用户,重复-a参数即可.
|
||||||
也可以放在文件中,格式是一行一个"用户名:密码",然后用-F指定.
|
也可以放在文件中,格式是一行一个"用户名:密码",然后用-F指定.
|
||||||
`./proxy socks -t tcp -p ":33080" -F auth-file.txt`
|
`./proxy socks -t tcp -p ":33080" -F auth-file.txt`
|
||||||
如果没有-a或-F参数,就是关闭认证.
|
|
||||||
|
另外,socks5代理还集成了外部HTTP API认证,我们可以通过--auth-url参数指定一个http url接口地址,
|
||||||
|
然后有用户连接的时候,proxy会GET方式请求这url,带上下面四个参数,如果返回HTTP状态码204,代表认证成功
|
||||||
|
其它情况认为认证失败.
|
||||||
|
比如:
|
||||||
|
`./proxy socks -t tcp -p ":33080" --auth-url "http://test.com/auth.php"`
|
||||||
|
用户连接的时候,proxy会GET方式请求这url("http://test.com/auth.php"),
|
||||||
|
带上user,pass,ip,三个参数:
|
||||||
|
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}
|
||||||
|
user:用户名
|
||||||
|
pass:密码
|
||||||
|
ip:用户的IP,比如:192.168.1.200
|
||||||
|
|
||||||
|
如果没有-a或-F或--auth-url参数,就是关闭认证.
|
||||||
|
|
||||||
#### **5.8.KCP协议传输**
|
#### **5.8.KCP协议传输**
|
||||||
KCP协议需要-B参数设置一个密码用于加密解密数据
|
KCP协议需要-B参数设置一个密码用于加密解密数据
|
||||||
@ -527,7 +560,7 @@ KCP协议需要-B参数设置一个密码用于加密解密数据
|
|||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- http,socks代理多个上级负载均衡?
|
- http,socks代理多个上级负载均衡?
|
||||||
- 内网穿透server<->bridge心跳机制?
|
- 内网穿透增加multiplexing模式?
|
||||||
- 欢迎加群反馈...
|
- 欢迎加群反馈...
|
||||||
|
|
||||||
### 如何使用源码?
|
### 如何使用源码?
|
||||||
|
|||||||
24
config.go
24
config.go
@ -38,6 +38,8 @@ func initConfig() (err error) {
|
|||||||
app.Author("snail").Version(APP_VERSION)
|
app.Author("snail").Version(APP_VERSION)
|
||||||
debug := app.Flag("debug", "debug log output").Default("false").Bool()
|
debug := app.Flag("debug", "debug log output").Default("false").Bool()
|
||||||
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool()
|
||||||
|
logfile := app.Flag("log", "log file path").Default("").String()
|
||||||
|
|
||||||
//########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()
|
||||||
@ -63,6 +65,10 @@ func initConfig() (err error) {
|
|||||||
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()
|
httpArgs.LocalIPS = http.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
||||||
|
httpArgs.AuthURL = http.Flag("auth-url", "http basic auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
|
||||||
|
httpArgs.AuthURLTimeout = http.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
|
||||||
|
httpArgs.AuthURLOkCode = http.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int()
|
||||||
|
httpArgs.AuthURLRetry = http.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("1").Int()
|
||||||
|
|
||||||
//########tcp#########
|
//########tcp#########
|
||||||
tcp := app.Command("tcp", "proxy on tcp mode")
|
tcp := app.Command("tcp", "proxy on tcp mode")
|
||||||
@ -98,6 +104,7 @@ func initConfig() (err error) {
|
|||||||
tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool()
|
tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool()
|
||||||
tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String()
|
tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String()
|
||||||
tunnelServerArgs.Route = tunnelServer.Flag("route", "local route to client's network, such as :PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings()
|
tunnelServerArgs.Route = tunnelServer.Flag("route", "local route to client's network, such as :PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings()
|
||||||
|
tunnelServerArgs.Mux = tunnelServer.Flag("mux", "use multiplexing mode").Default("false").Bool()
|
||||||
|
|
||||||
//########tunnel-client#########
|
//########tunnel-client#########
|
||||||
tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
|
tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
|
||||||
@ -106,6 +113,7 @@ func initConfig() (err error) {
|
|||||||
tunnelClientArgs.KeyFile = tunnelClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").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.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()
|
tunnelClientArgs.Key = tunnelClient.Flag("k", "key same with server").Default("default").String()
|
||||||
|
tunnelClientArgs.Mux = tunnelClient.Flag("mux", "use multiplexing mode").Default("false").Bool()
|
||||||
|
|
||||||
//########tunnel-bridge#########
|
//########tunnel-bridge#########
|
||||||
tunnelBridge := app.Command("tbridge", "proxy on tunnel bridge mode")
|
tunnelBridge := app.Command("tbridge", "proxy on tunnel bridge mode")
|
||||||
@ -113,6 +121,7 @@ func initConfig() (err error) {
|
|||||||
tunnelBridgeArgs.KeyFile = tunnelBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").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.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()
|
tunnelBridgeArgs.Local = tunnelBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||||
|
tunnelBridgeArgs.Mux = tunnelBridge.Flag("mux", "use multiplexing mode").Default("false").Bool()
|
||||||
|
|
||||||
//########ssh#########
|
//########ssh#########
|
||||||
socks := app.Command("socks", "proxy on ssh mode")
|
socks := app.Command("socks", "proxy on ssh mode")
|
||||||
@ -138,6 +147,10 @@ func initConfig() (err error) {
|
|||||||
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()
|
socksArgs.LocalIPS = socks.Flag("local bind ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
|
||||||
|
socksArgs.AuthURL = socks.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
|
||||||
|
socksArgs.AuthURLTimeout = socks.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
|
||||||
|
socksArgs.AuthURLOkCode = socks.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int()
|
||||||
|
socksArgs.AuthURLRetry = socks.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int()
|
||||||
|
|
||||||
//parse args
|
//parse args
|
||||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
@ -160,7 +173,16 @@ func initConfig() (err error) {
|
|||||||
flags |= log.Ltime
|
flags |= log.Ltime
|
||||||
}
|
}
|
||||||
log.SetFlags(flags)
|
log.SetFlags(flags)
|
||||||
poster()
|
|
||||||
|
if *logfile != "" {
|
||||||
|
f, e := os.OpenFile(*logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
||||||
|
if e != nil {
|
||||||
|
log.Fatal(e)
|
||||||
|
}
|
||||||
|
log.SetOutput(f)
|
||||||
|
} else {
|
||||||
|
poster()
|
||||||
|
}
|
||||||
//regist services and run service
|
//regist services and run service
|
||||||
services.Regist("http", services.NewHTTP(), httpArgs)
|
services.Regist("http", services.NewHTTP(), httpArgs)
|
||||||
services.Regist("tcp", services.NewTCP(), tcpArgs)
|
services.Regist("tcp", services.NewTCP(), tcpArgs)
|
||||||
|
|||||||
@ -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.4/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v3.8/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.5"
|
const APP_VERSION = "3.8"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := initConfig()
|
err := initConfig()
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
VER="3.5"
|
VER="3.8"
|
||||||
RELEASE="release-${VER}"
|
RELEASE="release-${VER}"
|
||||||
rm -rf .cert
|
rm -rf .cert
|
||||||
mkdir .cert
|
mkdir .cert
|
||||||
|
|||||||
@ -16,6 +16,8 @@ const (
|
|||||||
CONN_SERVER_HEARBEAT = uint8(3)
|
CONN_SERVER_HEARBEAT = uint8(3)
|
||||||
CONN_SERVER = uint8(4)
|
CONN_SERVER = uint8(4)
|
||||||
CONN_CLIENT = uint8(5)
|
CONN_CLIENT = uint8(5)
|
||||||
|
CONN_SERVER_MUX = uint8(6)
|
||||||
|
CONN_CLIENT_MUX = uint8(7)
|
||||||
)
|
)
|
||||||
|
|
||||||
type TunnelServerArgs struct {
|
type TunnelServerArgs struct {
|
||||||
@ -31,6 +33,7 @@ type TunnelServerArgs struct {
|
|||||||
Timeout *int
|
Timeout *int
|
||||||
Route *[]string
|
Route *[]string
|
||||||
Mgr *TunnelServerManager
|
Mgr *TunnelServerManager
|
||||||
|
Mux *bool
|
||||||
}
|
}
|
||||||
type TunnelClientArgs struct {
|
type TunnelClientArgs struct {
|
||||||
Parent *string
|
Parent *string
|
||||||
@ -40,6 +43,7 @@ type TunnelClientArgs struct {
|
|||||||
KeyBytes []byte
|
KeyBytes []byte
|
||||||
Key *string
|
Key *string
|
||||||
Timeout *int
|
Timeout *int
|
||||||
|
Mux *bool
|
||||||
}
|
}
|
||||||
type TunnelBridgeArgs struct {
|
type TunnelBridgeArgs struct {
|
||||||
Parent *string
|
Parent *string
|
||||||
@ -49,6 +53,7 @@ type TunnelBridgeArgs struct {
|
|||||||
KeyBytes []byte
|
KeyBytes []byte
|
||||||
Local *string
|
Local *string
|
||||||
Timeout *int
|
Timeout *int
|
||||||
|
Mux *bool
|
||||||
}
|
}
|
||||||
type TCPArgs struct {
|
type TCPArgs struct {
|
||||||
Parent *string
|
Parent *string
|
||||||
@ -80,6 +85,10 @@ type HTTPArgs struct {
|
|||||||
Direct *string
|
Direct *string
|
||||||
AuthFile *string
|
AuthFile *string
|
||||||
Auth *[]string
|
Auth *[]string
|
||||||
|
AuthURL *string
|
||||||
|
AuthURLOkCode *int
|
||||||
|
AuthURLTimeout *int
|
||||||
|
AuthURLRetry *int
|
||||||
ParentType *string
|
ParentType *string
|
||||||
LocalType *string
|
LocalType *string
|
||||||
Timeout *int
|
Timeout *int
|
||||||
@ -129,6 +138,10 @@ type SocksArgs struct {
|
|||||||
Direct *string
|
Direct *string
|
||||||
AuthFile *string
|
AuthFile *string
|
||||||
Auth *[]string
|
Auth *[]string
|
||||||
|
AuthURL *string
|
||||||
|
AuthURLOkCode *int
|
||||||
|
AuthURLTimeout *int
|
||||||
|
AuthURLRetry *int
|
||||||
KCPMethod *string
|
KCPMethod *string
|
||||||
KCPKey *string
|
KCPKey *string
|
||||||
UDPParent *string
|
UDPParent *string
|
||||||
|
|||||||
@ -146,7 +146,7 @@ func (s *HTTP) callback(inConn net.Conn) {
|
|||||||
req, err = utils.NewHTTPRequest(&inConn, 4096, s.IsBasicAuth(), &s.basicAuth)
|
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 , from %s, ERR:%s", inConn.RemoteAddr(), err)
|
||||||
}
|
}
|
||||||
utils.CloseConn(&inConn)
|
utils.CloseConn(&inConn)
|
||||||
return
|
return
|
||||||
@ -322,6 +322,10 @@ func (s *HTTP) InitOutConnPool() {
|
|||||||
}
|
}
|
||||||
func (s *HTTP) InitBasicAuth() (err error) {
|
func (s *HTTP) InitBasicAuth() (err error) {
|
||||||
s.basicAuth = utils.NewBasicAuth()
|
s.basicAuth = utils.NewBasicAuth()
|
||||||
|
if *s.cfg.AuthURL != "" {
|
||||||
|
s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry)
|
||||||
|
log.Printf("auth from %s", *s.cfg.AuthURL)
|
||||||
|
}
|
||||||
if *s.cfg.AuthFile != "" {
|
if *s.cfg.AuthFile != "" {
|
||||||
var n = 0
|
var n = 0
|
||||||
n, err = s.basicAuth.AddFromFile(*s.cfg.AuthFile)
|
n, err = s.basicAuth.AddFromFile(*s.cfg.AuthFile)
|
||||||
@ -338,7 +342,7 @@ func (s *HTTP) InitBasicAuth() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *HTTP) IsBasicAuth() bool {
|
func (s *HTTP) IsBasicAuth() bool {
|
||||||
return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0
|
return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0 || *s.cfg.AuthURL != ""
|
||||||
}
|
}
|
||||||
func (s *HTTP) IsDeadLoop(inLocalAddr string, host string) bool {
|
func (s *HTTP) IsDeadLoop(inLocalAddr string, host string) bool {
|
||||||
inIP, inPort, err := net.SplitHostPort(inLocalAddr)
|
inIP, inPort, err := net.SplitHostPort(inLocalAddr)
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"proxy/utils/aes"
|
"proxy/utils/aes"
|
||||||
"proxy/utils/socks"
|
"proxy/utils/socks"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
@ -353,7 +354,8 @@ func (s *Socks) socksConnCallback(inConn net.Conn) {
|
|||||||
pass := string(r[2+r[1]+1:])
|
pass := string(r[2+r[1]+1:])
|
||||||
//log.Printf("user:%s,pass:%s", user, pass)
|
//log.Printf("user:%s,pass:%s", user, pass)
|
||||||
//auth
|
//auth
|
||||||
if s.basicAuth.CheckUserPass(user, pass) {
|
_addr := strings.Split(inConn.RemoteAddr().String(), ":")
|
||||||
|
if s.basicAuth.CheckUserPass(user, pass, _addr[0], "") {
|
||||||
inConn.Write([]byte{0x01, 0x00})
|
inConn.Write([]byte{0x01, 0x00})
|
||||||
} else {
|
} else {
|
||||||
inConn.Write([]byte{0x01, 0x01})
|
inConn.Write([]byte{0x01, 0x01})
|
||||||
@ -490,11 +492,11 @@ func (s *Socks) getOutConn(methodBytes, reqBytes []byte, host string) (outConn n
|
|||||||
err = fmt.Errorf("write req detail fail,%s", err)
|
err = fmt.Errorf("write req detail fail,%s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// _, err = outConn.Read(buf)
|
_, err = outConn.Read(buf)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// err = fmt.Errorf("read req reply fail,%s", err)
|
err = fmt.Errorf("read req reply fail,%s", err)
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
//result := buf[:n]
|
//result := buf[:n]
|
||||||
//log.Printf("result:%v", result)
|
//log.Printf("result:%v", result)
|
||||||
|
|
||||||
@ -560,6 +562,10 @@ func (s *Socks) ConnectSSH() (err error) {
|
|||||||
}
|
}
|
||||||
func (s *Socks) InitBasicAuth() (err error) {
|
func (s *Socks) InitBasicAuth() (err error) {
|
||||||
s.basicAuth = utils.NewBasicAuth()
|
s.basicAuth = utils.NewBasicAuth()
|
||||||
|
if *s.cfg.AuthURL != "" {
|
||||||
|
s.basicAuth.SetAuthURL(*s.cfg.AuthURL, *s.cfg.AuthURLOkCode, *s.cfg.AuthURLTimeout, *s.cfg.AuthURLRetry)
|
||||||
|
log.Printf("auth from %s", *s.cfg.AuthURL)
|
||||||
|
}
|
||||||
if *s.cfg.AuthFile != "" {
|
if *s.cfg.AuthFile != "" {
|
||||||
var n = 0
|
var n = 0
|
||||||
n, err = s.basicAuth.AddFromFile(*s.cfg.AuthFile)
|
n, err = s.basicAuth.AddFromFile(*s.cfg.AuthFile)
|
||||||
@ -576,7 +582,7 @@ func (s *Socks) InitBasicAuth() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
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 || *s.cfg.AuthURL != ""
|
||||||
}
|
}
|
||||||
func (s *Socks) IsDeadLoop(inLocalAddr string, host string) bool {
|
func (s *Socks) IsDeadLoop(inLocalAddr string, host string) bool {
|
||||||
inIP, inPort, err := net.SplitHostPort(inLocalAddr)
|
inIP, inPort, err := net.SplitHostPort(inLocalAddr)
|
||||||
|
|||||||
@ -17,8 +17,8 @@ type TunnelBridge struct {
|
|||||||
cfg TunnelBridgeArgs
|
cfg TunnelBridgeArgs
|
||||||
serverConns utils.ConcurrentMap
|
serverConns utils.ConcurrentMap
|
||||||
clientControlConns utils.ConcurrentMap
|
clientControlConns utils.ConcurrentMap
|
||||||
cmServer utils.ConnManager
|
// cmServer utils.ConnManager
|
||||||
cmClient utils.ConnManager
|
// cmClient utils.ConnManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTunnelBridge() Service {
|
func NewTunnelBridge() Service {
|
||||||
@ -26,8 +26,8 @@ func NewTunnelBridge() Service {
|
|||||||
cfg: TunnelBridgeArgs{},
|
cfg: TunnelBridgeArgs{},
|
||||||
serverConns: utils.NewConcurrentMap(),
|
serverConns: utils.NewConcurrentMap(),
|
||||||
clientControlConns: utils.NewConcurrentMap(),
|
clientControlConns: utils.NewConcurrentMap(),
|
||||||
cmServer: utils.NewConnManager(),
|
// cmServer: utils.NewConnManager(),
|
||||||
cmClient: utils.NewConnManager(),
|
// cmClient: utils.NewConnManager(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
|
|||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
s.cmServer.Add(serverID, ID, &inConn)
|
// s.cmServer.Add(serverID, ID, &inConn)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,11 +114,11 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
|
|||||||
serverConn := serverConnItem.(ServerConn).Conn
|
serverConn := serverConnItem.(ServerConn).Conn
|
||||||
utils.IoBind(*serverConn, inConn, func(err interface{}) {
|
utils.IoBind(*serverConn, inConn, func(err interface{}) {
|
||||||
s.serverConns.Remove(ID)
|
s.serverConns.Remove(ID)
|
||||||
s.cmClient.RemoveOne(key, ID)
|
// s.cmClient.RemoveOne(key, ID)
|
||||||
s.cmServer.RemoveOne(serverID, ID)
|
// s.cmServer.RemoveOne(serverID, ID)
|
||||||
log.Printf("conn %s released", ID)
|
log.Printf("conn %s released", ID)
|
||||||
})
|
})
|
||||||
s.cmClient.Add(key, ID, &inConn)
|
// s.cmClient.Add(key, ID, &inConn)
|
||||||
log.Printf("conn %s created", ID)
|
log.Printf("conn %s created", ID)
|
||||||
|
|
||||||
case CONN_CLIENT_CONTROL:
|
case CONN_CLIENT_CONTROL:
|
||||||
@ -136,101 +136,101 @@ func (s *TunnelBridge) Start(args interface{}) (err error) {
|
|||||||
s.clientControlConns.Set(key, &inConn)
|
s.clientControlConns.Set(key, &inConn)
|
||||||
log.Printf("set client %s control conn", key)
|
log.Printf("set client %s control conn", key)
|
||||||
|
|
||||||
case CONN_SERVER_HEARBEAT:
|
// case CONN_SERVER_HEARBEAT:
|
||||||
var serverID string
|
// var serverID string
|
||||||
err = utils.ReadPacketData(reader, &serverID)
|
// err = utils.ReadPacketData(reader, &serverID)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("read error,ERR:%s", err)
|
// log.Printf("read error,ERR:%s", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
log.Printf("server heartbeat connection, id: %s", serverID)
|
// log.Printf("server heartbeat connection, id: %s", serverID)
|
||||||
writeDie := make(chan bool)
|
// writeDie := make(chan bool)
|
||||||
readDie := make(chan bool)
|
// readDie := make(chan bool)
|
||||||
go func() {
|
// go func() {
|
||||||
for {
|
// for {
|
||||||
inConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
// inConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
||||||
_, err = inConn.Write([]byte{0x00})
|
// _, err = inConn.Write([]byte{0x00})
|
||||||
inConn.SetWriteDeadline(time.Time{})
|
// inConn.SetWriteDeadline(time.Time{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("server heartbeat connection write err %s", err)
|
// log.Printf("server heartbeat connection write err %s", err)
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
time.Sleep(time.Second * 3)
|
// time.Sleep(time.Second * 3)
|
||||||
}
|
// }
|
||||||
close(writeDie)
|
// close(writeDie)
|
||||||
}()
|
// }()
|
||||||
go func() {
|
// go func() {
|
||||||
for {
|
// for {
|
||||||
signal := make([]byte, 1)
|
// signal := make([]byte, 1)
|
||||||
inConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
// inConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
||||||
_, err := inConn.Read(signal)
|
// _, err := inConn.Read(signal)
|
||||||
inConn.SetReadDeadline(time.Time{})
|
// inConn.SetReadDeadline(time.Time{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("server heartbeat connection read err: %s", err)
|
// log.Printf("server heartbeat connection read err: %s", err)
|
||||||
break
|
// break
|
||||||
} else {
|
// } else {
|
||||||
// log.Printf("heartbeat from server ,id:%s", serverID)
|
// // log.Printf("heartbeat from server ,id:%s", serverID)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
close(readDie)
|
// close(readDie)
|
||||||
}()
|
// }()
|
||||||
select {
|
// select {
|
||||||
case <-readDie:
|
// case <-readDie:
|
||||||
case <-writeDie:
|
// case <-writeDie:
|
||||||
}
|
// }
|
||||||
utils.CloseConn(&inConn)
|
// utils.CloseConn(&inConn)
|
||||||
s.cmServer.Remove(serverID)
|
// s.cmServer.Remove(serverID)
|
||||||
log.Printf("server heartbeat conn %s released", serverID)
|
// log.Printf("server heartbeat conn %s released", serverID)
|
||||||
case CONN_CLIENT_HEARBEAT:
|
// case CONN_CLIENT_HEARBEAT:
|
||||||
var clientID string
|
// var clientID string
|
||||||
err = utils.ReadPacketData(reader, &clientID)
|
// err = utils.ReadPacketData(reader, &clientID)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("read error,ERR:%s", err)
|
// log.Printf("read error,ERR:%s", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
log.Printf("client heartbeat connection, id: %s", clientID)
|
// log.Printf("client heartbeat connection, id: %s", clientID)
|
||||||
writeDie := make(chan bool)
|
// writeDie := make(chan bool)
|
||||||
readDie := make(chan bool)
|
// readDie := make(chan bool)
|
||||||
go func() {
|
// go func() {
|
||||||
for {
|
// for {
|
||||||
inConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
// inConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
||||||
_, err = inConn.Write([]byte{0x00})
|
// _, err = inConn.Write([]byte{0x00})
|
||||||
inConn.SetWriteDeadline(time.Time{})
|
// inConn.SetWriteDeadline(time.Time{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("client heartbeat connection write err %s", err)
|
// log.Printf("client heartbeat connection write err %s", err)
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
time.Sleep(time.Second * 3)
|
// time.Sleep(time.Second * 3)
|
||||||
}
|
// }
|
||||||
close(writeDie)
|
// close(writeDie)
|
||||||
}()
|
// }()
|
||||||
go func() {
|
// go func() {
|
||||||
for {
|
// for {
|
||||||
signal := make([]byte, 1)
|
// signal := make([]byte, 1)
|
||||||
inConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
// inConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
||||||
_, err := inConn.Read(signal)
|
// _, err := inConn.Read(signal)
|
||||||
inConn.SetReadDeadline(time.Time{})
|
// inConn.SetReadDeadline(time.Time{})
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
log.Printf("client control connection read err: %s", err)
|
// log.Printf("client control connection read err: %s", err)
|
||||||
break
|
// break
|
||||||
} else {
|
// } else {
|
||||||
// log.Printf("heartbeat from client ,id:%s", clientID)
|
// // log.Printf("heartbeat from client ,id:%s", clientID)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
close(readDie)
|
// close(readDie)
|
||||||
}()
|
// }()
|
||||||
select {
|
// select {
|
||||||
case <-readDie:
|
// case <-readDie:
|
||||||
case <-writeDie:
|
// case <-writeDie:
|
||||||
}
|
// }
|
||||||
utils.CloseConn(&inConn)
|
// utils.CloseConn(&inConn)
|
||||||
s.cmClient.Remove(clientID)
|
// s.cmClient.Remove(clientID)
|
||||||
if s.clientControlConns.Has(clientID) {
|
// if s.clientControlConns.Has(clientID) {
|
||||||
item, _ := s.clientControlConns.Get(clientID)
|
// item, _ := s.clientControlConns.Get(clientID)
|
||||||
(*item.(*net.Conn)).Close()
|
// (*item.(*net.Conn)).Close()
|
||||||
}
|
// }
|
||||||
s.clientControlConns.Remove(clientID)
|
// s.clientControlConns.Remove(clientID)
|
||||||
log.Printf("client heartbeat conn %s released", clientID)
|
// log.Printf("client heartbeat conn %s released", clientID)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -11,79 +11,80 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TunnelClient struct {
|
type TunnelClient struct {
|
||||||
cfg TunnelClientArgs
|
cfg TunnelClientArgs
|
||||||
cm utils.ConnManager
|
// cm utils.ConnManager
|
||||||
ctrlConn net.Conn
|
ctrlConn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTunnelClient() Service {
|
func NewTunnelClient() Service {
|
||||||
return &TunnelClient{
|
return &TunnelClient{
|
||||||
cfg: TunnelClientArgs{},
|
cfg: TunnelClientArgs{},
|
||||||
cm: utils.NewConnManager(),
|
// cm: utils.NewConnManager(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TunnelClient) InitService() {
|
func (s *TunnelClient) InitService() {
|
||||||
s.InitHeartbeatDeamon()
|
// s.InitHeartbeatDeamon()
|
||||||
}
|
}
|
||||||
func (s *TunnelClient) InitHeartbeatDeamon() {
|
|
||||||
log.Printf("heartbeat started")
|
|
||||||
go func() {
|
|
||||||
var heartbeatConn net.Conn
|
|
||||||
var ID = *s.cfg.Key
|
|
||||||
for {
|
|
||||||
|
|
||||||
//close all connection
|
// func (s *TunnelClient) InitHeartbeatDeamon() {
|
||||||
s.cm.RemoveAll()
|
// log.Printf("heartbeat started")
|
||||||
if s.ctrlConn != nil {
|
// go func() {
|
||||||
s.ctrlConn.Close()
|
// var heartbeatConn net.Conn
|
||||||
}
|
// var ID = *s.cfg.Key
|
||||||
utils.CloseConn(&heartbeatConn)
|
// for {
|
||||||
heartbeatConn, err := s.GetInConn(CONN_CLIENT_HEARBEAT, ID)
|
|
||||||
if err != nil {
|
// //close all connection
|
||||||
log.Printf("heartbeat connection err: %s, retrying...", err)
|
// s.cm.RemoveAll()
|
||||||
time.Sleep(time.Second * 3)
|
// if s.ctrlConn != nil {
|
||||||
utils.CloseConn(&heartbeatConn)
|
// s.ctrlConn.Close()
|
||||||
continue
|
// }
|
||||||
}
|
// utils.CloseConn(&heartbeatConn)
|
||||||
log.Printf("heartbeat connection created,id:%s", ID)
|
// heartbeatConn, err := s.GetInConn(CONN_CLIENT_HEARBEAT, ID)
|
||||||
writeDie := make(chan bool)
|
// if err != nil {
|
||||||
readDie := make(chan bool)
|
// log.Printf("heartbeat connection err: %s, retrying...", err)
|
||||||
go func() {
|
// time.Sleep(time.Second * 3)
|
||||||
for {
|
// utils.CloseConn(&heartbeatConn)
|
||||||
heartbeatConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
// continue
|
||||||
_, err = heartbeatConn.Write([]byte{0x00})
|
// }
|
||||||
heartbeatConn.SetWriteDeadline(time.Time{})
|
// log.Printf("heartbeat connection created,id:%s", ID)
|
||||||
if err != nil {
|
// writeDie := make(chan bool)
|
||||||
log.Printf("heartbeat connection write err %s", err)
|
// readDie := make(chan bool)
|
||||||
break
|
// go func() {
|
||||||
}
|
// for {
|
||||||
time.Sleep(time.Second * 3)
|
// heartbeatConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
||||||
}
|
// _, err = heartbeatConn.Write([]byte{0x00})
|
||||||
close(writeDie)
|
// heartbeatConn.SetWriteDeadline(time.Time{})
|
||||||
}()
|
// if err != nil {
|
||||||
go func() {
|
// log.Printf("heartbeat connection write err %s", err)
|
||||||
for {
|
// break
|
||||||
signal := make([]byte, 1)
|
// }
|
||||||
heartbeatConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
// time.Sleep(time.Second * 3)
|
||||||
_, err := heartbeatConn.Read(signal)
|
// }
|
||||||
heartbeatConn.SetReadDeadline(time.Time{})
|
// close(writeDie)
|
||||||
if err != nil {
|
// }()
|
||||||
log.Printf("heartbeat connection read err: %s", err)
|
// go func() {
|
||||||
break
|
// for {
|
||||||
} else {
|
// signal := make([]byte, 1)
|
||||||
//log.Printf("heartbeat from bridge")
|
// heartbeatConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
||||||
}
|
// _, err := heartbeatConn.Read(signal)
|
||||||
}
|
// heartbeatConn.SetReadDeadline(time.Time{})
|
||||||
close(readDie)
|
// if err != nil {
|
||||||
}()
|
// log.Printf("heartbeat connection read err: %s", err)
|
||||||
select {
|
// break
|
||||||
case <-readDie:
|
// } else {
|
||||||
case <-writeDie:
|
// //log.Printf("heartbeat from bridge")
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}()
|
// close(readDie)
|
||||||
}
|
// }()
|
||||||
|
// select {
|
||||||
|
// case <-readDie:
|
||||||
|
// case <-writeDie:
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }()
|
||||||
|
// }
|
||||||
func (s *TunnelClient) CheckArgs() {
|
func (s *TunnelClient) CheckArgs() {
|
||||||
if *s.cfg.Parent != "" {
|
if *s.cfg.Parent != "" {
|
||||||
log.Printf("use tls parent %s", *s.cfg.Parent)
|
log.Printf("use tls parent %s", *s.cfg.Parent)
|
||||||
@ -96,7 +97,7 @@ func (s *TunnelClient) CheckArgs() {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
func (s *TunnelClient) StopService() {
|
func (s *TunnelClient) StopService() {
|
||||||
s.cm.RemoveAll()
|
// s.cm.RemoveAll()
|
||||||
}
|
}
|
||||||
func (s *TunnelClient) Start(args interface{}) (err error) {
|
func (s *TunnelClient) Start(args interface{}) (err error) {
|
||||||
s.cfg = args.(TunnelClientArgs)
|
s.cfg = args.(TunnelClientArgs)
|
||||||
@ -106,7 +107,7 @@ func (s *TunnelClient) Start(args interface{}) (err error) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
//close all conn
|
//close all conn
|
||||||
s.cm.Remove(*s.cfg.Key)
|
// s.cm.Remove(*s.cfg.Key)
|
||||||
if s.ctrlConn != nil {
|
if s.ctrlConn != nil {
|
||||||
s.ctrlConn.Close()
|
s.ctrlConn.Close()
|
||||||
}
|
}
|
||||||
@ -171,7 +172,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
|
|||||||
var err error
|
var err error
|
||||||
// for {
|
// for {
|
||||||
for {
|
for {
|
||||||
s.cm.RemoveOne(*s.cfg.Key, ID)
|
// s.cm.RemoveOne(*s.cfg.Key, ID)
|
||||||
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
|
inConn, err = s.GetInConn(CONN_CLIENT, *s.cfg.Key, ID, serverID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.CloseConn(&inConn)
|
utils.CloseConn(&inConn)
|
||||||
@ -182,7 +183,7 @@ func (s *TunnelClient) ServeUDP(localAddr, ID, serverID string) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.cm.Add(*s.cfg.Key, ID, &inConn)
|
// s.cm.Add(*s.cfg.Key, ID, &inConn)
|
||||||
log.Printf("conn %s created", ID)
|
log.Printf("conn %s created", ID)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -275,8 +276,8 @@ func (s *TunnelClient) ServeConn(localAddr, ID, serverID string) {
|
|||||||
}
|
}
|
||||||
utils.IoBind(inConn, outConn, func(err interface{}) {
|
utils.IoBind(inConn, outConn, func(err interface{}) {
|
||||||
log.Printf("conn %s released", ID)
|
log.Printf("conn %s released", ID)
|
||||||
s.cm.RemoveOne(*s.cfg.Key, ID)
|
// s.cm.RemoveOne(*s.cfg.Key, ID)
|
||||||
})
|
})
|
||||||
s.cm.Add(*s.cfg.Key, ID, &inConn)
|
// s.cm.Add(*s.cfg.Key, ID, &inConn)
|
||||||
log.Printf("conn %s created", ID)
|
log.Printf("conn %s created", ID)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ type TunnelServerManager struct {
|
|||||||
udpChn chan UDPItem
|
udpChn chan UDPItem
|
||||||
sc utils.ServerChannel
|
sc utils.ServerChannel
|
||||||
serverID string
|
serverID string
|
||||||
cm utils.ConnManager
|
// cm utils.ConnManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTunnelServerManager() Service {
|
func NewTunnelServerManager() Service {
|
||||||
@ -32,7 +32,7 @@ func NewTunnelServerManager() Service {
|
|||||||
cfg: TunnelServerArgs{},
|
cfg: TunnelServerArgs{},
|
||||||
udpChn: make(chan UDPItem, 50000),
|
udpChn: make(chan UDPItem, 50000),
|
||||||
serverID: utils.Uniqueid(),
|
serverID: utils.Uniqueid(),
|
||||||
cm: utils.NewConnManager(),
|
// cm: utils.NewConnManager(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (s *TunnelServerManager) Start(args interface{}) (err error) {
|
func (s *TunnelServerManager) Start(args interface{}) (err error) {
|
||||||
@ -91,7 +91,7 @@ func (s *TunnelServerManager) Clean() {
|
|||||||
s.StopService()
|
s.StopService()
|
||||||
}
|
}
|
||||||
func (s *TunnelServerManager) StopService() {
|
func (s *TunnelServerManager) StopService() {
|
||||||
s.cm.RemoveAll()
|
// s.cm.RemoveAll()
|
||||||
}
|
}
|
||||||
func (s *TunnelServerManager) CheckArgs() {
|
func (s *TunnelServerManager) CheckArgs() {
|
||||||
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
if *s.cfg.CertFile == "" || *s.cfg.KeyFile == "" {
|
||||||
@ -100,62 +100,63 @@ func (s *TunnelServerManager) CheckArgs() {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
func (s *TunnelServerManager) InitService() {
|
func (s *TunnelServerManager) InitService() {
|
||||||
s.InitHeartbeatDeamon()
|
// s.InitHeartbeatDeamon()
|
||||||
}
|
|
||||||
func (s *TunnelServerManager) InitHeartbeatDeamon() {
|
|
||||||
log.Printf("heartbeat started")
|
|
||||||
go func() {
|
|
||||||
var heartbeatConn net.Conn
|
|
||||||
var ID string
|
|
||||||
for {
|
|
||||||
//close all connection
|
|
||||||
s.cm.Remove(ID)
|
|
||||||
utils.CloseConn(&heartbeatConn)
|
|
||||||
heartbeatConn, ID, err := s.GetOutConn(CONN_SERVER_HEARBEAT)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("heartbeat connection err: %s, retrying...", err)
|
|
||||||
time.Sleep(time.Second * 3)
|
|
||||||
utils.CloseConn(&heartbeatConn)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Printf("heartbeat connection created,id:%s", ID)
|
|
||||||
writeDie := make(chan bool)
|
|
||||||
readDie := make(chan bool)
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
heartbeatConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
|
||||||
_, err = heartbeatConn.Write([]byte{0x00})
|
|
||||||
heartbeatConn.SetWriteDeadline(time.Time{})
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("heartbeat connection write err %s", err)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second * 3)
|
|
||||||
}
|
|
||||||
close(writeDie)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
signal := make([]byte, 1)
|
|
||||||
heartbeatConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
|
||||||
_, err := heartbeatConn.Read(signal)
|
|
||||||
heartbeatConn.SetReadDeadline(time.Time{})
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("heartbeat connection read err: %s", err)
|
|
||||||
break
|
|
||||||
} else {
|
|
||||||
// log.Printf("heartbeat from bridge")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(readDie)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-readDie:
|
|
||||||
case <-writeDie:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (s *TunnelServerManager) InitHeartbeatDeamon() {
|
||||||
|
// log.Printf("heartbeat started")
|
||||||
|
// go func() {
|
||||||
|
// var heartbeatConn net.Conn
|
||||||
|
// var ID string
|
||||||
|
// for {
|
||||||
|
// //close all connection
|
||||||
|
// s.cm.Remove(ID)
|
||||||
|
// utils.CloseConn(&heartbeatConn)
|
||||||
|
// heartbeatConn, ID, err := s.GetOutConn(CONN_SERVER_HEARBEAT)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("heartbeat connection err: %s, retrying...", err)
|
||||||
|
// time.Sleep(time.Second * 3)
|
||||||
|
// utils.CloseConn(&heartbeatConn)
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// log.Printf("heartbeat connection created,id:%s", ID)
|
||||||
|
// writeDie := make(chan bool)
|
||||||
|
// readDie := make(chan bool)
|
||||||
|
// go func() {
|
||||||
|
// for {
|
||||||
|
// heartbeatConn.SetWriteDeadline(time.Now().Add(time.Second * 3))
|
||||||
|
// _, err = heartbeatConn.Write([]byte{0x00})
|
||||||
|
// heartbeatConn.SetWriteDeadline(time.Time{})
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("heartbeat connection write err %s", err)
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// time.Sleep(time.Second * 3)
|
||||||
|
// }
|
||||||
|
// close(writeDie)
|
||||||
|
// }()
|
||||||
|
// go func() {
|
||||||
|
// for {
|
||||||
|
// signal := make([]byte, 1)
|
||||||
|
// heartbeatConn.SetReadDeadline(time.Now().Add(time.Second * 6))
|
||||||
|
// _, err := heartbeatConn.Read(signal)
|
||||||
|
// heartbeatConn.SetReadDeadline(time.Time{})
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("heartbeat connection read err: %s", err)
|
||||||
|
// break
|
||||||
|
// } else {
|
||||||
|
// // log.Printf("heartbeat from bridge")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// close(readDie)
|
||||||
|
// }()
|
||||||
|
// select {
|
||||||
|
// case <-readDie:
|
||||||
|
// case <-writeDie:
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }()
|
||||||
|
// }
|
||||||
func (s *TunnelServerManager) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) {
|
func (s *TunnelServerManager) GetOutConn(typ uint8) (outConn net.Conn, ID string, err error) {
|
||||||
outConn, err = s.GetConn()
|
outConn, err = s.GetConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -241,11 +242,11 @@ func (s *TunnelServer) Start(args interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
utils.IoBind(inConn, outConn, func(err interface{}) {
|
utils.IoBind(inConn, outConn, func(err interface{}) {
|
||||||
s.cfg.Mgr.cm.RemoveOne(s.cfg.Mgr.serverID, ID)
|
// s.cfg.Mgr.cm.RemoveOne(s.cfg.Mgr.serverID, ID)
|
||||||
log.Printf("%s conn %s released", *s.cfg.Key, ID)
|
log.Printf("%s conn %s released", *s.cfg.Key, ID)
|
||||||
})
|
})
|
||||||
//add conn
|
//add conn
|
||||||
s.cfg.Mgr.cm.Add(s.cfg.Mgr.serverID, ID, &inConn)
|
// s.cfg.Mgr.cm.Add(s.cfg.Mgr.serverID, ID, &inConn)
|
||||||
log.Printf("%s conn %s created", *s.cfg.Key, ID)
|
log.Printf("%s conn %s created", *s.cfg.Key, ID)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -42,7 +42,8 @@ func IoBind(dst io.ReadWriteCloser, src io.ReadWriteCloser, fn func(err interfac
|
|||||||
log.Printf("bind crashed %s", err)
|
log.Printf("bind crashed %s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
_, err := io.Copy(dst, src)
|
//_, err := io.Copy(dst, src)
|
||||||
|
err := ioCopy(dst, src)
|
||||||
e1 <- err
|
e1 <- err
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
@ -51,7 +52,8 @@ func IoBind(dst io.ReadWriteCloser, src io.ReadWriteCloser, fn func(err interfac
|
|||||||
log.Printf("bind crashed %s", err)
|
log.Printf("bind crashed %s", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
_, err := io.Copy(src, dst)
|
//_, err := io.Copy(src, dst)
|
||||||
|
err := ioCopy(src, dst)
|
||||||
e2 <- err
|
e2 <- err
|
||||||
}()
|
}()
|
||||||
var err interface{}
|
var err interface{}
|
||||||
@ -428,6 +430,29 @@ func GetKCPBlock(method, key string) (block kcp.BlockCrypt) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
func HttpGet(URL string, timeout int) (body []byte, code int, err error) {
|
||||||
|
var tr *http.Transport
|
||||||
|
var client *http.Client
|
||||||
|
conf := &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
if strings.Contains(URL, "https://") {
|
||||||
|
tr = &http.Transport{TLSClientConfig: conf}
|
||||||
|
client = &http.Client{Timeout: time.Millisecond * time.Duration(timeout), Transport: tr}
|
||||||
|
} else {
|
||||||
|
tr = &http.Transport{}
|
||||||
|
client = &http.Client{Timeout: time.Millisecond * time.Duration(timeout), Transport: tr}
|
||||||
|
}
|
||||||
|
defer tr.CloseIdleConnections()
|
||||||
|
resp, err := client.Get(URL)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
code = resp.StatusCode
|
||||||
|
body, err = ioutil.ReadAll(resp.Body)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// type sockaddr struct {
|
// type sockaddr struct {
|
||||||
// family uint16
|
// family uint16
|
||||||
|
|||||||
@ -176,7 +176,11 @@ func (c *Checker) Add(address string, isHTTPS bool, method, URL string, data []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BasicAuth struct {
|
type BasicAuth struct {
|
||||||
data ConcurrentMap
|
data ConcurrentMap
|
||||||
|
authURL string
|
||||||
|
authOkCode int
|
||||||
|
authTimeout int
|
||||||
|
authRetry int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBasicAuth() BasicAuth {
|
func NewBasicAuth() BasicAuth {
|
||||||
@ -184,6 +188,12 @@ func NewBasicAuth() BasicAuth {
|
|||||||
data: NewConcurrentMap(),
|
data: NewConcurrentMap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (ba *BasicAuth) SetAuthURL(URL string, code, timeout, retry int) {
|
||||||
|
ba.authURL = URL
|
||||||
|
ba.authOkCode = code
|
||||||
|
ba.authTimeout = timeout
|
||||||
|
ba.authRetry = retry
|
||||||
|
}
|
||||||
func (ba *BasicAuth) AddFromFile(file string) (n int, err error) {
|
func (ba *BasicAuth) AddFromFile(file string) (n int, err error) {
|
||||||
_content, err := ioutil.ReadFile(file)
|
_content, err := ioutil.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -213,21 +223,69 @@ func (ba *BasicAuth) Add(userpassArr []string) (n int) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (ba *BasicAuth) CheckUserPass(user, pass string) (ok bool) {
|
func (ba *BasicAuth) CheckUserPass(user, pass, ip, target string) (ok bool) {
|
||||||
if p, _ok := ba.data.Get(user); _ok {
|
|
||||||
return p.(string) == pass
|
return ba.Check(user+":"+pass, ip, target)
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
func (ba *BasicAuth) Check(userpass string) (ok bool) {
|
func (ba *BasicAuth) Check(userpass string, ip, target string) (ok bool) {
|
||||||
u := strings.Split(strings.Trim(userpass, " "), ":")
|
u := strings.Split(strings.Trim(userpass, " "), ":")
|
||||||
if len(u) == 2 {
|
if len(u) == 2 {
|
||||||
if p, _ok := ba.data.Get(u[0]); _ok {
|
if p, _ok := ba.data.Get(u[0]); _ok {
|
||||||
return p.(string) == u[1]
|
return p.(string) == u[1]
|
||||||
}
|
}
|
||||||
|
if ba.authURL != "" {
|
||||||
|
err := ba.checkFromURL(userpass, ip, target)
|
||||||
|
if err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
log.Printf("%s", err)
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
|
||||||
|
u := strings.Split(strings.Trim(userpass, " "), ":")
|
||||||
|
if len(u) != 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
URL := ba.authURL
|
||||||
|
if strings.Contains(URL, "?") {
|
||||||
|
URL += "&"
|
||||||
|
} else {
|
||||||
|
URL += "?"
|
||||||
|
}
|
||||||
|
URL += fmt.Sprintf("user=%s&pass=%s&ip=%s&target=%s", u[0], u[1], ip, target)
|
||||||
|
var code int
|
||||||
|
var tryCount = 0
|
||||||
|
var body []byte
|
||||||
|
for tryCount <= ba.authRetry {
|
||||||
|
body, code, err = HttpGet(URL, ba.authTimeout)
|
||||||
|
if err == nil && code == ba.authOkCode {
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
|
err = fmt.Errorf("auth fail from url %s,resonse err:%s , %s", URL, err, ip)
|
||||||
|
} else {
|
||||||
|
if len(body) > 0 {
|
||||||
|
err = fmt.Errorf(string(body[0:100]))
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("token error")
|
||||||
|
}
|
||||||
|
err = fmt.Errorf("auth fail from url %s,resonse code: %d, except: %d , %s , %s", URL, code, ba.authOkCode, ip, string(body))
|
||||||
|
}
|
||||||
|
if err != nil && tryCount < ba.authRetry {
|
||||||
|
log.Print(err)
|
||||||
|
time.Sleep(time.Second * 2)
|
||||||
|
}
|
||||||
|
tryCount++
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//log.Printf("auth success from auth url, %s", ip)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (ba *BasicAuth) Total() (n int) {
|
func (ba *BasicAuth) Total() (n int) {
|
||||||
n = ba.data.Count()
|
n = ba.data.Count()
|
||||||
return
|
return
|
||||||
@ -292,7 +350,11 @@ func (req *HTTPRequest) HTTP() (err error) {
|
|||||||
}
|
}
|
||||||
req.URL, err = req.getHTTPURL()
|
req.URL, err = req.getHTTPURL()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
u, _ := url.Parse(req.URL)
|
var u *url.URL
|
||||||
|
u, err = url.Parse(req.URL)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
req.Host = u.Host
|
req.Host = u.Host
|
||||||
req.addPortIfNot()
|
req.addPortIfNot()
|
||||||
}
|
}
|
||||||
@ -321,6 +383,14 @@ func (req *HTTPRequest) BasicAuth() (err error) {
|
|||||||
CloseConn(req.conn)
|
CloseConn(req.conn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if authorization == "" {
|
||||||
|
authorization, err = req.getHeader("Proxy-Authorization")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprint((*req.conn), "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"\"\r\n\r\nUnauthorized")
|
||||||
|
CloseConn(req.conn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
//log.Printf("Authorization:%s", authorization)
|
//log.Printf("Authorization:%s", authorization)
|
||||||
basic := strings.Fields(authorization)
|
basic := strings.Fields(authorization)
|
||||||
if len(basic) != 2 {
|
if len(basic) != 2 {
|
||||||
@ -334,7 +404,14 @@ func (req *HTTPRequest) BasicAuth() (err error) {
|
|||||||
CloseConn(req.conn)
|
CloseConn(req.conn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
authOk := (*req.basicAuth).Check(string(user))
|
addr := strings.Split((*req.conn).RemoteAddr().String(), ":")
|
||||||
|
URL := ""
|
||||||
|
if req.IsHTTPS() {
|
||||||
|
URL = "https://" + req.Host
|
||||||
|
} else {
|
||||||
|
URL, _ = req.getHTTPURL()
|
||||||
|
}
|
||||||
|
authOk := (*req.basicAuth).Check(string(user), addr[0], URL)
|
||||||
//log.Printf("auth %s,%v", string(user), authOk)
|
//log.Printf("auth %s,%v", string(user), authOk)
|
||||||
if !authOk {
|
if !authOk {
|
||||||
fmt.Fprint((*req.conn), "HTTP/1.1 401 Unauthorized\r\n\r\nUnauthorized")
|
fmt.Fprint((*req.conn), "HTTP/1.1 401 Unauthorized\r\n\r\nUnauthorized")
|
||||||
@ -358,6 +435,7 @@ func (req *HTTPRequest) getHTTPURL() (URL string, err error) {
|
|||||||
func (req *HTTPRequest) getHeader(key string) (val string, err error) {
|
func (req *HTTPRequest) getHeader(key string) (val string, err error) {
|
||||||
key = strings.ToUpper(key)
|
key = strings.ToUpper(key)
|
||||||
lines := strings.Split(string(req.HeadBuf), "\r\n")
|
lines := strings.Split(string(req.HeadBuf), "\r\n")
|
||||||
|
//log.Println(lines)
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
line := strings.SplitN(strings.Trim(line, "\r\n "), ":", 2)
|
line := strings.SplitN(strings.Trim(line, "\r\n "), ":", 2)
|
||||||
if len(line) == 2 {
|
if len(line) == 2 {
|
||||||
@ -369,7 +447,6 @@ func (req *HTTPRequest) getHeader(key string) (val string, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = fmt.Errorf("can not find HOST header")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user