Feature: process condition for rules
This commit is contained in:
parent
d876d6e74c
commit
2f234cf6bc
6 changed files with 55 additions and 12 deletions
|
@ -82,16 +82,19 @@ tun:
|
||||||
### Rules configuration
|
### Rules configuration
|
||||||
- Support rule `GEOSITE`.
|
- Support rule `GEOSITE`.
|
||||||
- Support `multiport` condition for rule `SRC-PORT` and `DST-PORT`.
|
- Support `multiport` condition for rule `SRC-PORT` and `DST-PORT`.
|
||||||
- Support not match condition for rule `GEOIP`.
|
|
||||||
- Support `network` condition for all rules.
|
- Support `network` condition for all rules.
|
||||||
|
- Support `process` condition for all rules.
|
||||||
- Support source IPCIDR condition for all rules, just append to the end.
|
- Support source IPCIDR condition for all rules, just append to the end.
|
||||||
|
|
||||||
The `GEOSITE` databases via https://github.com/Loyalsoldier/v2ray-rules-dat.
|
The `GEOSITE` databases via https://github.com/Loyalsoldier/v2ray-rules-dat.
|
||||||
```yaml
|
```yaml
|
||||||
rules:
|
rules:
|
||||||
# network condition for all rules
|
# network condition for all rules
|
||||||
- DOMAIN-SUFFIX,bilibili.com,DIRECT,tcp
|
- DOMAIN-SUFFIX,example.com,DIRECT,tcp
|
||||||
- DOMAIN-SUFFIX,bilibili.com,REJECT,udp
|
- DOMAIN-SUFFIX,example.com,REJECT,udp
|
||||||
|
|
||||||
|
# process(add 'P:' prefix) condition for all rules
|
||||||
|
- DOMAIN-SUFFIX,example.com,REJECT,P:Google Chrome Helper
|
||||||
|
|
||||||
# multiport condition for rules SRC-PORT and DST-PORT
|
# multiport condition for rules SRC-PORT and DST-PORT
|
||||||
- DST-PORT,123/136/137-139,DIRECT,udp
|
- DST-PORT,123/136/137-139,DIRECT,udp
|
||||||
|
|
|
@ -2,6 +2,7 @@ package constant
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/Dreamacro/clash/component/geodata/router"
|
"github.com/Dreamacro/clash/component/geodata/router"
|
||||||
)
|
)
|
||||||
|
@ -11,6 +12,7 @@ var TunBroadcastAddr = net.IPv4(198, 18, 255, 255)
|
||||||
type RuleExtra struct {
|
type RuleExtra struct {
|
||||||
Network NetWork
|
Network NetWork
|
||||||
SourceIPs []*net.IPNet
|
SourceIPs []*net.IPNet
|
||||||
|
ProcessNames []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (re *RuleExtra) NotMatchNetwork(network NetWork) bool {
|
func (re *RuleExtra) NotMatchNetwork(network NetWork) bool {
|
||||||
|
@ -30,6 +32,19 @@ func (re *RuleExtra) NotMatchSourceIP(srcIP net.IP) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (re *RuleExtra) NotMatchProcessName(processName string) bool {
|
||||||
|
if re.ProcessNames == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pn := range re.ProcessNames {
|
||||||
|
if strings.EqualFold(pn, processName) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
type RuleGeoSite interface {
|
type RuleGeoSite interface {
|
||||||
GetDomainMatcher() *router.DomainMatcher
|
GetDomainMatcher() *router.DomainMatcher
|
||||||
}
|
}
|
||||||
|
|
19
rule/base.go
19
rule/base.go
|
@ -3,6 +3,7 @@ package rules
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
C "github.com/Dreamacro/clash/constant"
|
C "github.com/Dreamacro/clash/constant"
|
||||||
)
|
)
|
||||||
|
@ -24,9 +25,9 @@ func HasNoResolve(params []string) bool {
|
||||||
|
|
||||||
func findNetwork(params []string) C.NetWork {
|
func findNetwork(params []string) C.NetWork {
|
||||||
for _, p := range params {
|
for _, p := range params {
|
||||||
if p == "tcp" {
|
if strings.EqualFold(p, "tcp") {
|
||||||
return C.TCP
|
return C.TCP
|
||||||
} else if p == "udp" {
|
} else if strings.EqualFold(p, "udp") {
|
||||||
return C.UDP
|
return C.UDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,3 +52,17 @@ func findSourceIPs(params []string) []*net.IPNet {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findProcessName(params []string) []string {
|
||||||
|
var processNames []string
|
||||||
|
for _, p := range params {
|
||||||
|
if strings.HasPrefix(p, "P:") {
|
||||||
|
processNames = append(processNames, strings.TrimPrefix(p, "P:"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(processNames) > 0 {
|
||||||
|
return processNames
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -24,9 +24,14 @@ func (g *GEOIP) Match(metadata *C.Metadata) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.EqualFold(g.country, "LAN") || C.TunBroadcastAddr.Equal(ip) {
|
if strings.EqualFold(g.country, "LAN") {
|
||||||
return ip.IsPrivate()
|
return ip.IsPrivate() ||
|
||||||
|
ip.IsUnspecified() ||
|
||||||
|
ip.IsLoopback() ||
|
||||||
|
ip.IsMulticast() ||
|
||||||
|
C.TunBroadcastAddr.Equal(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
record, _ := mmdb.Instance().Country(ip)
|
record, _ := mmdb.Instance().Country(ip)
|
||||||
return strings.EqualFold(record.Country.IsoCode, g.country)
|
return strings.EqualFold(record.Country.IsoCode, g.country)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ func ParseRule(tp, payload, target string, params []string) (C.Rule, error) {
|
||||||
ruleExtra := &C.RuleExtra{
|
ruleExtra := &C.RuleExtra{
|
||||||
Network: findNetwork(params),
|
Network: findNetwork(params),
|
||||||
SourceIPs: findSourceIPs(params),
|
SourceIPs: findSourceIPs(params),
|
||||||
|
ProcessNames: findProcessName(params),
|
||||||
}
|
}
|
||||||
|
|
||||||
switch tp {
|
switch tp {
|
||||||
|
|
|
@ -353,6 +353,10 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
||||||
if extra.NotMatchSourceIP(metadata.SrcIP) {
|
if extra.NotMatchSourceIP(metadata.SrcIP) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if extra.NotMatchProcessName(metadata.Process) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return adapter, rule, nil
|
return adapter, rule, nil
|
||||||
|
|
Loading…
Reference in a new issue