mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
ipset: 1. ipset flush; 2. ipset in main config
This commit is contained in:
parent
45a03ff62d
commit
e7dd21289f
@ -38,6 +38,7 @@ TODO:
|
|||||||
- [ ] TUN/TAP device support
|
- [ ] TUN/TAP device support
|
||||||
- [ ] Code refactoring: support proxy registering so it can be pluggable
|
- [ ] Code refactoring: support proxy registering so it can be pluggable
|
||||||
- [ ] Conditional compilation so we can abandon needless proxy type and get a smaller binary size
|
- [ ] Conditional compilation so we can abandon needless proxy type and get a smaller binary size
|
||||||
|
- [ ] IPv6 support
|
||||||
- [ ] SSH tunnel support
|
- [ ] SSH tunnel support
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
2
conf.go
2
conf.go
@ -42,7 +42,7 @@ func confInit() {
|
|||||||
flag.StringVar(&conf.DNS, "dns", "", "dns listen address")
|
flag.StringVar(&conf.DNS, "dns", "", "dns listen address")
|
||||||
flag.StringSliceUniqVar(&conf.DNSServer, "dnsserver", []string{"8.8.8.8:53"}, "remote dns server")
|
flag.StringSliceUniqVar(&conf.DNSServer, "dnsserver", []string{"8.8.8.8:53"}, "remote dns server")
|
||||||
|
|
||||||
flag.StringVar(&conf.IPSet, "ipset", "glider", "ipset name")
|
flag.StringVar(&conf.IPSet, "ipset", "", "ipset name")
|
||||||
|
|
||||||
flag.Usage = usage
|
flag.Usage = usage
|
||||||
err := flag.Parse()
|
err := flag.Parse()
|
||||||
|
102
ipset_linux.go
102
ipset_linux.go
@ -27,6 +27,7 @@ const IPSET_MAXNAMELEN = 32
|
|||||||
|
|
||||||
/* Message types and commands */
|
/* Message types and commands */
|
||||||
const IPSET_CMD_CREATE = 2
|
const IPSET_CMD_CREATE = 2
|
||||||
|
const IPSET_CMD_FLUSH = 4
|
||||||
const IPSET_CMD_ADD = 9
|
const IPSET_CMD_ADD = 9
|
||||||
const IPSET_CMD_DEL = 10
|
const IPSET_CMD_DEL = 10
|
||||||
|
|
||||||
@ -38,7 +39,9 @@ const IPSET_ATTR_REVISION = 4 /* 4: Settype revision */
|
|||||||
const IPSET_ATTR_FAMILY = 5 /* 5: Settype family */
|
const IPSET_ATTR_FAMILY = 5 /* 5: Settype family */
|
||||||
const IPSET_ATTR_DATA = 7 /* 7: Nested attributes */
|
const IPSET_ATTR_DATA = 7 /* 7: Nested attributes */
|
||||||
|
|
||||||
|
/* CADT specific attributes */
|
||||||
const IPSET_ATTR_IP = 1
|
const IPSET_ATTR_IP = 1
|
||||||
|
const IPSET_ATTR_CIDR = 3
|
||||||
|
|
||||||
/* IP specific attributes */
|
/* IP specific attributes */
|
||||||
const IPSET_ATTR_IPADDR_IPV4 = 1
|
const IPSET_ATTR_IPADDR_IPV4 = 1
|
||||||
@ -54,10 +57,11 @@ type IPSetManager struct {
|
|||||||
fd int
|
fd int
|
||||||
lsa syscall.SockaddrNetlink
|
lsa syscall.SockaddrNetlink
|
||||||
|
|
||||||
|
mainSet string
|
||||||
domainSet sync.Map
|
domainSet sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIPSetManager(rules []*RuleConf) (*IPSetManager, error) {
|
func NewIPSetManager(mainSet string, rules []*RuleConf) (*IPSetManager, error) {
|
||||||
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
|
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("%s", err)
|
logf("%s", err)
|
||||||
@ -74,32 +78,37 @@ func NewIPSetManager(rules []*RuleConf) (*IPSetManager, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var domainSet sync.Map
|
m := &IPSetManager{fd: fd, lsa: lsa, mainSet: mainSet}
|
||||||
|
|
||||||
|
CreateSet(fd, lsa, mainSet)
|
||||||
|
|
||||||
for _, r := range rules {
|
for _, r := range rules {
|
||||||
|
|
||||||
if r.IPSet == "" {
|
set := r.IPSet
|
||||||
continue
|
|
||||||
|
if set != "" && set != m.mainSet {
|
||||||
|
CreateSet(fd, lsa, set)
|
||||||
|
} else {
|
||||||
|
set = m.mainSet
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateSet(fd, lsa, r.IPSet)
|
|
||||||
|
|
||||||
for _, domain := range r.Domain {
|
for _, domain := range r.Domain {
|
||||||
domainSet.Store(domain, r.IPSet)
|
m.domainSet.Store(domain, set)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ip := range r.IP {
|
for _, ip := range r.IP {
|
||||||
|
AddToSet(fd, lsa, mainSet, ip)
|
||||||
AddToSet(fd, lsa, r.IPSet, ip)
|
AddToSet(fd, lsa, r.IPSet, ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add all ip in cidr to ipset
|
for _, cidr := range r.CIDR {
|
||||||
// for _, s := range r.CIDR {
|
AddToSet(fd, lsa, mainSet, cidr)
|
||||||
// if _, cidr, err := net.ParseCIDR(s); err == nil {
|
AddToSet(fd, lsa, r.IPSet, cidr)
|
||||||
// rd.cidrMap.Store(cidr, sd)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &IPSetManager{fd: fd, lsa: lsa, domainSet: domainSet}, nil
|
}
|
||||||
|
|
||||||
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddDomainIP used to update ipset according to domainSet rule
|
// AddDomainIP used to update ipset according to domainSet rule
|
||||||
@ -113,8 +122,8 @@ func (m *IPSetManager) AddDomainIP(domain, ip string) error {
|
|||||||
|
|
||||||
// find in domainMap
|
// find in domainMap
|
||||||
if ipset, ok := m.domainSet.Load(domain); ok {
|
if ipset, ok := m.domainSet.Load(domain); ok {
|
||||||
|
AddToSet(m.fd, m.lsa, m.mainSet, ip)
|
||||||
AddToSet(m.fd, m.lsa, ipset.(string), ip)
|
AddToSet(m.fd, m.lsa, ipset.(string), ip)
|
||||||
logf("ipset: domain: %s, ip: %s\n", domain, ip)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,11 +132,16 @@ func (m *IPSetManager) AddDomainIP(domain, ip string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateSet(fd int, lsa syscall.SockaddrNetlink, setName string) {
|
func CreateSet(fd int, lsa syscall.SockaddrNetlink, setName string) {
|
||||||
|
if setName == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if len(setName) > IPSET_MAXNAMELEN {
|
if len(setName) > IPSET_MAXNAMELEN {
|
||||||
log.Fatal("ipset name too long")
|
log.Fatal("ipset name too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
// req := NewNetlinkRequest(1538, syscall.NLM_F_REQUEST)
|
logf("ipset: create %s hash:net", setName)
|
||||||
|
|
||||||
req := NewNetlinkRequest(IPSET_CMD_CREATE|(NFNL_SUBSYS_IPSET<<8), syscall.NLM_F_REQUEST)
|
req := NewNetlinkRequest(IPSET_CMD_CREATE|(NFNL_SUBSYS_IPSET<<8), syscall.NLM_F_REQUEST)
|
||||||
|
|
||||||
// TODO: support AF_INET6
|
// TODO: support AF_INET6
|
||||||
@ -140,7 +154,7 @@ func CreateSet(fd int, lsa syscall.SockaddrNetlink, setName string) {
|
|||||||
attrSiteName := NewRtAttr(IPSET_ATTR_SETNAME, ZeroTerminated(setName))
|
attrSiteName := NewRtAttr(IPSET_ATTR_SETNAME, ZeroTerminated(setName))
|
||||||
req.AddData(attrSiteName)
|
req.AddData(attrSiteName)
|
||||||
|
|
||||||
attrSiteType := NewRtAttr(IPSET_ATTR_TYPENAME, ZeroTerminated("hash:ip"))
|
attrSiteType := NewRtAttr(IPSET_ATTR_TYPENAME, ZeroTerminated("hash:net"))
|
||||||
req.AddData(attrSiteType)
|
req.AddData(attrSiteType)
|
||||||
|
|
||||||
attrRev := NewRtAttr(IPSET_ATTR_REVISION, Uint8Attr(1))
|
attrRev := NewRtAttr(IPSET_ATTR_REVISION, Uint8Attr(1))
|
||||||
@ -157,14 +171,49 @@ func CreateSet(fd int, lsa syscall.SockaddrNetlink, setName string) {
|
|||||||
logf("%s", err)
|
logf("%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlushSet(fd, lsa, setName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FlushSet(fd int, lsa syscall.SockaddrNetlink, setName string) {
|
||||||
|
logf("ipset: flush %s", setName)
|
||||||
|
|
||||||
|
req := NewNetlinkRequest(IPSET_CMD_FLUSH|(NFNL_SUBSYS_IPSET<<8), syscall.NLM_F_REQUEST)
|
||||||
|
|
||||||
|
// TODO: support AF_INET6
|
||||||
|
req.AddData(NewNfGenMsg(syscall.AF_INET, 0, 0))
|
||||||
|
req.AddData(NewRtAttr(IPSET_ATTR_PROTOCOL, Uint8Attr(IPSET_PROTOCOL)))
|
||||||
|
req.AddData(NewRtAttr(IPSET_ATTR_SETNAME, ZeroTerminated(setName)))
|
||||||
|
|
||||||
|
err := syscall.Sendto(fd, req.Serialize(), 0, &lsa)
|
||||||
|
if err != nil {
|
||||||
|
logf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddToSet(fd int, lsa syscall.SockaddrNetlink, setName, entry string) {
|
||||||
|
if setName == "" {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddToSet(fd int, lsa syscall.SockaddrNetlink, setName, ipStr string) {
|
|
||||||
if len(setName) > IPSET_MAXNAMELEN {
|
if len(setName) > IPSET_MAXNAMELEN {
|
||||||
logf("ipset name too long")
|
logf("ipset name too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
ip := net.ParseIP(ipStr).To4()
|
logf("ipset: add %s %s", setName, entry)
|
||||||
|
|
||||||
|
var ip net.IP
|
||||||
|
var cidr *net.IPNet
|
||||||
|
|
||||||
|
ip, cidr, err := net.ParseCIDR(entry)
|
||||||
|
if err != nil {
|
||||||
|
ip = net.ParseIP(entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ip == nil {
|
||||||
|
logf("ipset: parse %s error", entry)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
req := NewNetlinkRequest(IPSET_CMD_ADD|(NFNL_SUBSYS_IPSET<<8), syscall.NLM_F_REQUEST)
|
req := NewNetlinkRequest(IPSET_CMD_ADD|(NFNL_SUBSYS_IPSET<<8), syscall.NLM_F_REQUEST)
|
||||||
|
|
||||||
@ -180,11 +229,20 @@ func AddToSet(fd int, lsa syscall.SockaddrNetlink, setName, ipStr string) {
|
|||||||
|
|
||||||
attrNested := NewRtAttr(IPSET_ATTR_DATA|NLA_F_NESTED, nil)
|
attrNested := NewRtAttr(IPSET_ATTR_DATA|NLA_F_NESTED, nil)
|
||||||
attrIP := NewRtAttrChild(attrNested, IPSET_ATTR_IP|NLA_F_NESTED, nil)
|
attrIP := NewRtAttrChild(attrNested, IPSET_ATTR_IP|NLA_F_NESTED, nil)
|
||||||
NewRtAttrChild(attrIP, IPSET_ATTR_IPADDR_IPV4|NLA_F_NET_BYTEORDER, ip)
|
|
||||||
// NewRtAttrChild(attrNested, 9|NLA_F_NET_BYTEORDER, Uint32Attr(0))
|
// TODO: support ipV6
|
||||||
|
NewRtAttrChild(attrIP, IPSET_ATTR_IPADDR_IPV4|NLA_F_NET_BYTEORDER, ip.To4())
|
||||||
|
|
||||||
|
// for cidr prefix
|
||||||
|
if cidr != nil {
|
||||||
|
cidrPrefix, _ := cidr.Mask.Size()
|
||||||
|
NewRtAttrChild(attrNested, IPSET_ATTR_CIDR, Uint8Attr(uint8(cidrPrefix)))
|
||||||
|
}
|
||||||
|
|
||||||
|
NewRtAttrChild(attrNested, 9|NLA_F_NET_BYTEORDER, Uint32Attr(0))
|
||||||
req.AddData(attrNested)
|
req.AddData(attrNested)
|
||||||
|
|
||||||
err := syscall.Sendto(fd, req.Serialize(), 0, &lsa)
|
err = syscall.Sendto(fd, req.Serialize(), 0, &lsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("%s", err)
|
logf("%s", err)
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import "errors"
|
|||||||
type IPSetManager struct {
|
type IPSetManager struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIPSetManager(rules []*RuleConf) (*IPSetManager, error) {
|
func NewIPSetManager(mainSet string, rules []*RuleConf) (*IPSetManager, error) {
|
||||||
return nil, errors.New("ipset not supported on this os")
|
return nil, errors.New("ipset not supported on this os")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
main.go
4
main.go
@ -43,9 +43,9 @@ func main() {
|
|||||||
go local.ListenAndServe()
|
go local.ListenAndServe()
|
||||||
}
|
}
|
||||||
|
|
||||||
ipsetM, err := NewIPSetManager(conf.rules)
|
ipsetM, err := NewIPSetManager(conf.IPSet, conf.rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("ipset error: %s", err)
|
logf("create ipset manager error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.DNS != "" {
|
if conf.DNS != "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user