From 48a01adb7a4f38974b9d9639f931d0d245aebf28 Mon Sep 17 00:00:00 2001 From: Skyxim Date: Sun, 17 Apr 2022 20:02:13 +0800 Subject: [PATCH] refactor: sniffer param force and reverses deprecated, will be removed when release version, replace force-domain and skip-sni, force-domain add '+' equivalent to force is true sniffer: enable: true force-domain: - "google.com" skip-sni: - www.baidu.com sniffing: - tls --- component/sniffer/dispatcher.go | 67 ++++++++++---------------------- config/config.go | 68 +++++++++++++++++++++++++-------- hub/executor/executor.go | 2 +- 3 files changed, 73 insertions(+), 64 deletions(-) diff --git a/component/sniffer/dispatcher.go b/component/sniffer/dispatcher.go index 73e2e9eb..5833b1a6 100644 --- a/component/sniffer/dispatcher.go +++ b/component/sniffer/dispatcher.go @@ -19,41 +19,12 @@ var ( var Dispatcher SnifferDispatcher type SnifferDispatcher struct { - enable bool - force bool - sniffers []C.Sniffer - domains *trie.DomainTrie[bool] - tcpHandler func(conn *CN.BufferedConn, metadata *C.Metadata) -} + enable bool -func (sd *SnifferDispatcher) forceReplace(conn *CN.BufferedConn, metadata *C.Metadata) { - host, err := sd.sniffDomain(conn, metadata) - if err != nil { - log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%s] to [%s:%s]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort) - return - } else { - if sd.inReverse(host) { - log.Debugln("[Sniffer] Skip replace host:%s", host) - return - } - } + sniffers []C.Sniffer - sd.replaceDomain(metadata, host) -} - -func (sd *SnifferDispatcher) replace(conn *CN.BufferedConn, metadata *C.Metadata) { - if metadata.Host != "" && !sd.inReverse(metadata.Host) { - log.Debugln("[Sniffer] Skip Sniff domain:%s", metadata.Host) - return - } - - host, err := sd.sniffDomain(conn, metadata) - if err != nil { - log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%s] to [%s:%s]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort) - return - } - - sd.replaceDomain(metadata, host) + foreDomain *trie.DomainTrie[bool] + skipSNI *trie.DomainTrie[bool] } func (sd *SnifferDispatcher) TCPSniff(conn net.Conn, metadata *C.Metadata) { @@ -62,11 +33,19 @@ func (sd *SnifferDispatcher) TCPSniff(conn net.Conn, metadata *C.Metadata) { return } - sd.tcpHandler(bufConn, metadata) -} + if metadata.Host == "" || sd.foreDomain.Search(metadata.Host) != nil { + if host, err := sd.sniffDomain(bufConn, metadata); err != nil { + log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%s] to [%s:%s]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort) + return + } else { + if sd.skipSNI.Search(host) != nil { + log.Debugln("[Sniffer] Skip sni[%s]", host) + return + } -func (sd *SnifferDispatcher) inReverse(host string) bool { - return sd.domains != nil && sd.domains.Search(host) != nil + sd.replaceDomain(metadata, host) + } + } } func (sd *SnifferDispatcher) replaceDomain(metadata *C.Metadata, host string) { @@ -122,11 +101,11 @@ func NewCloseSnifferDispatcher() (*SnifferDispatcher, error) { return &dispatcher, nil } -func NewSnifferDispatcher(needSniffer []C.SnifferType, force bool, reverses *trie.DomainTrie[bool]) (*SnifferDispatcher, error) { +func NewSnifferDispatcher(needSniffer []C.SnifferType, forceDomain *trie.DomainTrie[bool], skipSNI *trie.DomainTrie[bool]) (*SnifferDispatcher, error) { dispatcher := SnifferDispatcher{ - enable: true, - force: force, - domains: reverses, + enable: true, + foreDomain: forceDomain, + skipSNI: skipSNI, } for _, snifferName := range needSniffer { @@ -139,12 +118,6 @@ func NewSnifferDispatcher(needSniffer []C.SnifferType, force bool, reverses *tri dispatcher.sniffers = append(dispatcher.sniffers, sniffer) } - if force { - dispatcher.tcpHandler = dispatcher.forceReplace - } else { - dispatcher.tcpHandler = dispatcher.replace - } - return &dispatcher, nil } diff --git a/config/config.go b/config/config.go index 5d2c6847..c3894f31 100644 --- a/config/config.go +++ b/config/config.go @@ -121,10 +121,12 @@ type IPTables struct { } type Sniffer struct { - Enable bool - Force bool - Sniffers []C.SnifferType - Reverses *trie.DomainTrie[bool] + Enable bool + Force bool + Sniffers []C.SnifferType + Reverses *trie.DomainTrie[bool] + ForceDomain *trie.DomainTrie[bool] + SkipSNI *trie.DomainTrie[bool] } // Experimental config @@ -216,10 +218,12 @@ type RawConfig struct { } type SnifferRaw struct { - Enable bool `yaml:"enable" json:"enable"` - Force bool `yaml:"force" json:"force"` - Sniffing []string `yaml:"sniffing" json:"sniffing"` - Reverse []string `yaml:"reverses" json:"reverses"` + Enable bool `yaml:"enable" json:"enable"` + Sniffing []string `yaml:"sniffing" json:"sniffing"` + Force bool `yaml:"force" json:"force"` + Reverse []string `yaml:"reverses" json:"reverses"` + ForceDomain []string `yaml:"force-domain" json:"force-domain"` + SkipSNI []string `yaml:"skip-sni" json:"skip-sni"` } // Parse config @@ -288,10 +292,12 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) { }, }, Sniffer: SnifferRaw{ - Enable: false, - Force: false, - Sniffing: []string{}, - Reverse: []string{}, + Enable: false, + Force: false, + Sniffing: []string{}, + Reverse: []string{}, + ForceDomain: []string{}, + SkipSNI: []string{}, }, Profile: Profile{ StoreSelected: true, @@ -928,11 +934,41 @@ func parseSniffer(snifferRaw SnifferRaw) (*Sniffer, error) { sniffer.Sniffers = append(sniffer.Sniffers, st) } - sniffer.Reverses = trie.New[bool]() - for _, domain := range snifferRaw.Reverse { - err := sniffer.Reverses.Insert(domain, true) + sniffer.ForceDomain = trie.New[bool]() + for _, domain := range snifferRaw.ForceDomain { + err := sniffer.ForceDomain.Insert(domain, true) if err != nil { - return nil, fmt.Errorf("error domian[%s], error:%v", domain, err) + return nil, fmt.Errorf("error domian[%s] in force-domain, error:%v", domain, err) + } + } + + sniffer.SkipSNI = trie.New[bool]() + for _, domain := range snifferRaw.ForceDomain { + err := sniffer.SkipSNI.Insert(domain, true) + if err != nil { + return nil, fmt.Errorf("error domian[%s] in force-domain, error:%v", domain, err) + } + } + + // Compatibility, remove it when release + if strings.Contains(C.Version, "alpha") || strings.Contains(C.Version, "develop") || strings.Contains(C.Version, "1.10.0") { + log.Warnln("Sniffer param force and reverses deprecated, will be removed in the release version") + if snifferRaw.Force { + // match all domain + sniffer.ForceDomain.Insert("+", true) + for _, domain := range snifferRaw.Reverse { + err := sniffer.SkipSNI.Insert(domain, true) + if err != nil { + return nil, fmt.Errorf("error domian[%s], error:%v", domain, err) + } + } + } else { + for _, domain := range snifferRaw.Reverse { + err := sniffer.ForceDomain.Insert(domain, true) + if err != nil { + return nil, fmt.Errorf("error domian[%s], error:%v", domain, err) + } + } } } diff --git a/hub/executor/executor.go b/hub/executor/executor.go index e5cd6ba6..01222ce1 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -222,7 +222,7 @@ func updateTun(tun *config.Tun, dns *config.DNS) { func updateSniffer(sniffer *config.Sniffer) { if sniffer.Enable { - dispatcher, err := SNI.NewSnifferDispatcher(sniffer.Sniffers, sniffer.Force, sniffer.Reverses) + dispatcher, err := SNI.NewSnifferDispatcher(sniffer.Sniffers, sniffer.ForceDomain, sniffer.SkipSNI) if err != nil { log.Warnln("initial sniffer failed, err:%v", err) }