sps代理增加了对单个上级认证信息的支持,如果没有单独设置,就使用全局-A设置.
现在上级格式: YTpi#2.2.2.2:33080@1
说明:
YTpi 是经过base64编码的认证信息,比如是http(s)/socks原始认证信息a:b,用户是a密码是b,base64编码之后是:YTpi
如果是ss,那么a就是加密方法,b是密码,比如:aes-192-cfb:your_pass,base64编码之后是:YWVzLTE5Mi1jZmI6eW91cl9wYXNz
# 是间隔符号,如果有认证信息,必须有#,没有认证信息可以省略#.
2.2.2.2:33080 是上级地址
@1 是设置权重,可以参考手册权重部分.
This commit is contained in:
@ -3,6 +3,14 @@ proxy更新日志
|
||||
v6.9
|
||||
1.修复了sps的start潜在的crash问题.
|
||||
2.sps代理增加了--parent-tls-single参数用来支持单向tls上级。
|
||||
3.sps代理增加了对单个上级认证信息的支持,如果没有单独设置,就使用全局-A设置.
|
||||
现在上级格式: YTpi#2.2.2.2:33080@1
|
||||
说明:
|
||||
YTpi 是经过base64编码的认证信息,比如是http(s)/socks原始认证信息a:b,用户是a密码是b,base64编码之后是:YTpi
|
||||
如果是ss,那么a就是加密方法,b是密码,比如:aes-192-cfb:your_pass,base64编码之后是:YWVzLTE5Mi1jZmI6eW91cl9wYXNz
|
||||
# 是间隔符号,如果有认证信息,必须有#,没有认证信息可以省略#.
|
||||
2.2.2.2:33080 是上级地址
|
||||
@1 是设置权重,可以参考手册权重部分.
|
||||
|
||||
v6.8
|
||||
1.HTTP(S)\SOCKS5代理,API认证功能,发送给认证接口的参数增加了本地IP,local_ip字段,
|
||||
|
||||
12
README_ZH.md
12
README_ZH.md
@ -1157,6 +1157,18 @@ target:如果客户端是http(s)代理请求,这里代表的是请求的完整ur
|
||||
如果没有-a或-F或--auth-url参数,就是关闭本地认证.
|
||||
如果没有-A参数,连接上级不使用认证.
|
||||
|
||||
**设置单独认证信息**
|
||||
|
||||
如果存在多个不同上级,而且他们的密码有的一样有的不一样,那么可以针对每个上级设置认证信息,
|
||||
同时还可以用-A参数设置一个全局认证信息,如果某个上级没有单独设置认证信息就使用全局设置的认证信息.
|
||||
认证信息和上级写在一起.
|
||||
格式是: YTpi#2.2.2.2:33080@1
|
||||
说明:
|
||||
YTpi 是经过base64编码的认证信息,比如是http(s)/socks原始认证信息a:b,用户是a密码是b,base64编码之后是:YTpi
|
||||
如果是ss,那么a就是加密方法,b是密码,比如:aes-192-cfb:your_pass,base64编码之后是:YWVzLTE5Mi1jZmI6eW91cl9wYXNz
|
||||
# 是间隔符号,如果有认证信息,必须有#,没有认证信息可以省略#
|
||||
2.2.2.2:33080 是上级地址
|
||||
@1 是设置权重,没有可以省略,详细说明可以参考手册***权重部分***
|
||||
|
||||
#### **6.8 自定义加密**
|
||||
proxy的sps代理在tcp之上可以通过tls标准加密以及kcp协议加密tcp数据,除此之外还支持在tls和kcp之后进行
|
||||
|
||||
@ -101,7 +101,7 @@ func (s *SPS) proxyUDP(inConn *net.Conn, serverConn *socks.ServerConn) {
|
||||
s.log.Printf("connect %s for udp", serverConn.Target())
|
||||
//socks client
|
||||
|
||||
client, err := s.HandshakeSocksParent(&outconn, "udp", serverConn.Target(), serverConn.AuthData(), false)
|
||||
client, err := s.HandshakeSocksParent(s.getParentAuth(lbAddr), &outconn, "udp", serverConn.Target(), serverConn.AuthData(), false)
|
||||
if err != nil {
|
||||
clean("handshake fail", fmt.Sprintf("%s", err))
|
||||
return
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/snail007/goproxy/core/cs/server"
|
||||
@ -20,6 +21,7 @@ import (
|
||||
"github.com/snail007/goproxy/services"
|
||||
"github.com/snail007/goproxy/utils"
|
||||
"github.com/snail007/goproxy/utils/conncrypt"
|
||||
cryptool "github.com/snail007/goproxy/utils/crypt"
|
||||
"github.com/snail007/goproxy/utils/datasize"
|
||||
"github.com/snail007/goproxy/utils/dnsx"
|
||||
"github.com/snail007/goproxy/utils/iolimiter"
|
||||
@ -92,6 +94,8 @@ type SPS struct {
|
||||
udpLocalKey []byte
|
||||
udpParentKey []byte
|
||||
jumper *jumper.Jumper
|
||||
parentAuthData *sync.Map
|
||||
parentCipherData *sync.Map
|
||||
}
|
||||
|
||||
func NewSPS() services.Service {
|
||||
@ -101,6 +105,8 @@ func NewSPS() services.Service {
|
||||
serverChannels: []*server.ServerChannel{},
|
||||
userConns: mapx.NewConcurrentMap(),
|
||||
udpRelatedPacketConns: mapx.NewConcurrentMap(),
|
||||
parentAuthData: &sync.Map{},
|
||||
parentCipherData: &sync.Map{},
|
||||
}
|
||||
}
|
||||
func (s *SPS) CheckArgs() (err error) {
|
||||
@ -169,7 +175,10 @@ func (s *SPS) InitService() (err error) {
|
||||
}
|
||||
|
||||
if len(*s.cfg.Parent) > 0 {
|
||||
s.InitLB()
|
||||
err = s.InitLB()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = s.InitBasicAuth()
|
||||
@ -211,6 +220,8 @@ func (s *SPS) StopService() {
|
||||
s.udpParentKey = nil
|
||||
s.udpRelatedPacketConns = nil
|
||||
s.userConns = nil
|
||||
s.parentAuthData = nil
|
||||
s.parentCipherData = nil
|
||||
s = nil
|
||||
}()
|
||||
for _, sc := range s.serverChannels {
|
||||
@ -437,8 +448,8 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
||||
utils.CloseConn(inConn)
|
||||
return
|
||||
}
|
||||
|
||||
if *s.cfg.ParentAuth != "" || *s.cfg.ParentSSKey != "" || s.IsBasicAuth() {
|
||||
ParentAuth := s.getParentAuth(lbAddr)
|
||||
if ParentAuth != "" || *s.cfg.ParentSSKey != "" || s.IsBasicAuth() {
|
||||
forwardBytes = utils.RemoveProxyHeaders(forwardBytes)
|
||||
}
|
||||
|
||||
@ -458,8 +469,8 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
||||
pb.WriteString("Connection: Keep-Alive\r\n")
|
||||
|
||||
u := ""
|
||||
if *s.cfg.ParentAuth != "" {
|
||||
a := strings.Split(*s.cfg.ParentAuth, ":")
|
||||
if ParentAuth != "" {
|
||||
a := strings.Split(ParentAuth, ":")
|
||||
if len(a) != 2 {
|
||||
err = fmt.Errorf("parent auth data format error")
|
||||
return
|
||||
@ -510,7 +521,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
||||
s.log.Printf("connect %s", address)
|
||||
|
||||
//socks client
|
||||
_, err = s.HandshakeSocksParent(&outConn, "tcp", address, auth, false)
|
||||
_, err = s.HandshakeSocksParent(ParentAuth, &outConn, "tcp", address, auth, false)
|
||||
if err != nil {
|
||||
s.log.Printf("handshake fail, %s", err)
|
||||
return
|
||||
@ -523,7 +534,7 @@ func (s *SPS) OutToTCP(inConn *net.Conn) (lbAddr string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
outConn, err = ss.DialWithRawAddr(&outConn, ra, "", s.parentCipher.Copy())
|
||||
outConn, err = ss.DialWithRawAddr(&outConn, ra, "", s.getParentCipher(lbAddr))
|
||||
if err != nil {
|
||||
err = fmt.Errorf("dial ss parent fail, err : %s", err)
|
||||
return
|
||||
@ -583,10 +594,41 @@ func (s *SPS) InitBasicAuth() (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *SPS) InitLB() {
|
||||
func (s *SPS) InitLB() (err error) {
|
||||
configs := lb.BackendsConfig{}
|
||||
for _, addr := range *s.cfg.Parent {
|
||||
_addrInfo := strings.Split(addr, "@")
|
||||
var _addrInfo []string
|
||||
if strings.Contains(addr, "#") {
|
||||
_s := addr[:strings.Index(addr, "#")]
|
||||
_auth, err := cryptool.CryptTools.Base64Decode(_s)
|
||||
if err != nil {
|
||||
s.log.Printf("decoding parent auth data [ %s ] fail , error : %s", _s, err)
|
||||
return err
|
||||
}
|
||||
_addrInfo = strings.Split(addr[strings.Index(addr, "#")+1:], "@")
|
||||
if *s.cfg.ParentServiceType == "ss" {
|
||||
_s := strings.Split(_auth, ":")
|
||||
m := _s[0]
|
||||
k := _s[1]
|
||||
if m == "" {
|
||||
m = *s.cfg.ParentSSMethod
|
||||
}
|
||||
if k == "" {
|
||||
k = *s.cfg.ParentSSKey
|
||||
}
|
||||
cipher, err := ss.NewCipher(m, k)
|
||||
if err != nil {
|
||||
s.log.Printf("error generating cipher, ssMethod: %s, ssKey: %s, error : %s", m, k, err)
|
||||
return err
|
||||
}
|
||||
s.parentCipherData.Store(_addrInfo[0], cipher)
|
||||
} else {
|
||||
s.parentAuthData.Store(_addrInfo[0], _auth)
|
||||
}
|
||||
|
||||
} else {
|
||||
_addrInfo = strings.Split(addr, "@")
|
||||
}
|
||||
_addr := _addrInfo[0]
|
||||
weight := 1
|
||||
if len(_addrInfo) == 2 {
|
||||
@ -603,6 +645,19 @@ func (s *SPS) InitLB() {
|
||||
}
|
||||
LB := lb.NewGroup(utils.LBMethod(*s.cfg.LoadBalanceMethod), configs, &s.domainResolver, s.log, *s.cfg.Debug)
|
||||
s.lb = &LB
|
||||
return
|
||||
}
|
||||
func (s *SPS) getParentAuth(lbAddr string) string {
|
||||
if v, ok := s.parentAuthData.Load(lbAddr); ok {
|
||||
return v.(string)
|
||||
}
|
||||
return *s.cfg.ParentAuth
|
||||
}
|
||||
func (s *SPS) getParentCipher(lbAddr string) *ss.Cipher {
|
||||
if v, ok := s.parentCipherData.Load(lbAddr); ok {
|
||||
return v.(*ss.Cipher).Copy()
|
||||
}
|
||||
return s.parentCipher.Copy()
|
||||
}
|
||||
func (s *SPS) IsBasicAuth() bool {
|
||||
return *s.cfg.AuthFile != "" || len(*s.cfg.Auth) > 0 || *s.cfg.AuthURL != ""
|
||||
@ -706,9 +761,9 @@ func (s *SPS) GetParentConn(address string) (conn net.Conn, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *SPS) HandshakeSocksParent(outconn *net.Conn, network, dstAddr string, auth socks.Auth, fromSS bool) (client *socks.ClientConn, err error) {
|
||||
if *s.cfg.ParentAuth != "" {
|
||||
a := strings.Split(*s.cfg.ParentAuth, ":")
|
||||
func (s *SPS) HandshakeSocksParent(parentAuth string, outconn *net.Conn, network, dstAddr string, auth socks.Auth, fromSS bool) (client *socks.ClientConn, err error) {
|
||||
if parentAuth != "" {
|
||||
a := strings.Split(parentAuth, ":")
|
||||
if len(a) != 2 {
|
||||
err = fmt.Errorf("parent auth data format error")
|
||||
return
|
||||
|
||||
@ -88,7 +88,7 @@ func (s *SPS) RunSSUDP(addr string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
client, err := s.HandshakeSocksParent(&outconn, "udp", socksPacket.Addr(), socks.Auth{}, true)
|
||||
client, err := s.HandshakeSocksParent(s.getParentAuth(lbAddr), &outconn, "udp", socksPacket.Addr(), socks.Auth{}, true)
|
||||
if err != nil {
|
||||
clean("handshake fail", fmt.Sprintf("%s", err))
|
||||
return
|
||||
|
||||
38
utils/crypt/misc.go
Normal file
38
utils/crypt/misc.go
Normal file
@ -0,0 +1,38 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
type CryptTool struct{}
|
||||
|
||||
var CryptTools = NewCryptTool()
|
||||
|
||||
func NewCryptTool() *CryptTool {
|
||||
return &CryptTool{}
|
||||
}
|
||||
|
||||
func (encrypt *CryptTool) Base64Encode(str string) string {
|
||||
return string([]byte(base64.StdEncoding.EncodeToString([]byte(str))))
|
||||
}
|
||||
|
||||
func (encrypt *CryptTool) Base64EncodeBytes(bytes []byte) []byte {
|
||||
return []byte(base64.StdEncoding.EncodeToString(bytes))
|
||||
}
|
||||
|
||||
func (encrypt *CryptTool) Base64Decode(str string) (string, error) {
|
||||
by, err := base64.StdEncoding.DecodeString(str)
|
||||
return string(by), err
|
||||
}
|
||||
|
||||
func (encrypt *CryptTool) Base64DecodeBytes(str string) ([]byte, error) {
|
||||
return base64.StdEncoding.DecodeString(str)
|
||||
}
|
||||
|
||||
func (encrypt *CryptTool) MD5(str string) string {
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(str))
|
||||
return hex.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
Reference in New Issue
Block a user