glider/config.go

253 lines
8.9 KiB
Go
Raw Normal View History

package main
import (
"fmt"
"os"
"path"
"github.com/nadoo/conflag"
2018-08-11 11:46:10 +08:00
"github.com/nadoo/glider/dns"
"github.com/nadoo/glider/pkg/log"
"github.com/nadoo/glider/proxy"
2018-08-12 22:24:49 +08:00
"github.com/nadoo/glider/rule"
)
var flag = conflag.New()
2020-10-03 20:51:27 +08:00
// Config is global config struct.
type Config struct {
Verbose bool
LogFlags int
TCPBufSize int
UDPBufSize int
2020-09-27 19:50:21 +08:00
Listens []string
Forwards []string
Strategy rule.Strategy
2020-09-27 19:50:21 +08:00
RuleFiles []string
RulesDir string
DNS string
DNSConfig dns.Config
2018-08-12 22:24:49 +08:00
rules []*rule.Config
2020-09-27 19:50:21 +08:00
Services []string
}
func parseConfig() *Config {
conf := &Config{}
2019-10-21 21:03:19 +08:00
flag.SetOutput(os.Stdout)
scheme := flag.String("scheme", "", "show help message of proxy scheme, use 'all' to see all schemes")
example := flag.Bool("example", false, "show usage examples")
2022-02-15 21:34:55 +08:00
flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode")
2022-02-15 21:34:55 +08:00
flag.IntVar(&conf.LogFlags, "logflags", 19, "do not change it if you do not know what it is, ref: https://pkg.go.dev/log#pkg-constants")
flag.IntVar(&conf.TCPBufSize, "tcpbufsize", 32768, "tcp buffer size in Bytes")
flag.IntVar(&conf.UDPBufSize, "udpbufsize", 2048, "udp buffer size in Bytes")
2022-02-15 21:34:55 +08:00
flag.StringSliceUniqVar(&conf.Listens, "listen", nil, "listen url, see the URL section below")
flag.StringSliceVar(&conf.Forwards, "forward", nil, "forward url, see the URL section below")
flag.StringVar(&conf.Strategy.Strategy, "strategy", "rr", `rr: Round Robin mode
ha: High Availability mode
lha: Latency based High Availability mode
dh: Destination Hashing mode`)
flag.StringVar(&conf.Strategy.Check, "check", "http://www.msftconnecttest.com/connecttest.txt#expect=200",
`check=tcp[://HOST:PORT]: tcp port connect check
check=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
check=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]
check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, env vars: FORWARDER_ADDR,FORWARDER_URL
check=disable: disable health check`)
flag.IntVar(&conf.Strategy.CheckInterval, "checkinterval", 30, "fowarder check interval(seconds)")
flag.IntVar(&conf.Strategy.CheckTimeout, "checktimeout", 10, "fowarder check timeout(seconds)")
flag.IntVar(&conf.Strategy.CheckTolerance, "checktolerance", 0, "fowarder check tolerance(ms), switch only when new_latency < old_latency - tolerance, only used in lha mode")
flag.IntVar(&conf.Strategy.CheckLatencySamples, "checklatencysamples", 10, "use the average latency of the latest N checks")
flag.BoolVar(&conf.Strategy.CheckDisabledOnly, "checkdisabledonly", false, "check disabled fowarders only")
flag.IntVar(&conf.Strategy.MaxFailures, "maxfailures", 3, "max failures to change forwarder status to disabled")
flag.IntVar(&conf.Strategy.DialTimeout, "dialtimeout", 3, "dial timeout(seconds)")
flag.IntVar(&conf.Strategy.RelayTimeout, "relaytimeout", 0, "relay timeout(seconds)")
flag.StringVar(&conf.Strategy.IntFace, "interface", "", "source ip or source interface")
2020-09-27 19:50:21 +08:00
flag.StringSliceUniqVar(&conf.RuleFiles, "rulefile", nil, "rule file path")
2017-09-04 23:32:12 +08:00
flag.StringVar(&conf.RulesDir, "rules-dir", "", "rule file folder")
2020-10-08 18:48:23 +08:00
// dns configs
2018-11-28 23:28:32 +08:00
flag.StringVar(&conf.DNS, "dns", "", "local dns server listen address")
flag.StringSliceUniqVar(&conf.DNSConfig.Servers, "dnsserver", []string{"8.8.8.8:53"}, "remote dns server address")
2018-08-27 00:01:09 +08:00
flag.BoolVar(&conf.DNSConfig.AlwaysTCP, "dnsalwaystcp", false, "always use tcp to query upstream dns servers no matter there is a forwarder or not")
flag.IntVar(&conf.DNSConfig.Timeout, "dnstimeout", 3, "timeout value used in multiple dnsservers switch(seconds)")
flag.IntVar(&conf.DNSConfig.MaxTTL, "dnsmaxttl", 1800, "maximum TTL value for entries in the CACHE(seconds)")
flag.IntVar(&conf.DNSConfig.MinTTL, "dnsminttl", 0, "minimum TTL value for entries in the CACHE(seconds)")
2022-02-15 21:34:55 +08:00
flag.IntVar(&conf.DNSConfig.CacheSize, "dnscachesize", 4096, "max number of dns response in CACHE")
flag.BoolVar(&conf.DNSConfig.CacheLog, "dnscachelog", false, "show query log of dns cache")
flag.BoolVar(&conf.DNSConfig.NoAAAA, "dnsnoaaaa", false, "disable AAAA query")
flag.StringSliceUniqVar(&conf.DNSConfig.Records, "dnsrecord", nil, "custom dns record, format: domain/ip")
2020-10-08 18:48:23 +08:00
// service configs
2020-10-01 22:38:34 +08:00
flag.StringSliceUniqVar(&conf.Services, "service", nil, "run specified services, format: SERVICE_NAME[,SERVICE_CONFIG]")
2020-09-27 19:50:21 +08:00
flag.Usage = usage
err := flag.Parse()
if err != nil {
2019-03-01 00:59:55 +08:00
// flag.Usage()
fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
os.Exit(-1)
}
2022-02-15 21:34:55 +08:00
if *scheme != "" {
fmt.Fprintf(flag.Output(), proxy.Usage(*scheme))
os.Exit(0)
}
if *example {
fmt.Fprintf(flag.Output(), examples)
2022-02-15 21:34:55 +08:00
os.Exit(0)
}
2022-01-28 23:35:29 +08:00
// setup logger
log.Set(conf.Verbose, conf.LogFlags)
2020-09-27 19:50:21 +08:00
if len(conf.Listens) == 0 && conf.DNS == "" && len(conf.Services) == 0 {
2019-03-01 00:59:55 +08:00
// flag.Usage()
fmt.Fprintf(os.Stderr, "ERROR: listen url must be specified.\n")
os.Exit(-1)
}
// tcpbufsize
if conf.TCPBufSize > 0 {
proxy.TCPBufSize = conf.TCPBufSize
}
// udpbufsize
if conf.UDPBufSize > 0 {
proxy.UDPBufSize = conf.UDPBufSize
}
// rulefiles
2020-09-27 19:50:21 +08:00
for _, ruleFile := range conf.RuleFiles {
if !path.IsAbs(ruleFile) {
ruleFile = path.Join(flag.ConfDir(), ruleFile)
}
2018-08-12 22:24:49 +08:00
rule, err := rule.NewConfFromFile(ruleFile)
if err != nil {
log.Fatal(err)
}
conf.rules = append(conf.rules, rule)
}
2017-09-04 23:32:12 +08:00
if conf.RulesDir != "" {
2018-07-29 23:44:23 +08:00
if !path.IsAbs(conf.RulesDir) {
conf.RulesDir = path.Join(flag.ConfDir(), conf.RulesDir)
}
ruleFolderFiles, _ := rule.ListDir(conf.RulesDir, ".rule")
2017-09-04 23:32:12 +08:00
for _, ruleFile := range ruleFolderFiles {
2018-08-12 22:24:49 +08:00
rule, err := rule.NewConfFromFile(ruleFile)
2017-09-04 23:32:12 +08:00
if err != nil {
log.Fatal(err)
}
conf.rules = append(conf.rules, rule)
}
}
2017-09-04 23:32:12 +08:00
return conf
}
func usage() {
fmt.Fprint(flag.Output(), usage1)
flag.PrintDefaults()
fmt.Fprintf(flag.Output(), usage2, proxy.ServerSchemes(), proxy.DialerSchemes(), version)
}
2019-10-21 21:03:19 +08:00
var usage1 = `
2022-02-15 21:34:55 +08:00
Usage: glider [-listen URL]... [-forward URL]... [OPTION]...
2022-02-16 00:25:14 +08:00
2022-02-15 21:34:55 +08:00
e.g. glider -config /etc/glider/glider.conf
glider -listen :8443 -forward socks5://serverA:1080 -forward socks5://serverB:1080 -verbose
OPTION:
`
2022-02-15 21:34:55 +08:00
var usage2 = `
2022-02-15 21:34:55 +08:00
URL:
proxy: SCHEME://[USER:PASS@][HOST]:PORT
2022-02-16 00:25:14 +08:00
chain: proxy,proxy[,proxy]...
2022-02-15 21:34:55 +08:00
e.g. -listen socks5://:1080
-listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// (protocol chain)
e.g. -forward socks5://server:1080
-forward tls://server.com:443,http:// (protocol chain)
-forward socks5://serverA:1080,socks5://serverB:1080 (proxy chain)
SCHEME:
listen : %s
forward: %s
2022-02-15 21:34:55 +08:00
Note: use 'glider -scheme all' or 'glider -scheme SCHEME' to see help info for the scheme.
2022-02-15 21:34:55 +08:00
--
Forwarder Options: FORWARD_URL#OPTIONS
priority : the priority of that forwarder, the larger the higher, default: 0
interface: the local interface or ip address used to connect remote server.
e.g. -forward socks5://server:1080#priority=100
-forward socks5://server:1080#interface=eth0
-forward socks5://server:1080#priority=100&interface=192.168.1.99
Services:
dhcpd: service=dhcpd,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...]
service=dhcpd-failover,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...]
2022-02-15 21:34:55 +08:00
e.g. service=dhcpd,eth1,192.168.1.100,192.168.1.199,720
--
Help:
glider -help
glider -scheme all
glider -example
2022-02-15 21:34:55 +08:00
see README.md and glider.conf.example for more details.
--
2022-03-06 12:58:20 +08:00
glider %s, https://github.com/nadoo/glider (glider.proxy@gmail.com)
`
var examples = `
Examples:
glider -config glider.conf
-run glider with specified config file.
glider -listen :8443 -verbose
-listen on :8443, serve as http/socks5 proxy on the same port, in verbose mode.
glider -listen socks5://:1080 -listen http://:8080 -verbose
-multiple listeners: listen on :1080 as socks5 proxy server, and on :8080 as http proxy server.
glider -listen :8443 -forward direct://#interface=eth0 -forward direct://#interface=eth1
-multiple forwarders: listen on 8443 and forward requests via interface eth0 and eth1 in round robin mode.
glider -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose
-protocol chain: listen on :443 as a https(http over tls) proxy server.
glider -listen http://:8080 -forward socks5://serverA:1080,socks5://serverB:1080
-proxy chain: listen on :8080 as a http proxy server, forward all requests via forward chain.
glider -listen :8443 -forward socks5://serverA:1080 -forward socks5://serverB:1080#priority=10 -forward socks5://serverC:1080#priority=10
-forwarder priority: serverA will only be used when serverB and serverC are not available.
glider -listen tcp://:80 -forward tcp://serverA:80
-tcp tunnel: listen on :80 and forward all requests to serverA:80.
glider -listen udp://:53 -forward socks5://serverA:1080,udp://8.8.8.8:53
-udp tunnel: listen on :53 and forward all udp requests to 8.8.8.8:53 via remote socks5 server.
glider -verbose -listen -dns=:53 -dnsserver=8.8.8.8:53 -forward socks5://serverA:1080 -dnsrecord=abc.com/1.2.3.4
-dns over proxy: listen on :53 as dns server, forward to 8.8.8.8:53 via socks5 server.
`