socks5.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package proxy
  2. import (
  3. "encoding/binary"
  4. "errors"
  5. "github.com/cnlh/nps/bridge"
  6. "github.com/cnlh/nps/lib/common"
  7. "github.com/cnlh/nps/lib/conn"
  8. "github.com/cnlh/nps/lib/file"
  9. "github.com/cnlh/nps/lib/lg"
  10. "io"
  11. "net"
  12. "strconv"
  13. "strings"
  14. )
  15. const (
  16. ipV4 = 1
  17. domainName = 3
  18. ipV6 = 4
  19. connectMethod = 1
  20. bindMethod = 2
  21. associateMethod = 3
  22. // The maximum packet size of any udp Associate packet, based on ethernet's max size,
  23. // minus the IP and UDP headers. IPv4 has a 20 byte header, UDP adds an
  24. // additional 4 bytes. This is a total overhead of 24 bytes. Ethernet's
  25. // max packet size is 1500 bytes, 1500 - 24 = 1476.
  26. maxUDPPacketSize = 1476
  27. )
  28. const (
  29. succeeded uint8 = iota
  30. serverFailure
  31. notAllowed
  32. networkUnreachable
  33. hostUnreachable
  34. connectionRefused
  35. ttlExpired
  36. commandNotSupported
  37. addrTypeNotSupported
  38. )
  39. const (
  40. UserPassAuth = uint8(2)
  41. userAuthVersion = uint8(1)
  42. authSuccess = uint8(0)
  43. authFailure = uint8(1)
  44. )
  45. type Sock5ModeServer struct {
  46. server
  47. listener net.Listener
  48. }
  49. //req
  50. func (s *Sock5ModeServer) handleRequest(c net.Conn) {
  51. /*
  52. The SOCKS request is formed as follows:
  53. +----+-----+-------+------+----------+----------+
  54. |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
  55. +----+-----+-------+------+----------+----------+
  56. | 1 | 1 | X'00' | 1 | Variable | 2 |
  57. +----+-----+-------+------+----------+----------+
  58. */
  59. header := make([]byte, 3)
  60. _, err := io.ReadFull(c, header)
  61. if err != nil {
  62. lg.Println("illegal request", err)
  63. c.Close()
  64. return
  65. }
  66. switch header[1] {
  67. case connectMethod:
  68. s.handleConnect(c)
  69. case bindMethod:
  70. s.handleBind(c)
  71. case associateMethod:
  72. s.handleUDP(c)
  73. default:
  74. s.sendReply(c, commandNotSupported)
  75. c.Close()
  76. }
  77. }
  78. //reply
  79. func (s *Sock5ModeServer) sendReply(c net.Conn, rep uint8) {
  80. reply := []byte{
  81. 5,
  82. rep,
  83. 0,
  84. 1,
  85. }
  86. localAddr := c.LocalAddr().String()
  87. localHost, localPort, _ := net.SplitHostPort(localAddr)
  88. ipBytes := net.ParseIP(localHost).To4()
  89. nPort, _ := strconv.Atoi(localPort)
  90. reply = append(reply, ipBytes...)
  91. portBytes := make([]byte, 2)
  92. binary.BigEndian.PutUint16(portBytes, uint16(nPort))
  93. reply = append(reply, portBytes...)
  94. c.Write(reply)
  95. }
  96. //do conn
  97. func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) {
  98. addrType := make([]byte, 1)
  99. c.Read(addrType)
  100. var host string
  101. switch addrType[0] {
  102. case ipV4:
  103. ipv4 := make(net.IP, net.IPv4len)
  104. c.Read(ipv4)
  105. host = ipv4.String()
  106. case ipV6:
  107. ipv6 := make(net.IP, net.IPv6len)
  108. c.Read(ipv6)
  109. host = ipv6.String()
  110. case domainName:
  111. var domainLen uint8
  112. binary.Read(c, binary.BigEndian, &domainLen)
  113. domain := make([]byte, domainLen)
  114. c.Read(domain)
  115. host = string(domain)
  116. default:
  117. s.sendReply(c, addrTypeNotSupported)
  118. return
  119. }
  120. var port uint16
  121. binary.Read(c, binary.BigEndian, &port)
  122. // connect to host
  123. addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
  124. var ltype string
  125. if command == associateMethod {
  126. ltype = common.CONN_UDP
  127. } else {
  128. ltype = common.CONN_TCP
  129. }
  130. link := conn.NewLink(s.task.Client.GetId(), ltype, addr, s.task.Client.Cnf.CompressEncode, s.task.Client.Cnf.CompressDecode, s.task.Client.Cnf.Crypt, conn.NewConn(c), s.task.Flow, nil, s.task.Client.Rate, nil)
  131. if tunnel, err := s.bridge.SendLinkInfo(s.task.Client.Id, link, c.RemoteAddr().String()); err != nil {
  132. c.Close()
  133. return
  134. } else {
  135. s.sendReply(c, succeeded)
  136. s.linkCopy(link, conn.NewConn(c), nil, tunnel, s.task.Flow)
  137. }
  138. return
  139. }
  140. //conn
  141. func (s *Sock5ModeServer) handleConnect(c net.Conn) {
  142. s.doConnect(c, connectMethod)
  143. }
  144. // passive mode
  145. func (s *Sock5ModeServer) handleBind(c net.Conn) {
  146. }
  147. //udp
  148. func (s *Sock5ModeServer) handleUDP(c net.Conn) {
  149. lg.Println("UDP Associate")
  150. /*
  151. +----+------+------+----------+----------+----------+
  152. |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
  153. +----+------+------+----------+----------+----------+
  154. | 2 | 1 | 1 | Variable | 2 | Variable |
  155. +----+------+------+----------+----------+----------+
  156. */
  157. buf := make([]byte, 3)
  158. c.Read(buf)
  159. // relay udp datagram silently, without any notification to the requesting client
  160. if buf[2] != 0 {
  161. // does not support fragmentation, drop it
  162. lg.Println("does not support fragmentation, drop")
  163. dummy := make([]byte, maxUDPPacketSize)
  164. c.Read(dummy)
  165. }
  166. s.doConnect(c, associateMethod)
  167. }
  168. //new conn
  169. func (s *Sock5ModeServer) handleConn(c net.Conn) {
  170. buf := make([]byte, 2)
  171. if _, err := io.ReadFull(c, buf); err != nil {
  172. lg.Println("negotiation err", err)
  173. c.Close()
  174. return
  175. }
  176. if version := buf[0]; version != 5 {
  177. lg.Println("only support socks5, request from: ", c.RemoteAddr())
  178. c.Close()
  179. return
  180. }
  181. nMethods := buf[1]
  182. methods := make([]byte, nMethods)
  183. if len, err := c.Read(methods); len != int(nMethods) || err != nil {
  184. lg.Println("wrong method")
  185. c.Close()
  186. return
  187. }
  188. if s.task.Client.Cnf.U != "" && s.task.Client.Cnf.P != "" {
  189. buf[1] = UserPassAuth
  190. c.Write(buf)
  191. if err := s.Auth(c); err != nil {
  192. c.Close()
  193. lg.Println("Validation failed:", err)
  194. return
  195. }
  196. } else {
  197. buf[1] = 0
  198. c.Write(buf)
  199. }
  200. s.handleRequest(c)
  201. }
  202. //socks5 auth
  203. func (s *Sock5ModeServer) Auth(c net.Conn) error {
  204. header := []byte{0, 0}
  205. if _, err := io.ReadAtLeast(c, header, 2); err != nil {
  206. return err
  207. }
  208. if header[0] != userAuthVersion {
  209. return errors.New("验证方式不被支持")
  210. }
  211. userLen := int(header[1])
  212. user := make([]byte, userLen)
  213. if _, err := io.ReadAtLeast(c, user, userLen); err != nil {
  214. return err
  215. }
  216. if _, err := c.Read(header[:1]); err != nil {
  217. return errors.New("密码长度获取错误")
  218. }
  219. passLen := int(header[0])
  220. pass := make([]byte, passLen)
  221. if _, err := io.ReadAtLeast(c, pass, passLen); err != nil {
  222. return err
  223. }
  224. if string(user) == s.task.Client.Cnf.U && string(pass) == s.task.Client.Cnf.P {
  225. if _, err := c.Write([]byte{userAuthVersion, authSuccess}); err != nil {
  226. return err
  227. }
  228. return nil
  229. } else {
  230. if _, err := c.Write([]byte{userAuthVersion, authFailure}); err != nil {
  231. return err
  232. }
  233. return errors.New("验证不通过")
  234. }
  235. }
  236. //start
  237. func (s *Sock5ModeServer) Start() error {
  238. var err error
  239. s.listener, err = net.Listen("tcp", ":"+strconv.Itoa(s.task.Port))
  240. if err != nil {
  241. return err
  242. }
  243. for {
  244. conn, err := s.listener.Accept()
  245. if err != nil {
  246. if strings.Contains(err.Error(), "use of closed network connection") {
  247. break
  248. }
  249. lg.Fatalln("accept error: ", err)
  250. }
  251. go s.handleConn(conn)
  252. }
  253. return nil
  254. }
  255. //close
  256. func (s *Sock5ModeServer) Close() error {
  257. return s.listener.Close()
  258. }
  259. //new
  260. func NewSock5ModeServer(bridge *bridge.Bridge, task *file.Tunnel) *Sock5ModeServer {
  261. s := new(Sock5ModeServer)
  262. s.bridge = bridge
  263. s.task = task
  264. return s
  265. }