shadowsocks.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * Copyright (c) 2024, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package server
  20. import (
  21. "bytes"
  22. "fmt"
  23. "io"
  24. "net"
  25. "github.com/Jigsaw-Code/outline-sdk/transport"
  26. "github.com/Jigsaw-Code/outline-sdk/transport/shadowsocks"
  27. "github.com/Jigsaw-Code/outline-ss-server/service"
  28. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  29. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  30. )
  31. // ShadowsocksServer tunnels TCP traffic (in the case of Psiphon, SSH traffic)
  32. // over Shadowsocks.
  33. type ShadowsocksServer struct {
  34. support *SupportServices
  35. listener net.Listener
  36. key *shadowsocks.EncryptionKey
  37. saltGenerator service.ServerSaltGenerator
  38. replayCache service.ReplayCache
  39. irregularTunnelLogger func(string, error, common.LogFields)
  40. }
  41. // ListenShadowsocks returns the listener of a new ShadowsocksServer.
  42. func ListenShadowsocks(
  43. support *SupportServices,
  44. listener net.Listener,
  45. ssEncryptionKey string,
  46. irregularTunnelLogger func(string, error, common.LogFields),
  47. ) (net.Listener, error) {
  48. server, err := NewShadowsocksServer(support, listener, ssEncryptionKey, irregularTunnelLogger)
  49. if err != nil {
  50. return nil, errors.Trace(err)
  51. }
  52. return NewShadowsocksListener(listener, server), nil
  53. }
  54. // NewShadowsocksServer initializes a new ShadowsocksServer.
  55. func NewShadowsocksServer(
  56. support *SupportServices,
  57. listener net.Listener,
  58. ssEncryptionKey string,
  59. irregularTunnelLogger func(string, error, common.LogFields)) (*ShadowsocksServer, error) {
  60. // Note: client must use the same cipher.
  61. key, err := shadowsocks.NewEncryptionKey(shadowsocks.CHACHA20IETFPOLY1305, ssEncryptionKey)
  62. if err != nil {
  63. return nil, errors.TraceMsg(err, "shadowsocks.NewEncryptionKey failed")
  64. }
  65. // Note: see comment for service.MaxCapacity for a description of
  66. // the expected false positive rate.
  67. replayHistory := service.MaxCapacity
  68. shadowsocksServer := &ShadowsocksServer{
  69. support: support,
  70. listener: listener,
  71. key: key,
  72. saltGenerator: service.NewServerSaltGenerator(ssEncryptionKey),
  73. replayCache: service.NewReplayCache(replayHistory),
  74. irregularTunnelLogger: irregularTunnelLogger,
  75. }
  76. return shadowsocksServer, nil
  77. }
  78. // ShadowsocksListener implements the net.Listener interface. Accept returns a
  79. // net.Conn which implements the common.MetricsSource interface.
  80. type ShadowsocksListener struct {
  81. net.Listener
  82. server *ShadowsocksServer
  83. }
  84. // NewShadowsocksListener initializes a new ShadowsocksListener.
  85. func NewShadowsocksListener(listener net.Listener, server *ShadowsocksServer) *ShadowsocksListener {
  86. return &ShadowsocksListener{
  87. Listener: listener,
  88. server: server,
  89. }
  90. }
  91. func (l *ShadowsocksListener) Accept() (net.Conn, error) {
  92. conn, err := l.Listener.Accept()
  93. if err != nil {
  94. return nil, errors.Trace(err)
  95. }
  96. salt, reader, err := l.readSalt(conn)
  97. if err != nil {
  98. return nil, errors.TraceMsg(err, "failed to read salt")
  99. }
  100. // TODO: code mostly copied from [1]; use NewShadowsocksStreamAuthenticator instead?
  101. //
  102. // [1] https://github.com/Jigsaw-Code/outline-ss-server/blob/fa651d3e87cc0a94104babb3ae85253471a22ebc/service/tcp.go#L138
  103. // Hardcode key ID because all clients use the same cipher per server,
  104. // which is fine because the underlying SSH connection protects the
  105. // confidentiality and integrity of client traffic between the client and
  106. // server.
  107. keyID := "1"
  108. isServerSalt := l.server.saltGenerator.IsServerSalt(salt)
  109. if isServerSalt || !l.server.replayCache.Add(keyID, salt) {
  110. go drainConn(conn)
  111. var err error
  112. if isServerSalt {
  113. err = errors.TraceNew("server replay detected")
  114. } else {
  115. err = errors.TraceNew("client replay detected")
  116. }
  117. l.server.irregularTunnelLogger(conn.RemoteAddr().String(), err, nil)
  118. return nil, err
  119. }
  120. ssr := shadowsocks.NewReader(reader, l.server.key)
  121. ssw := shadowsocks.NewWriter(conn, l.server.key)
  122. ssw.SetSaltGenerator(l.server.saltGenerator)
  123. ssClientConn := transport.WrapConn(conn.(*net.TCPConn), ssr, ssw)
  124. return NewShadowsocksConn(ssClientConn), nil
  125. }
  126. func drainConn(conn net.Conn) {
  127. _, _ = io.Copy(io.Discard, conn)
  128. conn.Close()
  129. }
  130. func (l *ShadowsocksListener) readSalt(conn net.Conn) ([]byte, io.Reader, error) {
  131. type result struct {
  132. salt []byte
  133. err error
  134. }
  135. resultChannel := make(chan result)
  136. go func() {
  137. saltSize := l.server.key.SaltSize()
  138. salt := make([]byte, saltSize)
  139. if n, err := io.ReadFull(conn, salt); err != nil {
  140. resultChannel <- result{
  141. err: fmt.Errorf("reading conn failed after %d bytes: %w", n, err),
  142. }
  143. return
  144. }
  145. resultChannel <- result{
  146. salt: salt,
  147. }
  148. }()
  149. select {
  150. case result := <-resultChannel:
  151. if result.err != nil {
  152. return nil, nil, result.err
  153. }
  154. return result.salt, io.MultiReader(bytes.NewReader(result.salt), conn), nil
  155. case <-l.server.support.TunnelServer.shutdownBroadcast:
  156. return nil, nil, errors.TraceNew("shutdown broadcast")
  157. }
  158. }
  159. // ShadowsocksConn implements the net.Conn and common.MetricsSource interfaces.
  160. type ShadowsocksConn struct {
  161. net.Conn
  162. }
  163. // NewShadowsocksConn initializes a new NewShadowsocksConn.
  164. func NewShadowsocksConn(conn net.Conn) *ShadowsocksConn {
  165. return &ShadowsocksConn{
  166. Conn: conn,
  167. }
  168. }
  169. func (conn *ShadowsocksConn) Read(b []byte) (int, error) {
  170. return conn.Conn.Read(b)
  171. }
  172. // GetMetrics implements the common.MetricsSource interface.
  173. func (conn *ShadowsocksConn) GetMetrics() common.LogFields {
  174. var logFields common.LogFields
  175. // Relay any metrics from the underlying conn.
  176. if m, ok := conn.Conn.(common.MetricsSource); ok {
  177. logFields = m.GetMetrics()
  178. } else {
  179. logFields = make(common.LogFields)
  180. }
  181. return logFields
  182. }