client.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. package plugin
  2. import (
  3. "crypto/tls"
  4. "fmt"
  5. "strconv"
  6. "github.com/fatedier/frp/pkg/transport"
  7. "github.com/fatedier/frp/test/e2e/framework"
  8. "github.com/fatedier/frp/test/e2e/framework/consts"
  9. "github.com/fatedier/frp/test/e2e/mock/server/httpserver"
  10. "github.com/fatedier/frp/test/e2e/pkg/cert"
  11. "github.com/fatedier/frp/test/e2e/pkg/port"
  12. "github.com/fatedier/frp/test/e2e/pkg/request"
  13. "github.com/fatedier/frp/test/e2e/pkg/utils"
  14. . "github.com/onsi/ginkgo"
  15. )
  16. var _ = Describe("[Feature: Client-Plugins]", func() {
  17. f := framework.NewDefaultFramework()
  18. Describe("UnixDomainSocket", func() {
  19. It("Expose a unix domain socket echo server", func() {
  20. serverConf := consts.DefaultServerConfig
  21. clientConf := consts.DefaultClientConfig
  22. getProxyConf := func(proxyName string, portName string, extra string) string {
  23. return fmt.Sprintf(`
  24. [%s]
  25. type = tcp
  26. remote_port = {{ .%s }}
  27. plugin = unix_domain_socket
  28. plugin_unix_path = {{ .%s }}
  29. `+extra, proxyName, portName, framework.UDSEchoServerAddr)
  30. }
  31. tests := []struct {
  32. proxyName string
  33. portName string
  34. extraConfig string
  35. }{
  36. {
  37. proxyName: "normal",
  38. portName: port.GenName("Normal"),
  39. },
  40. {
  41. proxyName: "with-encryption",
  42. portName: port.GenName("WithEncryption"),
  43. extraConfig: "use_encryption = true",
  44. },
  45. {
  46. proxyName: "with-compression",
  47. portName: port.GenName("WithCompression"),
  48. extraConfig: "use_compression = true",
  49. },
  50. {
  51. proxyName: "with-encryption-and-compression",
  52. portName: port.GenName("WithEncryptionAndCompression"),
  53. extraConfig: `
  54. use_encryption = true
  55. use_compression = true
  56. `,
  57. },
  58. }
  59. // build all client config
  60. for _, test := range tests {
  61. clientConf += getProxyConf(test.proxyName, test.portName, test.extraConfig) + "\n"
  62. }
  63. // run frps and frpc
  64. f.RunProcesses([]string{serverConf}, []string{clientConf})
  65. for _, test := range tests {
  66. framework.NewRequestExpect(f).Port(f.PortByName(test.portName)).Ensure()
  67. }
  68. })
  69. })
  70. It("http_proxy", func() {
  71. serverConf := consts.DefaultServerConfig
  72. clientConf := consts.DefaultClientConfig
  73. remotePort := f.AllocPort()
  74. clientConf += fmt.Sprintf(`
  75. [tcp]
  76. type = tcp
  77. remote_port = %d
  78. plugin = http_proxy
  79. plugin_http_user = abc
  80. plugin_http_passwd = 123
  81. `, remotePort)
  82. f.RunProcesses([]string{serverConf}, []string{clientConf})
  83. // http proxy, no auth info
  84. framework.NewRequestExpect(f).PortName(framework.HTTPSimpleServerPort).RequestModify(func(r *request.Request) {
  85. r.HTTP().Proxy("http://127.0.0.1:" + strconv.Itoa(remotePort))
  86. }).Ensure(framework.ExpectResponseCode(407))
  87. // http proxy, correct auth
  88. framework.NewRequestExpect(f).PortName(framework.HTTPSimpleServerPort).RequestModify(func(r *request.Request) {
  89. r.HTTP().Proxy("http://abc:123@127.0.0.1:" + strconv.Itoa(remotePort))
  90. }).Ensure()
  91. // connect TCP server by CONNECT method
  92. framework.NewRequestExpect(f).PortName(framework.TCPEchoServerPort).RequestModify(func(r *request.Request) {
  93. r.TCP().Proxy("http://abc:123@127.0.0.1:" + strconv.Itoa(remotePort))
  94. })
  95. })
  96. It("socks5 proxy", func() {
  97. serverConf := consts.DefaultServerConfig
  98. clientConf := consts.DefaultClientConfig
  99. remotePort := f.AllocPort()
  100. clientConf += fmt.Sprintf(`
  101. [tcp]
  102. type = tcp
  103. remote_port = %d
  104. plugin = socks5
  105. plugin_user = abc
  106. plugin_passwd = 123
  107. `, remotePort)
  108. f.RunProcesses([]string{serverConf}, []string{clientConf})
  109. // http proxy, no auth info
  110. framework.NewRequestExpect(f).PortName(framework.TCPEchoServerPort).RequestModify(func(r *request.Request) {
  111. r.TCP().Proxy("socks5://127.0.0.1:" + strconv.Itoa(remotePort))
  112. }).ExpectError(true).Ensure()
  113. // http proxy, correct auth
  114. framework.NewRequestExpect(f).PortName(framework.TCPEchoServerPort).RequestModify(func(r *request.Request) {
  115. r.TCP().Proxy("socks5://abc:123@127.0.0.1:" + strconv.Itoa(remotePort))
  116. }).Ensure()
  117. })
  118. It("static_file", func() {
  119. vhostPort := f.AllocPort()
  120. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  121. vhost_http_port = %d
  122. `, vhostPort)
  123. clientConf := consts.DefaultClientConfig
  124. remotePort := f.AllocPort()
  125. f.WriteTempFile("test_static_file", "foo")
  126. clientConf += fmt.Sprintf(`
  127. [tcp]
  128. type = tcp
  129. remote_port = %d
  130. plugin = static_file
  131. plugin_local_path = %s
  132. [http]
  133. type = http
  134. custom_domains = example.com
  135. plugin = static_file
  136. plugin_local_path = %s
  137. [http-with-auth]
  138. type = http
  139. custom_domains = other.example.com
  140. plugin = static_file
  141. plugin_local_path = %s
  142. plugin_http_user = abc
  143. plugin_http_passwd = 123
  144. `, remotePort, f.TempDirectory, f.TempDirectory, f.TempDirectory)
  145. f.RunProcesses([]string{serverConf}, []string{clientConf})
  146. // from tcp proxy
  147. framework.NewRequestExpect(f).Request(
  148. framework.NewHTTPRequest().HTTPPath("/test_static_file").Port(remotePort),
  149. ).ExpectResp([]byte("foo")).Ensure()
  150. // from http proxy without auth
  151. framework.NewRequestExpect(f).Request(
  152. framework.NewHTTPRequest().HTTPHost("example.com").HTTPPath("/test_static_file").Port(vhostPort),
  153. ).ExpectResp([]byte("foo")).Ensure()
  154. // from http proxy with auth
  155. framework.NewRequestExpect(f).Request(
  156. framework.NewHTTPRequest().HTTPHost("other.example.com").HTTPPath("/test_static_file").Port(vhostPort).HTTPHeaders(map[string]string{
  157. "Authorization": utils.BasicAuth("abc", "123"),
  158. }),
  159. ).ExpectResp([]byte("foo")).Ensure()
  160. })
  161. It("http2https", func() {
  162. serverConf := consts.DefaultServerConfig
  163. vhostHTTPPort := f.AllocPort()
  164. serverConf += fmt.Sprintf(`
  165. vhost_http_port = %d
  166. `, vhostHTTPPort)
  167. localPort := f.AllocPort()
  168. clientConf := consts.DefaultClientConfig + fmt.Sprintf(`
  169. [http2https]
  170. type = http
  171. custom_domains = example.com
  172. plugin = http2https
  173. plugin_local_addr = 127.0.0.1:%d
  174. `, localPort)
  175. f.RunProcesses([]string{serverConf}, []string{clientConf})
  176. tlsConfig, err := transport.NewServerTLSConfig("", "", "")
  177. framework.ExpectNoError(err)
  178. localServer := httpserver.New(
  179. httpserver.WithBindPort(localPort),
  180. httpserver.WithTlsConfig(tlsConfig),
  181. httpserver.WithResponse([]byte("test")),
  182. )
  183. f.RunServer("", localServer)
  184. framework.NewRequestExpect(f).
  185. Port(vhostHTTPPort).
  186. RequestModify(func(r *request.Request) {
  187. r.HTTP().HTTPHost("example.com")
  188. }).
  189. ExpectResp([]byte("test")).
  190. Ensure()
  191. })
  192. It("https2http", func() {
  193. generator := &cert.SelfSignedCertGenerator{}
  194. artifacts, err := generator.Generate("example.com")
  195. framework.ExpectNoError(err)
  196. crtPath := f.WriteTempFile("server.crt", string(artifacts.Cert))
  197. keyPath := f.WriteTempFile("server.key", string(artifacts.Key))
  198. serverConf := consts.DefaultServerConfig
  199. vhostHTTPSPort := f.AllocPort()
  200. serverConf += fmt.Sprintf(`
  201. vhost_https_port = %d
  202. `, vhostHTTPSPort)
  203. localPort := f.AllocPort()
  204. clientConf := consts.DefaultClientConfig + fmt.Sprintf(`
  205. [https2http]
  206. type = https
  207. custom_domains = example.com
  208. plugin = https2http
  209. plugin_local_addr = 127.0.0.1:%d
  210. plugin_crt_path = %s
  211. plugin_key_path = %s
  212. `, localPort, crtPath, keyPath)
  213. f.RunProcesses([]string{serverConf}, []string{clientConf})
  214. localServer := httpserver.New(
  215. httpserver.WithBindPort(localPort),
  216. httpserver.WithResponse([]byte("test")),
  217. )
  218. f.RunServer("", localServer)
  219. framework.NewRequestExpect(f).
  220. Port(vhostHTTPSPort).
  221. RequestModify(func(r *request.Request) {
  222. r.HTTPS().HTTPHost("example.com").TLSConfig(&tls.Config{
  223. ServerName: "example.com",
  224. InsecureSkipVerify: true,
  225. })
  226. }).
  227. ExpectResp([]byte("test")).
  228. Ensure()
  229. })
  230. It("https2https", func() {
  231. generator := &cert.SelfSignedCertGenerator{}
  232. artifacts, err := generator.Generate("example.com")
  233. framework.ExpectNoError(err)
  234. crtPath := f.WriteTempFile("server.crt", string(artifacts.Cert))
  235. keyPath := f.WriteTempFile("server.key", string(artifacts.Key))
  236. serverConf := consts.DefaultServerConfig
  237. vhostHTTPSPort := f.AllocPort()
  238. serverConf += fmt.Sprintf(`
  239. vhost_https_port = %d
  240. `, vhostHTTPSPort)
  241. localPort := f.AllocPort()
  242. clientConf := consts.DefaultClientConfig + fmt.Sprintf(`
  243. [https2https]
  244. type = https
  245. custom_domains = example.com
  246. plugin = https2https
  247. plugin_local_addr = 127.0.0.1:%d
  248. plugin_crt_path = %s
  249. plugin_key_path = %s
  250. `, localPort, crtPath, keyPath)
  251. f.RunProcesses([]string{serverConf}, []string{clientConf})
  252. tlsConfig, err := transport.NewServerTLSConfig("", "", "")
  253. framework.ExpectNoError(err)
  254. localServer := httpserver.New(
  255. httpserver.WithBindPort(localPort),
  256. httpserver.WithResponse([]byte("test")),
  257. httpserver.WithTlsConfig(tlsConfig),
  258. )
  259. f.RunServer("", localServer)
  260. framework.NewRequestExpect(f).
  261. Port(vhostHTTPSPort).
  262. RequestModify(func(r *request.Request) {
  263. r.HTTPS().HTTPHost("example.com").TLSConfig(&tls.Config{
  264. ServerName: "example.com",
  265. InsecureSkipVerify: true,
  266. })
  267. }).
  268. ExpectResp([]byte("test")).
  269. Ensure()
  270. })
  271. })