mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 11:54:01 +03:00
Correctly process doppel conns
This commit is contained in:
@@ -9,13 +9,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DoppelGangerMaxDurations = 4096
|
DoppelGangerMaxDurations = 4096
|
||||||
DoppelGangerScoutRaidEach = 30 * time.Minute
|
DoppelGangerScoutRaidEach = 30 * time.Minute
|
||||||
DoppelGangerScoutRepeats = 10
|
DoppelGangerScoutRepeats = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
type gangerConnRequest struct {
|
type gangerConnRequest struct {
|
||||||
ret chan Conn
|
ret chan<- Conn
|
||||||
payload essentials.Conn
|
payload essentials.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ type Ganger struct {
|
|||||||
logger Logger
|
logger Logger
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
scout Scout
|
scout Scout
|
||||||
scoutRaidEach time.Duration
|
scoutRaidEach time.Duration
|
||||||
scoutRaidRepeats int
|
scoutRaidRepeats int
|
||||||
|
|
||||||
@@ -47,8 +47,9 @@ func (g *Ganger) Run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *Ganger) NewConn(conn essentials.Conn) (Conn, error) {
|
func (g *Ganger) NewConn(conn essentials.Conn) (Conn, error) {
|
||||||
|
rvChan := make(chan Conn)
|
||||||
req := gangerConnRequest{
|
req := gangerConnRequest{
|
||||||
ret: make(chan Conn),
|
ret: rvChan,
|
||||||
payload: conn,
|
payload: conn,
|
||||||
}
|
}
|
||||||
defer close(req.ret)
|
defer close(req.ret)
|
||||||
@@ -62,7 +63,7 @@ func (g *Ganger) NewConn(conn essentials.Conn) (Conn, error) {
|
|||||||
select {
|
select {
|
||||||
case <-g.ctx.Done():
|
case <-g.ctx.Done():
|
||||||
return Conn{}, context.Cause(g.ctx)
|
return Conn{}, context.Cause(g.ctx)
|
||||||
case conn := <-req.ret:
|
case conn := <-rvChan:
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,9 +159,9 @@ func NewGanger(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Ganger{
|
return &Ganger{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
ctxCancel: cancel,
|
ctxCancel: cancel,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
scoutRaidEach: scoutEach,
|
scoutRaidEach: scoutEach,
|
||||||
scoutRaidRepeats: scoutRepeats,
|
scoutRaidRepeats: scoutRepeats,
|
||||||
stats: &Stats{
|
stats: &Stats{
|
||||||
|
|||||||
+24
-17
@@ -78,19 +78,32 @@ func (p *Proxy) ServeConn(conn essentials.Conn) {
|
|||||||
ctx.logger.Info("Stream has been finished")
|
ctx.logger.Info("Stream has been finished")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if !p.doFakeTLSHandshake(ctx) {
|
noise, ok := p.doFakeTLSHandshake(ctx)
|
||||||
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.doObfuscatedHandshake(ctx); err != nil {
|
clientConn, err := p.doppelGanger.NewConn(ctx.clientConn)
|
||||||
p.logger.InfoError("obfuscated handshake is failed", err)
|
if err != nil {
|
||||||
|
ctx.logger.InfoError("cannot wrap into doppelganger connection", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer clientConn.Stop()
|
||||||
|
|
||||||
|
if _, err := clientConn.Write(noise); err != nil {
|
||||||
|
ctx.logger.InfoError("cannot send the first packet", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.clientConn = clientConn
|
||||||
|
|
||||||
|
if err := p.doObfuscatedHandshake(ctx); err != nil {
|
||||||
|
ctx.logger.InfoError("obfuscated handshake is failed", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.doTelegramCall(ctx); err != nil {
|
if err := p.doTelegramCall(ctx); err != nil {
|
||||||
p.logger.WarningError("cannot dial to telegram", err)
|
ctx.logger.WarningError("cannot dial to telegram", err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +176,7 @@ func (p *Proxy) Shutdown() {
|
|||||||
p.blocklist.Shutdown()
|
p.blocklist.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool {
|
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) ([]byte, bool) {
|
||||||
rewind := newConnRewind(ctx.clientConn)
|
rewind := newConnRewind(ctx.clientConn)
|
||||||
|
|
||||||
clientHello, err := fake.ReadClientHello(
|
clientHello, err := fake.ReadClientHello(
|
||||||
@@ -175,31 +188,25 @@ func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
p.logger.InfoError("cannot read client hello", err)
|
p.logger.InfoError("cannot read client hello", err)
|
||||||
p.doDomainFronting(ctx, rewind)
|
p.doDomainFronting(ctx, rewind)
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
|
if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
|
||||||
p.logger.Warning("replay attack has been detected!")
|
p.logger.Warning("replay attack has been detected!")
|
||||||
p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
|
p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
|
||||||
p.doDomainFronting(ctx, rewind)
|
p.doDomainFronting(ctx, rewind)
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello)
|
noise, err := fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.logger.InfoError("cannot send welcome packet", err)
|
p.logger.InfoError("cannot send welcome packet", err)
|
||||||
return false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.clientConn = tls.New(ctx.clientConn, true, true)
|
ctx.clientConn = tls.New(ctx.clientConn, true, true)
|
||||||
|
|
||||||
ctx.clientConn, err = p.doppelGanger.NewConn(ctx.clientConn)
|
return noise, true
|
||||||
if err != nil {
|
|
||||||
p.logger.WarningError("cannot create connection", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Proxy) doObfuscatedHandshake(ctx *streamContext) error {
|
func (p *Proxy) doObfuscatedHandshake(ctx *streamContext) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user