From 3d8c976bd054d3fd3b4edb65728918b6a007f9c6 Mon Sep 17 00:00:00 2001 From: nadoo <287492+nadoo@users.noreply.github.com> Date: Sun, 30 Jul 2017 10:35:11 +0800 Subject: [PATCH] 1. add CIDR rule support; 2. update some docs; 3. optimize rule.go codes. --- README.md | 41 +++++++++++++++++++++++++++++++++++++---- main.go | 3 +++ rule.go | 28 +++------------------------- rules.go | 31 +++++++++++++++++++------------ 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 919b5b6..d06692f 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,10 @@ Forward(upstream proxy): - SS proxy General: +- Http and socks5 on the same port - Forward chain - HA or RR strategy for multiple forwarders -- Http and socks5 on the same port +- Destination rule proxy support - Periodical proxy checking ## Install @@ -60,17 +61,19 @@ glider -config CONFIGPATH -listen :8080 -verbose ## Usage ```bash -glider v0.2 usage: +glider v0.3 usage: -checkduration int proxy check duration(seconds) (default 30) - -checkhost string - proxy check address (default "www.apple.com:443") + -checkwebsite string + proxy check WEBSITE address (default "www.apple.com:443") -config string config file path -forward value forward url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT[,SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT] -listen value listen url, format: SCHEMA://[USER|METHOD:PASSWORD@][HOST]:PORT + -rulefile value + rule file path -strategy string forward strategy, default: rr (default "rr") -verbose @@ -107,6 +110,9 @@ Examples: glider -config glider.conf -run glider with specified config file. + glider -config glider.conf -rulefile office.rule -rulefile home.rule + -run glider with specified global config file and rule config files. + glider -listen :8443 -listen on :8443, serve as http/socks5 proxy on the same port. @@ -170,9 +176,36 @@ checkhost=www.apple.com:443 # check duration checkduration=30 + +# RULE FILES +rulefile=office.rule +rulefile=home.rule ``` See [glider.conf.example](glider.conf.example) +## Rule File +Rule file, **same as the config file but specify forwarders based on destinations**: +```bash +# YOU CAN USE ALL KEYS IN THE GLOBAL CONFIG FILE EXCEPT "listen", "rulefile" +forward=socks5://192.168.1.10:1080 +forward=ss://method:pass@1.1.1.1:443 +forward=http://192.168.2.1:8080,socks5://192.168.2.2:1080 +strategy=rr +checkwebsite=www.apple.com:443 +checkduration=30 + +# YOU CAN SPECIFY DESTINATIONS TO USE THE ABOVE FORWARDERS +# matches abc.com and *.abc.com +domain=abc.com + +# matches 1.1.1.1 +ip=1.1.1.1 + +# matches 192.168.100.0/24 +cidr=192.168.100.0/24 +``` +See [office.rule.example](office.rule.example) + ## Service - systemd: [https://github.com/nadoo/glider/blob/master/systemd/](https://github.com/nadoo/glider/blob/master/systemd/) diff --git a/main.go b/main.go index 60cf25b..d94002f 100644 --- a/main.go +++ b/main.go @@ -76,6 +76,9 @@ func usage() { fmt.Fprintf(os.Stderr, " "+app+" -config glider.conf\n") fmt.Fprintf(os.Stderr, " -run glider with specified config file.\n") fmt.Fprintf(os.Stderr, "\n") + fmt.Fprintf(os.Stderr, " "+app+" -config glider.conf -rulefile office.rule -rulefile home.rule\n") + fmt.Fprintf(os.Stderr, " -run glider with specified global config file and rule config files.\n") + fmt.Fprintf(os.Stderr, "\n") fmt.Fprintf(os.Stderr, " "+app+" -listen :8443\n") fmt.Fprintf(os.Stderr, " -listen on :8443, serve as http/socks5 proxy on the same port.\n") fmt.Fprintf(os.Stderr, "\n") diff --git a/rule.go b/rule.go index c67a6a8..a71cfab 100644 --- a/rule.go +++ b/rule.go @@ -3,7 +3,6 @@ package main import ( "fmt" "log" - "net" "os" "strings" @@ -21,8 +20,8 @@ type ruleForwarder struct { IP arrFlags CIDR arrFlags - name string - sForwarder Proxy + name string + Proxy } // newRuleProxyFromFile . @@ -64,28 +63,7 @@ func newRuleProxyFromFile(ruleFile string) (*ruleForwarder, error) { go check(forward, p.CheckWebSite, p.CheckDuration) } - p.sForwarder = forwarder + p.Proxy = forwarder return p, err } - -func (p *ruleForwarder) Addr() string { return "rule forwarder" } -func (p *ruleForwarder) ListenAndServe() {} -func (p *ruleForwarder) Serve(c net.Conn) {} -func (p *ruleForwarder) CurrentProxy() Proxy { return p.sForwarder.CurrentProxy() } - -func (p *ruleForwarder) GetProxy(dstAddr string) Proxy { - - return p.sForwarder.NextProxy() -} - -func (p *ruleForwarder) NextProxy() Proxy { - return p.sForwarder.NextProxy() -} - -func (p *ruleForwarder) Enabled() bool { return true } -func (p *ruleForwarder) SetEnable(enable bool) {} - -func (p *ruleForwarder) Dial(network, addr string) (net.Conn, error) { - return p.NextProxy().Dial(network, addr) -} diff --git a/rules.go b/rules.go index a860bf3..a2679be 100644 --- a/rules.go +++ b/rules.go @@ -20,17 +20,17 @@ func newRulesForwarder(ruleForwarders []*ruleForwarder, globalForwarder Proxy) P for _, f := range ruleForwarders { p.domainMap = make(map[string]Proxy) for _, domain := range f.Domain { - p.domainMap[domain] = f.sForwarder + p.domainMap[domain] = f.Proxy } p.ipMap = make(map[string]Proxy) for _, ip := range f.IP { - p.ipMap[ip] = f.sForwarder + p.ipMap[ip] = f.Proxy } p.cidrMap = make(map[string]Proxy) for _, cidr := range f.CIDR { - p.cidrMap[cidr] = f.sForwarder + p.cidrMap[cidr] = f.Proxy } } @@ -44,22 +44,29 @@ func (p *rulesForwarder) CurrentProxy() Proxy { return p.globalForwarder.Current func (p *rulesForwarder) GetProxy(dstAddr string) Proxy { - logf("dstAddr: %s", dstAddr) - + // TODO: change to index finders host, _, err := net.SplitHostPort(dstAddr) if err != nil { // TODO: check here - logf("%s", err) + logf("SplitHostPort ERROR: %s", err) return p.globalForwarder.GetProxy(dstAddr) } // find ip if ip := net.ParseIP(host); ip != nil { - // check cidr - // check ip - if p, ok := p.ipMap[ip.String()]; ok { - return p + if proxy, ok := p.ipMap[ip.String()]; ok { + return proxy + } + + // check cidr + // TODO: do not parse cidr every time + for cidrStr, proxy := range p.cidrMap { + if _, net, err := net.ParseCIDR(cidrStr); err == nil { + if net.Contains(ip) { + return proxy + } + } } } @@ -69,8 +76,8 @@ func (p *rulesForwarder) GetProxy(dstAddr string) Proxy { domain := strings.Join(domainParts[i:length], ".") // find in domainMap - if p, ok := p.domainMap[domain]; ok { - return p + if proxy, ok := p.domainMap[domain]; ok { + return proxy } }