github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/config.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "crypto/sha1" 6 "fmt" 7 "io/ioutil" 8 logger "log" 9 "os" 10 "os/exec" 11 "path" 12 "path/filepath" 13 "runtime/debug" 14 "runtime/pprof" 15 "strings" 16 "time" 17 18 "github.com/AntonOrnatskyi/goproxy/core/lib/kcpcfg" 19 encryptconn "github.com/AntonOrnatskyi/goproxy/core/lib/transport/encrypt" 20 sdk "github.com/AntonOrnatskyi/goproxy/sdk/android-ios" 21 services "github.com/AntonOrnatskyi/goproxy/services" 22 httpx "github.com/AntonOrnatskyi/goproxy/services/http" 23 keygenx "github.com/AntonOrnatskyi/goproxy/services/keygen" 24 mux "github.com/AntonOrnatskyi/goproxy/services/mux" 25 socksx "github.com/AntonOrnatskyi/goproxy/services/socks" 26 spsx "github.com/AntonOrnatskyi/goproxy/services/sps" 27 tcpx "github.com/AntonOrnatskyi/goproxy/services/tcp" 28 tunnelx "github.com/AntonOrnatskyi/goproxy/services/tunnel" 29 udpx "github.com/AntonOrnatskyi/goproxy/services/udp" 30 kcp "github.com/xtaci/kcp-go" 31 32 "golang.org/x/crypto/pbkdf2" 33 kingpin "gopkg.in/alecthomas/kingpin.v2" 34 ) 35 36 var ( 37 app *kingpin.Application 38 service *services.ServiceItem 39 cmd *exec.Cmd 40 cpuProfilingFile, memProfilingFile, blockProfilingFile, 41 goroutineProfilingFile, threadcreateProfilingFile *os.File 42 isDebug *bool 43 ) 44 45 func initConfig() (err error) { 46 //define args 47 tcpArgs := tcpx.TCPArgs{} 48 httpArgs := httpx.HTTPArgs{} 49 tunnelServerArgs := tunnelx.TunnelServerArgs{} 50 tunnelClientArgs := tunnelx.TunnelClientArgs{} 51 tunnelBridgeArgs := tunnelx.TunnelBridgeArgs{} 52 muxServerArgs := mux.MuxServerArgs{} 53 muxClientArgs := mux.MuxClientArgs{} 54 muxBridgeArgs := mux.MuxBridgeArgs{} 55 udpArgs := udpx.UDPArgs{} 56 socksArgs := socksx.SocksArgs{} 57 spsArgs := spsx.SPSArgs{} 58 dnsArgs := sdk.DNSArgs{} 59 keygenArgs := keygenx.KeygenArgs{} 60 kcpArgs := kcpcfg.KCPConfigArgs{} 61 //build srvice args 62 app = kingpin.New("proxy", "happy with proxy") 63 app.Author("snail").Version(APP_VERSION) 64 isDebug = app.Flag("debug", "debug log output").Default("false").Bool() 65 daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool() 66 forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool() 67 logfile := app.Flag("log", "log file path").Default("").String() 68 nolog := app.Flag("nolog", "turn off logging").Default("false").Bool() 69 kcpArgs.Key = app.Flag("kcp-key", "pre-shared secret between client and server").Default("secrect").String() 70 kcpArgs.Crypt = app.Flag("kcp-method", "encrypt/decrypt method, can be: aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none").Default("aes").Enum("aes", "aes-128", "aes-192", "salsa20", "blowfish", "twofish", "cast5", "3des", "tea", "xtea", "xor", "sm4", "none") 71 kcpArgs.Mode = app.Flag("kcp-mode", "profiles: fast3, fast2, fast, normal, manual").Default("fast").Enum("fast3", "fast2", "fast", "normal", "manual") 72 kcpArgs.MTU = app.Flag("kcp-mtu", "set maximum transmission unit for UDP packets").Default("450").Int() 73 kcpArgs.SndWnd = app.Flag("kcp-sndwnd", "set send window size(num of packets)").Default("1024").Int() 74 kcpArgs.RcvWnd = app.Flag("kcp-rcvwnd", "set receive window size(num of packets)").Default("1024").Int() 75 kcpArgs.DataShard = app.Flag("kcp-ds", "set reed-solomon erasure coding - datashard").Default("10").Int() 76 kcpArgs.ParityShard = app.Flag("kcp-ps", "set reed-solomon erasure coding - parityshard").Default("3").Int() 77 kcpArgs.DSCP = app.Flag("kcp-dscp", "set DSCP(6bit)").Default("0").Int() 78 kcpArgs.NoComp = app.Flag("kcp-nocomp", "disable compression").Default("false").Bool() 79 kcpArgs.AckNodelay = app.Flag("kcp-acknodelay", "be carefull! flush ack immediately when a packet is received").Default("true").Bool() 80 kcpArgs.NoDelay = app.Flag("kcp-nodelay", "be carefull!").Default("0").Int() 81 kcpArgs.Interval = app.Flag("kcp-interval", "be carefull!").Default("50").Int() 82 kcpArgs.Resend = app.Flag("kcp-resend", "be carefull!").Default("0").Int() 83 kcpArgs.NoCongestion = app.Flag("kcp-nc", "be carefull! no congestion").Default("0").Int() 84 kcpArgs.SockBuf = app.Flag("kcp-sockbuf", "be carefull!").Default("4194304").Int() 85 kcpArgs.KeepAlive = app.Flag("kcp-keepalive", "be carefull!").Default("10").Int() 86 87 //########http######### 88 http := app.Command("http", "proxy on http mode") 89 httpArgs.Parent = http.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').Strings() 90 httpArgs.CaCertFile = http.Flag("ca", "ca cert file for tls").Default("").String() 91 httpArgs.CertFile = http.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 92 httpArgs.KeyFile = http.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 93 httpArgs.LocalType = http.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp") 94 httpArgs.ParentType = http.Flag("parent-type", "parent protocol type <tls|tcp|ssh|kcp>").Short('T').Enum("tls", "tcp", "ssh", "kcp") 95 httpArgs.Always = http.Flag("always", "always use parent proxy").Default("false").Bool() 96 httpArgs.Timeout = http.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int() 97 httpArgs.HTTPTimeout = http.Flag("http-timeout", "check domain if blocked , http request timeout milliseconds when connect to host").Default("3000").Int() 98 httpArgs.Interval = http.Flag("interval", "check domain if blocked every interval seconds").Default("10").Int() 99 httpArgs.Blocked = http.Flag("blocked", "blocked domain file , one domain each line").Default("blocked").Short('b').String() 100 httpArgs.Direct = http.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String() 101 httpArgs.AuthFile = http.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String() 102 httpArgs.Auth = http.Flag("auth", "http basic auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings() 103 httpArgs.CheckParentInterval = http.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int() 104 httpArgs.Local = http.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":33080").String() 105 httpArgs.SSHUser = http.Flag("ssh-user", "user for ssh").Short('u').Default("").String() 106 httpArgs.SSHKeyFile = http.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String() 107 httpArgs.SSHKeyFileSalt = http.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String() 108 httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String() 109 httpArgs.LocalIPS = http.Flag("local-bind-ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings() 110 httpArgs.AuthURL = http.Flag("auth-url", "http basic auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String() 111 httpArgs.AuthURLTimeout = http.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int() 112 httpArgs.AuthURLOkCode = http.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int() 113 httpArgs.AuthURLRetry = http.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("1").Int() 114 httpArgs.DNSAddress = http.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String() 115 httpArgs.DNSTTL = http.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int() 116 httpArgs.LocalKey = http.Flag("local-key", "the password for auto encrypt/decrypt local connection data").Short('z').Default("").String() 117 httpArgs.ParentKey = http.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String() 118 httpArgs.LocalCompress = http.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool() 119 httpArgs.ParentCompress = http.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool() 120 httpArgs.Intelligent = http.Flag("intelligent", "settting intelligent HTTP, SOCKS5 proxy mode, can be <intelligent|direct|parent>").Default("intelligent").Enum("intelligent", "direct", "parent") 121 httpArgs.LoadBalanceMethod = http.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash") 122 httpArgs.LoadBalanceTimeout = http.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int() 123 httpArgs.LoadBalanceRetryTime = http.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int() 124 httpArgs.LoadBalanceHashTarget = http.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool() 125 httpArgs.LoadBalanceOnlyHA = http.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool() 126 httpArgs.RateLimit = http.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String() 127 httpArgs.BindListen = http.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool() 128 httpArgs.Jumper = http.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() 129 httpArgs.Debug = isDebug 130 //########tcp######### 131 tcp := app.Command("tcp", "proxy on tcp mode") 132 tcpArgs.Parent = tcp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 133 tcpArgs.CertFile = tcp.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 134 tcpArgs.KeyFile = tcp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 135 tcpArgs.Timeout = tcp.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('e').Default("2000").Int() 136 tcpArgs.ParentType = tcp.Flag("parent-type", "parent protocol type <tls|tcp|kcp|udp>").Short('T').Enum("tls", "tcp", "udp", "kcp") 137 tcpArgs.LocalType = tcp.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp") 138 tcpArgs.CheckParentInterval = tcp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int() 139 tcpArgs.Local = tcp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() 140 tcpArgs.Jumper = tcp.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() 141 142 //########udp######### 143 udp := app.Command("udp", "proxy on udp mode") 144 udpArgs.Parent = udp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 145 udpArgs.CertFile = udp.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 146 udpArgs.KeyFile = udp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 147 udpArgs.Timeout = udp.Flag("timeout", "tcp timeout milliseconds when connect to parent proxy").Short('t').Default("2000").Int() 148 udpArgs.ParentType = udp.Flag("parent-type", "parent protocol type <tls|tcp|udp>").Short('T').Enum("tls", "tcp", "udp") 149 udpArgs.CheckParentInterval = udp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int() 150 udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() 151 152 //########mux-server######### 153 muxServer := app.Command("server", "proxy on mux server mode") 154 muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 155 muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou") 156 muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 157 muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 158 muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() 159 muxServerArgs.IsUDP = muxServer.Flag("udp", "proxy on udp mux server mode").Default("false").Bool() 160 muxServerArgs.Key = muxServer.Flag("k", "client key").Default("default").String() 161 muxServerArgs.Route = muxServer.Flag("route", "local route to client's network, such as: PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings() 162 muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool() 163 muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int() 164 muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() 165 muxServerArgs.TCPSMethod = muxServer.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() 166 muxServerArgs.TCPSPassword = muxServer.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() 167 muxServerArgs.TOUMethod = muxServer.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() 168 muxServerArgs.TOUPassword = muxServer.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String() 169 170 //########mux-client######### 171 muxClient := app.Command("client", "proxy on mux client mode") 172 muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 173 muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou") 174 muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 175 muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 176 muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() 177 muxClientArgs.Key = muxClient.Flag("k", "key same with server").Default("default").String() 178 muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool() 179 muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int() 180 muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() 181 muxClientArgs.TCPSMethod = muxClient.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() 182 muxClientArgs.TCPSPassword = muxClient.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() 183 muxClientArgs.TOUMethod = muxClient.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() 184 muxClientArgs.TOUPassword = muxClient.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String() 185 186 //########mux-bridge######### 187 muxBridge := app.Command("bridge", "proxy on mux bridge mode") 188 muxBridgeArgs.CertFile = muxBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 189 muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 190 muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int() 191 muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() 192 muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('t').Enum("tls", "tcp", "tcps", "kcp", "tou") 193 muxBridgeArgs.TCPSMethod = muxBridge.Flag("tcps-method", "method of local tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() 194 muxBridgeArgs.TCPSPassword = muxBridge.Flag("tcps-password", "password of local tcps's encrpyt/decrypt").Default("snail007's_goproxy").String() 195 muxBridgeArgs.TOUMethod = muxBridge.Flag("tou-method", "method of local tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String() 196 muxBridgeArgs.TOUPassword = muxBridge.Flag("tou-password", "password of local tou's encrpyt/decrypt").Default("snail007's_goproxy").String() 197 198 //########tunnel-server######### 199 tunnelServer := app.Command("tserver", "proxy on tunnel server mode") 200 tunnelServerArgs.Parent = tunnelServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 201 tunnelServerArgs.CertFile = tunnelServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 202 tunnelServerArgs.KeyFile = tunnelServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 203 tunnelServerArgs.Timeout = tunnelServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int() 204 tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool() 205 tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String() 206 tunnelServerArgs.Route = tunnelServer.Flag("route", "local route to client's network, such as: PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings() 207 tunnelServerArgs.Jumper = tunnelServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() 208 209 //########tunnel-client######### 210 tunnelClient := app.Command("tclient", "proxy on tunnel client mode") 211 tunnelClientArgs.Parent = tunnelClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 212 tunnelClientArgs.CertFile = tunnelClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 213 tunnelClientArgs.KeyFile = tunnelClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 214 tunnelClientArgs.Timeout = tunnelClient.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int() 215 tunnelClientArgs.Key = tunnelClient.Flag("k", "key same with server").Default("default").String() 216 tunnelClientArgs.Jumper = tunnelClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String() 217 218 //########tunnel-bridge######### 219 tunnelBridge := app.Command("tbridge", "proxy on tunnel bridge mode") 220 tunnelBridgeArgs.CertFile = tunnelBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 221 tunnelBridgeArgs.KeyFile = tunnelBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 222 tunnelBridgeArgs.Timeout = tunnelBridge.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int() 223 tunnelBridgeArgs.Local = tunnelBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() 224 225 //########socks######### 226 socks := app.Command("socks", "proxy on ssh mode") 227 socksArgs.Parent = socks.Flag("parent", "parent ssh address, such as: \"23.32.32.19:22\"").Default("").Short('P').Strings() 228 socksArgs.ParentType = socks.Flag("parent-type", "parent protocol type <tls|tcp|kcp|ssh>").Default("tcp").Short('T').Enum("tls", "tcp", "kcp", "ssh") 229 socksArgs.LocalType = socks.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp") 230 socksArgs.Local = socks.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String() 231 socksArgs.CertFile = socks.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 232 socksArgs.CaCertFile = socks.Flag("ca", "ca cert file for tls").Default("").String() 233 socksArgs.KeyFile = socks.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 234 socksArgs.SSHUser = socks.Flag("ssh-user", "user for ssh").Short('u').Default("").String() 235 socksArgs.SSHKeyFile = socks.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String() 236 socksArgs.SSHKeyFileSalt = socks.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String() 237 socksArgs.SSHPassword = socks.Flag("ssh-password", "password for ssh").Short('D').Default("").String() 238 socksArgs.Always = socks.Flag("always", "always use parent proxy").Default("false").Bool() 239 socksArgs.Timeout = socks.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("5000").Int() 240 socksArgs.Interval = socks.Flag("interval", "check domain if blocked every interval seconds").Default("10").Int() 241 socksArgs.Blocked = socks.Flag("blocked", "blocked domain file , one domain each line").Default("blocked").Short('b').String() 242 socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String() 243 socksArgs.AuthFile = socks.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String() 244 socksArgs.Auth = socks.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings() 245 socksArgs.LocalIPS = socks.Flag("local-bind-ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings() 246 socksArgs.AuthURL = socks.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String() 247 socksArgs.AuthURLTimeout = socks.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int() 248 socksArgs.AuthURLOkCode = socks.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int() 249 socksArgs.AuthURLRetry = socks.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int() 250 socksArgs.ParentAuth = socks.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String() 251 socksArgs.DNSAddress = socks.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String() 252 socksArgs.DNSTTL = socks.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int() 253 socksArgs.LocalKey = socks.Flag("local-key", "the password for auto encrypt/decrypt local connection data").Short('z').Default("").String() 254 socksArgs.ParentKey = socks.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String() 255 socksArgs.LocalCompress = socks.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool() 256 socksArgs.ParentCompress = socks.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool() 257 socksArgs.Intelligent = socks.Flag("intelligent", "settting intelligent HTTP, SOCKS5 proxy mode, can be <intelligent|direct|parent>").Default("intelligent").Enum("intelligent", "direct", "parent") 258 socksArgs.LoadBalanceMethod = socks.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash") 259 socksArgs.LoadBalanceTimeout = socks.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int() 260 socksArgs.LoadBalanceRetryTime = socks.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int() 261 socksArgs.LoadBalanceHashTarget = socks.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool() 262 socksArgs.LoadBalanceOnlyHA = socks.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool() 263 socksArgs.RateLimit = socks.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String() 264 socksArgs.BindListen = socks.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool() 265 socksArgs.Debug = isDebug 266 267 //########sps######### 268 sps := app.Command("sps", "proxy on socks+http(s) mode") 269 spsArgs.Parent = sps.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').Strings() 270 spsArgs.CertFile = sps.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 271 spsArgs.KeyFile = sps.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 272 spsArgs.CaCertFile = sps.Flag("ca", "ca cert file for tls").Default("").String() 273 spsArgs.Timeout = sps.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('i').Default("2000").Int() 274 spsArgs.ParentType = sps.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp") 275 spsArgs.LocalType = sps.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp") 276 spsArgs.Local = sps.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":33080").String() 277 spsArgs.ParentServiceType = sps.Flag("parent-service-type", "parent service type <http|socks|ss>").Short('S').Enum("http", "socks", "ss") 278 spsArgs.DNSAddress = sps.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String() 279 spsArgs.DNSTTL = sps.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int() 280 spsArgs.AuthFile = sps.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String() 281 spsArgs.Auth = sps.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings() 282 spsArgs.LocalIPS = sps.Flag("local-bind-ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings() 283 spsArgs.AuthURL = sps.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String() 284 spsArgs.AuthURLTimeout = sps.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int() 285 spsArgs.AuthURLOkCode = sps.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int() 286 spsArgs.AuthURLRetry = sps.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int() 287 spsArgs.ParentAuth = sps.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String() 288 spsArgs.LocalKey = sps.Flag("local-key", "the password for auto encrypt/decrypt local connection data").Short('z').Default("").String() 289 spsArgs.ParentKey = sps.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String() 290 spsArgs.LocalCompress = sps.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool() 291 spsArgs.ParentCompress = sps.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool() 292 spsArgs.SSMethod = sps.Flag("ss-method", "the following methods are supported: aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, rc4-md5-6, chacha20, salsa20, rc4, table, des-cfb, chacha20-ietf; if you use ss client , \"-t tcp\" is required").Short('h').Default("aes-256-cfb").String() 293 spsArgs.SSKey = sps.Flag("ss-key", "if you use ss client , \"-t tcp\" is required").Short('j').Default("sspassword").String() 294 spsArgs.ParentSSMethod = sps.Flag("parent-ss-method", "the following methods are supported: aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, rc4-md5-6, chacha20, salsa20, rc4, table, des-cfb, chacha20-ietf; if you use ss server as parent, \"-T tcp\" is required").Short('H').Default("aes-256-cfb").String() 295 spsArgs.ParentSSKey = sps.Flag("parent-ss-key", "if you use ss server as parent, \"-T tcp\" is required").Short('J').Default("sspassword").String() 296 spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool() 297 spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool() 298 spsArgs.DisableSS = sps.Flag("disable-ss", "disable ss proxy").Default("false").Bool() 299 spsArgs.LoadBalanceMethod = sps.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash") 300 spsArgs.LoadBalanceTimeout = sps.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int() 301 spsArgs.LoadBalanceRetryTime = sps.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int() 302 spsArgs.LoadBalanceHashTarget = sps.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool() 303 spsArgs.LoadBalanceOnlyHA = sps.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool() 304 spsArgs.RateLimit = sps.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String() 305 spsArgs.Jumper = sps.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Default("").String() 306 spsArgs.ParentTLSSingle = sps.Flag("parent-tls-single", "conntect to parent insecure skip verify").Default("false").Bool() 307 spsArgs.Debug = isDebug 308 309 //########dns######### 310 dns := app.Command("dns", "proxy on dns server mode") 311 dnsArgs.Parent = dns.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String() 312 dnsArgs.CertFile = dns.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String() 313 dnsArgs.KeyFile = dns.Flag("key", "key file for tls").Short('K').Default("proxy.key").String() 314 dnsArgs.CaCertFile = dns.Flag("ca", "ca cert file for tls").Default("").String() 315 dnsArgs.Timeout = dns.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('i').Default("2000").Int() 316 dnsArgs.ParentType = dns.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp") 317 dnsArgs.Local = dns.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":53").String() 318 dnsArgs.ParentServiceType = dns.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks") 319 dnsArgs.RemoteDNSAddress = dns.Flag("dns-address", "remote dns for resolve doamin").Short('q').Default("8.8.8.8:53").String() 320 dnsArgs.DNSTTL = dns.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int() 321 dnsArgs.ParentAuth = dns.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String() 322 dnsArgs.ParentKey = dns.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String() 323 dnsArgs.ParentCompress = dns.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool() 324 dnsArgs.CacheFile = dns.Flag("cache-file", "dns result cached file").Short('f').Default(filepath.Join(path.Dir(os.Args[0]), "cache.dat")).String() 325 dnsArgs.LocalSocks5Port = dns.Flag("socks-port", "local socks5 port").Short('s').Default("65501").String() 326 327 //########keygen######### 328 keygen := app.Command("keygen", "create certificate for proxy") 329 keygenArgs.CommonName = keygen.Flag("cn", "common name").Short('n').Default("").String() 330 keygenArgs.CaName = keygen.Flag("ca", "ca name").Short('C').Default("").String() 331 keygenArgs.CertName = keygen.Flag("cert", "cert name of sign to create").Short('c').Default("").String() 332 keygenArgs.SignDays = keygen.Flag("days", "days of sign").Short('d').Default("365").Int() 333 keygenArgs.Sign = keygen.Flag("sign", "cert is to signin").Short('s').Default("false").Bool() 334 335 //parse args 336 serviceName := kingpin.MustParse(app.Parse(os.Args[1:])) 337 338 //set kcp config 339 340 switch *kcpArgs.Mode { 341 case "normal": 342 *kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 0, 40, 2, 1 343 case "fast": 344 *kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 0, 30, 2, 1 345 case "fast2": 346 *kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 1, 20, 2, 1 347 case "fast3": 348 *kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 1, 10, 2, 1 349 } 350 pass := pbkdf2.Key([]byte(*kcpArgs.Key), []byte("snail007-goproxy"), 4096, 32, sha1.New) 351 352 switch *kcpArgs.Crypt { 353 case "sm4": 354 kcpArgs.Block, _ = kcp.NewSM4BlockCrypt(pass[:16]) 355 case "tea": 356 kcpArgs.Block, _ = kcp.NewTEABlockCrypt(pass[:16]) 357 case "xor": 358 kcpArgs.Block, _ = kcp.NewSimpleXORBlockCrypt(pass) 359 case "none": 360 kcpArgs.Block, _ = kcp.NewNoneBlockCrypt(pass) 361 case "aes-128": 362 kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass[:16]) 363 case "aes-192": 364 kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass[:24]) 365 case "blowfish": 366 kcpArgs.Block, _ = kcp.NewBlowfishBlockCrypt(pass) 367 case "twofish": 368 kcpArgs.Block, _ = kcp.NewTwofishBlockCrypt(pass) 369 case "cast5": 370 kcpArgs.Block, _ = kcp.NewCast5BlockCrypt(pass[:16]) 371 case "3des": 372 kcpArgs.Block, _ = kcp.NewTripleDESBlockCrypt(pass[:24]) 373 case "xtea": 374 kcpArgs.Block, _ = kcp.NewXTEABlockCrypt(pass[:16]) 375 case "salsa20": 376 kcpArgs.Block, _ = kcp.NewSalsa20BlockCrypt(pass) 377 default: 378 *kcpArgs.Crypt = "aes" 379 kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass) 380 } 381 //attach kcp config 382 tcpArgs.KCP = kcpArgs 383 httpArgs.KCP = kcpArgs 384 socksArgs.KCP = kcpArgs 385 spsArgs.KCP = kcpArgs 386 muxBridgeArgs.KCP = kcpArgs 387 muxServerArgs.KCP = kcpArgs 388 muxClientArgs.KCP = kcpArgs 389 dnsArgs.KCP = kcpArgs 390 391 log := logger.New(os.Stderr, "", logger.Ldate|logger.Ltime) 392 393 flags := logger.Ldate 394 if *isDebug { 395 flags |= logger.Lshortfile | logger.Lmicroseconds 396 cpuProfilingFile, _ = os.Create("cpu.prof") 397 memProfilingFile, _ = os.Create("memory.prof") 398 blockProfilingFile, _ = os.Create("block.prof") 399 goroutineProfilingFile, _ = os.Create("goroutine.prof") 400 threadcreateProfilingFile, _ = os.Create("threadcreate.prof") 401 pprof.StartCPUProfile(cpuProfilingFile) 402 } else { 403 flags |= logger.Ltime 404 } 405 log.SetFlags(flags) 406 if *nolog { 407 log.SetOutput(ioutil.Discard) 408 } else if *logfile != "" { 409 f, e := os.OpenFile(*logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) 410 if e != nil { 411 log.Fatal(e) 412 } 413 log.SetOutput(f) 414 } 415 if *daemon { 416 args := []string{} 417 for _, arg := range os.Args[1:] { 418 if arg != "--daemon" { 419 args = append(args, arg) 420 } 421 } 422 cmd = exec.Command(os.Args[0], args...) 423 cmd.Start() 424 f := "" 425 if *forever { 426 f = "forever " 427 } 428 log.Printf("%s%s [PID] %d running...\n", f, os.Args[0], cmd.Process.Pid) 429 os.Exit(0) 430 } 431 if *forever { 432 args := []string{} 433 for _, arg := range os.Args[1:] { 434 if arg != "--forever" { 435 args = append(args, arg) 436 } 437 } 438 go func() { 439 defer func() { 440 if e := recover(); e != nil { 441 fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) 442 } 443 }() 444 for { 445 if cmd != nil { 446 cmd.Process.Kill() 447 time.Sleep(time.Second * 5) 448 } 449 cmd = exec.Command(os.Args[0], args...) 450 cmdReaderStderr, err := cmd.StderrPipe() 451 if err != nil { 452 log.Printf("ERR:%s,restarting...\n", err) 453 continue 454 } 455 cmdReader, err := cmd.StdoutPipe() 456 if err != nil { 457 log.Printf("ERR:%s,restarting...\n", err) 458 continue 459 } 460 scanner := bufio.NewScanner(cmdReader) 461 scannerStdErr := bufio.NewScanner(cmdReaderStderr) 462 go func() { 463 defer func() { 464 if e := recover(); e != nil { 465 fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) 466 } 467 }() 468 for scanner.Scan() { 469 fmt.Println(scanner.Text()) 470 } 471 }() 472 go func() { 473 defer func() { 474 if e := recover(); e != nil { 475 fmt.Printf("crashed, err: %s\nstack:%s", e, string(debug.Stack())) 476 } 477 }() 478 for scannerStdErr.Scan() { 479 fmt.Println(scannerStdErr.Text()) 480 } 481 }() 482 if err := cmd.Start(); err != nil { 483 log.Printf("ERR:%s,restarting...\n", err) 484 continue 485 } 486 pid := cmd.Process.Pid 487 log.Printf("worker %s [PID] %d running...\n", os.Args[0], pid) 488 if err := cmd.Wait(); err != nil { 489 log.Printf("ERR:%s,restarting...", err) 490 continue 491 } 492 log.Printf("worker %s [PID] %d unexpected exited, restarting...\n", os.Args[0], pid) 493 } 494 }() 495 return 496 } 497 if *logfile == "" { 498 poster() 499 if *isDebug { 500 log.Println("[profiling] cpu profiling save to file : cpu.prof") 501 log.Println("[profiling] memory profiling save to file : memory.prof") 502 log.Println("[profiling] block profiling save to file : block.prof") 503 log.Println("[profiling] goroutine profiling save to file : goroutine.prof") 504 log.Println("[profiling] threadcreate profiling save to file : threadcreate.prof") 505 } 506 } 507 508 //regist services and run service 509 switch serviceName { 510 case "http": 511 services.Regist(serviceName, httpx.NewHTTP(), httpArgs, log) 512 case "tcp": 513 services.Regist(serviceName, tcpx.NewTCP(), tcpArgs, log) 514 case "udp": 515 services.Regist(serviceName, udpx.NewUDP(), udpArgs, log) 516 case "tserver": 517 services.Regist(serviceName, tunnelx.NewTunnelServerManager(), tunnelServerArgs, log) 518 case "tclient": 519 services.Regist(serviceName, tunnelx.NewTunnelClient(), tunnelClientArgs, log) 520 case "tbridge": 521 services.Regist(serviceName, tunnelx.NewTunnelBridge(), tunnelBridgeArgs, log) 522 case "server": 523 services.Regist(serviceName, mux.NewMuxServerManager(), muxServerArgs, log) 524 case "client": 525 services.Regist(serviceName, mux.NewMuxClient(), muxClientArgs, log) 526 case "bridge": 527 services.Regist(serviceName, mux.NewMuxBridge(), muxBridgeArgs, log) 528 case "socks": 529 services.Regist(serviceName, socksx.NewSocks(), socksArgs, log) 530 case "sps": 531 services.Regist(serviceName, spsx.NewSPS(), spsArgs, log) 532 case "dns": 533 services.Regist(serviceName, sdk.NewDNS(), dnsArgs, log) 534 case "keygen": 535 services.Regist(serviceName, keygenx.NewKeygen(), keygenArgs, log) 536 } 537 service, err = services.Run(serviceName, nil) 538 if err != nil { 539 log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err) 540 } 541 return 542 } 543 544 func poster() { 545 fmt.Printf(`Proxy Enterprise Version v%s`+" by snail , blog : http://www.host900.com/\n\n", APP_VERSION) 546 } 547 func saveProfiling() { 548 goroutine := pprof.Lookup("goroutine") 549 goroutine.WriteTo(goroutineProfilingFile, 1) 550 heap := pprof.Lookup("heap") 551 heap.WriteTo(memProfilingFile, 1) 552 block := pprof.Lookup("block") 553 block.WriteTo(blockProfilingFile, 1) 554 threadcreate := pprof.Lookup("threadcreate") 555 threadcreate.WriteTo(threadcreateProfilingFile, 1) 556 pprof.StopCPUProfile() 557 }