Integrate new fake package and doppel into proxy

This commit is contained in:
9seconds
2026-03-12 19:07:11 +01:00
parent 37f8d18be5
commit bb49c6a55d
8 changed files with 76 additions and 85 deletions
+9 -5
View File
@@ -12,7 +12,6 @@ import (
"slices" "slices"
"time" "time"
"github.com/9seconds/mtg/v2/mtglib"
"github.com/9seconds/mtg/v2/mtglib/internal/tls" "github.com/9seconds/mtg/v2/mtglib/internal/tls"
) )
@@ -37,7 +36,12 @@ type ClientHello struct {
CipherSuite uint16 CipherSuite uint16
} }
func ReadClientHello(conn net.Conn, secret mtglib.Secret, tolerateTimeSkewness time.Duration) (*ClientHello, error) { func ReadClientHello(
conn net.Conn,
secret []byte,
hostname string,
tolerateTimeSkewness time.Duration,
) (*ClientHello, error) {
if err := conn.SetReadDeadline(time.Now().Add(ClientHelloReadTimeout)); err != nil { if err := conn.SetReadDeadline(time.Now().Add(ClientHelloReadTimeout)); err != nil {
return nil, fmt.Errorf("cannot set read deadline: %w", err) return nil, fmt.Errorf("cannot set read deadline: %w", err)
} }
@@ -75,11 +79,11 @@ func ReadClientHello(conn net.Conn, secret mtglib.Secret, tolerateTimeSkewness t
return nil, fmt.Errorf("cannot parse SNI: %w", err) return nil, fmt.Errorf("cannot parse SNI: %w", err)
} }
if !slices.Contains(sniHostnames, secret.Host) { if !slices.Contains(sniHostnames, hostname) {
return nil, fmt.Errorf("cannot find %s in %v", secret.Host, sniHostnames) return nil, fmt.Errorf("cannot find %s in %v", hostname, sniHostnames)
} }
digest := hmac.New(sha256.New, secret.Key[:]) digest := hmac.New(sha256.New, secret)
// we write a copy of the handshake with client random all nullified. // we write a copy of the handshake with client random all nullified.
digest.Write(handshakeCopyBuf.Next(RandomOffset)) digest.Write(handshakeCopyBuf.Next(RandomOffset))
handshakeCopyBuf.Next(RandomLen) handshakeCopyBuf.Next(RandomLen)
@@ -42,7 +42,7 @@ func FuzzReadClientHello(f *testing.F) {
Twice(). Twice().
Return(nil) Return(nil)
_, err := fake.ReadClientHello(r, secret, time.Hour) _, err := fake.ReadClientHello(r, secret.Key[:], secret.Host, time.Hour)
assert.Error(t, err) assert.Error(t, err)
}) })
@@ -100,7 +100,12 @@ func (suite *ParseClientHelloSnapshotTestSuite) TestSnapshotOk() {
connMock := suite.makeConn(snapshot.GetFull()) connMock := suite.makeConn(snapshot.GetFull())
defer connMock.AssertExpectations(t) defer connMock.AssertExpectations(t)
hello, err := fake.ReadClientHello(connMock, suite.secret, TolerateTime) hello, err := fake.ReadClientHello(
connMock,
suite.secret.Key[:],
suite.secret.Host,
TolerateTime,
)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, snapshot.GetRandom(), hello.Random[:]) assert.Equal(t, snapshot.GetRandom(), hello.Random[:])
@@ -131,7 +136,12 @@ func (suite *ParseClientHelloSnapshotTestSuite) TestSnapshotBad() {
connMock := suite.makeConn(snapshot.GetFull()) connMock := suite.makeConn(snapshot.GetFull())
defer connMock.AssertExpectations(t) defer connMock.AssertExpectations(t)
_, err = fake.ReadClientHello(connMock, suite.secret, TolerateTime) _, err = fake.ReadClientHello(
connMock,
suite.secret.Key[:],
suite.secret.Host,
TolerateTime,
)
assert.ErrorIs(t, err, fake.ErrBadDigest) assert.ErrorIs(t, err, fake.ErrBadDigest)
}) })
} }
+27 -27
View File
@@ -73,7 +73,7 @@ func (suite *ParseClientHello_TLSHeaderTestSuite) TestEmpty() {
Once(). Once().
Return(errors.New("fail")) Return(errors.New("fail"))
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "fail") suite.ErrorContains(err, "fail")
} }
@@ -84,7 +84,7 @@ func (suite *ParseClientHello_TLSHeaderTestSuite) TestNothing() {
Twice(). Twice().
Return(nil) Return(nil)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorIs(err, io.EOF) suite.ErrorIs(err, io.EOF)
} }
@@ -96,7 +96,7 @@ func (suite *ParseClientHello_TLSHeaderTestSuite) TestUnknownRecord() {
}) })
suite.readBuf.WriteByte(10) suite.readBuf.WriteByte(10)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "unexpected record type 0xa") suite.ErrorContains(err, "unexpected record type 0xa")
} }
@@ -107,7 +107,7 @@ func (suite *ParseClientHello_TLSHeaderTestSuite) TestUnknownProtocolVersion() {
0, 0, 0, 0,
}) })
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "unexpected protocol version") suite.ErrorContains(err, "unexpected protocol version")
} }
@@ -118,7 +118,7 @@ func (suite *ParseClientHello_TLSHeaderTestSuite) TestCannotReadRestOfRecord() {
0, 10, 0, 10,
}) })
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorIs(err, io.EOF) suite.ErrorIs(err, io.EOF)
} }
@@ -142,7 +142,7 @@ func (suite *ParseClientHelloHandshakeTestSuite) TestCannotReadHeader() {
10, 10,
}) })
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read handshake header") suite.ErrorContains(err, "cannot read handshake header")
} }
@@ -152,7 +152,7 @@ func (suite *ParseClientHelloHandshakeTestSuite) TestIncorrectHandshakeType() {
10, 0, 0, 0, 10, 0, 0, 0,
}) })
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "incorrect handshake type") suite.ErrorContains(err, "incorrect handshake type")
} }
@@ -162,7 +162,7 @@ func (suite *ParseClientHelloHandshakeTestSuite) TestCannotReadHandshake() {
10, 0, 0, 0, 10, 0, 0, 0,
}) })
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorIs(err, io.EOF) suite.ErrorIs(err, io.EOF)
} }
@@ -192,14 +192,14 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) writeBody(body []byte) {
func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadVersion() { func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadVersion() {
suite.writeBody(nil) suite.writeBody(nil)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read client version") suite.ErrorContains(err, "cannot read client version")
} }
func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadRandom() { func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadRandom() {
suite.writeBody([]byte{3, 3}) suite.writeBody([]byte{3, 3})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read client random") suite.ErrorContains(err, "cannot read client random")
} }
@@ -208,7 +208,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadSessionIDLeng
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read session ID length") suite.ErrorContains(err, "cannot read session ID length")
} }
@@ -218,7 +218,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadSessionID() {
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read session id") suite.ErrorContains(err, "cannot read session id")
} }
@@ -227,7 +227,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadCipherSuiteLe
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read cipher suite length") suite.ErrorContains(err, "cannot read cipher suite length")
} }
@@ -236,7 +236,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadFirstCipherSu
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read first cipher suite") suite.ErrorContains(err, "cannot read first cipher suite")
} }
@@ -246,7 +246,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotSkipRemainingCiph
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot skip remaining cipher suites") suite.ErrorContains(err, "cannot skip remaining cipher suites")
} }
@@ -256,7 +256,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotReadCompressionMe
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read compression methods length") suite.ErrorContains(err, "cannot read compression methods length")
} }
@@ -267,7 +267,7 @@ func (suite *ParseClientHelloHandshakeBodyTestSuite) TestCannotSkipCompressionMe
suite.writeBody(body) suite.writeBody(body)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot skip compression methods") suite.ErrorContains(err, "cannot skip compression methods")
} }
@@ -307,70 +307,70 @@ func (suite *ParseClientHelloSNITestSuite) writeExtensions(extensions []byte) {
func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionsLength() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionsLength() {
suite.writeExtensions(nil) suite.writeExtensions(nil)
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read length of TLS extensions") suite.ErrorContains(err, "cannot read length of TLS extensions")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensions() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensions() {
suite.writeExtensions([]byte{0, 10}) suite.writeExtensions([]byte{0, 10})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read extensions") suite.ErrorContains(err, "cannot read extensions")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionType() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionType() {
suite.writeExtensions([]byte{0, 1, 0xAB}) suite.writeExtensions([]byte{0, 1, 0xAB})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read extension type") suite.ErrorContains(err, "cannot read extension type")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionLength() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionLength() {
suite.writeExtensions([]byte{0, 2, 0xFF, 0xFF}) suite.writeExtensions([]byte{0, 2, 0xFF, 0xFF})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "length:") suite.ErrorContains(err, "length:")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionData() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadExtensionData() {
suite.writeExtensions([]byte{0, 4, 0xFF, 0xFF, 0, 5}) suite.writeExtensions([]byte{0, 4, 0xFF, 0xFF, 0, 5})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "data: len") suite.ErrorContains(err, "data: len")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadSNIRecordLength() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadSNIRecordLength() {
suite.writeExtensions([]byte{0, 5, 0, 0, 0, 1, 0xAB}) suite.writeExtensions([]byte{0, 5, 0, 0, 0, 1, 0xAB})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read the length of the SNI record") suite.ErrorContains(err, "cannot read the length of the SNI record")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadSNIListType() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadSNIListType() {
suite.writeExtensions([]byte{0, 6, 0, 0, 0, 2, 0, 1}) suite.writeExtensions([]byte{0, 6, 0, 0, 0, 2, 0, 1})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "cannot read SNI list type") suite.ErrorContains(err, "cannot read SNI list type")
} }
func (suite *ParseClientHelloSNITestSuite) TestIncorrectSNIListType() { func (suite *ParseClientHelloSNITestSuite) TestIncorrectSNIListType() {
suite.writeExtensions([]byte{0, 7, 0, 0, 0, 3, 0, 1, 5}) suite.writeExtensions([]byte{0, 7, 0, 0, 0, 3, 0, 1, 5})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "incorrect SNI list type") suite.ErrorContains(err, "incorrect SNI list type")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadHostnameLength() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadHostnameLength() {
suite.writeExtensions([]byte{0, 8, 0, 0, 0, 4, 0, 2, 0, 0xAB}) suite.writeExtensions([]byte{0, 8, 0, 0, 0, 4, 0, 2, 0, 0xAB})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "incorrect length of the hostname") suite.ErrorContains(err, "incorrect length of the hostname")
} }
func (suite *ParseClientHelloSNITestSuite) TestCannotReadHostname() { func (suite *ParseClientHelloSNITestSuite) TestCannotReadHostname() {
suite.writeExtensions([]byte{0, 9, 0, 0, 0, 5, 0, 3, 0, 0, 5}) suite.writeExtensions([]byte{0, 9, 0, 0, 0, 5, 0, 3, 0, 0, 5})
_, err := fake.ReadClientHello(suite.connMock, suite.secret, TolerateTime) _, err := fake.ReadClientHello(suite.connMock, suite.secret.Key[:], suite.secret.Host, TolerateTime)
suite.ErrorContains(err, "incorrect length of SNI hostname") suite.ErrorContains(err, "incorrect length of SNI hostname")
} }
+2 -3
View File
@@ -8,7 +8,6 @@ import (
"encoding/binary" "encoding/binary"
"io" "io"
"github.com/9seconds/mtg/v2/mtglib"
"github.com/9seconds/mtg/v2/mtglib/internal/tls" "github.com/9seconds/mtg/v2/mtglib/internal/tls"
"golang.org/x/crypto/curve25519" "golang.org/x/crypto/curve25519"
) )
@@ -35,7 +34,7 @@ var (
} }
) )
func SendServerHello(w io.Writer, secret mtglib.Secret, clientHello *ClientHello) ([]byte, error) { func SendServerHello(w io.Writer, secret []byte, clientHello *ClientHello) ([]byte, error) {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
buf.Grow(tls.MaxRecordSize) buf.Grow(tls.MaxRecordSize)
@@ -46,7 +45,7 @@ func SendServerHello(w io.Writer, secret mtglib.Secret, clientHello *ClientHello
generateNoise(noise) generateNoise(noise)
packet := buf.Bytes() packet := buf.Bytes()
digest := hmac.New(sha256.New, secret.Key[:]) digest := hmac.New(sha256.New, secret)
digest.Write(clientHello.Random[:]) digest.Write(clientHello.Random[:])
digest.Write(packet) digest.Write(packet)
+4 -4
View File
@@ -38,7 +38,7 @@ func (suite *SendServerHelloTestSuite) SetupTest() {
} }
func (suite *SendServerHelloTestSuite) TestRecordStructure() { func (suite *SendServerHelloTestSuite) TestRecordStructure() {
noise, err := fake.SendServerHello(suite.buf, suite.secret, suite.hello) noise, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
suite.NoError(err) suite.NoError(err)
var rec bytes.Buffer var rec bytes.Buffer
@@ -65,7 +65,7 @@ func (suite *SendServerHelloTestSuite) TestRecordStructure() {
} }
func (suite *SendServerHelloTestSuite) TestHMAC() { func (suite *SendServerHelloTestSuite) TestHMAC() {
noise, err := fake.SendServerHello(suite.buf, suite.secret, suite.hello) noise, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
suite.NoError(err) suite.NoError(err)
packet := make([]byte, suite.buf.Len()) packet := make([]byte, suite.buf.Len())
@@ -84,7 +84,7 @@ func (suite *SendServerHelloTestSuite) TestHMAC() {
} }
func (suite *SendServerHelloTestSuite) TestHandshakePayload() { func (suite *SendServerHelloTestSuite) TestHandshakePayload() {
_, err := fake.SendServerHello(suite.buf, suite.secret, suite.hello) _, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
suite.NoError(err) suite.NoError(err)
packet := suite.buf.Bytes() packet := suite.buf.Bytes()
@@ -106,7 +106,7 @@ func (suite *SendServerHelloTestSuite) TestHandshakePayload() {
} }
func (suite *SendServerHelloTestSuite) TestChangeCipherSpec() { func (suite *SendServerHelloTestSuite) TestChangeCipherSpec() {
_, err := fake.SendServerHello(suite.buf, suite.secret, suite.hello) _, err := fake.SendServerHello(suite.buf, suite.secret.Key[:], suite.hello)
suite.NoError(err) suite.NoError(err)
// Skip first record // Skip first record
+20 -31
View File
@@ -11,10 +11,11 @@ import (
"github.com/9seconds/mtg/v2/essentials" "github.com/9seconds/mtg/v2/essentials"
"github.com/9seconds/mtg/v2/mtglib/internal/dc" "github.com/9seconds/mtg/v2/mtglib/internal/dc"
"github.com/9seconds/mtg/v2/mtglib/internal/faketls" "github.com/9seconds/mtg/v2/mtglib/internal/doppel"
"github.com/9seconds/mtg/v2/mtglib/internal/faketls/record"
"github.com/9seconds/mtg/v2/mtglib/internal/obfuscation" "github.com/9seconds/mtg/v2/mtglib/internal/obfuscation"
"github.com/9seconds/mtg/v2/mtglib/internal/relay" "github.com/9seconds/mtg/v2/mtglib/internal/relay"
"github.com/9seconds/mtg/v2/mtglib/internal/tls"
"github.com/9seconds/mtg/v2/mtglib/internal/tls/fake"
"github.com/panjf2000/ants/v2" "github.com/panjf2000/ants/v2"
) )
@@ -32,6 +33,7 @@ type Proxy struct {
workerPool *ants.PoolWithFunc workerPool *ants.PoolWithFunc
telegram *dc.Telegram telegram *dc.Telegram
configUpdater *dc.PublicConfigUpdater configUpdater *dc.PublicConfigUpdater
doppelGanger *doppel.Ganger
clientObfuscatror obfuscation.Obfuscator clientObfuscatror obfuscation.Obfuscator
secret Secret secret Secret
@@ -161,52 +163,39 @@ func (p *Proxy) Shutdown() {
} }
func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool { func (p *Proxy) doFakeTLSHandshake(ctx *streamContext) bool {
rec := record.AcquireRecord()
defer record.ReleaseRecord(rec)
rewind := newConnRewind(ctx.clientConn) rewind := newConnRewind(ctx.clientConn)
if err := rec.Read(rewind); err != nil { clientHello, err := fake.ReadClientHello(
rewind,
p.secret.Key[:],
p.secret.Host,
p.tolerateTimeSkewness,
)
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 false
} }
hello, err := faketls.ParseClientHello(p.secret.Key[:], rec.Payload.Bytes()) if p.antiReplayCache.SeenBefore(clientHello.SessionID) {
if err != nil {
p.logger.InfoError("cannot parse client hello", err)
p.doDomainFronting(ctx, rewind)
return false
}
if err := hello.Valid(p.secret.Host, p.tolerateTimeSkewness); err != nil {
p.logger.
BindStr("hostname", hello.Host).
BindStr("hello-time", hello.Time.String()).
InfoError("invalid faketls client hello", err)
p.doDomainFronting(ctx, rewind)
return false
}
if p.antiReplayCache.SeenBefore(hello.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 false
} }
if err := faketls.SendWelcomePacket(rewind, p.secret.Key[:], hello); err != nil { _, err = fake.SendServerHello(ctx.clientConn, p.secret.Key[:], clientHello)
if err != nil {
p.logger.InfoError("cannot send welcome packet", err) p.logger.InfoError("cannot send welcome packet", err)
return false return false
} }
ctx.clientConn = &faketls.Conn{ ctx.clientConn = tls.New(ctx.clientConn, true, true)
Conn: ctx.clientConn,
ctx.clientConn, err = p.doppelGanger.NewConn(ctx.clientConn)
if err != nil {
p.logger.WarningError("cannot create connection", err)
return false
} }
return true return true
+1 -12
View File
@@ -1,9 +1,6 @@
package network package network
import ( import "net/http"
"crypto/tls"
"net/http"
)
type networkHTTPTransport struct { type networkHTTPTransport struct {
userAgent string userAgent string
@@ -15,11 +12,3 @@ func (n networkHTTPTransport) RoundTrip(req *http.Request) (*http.Response, erro
return n.next.RoundTrip(req) //nolint: wrapcheck return n.next.RoundTrip(req) //nolint: wrapcheck
} }
func (n networkHTTPTransport) TrustTLS() {
tr := n.next.(*http.Transport)
if tr.TLSClientConfig == nil {
tr.TLSClientConfig = &tls.Config{}
}
tr.TLSClientConfig.InsecureSkipVerify = true
}