Skip to content

Commit

Permalink
feat: Add URL-REGEX rule
Browse files Browse the repository at this point in the history
  • Loading branch information
xishang0128 committed Apr 4, 2024
1 parent 698aecf commit 6a7f472
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 90 deletions.
3 changes: 2 additions & 1 deletion adapter/inbound/mitm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import (
)

// NewMitm receive mitm request and return MitmContext
func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
func NewMitm(target socks5.Addr, srcConn net.Conn, userAgent string, Url string, conn net.Conn, additions ...Addition) (net.Conn, *C.Metadata) {
metadata := parseSocksAddr(target)
metadata.NetWork = C.TCP
metadata.Type = C.MITM
metadata.UserAgent = userAgent
metadata.Url = Url
metadata.RawSrcAddr = srcConn.RemoteAddr()
metadata.RawDstAddr = srcConn.LocalAddr()
ApplyAdditions(metadata, WithSrcAddr(srcConn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
Expand Down
36 changes: 26 additions & 10 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"strings"
"time"

rewrites "github.com/metacubex/mihomo/rewrite"
"github.com/metacubex/mihomo/adapter"
"github.com/metacubex/mihomo/adapter/outbound"
"github.com/metacubex/mihomo/adapter/outboundgroup"
Expand All @@ -37,6 +36,7 @@ import (
L "github.com/metacubex/mihomo/listener"
LC "github.com/metacubex/mihomo/listener/config"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/mihomo/mitm"
R "github.com/metacubex/mihomo/rules"
RP "github.com/metacubex/mihomo/rules/provider"
T "github.com/metacubex/mihomo/tunnel"
Expand Down Expand Up @@ -168,8 +168,9 @@ type Sniffer struct {

// Mitm config
type Mitm struct {
Port int `yaml:"port" json:"port"`
Rules C.RewriteRule `yaml:"rules" json:"rules"`
Port int `yaml:"port" json:"port"`
Hosts *trie.DomainTrie[bool] `yaml:"hosts" json:"hosts"`
Rules C.RewriteRule `yaml:"rules" json:"rules"`
}

// Experimental config
Expand Down Expand Up @@ -293,8 +294,9 @@ type RawTuicServer struct {
}

type RawMitm struct {
Port int `yaml:"port" json:"port"`
Rules []rewrites.RawMitmRule `yaml:"rules" json:"rules"`
Port int `yaml:"port" json:"port"`
Hosts []string `yaml:"hosts" json:"hosts"`
Rules []mitm.RawMitmRule `yaml:"rules" json:"rules"`
}

type RawConfig struct {
Expand Down Expand Up @@ -514,8 +516,8 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
OverrideDest: true,
},
MITM: RawMitm{
Port: 0,
Rules: []rewrites.RawMitmRule{},
Hosts: []string{},
Rules: []mitm.RawMitmRule{},
},
Profile: Profile{
StoreSelected: true,
Expand Down Expand Up @@ -751,6 +753,9 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
if cfg.MITM.Port != 0 {
proxies["MITM"] = adapter.NewProxy(outbound.NewMitm(fmt.Sprintf("127.0.0.1:%d", cfg.MITM.Port)))
proxyList = append(proxyList, "MITM")
} else if len(cfg.MITM.Hosts) != 0 {
proxies["MITM"] = adapter.NewProxy(outbound.NewMitm(fmt.Sprintf("127.0.0.1:%d", cfg.MitmPort)))
proxyList = append(proxyList, "MITM")
}

// parse proxy
Expand Down Expand Up @@ -953,7 +958,7 @@ func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[s

l := len(rule)

if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" || ruleName == "DOMAIN-REGEX" {
if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" || ruleName == "DOMAIN-REGEX" || ruleName == "URL-REGEX" {
target = rule[l-1]
payload = strings.Join(rule[1:l-1], ",")
} else {
Expand Down Expand Up @@ -1609,7 +1614,7 @@ func parseMitm(rawMitm RawMitm) (*Mitm, error) {
)

for _, line := range rawMitm.Rules {
rule, err := rewrites.ParseRewrite(line)
rule, err := mitm.ParseRewrite(line)
if err != nil {
return nil, fmt.Errorf("parse rewrite rule failure: %w", err)
}
Expand All @@ -1621,8 +1626,19 @@ func parseMitm(rawMitm RawMitm) (*Mitm, error) {
}
}

hosts := trie.New[bool]()

if len(rawMitm.Hosts) != 0 {
for _, domain := range rawMitm.Hosts {
_ = hosts.Insert(domain, true)
}
}

_ = hosts.Insert("mitm.mihomo", true)

return &Mitm{
Port: rawMitm.Port,
Rules: rewrites.NewRewriteRules(req, res),
Hosts: hosts,
Rules: mitm.NewRewriteRules(req, res),
}, nil
}
5 changes: 3 additions & 2 deletions constant/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type Metadata struct {
SniffHost string `json:"sniffHost"`
// Only Mitm rule
UserAgent string `json:"userAgent"`
Url string `json:"url"`
}

func (m *Metadata) RemoteAddress() string {
Expand All @@ -176,7 +177,7 @@ func (m *Metadata) SourceAddrPort() netip.AddrPort {

func (m *Metadata) SourceDetail() string {
if m.Type == INNER {
return fmt.Sprintf("%s", MihomoName)
return MihomoName
} else if m.Type == MITM {
return fmt.Sprintf("%s-MITM", MihomoName)
}
Expand All @@ -189,7 +190,7 @@ func (m *Metadata) SourceDetail() string {
case m.Process != "":
return fmt.Sprintf("%s(%s)", m.SourceAddress(), m.Process)
default:
return fmt.Sprintf("%s", m.SourceAddress())
return m.SourceAddress()
}
}

Expand Down
3 changes: 3 additions & 0 deletions constant/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
Uid
SubRules
UserAgent
UrlRegex
MATCH
AND
OR
Expand Down Expand Up @@ -83,6 +84,8 @@ func (rt RuleType) String() string {
return "ProcessPath"
case UserAgent:
return "UserAgent"
case UrlRegex:
return "UrlRegex"
case MATCH:
return "Match"
case RuleSet:
Expand Down
6 changes: 3 additions & 3 deletions hub/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
}

updateUsers(cfg.Users)
updateProxies(cfg.Mitm, cfg.Proxies, cfg.Providers)
updateProxies(cfg.Proxies, cfg.Providers)
updateRules(cfg.Rules, cfg.SubRules, cfg.RuleProviders)
updateSniffer(cfg.Sniffer)
updateHosts(cfg.Hosts)
Expand Down Expand Up @@ -268,7 +268,7 @@ func updateHosts(tree *trie.DomainTrie[resolver.HostValue]) {
resolver.DefaultHosts = resolver.NewHosts(tree)
}

func updateProxies(mitm *config.Mitm, proxies map[string]C.Proxy, providers map[string]provider.ProxyProvider) {
func updateProxies(proxies map[string]C.Proxy, providers map[string]provider.ProxyProvider) {
tunnel.UpdateProxies(proxies, providers)
}

Expand Down Expand Up @@ -523,7 +523,7 @@ func updateIPTables(cfg *config.Config) {

func updateMitm(mitm *config.Mitm) {
listener.ReCreateMitm(mitm.Port, tunnel.Tunnel)
tunnel.UpdateRewrites(mitm.Rules)
tunnel.UpdateRewrites(mitm.Hosts, mitm.Rules)
}

func Shutdown() {
Expand Down
12 changes: 6 additions & 6 deletions listener/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/metacubex/mihomo/listener/autoredir"
LC "github.com/metacubex/mihomo/listener/config"
"github.com/metacubex/mihomo/listener/http"
"github.com/metacubex/mihomo/listener/mitm"
LM "github.com/metacubex/mihomo/listener/mitm"
"github.com/metacubex/mihomo/listener/mixed"
"github.com/metacubex/mihomo/listener/redir"
embedSS "github.com/metacubex/mihomo/listener/shadowsocks"
Expand All @@ -33,8 +33,8 @@ import (
"github.com/metacubex/mihomo/listener/tuic"
LT "github.com/metacubex/mihomo/listener/tunnel"
"github.com/metacubex/mihomo/log"
"github.com/metacubex/mihomo/mitm"

rewrites "github.com/metacubex/mihomo/rewrite"
"github.com/samber/lo"
)

Expand All @@ -61,7 +61,7 @@ var (
autoRedirListener *autoredir.Listener
autoRedirProgram *ebpf.TcEBpfProgram
tcProgram *ebpf.TcEBpfProgram
mitmListener *mitm.Listener
mitmListener *LM.Listener

// lock for recreate function
socksMux sync.Mutex
Expand Down Expand Up @@ -817,14 +817,14 @@ func ReCreateMitm(port int, tunnel C.Tunnel) {
certOption.SetValidity(time.Hour * 24 * 365 * 2) // 2 years
certOption.SetOrganization("Clash ManInTheMiddle Proxy Services")

opt := &mitm.Option{
opt := &LM.Option{
Addr: addr,
ApiHost: "mitm.clash",
CertConfig: certOption,
Handler: &rewrites.RewriteHandler{},
Handler: &mitm.RewriteHandler{},
}

mitmListener, err = mitm.New(opt, tunnel)
mitmListener, err = LM.New(opt, tunnel)
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion listener/mitm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func getServerConn(serverConn *N.BufferedConn, srcConn net.Conn, request *http.R

left, right := net.Pipe()

go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), right, additions...))
go tunnel.HandleTCPConn(inbound.NewMitm(dstAddr, srcConn, request.Header.Get("User-Agent"), request.URL.String(), right, additions...))

if request.TLS != nil {
tlsConn := tls.Client(left, &tls.Config{
Expand Down
5 changes: 2 additions & 3 deletions rewrite/base.go → mitm/base.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package rewrites
package mitm

import (
"bytes"
"io"
"io/ioutil"

C "github.com/metacubex/mihomo/constant"
)
Expand All @@ -25,7 +24,7 @@ type ResponseBody struct {
}

func (r *ResponseBody) Body() io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader(r.data))
return io.NopCloser(bytes.NewReader(r.data))
}

func (r *ResponseBody) ContentLength() int64 {
Expand Down
5 changes: 3 additions & 2 deletions rewrite/handler.go → mitm/handler.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package rewrites
package mitm

import (
"bufio"
"bytes"
"errors"
log "github.com/sirupsen/logrus"
"io"
"net/http"
"net/textproto"
"strconv"
"strings"

log "github.com/sirupsen/logrus"

C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/listener/mitm"
"github.com/metacubex/mihomo/tunnel"
Expand Down
5 changes: 3 additions & 2 deletions rewrite/parser.go → mitm/parser.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package rewrites
package mitm

import (
regexp "github.com/dlclark/regexp2"
"strings"

regexp "github.com/dlclark/regexp2"

C "github.com/metacubex/mihomo/constant"
)

Expand Down
8 changes: 6 additions & 2 deletions rewrite/rewrite.go → mitm/rewrite.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package rewrites
package mitm

import (
regexp "github.com/dlclark/regexp2"
"strconv"
"strings"

regexp "github.com/dlclark/regexp2"

C "github.com/metacubex/mihomo/constant"

"github.com/gofrs/uuid"
Expand Down Expand Up @@ -46,6 +47,9 @@ func (r *RewriteRule) RulePayload() string {
}

func (r *RewriteRule) ReplaceURLPayload(matchSub []string) string {
if len(r.RulePayload()) == 0 {
return ""
}
url := r.rulePayload

l := len(matchSub)
Expand Down
2 changes: 1 addition & 1 deletion rewrite/util.go → mitm/util.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package rewrites
package mitm

import (
"strings"
Expand Down
56 changes: 0 additions & 56 deletions rewrite/parser_test.go

This file was deleted.

Loading

0 comments on commit 6a7f472

Please sign in to comment.