mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 16:24:03 +03:00
Add documentation for antireplay package
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
// Antireplay package has cache implementations that are effective
|
||||||
|
// against replay attacks.
|
||||||
|
//
|
||||||
|
// To understand more about replay attacks, please read documentation
|
||||||
|
// for mtglib.AntiReplayCache interface. This package has a list of some
|
||||||
|
// implementations of this interface.
|
||||||
|
package antireplay
|
||||||
+7
-2
@@ -1,6 +1,11 @@
|
|||||||
package antireplay
|
package antireplay
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DefaultMaxSize = 1024 * 1024 // 1MiB
|
// DefaultStableBloomFilterMaxSize is a recommended byte size for a
|
||||||
DefaultErrorRate = 0.001
|
// stable bloom filter.
|
||||||
|
DefaultStableBloomFilterMaxSize = 1024 * 1024 // 1MiB
|
||||||
|
|
||||||
|
// DefaultStableBloomFilterErrorRate is a recommended default error
|
||||||
|
// rate for a stable bloom filter.
|
||||||
|
DefaultStableBloomFilterErrorRate = 0.001
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ type noop struct{}
|
|||||||
|
|
||||||
func (n noop) SeenBefore(_ []byte) bool { return false }
|
func (n noop) SeenBefore(_ []byte) bool { return false }
|
||||||
|
|
||||||
|
// NewNoop returns an implementation that does nothing. A corresponding
|
||||||
|
// method always returns false, so this cache accepts everything you
|
||||||
|
// pass to it.
|
||||||
func NewNoop() mtglib.AntiReplayCache {
|
func NewNoop() mtglib.AntiReplayCache {
|
||||||
return noop{}
|
return noop{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,18 @@ func (s *stableBloomFilter) SeenBefore(digest []byte) bool {
|
|||||||
return s.filter.TestAndAdd(digest)
|
return s.filter.TestAndAdd(digest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewStableBloomFilter returns an implementation of AntiReplayCache
|
||||||
|
// based on stable bloom filter.
|
||||||
|
//
|
||||||
|
// http://webdocs.cs.ualberta.ca/~drafiei/papers/DupDet06Sigmod.pdf
|
||||||
|
//
|
||||||
|
// The basic idea of a stable bloom filter is quite simple: each time
|
||||||
|
// when you set a new element, you randomly reset P elements. There is a
|
||||||
|
// hardcore math which proves that if you choose this P correctly, you
|
||||||
|
// can maintain the same error rate for a stream of elements.
|
||||||
|
//
|
||||||
|
// byteSize is the number of bytes you want to give to a bloom filter .
|
||||||
|
// errorRate is desired false-positive error rate .
|
||||||
func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache {
|
func NewStableBloomFilter(byteSize uint, errorRate float64) mtglib.AntiReplayCache {
|
||||||
sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd
|
sf := boom.NewDefaultStableBloomFilter(byteSize*8, errorRate) // nolint: gomnd
|
||||||
sf.SetHash(xxhash.New64())
|
sf.SetHash(xxhash.New64())
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ func (c *Proxy) setupAntiReplayCache(opts *mtglib.ProxyOpts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
opts.AntiReplayCache = antireplay.NewStableBloomFilter(
|
opts.AntiReplayCache = antireplay.NewStableBloomFilter(
|
||||||
c.Config.Defense.AntiReplay.MaxSize.Value(antireplay.DefaultMaxSize),
|
c.Config.Defense.AntiReplay.MaxSize.Value(antireplay.DefaultStableBloomFilterMaxSize),
|
||||||
c.Config.Defense.AntiReplay.ErrorRate.Value(antireplay.DefaultErrorRate),
|
c.Config.Defense.AntiReplay.ErrorRate.Value(antireplay.DefaultStableBloomFilterErrorRate),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,39 @@ type Network interface {
|
|||||||
MakeHTTPClient(func(ctx context.Context, network, address string) (net.Conn, error)) *http.Client
|
MakeHTTPClient(func(ctx context.Context, network, address string) (net.Conn, error)) *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AntiReplayCache is an interface that is used to detect replay attacks
|
||||||
|
// based on some traffic fingerprints.
|
||||||
|
//
|
||||||
|
// Replay attacks are probe attacks whose main goal is to identify if
|
||||||
|
// server software can be classified in some way. For example, if you
|
||||||
|
// send some HTTP request to a web server, then you can expect that this
|
||||||
|
// server will respond with HTTP response back.
|
||||||
|
//
|
||||||
|
// There is a problem though. Let's imagine, that connection is
|
||||||
|
// encrypted. Let's imagine, that it is encrypted with some static key
|
||||||
|
// like ShadowSocks (https://shadowsocks.org/assets/whitepaper.pdf).
|
||||||
|
// In that case, in theory, if you repeat the same bytes, you can get
|
||||||
|
// the same responses. Let's imagine, that you've cracked the key. then
|
||||||
|
// if you send the same bytes, you can decrypt a response and see its
|
||||||
|
// structure. Based on its structure you can identify if this server is
|
||||||
|
// SOCKS5, MTPROTO proxy etc.
|
||||||
|
//
|
||||||
|
// This is just one example, maybe not the best or not the most
|
||||||
|
// relevant. In real life, different organizations use such replay
|
||||||
|
// attacks to perform some reverse engineering of the proxy, do some
|
||||||
|
// statical analysis to identify server software.
|
||||||
|
//
|
||||||
|
// There are many ways how to protect your proxy against them. One
|
||||||
|
// is domain fronting which is a core part of mtg. Another one is to
|
||||||
|
// collect some 'handshake fingerprints' and forbid duplication.
|
||||||
|
//
|
||||||
|
// So, it one is sending the same byte flow right after you (or a couple
|
||||||
|
// of hours after), mtg should detect that and reject this connection
|
||||||
|
// (or redirect to fronting domain).
|
||||||
type AntiReplayCache interface {
|
type AntiReplayCache interface {
|
||||||
|
// Seen before checks if this set of bytes was observed before or
|
||||||
|
// not. If it is required to store this information somewhere else,
|
||||||
|
// then it has to do that.
|
||||||
SeenBefore(data []byte) bool
|
SeenBefore(data []byte) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user