diff --git a/README.md b/README.md index e0c0b3d..09444a3 100644 --- a/README.md +++ b/README.md @@ -101,12 +101,16 @@ glider -h click to see details ```bash -glider 0.16.0 usage: +Usage: glider [-listen URL]... [-forward URL]... [OPTION]... + e.g. glider -config /etc/glider/glider.conf + glider -listen :8443 -forward socks5://serverA:1080 -forward socks5://serverB:1080 -verbose + +OPTION: -check string 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, environment variables: FORWARDER_ADDR,FORWARDER_URL + check=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, env vars: FORWARDER_ADDR,FORWARDER_URL check=disable: disable health check (default "http://www.msftconnecttest.com/connecttest.txt#expect=200") -checkdisabledonly check disabled fowarders only @@ -127,7 +131,7 @@ glider 0.16.0 usage: -dnscachelog show query log of dns cache -dnscachesize int - size of CACHE (default 4096) + max number of dns response in CACHE (default 4096) -dnsmaxttl int maximum TTL value for entries in the CACHE(seconds) (default 1800) -dnsminttl int @@ -141,15 +145,15 @@ glider 0.16.0 usage: -dnstimeout int timeout value used in multiple dnsservers switch(seconds) (default 3) -forward value - forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS] + forward url, see the URL section below -include value include file -interface string source ip or source interface -listen value - listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS + listen url, see the URL section below -logflags int - log flags, do not change it if you do not know what it is, ref: https://pkg.go.dev/log#pkg-constants (default 19) + do not change it if you do not know what it is, ref: https://pkg.go.dev/log#pkg-constants (default 19) -maxfailures int max failures to change forwarder status to disabled (default 3) -relaytimeout int @@ -158,23 +162,62 @@ glider 0.16.0 usage: rule file path -rules-dir string rule file folder + -scheme string + show help message of proxy scheme, use 'all' to see all -service value run specified services, format: SERVICE_NAME[,SERVICE_CONFIG] -strategy string - forward strategy, default: rr (default "rr") + rr: Round Robin mode + ha: High Availability mode + lha: Latency based High Availability mode + dh: Destination Hashing mode (default "rr") -tcpbufsize int tcp buffer size in Bytes (default 32768) -udpbufsize int udp buffer size in Bytes (default 2048) -verbose verbose mode + +URL: + proxy: SCHEME://[USER:PASS@][HOST]:PORT + chain: proxy,proxy,[proxy]... + + 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 : sni,mixed,tcp,tls,vless,http,ss,trojan,trojanc,wss,ws,kcp,socks5,pxyproto,smux,udp + forward: vmess,wss,simple-obfs,udp,ws,kcp,socks5,ssh,ssr,tls,trojanc,reject,socks4a,smux,socks4,ss,tcp,trojan,vless,direct,http + + Note: use `glider -scheme all` or `glider -scheme SCHEME` to see help info for the scheme. + +-- +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...] + e.g. service=dhcpd,eth1,192.168.1.100,192.168.1.199,720 + +see README.md and glider.conf.example for more details. +-- +glider v0.16.0, https://github.com/nadoo/glider ``` run: ```bash -glider -config CONFIGPATH +glider -config CONFIG_PATH ``` ```bash glider -verbose -listen :8443 -forward SCHEME://HOST:PORT @@ -182,144 +225,118 @@ glider -verbose -listen :8443 -forward SCHEME://HOST:PORT #### Schemes +```bash +glider -scheme all +```
click to see details ```bash -Available schemes: - listen: mixed ss socks5 http vless trojan trojanc redir redir6 tproxy tcp udp tls ws wss unix smux kcp pxyproto - forward: direct reject ss socks4 socks5 http ssr ssh vless vmess trojan trojanc tcp udp tls ws wss unix smux kcp simple-obfs +KCP scheme: + kcp://CRYPT:KEY@host:port[?dataShards=NUM&parityShards=NUM&mode=MODE] + +Available crypt types for KCP: + none, sm4, tea, xor, aes, aes-128, aes-192, blowfish, twofish, cast5, 3des, xtea, salsa20 + +Available modes for KCP: + fast, fast2, fast3, normal, default: fast +-- Socks5 scheme: socks://[user:pass@]host:port +-- +Simple-Obfs scheme: + simple-obfs://host:port[?type=TYPE&host=HOST&uri=URI&ua=UA] + +Available types for simple-obfs: + http, tls + +-- +Smux scheme: + smux://host:port + +-- SS scheme: ss://method:pass@host:port + + Available methods for ss: + AEAD Ciphers: + AEAD_AES_128_GCM AEAD_AES_192_GCM AEAD_AES_256_GCM AEAD_CHACHA20_POLY1305 AEAD_XCHACHA20_POLY1305 + Stream Ciphers: + AES-128-CFB AES-128-CTR AES-192-CFB AES-192-CTR AES-256-CFB AES-256-CTR CHACHA20-IETF XCHACHA20 CHACHA20 RC4-MD5 + Alias: + chacha20-ietf-poly1305 = AEAD_CHACHA20_POLY1305, xchacha20-ietf-poly1305 = AEAD_XCHACHA20_POLY1305 + Plain: NONE -Available methods for ss: - AEAD Ciphers: - AEAD_AES_128_GCM AEAD_AES_192_GCM AEAD_AES_256_GCM AEAD_CHACHA20_POLY1305 AEAD_XCHACHA20_POLY1305 - Stream Ciphers: - AES-128-CFB AES-128-CTR AES-192-CFB AES-192-CTR AES-256-CFB AES-256-CTR CHACHA20-IETF XCHACHA20 CHACHA20 RC4-MD5 - Alias: - chacha20-ietf-poly1305 = AEAD_CHACHA20_POLY1305, xchacha20-ietf-poly1305 = AEAD_XCHACHA20_POLY1305 - Plain: NONE - -SSR scheme: - ssr://method:pass@host:port?protocol=xxx&protocol_param=yyy&obfs=zzz&obfs_param=xyz - +-- SSH scheme: ssh://user[:pass]@host:port[?key=keypath&timeout=SECONDS] timeout: timeout of ssh handshake and channel operation, default: 5 -VMess scheme: - vmess://[security:]uuid@host:port[?alterID=num] - if alterID=0 or not set, VMessAEAD will be enabled - -Available security for vmess: - zero, none, aes-128-gcm, chacha20-poly1305 - -VLESS scheme: - vless://uuid@host:port[?fallback=127.0.0.1:80] - -Trojan client scheme: - trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH] - trojanc://pass@host:port (cleartext, without TLS) - -Trojan server scheme: - trojan://pass@host:port?cert=PATH&key=PATH[&fallback=127.0.0.1] - trojanc://pass@host:port[?fallback=127.0.0.1] (cleartext, without TLS) +-- +SSR scheme: + ssr://method:pass@host:port?protocol=xxx&protocol_param=yyy&obfs=zzz&obfs_param=xyz +-- TLS client scheme: tls://host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH][&alpn=proto1][&alpn=proto2] - + Proxy over tls client: tls://host:port[?skipVerify=true][&serverName=SERVERNAME],scheme:// tls://host:port[?skipVerify=true],http://[user:pass@] tls://host:port[?skipVerify=true],socks5://[user:pass@] tls://host:port[?skipVerify=true],vmess://[security:]uuid@?alterID=num - + TLS server scheme: tls://host:port?cert=PATH&key=PATH[&alpn=proto1][&alpn=proto2] - + Proxy over tls server: tls://host:port?cert=PATH&key=PATH,scheme:// tls://host:port?cert=PATH&key=PATH,http:// tls://host:port?cert=PATH&key=PATH,socks5:// tls://host:port?cert=PATH&key=PATH,ss://method:pass@ +-- +Trojan client scheme: + trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH] + trojanc://pass@host:port (cleartext, without TLS) + +Trojan server scheme: + trojan://pass@host:port?cert=PATH&key=PATH[&fallback=127.0.0.1] + trojanc://pass@host:port[?fallback=127.0.0.1] (cleartext, without TLS) + +-- +VLESS scheme: + vless://uuid@host:port[?fallback=127.0.0.1:80] + +-- +VMess scheme: + vmess://[security:]uuid@host:port[?alterID=num] + if alterID=0 or not set, VMessAEAD will be enabled + + Available security for vmess: + zero, none, aes-128-gcm, chacha20-poly1305 + +-- Websocket client scheme: ws://host:port[/path][?host=HOST][&origin=ORIGIN] wss://host:port[/path][?serverName=SERVERNAME][&skipVerify=true][&cert=PATH][&host=HOST][&origin=ORIGIN] - + Websocket server scheme: ws://:port[/path][?host=HOST] wss://:port[/path]?cert=PATH&key=PATH[?host=HOST] - + Websocket with a specified proxy protocol: ws://host:port[/path][?host=HOST],scheme:// ws://host:port[/path][?host=HOST],http://[user:pass@] ws://host:port[/path][?host=HOST],socks5://[user:pass@] - + TLS and Websocket with a specified proxy protocol: tls://host:port[?skipVerify=true][&serverName=SERVERNAME],ws://[@/path[?host=HOST]],scheme:// tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],http://[user:pass@] tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],socks5://[user:pass@] tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],vmess://[security:]uuid@?alterID=num - -Unix domain socket scheme: - unix://path - -Smux scheme: - smux://host:port - -KCP scheme: - kcp://CRYPT:KEY@host:port[?dataShards=NUM&parityShards=NUM&mode=MODE] - -Available crypt types for KCP: - none, sm4, tea, xor, aes, aes-128, aes-192, blowfish, twofish, cast5, 3des, xtea, salsa20 - -Available modes for KCP: - fast, fast2, fast3, normal, default: fast - -Simple-Obfs scheme: - simple-obfs://host:port[?type=TYPE&host=HOST&uri=URI&ua=UA] - -Available types for simple-obfs: - http, tls - -DNS forwarding server: - dns=:53 - dnsserver=8.8.8.8:53 - dnsserver=1.1.1.1:53 - dnsrecord=www.example.com/1.2.3.4 - dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946 - -Available forward strategies: - rr: Round Robin mode - ha: High Availability mode - lha: Latency based High Availability mode - dh: Destination Hashing mode - -Forwarder option scheme: FORWARD_URL#OPTIONS - priority: set the priority of that forwarder, default:0 - interface: set local interface or ip address used to connect remote server - - - Examples: - socks5://1.1.1.1:1080#priority=100 - vmess://[security:]uuid@host:port?alterID=num#priority=200 - vmess://[security:]uuid@host:port?alterID=num#priority=200&interface=192.168.1.99 - vmess://[security:]uuid@host:port?alterID=num#priority=200&interface=eth0 - -Services: - dhcpd: service=dhcpd,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...] - e.g.,service=dhcpd,eth1,192.168.1.100,192.168.1.199,720 - -Config file format(see `./glider.conf.example` as an example): - # COMMENT LINE - KEY=VALUE - KEY=VALUE - # KEY equals to command line flag name: listen forward strategy... ```
diff --git a/config.go b/config.go index c34ca34..1e7dbee 100644 --- a/config.go +++ b/config.go @@ -43,15 +43,25 @@ func parseConfig() *Config { flag.SetOutput(os.Stdout) + scheme := flag.String("scheme", "", "show help message of proxy scheme, use 'all' to see all ") + flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode") - flag.IntVar(&conf.LogFlags, "logflags", 19, "log flags, do not change it if you do not know what it is, ref: https://pkg.go.dev/log#pkg-constants") + 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") - flag.StringSliceUniqVar(&conf.Listens, "listen", nil, "listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS") + flag.StringSliceUniqVar(&conf.Listens, "listen", nil, "listen url, see the URL section below") - flag.StringSliceVar(&conf.Forwards, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]") - flag.StringVar(&conf.Strategy.Strategy, "strategy", "rr", "forward strategy, default: rr") - flag.StringVar(&conf.Strategy.Check, "check", "http://www.msftconnecttest.com/connecttest.txt#expect=200", "check=tcp[://HOST:PORT]: tcp port connect check\ncheck=http://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=https://HOST[:PORT][/URI][#expect=REGEX_MATCH_IN_RESP_LINE]\ncheck=file://SCRIPT_PATH: run a check script, healthy when exitcode=0, environment variables: FORWARDER_ADDR,FORWARDER_URL\ncheck=disable: disable health check") + 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") @@ -71,7 +81,7 @@ func parseConfig() *Config { 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)") - flag.IntVar(&conf.DNSConfig.CacheSize, "dnscachesize", 4096, "size of CACHE") + 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") @@ -87,6 +97,11 @@ func parseConfig() *Config { os.Exit(-1) } + if *scheme != "" { + fmt.Fprintf(os.Stdout, proxy.Usage(*scheme)) + os.Exit(0) + } + // setup logger log.Set(conf.Verbose, conf.LogFlags) @@ -139,212 +154,53 @@ func parseConfig() *Config { } func usage() { - app := os.Args[0] w := flag.Output() - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, "%s %s usage:\n", app, version) + fmt.Fprint(w, ` +Usage: glider [-listen URL]... [-forward URL]... [OPTION]... + e.g. glider -config /etc/glider/glider.conf + glider -listen :8443 -forward socks5://serverA:1080 -forward socks5://serverB:1080 -verbose + +`) + + fmt.Fprintf(w, "OPTION:\n") flag.PrintDefaults() - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, "Available schemes:\n") - fmt.Fprintf(w, " listen: mixed ss socks5 http vless trojan trojanc redir redir6 tproxy tcp udp tls ws wss unix smux kcp pxyproto\n") - fmt.Fprintf(w, " forward: direct reject ss socks4 socks5 http ssr ssh vless vmess trojan trojanc tcp udp tls ws wss unix smux kcp simple-obfs\n") - fmt.Fprintf(w, "\n") + fmt.Fprint(w, ` +URL: + proxy: SCHEME://[USER:PASS@][HOST]:PORT + chain: proxy,proxy,[proxy]... - fmt.Fprintf(w, "Socks5 scheme:\n") - fmt.Fprintf(w, " socks://[user:pass@]host:port\n") - fmt.Fprintf(w, "\n") + e.g. -listen socks5://:1080 + -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// (protocol chain) - fmt.Fprintf(w, "SS scheme:\n") - fmt.Fprintf(w, " ss://method:pass@host:port\n") - fmt.Fprintf(w, "\n") + e.g. -forward socks5://server:1080 + -forward tls://server.com:443,http:// (protocol chain) + -forward socks5://serverA:1080,socks5://serverB:1080 (proxy chain) - fmt.Fprintf(w, "Available methods for ss:\n") - fmt.Fprintf(w, " AEAD Ciphers:\n") - fmt.Fprintf(w, " AEAD_AES_128_GCM AEAD_AES_192_GCM AEAD_AES_256_GCM AEAD_CHACHA20_POLY1305 AEAD_XCHACHA20_POLY1305\n") - fmt.Fprintf(w, " Stream Ciphers:\n") - fmt.Fprintf(w, " AES-128-CFB AES-128-CTR AES-192-CFB AES-192-CTR AES-256-CFB AES-256-CTR CHACHA20-IETF XCHACHA20 CHACHA20 RC4-MD5\n") - fmt.Fprintf(w, " Alias:\n") - fmt.Fprintf(w, " chacha20-ietf-poly1305 = AEAD_CHACHA20_POLY1305, xchacha20-ietf-poly1305 = AEAD_XCHACHA20_POLY1305\n") - fmt.Fprintf(w, " Plain: NONE\n") - fmt.Fprintf(w, "\n") +`) - fmt.Fprintf(w, "SSR scheme:\n") - fmt.Fprintf(w, " ssr://method:pass@host:port?protocol=xxx&protocol_param=yyy&obfs=zzz&obfs_param=xyz\n") - fmt.Fprintf(w, "\n") + fmt.Fprintf(w, "SCHEME:\n") + fmt.Fprintf(w, " listen : %s\n", proxy.ServerSchemes()) + fmt.Fprintf(w, " forward: %s\n", proxy.DialerSchemes()) + fmt.Fprintf(w, "\n Note: use `glider -scheme all` or `glider -scheme SCHEME` to see help info for the scheme.\n") - fmt.Fprintf(w, "SSH scheme:\n") - fmt.Fprintf(w, " ssh://user[:pass]@host:port[?key=keypath&timeout=SECONDS]\n") - fmt.Fprintf(w, " timeout: timeout of ssh handshake and channel operation, default: 5\n") - fmt.Fprintf(w, "\n") + fmt.Fprint(w, ` +-- +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. - fmt.Fprintf(w, "VMess scheme:\n") - fmt.Fprintf(w, " vmess://[security:]uuid@host:port[?alterID=num]\n") - fmt.Fprintf(w, " if alterID=0 or not set, VMessAEAD will be enabled\n") - fmt.Fprintf(w, "\n") + 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 - fmt.Fprintf(w, "Available security for vmess:\n") - fmt.Fprintf(w, " zero, none, aes-128-gcm, chacha20-poly1305\n") - fmt.Fprintf(w, "\n") +Services: + dhcpd: service=dhcpd,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...] + e.g. service=dhcpd,eth1,192.168.1.100,192.168.1.199,720 - fmt.Fprintf(w, "VLESS scheme:\n") - fmt.Fprintf(w, " vless://uuid@host:port[?fallback=127.0.0.1:80]\n") - fmt.Fprintf(w, "\n") +see README.md and glider.conf.example for more details. +`) - fmt.Fprintf(w, "Trojan client scheme:\n") - fmt.Fprintf(w, " trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH]\n") - fmt.Fprintf(w, " trojanc://pass@host:port (cleartext, without TLS)\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Trojan server scheme:\n") - fmt.Fprintf(w, " trojan://pass@host:port?cert=PATH&key=PATH[&fallback=127.0.0.1]\n") - fmt.Fprintf(w, " trojanc://pass@host:port[?fallback=127.0.0.1] (cleartext, without TLS)\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "TLS client scheme:\n") - fmt.Fprintf(w, " tls://host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH][&alpn=proto1][&alpn=proto2]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Proxy over tls client:\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true][&serverName=SERVERNAME],scheme://\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true],http://[user:pass@]\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true],socks5://[user:pass@]\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true],vmess://[security:]uuid@?alterID=num\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "TLS server scheme:\n") - fmt.Fprintf(w, " tls://host:port?cert=PATH&key=PATH[&alpn=proto1][&alpn=proto2]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Proxy over tls server:\n") - fmt.Fprintf(w, " tls://host:port?cert=PATH&key=PATH,scheme://\n") - fmt.Fprintf(w, " tls://host:port?cert=PATH&key=PATH,http://\n") - fmt.Fprintf(w, " tls://host:port?cert=PATH&key=PATH,socks5://\n") - fmt.Fprintf(w, " tls://host:port?cert=PATH&key=PATH,ss://method:pass@\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Websocket client scheme:\n") - fmt.Fprintf(w, " ws://host:port[/path][?host=HOST][&origin=ORIGIN]\n") - fmt.Fprintf(w, " wss://host:port[/path][?serverName=SERVERNAME][&skipVerify=true][&cert=PATH][&host=HOST][&origin=ORIGIN]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Websocket server scheme:\n") - fmt.Fprintf(w, " ws://:port[/path][?host=HOST]\n") - fmt.Fprintf(w, " wss://:port[/path]?cert=PATH&key=PATH[?host=HOST]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Websocket with a specified proxy protocol:\n") - fmt.Fprintf(w, " ws://host:port[/path][?host=HOST],scheme://\n") - fmt.Fprintf(w, " ws://host:port[/path][?host=HOST],http://[user:pass@]\n") - fmt.Fprintf(w, " ws://host:port[/path][?host=HOST],socks5://[user:pass@]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "TLS and Websocket with a specified proxy protocol:\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true][&serverName=SERVERNAME],ws://[@/path[?host=HOST]],scheme://\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],http://[user:pass@]\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],socks5://[user:pass@]\n") - fmt.Fprintf(w, " tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],vmess://[security:]uuid@?alterID=num\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Unix domain socket scheme:\n") - fmt.Fprintf(w, " unix://path\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Smux scheme:\n") - fmt.Fprintf(w, " smux://host:port\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "KCP scheme:\n") - fmt.Fprintf(w, " kcp://CRYPT:KEY@host:port[?dataShards=NUM&parityShards=NUM&mode=MODE]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Available crypt types for KCP:\n") - fmt.Fprintf(w, " none, sm4, tea, xor, aes, aes-128, aes-192, blowfish, twofish, cast5, 3des, xtea, salsa20\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Available modes for KCP:\n") - fmt.Fprintf(w, " fast, fast2, fast3, normal, default: fast\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Simple-Obfs scheme:\n") - fmt.Fprintf(w, " simple-obfs://host:port[?type=TYPE&host=HOST&uri=URI&ua=UA]\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Available types for simple-obfs:\n") - fmt.Fprintf(w, " http, tls\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "DNS forwarding server:\n") - fmt.Fprintf(w, " dns=:53\n") - fmt.Fprintf(w, " dnsserver=8.8.8.8:53\n") - fmt.Fprintf(w, " dnsserver=1.1.1.1:53\n") - fmt.Fprintf(w, " dnsrecord=www.example.com/1.2.3.4\n") - fmt.Fprintf(w, " dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Available forward strategies:\n") - fmt.Fprintf(w, " rr: Round Robin mode\n") - fmt.Fprintf(w, " ha: High Availability mode\n") - fmt.Fprintf(w, " lha: Latency based High Availability mode\n") - fmt.Fprintf(w, " dh: Destination Hashing mode\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Forwarder option scheme: FORWARD_URL#OPTIONS\n") - fmt.Fprintf(w, " priority: set the priority of that forwarder, default:0\n") - fmt.Fprintf(w, " interface: set local interface or ip address used to connect remote server\n") - fmt.Fprintf(w, " -\n") - fmt.Fprintf(w, " Examples:\n") - fmt.Fprintf(w, " socks5://1.1.1.1:1080#priority=100\n") - fmt.Fprintf(w, " vmess://[security:]uuid@host:port?alterID=num#priority=200\n") - fmt.Fprintf(w, " vmess://[security:]uuid@host:port?alterID=num#priority=200&interface=192.168.1.99\n") - fmt.Fprintf(w, " vmess://[security:]uuid@host:port?alterID=num#priority=200&interface=eth0\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Services:\n") - fmt.Fprintf(w, " dhcpd: service=dhcpd,INTERFACE,START_IP,END_IP,LEASE_MINUTES[,MAC=IP,MAC=IP...]\n") - fmt.Fprintf(w, " e.g.,service=dhcpd,eth1,192.168.1.100,192.168.1.199,720\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Config file format(see `"+app+".conf.example` as an example):\n") - fmt.Fprintf(w, " # COMMENT LINE\n") - fmt.Fprintf(w, " KEY=VALUE\n") - fmt.Fprintf(w, " KEY=VALUE\n") - fmt.Fprintf(w, " # KEY equals to command line flag name: listen forward strategy...\n") - fmt.Fprintf(w, "\n") - - fmt.Fprintf(w, "Examples:\n") - fmt.Fprintf(w, " "+app+" -config glider.conf\n") - fmt.Fprintf(w, " -run glider with specified config file.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen :8443 -verbose\n") - fmt.Fprintf(w, " -listen on :8443, serve as http/socks5 proxy on the same port, in verbose mode.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen ss://AEAD_AES_128_GCM:pass@:8443 -verbose\n") - fmt.Fprintf(w, " -listen on 0.0.0.0:8443 as a ss server.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen tls://:443?cert=crtFilePath&key=keyFilePath,http:// -verbose\n") - fmt.Fprintf(w, " -listen on :443 as a https(http over tls) proxy server.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen http://:8080 -forward socks5://127.0.0.1:1080\n") - fmt.Fprintf(w, " -listen on :8080 as a http proxy server, forward all requests via socks5 server.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen socks5://:1080 -forward \"tls://abc.com:443,vmess://security:uuid@?alterID=10\"\n") - fmt.Fprintf(w, " -listen on :1080 as a socks5 server, forward all requests via remote tls+vmess server.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen socks5://:1080 -forward ss://method:pass@server1:port1 -forward ss://method:pass@server2:port2 -strategy rr\n") - fmt.Fprintf(w, " -listen on :1080 as socks5 server, forward requests via server1 and server2 in round robin mode.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen tcp://:80 -forward tcp://2.2.2.2:80\n") - fmt.Fprintf(w, " -tcp tunnel: listen on :80 and forward all requests to 2.2.2.2:80.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen udp://:53 -forward ss://method:pass@1.1.1.1:8443,udp://8.8.8.8:53\n") - fmt.Fprintf(w, " -listen on :53 and forward all udp requests to 8.8.8.8:53 via remote ss server.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -listen socks5://:1080 -listen http://:8080 -forward ss://method:pass@1.1.1.1:8443\n") - fmt.Fprintf(w, " -listen on :1080 as socks5 server, :8080 as http proxy server, forward all requests via remote ss server.\n") - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, " "+app+" -verbose -listen -dns=:53 -dnsserver=8.8.8.8:53 -forward ss://method:pass@server:port -dnsrecord=www.example.com/1.2.3.4\n") - fmt.Fprintf(w, " -listen on :53 as dns server, forward to 8.8.8.8:53 via ss server.\n") - fmt.Fprintf(w, "\n") + fmt.Fprintf(w, "--\nglider v%s, https://github.com/nadoo/glider\n\n", version) } diff --git a/go.mod b/go.mod index 155ef64..a2e49b6 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,9 @@ require ( github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152 github.com/insomniacslk/dhcp v0.0.0-20220119180841-3c283ff8b7dd github.com/nadoo/conflag v0.3.1 - github.com/nadoo/ipset v0.4.1-0.20220202154244-ddbfbad6db35 + github.com/nadoo/ipset v0.4.1-0.20220214103201-761217ee1ee0 github.com/xtaci/kcp-go/v5 v5.6.1 - golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 + golang.org/x/crypto v0.0.0-20220214200702-86341886e292 golang.org/x/sys v0.0.0-20220209214540-3681064d5158 ) diff --git a/go.sum b/go.sum index dc34c82..acc7747 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b/go.mod h1:7EpbotpCmVZ github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls= github.com/nadoo/conflag v0.3.1 h1:4pHkLIz8PUsfg6ajNYRRSY3bt6m2LPsu6KOzn5uIXQw= github.com/nadoo/conflag v0.3.1/go.mod h1:dzFfDUpXdr2uS2oV+udpy5N2vfNOu/bFzjhX1WI52co= -github.com/nadoo/ipset v0.4.1-0.20220202154244-ddbfbad6db35 h1:ROGpIZqxtrO0mJhSS9bte1VNwVUmmavcjjtw3720t94= -github.com/nadoo/ipset v0.4.1-0.20220202154244-ddbfbad6db35/go.mod h1:rYF5DQLRGGoQ8ZSWeK+6eX5amAuPqwFkWjhQlEITGJQ= +github.com/nadoo/ipset v0.4.1-0.20220214103201-761217ee1ee0 h1:i81BROp7xvMIkR1KpLwERTrRVgwwFAN0prz1kQmz9RE= +github.com/nadoo/ipset v0.4.1-0.20220214103201-761217ee1ee0/go.mod h1:rYF5DQLRGGoQ8ZSWeK+6eX5amAuPqwFkWjhQlEITGJQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -104,8 +104,8 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506 h1:EuGTJDfeg/PGZJp3gq1K+14eSLFTsrj1eg8KQuiUyKg= -golang.org/x/crypto v0.0.0-20220213190939-1e6e3497d506/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= diff --git a/proxy/dialer.go b/proxy/dialer.go index 5df7174..4112468 100644 --- a/proxy/dialer.go +++ b/proxy/dialer.go @@ -66,3 +66,12 @@ func DialerFromURL(s string, dialer Dialer) (Dialer, error) { return nil, errors.New("unknown scheme '" + scheme + "'") } + +// DialerSchemes returns the registered dialer schemes. +func DialerSchemes() string { + s := make([]string, 0, len(dialerCreators)) + for name := range dialerCreators { + s = append(s, name) + } + return strings.Join(s, ",") +} diff --git a/proxy/kcp/kcp.go b/proxy/kcp/kcp.go index a0b46e9..3a41e8f 100644 --- a/proxy/kcp/kcp.go +++ b/proxy/kcp/kcp.go @@ -266,3 +266,16 @@ func (s *KCP) setParams(c *kcp.UDPSession) { c.SetMtu(1350) c.SetACKNoDelay(true) } + +func init() { + proxy.AddUsage("kcp", ` +KCP scheme: + kcp://CRYPT:KEY@host:port[?dataShards=NUM&parityShards=NUM&mode=MODE] + +Available crypt types for KCP: + none, sm4, tea, xor, aes, aes-128, aes-192, blowfish, twofish, cast5, 3des, xtea, salsa20 + +Available modes for KCP: + fast, fast2, fast3, normal, default: fast +`) +} diff --git a/proxy/obfs/obfs.go b/proxy/obfs/obfs.go index 21d1d38..75ffe0b 100644 --- a/proxy/obfs/obfs.go +++ b/proxy/obfs/obfs.go @@ -109,3 +109,13 @@ func (s *Obfs) Dial(network, addr string) (net.Conn, error) { func (s *Obfs) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) { return nil, nil, proxy.ErrNotSupported } + +func init() { + proxy.AddUsage("simple-obfs", ` +Simple-Obfs scheme: + simple-obfs://host:port[?type=TYPE&host=HOST&uri=URI&ua=UA] + +Available types for simple-obfs: + http, tls +`) +} diff --git a/proxy/server.go b/proxy/server.go index 3271feb..c674420 100644 --- a/proxy/server.go +++ b/proxy/server.go @@ -51,3 +51,12 @@ func ServerFromURL(s string, proxy Proxy) (Server, error) { return nil, errors.New("unknown scheme '" + scheme + "'") } + +// ServerSchemes returns the registered server schemes. +func ServerSchemes() string { + s := make([]string, 0, len(serverCreators)) + for name := range serverCreators { + s = append(s, name) + } + return strings.Join(s, ",") +} diff --git a/proxy/smux/smux.go b/proxy/smux/smux.go new file mode 100644 index 0000000..fae7406 --- /dev/null +++ b/proxy/smux/smux.go @@ -0,0 +1,10 @@ +package smux + +import "github.com/nadoo/glider/proxy" + +func init() { + proxy.AddUsage("smux", ` +Smux scheme: + smux://host:port +`) +} diff --git a/proxy/socks5/client.go b/proxy/socks5/client.go index c470c3c..d0ba28f 100644 --- a/proxy/socks5/client.go +++ b/proxy/socks5/client.go @@ -13,6 +13,10 @@ import ( "github.com/nadoo/glider/proxy" ) +func init() { + proxy.RegisterDialer("socks5", NewSocks5Dialer) +} + // NewSocks5Dialer returns a socks5 proxy dialer. func NewSocks5Dialer(s string, d proxy.Dialer) (proxy.Dialer, error) { return NewSocks5(s, d, nil) diff --git a/proxy/socks5/server.go b/proxy/socks5/server.go index a753193..471255f 100644 --- a/proxy/socks5/server.go +++ b/proxy/socks5/server.go @@ -16,6 +16,10 @@ import ( var nm sync.Map +func init() { + proxy.RegisterServer("socks5", NewSocks5Server) +} + // NewSocks5Server returns a socks5 proxy server. func NewSocks5Server(s string, p proxy.Proxy) (proxy.Server, error) { return NewSocks5(s, nil, p) diff --git a/proxy/socks5/socks5.go b/proxy/socks5/socks5.go index f190e58..dffb204 100644 --- a/proxy/socks5/socks5.go +++ b/proxy/socks5/socks5.go @@ -28,11 +28,6 @@ type Socks5 struct { password string } -func init() { - proxy.RegisterDialer("socks5", NewSocks5Dialer) - proxy.RegisterServer("socks5", NewSocks5Server) -} - // NewSocks5 returns a Proxy that makes SOCKS v5 connections to the given address. // with an optional username and password. (RFC 1928) func NewSocks5(s string, d proxy.Dialer, p proxy.Proxy) (*Socks5, error) { @@ -56,3 +51,10 @@ func NewSocks5(s string, d proxy.Dialer, p proxy.Proxy) (*Socks5, error) { return h, nil } + +func init() { + proxy.AddUsage("socks5", ` +Socks5 scheme: + socks://[user:pass@]host:port +`) +} diff --git a/proxy/ss/ss.go b/proxy/ss/ss.go index 71351cf..ba6be4a 100644 --- a/proxy/ss/ss.go +++ b/proxy/ss/ss.go @@ -48,3 +48,19 @@ func NewSS(s string, d proxy.Dialer, p proxy.Proxy) (*SS, error) { return ss, nil } + +func init() { + proxy.AddUsage("ss", ` +SS scheme: + ss://method:pass@host:port + + Available methods for ss: + AEAD Ciphers: + AEAD_AES_128_GCM AEAD_AES_192_GCM AEAD_AES_256_GCM AEAD_CHACHA20_POLY1305 AEAD_XCHACHA20_POLY1305 + Stream Ciphers: + AES-128-CFB AES-128-CTR AES-192-CFB AES-192-CTR AES-256-CFB AES-256-CTR CHACHA20-IETF XCHACHA20 CHACHA20 RC4-MD5 + Alias: + chacha20-ietf-poly1305 = AEAD_CHACHA20_POLY1305, xchacha20-ietf-poly1305 = AEAD_XCHACHA20_POLY1305 + Plain: NONE +`) +} diff --git a/proxy/ssh/ssh.go b/proxy/ssh/ssh.go index 697806d..dc51f0f 100644 --- a/proxy/ssh/ssh.go +++ b/proxy/ssh/ssh.go @@ -166,3 +166,11 @@ func privateKeyAuth(file string) (ssh.AuthMethod, error) { return ssh.PublicKeys(key), nil } + +func init() { + proxy.AddUsage("ssh", ` +SSH scheme: + ssh://user[:pass]@host:port[?key=keypath&timeout=SECONDS] + timeout: timeout of ssh handshake and channel operation, default: 5 +`) +} diff --git a/proxy/ssr/ssr.go b/proxy/ssr/ssr.go index df4b398..257e243 100644 --- a/proxy/ssr/ssr.go +++ b/proxy/ssr/ssr.go @@ -155,3 +155,10 @@ func (s *SSR) Dial(network, addr string) (net.Conn, error) { func (s *SSR) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) { return nil, nil, proxy.ErrNotSupported } + +func init() { + proxy.AddUsage("ssr", ` +SSR scheme: + ssr://method:pass@host:port?protocol=xxx&protocol_param=yyy&obfs=zzz&obfs_param=xyz +`) +} diff --git a/proxy/tls/tls.go b/proxy/tls/tls.go index 9a053de..1cc493b 100644 --- a/proxy/tls/tls.go +++ b/proxy/tls/tls.go @@ -210,3 +210,25 @@ func (s *TLS) Dial(network, addr string) (net.Conn, error) { func (s *TLS) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) { return nil, nil, proxy.ErrNotSupported } + +func init() { + proxy.AddUsage("tls", ` +TLS client scheme: + tls://host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH][&alpn=proto1][&alpn=proto2] + +Proxy over tls client: + tls://host:port[?skipVerify=true][&serverName=SERVERNAME],scheme:// + tls://host:port[?skipVerify=true],http://[user:pass@] + tls://host:port[?skipVerify=true],socks5://[user:pass@] + tls://host:port[?skipVerify=true],vmess://[security:]uuid@?alterID=num + +TLS server scheme: + tls://host:port?cert=PATH&key=PATH[&alpn=proto1][&alpn=proto2] + +Proxy over tls server: + tls://host:port?cert=PATH&key=PATH,scheme:// + tls://host:port?cert=PATH&key=PATH,http:// + tls://host:port?cert=PATH&key=PATH,socks5:// + tls://host:port?cert=PATH&key=PATH,ss://method:pass@ +`) +} diff --git a/proxy/trojan/trojan.go b/proxy/trojan/trojan.go index 6e065c6..6ee811c 100644 --- a/proxy/trojan/trojan.go +++ b/proxy/trojan/trojan.go @@ -71,3 +71,15 @@ func NewTrojan(s string, d proxy.Dialer, p proxy.Proxy) (*Trojan, error) { return t, nil } + +func init() { + proxy.AddUsage("trojan", ` +Trojan client scheme: + trojan://pass@host:port[?serverName=SERVERNAME][&skipVerify=true][&cert=PATH] + trojanc://pass@host:port (cleartext, without TLS) + +Trojan server scheme: + trojan://pass@host:port?cert=PATH&key=PATH[&fallback=127.0.0.1] + trojanc://pass@host:port[?fallback=127.0.0.1] (cleartext, without TLS) +`) +} diff --git a/proxy/unix/unix.go b/proxy/unix/unix.go index aee57bd..e8c3e74 100644 --- a/proxy/unix/unix.go +++ b/proxy/unix/unix.go @@ -48,3 +48,10 @@ func NewUnix(s string, d proxy.Dialer, p proxy.Proxy) (*Unix, error) { return unix, nil } + +func init() { + proxy.AddUsage("unix", ` +Unix domain socket scheme: + unix://path +`) +} diff --git a/proxy/usage.go b/proxy/usage.go new file mode 100644 index 0000000..f707fd6 --- /dev/null +++ b/proxy/usage.go @@ -0,0 +1,24 @@ +package proxy + +import "strings" + +var msg strings.Builder +var usages = make(map[string]string) + +// AddUsage adds help message for the named proxy. +func AddUsage(name, usage string) { + usages[name] = usage + msg.WriteString(usage) + msg.WriteString("\n--") +} + +// Usage returns help message of the named proxy. +func Usage(name string) string { + if name == "all" { + return msg.String() + } + if usage, ok := usages[name]; ok { + return usage + } + return "can not find usage for: " + name +} diff --git a/proxy/vless/vless.go b/proxy/vless/vless.go index ce88a78..06efa1e 100644 --- a/proxy/vless/vless.go +++ b/proxy/vless/vless.go @@ -81,3 +81,10 @@ func StrToUUID(s string) (uuid [16]byte, err error) { _, err = hex.Decode(uuid[:], b) return } + +func init() { + proxy.AddUsage("vless", ` +VLESS scheme: + vless://uuid@host:port[?fallback=127.0.0.1:80] +`) +} diff --git a/proxy/vmess/vmess.go b/proxy/vmess/vmess.go index a41a305..6f07f3b 100644 --- a/proxy/vmess/vmess.go +++ b/proxy/vmess/vmess.go @@ -109,3 +109,14 @@ func (s *VMess) DialUDP(network, addr string) (net.PacketConn, net.Addr, error) } return NewPktConn(rc), nil, err } + +func init() { + proxy.AddUsage("vmess", ` +VMess scheme: + vmess://[security:]uuid@host:port[?alterID=num] + if alterID=0 or not set, VMessAEAD will be enabled + + Available security for vmess: + zero, none, aes-128-gcm, chacha20-poly1305 +`) +} diff --git a/proxy/ws/ws.go b/proxy/ws/ws.go index 7de14d0..9a4e978 100644 --- a/proxy/ws/ws.go +++ b/proxy/ws/ws.go @@ -115,3 +115,26 @@ func computeServerKey(clientKey string) string { h.Write(keyGUID) return base64.StdEncoding.EncodeToString(h.Sum(nil)) } + +func init() { + proxy.AddUsage("ws", ` +Websocket client scheme: + ws://host:port[/path][?host=HOST][&origin=ORIGIN] + wss://host:port[/path][?serverName=SERVERNAME][&skipVerify=true][&cert=PATH][&host=HOST][&origin=ORIGIN] + +Websocket server scheme: + ws://:port[/path][?host=HOST] + wss://:port[/path]?cert=PATH&key=PATH[?host=HOST] + +Websocket with a specified proxy protocol: + ws://host:port[/path][?host=HOST],scheme:// + ws://host:port[/path][?host=HOST],http://[user:pass@] + ws://host:port[/path][?host=HOST],socks5://[user:pass@] + +TLS and Websocket with a specified proxy protocol: + tls://host:port[?skipVerify=true][&serverName=SERVERNAME],ws://[@/path[?host=HOST]],scheme:// + tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],http://[user:pass@] + tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],socks5://[user:pass@] + tls://host:port[?skipVerify=true],ws://[@/path[?host=HOST]],vmess://[security:]uuid@?alterID=num +`) +}