add local_ip for auth url

This commit is contained in:
arraykeys@gmail.com
2018-12-03 15:40:52 +08:00
parent 4a7b1af383
commit 8a86a53bd2
6 changed files with 30 additions and 20 deletions

View File

@ -1,4 +1,7 @@
proxy更新日志
v6.7
1.HTTP(S)\SOCKS5代理,API认证功能,发送给认证接口的参数增加了本地IP,local_ip字段,
代表用户访问的是本地服务器的哪个IP.
v6.6
1.优化了limitconn的关闭逻辑,释放更多资源.

View File

@ -366,11 +366,12 @@ weight 根据每个上级的权重和连接数情况,选择出一个上级
比如:
`./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,local_ip,target五个参数:
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}&local_ip={LOCAL_IP}&target={TARGET}
user:用户名
pass:密码
ip:用户的IP,比如:192.168.1.200
local_ip:用户访问的服务器的IP,比如:3.3.3.3
target:用户访问的URL,比如:http://demo.com:80/1.html或https://www.baidu.com:80
如果没有-a或-F或--auth-url参数,就是关闭Basic认证.
@ -915,11 +916,12 @@ SOCKS5代理,支持CONNECT,UDP协议,不支持BIND,支持用户名密码认证.
比如:
`./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,local_ip四个参数:
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}&local_ip={LOCAL_IP}
user:用户名
pass:密码
ip:用户的IP,比如:192.168.1.200
local_ip:用户访问的服务器的IP,比如:3.3.3.3
如果没有-a或-F或--auth-url参数,就是关闭认证.

View File

@ -1 +1 @@
6.6
6.7

View File

@ -14,7 +14,7 @@ import (
)
type BasicAuther interface {
CheckUserPass(username, password, fromIP, ToTarget string) bool
CheckUserPass(username, password, userIP, localIP, toTarget string) bool
}
type Request struct {
ver uint8
@ -239,6 +239,7 @@ func (s *ServerConn) Target() string {
}
func (s *ServerConn) Handshake() (err error) {
remoteAddr := (*s.conn).RemoteAddr()
localAddr := (*s.conn).LocalAddr()
//协商开始
//method select request
var methodReq MethodsRequest
@ -305,8 +306,9 @@ func (s *ServerConn) Handshake() (err error) {
s.password = string(r[2+r[1]+1:])
//err = fmt.Errorf("user:%s,pass:%s", user, pass)
//auth
_addr := strings.Split(remoteAddr.String(), ":")
if s.auth == nil || (*s.auth).CheckUserPass(s.user, s.password, _addr[0], "") {
_userAddr := strings.Split(remoteAddr.String(), ":")
_localAddr := strings.Split(localAddr.String(), ":")
if s.auth == nil || (*s.auth).CheckUserPass(s.user, s.password, _userAddr[0], _localAddr[0], "") {
(*s.conn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(s.timeout)))
_, err = (*s.conn).Write([]byte{0x01, 0x00})
(*s.conn).SetDeadline(time.Time{})

View File

@ -106,6 +106,7 @@ func (s *ServerConn) Port() string {
}
func (s *ServerConn) Handshake() (err error) {
remoteAddr := (*s.conn).RemoteAddr()
localAddr := (*s.conn).LocalAddr()
//协商开始
//method select request
var methodReq MethodsRequest
@ -172,8 +173,9 @@ func (s *ServerConn) Handshake() (err error) {
s.password = string(r[2+r[1]+1:])
//err = fmt.Errorf("user:%s,pass:%s", user, pass)
//auth
_addr := strings.Split(remoteAddr.String(), ":")
if s.auth == nil || s.auth.CheckUserPass(s.user, s.password, _addr[0], "") {
_userAddr := strings.Split(remoteAddr.String(), ":")
_localAddr := strings.Split(localAddr.String(), ":")
if s.auth == nil || s.auth.CheckUserPass(s.user, s.password, _userAddr[0], _localAddr[0], "") {
(*s.conn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(s.timeout)))
_, err = (*s.conn).Write([]byte{0x01, 0x00})
(*s.conn).SetDeadline(time.Time{})

View File

@ -268,18 +268,18 @@ func (ba *BasicAuth) Add(userpassArr []string) (n int) {
}
return
}
func (ba *BasicAuth) CheckUserPass(user, pass, ip, target string) (ok bool) {
func (ba *BasicAuth) CheckUserPass(user, pass, userIP, localIP, target string) (ok bool) {
return ba.Check(user+":"+pass, ip, target)
return ba.Check(user+":"+pass, userIP, localIP, target)
}
func (ba *BasicAuth) Check(userpass string, ip, target string) (ok bool) {
func (ba *BasicAuth) Check(userpass string, userIP, localIP, target string) (ok bool) {
u := strings.Split(strings.Trim(userpass, " "), ":")
if len(u) == 2 {
if p, _ok := ba.data.Get(u[0]); _ok {
return p.(string) == u[1]
}
if ba.authURL != "" {
err := ba.checkFromURL(userpass, ip, target)
err := ba.checkFromURL(userpass, userIP, localIP, target)
if err == nil {
return true
}
@ -289,7 +289,7 @@ func (ba *BasicAuth) Check(userpass string, ip, target string) (ok bool) {
}
return
}
func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
func (ba *BasicAuth) checkFromURL(userpass, userIP, localIP, target string) (err error) {
u := strings.Split(strings.Trim(userpass, " "), ":")
if len(u) != 2 {
return
@ -301,7 +301,7 @@ func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
} else {
URL += "?"
}
URL += fmt.Sprintf("user=%s&pass=%s&ip=%s&target=%s", u[0], u[1], ip, url.QueryEscape(target))
URL += fmt.Sprintf("user=%s&pass=%s&ip=%s&local_ip=%s&target=%s", u[0], u[1], userIP, localIP, url.QueryEscape(target))
getURL := URL
var domain string
if ba.dns != nil {
@ -318,7 +318,7 @@ func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
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)
err = fmt.Errorf("auth fail from url %s,resonse err:%s , %s -> %s", URL, err, userIP, localIP)
} else {
if len(body) > 0 {
err = fmt.Errorf(string(body[0:100]))
@ -329,7 +329,7 @@ func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
if len(b) > 50 {
b = b[:50]
}
err = fmt.Errorf("auth fail from url %s,resonse code: %d, except: %d , %s , %s", URL, code, ba.authOkCode, ip, b)
err = fmt.Errorf("auth fail from url %s,resonse code: %d, except: %d , %s -> %s, %s", URL, code, ba.authOkCode, userIP, localIP, b)
}
if err != nil && tryCount < ba.authRetry {
ba.log.Print(err)
@ -483,7 +483,8 @@ func (req *HTTPRequest) GetAuthDataStr() (basicInfo string, err error) {
return
}
func (req *HTTPRequest) BasicAuth() (err error) {
addr := strings.Split((*req.conn).RemoteAddr().String(), ":")
userIP := strings.Split((*req.conn).RemoteAddr().String(), ":")
localIP := strings.Split((*req.conn).LocalAddr().String(), ":")
URL := ""
if req.IsHTTPS() {
URL = "https://" + req.Host
@ -494,7 +495,7 @@ func (req *HTTPRequest) BasicAuth() (err error) {
if err != nil {
return
}
authOk := (*req.basicAuth).Check(string(user), addr[0], URL)
authOk := (*req.basicAuth).Check(string(user), userIP[0], localIP[0], URL)
//log.Printf("auth %s,%v", string(user), authOk)
if !authOk {
fmt.Fprintf((*req.conn), "HTTP/1.1 %s Proxy Authentication Required\r\n\r\nProxy Authentication Required", "407")