feature: MITM

This commit is contained in:
yaling888
2022-04-10 03:59:27 +08:00
committed by Adlyq
parent d6b80acfbc
commit 2092a481b3
37 changed files with 3431 additions and 133 deletions

View File

@ -35,6 +35,7 @@ import (
L "github.com/Dreamacro/clash/listener"
LC "github.com/Dreamacro/clash/listener/config"
"github.com/Dreamacro/clash/log"
rewrites "github.com/Dreamacro/clash/rewrite"
R "github.com/Dreamacro/clash/rules"
RP "github.com/Dreamacro/clash/rules/provider"
T "github.com/Dreamacro/clash/tunnel"
@ -79,6 +80,7 @@ type Inbound struct {
BindAddress string `json:"bind-address"`
InboundTfo bool `json:"inbound-tfo"`
InboundMPTCP bool `json:"inbound-mptcp"`
MitmPort int `json:"mitm-port"`
}
// Controller config
@ -152,6 +154,12 @@ type Sniffer struct {
ParsePureIp bool
}
// Mitm config
type Mitm struct {
Port int `yaml:"port" json:"port"`
Rules C.RewriteRule `yaml:"rules" json:"rules"`
}
// Experimental config
type Experimental struct {
Fingerprints []string `yaml:"fingerprints"`
@ -161,6 +169,7 @@ type Experimental struct {
type Config struct {
General *General
IPTables *IPTables
Mitm *Mitm
NTP *NTP
DNS *DNS
Experimental *Experimental
@ -253,12 +262,18 @@ type RawTuicServer struct {
CWND int `yaml:"cwnd" json:"cwnd,omitempty"`
}
type RawMitm struct {
Port int `yaml:"port" json:"port"`
Rules []string `yaml:"rules" json:"rules"`
}
type RawConfig struct {
Port int `yaml:"port"`
SocksPort int `yaml:"socks-port"`
RedirPort int `yaml:"redir-port"`
TProxyPort int `yaml:"tproxy-port"`
MixedPort int `yaml:"mixed-port"`
MitmPort int `yaml:"mitm-port"`
ShadowSocksConfig string `yaml:"ss-config"`
VmessConfig string `yaml:"vmess-config"`
InboundTfo bool `yaml:"inbound-tfo"`
@ -294,6 +309,7 @@ type RawConfig struct {
TuicServer RawTuicServer `yaml:"tuic-server"`
EBpf EBpf `yaml:"ebpf"`
IPTables IPTables `yaml:"iptables"`
MITM RawMitm `yaml:"mitm"`
Experimental Experimental `yaml:"experimental"`
Profile Profile `yaml:"profile"`
GeoXUrl GeoXUrl `yaml:"geox-url"`
@ -438,6 +454,10 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
ParsePureIp: true,
OverrideDest: true,
},
MITM: RawMitm{
Port: 0,
Rules: []string{},
},
Profile: Profile{
StoreSelected: true,
},
@ -532,6 +552,12 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
return nil, err
}
mitm, err := parseMitm(rawCfg.MITM)
if err != nil {
return nil, err
}
config.Mitm = mitm
config.Users = parseAuthentication(rawCfg.Authentication)
config.Tunnels = rawCfg.Tunnels
@ -582,6 +608,7 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
RedirPort: cfg.RedirPort,
TProxyPort: cfg.TProxyPort,
MixedPort: cfg.MixedPort,
MitmPort: cfg.MitmPort,
ShadowSocksConfig: cfg.ShadowSocksConfig,
VmessConfig: cfg.VmessConfig,
AllowLan: cfg.AllowLan,
@ -629,6 +656,11 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[
proxies["PASS"] = adapter.NewProxy(outbound.NewPass())
proxyList = append(proxyList, "DIRECT", "REJECT")
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")
}
// parse proxy
for idx, mapping := range proxiesConfig {
proxy, err := adapter.ParseProxy(mapping)
@ -909,6 +941,14 @@ func parseHosts(cfg *RawConfig) (*trie.DomainTrie[resolver.HostValue], error) {
_ = tree.Insert(domain, value)
}
}
if cfg.MITM.Port != 0 {
value, _ := resolver.NewHostValue("8.8.9.9")
if err := tree.Insert("mitm.clash", value); err != nil {
log.Errorln("insert mitm.clash to host error: %s", err.Error())
}
}
tree.Optimize()
return tree, nil
@ -1457,3 +1497,28 @@ func parseSniffer(snifferRaw RawSniffer) (*Sniffer, error) {
return sniffer, nil
}
func parseMitm(rawMitm RawMitm) (*Mitm, error) {
var (
req []C.Rewrite
res []C.Rewrite
)
for _, line := range rawMitm.Rules {
rule, err := rewrites.ParseRewrite(line)
if err != nil {
return nil, fmt.Errorf("parse rewrite rule failure: %w", err)
}
if rule.RuleType() == C.MitmResponseHeader || rule.RuleType() == C.MitmResponseBody {
res = append(res, rule)
} else {
req = append(req, rule)
}
}
return &Mitm{
Port: rawMitm.Port,
Rules: rewrites.NewRewriteRules(req, res),
}, nil
}