Add RDP sniffer

This commit is contained in:
世界 2024-08-28 14:22:19 +08:00
parent e39a28ed5a
commit 4a95558c53
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
5 changed files with 135 additions and 15 deletions

90
common/sniff/rdp.go Normal file
View file

@ -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
common/sniff/rdp_test.go Normal file
View file

@ -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)
}

View file

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

View file

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

View file

@ -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 | `http` | Host | / |
| TCP | `tls` | Server Name | / | | TCP | `tls` | Server Name | / |
| UDP | `quic` | Server Name | QUIC 客户端类型 | | UDP | `quic` | Server Name | QUIC 客户端类型 |
| UDP | `stun` | / | / | | UDP | `stun` | / | / |
| TCP/UDP | `dns` | / | / | | TCP/UDP | `dns` | / | / |
| TCP/UDP | `bittorrent` | / | / | | TCP/UDP | `bittorrent` | / | / |
| UDP | `dtls` | / | / | | UDP | `dtls` | / | / |
| TCP | `SSH` | / | SSH 客户端名称 | | 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` |