1
0

Feature: support IPSET rule (#2693)

This commit is contained in:
major1201 2023-04-22 20:07:47 +08:00 committed by GitHub
parent 765982e86a
commit 6eee226965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 107 additions and 0 deletions

View File

@ -0,0 +1,22 @@
//go:build linux
package ipset
import (
"net"
"github.com/vishvananda/netlink"
)
// Test whether the ip is in the set or not
func Test(setName string, ip net.IP) (bool, error) {
return netlink.IpsetTest(setName, &netlink.IPSetEntry{
IP: ip,
})
}
// Verify dumps a specific ipset to check if we can use the set normally
func Verify(setName string) error {
_, err := netlink.IpsetList(setName)
return err
}

View File

@ -0,0 +1,17 @@
//go:build !linux
package ipset
import (
"net"
)
// Always return false in non-linux
func Test(setName string, ip net.IP) (bool, error) {
return false, nil
}
// Always pass in non-linux
func Verify(setName string) error {
return nil
}

View File

@ -12,6 +12,7 @@ const (
DstPort DstPort
Process Process
ProcessPath ProcessPath
IPSet
MATCH MATCH
) )
@ -39,6 +40,8 @@ func (rt RuleType) String() string {
return "Process" return "Process"
case ProcessPath: case ProcessPath:
return "ProcessPath" return "ProcessPath"
case IPSet:
return "IPSet"
case MATCH: case MATCH:
return "Match" return "Match"
default: default:

2
go.mod
View File

@ -16,6 +16,7 @@ require (
github.com/samber/lo v1.38.1 github.com/samber/lo v1.38.1
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.2 github.com/stretchr/testify v1.8.2
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230420174744-55c8b9515a01
go.etcd.io/bbolt v1.3.7 go.etcd.io/bbolt v1.3.7
go.uber.org/atomic v1.10.0 go.uber.org/atomic v1.10.0
go.uber.org/automaxprocs v1.5.2 go.uber.org/automaxprocs v1.5.2
@ -37,6 +38,7 @@ require (
github.com/pierrec/lz4/v4 v4.1.14 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/mod v0.8.0 // indirect golang.org/x/mod v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect golang.org/x/text v0.9.0 // indirect

6
go.sum
View File

@ -55,6 +55,10 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230420174744-55c8b9515a01 h1:F9xjJm4IH8VjcqG4ujciOF+GIM4mjPkHhWLLzOghPtM=
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230420174744-55c8b9515a01/go.mod h1:cAAsePK2e15YDAMJNyOpGYEWNe4sIghTY7gpz4cX/Ik=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
@ -71,8 +75,10 @@ golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=

54
rule/ipset.go Normal file
View File

@ -0,0 +1,54 @@
package rules
import (
"github.com/Dreamacro/clash/component/ipset"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
)
type IPSet struct {
name string
adapter string
noResolveIP bool
}
func (f *IPSet) RuleType() C.RuleType {
return C.IPSet
}
func (f *IPSet) Match(metadata *C.Metadata) bool {
exist, err := ipset.Test(f.name, metadata.DstIP)
if err != nil {
log.Warnln("check ipset '%s' failed: %s", f.name, err.Error())
return false
}
return exist
}
func (f *IPSet) Adapter() string {
return f.adapter
}
func (f *IPSet) Payload() string {
return f.name
}
func (f *IPSet) ShouldResolveIP() bool {
return !f.noResolveIP
}
func (f *IPSet) ShouldFindProcess() bool {
return false
}
func NewIPSet(name string, adapter string, noResolveIP bool) (*IPSet, error) {
if err := ipset.Verify(name); err != nil {
return nil, err
}
return &IPSet{
name: name,
adapter: adapter,
noResolveIP: noResolveIP,
}, nil
}

View File

@ -35,6 +35,9 @@ func ParseRule(tp, payload, target string, params []string) (C.Rule, error) {
parsed, parseErr = NewProcess(payload, target, true) parsed, parseErr = NewProcess(payload, target, true)
case "PROCESS-PATH": case "PROCESS-PATH":
parsed, parseErr = NewProcess(payload, target, false) parsed, parseErr = NewProcess(payload, target, false)
case "IPSET":
noResolve := HasNoResolve(params)
parsed, parseErr = NewIPSet(payload, target, noResolve)
case "MATCH": case "MATCH":
parsed = NewMatch(target) parsed = NewMatch(target)
default: default: