inbound.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. package naive
  2. import (
  3. "context"
  4. "io"
  5. "math/rand"
  6. "net"
  7. "net/http"
  8. "github.com/sagernet/sing-box/adapter"
  9. "github.com/sagernet/sing-box/adapter/inbound"
  10. "github.com/sagernet/sing-box/common/listener"
  11. "github.com/sagernet/sing-box/common/tls"
  12. "github.com/sagernet/sing-box/common/uot"
  13. C "github.com/sagernet/sing-box/constant"
  14. "github.com/sagernet/sing-box/log"
  15. "github.com/sagernet/sing-box/option"
  16. "github.com/sagernet/sing-box/transport/v2rayhttp"
  17. "github.com/sagernet/sing/common"
  18. "github.com/sagernet/sing/common/auth"
  19. E "github.com/sagernet/sing/common/exceptions"
  20. "github.com/sagernet/sing/common/logger"
  21. M "github.com/sagernet/sing/common/metadata"
  22. N "github.com/sagernet/sing/common/network"
  23. sHttp "github.com/sagernet/sing/protocol/http"
  24. )
  25. var ConfigureHTTP3ListenerFunc func(listener *listener.Listener, handler http.Handler, tlsConfig tls.ServerConfig, logger logger.Logger) (io.Closer, error)
  26. func RegisterInbound(registry *inbound.Registry) {
  27. inbound.Register[option.NaiveInboundOptions](registry, C.TypeNaive, NewInbound)
  28. }
  29. type Inbound struct {
  30. inbound.Adapter
  31. ctx context.Context
  32. router adapter.ConnectionRouterEx
  33. logger logger.ContextLogger
  34. listener *listener.Listener
  35. network []string
  36. networkIsDefault bool
  37. authenticator *auth.Authenticator
  38. tlsConfig tls.ServerConfig
  39. httpServer *http.Server
  40. h3Server io.Closer
  41. }
  42. func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.NaiveInboundOptions) (adapter.Inbound, error) {
  43. inbound := &Inbound{
  44. Adapter: inbound.NewAdapter(C.TypeNaive, tag),
  45. ctx: ctx,
  46. router: uot.NewRouter(router, logger),
  47. listener: listener.New(listener.Options{
  48. Context: ctx,
  49. Logger: logger,
  50. Listen: options.ListenOptions,
  51. }),
  52. networkIsDefault: options.Network == "",
  53. network: options.Network.Build(),
  54. authenticator: auth.NewAuthenticator(options.Users),
  55. }
  56. if common.Contains(inbound.network, N.NetworkUDP) {
  57. if options.TLS == nil || !options.TLS.Enabled {
  58. return nil, E.New("TLS is required for QUIC server")
  59. }
  60. }
  61. if len(options.Users) == 0 {
  62. return nil, E.New("missing users")
  63. }
  64. if options.TLS != nil {
  65. tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
  66. if err != nil {
  67. return nil, err
  68. }
  69. inbound.tlsConfig = tlsConfig
  70. }
  71. return inbound, nil
  72. }
  73. func (n *Inbound) Start() error {
  74. var tlsConfig *tls.STDConfig
  75. if n.tlsConfig != nil {
  76. err := n.tlsConfig.Start()
  77. if err != nil {
  78. return E.Cause(err, "create TLS config")
  79. }
  80. tlsConfig, err = n.tlsConfig.Config()
  81. if err != nil {
  82. return err
  83. }
  84. }
  85. if common.Contains(n.network, N.NetworkTCP) {
  86. tcpListener, err := n.listener.ListenTCP()
  87. if err != nil {
  88. return err
  89. }
  90. n.httpServer = &http.Server{
  91. Handler: n,
  92. TLSConfig: tlsConfig,
  93. BaseContext: func(listener net.Listener) context.Context {
  94. return n.ctx
  95. },
  96. }
  97. go func() {
  98. var sErr error
  99. if tlsConfig != nil {
  100. sErr = n.httpServer.ServeTLS(tcpListener, "", "")
  101. } else {
  102. sErr = n.httpServer.Serve(tcpListener)
  103. }
  104. if sErr != nil && !E.IsClosedOrCanceled(sErr) {
  105. n.logger.Error("http server serve error: ", sErr)
  106. }
  107. }()
  108. }
  109. if common.Contains(n.network, N.NetworkUDP) {
  110. http3Server, err := ConfigureHTTP3ListenerFunc(n.listener, n, n.tlsConfig, n.logger)
  111. if len(n.network) > 1 {
  112. n.logger.Warn(E.Cause(err, "naive http3 disabled"))
  113. } else if err != nil {
  114. return err
  115. } else {
  116. n.h3Server = http3Server
  117. }
  118. }
  119. return nil
  120. }
  121. func (n *Inbound) Close() error {
  122. return common.Close(
  123. &n.listener,
  124. common.PtrOrNil(n.httpServer),
  125. n.h3Server,
  126. n.tlsConfig,
  127. )
  128. }
  129. func (n *Inbound) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
  130. ctx := log.ContextWithNewID(request.Context())
  131. if request.Method != "CONNECT" {
  132. rejectHTTP(writer, http.StatusBadRequest)
  133. n.badRequest(ctx, request, E.New("not CONNECT request"))
  134. return
  135. } else if request.Header.Get("Padding") == "" {
  136. rejectHTTP(writer, http.StatusBadRequest)
  137. n.badRequest(ctx, request, E.New("missing naive padding"))
  138. return
  139. }
  140. userName, password, authOk := sHttp.ParseBasicAuth(request.Header.Get("Proxy-Authorization"))
  141. if authOk {
  142. authOk = n.authenticator.Verify(userName, password)
  143. }
  144. if !authOk {
  145. rejectHTTP(writer, http.StatusProxyAuthRequired)
  146. n.badRequest(ctx, request, E.New("authorization failed"))
  147. return
  148. }
  149. writer.Header().Set("Padding", generateNaivePaddingHeader())
  150. writer.WriteHeader(http.StatusOK)
  151. writer.(http.Flusher).Flush()
  152. hostPort := request.URL.Host
  153. if hostPort == "" {
  154. hostPort = request.Host
  155. }
  156. source := sHttp.SourceAddress(request)
  157. destination := M.ParseSocksaddr(hostPort)
  158. if hijacker, isHijacker := writer.(http.Hijacker); isHijacker {
  159. conn, _, err := hijacker.Hijack()
  160. if err != nil {
  161. n.badRequest(ctx, request, E.New("hijack failed"))
  162. return
  163. }
  164. n.newConnection(ctx, false, &naiveH1Conn{Conn: conn}, userName, source, destination)
  165. } else {
  166. n.newConnection(ctx, true, &naiveH2Conn{reader: request.Body, writer: writer, flusher: writer.(http.Flusher)}, userName, source, destination)
  167. }
  168. }
  169. func (n *Inbound) newConnection(ctx context.Context, waitForClose bool, conn net.Conn, userName string, source M.Socksaddr, destination M.Socksaddr) {
  170. if userName != "" {
  171. n.logger.InfoContext(ctx, "[", userName, "] inbound connection from ", source)
  172. n.logger.InfoContext(ctx, "[", userName, "] inbound connection to ", destination)
  173. } else {
  174. n.logger.InfoContext(ctx, "inbound connection from ", source)
  175. n.logger.InfoContext(ctx, "inbound connection to ", destination)
  176. }
  177. var metadata adapter.InboundContext
  178. metadata.Inbound = n.Tag()
  179. metadata.InboundType = n.Type()
  180. metadata.InboundDetour = n.listener.ListenOptions().Detour
  181. metadata.InboundOptions = n.listener.ListenOptions().InboundOptions
  182. metadata.Source = source
  183. metadata.Destination = destination
  184. metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
  185. metadata.User = userName
  186. if !waitForClose {
  187. n.router.RouteConnectionEx(ctx, conn, metadata, nil)
  188. } else {
  189. done := make(chan struct{})
  190. wrapper := v2rayhttp.NewHTTP2Wrapper(conn)
  191. n.router.RouteConnectionEx(ctx, conn, metadata, N.OnceClose(func(it error) {
  192. close(done)
  193. }))
  194. <-done
  195. wrapper.CloseWrapper()
  196. }
  197. }
  198. func (n *Inbound) badRequest(ctx context.Context, request *http.Request, err error) {
  199. n.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", request.RemoteAddr))
  200. }
  201. func rejectHTTP(writer http.ResponseWriter, statusCode int) {
  202. hijacker, ok := writer.(http.Hijacker)
  203. if !ok {
  204. writer.WriteHeader(statusCode)
  205. return
  206. }
  207. conn, _, err := hijacker.Hijack()
  208. if err != nil {
  209. writer.WriteHeader(statusCode)
  210. return
  211. }
  212. if tcpConn, isTCP := common.Cast[*net.TCPConn](conn); isTCP {
  213. tcpConn.SetLinger(0)
  214. }
  215. conn.Close()
  216. }
  217. func generateNaivePaddingHeader() string {
  218. paddingLen := rand.Intn(32) + 30
  219. padding := make([]byte, paddingLen)
  220. bits := rand.Uint64()
  221. for i := 0; i < 16; i++ {
  222. // Codes that won't be Huffman coded.
  223. padding[i] = "!#$()+<>?@[]^`{}"[bits&15]
  224. bits >>= 4
  225. }
  226. for i := 16; i < paddingLen; i++ {
  227. padding[i] = '~'
  228. }
  229. return string(padding)
  230. }