Просмотр исходного кода

Correctly process doppel conns

tags/v2.2.0^2^2
9seconds 1 месяц назад
Родитель
Сommit
7a58c74cfe
2 измененных файлов: 34 добавлений и 26 удалений
  1. 10
    9
      mtglib/internal/doppel/ganger.go
  2. 24
    17
      mtglib/proxy.go

+ 10
- 9
mtglib/internal/doppel/ganger.go Просмотреть файл

9
 )
9
 )
10
 
10
 
11
 const (
11
 const (
12
-	DoppelGangerMaxDurations     = 4096
12
+	DoppelGangerMaxDurations  = 4096
13
 	DoppelGangerScoutRaidEach = 30 * time.Minute
13
 	DoppelGangerScoutRaidEach = 30 * time.Minute
14
-	DoppelGangerScoutRepeats     = 10
14
+	DoppelGangerScoutRepeats  = 10
15
 )
15
 )
16
 
16
 
17
 type gangerConnRequest struct {
17
 type gangerConnRequest struct {
18
-	ret     chan Conn
18
+	ret     chan<- Conn
19
 	payload essentials.Conn
19
 	payload essentials.Conn
20
 }
20
 }
21
 
21
 
25
 	logger    Logger
25
 	logger    Logger
26
 	wg        sync.WaitGroup
26
 	wg        sync.WaitGroup
27
 
27
 
28
-	scout               Scout
28
+	scout            Scout
29
 	scoutRaidEach    time.Duration
29
 	scoutRaidEach    time.Duration
30
 	scoutRaidRepeats int
30
 	scoutRaidRepeats int
31
 
31
 
47
 }
47
 }
48
 
48
 
49
 func (g *Ganger) NewConn(conn essentials.Conn) (Conn, error) {
49
 func (g *Ganger) NewConn(conn essentials.Conn) (Conn, error) {
50
+	rvChan := make(chan Conn)
50
 	req := gangerConnRequest{
51
 	req := gangerConnRequest{
51
-		ret:     make(chan Conn),
52
+		ret:     rvChan,
52
 		payload: conn,
53
 		payload: conn,
53
 	}
54
 	}
54
 	defer close(req.ret)
55
 	defer close(req.ret)
62
 	select {
63
 	select {
63
 	case <-g.ctx.Done():
64
 	case <-g.ctx.Done():
64
 		return Conn{}, context.Cause(g.ctx)
65
 		return Conn{}, context.Cause(g.ctx)
65
-	case conn := <-req.ret:
66
+	case conn := <-rvChan:
66
 		return conn, nil
67
 		return conn, nil
67
 	}
68
 	}
68
 }
69
 }
158
 	}
159
 	}
159
 
160
 
160
 	return &Ganger{
161
 	return &Ganger{
161
-		ctx:                 ctx,
162
-		ctxCancel:           cancel,
163
-		logger:              logger,
162
+		ctx:              ctx,
163
+		ctxCancel:        cancel,
164
+		logger:           logger,
164
 		scoutRaidEach:    scoutEach,
165
 		scoutRaidEach:    scoutEach,
165
 		scoutRaidRepeats: scoutRepeats,
166
 		scoutRaidRepeats: scoutRepeats,
166
 		stats: &Stats{
167
 		stats: &Stats{

+ 24
- 17
mtglib/proxy.go Просмотреть файл

78
 		ctx.logger.Info("Stream has been finished")
78
 		ctx.logger.Info("Stream has been finished")
79
 	}()
79
 	}()
80
 
80
 
81
-	if !p.doFakeTLSHandshake(ctx) {
81
+	noise, ok := p.doFakeTLSHandshake(ctx)
82
+	if !ok {
82
 		return
83
 		return
83
 	}
84
 	}
84
 
85
 
85
-	if err := p.doObfuscatedHandshake(ctx); err != nil {
86
-		p.logger.InfoError("obfuscated handshake is failed", err)
86
+	clientConn, err := p.doppelGanger.NewConn(ctx.clientConn)
87
+	if err != nil {
88
+		ctx.logger.InfoError("cannot wrap into doppelganger connection", err)
89
+		return
90
+	}
91
+	defer clientConn.Stop()
87
 
92
 
93
+	if _, err := clientConn.Write(noise); err != nil {
94
+		ctx.logger.InfoError("cannot send the first packet", err)
88
 		return
95
 		return
89
 	}
96
 	}
90
 
97
 
91
-	if err := p.doTelegramCall(ctx); err != nil {
92
-		p.logger.WarningError("cannot dial to telegram", err)
98
+	ctx.clientConn = clientConn
93
 
99
 
100
+	if err := p.doObfuscatedHandshake(ctx); err != nil {
101
+		ctx.logger.InfoError("obfuscated handshake is failed", err)
102
+		return
103
+	}
104
+
105
+	if err := p.doTelegramCall(ctx); err != nil {
106
+		ctx.logger.WarningError("cannot dial to telegram", err)
94
 		return
107
 		return
95
 	}
108
 	}
96
 
109
 
163
 	p.blocklist.Shutdown()
176
 	p.blocklist.Shutdown()
164
 }
177
 }
165
 
178
 
166
-func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool {
179
+func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) ([]byte, bool) {
167
 	rewind := newConnRewind(ctx.clientConn)
180
 	rewind := newConnRewind(ctx.clientConn)
168
 
181
 
169
 	clientHello, err := fake.ReadClientHello(
182
 	clientHello, err := fake.ReadClientHello(
175
 	if err != nil {
188
 	if err != nil {
176
 		p.logger.InfoError("cannot read client hello", err)
189
 		p.logger.InfoError("cannot read client hello", err)
177
 		p.doDomainFronting(ctx, rewind)
190
 		p.doDomainFronting(ctx, rewind)
178
-		return false
191
+		return nil, false
179
 	}
192
 	}
180
 
193
 
181
 	if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
194
 	if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
182
 		p.logger.Warning("replay attack has been detected!")
195
 		p.logger.Warning("replay attack has been detected!")
183
 		p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
196
 		p.eventStream.Send(p.ctx, NewEventReplayAttack(ctx.streamID))
184
 		p.doDomainFronting(ctx, rewind)
197
 		p.doDomainFronting(ctx, rewind)
185
-		return false
198
+		return nil, false
186
 	}
199
 	}
187
 
200
 
188
-	_, err = fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello)
201
+	noise, err := fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello)
189
 	if err != nil {
202
 	if err != nil {
190
 		p.logger.InfoError("cannot send welcome packet", err)
203
 		p.logger.InfoError("cannot send welcome packet", err)
191
-		return false
204
+		return nil, false
192
 	}
205
 	}
193
 
206
 
194
 	ctx.clientConn = tls.New(ctx.clientConn, true, true)
207
 	ctx.clientConn = tls.New(ctx.clientConn, true, true)
195
 
208
 
196
-	ctx.clientConn, err = p.doppelGanger.NewConn(ctx.clientConn)
197
-	if err != nil {
198
-		p.logger.WarningError("cannot create connection", err)
199
-		return false
200
-	}
201
-
202
-	return true
209
+	return noise, true
203
 }
210
 }
204
 
211
 
205
 func (p *Proxy) doObfuscatedHandshake(ctx *streamContext) error {
212
 func (p *Proxy) doObfuscatedHandshake(ctx *streamContext) error {

Загрузка…
Отмена
Сохранить