ssh_tunnel.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package features
  2. import (
  3. "crypto/tls"
  4. "fmt"
  5. "time"
  6. "github.com/onsi/ginkgo/v2"
  7. "github.com/fatedier/frp/pkg/transport"
  8. "github.com/fatedier/frp/test/e2e/framework"
  9. "github.com/fatedier/frp/test/e2e/framework/consts"
  10. "github.com/fatedier/frp/test/e2e/mock/server/httpserver"
  11. "github.com/fatedier/frp/test/e2e/mock/server/streamserver"
  12. "github.com/fatedier/frp/test/e2e/pkg/request"
  13. "github.com/fatedier/frp/test/e2e/pkg/ssh"
  14. )
  15. var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() {
  16. f := framework.NewDefaultFramework()
  17. ginkgo.It("tcp", func() {
  18. sshPort := f.AllocPort()
  19. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  20. sshTunnelGateway.bindPort = %d
  21. `, sshPort)
  22. f.RunProcesses([]string{serverConf}, nil)
  23. localPort := f.PortByName(framework.TCPEchoServerPort)
  24. remotePort := f.AllocPort()
  25. tc := ssh.NewTunnelClient(
  26. fmt.Sprintf("127.0.0.1:%d", localPort),
  27. fmt.Sprintf("127.0.0.1:%d", sshPort),
  28. fmt.Sprintf("tcp --remote-port %d", remotePort),
  29. )
  30. framework.ExpectNoError(tc.Start())
  31. defer tc.Close()
  32. time.Sleep(time.Second)
  33. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  34. })
  35. ginkgo.It("http", func() {
  36. sshPort := f.AllocPort()
  37. vhostPort := f.AllocPort()
  38. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  39. vhostHTTPPort = %d
  40. sshTunnelGateway.bindPort = %d
  41. `, vhostPort, sshPort)
  42. f.RunProcesses([]string{serverConf}, nil)
  43. localPort := f.PortByName(framework.HTTPSimpleServerPort)
  44. tc := ssh.NewTunnelClient(
  45. fmt.Sprintf("127.0.0.1:%d", localPort),
  46. fmt.Sprintf("127.0.0.1:%d", sshPort),
  47. "http --custom-domain test.example.com",
  48. )
  49. framework.ExpectNoError(tc.Start())
  50. defer tc.Close()
  51. time.Sleep(time.Second)
  52. framework.NewRequestExpect(f).Port(vhostPort).
  53. RequestModify(func(r *request.Request) {
  54. r.HTTP().HTTPHost("test.example.com")
  55. }).
  56. Ensure()
  57. })
  58. ginkgo.It("https", func() {
  59. sshPort := f.AllocPort()
  60. vhostPort := f.AllocPort()
  61. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  62. vhostHTTPSPort = %d
  63. sshTunnelGateway.bindPort = %d
  64. `, vhostPort, sshPort)
  65. f.RunProcesses([]string{serverConf}, nil)
  66. localPort := f.AllocPort()
  67. testDomain := "test.example.com"
  68. tc := ssh.NewTunnelClient(
  69. fmt.Sprintf("127.0.0.1:%d", localPort),
  70. fmt.Sprintf("127.0.0.1:%d", sshPort),
  71. fmt.Sprintf("https --custom-domain %s", testDomain),
  72. )
  73. framework.ExpectNoError(tc.Start())
  74. defer tc.Close()
  75. tlsConfig, err := transport.NewServerTLSConfig("", "", "")
  76. framework.ExpectNoError(err)
  77. localServer := httpserver.New(
  78. httpserver.WithBindPort(localPort),
  79. httpserver.WithTLSConfig(tlsConfig),
  80. httpserver.WithResponse([]byte("test")),
  81. )
  82. f.RunServer("", localServer)
  83. time.Sleep(time.Second)
  84. framework.NewRequestExpect(f).
  85. Port(vhostPort).
  86. RequestModify(func(r *request.Request) {
  87. r.HTTPS().HTTPHost(testDomain).TLSConfig(&tls.Config{
  88. ServerName: testDomain,
  89. InsecureSkipVerify: true,
  90. })
  91. }).
  92. ExpectResp([]byte("test")).
  93. Ensure()
  94. })
  95. ginkgo.It("tcpmux", func() {
  96. sshPort := f.AllocPort()
  97. tcpmuxPort := f.AllocPort()
  98. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  99. tcpmuxHTTPConnectPort = %d
  100. sshTunnelGateway.bindPort = %d
  101. `, tcpmuxPort, sshPort)
  102. f.RunProcesses([]string{serverConf}, nil)
  103. localPort := f.AllocPort()
  104. testDomain := "test.example.com"
  105. tc := ssh.NewTunnelClient(
  106. fmt.Sprintf("127.0.0.1:%d", localPort),
  107. fmt.Sprintf("127.0.0.1:%d", sshPort),
  108. fmt.Sprintf("tcpmux --mux=httpconnect --custom-domain %s", testDomain),
  109. )
  110. framework.ExpectNoError(tc.Start())
  111. defer tc.Close()
  112. localServer := streamserver.New(
  113. streamserver.TCP,
  114. streamserver.WithBindPort(localPort),
  115. streamserver.WithRespContent([]byte("test")),
  116. )
  117. f.RunServer("", localServer)
  118. time.Sleep(time.Second)
  119. // Request without HTTP connect should get error
  120. framework.NewRequestExpect(f).
  121. Port(tcpmuxPort).
  122. ExpectError(true).
  123. Explain("request without HTTP connect expect error").
  124. Ensure()
  125. proxyURL := fmt.Sprintf("http://127.0.0.1:%d", tcpmuxPort)
  126. // Request with incorrect connect hostname
  127. framework.NewRequestExpect(f).RequestModify(func(r *request.Request) {
  128. r.Addr("invalid").Proxy(proxyURL)
  129. }).ExpectError(true).Explain("request without HTTP connect expect error").Ensure()
  130. // Request with correct connect hostname
  131. framework.NewRequestExpect(f).RequestModify(func(r *request.Request) {
  132. r.Addr(testDomain).Proxy(proxyURL)
  133. }).ExpectResp([]byte("test")).Ensure()
  134. })
  135. ginkgo.It("stcp", func() {
  136. sshPort := f.AllocPort()
  137. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  138. sshTunnelGateway.bindPort = %d
  139. `, sshPort)
  140. bindPort := f.AllocPort()
  141. visitorConf := consts.DefaultClientConfig + fmt.Sprintf(`
  142. [[visitors]]
  143. name = "stcp-test-visitor"
  144. type = "stcp"
  145. serverName = "stcp-test"
  146. secretKey = "abcdefg"
  147. bindPort = %d
  148. `, bindPort)
  149. f.RunProcesses([]string{serverConf}, []string{visitorConf})
  150. localPort := f.PortByName(framework.TCPEchoServerPort)
  151. tc := ssh.NewTunnelClient(
  152. fmt.Sprintf("127.0.0.1:%d", localPort),
  153. fmt.Sprintf("127.0.0.1:%d", sshPort),
  154. "stcp -n stcp-test --sk=abcdefg --allow-users=\"*\"",
  155. )
  156. framework.ExpectNoError(tc.Start())
  157. defer tc.Close()
  158. time.Sleep(time.Second)
  159. framework.NewRequestExpect(f).
  160. Port(bindPort).
  161. Ensure()
  162. })
  163. })