Explorar el Código

Add DTLS sniffer

世界 hace 1 año
padre
commit
369bc7cea3

+ 31 - 0
common/sniff/dtls.go

@@ -0,0 +1,31 @@
+package sniff
+
+import (
+	"context"
+	"os"
+
+	"github.com/sagernet/sing-box/adapter"
+	C "github.com/sagernet/sing-box/constant"
+)
+
+func DTLSRecord(ctx context.Context, packet []byte) (*adapter.InboundContext, error) {
+	const fixedHeaderSize = 13
+	if len(packet) < fixedHeaderSize {
+		return nil, os.ErrInvalid
+	}
+	contentType := packet[0]
+	switch contentType {
+	case 20, 21, 22, 23, 25:
+	default:
+		return nil, os.ErrInvalid
+	}
+	versionMajor := packet[1]
+	if versionMajor != 0xfe {
+		return nil, os.ErrInvalid
+	}
+	versionMinor := packet[2]
+	if versionMinor != 0xff && versionMinor != 0xfd {
+		return nil, os.ErrInvalid
+	}
+	return &adapter.InboundContext{Protocol: C.ProtocolDTLS}, nil
+}

+ 30 - 0
common/sniff/dtls_test.go

@@ -0,0 +1,30 @@
+package sniff_test
+
+import (
+	"context"
+	"encoding/hex"
+	"testing"
+
+	"github.com/sagernet/sing-box/common/sniff"
+	C "github.com/sagernet/sing-box/constant"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestSniffDTLSClientHello(t *testing.T) {
+	t.Parallel()
+	packet, err := hex.DecodeString("16fefd0000000000000000007e010000720000000000000072fefd668a43523798e064bd806d0c87660de9c611a59bbdfc3892c4e072d94f2cafc40000000cc02bc02fc00ac014c02cc0300100003c000d0010000e0403050306030401050106010807ff01000100000a00080006001d00170018000b00020100000e000900060008000700010000170000")
+	require.NoError(t, err)
+	metadata, err := sniff.DTLSRecord(context.Background(), packet)
+	require.NoError(t, err)
+	require.Equal(t, metadata.Protocol, C.ProtocolDTLS)
+}
+
+func TestSniffDTLSClientApplicationData(t *testing.T) {
+	t.Parallel()
+	packet, err := hex.DecodeString("17fefd000100000000000100440001000000000001a4f682b77ecadd10f3f3a2f78d90566212366ff8209fd77314f5a49352f9bb9bd12f4daba0b4736ae29e46b9714d3b424b3e6d0234736619b5aa0d3f")
+	require.NoError(t, err)
+	metadata, err := sniff.DTLSRecord(context.Background(), packet)
+	require.NoError(t, err)
+	require.Equal(t, metadata.Protocol, C.ProtocolDTLS)
+}

+ 1 - 0
constant/protocol.go

@@ -7,4 +7,5 @@ const (
 	ProtocolDNS        = "dns"
 	ProtocolSTUN       = "stun"
 	ProtocolBitTorrent = "bittorrent"
+	ProtocolDTLS       = "dtls"
 )

+ 18 - 8
docs/configuration/route/sniff.md

@@ -1,12 +1,22 @@
+---
+icon: material/new-box
+---
+
+!!! quote "Changes in sing-box 1.10.0"
+
+    :material-plus: BitTorrent support
+    :material-plus: DTLS support
+
 If enabled in the inbound, the protocol and domain name (if present) of by the connection can be sniffed.
 
 #### Supported Protocols
 
-| Network |  Protocol   | Domain Name |
-|:-------:|:-----------:|:-----------:|
-|   TCP   |    HTTP     |    Host     |
-|   TCP   |     TLS     | Server Name |
-|   UDP   |    QUIC     | Server Name |
-|   UDP   |    STUN     |      /      |
-| TCP/UDP |     DNS     |      /      |
-| TCP/UDP | BitTorrent  |      /      |
+| Network |   Protocol   | Domain Name |
+|:-------:|:------------:|:-----------:|
+|   TCP   |    `http`    |    Host     |
+|   TCP   |    `tls`     | Server Name |
+|   UDP   |    `quic`    | Server Name |
+|   UDP   |    `stun`    |      /      |
+| TCP/UDP |    `dns`     |      /      |
+| TCP/UDP | `bittorrent` |      /      |
+|   UDP   |    `dtls`    |      /      |

+ 18 - 8
docs/configuration/route/sniff.zh.md

@@ -1,12 +1,22 @@
+---
+icon: material/new-box
+---
+
+!!! quote "sing-box 1.10.0 中的更改"
+
+    :material-plus: BitTorrent 支持
+    :material-plus: DTLS 支持
+
 如果在入站中启用,则可以嗅探连接的协议和域名(如果存在)。
 
 #### 支持的协议
 
-|   网络    |     协议      |     域名      |
-|:-------:|:-----------:|:-----------:|
-|   TCP   |    HTTP     |    Host     |
-|   TCP   |     TLS     | Server Name |
-|   UDP   |    QUIC     | Server Name |
-|   UDP   |    STUN     |      /      |
-| TCP/UDP |     DNS     |      /      |
-| TCP/UDP | BitTorrent  |      /      |
+|   网络    |      协议      |     域名      |
+|:-------:|:------------:|:-----------:|
+|   TCP   |    `http`    |    Host     |
+|   TCP   |    `tls`     | Server Name |
+|   UDP   |    `quic`    | Server Name |
+|   UDP   |    `stun`    |      /      |
+| TCP/UDP |    `dns`     |      /      |
+| TCP/UDP | `bittorrent` |      /      |
+|   UDP   |    `dtls`    |      /      |

+ 1 - 0
route/router.go

@@ -1000,6 +1000,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
 				sniff.STUNMessage,
 				sniff.UTP,
 				sniff.UDPTracker,
+				sniff.DTLSRecord,
 			)
 				if sniffMetadata != nil {
 					metadata.Protocol = sniffMetadata.Protocol