Bladeren bron

Insert padding with empty content to camouflage VLESS header (#1610)

This only affects the Vision client for protocols expecting server to send data first.
The change is compatible with existing version of Vision server.
yuhan6665 2 jaren geleden
bovenliggende
commit
c3faa8b7ac
2 gewijzigde bestanden met toevoegingen van 22 en 9 verwijderingen
  1. 15 9
      proxy/vless/encoding/encoding.go
  2. 7 0
      proxy/vless/outbound/outbound.go

+ 15 - 9
proxy/vless/encoding/encoding.go

@@ -506,25 +506,31 @@ func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBu
 
 // XtlsPadding add padding to eliminate length siganature during tls handshake
 func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, ctx context.Context) *buf.Buffer {
-	var length int32 = 0
-	if b.Len() < 900 {
+	var contantLen int32 = 0
+	var paddingLen int32 = 0
+	if b != nil {
+		contantLen = b.Len()
+	}
+	if contantLen < 900 {
 		l, err := rand.Int(rand.Reader, big.NewInt(500))
 		if err != nil {
 			newError("failed to generate padding").Base(err).WriteToLog(session.ExportIDToError(ctx))
 		}
-		length = int32(l.Int64()) + 900 - b.Len()
+		paddingLen = int32(l.Int64()) + 900 - contantLen
 	}
 	newbuffer := buf.New()
 	if userUUID != nil {
 		newbuffer.Write(*userUUID)
 		*userUUID = nil
 	}
-	newbuffer.Write([]byte{command, byte(b.Len() >> 8), byte(b.Len()), byte(length >> 8), byte(length)})
-	newbuffer.Write(b.Bytes())
-	newbuffer.Extend(length)
-	newError("XtlsPadding ", b.Len(), " ", length, " ", command).WriteToLog(session.ExportIDToError(ctx))
-	b.Release()
-	b = nil
+	newbuffer.Write([]byte{command, byte(contantLen >> 8), byte(contantLen), byte(paddingLen >> 8), byte(paddingLen)})
+	if (b != nil) {
+		newbuffer.Write(b.Bytes())
+		b.Release()
+		b = nil
+	}
+	newbuffer.Extend(paddingLen)
+	newError("XtlsPadding ", contantLen, " ", paddingLen, " ", command).WriteToLog(session.ExportIDToError(ctx))
 	return newbuffer
 }
 

+ 7 - 0
proxy/vless/outbound/outbound.go

@@ -249,6 +249,13 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
 				}
 			} else if err1 != buf.ErrReadTimeout {
 				return err1
+			} else if requestAddons.Flow == vless.XRV {
+				mb := make(buf.MultiBuffer, 1)
+				mb[0] = encoding.XtlsPadding(nil, 0x01, &userUUID, ctx) // it must not be tls so padding finish with it (command 1)
+				newError("Insert padding with empty content to camouflage VLESS header ", mb.Len()).WriteToLog(session.ExportIDToError(ctx))
+				if err := serverWriter.WriteMultiBuffer(mb); err != nil {
+					return err
+				}
 			}
 		} else {
 			newError("Reader is not timeout reader, will send out vless header separately from first payload").AtDebug().WriteToLog(session.ExportIDToError(ctx))