func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) { switch method { case MethodTLS: var cert tls.Certificate var err error if len(CertFile) == 0 || len(KeyFile) == 0 { cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey)) } else { cert, err = tls.LoadX509KeyPair(CertFile, KeyFile) } if err != nil { return nil, err } conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}}) if err := svrTLSAuth(conn); err != nil { return nil, err } case MethodAES128, MethodAES192, MethodAES256, MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable: cipher, err := shadowsocks.NewCipher(Methods[method], Password) if err != nil { return nil, err } conn = shadowsocks.NewConn(conn, cipher) case gosocks5.MethodNoAcceptable: return nil, gosocks5.ErrBadMethod } return conn, nil }
func handleShadow(conn net.Conn, arg Args) { if arg.User != nil { method := arg.User.Username() password, _ := arg.User.Password() cipher, err := shadowsocks.NewCipher(method, password) if err != nil { glog.V(LWARNING).Infoln("shadowsocks:", err) return } conn = shadowsocks.NewConn(conn, cipher) } addr, extra, err := getShadowRequest(conn) if err != nil { glog.V(LWARNING).Infoln("shadowsocks:", err) return } glog.V(LINFO).Infoln("shadowsocks connect:", addr.String()) sconn, err := Connect(addr.String()) if err != nil { glog.V(LWARNING).Infoln("shadowsocks:", err) return } defer sconn.Close() if extra != nil { if _, err := sconn.Write(extra); err != nil { glog.V(LWARNING).Infoln("shadowsocks:", err) return } } Transport(conn, sconn) }
func runWithCustomMethod(user user.User) { // port, password string, Cipher *ss.Cipher port := strconv.Itoa(user.GetPort()) password := user.GetPasswd() ln, err := net.Listen("tcp", ":"+port) if err != nil { Log.Error(fmt.Sprintf("error listening port %v: %v\n", port, err)) os.Exit(1) } passwdManager.add(port, password, ln) cipher, err := user.GetCipher() if err != nil { return } Log.Info(fmt.Sprintf("server listening port %v ...\n", port)) for { conn, err := ln.Accept() if err != nil { // listener maybe closed to update password Log.Debug(fmt.Sprintf("accept error: %v\n", err)) return } // Creating cipher upon first connection. if cipher == nil { Log.Debug("creating cipher for port:", port) cipher, err = ss.NewCipher(user.GetMethod(), password) if err != nil { Log.Error(fmt.Sprintf("Error generating cipher for port: %s %v\n", port, err)) conn.Close() continue } } go handleConnection(user, ss.NewConn(conn, cipher.Copy())) } }
func (cp *meowProxy) Serve(wg *sync.WaitGroup) { defer func() { wg.Done() }() ln, err := net.Listen("tcp", cp.addr) if err != nil { fmt.Println("listen meow failed:", err) return } info.Printf("meow proxy address %s\n", cp.addr) for { conn, err := ln.Accept() if err != nil { errl.Printf("meow proxy(%s) accept %v\n", ln.Addr(), err) if isErrTooManyOpenFd(err) { connPool.CloseAll() } time.Sleep(time.Millisecond) continue } ssConn := ss.NewConn(conn, cp.cipher.Copy()) c := newClientConn(ssConn, cp) go c.serve() } }
func run(port, password string) { ln, err := net.Listen("tcp", ":"+port) if err != nil { log.Printf("error listening port %v: %v\n", port, err) return } passwdManager.add(port, password, ln) var cipher *ss.Cipher log.Printf("server listening port %v ...\n", port) for { conn, err := ln.Accept() if err != nil { // listener maybe closed to update password debug.Printf("accept error: %v\n", err) return } // Creating cipher upon first connection. if cipher == nil { log.Println("creating cipher for port:", port) cipher, err = ss.NewCipher(config.Method, password) if err != nil { log.Printf("Error generating cipher for port: %s %v\n", port, err) conn.Close() continue } } go handleConnection(ss.NewConn(conn, cipher.Copy())) } }
func clientMethodSelected(method uint8, conn net.Conn) (net.Conn, error) { switch method { case gosocks5.MethodUserPass: user, pass := parseUserPass(Password) if err := clientSocksAuth(conn, user, pass); err != nil { return nil, err } case MethodTLS, MethodTLSAuth: conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true}) if method == MethodTLSAuth { if len(Password) == 0 { return nil, ErrEmptyAuth } if err := clientSocksAuth(conn, "", Password); err != nil { return nil, err } } case MethodAES128, MethodAES192, MethodAES256, MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable: cipher, err := shadowsocks.NewCipher(Methods[method], Password) if err != nil { log.Println(err) return nil, err } conn = shadowsocks.NewConn(conn, cipher) case gosocks5.MethodNoAcceptable: return nil, gosocks5.ErrBadMethod } return conn, nil }
func forward(conn net.Conn, arg Args) (net.Conn, error) { var err error if glog.V(LINFO) { proto := arg.Protocol if proto == "default" { proto = "http" // default is http } glog.Infof("forward: %s/%s %s", proto, arg.Transport, arg.Addr) } switch arg.Transport { case "ws": // websocket connection conn, err = wsClient(conn, arg.Addr) if err != nil { return nil, err } case "tls": // tls connection conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true}) case "tcp": fallthrough default: } switch arg.Protocol { case "socks", "socks5": selector := &clientSelector{ methods: []uint8{ gosocks5.MethodNoAuth, gosocks5.MethodUserPass, MethodTLS, }, arg: arg, } c := gosocks5.ClientConn(conn, selector) if err := c.Handleshake(); err != nil { return nil, err } conn = c case "ss": // shadowsocks if arg.User != nil { method := arg.User.Username() password, _ := arg.User.Password() cipher, err := shadowsocks.NewCipher(method, password) if err != nil { return nil, err } conn = shadowsocks.NewConn(conn, cipher) } case "http": fallthrough default: } return conn, nil }
func (cp *cowParent) connect(url *URL) (net.Conn, error) { c, err := net.Dial("tcp", cp.server) if err != nil { errl.Printf("can't connect to cow parent %s for %s: %v\n", cp.server, url.HostPort, err) return nil, err } debug.Printf("connected to: %s via cow parent: %s\n", url.HostPort, cp.server) ssconn := ss.NewConn(c, cp.cipher.Copy()) return cowConn{ssconn, cp}, nil }
func (s *ProxyServer) newClient(conn net.Conn) { conn.SetReadDeadline(time.Now().Add(s.config.Timeout * time.Second)) client := &client{ Conn: ss.NewConn(conn, s.Cip.Copy()), server: s, } go client.listen() s.CallbackMethods.NewClient(client) }
func runWithCustomMethod(user user.User) { // port, password string, Cipher *ss.Cipher port := strconv.Itoa(user.GetPort()) // 检测端口是否已存在 _, ok := passwdManager.get(port) // 如果存在 if ok { return } password := user.GetPasswd() ln, err := net.Listen("tcp", ":"+port) if err != nil { Log.Error(fmt.Sprintf("error listening port %v: %v\n", port, err)) // os.Exit(1) return } passwdManager.add(port, password, ln) cipher, err, auth := user.GetCipher() if err != nil { return } Log.Info(fmt.Sprintf("server listening port %v ...\n", port)) for { conn, err := ln.Accept() if err != nil { // listener maybe closed to update password Log.Debug(fmt.Sprintf("accept error: %v\n", err)) return } // Creating cipher upon first connection. if cipher == nil { Log.Debug("creating cipher for port:", port) method := user.GetMethod() if strings.HasSuffix(method, "-auth") { method = method[:len(method)-5] auth = true } else { auth = false } cipher, err = ss.NewCipher(method, password) if err != nil { Log.Error(fmt.Sprintf("Error generating cipher for port: %s %v\n", port, err)) conn.Close() continue } } go handleConnection(user, ss.NewConn(conn, cipher.Copy()), auth) } }
func serverMethodSelected(method uint8, conn net.Conn) (net.Conn, error) { //log.Println(method) switch method { case gosocks5.MethodUserPass: var username, password string if listenUrl != nil && listenUrl.User != nil { username = listenUrl.User.Username() password, _ = listenUrl.User.Password() } if err := serverSocksAuth(conn, username, password); err != nil { return nil, err } case MethodTLS, MethodTLSAuth: var cert tls.Certificate var err error if len(CertFile) == 0 || len(KeyFile) == 0 { cert, err = tls.X509KeyPair([]byte(rawCert), []byte(rawKey)) } else { cert, err = tls.LoadX509KeyPair(CertFile, KeyFile) } if err != nil { return nil, err } conn = tls.Server(conn, &tls.Config{Certificates: []tls.Certificate{cert}}) if method == MethodTLSAuth { // password is mandatory if len(Password) == 0 { return nil, ErrEmptyAuth } if err := serverSocksAuth(conn, "", Password); err != nil { return nil, err } } case MethodAES128, MethodAES192, MethodAES256, MethodDES, MethodBF, MethodCAST5, MethodRC4MD5, MethodRC4, MethodTable: cipher, err := shadowsocks.NewCipher(Methods[method], Password) if err != nil { return nil, err } conn = shadowsocks.NewConn(conn, cipher) case gosocks5.MethodNoAcceptable: return nil, gosocks5.ErrBadMethod } return conn, nil }
func run(port, password string) { var addr string var lastTime int64 ln, err := net.Listen("tcp", ":"+port) if err != nil { log.Printf("error listening port %v: %v\n", port, err) return } passwdManager.add(port, password, ln) var cipher *ss.Cipher log.Printf("server listening port %v ...\n", port) for { conn, err := ln.Accept() if err != nil { // listener maybe closed to update password debug.Printf("accept error: %v\n", err) return } newaddr := conn.RemoteAddr().String() nowtime := time.Now().Unix() if addr != newaddr && lastTime >= nowtime { conn.Close() continue } lastTime = nowtime addr = newaddr // Creating cipher upon first connection. if cipher == nil { log.Println("creating cipher for port:", port) cipher, err = ss.NewCipher(config.Method, password) if err != nil { log.Printf("Error generating cipher for port: %s %v\n", port, err) conn.Close() continue } } go handleConnection(ss.NewConn(conn, cipher.Copy())) } }
func run(port, password string) { ln, err := net.Listen("tcp", ":"+port) if err != nil { log.Printf("try listening port %v: %v\n", port, err) return } passwdManager.add(port, password, ln) encTbl := getTable(password) atomic.AddInt32(&table.getCnt, 1) log.Printf("server listening port %v ...\n", port) for { conn, err := ln.Accept() if err != nil { // listener maybe closed to update password debug.Printf("accept error: %v\n", err) return } go handleConnection(ss.NewConn(conn, encTbl)) } }
func cliHandle(conn net.Conn) { defer conn.Close() if Shadows { cipher, _ := shadowsocks.NewCipher(SMethod, SPassword) conn = shadowsocks.NewConn(conn, cipher) handleShadow(conn) return } b := mpool.Take() defer mpool.put(b) n, err := io.ReadAtLeast(conn, b, 2) if err != nil { return } if b[0] == gosocks5.Ver5 { mn := int(b[1]) // methods count length := 2 + mn if n < length { if _, err := io.ReadFull(conn, b[n:length]); err != nil { return } } methods := b[2 : 2+mn] handleSocks5(conn, methods) return } req, err := http.ReadRequest(bufio.NewReader(newReqReader(b[:n], conn))) if err != nil { //log.Println(hex.Dump(b[:n])) log.Println(err) return } handleHttp(req, conn) }
func (cp *cowProxy) Serve(wg *sync.WaitGroup) { defer func() { wg.Done() }() ln, err := net.Listen("tcp", cp.addr) if err != nil { fmt.Println("listen cow failed:", err) return } info.Printf("COW %s cow proxy address %s\n", version, cp.addr) for { conn, err := ln.Accept() if err != nil { errl.Printf("cow proxy(%s) accept %v\n", ln.Addr(), err) continue } ssConn := ss.NewConn(conn, cp.cipher.Copy()) c := newClientConn(ssConn, cp) go c.serve() } }
func run(port string) { ln, err := net.Listen("tcp", ":"+port) if err != nil { log.Printf("error listening port %v: %v\n", port, err) os.Exit(0) } var cipher *ss.Cipher log.Printf("server listening port %v ...\n", port) for { conn, err := ln.Accept() if err != nil { log.Printf("accept error: %v\n", err) continue } user, err := getUser(conn) if err != nil { log.Printf("Error get passeoed: %s %v\n", port, err) conn.Close() continue } size, err := storage.GetSize("flow:" + user.Name) if user.Limit < size { log.Printf("Error user runover: %s\n", size) conn.Close() continue } // log.Println("creating cipher for user:"******"Error generating cipher for user: %s %v\n", user.Name, err) conn.Close() continue } go handleConnection(user, ss.NewConn(conn, cipher.Copy())) } }
func DialWithRawAddr(rawaddr []byte, user User, server string, cipher *ss.Cipher) (remote *ss.Conn, err error) { conn, err := net.Dial("tcp", server) if err != nil { return nil, err } buf := make([]byte, 2) buf[0] = 1 buf[1] = byte(len(user.Name)) if _, err = conn.Write(buf); err != nil { conn.Close() return nil, err } if _, err = conn.Write([]byte(user.Name)); err != nil { conn.Close() return nil, err } remote = ss.NewConn(conn, cipher) if _, err = remote.Write(rawaddr); err != nil { remote.Close() return nil, err } return }
func (cp *cowProxy) Serve(wg *sync.WaitGroup, quit <-chan struct{}) { defer func() { wg.Done() }() ln, err := net.Listen("tcp", cp.addr) if err != nil { fmt.Println("listen cow failed:", err) return } info.Printf("COW %s cow proxy address %s\n", version, cp.addr) var exit bool go func() { <-quit exit = true ln.Close() }() for { conn, err := ln.Accept() if err != nil && !exit { errl.Printf("cow proxy(%s) accept %v\n", ln.Addr(), err) if isErrTooManyOpenFd(err) { connPool.CloseAll() } time.Sleep(time.Millisecond) continue } if exit { debug.Println("exiting cow listner") break } ssConn := ss.NewConn(conn, cp.cipher.Copy()) c := newClientConn(ssConn, cp) go c.serve() } }
func TestSsProxy(t *testing.T) { // 测试域名 testAddr := "www.test123.com:80" testData := []byte("dsgbhdfhgsq36jhrawdxghucn46ggetst") testServerAddr := "127.0.0.1:1458" testMethod := "aes-256-cfb" testPassword := "******" testRawAddr, err := ss.RawAddr(testAddr) if err != nil { t.Fatal(err) } // 简单模拟服务器 cipher, err := ss.NewCipher(testMethod, testPassword) if err != nil { t.Fatal(err) } l, err := net.Listen("tcp", testServerAddr) if err != nil { t.Fatal(err) } defer l.Close() go func() { c, err := l.Accept() if err != nil { t.Fatal(err) } c.SetDeadline(time.Now().Add(5 * time.Second)) sc := ss.NewConn(c, cipher) defer sc.Close() // 读内容并返回 for i := 0; i < 2; i++ { buf := make([]byte, 1024) if n, err := sc.Read(buf); err != nil { t.Fatal("i=", i, "服务器读内容错误:", err) } else { if _, err := sc.Write(buf[:n]); err != nil { t.Fatal(err) } } } }() // 发出请求,然后解密。 p, err := newSsProxyClient(testServerAddr, testMethod, testPassword, nil, nil) if err != nil { t.Fatal(err) } c, err := p.DialTimeout("tcp", testAddr, 1*time.Second) if err != nil { t.Fatal(err) } defer c.Close() // 比较地址是否正确 buf := make([]byte, 1024) if n, err := c.Read(buf); err != nil { t.Fatal("读地址错误:", err) } else { if bytes.Compare(buf[:n], testRawAddr) != 0 { t.Fatal("地址未正确发送") } } // 发送测试数据,并读取比较 if _, err := c.Write(testData); err != nil { t.Fatal(err) } if n, err := c.Read(buf); err != nil { t.Fatal(err) } else { if bytes.Compare(buf[:n], testData) != 0 { t.Fatal("数据未正确发送") } } }
func (s *ProxyServer) handleConn(conn net.Conn) { defer conn.Close() switch s.Node.Protocol { case "ss": // shadowsocks server := NewShadowServer(ss.NewConn(conn, s.cipher.Copy()), s) server.OTA = s.Node.getBool("ota") server.Serve() return case "http": req, err := http.ReadRequest(bufio.NewReader(conn)) if err != nil { glog.V(LWARNING).Infoln("[http]", err) return } NewHttpServer(conn, s).HandleRequest(req) return case "socks", "socks5": conn = gosocks5.ServerConn(conn, s.selector) req, err := gosocks5.ReadRequest(conn) if err != nil { glog.V(LWARNING).Infoln("[socks5]", err) return } NewSocks5Server(conn, s).HandleRequest(req) return } // http or socks5 b := make([]byte, MediumBufferSize) n, err := io.ReadAtLeast(conn, b, 2) if err != nil { glog.V(LWARNING).Infoln(err) return } // TODO: use bufio.Reader if b[0] == gosocks5.Ver5 { mn := int(b[1]) // methods count length := 2 + mn if n < length { if _, err := io.ReadFull(conn, b[n:length]); err != nil { glog.V(LWARNING).Infoln("[socks5]", err) return } } // TODO: use gosocks5.ServerConn methods := b[2 : 2+mn] method := s.selector.Select(methods...) if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil { glog.V(LWARNING).Infoln("[socks5] select:", err) return } c, err := s.selector.OnSelected(method, conn) if err != nil { glog.V(LWARNING).Infoln("[socks5] onselected:", err) return } conn = c req, err := gosocks5.ReadRequest(conn) if err != nil { glog.V(LWARNING).Infoln("[socks5] request:", err) return } NewSocks5Server(conn, s).HandleRequest(req) return } req, err := http.ReadRequest(bufio.NewReader(&reqReader{b: b[:n], r: conn})) if err != nil { glog.V(LWARNING).Infoln("[http]", err) return } NewHttpServer(conn, s).HandleRequest(req) }
func (c *ProxyConn) handshake() error { var tlsUsed bool switch c.Node.Transport { case "ws": // websocket connection u := url.URL{Scheme: "ws", Host: c.Node.Addr, Path: "/ws"} conn, err := WebsocketClientConn(u.String(), c.conn, nil) if err != nil { return err } c.conn = conn case "wss": // websocket security tlsUsed = true u := url.URL{Scheme: "wss", Host: c.Node.Addr, Path: "/ws"} config := &tls.Config{ InsecureSkipVerify: c.Node.insecureSkipVerify(), ServerName: c.Node.serverName, } conn, err := WebsocketClientConn(u.String(), c.conn, config) if err != nil { return err } c.conn = conn case "tls", "http2": // tls connection tlsUsed = true cfg := &tls.Config{ InsecureSkipVerify: c.Node.insecureSkipVerify(), ServerName: c.Node.serverName, } c.conn = tls.Client(c.conn, cfg) case "h2": // same as http2, but just set a flag for later using. tlsUsed = true case "kcp": // kcp connection tlsUsed = true default: } switch c.Node.Protocol { case "socks", "socks5": // socks5 handshake with auth and tls supported selector := &clientSelector{ methods: []uint8{ gosocks5.MethodNoAuth, gosocks5.MethodUserPass, //MethodTLS, }, user: c.Node.User, } if !tlsUsed { // if transport is not security, enable security socks5 selector.methods = append(selector.methods, MethodTLS) selector.tlsConfig = &tls.Config{ InsecureSkipVerify: c.Node.insecureSkipVerify(), ServerName: c.Node.serverName, } } conn := gosocks5.ClientConn(c.conn, selector) if err := conn.Handleshake(); err != nil { return err } c.conn = conn case "ss": // shadowsocks if c.Node.User != nil { method := c.Node.User.Username() password, _ := c.Node.User.Password() cipher, err := shadowsocks.NewCipher(method, password) if err != nil { return err } c.conn = &shadowConn{conn: shadowsocks.NewConn(c.conn, cipher)} } case "http", "http2": fallthrough default: } c.handshaked = true return nil }
func (p *ssProxyClient) DialTCPSAddrTimeout(network string, raddr string, timeout time.Duration) (rconn ProxyTCPConn, rerr error) { // 截止时间 finalDeadline := time.Time{} if timeout != 0 { finalDeadline = time.Now().Add(timeout) } ra, err := ss.RawAddr(raddr) if err != nil { return } c, err := p.upProxy.DialTCPSAddrTimeout(network, p.proxyAddr, timeout) if err != nil { return nil, fmt.Errorf("无法连接代理服务器 %v ,错误:%v", p.proxyAddr, err) } ch := make(chan int) defer close(ch) // 实际执行部分 run := func() { sc := ss.NewConn(c, p.cipher.Copy()) closed := false // 当连接不被使用时,ch<-1会引发异常,这时将关闭连接。 defer func() { e := recover() if e != nil && closed == false { sc.Close() } }() if _, err := sc.Write(ra); err != nil { closed = true sc.Close() rerr = err ch <- 0 return } r := ssTCPConn{TCPConn: c, sc: sc, proxyClient: p} //{c,net.ResolveTCPAddr("tcp","0.0.0.0:0"),net.ResolveTCPAddr("tcp","0.0.0.0:0"),"","",0,0 p} rconn = &r ch <- 1 } if timeout == 0 { go run() select { case <-ch: return } } else { c.SetDeadline(finalDeadline) ntimeout := finalDeadline.Sub(time.Now()) if ntimeout <= 0 { return nil, fmt.Errorf("timeout") } t := time.NewTimer(ntimeout) defer t.Stop() go run() select { case <-t.C: return nil, fmt.Errorf("连接超时。") case <-ch: if rerr == nil { c.SetDeadline(time.Time{}) } return } } }