mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 15:24:01 +03:00
Use ristretto instead of bigcache
This commit is contained in:
+21
-9
@@ -1,26 +1,38 @@
|
||||
package antireplay
|
||||
|
||||
import "github.com/allegro/bigcache"
|
||||
import "github.com/dgraph-io/ristretto"
|
||||
|
||||
var (
|
||||
prefixObfuscated2 = []byte{0x00}
|
||||
prefixTLS = []byte{0x01}
|
||||
)
|
||||
|
||||
type cache struct {
|
||||
obfuscated2 *bigcache.BigCache
|
||||
tls *bigcache.BigCache
|
||||
data *ristretto.Cache
|
||||
}
|
||||
|
||||
func (c *cache) AddObfuscated2(data []byte) {
|
||||
c.obfuscated2.Set(string(data), nil) // nolint: errcheck
|
||||
c.data.Set(keyObfuscated2(data), nil, int64(len(data)))
|
||||
}
|
||||
|
||||
func (c *cache) AddTLS(data []byte) {
|
||||
c.tls.Set(string(data), nil) // nolint: errcheck
|
||||
c.data.Set(keyTLS(data), nil, int64(len(data)))
|
||||
}
|
||||
|
||||
func (c *cache) HasObfuscated2(data []byte) bool {
|
||||
_, err := c.obfuscated2.Get(string(data))
|
||||
return err == nil
|
||||
_, ok := c.data.Get(keyObfuscated2(data))
|
||||
return ok
|
||||
}
|
||||
|
||||
func (c *cache) HasTLS(data []byte) bool {
|
||||
_, err := c.tls.Get(string(data))
|
||||
return err == nil
|
||||
_, ok := c.data.Get(keyTLS(data))
|
||||
return ok
|
||||
}
|
||||
|
||||
func keyObfuscated2(data []byte) string {
|
||||
return string(append(prefixObfuscated2, data...))
|
||||
}
|
||||
|
||||
func keyTLS(data []byte) string {
|
||||
return string(append(prefixTLS, data...))
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package antireplay
|
||||
|
||||
import "github.com/cespare/xxhash"
|
||||
|
||||
type hasher struct{}
|
||||
|
||||
func (h hasher) Sum64(value string) uint64 {
|
||||
return xxhash.Sum64String(value)
|
||||
}
|
||||
+12
-21
@@ -1,42 +1,33 @@
|
||||
package antireplay
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
"github.com/9seconds/mtg/config"
|
||||
"github.com/allegro/bigcache"
|
||||
"github.com/dgraph-io/ristretto"
|
||||
)
|
||||
|
||||
var (
|
||||
Cache *cache
|
||||
Cache cache
|
||||
initOnce sync.Once
|
||||
)
|
||||
|
||||
func Init() {
|
||||
initOnce.Do(func() {
|
||||
c1, err := bigcache.NewBigCache(bigcache.Config{
|
||||
Shards: 1024,
|
||||
LifeWindow: config.C.AntiReplayEvictionTime,
|
||||
Hasher: hasher{},
|
||||
HardMaxCacheSize: config.C.AntiReplayMaxSize,
|
||||
cost := float64(config.C.AntiReplayMaxSize) / 32.0
|
||||
cost = math.Ceil(cost)
|
||||
|
||||
c, err := ristretto.NewCache(&ristretto.Config{
|
||||
NumCounters: int64(cost) * 10,
|
||||
MaxCost: config.C.AntiReplayMaxSize,
|
||||
BufferItems: 64,
|
||||
Metrics: false,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c2, err := bigcache.NewBigCache(bigcache.Config{
|
||||
Shards: 1024,
|
||||
LifeWindow: config.C.AntiReplayEvictionTime,
|
||||
Hasher: hasher{},
|
||||
HardMaxCacheSize: config.C.AntiReplayMaxSize,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Cache = &cache{
|
||||
obfuscated2: c1,
|
||||
tls: c2,
|
||||
}
|
||||
Cache.data = c
|
||||
})
|
||||
}
|
||||
|
||||
+2
-7
@@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/alecthomas/units"
|
||||
"go.uber.org/zap"
|
||||
@@ -58,7 +57,6 @@ const (
|
||||
OptionTypeCloakPort
|
||||
|
||||
OptionTypeAntiReplayMaxSize
|
||||
OptionTypeAntiReplayEvictionTime
|
||||
|
||||
OptionTypeSecret
|
||||
OptionTypeAdtag
|
||||
@@ -80,8 +78,7 @@ type Config struct {
|
||||
ReadBuffer int `json:"read_buffer"`
|
||||
CloakPort int `json:"cloak_port"`
|
||||
|
||||
AntiReplayMaxSize int `json:"anti_replay_max_size"`
|
||||
AntiReplayEvictionTime time.Duration `json:"anti_replay_eviction_time"`
|
||||
AntiReplayMaxSize int64 `json:"anti_replay_max_size"`
|
||||
|
||||
Debug bool `json:"debug"`
|
||||
Verbose bool `json:"verbose"`
|
||||
@@ -151,9 +148,7 @@ func Init(options ...Opt) error { // nolint: gocyclo, funlen
|
||||
case OptionTypeCloakPort:
|
||||
C.CloakPort = int(opt.Value.(uint16))
|
||||
case OptionTypeAntiReplayMaxSize:
|
||||
C.AntiReplayMaxSize = opt.Value.(int)
|
||||
case OptionTypeAntiReplayEvictionTime:
|
||||
C.AntiReplayEvictionTime = opt.Value.(time.Duration)
|
||||
C.AntiReplayMaxSize = int64(opt.Value.(units.Base2Bytes))
|
||||
case OptionTypeSecret:
|
||||
C.Secret = opt.Value.([]byte)
|
||||
case OptionTypeAdtag:
|
||||
|
||||
@@ -11,10 +11,12 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/9seconds/mtg/antireplay"
|
||||
"github.com/9seconds/mtg/config"
|
||||
"github.com/9seconds/mtg/conntypes"
|
||||
"github.com/9seconds/mtg/obfuscated2"
|
||||
"github.com/9seconds/mtg/protocol"
|
||||
"github.com/9seconds/mtg/stats"
|
||||
"github.com/9seconds/mtg/tlstypes"
|
||||
"github.com/9seconds/mtg/wrappers/stream"
|
||||
)
|
||||
@@ -82,6 +84,13 @@ func (c *ClientProtocol) tlsHandshake(conn io.ReadWriter) error {
|
||||
return errBadTime
|
||||
}
|
||||
|
||||
if antireplay.Cache.HasTLS(clientHello.Random[:]) {
|
||||
stats.Stats.ReplayDetected()
|
||||
return errors.New("replay attack is detected")
|
||||
}
|
||||
|
||||
antireplay.Cache.AddTLS(clientHello.Random[:])
|
||||
|
||||
hostCert, err := connectionServerInstance.get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot get host certificate: %w", err)
|
||||
|
||||
@@ -3,13 +3,10 @@ module github.com/9seconds/mtg
|
||||
replace github.com/golang/lint => github.com/golang/lint v0.0.0-20190227174305-8f45f776aaf1
|
||||
|
||||
require (
|
||||
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d
|
||||
github.com/allegro/bigcache v1.2.1
|
||||
github.com/beevik/ntp v0.2.0
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/dgraph-io/ristretto v0.0.0-20191108194154-8d6a8a75b4ca
|
||||
github.com/prometheus/client_golang v1.2.1
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
go.uber.org/multierr v1.4.0 // indirect
|
||||
go.uber.org/zap v1.12.0
|
||||
golang.org/x/crypto v0.0.0-20191106202628-ed6320f186d4
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
||||
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
@@ -13,8 +10,6 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1C
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
|
||||
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
|
||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
@@ -23,13 +18,15 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
|
||||
github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgraph-io/ristretto v0.0.0-20191108194154-8d6a8a75b4ca h1:NgFAOh7RDM5WbdADm6VyLG1koLrzG0G24M/f5395PcI=
|
||||
github.com/dgraph-io/ristretto v0.0.0-20191108194154-8d6a8a75b4ca/go.mod h1:edzKIzGvqUCMzhTVWbiTSe75zD9Xxq0GtSBtFmaUTZs=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
@@ -94,9 +91,6 @@ github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
|
||||
@@ -104,15 +104,10 @@ var (
|
||||
Default("443").
|
||||
Uint16()
|
||||
runAntiReplayMaxSize = runCommand.Flag("anti-replay-max-size",
|
||||
"Max size of antireplay cache in megabytes.").
|
||||
"Max size of antireplay cache.").
|
||||
Envar("MTG_ANTIREPLAY_MAXSIZE").
|
||||
Default("128").
|
||||
Int()
|
||||
runAntiReplayEvictionTime = runCommand.Flag("anti-replay-eviction-time",
|
||||
"Eviction time period for obfuscated2 handshakes").
|
||||
Envar("MTG_ANTIREPLAY_EVICTIONTIME").
|
||||
Default("168h").
|
||||
Duration()
|
||||
Default("128MB").
|
||||
Bytes()
|
||||
runSecret = runCommand.Arg("secret", "Secret of this proxy.").Required().HexBytes()
|
||||
runAdtag = runCommand.Arg("adtag", "ADTag of the proxy.").HexBytes()
|
||||
)
|
||||
@@ -146,7 +141,6 @@ func main() {
|
||||
config.Opt{Option: config.OptionTypeReadBufferSize, Value: *runReadBufferSize},
|
||||
config.Opt{Option: config.OptionTypeCloakPort, Value: *runTLSCloakPort},
|
||||
config.Opt{Option: config.OptionTypeAntiReplayMaxSize, Value: *runAntiReplayMaxSize},
|
||||
config.Opt{Option: config.OptionTypeAntiReplayEvictionTime, Value: *runAntiReplayEvictionTime},
|
||||
config.Opt{Option: config.OptionTypeSecret, Value: *runSecret},
|
||||
config.Opt{Option: config.OptionTypeAdtag, Value: *runAdtag},
|
||||
)
|
||||
|
||||
@@ -81,13 +81,13 @@ func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conn
|
||||
c.dc = conntypes.DCDefaultIdx
|
||||
}
|
||||
|
||||
replayKeys := decryptedFrame.Unique()
|
||||
if antireplay.Cache.HasObfuscated2(replayKeys) {
|
||||
replayKey := decryptedFrame.Unique()
|
||||
if antireplay.Cache.HasObfuscated2(replayKey) {
|
||||
stats.Stats.ReplayDetected()
|
||||
return nil, errors.New("replay attack is detected")
|
||||
}
|
||||
|
||||
antireplay.Cache.AddObfuscated2(replayKeys)
|
||||
antireplay.Cache.AddObfuscated2(replayKey)
|
||||
|
||||
return stream.NewObfuscated2(socket, encryptor, decryptor), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user