1
0

server.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. package plugin
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/onsi/ginkgo/v2"
  6. plugin "github.com/fatedier/frp/pkg/plugin/server"
  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. )
  11. var _ = ginkgo.Describe("[Feature: Server-Plugins]", func() {
  12. f := framework.NewDefaultFramework()
  13. ginkgo.Describe("Login", func() {
  14. newFunc := func() *plugin.Request {
  15. var r plugin.Request
  16. r.Content = &plugin.LoginContent{}
  17. return &r
  18. }
  19. ginkgo.It("Auth for custom meta token", func() {
  20. localPort := f.AllocPort()
  21. clientAddressGot := false
  22. handler := func(req *plugin.Request) *plugin.Response {
  23. var ret plugin.Response
  24. content := req.Content.(*plugin.LoginContent)
  25. if content.ClientAddress != "" {
  26. clientAddressGot = true
  27. }
  28. if content.Metas["token"] == "123" {
  29. ret.Unchange = true
  30. } else {
  31. ret.Reject = true
  32. ret.RejectReason = "invalid token"
  33. }
  34. return &ret
  35. }
  36. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  37. f.RunServer("", pluginServer)
  38. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  39. [plugin.user-manager]
  40. addr = 127.0.0.1:%d
  41. path = /handler
  42. ops = Login
  43. `, localPort)
  44. clientConf := consts.DefaultClientConfig
  45. remotePort := f.AllocPort()
  46. clientConf += fmt.Sprintf(`
  47. meta_token = 123
  48. [tcp]
  49. type = tcp
  50. local_port = {{ .%s }}
  51. remote_port = %d
  52. `, framework.TCPEchoServerPort, remotePort)
  53. remotePort2 := f.AllocPort()
  54. invalidTokenClientConf := consts.DefaultClientConfig + fmt.Sprintf(`
  55. [tcp2]
  56. type = tcp
  57. local_port = {{ .%s }}
  58. remote_port = %d
  59. `, framework.TCPEchoServerPort, remotePort2)
  60. f.RunProcesses([]string{serverConf}, []string{clientConf, invalidTokenClientConf})
  61. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  62. framework.NewRequestExpect(f).Port(remotePort2).ExpectError(true).Ensure()
  63. framework.ExpectTrue(clientAddressGot)
  64. })
  65. })
  66. ginkgo.Describe("NewProxy", func() {
  67. newFunc := func() *plugin.Request {
  68. var r plugin.Request
  69. r.Content = &plugin.NewProxyContent{}
  70. return &r
  71. }
  72. ginkgo.It("Validate Info", func() {
  73. localPort := f.AllocPort()
  74. handler := func(req *plugin.Request) *plugin.Response {
  75. var ret plugin.Response
  76. content := req.Content.(*plugin.NewProxyContent)
  77. if content.ProxyName == "tcp" {
  78. ret.Unchange = true
  79. } else {
  80. ret.Reject = true
  81. }
  82. return &ret
  83. }
  84. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  85. f.RunServer("", pluginServer)
  86. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  87. [plugin.test]
  88. addr = 127.0.0.1:%d
  89. path = /handler
  90. ops = NewProxy
  91. `, localPort)
  92. clientConf := consts.DefaultClientConfig
  93. remotePort := f.AllocPort()
  94. clientConf += fmt.Sprintf(`
  95. [tcp]
  96. type = tcp
  97. local_port = {{ .%s }}
  98. remote_port = %d
  99. `, framework.TCPEchoServerPort, remotePort)
  100. f.RunProcesses([]string{serverConf}, []string{clientConf})
  101. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  102. })
  103. ginkgo.It("Mofify RemotePort", func() {
  104. localPort := f.AllocPort()
  105. remotePort := f.AllocPort()
  106. handler := func(req *plugin.Request) *plugin.Response {
  107. var ret plugin.Response
  108. content := req.Content.(*plugin.NewProxyContent)
  109. content.RemotePort = remotePort
  110. ret.Content = content
  111. return &ret
  112. }
  113. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  114. f.RunServer("", pluginServer)
  115. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  116. [plugin.test]
  117. addr = 127.0.0.1:%d
  118. path = /handler
  119. ops = NewProxy
  120. `, localPort)
  121. clientConf := consts.DefaultClientConfig
  122. clientConf += fmt.Sprintf(`
  123. [tcp]
  124. type = tcp
  125. local_port = {{ .%s }}
  126. remote_port = 0
  127. `, framework.TCPEchoServerPort)
  128. f.RunProcesses([]string{serverConf}, []string{clientConf})
  129. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  130. })
  131. })
  132. ginkgo.Describe("CloseProxy", func() {
  133. newFunc := func() *plugin.Request {
  134. var r plugin.Request
  135. r.Content = &plugin.CloseProxyContent{}
  136. return &r
  137. }
  138. ginkgo.It("Validate Info", func() {
  139. localPort := f.AllocPort()
  140. var recordProxyName string
  141. handler := func(req *plugin.Request) *plugin.Response {
  142. var ret plugin.Response
  143. content := req.Content.(*plugin.CloseProxyContent)
  144. recordProxyName = content.ProxyName
  145. return &ret
  146. }
  147. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  148. f.RunServer("", pluginServer)
  149. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  150. [plugin.test]
  151. addr = 127.0.0.1:%d
  152. path = /handler
  153. ops = CloseProxy
  154. `, localPort)
  155. clientConf := consts.DefaultClientConfig
  156. remotePort := f.AllocPort()
  157. clientConf += fmt.Sprintf(`
  158. [tcp]
  159. type = tcp
  160. local_port = {{ .%s }}
  161. remote_port = %d
  162. `, framework.TCPEchoServerPort, remotePort)
  163. _, clients := f.RunProcesses([]string{serverConf}, []string{clientConf})
  164. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  165. for _, c := range clients {
  166. _ = c.Stop()
  167. }
  168. time.Sleep(1 * time.Second)
  169. framework.ExpectEqual(recordProxyName, "tcp")
  170. })
  171. })
  172. ginkgo.Describe("Ping", func() {
  173. newFunc := func() *plugin.Request {
  174. var r plugin.Request
  175. r.Content = &plugin.PingContent{}
  176. return &r
  177. }
  178. ginkgo.It("Validate Info", func() {
  179. localPort := f.AllocPort()
  180. var record string
  181. handler := func(req *plugin.Request) *plugin.Response {
  182. var ret plugin.Response
  183. content := req.Content.(*plugin.PingContent)
  184. record = content.Ping.PrivilegeKey
  185. ret.Unchange = true
  186. return &ret
  187. }
  188. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  189. f.RunServer("", pluginServer)
  190. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  191. [plugin.test]
  192. addr = 127.0.0.1:%d
  193. path = /handler
  194. ops = Ping
  195. `, localPort)
  196. remotePort := f.AllocPort()
  197. clientConf := consts.DefaultClientConfig
  198. clientConf += fmt.Sprintf(`
  199. heartbeat_interval = 1
  200. authenticate_heartbeats = true
  201. [tcp]
  202. type = tcp
  203. local_port = {{ .%s }}
  204. remote_port = %d
  205. `, framework.TCPEchoServerPort, remotePort)
  206. f.RunProcesses([]string{serverConf}, []string{clientConf})
  207. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  208. time.Sleep(3 * time.Second)
  209. framework.ExpectNotEqual("", record)
  210. })
  211. })
  212. ginkgo.Describe("NewWorkConn", func() {
  213. newFunc := func() *plugin.Request {
  214. var r plugin.Request
  215. r.Content = &plugin.NewWorkConnContent{}
  216. return &r
  217. }
  218. ginkgo.It("Validate Info", func() {
  219. localPort := f.AllocPort()
  220. var record string
  221. handler := func(req *plugin.Request) *plugin.Response {
  222. var ret plugin.Response
  223. content := req.Content.(*plugin.NewWorkConnContent)
  224. record = content.NewWorkConn.RunID
  225. ret.Unchange = true
  226. return &ret
  227. }
  228. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  229. f.RunServer("", pluginServer)
  230. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  231. [plugin.test]
  232. addr = 127.0.0.1:%d
  233. path = /handler
  234. ops = NewWorkConn
  235. `, localPort)
  236. remotePort := f.AllocPort()
  237. clientConf := consts.DefaultClientConfig
  238. clientConf += fmt.Sprintf(`
  239. [tcp]
  240. type = tcp
  241. local_port = {{ .%s }}
  242. remote_port = %d
  243. `, framework.TCPEchoServerPort, remotePort)
  244. f.RunProcesses([]string{serverConf}, []string{clientConf})
  245. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  246. framework.ExpectNotEqual("", record)
  247. })
  248. })
  249. ginkgo.Describe("NewUserConn", func() {
  250. newFunc := func() *plugin.Request {
  251. var r plugin.Request
  252. r.Content = &plugin.NewUserConnContent{}
  253. return &r
  254. }
  255. ginkgo.It("Validate Info", func() {
  256. localPort := f.AllocPort()
  257. var record string
  258. handler := func(req *plugin.Request) *plugin.Response {
  259. var ret plugin.Response
  260. content := req.Content.(*plugin.NewUserConnContent)
  261. record = content.RemoteAddr
  262. ret.Unchange = true
  263. return &ret
  264. }
  265. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, nil)
  266. f.RunServer("", pluginServer)
  267. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  268. [plugin.test]
  269. addr = 127.0.0.1:%d
  270. path = /handler
  271. ops = NewUserConn
  272. `, localPort)
  273. remotePort := f.AllocPort()
  274. clientConf := consts.DefaultClientConfig
  275. clientConf += fmt.Sprintf(`
  276. [tcp]
  277. type = tcp
  278. local_port = {{ .%s }}
  279. remote_port = %d
  280. `, framework.TCPEchoServerPort, remotePort)
  281. f.RunProcesses([]string{serverConf}, []string{clientConf})
  282. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  283. framework.ExpectNotEqual("", record)
  284. })
  285. })
  286. ginkgo.Describe("HTTPS Protocol", func() {
  287. newFunc := func() *plugin.Request {
  288. var r plugin.Request
  289. r.Content = &plugin.NewUserConnContent{}
  290. return &r
  291. }
  292. ginkgo.It("Validate Login Info, disable tls verify", func() {
  293. localPort := f.AllocPort()
  294. var record string
  295. handler := func(req *plugin.Request) *plugin.Response {
  296. var ret plugin.Response
  297. content := req.Content.(*plugin.NewUserConnContent)
  298. record = content.RemoteAddr
  299. ret.Unchange = true
  300. return &ret
  301. }
  302. tlsConfig, err := transport.NewServerTLSConfig("", "", "")
  303. framework.ExpectNoError(err)
  304. pluginServer := NewHTTPPluginServer(localPort, newFunc, handler, tlsConfig)
  305. f.RunServer("", pluginServer)
  306. serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
  307. [plugin.test]
  308. addr = https://127.0.0.1:%d
  309. path = /handler
  310. ops = NewUserConn
  311. `, localPort)
  312. remotePort := f.AllocPort()
  313. clientConf := consts.DefaultClientConfig
  314. clientConf += fmt.Sprintf(`
  315. [tcp]
  316. type = tcp
  317. local_port = {{ .%s }}
  318. remote_port = %d
  319. `, framework.TCPEchoServerPort, remotePort)
  320. f.RunProcesses([]string{serverConf}, []string{clientConf})
  321. framework.NewRequestExpect(f).Port(remotePort).Ensure()
  322. framework.ExpectNotEqual("", record)
  323. })
  324. })
  325. })