mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 07:42:38 +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 AddToSet(fd int, lsa syscall.SockaddrNetlink, setName, ipStr string) {
 | 
					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
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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