Explorar el Código

Add RDP sniffer

世界 hace 1 año
padre
commit
4a95558c53

+ 90 - 0
common/sniff/rdp.go

@@ -0,0 +1,90 @@
+package sniff
+
+import (
+	"context"
+	"encoding/binary"
+	"io"
+	"os"
+
+	"github.com/sagernet/sing-box/adapter"
+	C "github.com/sagernet/sing-box/constant"
+	"github.com/sagernet/sing/common/rw"
+)
+
+func RDP(_ context.Context, metadata *adapter.InboundContext, reader io.Reader) error {
+	var tpktVersion uint8
+	err := binary.Read(reader, binary.BigEndian, &tpktVersion)
+	if err != nil {
+		return err
+	}
+	if tpktVersion != 0x03 {
+		return os.ErrInvalid
+	}
+
+	var tpktReserved uint8
+	err = binary.Read(reader, binary.BigEndian, &tpktReserved)
+	if err != nil {
+		return err
+	}
+	if tpktReserved != 0x00 {
+		return os.ErrInvalid
+	}
+
+	var tpktLength uint16
+	err = binary.Read(reader, binary.BigEndian, &tpktLength)
+	if err != nil {
+		return err
+	}
+
+	if tpktLength != 19 {
+		return os.ErrInvalid
+	}
+
+	var cotpLength uint8
+	err = binary.Read(reader, binary.BigEndian, &cotpLength)
+	if err != nil {
+		return err
+	}
+
+	if cotpLength != 14 {
+		return os.ErrInvalid
+	}
+
+	var cotpTpduType uint8
+	err = binary.Read(reader, binary.BigEndian, &cotpTpduType)
+	if err != nil {
+		return err
+	}
+	if cotpTpduType != 0xE0 {
+		return os.ErrInvalid
+	}
+
+	err = rw.SkipN(reader, 5)
+	if err != nil {
+		return err
+	}
+
+	var rdpType uint8
+	err = binary.Read(reader, binary.BigEndian, &rdpType)
+	if err != nil {
+		return err
+	}
+	if rdpType != 0x01 {
+		return os.ErrInvalid
+	}
+	var rdpFlags uint8
+	err = binary.Read(reader, binary.BigEndian, &rdpFlags)
+	if err != nil {
+		return err
+	}
+	var rdpLength uint8
+	err = binary.Read(reader, binary.BigEndian, &rdpLength)
+	if err != nil {
+		return err
+	}
+	if rdpLength != 8 {
+		return os.ErrInvalid
+	}
+	metadata.Protocol = C.ProtocolRDP
+	return nil
+}

+ 25 - 0
common/sniff/rdp_test.go

@@ -0,0 +1,25 @@
+package sniff_test
+
+import (
+	"bytes"
+	"context"
+	"encoding/hex"
+	"testing"
+
+	"github.com/sagernet/sing-box/adapter"
+	"github.com/sagernet/sing-box/common/sniff"
+	C "github.com/sagernet/sing-box/constant"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestSniffRDP(t *testing.T) {
+	t.Parallel()
+
+	pkt, err := hex.DecodeString("030000130ee00000000000010008000b000000010008000b000000")
+	require.NoError(t, err)
+	var metadata adapter.InboundContext
+	err = sniff.RDP(context.TODO(), &metadata, bytes.NewReader(pkt))
+	require.NoError(t, err)
+	require.Equal(t, C.ProtocolRDP, metadata.Protocol)
+}

+ 1 - 0
constant/protocol.go

@@ -9,6 +9,7 @@ const (
 	ProtocolBitTorrent = "bittorrent"
 	ProtocolBitTorrent = "bittorrent"
 	ProtocolDTLS       = "dtls"
 	ProtocolDTLS       = "dtls"
 	ProtocolSSH        = "ssh"
 	ProtocolSSH        = "ssh"
+	ProtocolRDP        = "rdp"
 )
 )
 
 
 const (
 const (

+ 5 - 3
docs/configuration/route/sniff.md

@@ -8,14 +8,15 @@ icon: material/new-box
     :material-plus: Chromium support for QUIC  
     :material-plus: Chromium support for QUIC  
     :material-plus: BitTorrent support  
     :material-plus: BitTorrent support  
     :material-plus: DTLS support  
     :material-plus: DTLS support  
-    :material-plus: SSH support
+    :material-plus: SSH support  
+    :material-plus: RDP support
 
 
 If enabled in the inbound, the protocol and domain name (if present) of by the connection can be sniffed.
 If enabled in the inbound, the protocol and domain name (if present) of by the connection can be sniffed.
 
 
 #### Supported Protocols
 #### Supported Protocols
 
 
 | Network |   Protocol   | Domain Name |      Client      |
 | Network |   Protocol   | Domain Name |      Client      |
-| :-----: | :----------: | :---------: | :--------------: |
+|:-------:|:------------:|:-----------:|:----------------:|
 |   TCP   |    `http`    |    Host     |        /         |
 |   TCP   |    `http`    |    Host     |        /         |
 |   TCP   |    `tls`     | Server Name |        /         |
 |   TCP   |    `tls`     | Server Name |        /         |
 |   UDP   |    `quic`    | Server Name | QUIC Client Type |
 |   UDP   |    `quic`    | Server Name | QUIC Client Type |
@@ -24,9 +25,10 @@ If enabled in the inbound, the protocol and domain name (if present) of by the c
 | TCP/UDP | `bittorrent` |      /      |        /         |
 | TCP/UDP | `bittorrent` |      /      |        /         |
 |   UDP   |    `dtls`    |      /      |        /         |
 |   UDP   |    `dtls`    |      /      |        /         |
 |   TCP   |    `ssh`     |      /      | SSH Client Name  |
 |   TCP   |    `ssh`     |      /      | SSH Client Name  |
+|   TCP   |    `rdp`     |      /      |        /         |
 
 
 |       QUIC Client        |    Type    |
 |       QUIC Client        |    Type    |
-| :----------------------: | :--------: |
+|:------------------------:|:----------:|
 |     Chromium/Cronet      | `chrimium` |
 |     Chromium/Cronet      | `chrimium` |
 | Safari/Apple Network API |  `safari`  |
 | Safari/Apple Network API |  `safari`  |
 | Firefox / uquic firefox  | `firefox`  |
 | Firefox / uquic firefox  | `firefox`  |

+ 14 - 12
docs/configuration/route/sniff.zh.md

@@ -8,25 +8,27 @@ icon: material/new-box
     :material-plus: QUIC 的 Chromium 支持  
     :material-plus: QUIC 的 Chromium 支持  
     :material-plus: BitTorrent 支持  
     :material-plus: BitTorrent 支持  
     :material-plus: DTLS 支持  
     :material-plus: DTLS 支持  
-    :material-plus: SSH 支持
+    :material-plus: SSH 支持  
+    :material-plus: RDP 支持
 
 
 如果在入站中启用,则可以嗅探连接的协议和域名(如果存在)。
 如果在入站中启用,则可以嗅探连接的协议和域名(如果存在)。
 
 
 #### 支持的协议
 #### 支持的协议
 
 
-|  网络   |     协议     |    域名     |     客户端      |
-| :-----: | :----------: | :---------: | :-------------: |
-|   TCP   |    `http`    |    Host     |        /        |
-|   TCP   |    `tls`     | Server Name |        /        |
+|   网络    |      协议      |     域名      |    客户端     |
+|:-------:|:------------:|:-----------:|:----------:|
+|   TCP   |    `http`    |    Host     |     /      |
+|   TCP   |    `tls`     | Server Name |     /      |
 |   UDP   |    `quic`    | Server Name | QUIC 客户端类型 |
 |   UDP   |    `quic`    | Server Name | QUIC 客户端类型 |
-|   UDP   |    `stun`    |      /      |        /        |
-| TCP/UDP |    `dns`     |      /      |        /        |
-| TCP/UDP | `bittorrent` |      /      |        /        |
-|   UDP   |    `dtls`    |      /      |        /        |
-|   TCP   |    `SSH`     |      /      | SSH 客户端名称  |
+|   UDP   |    `stun`    |      /      |     /      |
+| TCP/UDP |    `dns`     |      /      |     /      |
+| TCP/UDP | `bittorrent` |      /      |     /      |
+|   UDP   |    `dtls`    |      /      |     /      |
+|   TCP   |    `ssh`     |      /      | SSH 客户端名称  |
+|   TCP   |    `rdp`     |      /      |     /      |
 
 
-|       QUIC 客户端        |    类型    |
-| :----------------------: | :--------: |
+|         QUIC 客户端         |     类型     |
+|:------------------------:|:----------:|
 |     Chromium/Cronet      | `chrimium` |
 |     Chromium/Cronet      | `chrimium` |
 | Safari/Apple Network API |  `safari`  |
 | Safari/Apple Network API |  `safari`  |
 | Firefox / uquic firefox  | `firefox`  |
 | Firefox / uquic firefox  | `firefox`  |