浏览代码

Add RDP sniffer

世界 1 年之前
父节点
当前提交
cb46b648d7
共有 5 个文件被更改,包括 135 次插入15 次删除
  1. 90 0
      common/sniff/rdp.go
  2. 25 0
      common/sniff/rdp_test.go
  3. 1 0
      constant/protocol.go
  4. 5 3
      docs/configuration/route/sniff.md
  5. 14 12
      docs/configuration/route/sniff.zh.md

+ 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`  |