add local_ip for auth url
This commit is contained in:
@ -1,4 +1,7 @@
|
|||||||
proxy更新日志
|
proxy更新日志
|
||||||
|
v6.7
|
||||||
|
1.HTTP(S)\SOCKS5代理,API认证功能,发送给认证接口的参数增加了本地IP,local_ip字段,
|
||||||
|
代表用户访问的是本地服务器的哪个IP.
|
||||||
|
|
||||||
v6.6
|
v6.6
|
||||||
1.优化了limitconn的关闭逻辑,释放更多资源.
|
1.优化了limitconn的关闭逻辑,释放更多资源.
|
||||||
|
|||||||
10
README_ZH.md
10
README_ZH.md
@ -366,11 +366,12 @@ weight 根据每个上级的权重和连接数情况,选择出一个上级
|
|||||||
比如:
|
比如:
|
||||||
`./proxy http -t tcp -p ":33080" --auth-url "http://test.com/auth.php"`
|
`./proxy http -t tcp -p ":33080" --auth-url "http://test.com/auth.php"`
|
||||||
用户连接的时候,proxy会GET方式请求这url("http://test.com/auth.php"),
|
用户连接的时候,proxy会GET方式请求这url("http://test.com/auth.php"),
|
||||||
带上user,pass,ip,target四个参数:
|
带上user,pass,ip,local_ip,target五个参数:
|
||||||
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}&target={TARGET}
|
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}&local_ip={LOCAL_IP}&target={TARGET}
|
||||||
user:用户名
|
user:用户名
|
||||||
pass:密码
|
pass:密码
|
||||||
ip:用户的IP,比如:192.168.1.200
|
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
|
target:用户访问的URL,比如:http://demo.com:80/1.html或https://www.baidu.com:80
|
||||||
|
|
||||||
如果没有-a或-F或--auth-url参数,就是关闭Basic认证.
|
如果没有-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 socks -t tcp -p ":33080" --auth-url "http://test.com/auth.php"`
|
||||||
用户连接的时候,proxy会GET方式请求这url("http://test.com/auth.php"),
|
用户连接的时候,proxy会GET方式请求这url("http://test.com/auth.php"),
|
||||||
带上user,pass,ip,三个参数:
|
带上user,pass,ip,local_ip四个参数:
|
||||||
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}
|
http://test.com/auth.php?user={USER}&pass={PASS}&ip={IP}&local_ip={LOCAL_IP}
|
||||||
user:用户名
|
user:用户名
|
||||||
pass:密码
|
pass:密码
|
||||||
ip:用户的IP,比如:192.168.1.200
|
ip:用户的IP,比如:192.168.1.200
|
||||||
|
local_ip:用户访问的服务器的IP,比如:3.3.3.3
|
||||||
|
|
||||||
如果没有-a或-F或--auth-url参数,就是关闭认证.
|
如果没有-a或-F或--auth-url参数,就是关闭认证.
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type BasicAuther interface {
|
type BasicAuther interface {
|
||||||
CheckUserPass(username, password, fromIP, ToTarget string) bool
|
CheckUserPass(username, password, userIP, localIP, toTarget string) bool
|
||||||
}
|
}
|
||||||
type Request struct {
|
type Request struct {
|
||||||
ver uint8
|
ver uint8
|
||||||
@ -239,6 +239,7 @@ func (s *ServerConn) Target() string {
|
|||||||
}
|
}
|
||||||
func (s *ServerConn) Handshake() (err error) {
|
func (s *ServerConn) Handshake() (err error) {
|
||||||
remoteAddr := (*s.conn).RemoteAddr()
|
remoteAddr := (*s.conn).RemoteAddr()
|
||||||
|
localAddr := (*s.conn).LocalAddr()
|
||||||
//协商开始
|
//协商开始
|
||||||
//method select request
|
//method select request
|
||||||
var methodReq MethodsRequest
|
var methodReq MethodsRequest
|
||||||
@ -305,8 +306,9 @@ func (s *ServerConn) Handshake() (err error) {
|
|||||||
s.password = string(r[2+r[1]+1:])
|
s.password = string(r[2+r[1]+1:])
|
||||||
//err = fmt.Errorf("user:%s,pass:%s", user, pass)
|
//err = fmt.Errorf("user:%s,pass:%s", user, pass)
|
||||||
//auth
|
//auth
|
||||||
_addr := strings.Split(remoteAddr.String(), ":")
|
_userAddr := strings.Split(remoteAddr.String(), ":")
|
||||||
if s.auth == nil || (*s.auth).CheckUserPass(s.user, s.password, _addr[0], "") {
|
_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)))
|
(*s.conn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(s.timeout)))
|
||||||
_, err = (*s.conn).Write([]byte{0x01, 0x00})
|
_, err = (*s.conn).Write([]byte{0x01, 0x00})
|
||||||
(*s.conn).SetDeadline(time.Time{})
|
(*s.conn).SetDeadline(time.Time{})
|
||||||
|
|||||||
@ -106,6 +106,7 @@ func (s *ServerConn) Port() string {
|
|||||||
}
|
}
|
||||||
func (s *ServerConn) Handshake() (err error) {
|
func (s *ServerConn) Handshake() (err error) {
|
||||||
remoteAddr := (*s.conn).RemoteAddr()
|
remoteAddr := (*s.conn).RemoteAddr()
|
||||||
|
localAddr := (*s.conn).LocalAddr()
|
||||||
//协商开始
|
//协商开始
|
||||||
//method select request
|
//method select request
|
||||||
var methodReq MethodsRequest
|
var methodReq MethodsRequest
|
||||||
@ -172,8 +173,9 @@ func (s *ServerConn) Handshake() (err error) {
|
|||||||
s.password = string(r[2+r[1]+1:])
|
s.password = string(r[2+r[1]+1:])
|
||||||
//err = fmt.Errorf("user:%s,pass:%s", user, pass)
|
//err = fmt.Errorf("user:%s,pass:%s", user, pass)
|
||||||
//auth
|
//auth
|
||||||
_addr := strings.Split(remoteAddr.String(), ":")
|
_userAddr := strings.Split(remoteAddr.String(), ":")
|
||||||
if s.auth == nil || s.auth.CheckUserPass(s.user, s.password, _addr[0], "") {
|
_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)))
|
(*s.conn).SetDeadline(time.Now().Add(time.Millisecond * time.Duration(s.timeout)))
|
||||||
_, err = (*s.conn).Write([]byte{0x01, 0x00})
|
_, err = (*s.conn).Write([]byte{0x01, 0x00})
|
||||||
(*s.conn).SetDeadline(time.Time{})
|
(*s.conn).SetDeadline(time.Time{})
|
||||||
|
|||||||
@ -268,18 +268,18 @@ func (ba *BasicAuth) Add(userpassArr []string) (n int) {
|
|||||||
}
|
}
|
||||||
return
|
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, " "), ":")
|
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 != "" {
|
if ba.authURL != "" {
|
||||||
err := ba.checkFromURL(userpass, ip, target)
|
err := ba.checkFromURL(userpass, userIP, localIP, target)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -289,7 +289,7 @@ func (ba *BasicAuth) Check(userpass string, ip, target string) (ok bool) {
|
|||||||
}
|
}
|
||||||
return
|
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, " "), ":")
|
u := strings.Split(strings.Trim(userpass, " "), ":")
|
||||||
if len(u) != 2 {
|
if len(u) != 2 {
|
||||||
return
|
return
|
||||||
@ -301,7 +301,7 @@ func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
|
|||||||
} else {
|
} else {
|
||||||
URL += "?"
|
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
|
getURL := URL
|
||||||
var domain string
|
var domain string
|
||||||
if ba.dns != nil {
|
if ba.dns != nil {
|
||||||
@ -318,7 +318,7 @@ func (ba *BasicAuth) checkFromURL(userpass, ip, target string) (err error) {
|
|||||||
if err == nil && code == ba.authOkCode {
|
if err == nil && code == ba.authOkCode {
|
||||||
break
|
break
|
||||||
} else if err != nil {
|
} 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 {
|
} else {
|
||||||
if len(body) > 0 {
|
if len(body) > 0 {
|
||||||
err = fmt.Errorf(string(body[0:100]))
|
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 {
|
if len(b) > 50 {
|
||||||
b = 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 {
|
if err != nil && tryCount < ba.authRetry {
|
||||||
ba.log.Print(err)
|
ba.log.Print(err)
|
||||||
@ -483,7 +483,8 @@ func (req *HTTPRequest) GetAuthDataStr() (basicInfo string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (req *HTTPRequest) BasicAuth() (err error) {
|
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 := ""
|
URL := ""
|
||||||
if req.IsHTTPS() {
|
if req.IsHTTPS() {
|
||||||
URL = "https://" + req.Host
|
URL = "https://" + req.Host
|
||||||
@ -494,7 +495,7 @@ func (req *HTTPRequest) BasicAuth() (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
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)
|
//log.Printf("auth %s,%v", string(user), authOk)
|
||||||
if !authOk {
|
if !authOk {
|
||||||
fmt.Fprintf((*req.conn), "HTTP/1.1 %s Proxy Authentication Required\r\n\r\nProxy Authentication Required", "407")
|
fmt.Fprintf((*req.conn), "HTTP/1.1 %s Proxy Authentication Required\r\n\r\nProxy Authentication Required", "407")
|
||||||
|
|||||||
Reference in New Issue
Block a user