mirror of
https://github.com/wyx2685/V2bX.git
synced 2026-02-04 12:40:11 +00:00
Compare commits
4 Commits
v0.0.9-202
...
v0.0.11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
248ff3764f | ||
|
|
3dfeba7e68 | ||
|
|
8eb623b3f0 | ||
|
|
cdcbddd464 |
@@ -2,7 +2,6 @@ package panel
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -10,7 +9,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/InazumaV/V2bX/common/crypt"
|
||||
"github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
@@ -186,18 +184,6 @@ func (c *Client) GetNodeInfo() (node *NodeInfo, err error) {
|
||||
cm = &rsp.CommonNode
|
||||
node.VAllss = rsp
|
||||
node.Security = node.VAllss.Tls
|
||||
if len(rsp.NetworkSettings) > 0 {
|
||||
err = json.Unmarshal(rsp.NetworkSettings, &rsp.RealityConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode reality config error: %s", err)
|
||||
}
|
||||
}
|
||||
if node.Security == Reality {
|
||||
if rsp.TlsSettings.PrivateKey == "" {
|
||||
key := crypt.GenX25519Private([]byte("vless" + c.Token))
|
||||
rsp.TlsSettings.PrivateKey = base64.RawURLEncoding.EncodeToString(key)
|
||||
}
|
||||
}
|
||||
case "shadowsocks":
|
||||
rsp := &ShadowsocksNode{}
|
||||
err = json.Unmarshal(r.Body(), rsp)
|
||||
|
||||
@@ -284,15 +284,23 @@ func (n *Hysteria2node) getMasqHandler(tlsconfig *server.TLSConfig, conn net.Pac
|
||||
}
|
||||
u, err := url.Parse(c.Masquerade.Proxy.URL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(fmt.Sprintf("masquerade.proxy.url %s", err))
|
||||
return nil, fmt.Errorf("masquerade.proxy.url %s", err)
|
||||
}
|
||||
handler = &httputil.ReverseProxy{
|
||||
Rewrite: func(r *httputil.ProxyRequest) {
|
||||
r.SetURL(u)
|
||||
// SetURL rewrites the Host header,
|
||||
// but we don't want that if rewriteHost is false
|
||||
Director: func(req *http.Request) {
|
||||
req.URL.Scheme = u.Scheme
|
||||
req.URL.Host = u.Host
|
||||
|
||||
if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
|
||||
xff := req.Header.Get("X-Forwarded-For")
|
||||
if xff != "" {
|
||||
clientIP = xff + ", " + clientIP
|
||||
}
|
||||
req.Header.Set("X-Forwarded-For", clientIP)
|
||||
}
|
||||
|
||||
if !c.Masquerade.Proxy.RewriteHost {
|
||||
r.Out.Host = r.In.Host
|
||||
req.Host = req.URL.Host
|
||||
}
|
||||
},
|
||||
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||
|
||||
@@ -51,7 +51,7 @@ func (l *serverLogger) Connect(addr net.Addr, uuid string, tx uint64) {
|
||||
if err != nil {
|
||||
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
||||
}
|
||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp"); r {
|
||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp", true); r {
|
||||
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
||||
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func (l *serverLogger) TCPRequest(addr net.Addr, uuid, reqAddr string) {
|
||||
if err != nil {
|
||||
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
||||
}
|
||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp"); r {
|
||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp", true); r {
|
||||
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
||||
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func (l *serverLogger) UDPRequest(addr net.Addr, uuid string, sessionId uint32,
|
||||
if err != nil {
|
||||
l.logger.Panic("Get limiter error", zap.String("tag", l.Tag), zap.Error(err))
|
||||
}
|
||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp"); r {
|
||||
if _, r := limiterinfo.CheckLimit(format.UserTag(l.Tag, uuid), extractIPFromAddr(addr), addr.Network() == "tcp", true); r {
|
||||
if userLimit, ok := limiterinfo.UserLimitInfo.Load(format.UserTag(l.Tag, uuid)); ok {
|
||||
userLimit.(*limiter.UserLimitInfo).OverLimit = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package hy2
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/InazumaV/V2bX/api/panel"
|
||||
"github.com/InazumaV/V2bX/conf"
|
||||
"github.com/apernet/hysteria/core/v2/server"
|
||||
@@ -56,7 +58,9 @@ func (h *Hysteria2) AddNode(tag string, info *panel.NodeInfo, config *conf.Optio
|
||||
h.Hy2nodes[tag] = n
|
||||
go func() {
|
||||
if err := s.Serve(); err != nil {
|
||||
h.Logger.Error("Server Error", zap.Error(err))
|
||||
if !strings.Contains(err.Error(), "quic: server closed") {
|
||||
h.Logger.Error("Server Error", zap.Error(err))
|
||||
}
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
|
||||
@@ -108,7 +108,7 @@ func (h *HookServer) RoutedConnection(_ context.Context, conn net.Conn, m adapte
|
||||
return conn, t
|
||||
}
|
||||
ip := m.Source.Addr.String()
|
||||
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true); r {
|
||||
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true, true); r {
|
||||
conn.Close()
|
||||
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
|
||||
return conn, t
|
||||
@@ -162,7 +162,7 @@ func (h *HookServer) RoutedPacketConnection(_ context.Context, conn N.PacketConn
|
||||
return conn, t
|
||||
}
|
||||
ip := m.Source.Addr.String()
|
||||
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true); r {
|
||||
if b, r := l.CheckLimit(format.UserTag(m.Inbound, m.User), ip, true, false); r {
|
||||
conn.Close()
|
||||
log.Error("[", m.Inbound, "] ", "Limited ", m.User, " by ip or conn")
|
||||
return conn, t
|
||||
|
||||
@@ -177,7 +177,8 @@ func (d *DefaultDispatcher) getLink(ctx context.Context, network net.Network) (*
|
||||
// Speed Limit and Device Limit
|
||||
w, reject := limit.CheckLimit(user.Email,
|
||||
sessionInbound.Source.Address.IP().String(),
|
||||
network == net.Network_TCP)
|
||||
network == net.Network_TCP,
|
||||
sessionInbound.Source.Network == net.Network_TCP)
|
||||
if reject {
|
||||
errors.LogInfo(ctx, "Limited ", user.Email, " by conn or ip")
|
||||
common.Close(outboundLink.Writer)
|
||||
@@ -241,7 +242,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
|
||||
protocolString = resComp.ProtocolForDomainResult()
|
||||
}
|
||||
for _, p := range request.OverrideDestinationForProtocol {
|
||||
if strings.HasPrefix(protocolString, p) || strings.HasPrefix(protocolString, p) {
|
||||
if strings.HasPrefix(protocolString, p) || strings.HasPrefix(p, protocolString) {
|
||||
return true
|
||||
}
|
||||
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
|
||||
|
||||
@@ -190,7 +190,7 @@ func buildV2ray(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreCon
|
||||
return nil
|
||||
}
|
||||
|
||||
t := coreConf.TransportProtocol(nodeInfo.VAllss.Network)
|
||||
t := coreConf.TransportProtocol(v.Network)
|
||||
inbound.StreamSetting = &coreConf.StreamConfig{Network: &t}
|
||||
switch v.Network {
|
||||
case "tcp":
|
||||
@@ -221,12 +221,12 @@ func buildV2ray(config *conf.Options, nodeInfo *panel.NodeInfo, inbound *coreCon
|
||||
case "httpupgrade":
|
||||
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.HTTPUPGRADESettings)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshal grpc settings error: %s", err)
|
||||
return fmt.Errorf("unmarshal httpupgrade settings error: %s", err)
|
||||
}
|
||||
case "splithttp":
|
||||
err := json.Unmarshal(v.NetworkSettings, &inbound.StreamSetting.SplitHTTPSettings)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshal grpc settings error: %s", err)
|
||||
return fmt.Errorf("unmarshal splithttp settings error: %s", err)
|
||||
}
|
||||
default:
|
||||
return errors.New("the network type is not vail")
|
||||
|
||||
10
go.mod
10
go.mod
@@ -14,12 +14,12 @@ require (
|
||||
github.com/goccy/go-json v0.10.3
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/juju/ratelimit v1.0.2
|
||||
github.com/sagernet/sing v0.5.0-alpha.12
|
||||
github.com/sagernet/sing-box v1.10.0
|
||||
github.com/sagernet/sing v0.5.0-alpha.13
|
||||
github.com/sagernet/sing-box v1.10.0-alpha.23
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/viper v1.15.0
|
||||
github.com/xtls/xray-core v1.8.19
|
||||
github.com/xtls/xray-core v1.8.21
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.25.0
|
||||
golang.org/x/sys v0.22.0
|
||||
@@ -273,5 +273,5 @@ require (
|
||||
lukechampine.com/blake3 v1.3.0 // indirect
|
||||
)
|
||||
|
||||
//github.com/apernet/hysteria/core v1.3.5-0.20240201034858-bb99579bb92c => /root/hysteria/core
|
||||
replace github.com/sagernet/sing-box v1.10.0 => github.com/wyx2685/sing-box_mod v0.0.9
|
||||
// replace github.com/sagernet/sing-box v1.10.0-alpha.22 => /root/sing-box_mod
|
||||
replace github.com/sagernet/sing-box v1.10.0-alpha.23 => github.com/wyx2685/sing-box_mod v1.10.0-alpha.23
|
||||
|
||||
12
go.sum
12
go.sum
@@ -777,8 +777,8 @@ github.com/sagernet/quic-go v0.45.1-beta.2/go.mod h1:+N3FqM9DAzOWfe64uxXuBejVJwX
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||
github.com/sagernet/sing v0.5.0-alpha.12 h1:pjffG3SUpuF9PLDCqPO2fOAUozXItIBmnMVTKQ/QMhM=
|
||||
github.com/sagernet/sing v0.5.0-alpha.12/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.5.0-alpha.13 h1:fpR4TFZfu/9V3LbHSAnnnwcaXGMF8ijmAAPoY2WHSKw=
|
||||
github.com/sagernet/sing v0.5.0-alpha.13/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.10 h1:Js61EjQXVpcu2VDegWEQTH1isCcVwJju8WEHYgG4tQ0=
|
||||
github.com/sagernet/sing-dns v0.3.0-beta.10/go.mod h1:nXE6EYMXahB5DV3AcXYbFfuorqF7tbQ86kxweSxRKM4=
|
||||
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
|
||||
@@ -941,16 +941,16 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs=
|
||||
github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI=
|
||||
github.com/wyx2685/sing-box_mod v0.0.9 h1:xxxPk107vFiAFiD8jOCCAHbNLPJ5Jgq5IJIi1Lil4NI=
|
||||
github.com/wyx2685/sing-box_mod v0.0.9/go.mod h1:0IErt79whUyLappgPDCSORcDQCP1kubkf9KW6FVqPOk=
|
||||
github.com/wyx2685/sing-box_mod v1.10.0-alpha.23 h1:DqByg8ldMTMXoUBLJO1fGhmOE7DavSR7Zlr1uYGl1ZY=
|
||||
github.com/wyx2685/sing-box_mod v1.10.0-alpha.23/go.mod h1:a9BYzpu6AtQHdiIkf2B059xPFd95jh9QKXS2EaX8p7E=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg=
|
||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
|
||||
github.com/xtls/xray-core v1.8.19 h1:mml7smcO2FM5HyyKdqnf5F2BUvi3br2ldrqmeemEFRE=
|
||||
github.com/xtls/xray-core v1.8.19/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
|
||||
github.com/xtls/xray-core v1.8.21 h1:cNdepud+R9PENKzXlSZsq0je4BWI6liXAuep6CD6xvk=
|
||||
github.com/xtls/xray-core v1.8.21/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e h1:jLIqA7M9qY31g/Nw/5htVD0DFbxmLnlFZcHKJiG3osI=
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20240318083951-4fe6125f286e/go.mod h1:HEUYX/p8966tMUHHT+TsS0hF/Ca/NYwqprC5WXSDMfE=
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20240318084659-dfa50323a0b4 h1:wtzLQJmghkSUb1YkeFphIh7ST7NNVDaVOJZSAJcjMdw=
|
||||
|
||||
@@ -3,6 +3,7 @@ package limiter
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -129,7 +130,10 @@ func (l *Limiter) UpdateDynamicSpeedLimit(tag, uuid string, limit int, expire ti
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool) (Bucket *ratelimit.Bucket, Reject bool) {
|
||||
func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool, noSSUDP bool) (Bucket *ratelimit.Bucket, Reject bool) {
|
||||
// check if ipv4 mapped ipv6
|
||||
ip = strings.TrimPrefix(ip, "::ffff:")
|
||||
|
||||
// ip and conn limiter
|
||||
if l.ConnLimiter.AddConnCount(taguuid, ip, isTcp) {
|
||||
return nil, true
|
||||
@@ -155,23 +159,24 @@ func (l *Limiter) CheckLimit(taguuid string, ip string, isTcp bool) (Bucket *rat
|
||||
userLimit = determineSpeedLimit(u.SpeedLimit, u.DynamicSpeedLimit)
|
||||
}
|
||||
}
|
||||
|
||||
// Store online user for device limit
|
||||
ipMap := new(sync.Map)
|
||||
ipMap.Store(ip, uid)
|
||||
// If any device is online
|
||||
if v, ok := l.UserOnlineIP.LoadOrStore(taguuid, ipMap); ok {
|
||||
ipMap := v.(*sync.Map)
|
||||
// If this is a new ip
|
||||
if _, ok := ipMap.LoadOrStore(ip, uid); !ok {
|
||||
counter := 0
|
||||
ipMap.Range(func(key, value interface{}) bool {
|
||||
counter++
|
||||
return true
|
||||
})
|
||||
if counter > deviceLimit && deviceLimit > 0 {
|
||||
ipMap.Delete(ip)
|
||||
return nil, true
|
||||
if noSSUDP {
|
||||
// Store online user for device limit
|
||||
ipMap := new(sync.Map)
|
||||
ipMap.Store(ip, uid)
|
||||
// If any device is online
|
||||
if v, ok := l.UserOnlineIP.LoadOrStore(taguuid, ipMap); ok {
|
||||
ipMap := v.(*sync.Map)
|
||||
// If this is a new ip
|
||||
if _, ok := ipMap.LoadOrStore(ip, uid); !ok {
|
||||
counter := 0
|
||||
ipMap.Range(func(key, value interface{}) bool {
|
||||
counter++
|
||||
return true
|
||||
})
|
||||
if counter > deviceLimit && deviceLimit > 0 {
|
||||
ipMap.Delete(ip)
|
||||
return nil, true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user