real_ip.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package features
  2. import (
  3. "bufio"
  4. "fmt"
  5. "net"
  6. "net/http"
  7. "github.com/onsi/ginkgo/v2"
  8. pp "github.com/pires/go-proxyproto"
  9. "github.com/fatedier/frp/pkg/util/log"
  10. "github.com/fatedier/frp/test/e2e/framework"
  11. "github.com/fatedier/frp/test/e2e/framework/consts"
  12. "github.com/fatedier/frp/test/e2e/mock/server/httpserver"
  13. "github.com/fatedier/frp/test/e2e/mock/server/streamserver"
  14. "github.com/fatedier/frp/test/e2e/pkg/request"
  15. "github.com/fatedier/frp/test/e2e/pkg/rpc"
  16. )
  17. var _ = ginkgo.Describe("[Feature: Real IP]", func() {
  18. f := framework.NewDefaultFramework()
  19. ginkgo.It("HTTP X-Forwarded-For", func() {
  20. vhostHTTPPort := f.AllocPort()
  21. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  22. vhostHTTPPort = %d
  23. `, vhostHTTPPort)
  24. localPort := f.AllocPort()
  25. localServer := httpserver.New(
  26. httpserver.WithBindPort(localPort),
  27. httpserver.WithHandler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  28. _, _ = w.Write([]byte(req.Header.Get("X-Forwarded-For")))
  29. })),
  30. )
  31. f.RunServer("", localServer)
  32. clientConf := consts.DefaultClientConfig
  33. clientConf += fmt.Sprintf(`
  34. [[proxies]]
  35. name = "test"
  36. type = "http"
  37. localPort = %d
  38. customDomains = ["normal.example.com"]
  39. `, localPort)
  40. f.RunProcesses([]string{serverConf}, []string{clientConf})
  41. framework.NewRequestExpect(f).Port(vhostHTTPPort).
  42. RequestModify(func(r *request.Request) {
  43. r.HTTP().HTTPHost("normal.example.com")
  44. }).
  45. ExpectResp([]byte("127.0.0.1")).
  46. Ensure()
  47. })
  48. ginkgo.Describe("Proxy Protocol", func() {
  49. ginkgo.It("TCP", func() {
  50. serverConf := consts.DefaultServerConfig
  51. clientConf := consts.DefaultClientConfig
  52. localPort := f.AllocPort()
  53. localServer := streamserver.New(streamserver.TCP, streamserver.WithBindPort(localPort),
  54. streamserver.WithCustomHandler(func(c net.Conn) {
  55. defer c.Close()
  56. rd := bufio.NewReader(c)
  57. ppHeader, err := pp.Read(rd)
  58. if err != nil {
  59. log.Error("read proxy protocol error: %v", err)
  60. return
  61. }
  62. for {
  63. if _, err := rpc.ReadBytes(rd); err != nil {
  64. return
  65. }
  66. buf := []byte(ppHeader.SourceAddr.String())
  67. _, _ = rpc.WriteBytes(c, buf)
  68. }
  69. }))
  70. f.RunServer("", localServer)
  71. remotePort := f.AllocPort()
  72. clientConf += fmt.Sprintf(`
  73. [[proxies]]
  74. name = "tcp"
  75. type = "tcp"
  76. localPort = %d
  77. remotePort = %d
  78. transport.proxyProtocolVersion = "v2"
  79. `, localPort, remotePort)
  80. f.RunProcesses([]string{serverConf}, []string{clientConf})
  81. framework.NewRequestExpect(f).Port(remotePort).Ensure(func(resp *request.Response) bool {
  82. log.Trace("ProxyProtocol get SourceAddr: %s", string(resp.Content))
  83. addr, err := net.ResolveTCPAddr("tcp", string(resp.Content))
  84. if err != nil {
  85. return false
  86. }
  87. if addr.IP.String() != "127.0.0.1" {
  88. return false
  89. }
  90. return true
  91. })
  92. })
  93. ginkgo.It("HTTP", func() {
  94. vhostHTTPPort := f.AllocPort()
  95. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  96. vhostHTTPPort = %d
  97. `, vhostHTTPPort)
  98. clientConf := consts.DefaultClientConfig
  99. localPort := f.AllocPort()
  100. var srcAddrRecord string
  101. localServer := streamserver.New(streamserver.TCP, streamserver.WithBindPort(localPort),
  102. streamserver.WithCustomHandler(func(c net.Conn) {
  103. defer c.Close()
  104. rd := bufio.NewReader(c)
  105. ppHeader, err := pp.Read(rd)
  106. if err != nil {
  107. log.Error("read proxy protocol error: %v", err)
  108. return
  109. }
  110. srcAddrRecord = ppHeader.SourceAddr.String()
  111. }))
  112. f.RunServer("", localServer)
  113. clientConf += fmt.Sprintf(`
  114. [[proxies]]
  115. name = "test"
  116. type = "http"
  117. localPort = %d
  118. customDomains = ["normal.example.com"]
  119. transport.proxyProtocolVersion = "v2"
  120. `, localPort)
  121. f.RunProcesses([]string{serverConf}, []string{clientConf})
  122. framework.NewRequestExpect(f).Port(vhostHTTPPort).RequestModify(func(r *request.Request) {
  123. r.HTTP().HTTPHost("normal.example.com")
  124. }).Ensure(framework.ExpectResponseCode(404))
  125. log.Trace("ProxyProtocol get SourceAddr: %s", srcAddrRecord)
  126. addr, err := net.ResolveTCPAddr("tcp", srcAddrRecord)
  127. framework.ExpectNoError(err, srcAddrRecord)
  128. framework.ExpectEqualValues("127.0.0.1", addr.IP.String())
  129. })
  130. })
  131. })