github.com/v2fly/v2ray-core/v4@v4.45.2/proxy/trojan/server.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package trojan 5 6 import ( 7 "context" 8 "io" 9 "strconv" 10 "time" 11 12 core "github.com/v2fly/v2ray-core/v4" 13 "github.com/v2fly/v2ray-core/v4/common" 14 "github.com/v2fly/v2ray-core/v4/common/buf" 15 "github.com/v2fly/v2ray-core/v4/common/errors" 16 "github.com/v2fly/v2ray-core/v4/common/log" 17 "github.com/v2fly/v2ray-core/v4/common/net" 18 "github.com/v2fly/v2ray-core/v4/common/protocol" 19 udp_proto "github.com/v2fly/v2ray-core/v4/common/protocol/udp" 20 "github.com/v2fly/v2ray-core/v4/common/retry" 21 "github.com/v2fly/v2ray-core/v4/common/session" 22 "github.com/v2fly/v2ray-core/v4/common/signal" 23 "github.com/v2fly/v2ray-core/v4/common/task" 24 "github.com/v2fly/v2ray-core/v4/features/policy" 25 "github.com/v2fly/v2ray-core/v4/features/routing" 26 "github.com/v2fly/v2ray-core/v4/transport/internet" 27 "github.com/v2fly/v2ray-core/v4/transport/internet/tls" 28 "github.com/v2fly/v2ray-core/v4/transport/internet/udp" 29 ) 30 31 func init() { 32 common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 33 return NewServer(ctx, config.(*ServerConfig)) 34 })) 35 } 36 37 // Server is an inbound connection handler that handles messages in trojan protocol. 38 type Server struct { 39 policyManager policy.Manager 40 validator *Validator 41 fallbacks map[string]map[string]*Fallback // or nil 42 } 43 44 // NewServer creates a new trojan inbound handler. 45 func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { 46 validator := new(Validator) 47 for _, user := range config.Users { 48 u, err := user.ToMemoryUser() 49 if err != nil { 50 return nil, newError("failed to get trojan user").Base(err).AtError() 51 } 52 53 if err := validator.Add(u); err != nil { 54 return nil, newError("failed to add user").Base(err).AtError() 55 } 56 } 57 58 v := core.MustFromContext(ctx) 59 server := &Server{ 60 policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager), 61 validator: validator, 62 } 63 64 if config.Fallbacks != nil { 65 server.fallbacks = make(map[string]map[string]*Fallback) 66 for _, fb := range config.Fallbacks { 67 if server.fallbacks[fb.Alpn] == nil { 68 server.fallbacks[fb.Alpn] = make(map[string]*Fallback) 69 } 70 server.fallbacks[fb.Alpn][fb.Path] = fb 71 } 72 if server.fallbacks[""] != nil { 73 for alpn, pfb := range server.fallbacks { 74 if alpn != "" { // && alpn != "h2" { 75 for path, fb := range server.fallbacks[""] { 76 if pfb[path] == nil { 77 pfb[path] = fb 78 } 79 } 80 } 81 } 82 } 83 } 84 85 return server, nil 86 } 87 88 // AddUser implements proxy.UserManager.AddUser(). 89 func (s *Server) AddUser(ctx context.Context, u *protocol.MemoryUser) error { 90 return s.validator.Add(u) 91 } 92 93 // RemoveUser implements proxy.UserManager.RemoveUser(). 94 func (s *Server) RemoveUser(ctx context.Context, e string) error { 95 return s.validator.Del(e) 96 } 97 98 // Network implements proxy.Inbound.Network(). 99 func (s *Server) Network() []net.Network { 100 return []net.Network{net.Network_TCP, net.Network_UNIX} 101 } 102 103 // Process implements proxy.Inbound.Process(). 104 func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error { 105 sid := session.ExportIDToError(ctx) 106 107 iConn := conn 108 if statConn, ok := iConn.(*internet.StatCouterConnection); ok { 109 iConn = statConn.Connection 110 } 111 112 sessionPolicy := s.policyManager.ForLevel(0) 113 if err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil { 114 return newError("unable to set read deadline").Base(err).AtWarning() 115 } 116 117 first := buf.New() 118 defer first.Release() 119 120 firstLen, err := first.ReadFrom(conn) 121 if err != nil { 122 return newError("failed to read first request").Base(err) 123 } 124 newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid) 125 126 bufferedReader := &buf.BufferedReader{ 127 Reader: buf.NewReader(conn), 128 Buffer: buf.MultiBuffer{first}, 129 } 130 131 var user *protocol.MemoryUser 132 133 apfb := s.fallbacks 134 isfb := apfb != nil 135 136 shouldFallback := false 137 if firstLen < 58 || first.Byte(56) != '\r' { 138 // invalid protocol 139 err = newError("not trojan protocol") 140 log.Record(&log.AccessMessage{ 141 From: conn.RemoteAddr(), 142 To: "", 143 Status: log.AccessRejected, 144 Reason: err, 145 }) 146 147 shouldFallback = true 148 } else { 149 user = s.validator.Get(hexString(first.BytesTo(56))) 150 if user == nil { 151 // invalid user, let's fallback 152 err = newError("not a valid user") 153 log.Record(&log.AccessMessage{ 154 From: conn.RemoteAddr(), 155 To: "", 156 Status: log.AccessRejected, 157 Reason: err, 158 }) 159 160 shouldFallback = true 161 } 162 } 163 164 if isfb && shouldFallback { 165 return s.fallback(ctx, sid, err, sessionPolicy, conn, iConn, apfb, first, firstLen, bufferedReader) 166 } else if shouldFallback { 167 return newError("invalid protocol or invalid user") 168 } 169 170 clientReader := &ConnReader{Reader: bufferedReader} 171 if err := clientReader.ParseHeader(); err != nil { 172 log.Record(&log.AccessMessage{ 173 From: conn.RemoteAddr(), 174 To: "", 175 Status: log.AccessRejected, 176 Reason: err, 177 }) 178 return newError("failed to create request from: ", conn.RemoteAddr()).Base(err) 179 } 180 181 destination := clientReader.Target 182 if err := conn.SetReadDeadline(time.Time{}); err != nil { 183 return newError("unable to set read deadline").Base(err).AtWarning() 184 } 185 186 inbound := session.InboundFromContext(ctx) 187 if inbound == nil { 188 panic("no inbound metadata") 189 } 190 inbound.User = user 191 sessionPolicy = s.policyManager.ForLevel(user.Level) 192 193 if destination.Network == net.Network_UDP { // handle udp request 194 return s.handleUDPPayload(ctx, &PacketReader{Reader: clientReader}, &PacketWriter{Writer: conn}, dispatcher) 195 } 196 197 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 198 From: conn.RemoteAddr(), 199 To: destination, 200 Status: log.AccessAccepted, 201 Reason: "", 202 Email: user.Email, 203 }) 204 205 newError("received request for ", destination).WriteToLog(sid) 206 return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher) 207 } 208 209 func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error { 210 udpServer := udp.NewDispatcher(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) { 211 if err := clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source); err != nil { 212 newError("failed to write response").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx)) 213 } 214 }) 215 216 inbound := session.InboundFromContext(ctx) 217 user := inbound.User 218 219 for { 220 select { 221 case <-ctx.Done(): 222 return nil 223 default: 224 p, err := clientReader.ReadMultiBufferWithMetadata() 225 if err != nil { 226 if errors.Cause(err) != io.EOF { 227 return newError("unexpected EOF").Base(err) 228 } 229 return nil 230 } 231 232 ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{ 233 From: inbound.Source, 234 To: p.Target, 235 Status: log.AccessAccepted, 236 Reason: "", 237 Email: user.Email, 238 }) 239 newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx)) 240 241 for _, b := range p.Buffer { 242 udpServer.Dispatch(ctx, p.Target, b) 243 } 244 } 245 } 246 } 247 248 func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session, 249 destination net.Destination, 250 clientReader buf.Reader, 251 clientWriter buf.Writer, dispatcher routing.Dispatcher) error { 252 ctx, cancel := context.WithCancel(ctx) 253 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 254 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 255 256 link, err := dispatcher.Dispatch(ctx, destination) 257 if err != nil { 258 return newError("failed to dispatch request to ", destination).Base(err) 259 } 260 261 requestDone := func() error { 262 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 263 264 if err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil { 265 return newError("failed to transfer request").Base(err) 266 } 267 return nil 268 } 269 270 responseDone := func() error { 271 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 272 273 if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil { 274 return newError("failed to write response").Base(err) 275 } 276 return nil 277 } 278 279 requestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer)) 280 if err := task.Run(ctx, requestDonePost, responseDone); err != nil { 281 common.Must(common.Interrupt(link.Reader)) 282 common.Must(common.Interrupt(link.Writer)) 283 return newError("connection ends").Base(err) 284 } 285 286 return nil 287 } 288 289 func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err error, sessionPolicy policy.Session, connection internet.Connection, iConn internet.Connection, apfb map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error { 290 if err := connection.SetReadDeadline(time.Time{}); err != nil { 291 newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid) 292 } 293 newError("fallback starts").Base(err).AtInfo().WriteToLog(sid) 294 295 alpn := "" 296 if len(apfb) > 1 || apfb[""] == nil { 297 if tlsConn, ok := iConn.(*tls.Conn); ok { 298 alpn = tlsConn.ConnectionState().NegotiatedProtocol 299 newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid) 300 } 301 if apfb[alpn] == nil { 302 alpn = "" 303 } 304 } 305 pfb := apfb[alpn] 306 if pfb == nil { 307 return newError(`failed to find the default "alpn" config`).AtWarning() 308 } 309 310 path := "" 311 if len(pfb) > 1 || pfb[""] == nil { 312 if firstLen >= 18 && first.Byte(4) != '*' { // not h2c 313 firstBytes := first.Bytes() 314 for i := 4; i <= 8; i++ { // 5 -> 9 315 if firstBytes[i] == '/' && firstBytes[i-1] == ' ' { 316 search := len(firstBytes) 317 if search > 64 { 318 search = 64 // up to about 60 319 } 320 for j := i + 1; j < search; j++ { 321 k := firstBytes[j] 322 if k == '\r' || k == '\n' { // avoid logging \r or \n 323 break 324 } 325 if k == ' ' { 326 path = string(firstBytes[i:j]) 327 newError("realPath = " + path).AtInfo().WriteToLog(sid) 328 if pfb[path] == nil { 329 path = "" 330 } 331 break 332 } 333 } 334 break 335 } 336 } 337 } 338 } 339 fb := pfb[path] 340 if fb == nil { 341 return newError(`failed to find the default "path" config`).AtWarning() 342 } 343 344 ctx, cancel := context.WithCancel(ctx) 345 timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle) 346 ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer) 347 348 var conn net.Conn 349 if err := retry.ExponentialBackoff(5, 100).On(func() error { 350 var dialer net.Dialer 351 conn, err = dialer.DialContext(ctx, fb.Type, fb.Dest) 352 if err != nil { 353 return err 354 } 355 return nil 356 }); err != nil { 357 return newError("failed to dial to " + fb.Dest).Base(err).AtWarning() 358 } 359 defer conn.Close() 360 361 serverReader := buf.NewReader(conn) 362 serverWriter := buf.NewWriter(conn) 363 364 postRequest := func() error { 365 defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly) 366 if fb.Xver != 0 { 367 remoteAddr, remotePort, err := net.SplitHostPort(connection.RemoteAddr().String()) 368 if err != nil { 369 return err 370 } 371 localAddr, localPort, err := net.SplitHostPort(connection.LocalAddr().String()) 372 if err != nil { 373 return err 374 } 375 ipv4 := true 376 for i := 0; i < len(remoteAddr); i++ { 377 if remoteAddr[i] == ':' { 378 ipv4 = false 379 break 380 } 381 } 382 pro := buf.New() 383 defer pro.Release() 384 switch fb.Xver { 385 case 1: 386 if ipv4 { 387 common.Must2(pro.Write([]byte("PROXY TCP4 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) 388 } else { 389 common.Must2(pro.Write([]byte("PROXY TCP6 " + remoteAddr + " " + localAddr + " " + remotePort + " " + localPort + "\r\n"))) 390 } 391 case 2: 392 common.Must2(pro.Write([]byte("\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x21"))) // signature + v2 + PROXY 393 if ipv4 { 394 common.Must2(pro.Write([]byte("\x11\x00\x0C"))) // AF_INET + STREAM + 12 bytes 395 common.Must2(pro.Write(net.ParseIP(remoteAddr).To4())) 396 common.Must2(pro.Write(net.ParseIP(localAddr).To4())) 397 } else { 398 common.Must2(pro.Write([]byte("\x21\x00\x24"))) // AF_INET6 + STREAM + 36 bytes 399 common.Must2(pro.Write(net.ParseIP(remoteAddr).To16())) 400 common.Must2(pro.Write(net.ParseIP(localAddr).To16())) 401 } 402 p1, _ := strconv.ParseUint(remotePort, 10, 16) 403 p2, _ := strconv.ParseUint(localPort, 10, 16) 404 common.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)})) 405 } 406 if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil { 407 return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning() 408 } 409 } 410 if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil { 411 return newError("failed to fallback request payload").Base(err).AtInfo() 412 } 413 return nil 414 } 415 416 writer := buf.NewWriter(connection) 417 418 getResponse := func() error { 419 defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly) 420 if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil { 421 return newError("failed to deliver response payload").Base(err).AtInfo() 422 } 423 return nil 424 } 425 426 if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil { 427 common.Must(common.Interrupt(serverReader)) 428 common.Must(common.Interrupt(serverWriter)) 429 return newError("fallback ends").Base(err).AtInfo() 430 } 431 432 return nil 433 }