ipset: only allow to set ipset in rule files #69

This commit is contained in:
nadoo 2018-11-27 23:25:20 +08:00
parent 86478d2c25
commit 5a43cf873e
14 changed files with 59 additions and 71 deletions

View File

@ -26,6 +26,8 @@ Listen (local proxy server):
- TCP tunnel
- UDP tunnel
- UDP over TCP tunnel
- TLS, use it together with above proxy protocols(tcp)
- Unix domain socket, use it together with above proxy protocols(tcp)
Forward (local proxy client/upstream proxy server):
@ -36,6 +38,7 @@ Forward (local proxy client/upstream proxy server):
- VMess proxy(tcp)
- TLS, use it together with above proxy protocols(tcp)
- Websocket, use it together with above proxy protocols(tcp)
- Unix domain socket, use it together with above proxy protocols(tcp)
DNS Forwarding Server (udp2tcp):
@ -135,8 +138,6 @@ glider v0.6.9 usage:
forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]
-interface string
source ip or source interface
-ipset string
ipset name
-listen value
listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS
-maxfailures int
@ -262,7 +263,7 @@ Examples:
glider -listen socks5://:1080 -verbose
-listen on :1080 as a socks5 proxy server, in verbose mode.
glider -listen =tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose
glider -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose
-listen on :443 as a https proxy server.
glider -listen http://:8080 -forward socks5://127.0.0.1:1080

View File

@ -29,8 +29,6 @@ var conf struct {
DNS string
DNSConfig dns.Config
IPSet string
rules []*rule.Config
}
@ -57,8 +55,6 @@ func confInit() {
flag.IntVar(&conf.DNSConfig.MinTTL, "dnsminttl", 0, "minimum TTL value for entries in the CACHE(seconds)")
flag.StringSliceUniqVar(&conf.DNSConfig.Records, "dnsrecord", nil, "custom dns record, format: domain/ip")
flag.StringVar(&conf.IPSet, "ipset", "", "ipset name")
flag.Usage = usage
err := flag.Parse()
if err != nil {
@ -240,7 +236,7 @@ func usage() {
fmt.Fprintf(os.Stderr, " "+app+" -listen socks5://:1080 -verbose\n")
fmt.Fprintf(os.Stderr, " -listen on :1080 as a socks5 proxy server, in verbose mode.\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen =tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose\n")
fmt.Fprintf(os.Stderr, " -listen on :443 as a https proxy server.\n")
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n")

View File

@ -9,8 +9,5 @@ listen=redir://:1081
dns=:53
dnsserver=8.8.8.8:53
# as a ipset manager
ipset=glider
# parse all *.rule files in rules.d folder
rules-dir=rules.d

View File

@ -13,6 +13,8 @@ strategy=rr
checkwebsite=www.apple.com
checkduration=30
# as a ipset manager
ipset=glider
# matches 192.168.0.0/16
cidr=192.168.0.0/16

View File

@ -15,6 +15,9 @@ checkduration=30
# specify a different dns server(if need)
dnsserver=208.67.222.222:53
# as a ipset manager
ipset=glider
# specify destinations
include=office.list

View File

@ -107,6 +107,9 @@ listen=socks5://:1080
# forward=tls://1.1.1.1:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
# forward=tls://1.1.1.1:443,ws://@/path,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
# socks5 over unix domain socket
# forward=unix:///tmp/glider.socket,socks5://
# FORWARDER CHAIN
# ---------------
# We can setup a forward chain using 1 forward option,
@ -167,15 +170,6 @@ dnsminttl=0
dnsrecord=www.example.com/1.2.3.4
dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946
# IPSET MANAGEMENT
# ----------------
# Create and mange ipset on linux based on destinations in rule files
# - add ip/cidrs in rule files on startup
# - add resolved ips for domains in rule files by dns forwarding server
# Usually used in transparent proxy mode on linux
ipset=glider
# INTERFACE SPECIFIC
# ------------------
# Specify the outbound ip/interface.

View File

@ -20,9 +20,13 @@ checkduration=30
# DNS SERVER for domains in this rule file
dnsserver=208.67.222.222:53
# IPSET
# specify a ipset for destinations in this rule file
#ipset=office
# IPSET MANAGEMENT
# ----------------
# Create and mange ipset on linux based on destinations in rule files
# - add ip/cidrs in rule files on startup
# - add resolved ips for domains in rule files by dns forwarding server
# Usually used in transparent proxy mode on linux
ipset=glider
# DESTINATIONS
# ------------

View File

@ -91,17 +91,17 @@ func (s *Server) ListenAndServeTCP(wg *sync.WaitGroup) {
l, err := net.Listen("tcp", s.addr)
wg.Done()
if err != nil {
log.F("[dns]-tcp error: %v", err)
log.F("[dns-tcp] error: %v", err)
return
}
defer l.Close()
log.F("[dns]-tcp listening TCP on %s", s.addr)
log.F("[dns-tcp] listening TCP on %s", s.addr)
for {
c, err := l.Accept()
if err != nil {
log.F("[dns]-tcp error: failed to accept: %v", err)
log.F("[dns-tcp] error: failed to accept: %v", err)
continue
}
go s.ServeTCP(c)
@ -116,14 +116,14 @@ func (s *Server) ServeTCP(c net.Conn) {
var reqLen uint16
if err := binary.Read(c, binary.BigEndian, &reqLen); err != nil {
log.F("[dns]-tcp failed to get request length: %v", err)
log.F("[dns-tcp] failed to get request length: %v", err)
return
}
reqBytes := make([]byte, reqLen+2)
_, err := io.ReadFull(c, reqBytes[2:])
if err != nil {
log.F("[dns]-tcp error in read reqBytes %s", err)
log.F("[dns-tcp] error in read reqBytes %s", err)
return
}
@ -131,12 +131,12 @@ func (s *Server) ServeTCP(c net.Conn) {
respBytes, err := s.Exchange(reqBytes, c.RemoteAddr().String(), true)
if err != nil {
log.F("[dns]-tcp error in exchange: %s", err)
log.F("[dns-tcp] error in exchange: %s", err)
return
}
if err := binary.Write(c, binary.BigEndian, respBytes); err != nil {
log.F("[dns]-tcp error in local write respBytes: %s", err)
log.F("[dns-tcp] error in local write respBytes: %s", err)
return
}
}

View File

@ -73,12 +73,11 @@ type Manager struct {
fd int
lsa syscall.SockaddrNetlink
mainSet string
domainSet sync.Map
}
// NewManager returns a Manager
func NewManager(mainSet string, rules []*rule.Config) (*Manager, error) {
func NewManager(rules []*rule.Config) (*Manager, error) {
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER)
if err != nil {
log.F("%s", err)
@ -95,37 +94,28 @@ func NewManager(mainSet string, rules []*rule.Config) (*Manager, error) {
return nil, err
}
m := &Manager{fd: fd, lsa: lsa, mainSet: mainSet}
CreateSet(fd, lsa, mainSet)
m := &Manager{fd: fd, lsa: lsa}
// create ipset
for _, r := range rules {
set := r.IPSet
if set != "" && set != m.mainSet {
CreateSet(fd, lsa, set)
} else {
set = m.mainSet
if r.IPSet != "" {
CreateSet(fd, lsa, r.IPSet)
}
}
// if dialer is Direct, do not insert to ipset, in order to avoid iptables redirect loop
if len(r.Forward) == 0 {
continue
// init ipset
for _, r := range rules {
if r.IPSet != "" {
for _, domain := range r.Domain {
m.domainSet.Store(domain, r.IPSet)
}
for _, ip := range r.IP {
AddToSet(fd, lsa, r.IPSet, ip)
}
for _, cidr := range r.CIDR {
AddToSet(fd, lsa, r.IPSet, cidr)
}
}
for _, domain := range r.Domain {
m.domainSet.Store(domain, set)
}
for _, ip := range r.IP {
AddToSet(fd, lsa, mainSet, ip)
AddToSet(fd, lsa, r.IPSet, ip)
}
for _, cidr := range r.CIDR {
AddToSet(fd, lsa, mainSet, cidr)
AddToSet(fd, lsa, r.IPSet, cidr)
}
}
return m, nil
@ -141,14 +131,11 @@ func (m *Manager) AddDomainIP(domain, ip string) error {
// find in domainMap
if ipset, ok := m.domainSet.Load(domain); ok {
AddToSet(m.fd, m.lsa, m.mainSet, ip)
if ipset.(string) != m.mainSet {
AddToSet(m.fd, m.lsa, ipset.(string), ip)
}
AddToSet(m.fd, m.lsa, ipset.(string), ip)
}
}
}
return nil
}

View File

@ -12,7 +12,7 @@ import (
type Manager struct{}
// NewManager returns a Manager
func NewManager(mainSet string, rules []*rule.Config) (*Manager, error) {
func NewManager(rules []*rule.Config) (*Manager, error) {
return nil, errors.New("ipset not supported on this os")
}

View File

@ -44,7 +44,7 @@ func main() {
dialer := rule.NewDialer(conf.rules, strategy.NewDialer(conf.Forward, &conf.StrategyConfig))
// ipset manager
ipsetM, _ := ipset.NewManager(conf.IPSet, conf.rules)
ipsetM, _ := ipset.NewManager(conf.rules)
// check and setup dns server
if conf.DNS != "" {

View File

@ -232,7 +232,7 @@ func (s *SOCKS5) Dial(network, addr string) (net.Conn, error) {
c, err := s.dialer.Dial(network, s.addr)
if err != nil {
log.F("dial to %s error: %s", s.addr, err)
log.F("[socks5]: dial to %s error: %s", s.addr, err)
return nil, err
}

View File

@ -33,7 +33,7 @@ func init() {
proxy.RegisterServer("tls", NewTLSServer)
}
// NewTLS returns a tls proxy
// NewTLS returns a tls proxy struct
func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
u, err := url.Parse(s)
if err != nil {
@ -69,7 +69,7 @@ func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
return p, nil
}
// NewTLSDialer returns a tls proxy dialer.
// NewTLSDialer returns a tls proxy dialer
func NewTLSDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
p, err := NewTLS(s, dialer)
if err != nil {
@ -104,7 +104,7 @@ func NewTLSServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
cert, err := stdtls.LoadX509KeyPair(p.certFile, p.keyFile)
if err != nil {
log.F("[tls] unabled load cert: %s, key %s", p.certFile, p.keyFile)
log.F("[tls] unable to load cert: %s, key %s", p.certFile, p.keyFile)
return nil, err
}
@ -144,8 +144,11 @@ func (s *TLS) ListenAndServe() {
}
}
// Serve .
// Serve serves requests
func (s *TLS) Serve(c net.Conn) {
// we know the internal server will close the connection after serve
// defer c.Close()
if s.server != nil {
cc := stdtls.Server(c, s.tlsConfig)
s.server.Serve(cc)

View File

@ -93,7 +93,8 @@ func (s *Unix) ListenAndServe() {
// Serve serves requests
func (s *Unix) Serve(c net.Conn) {
defer c.Close()
// we know the internal server will close the connection after serve
// defer c.Close()
if s.server != nil {
s.server.Serve(c)