client_server.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. package basic
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/onsi/ginkgo"
  6. "github.com/fatedier/frp/test/e2e/framework"
  7. "github.com/fatedier/frp/test/e2e/framework/consts"
  8. "github.com/fatedier/frp/test/e2e/pkg/cert"
  9. "github.com/fatedier/frp/test/e2e/pkg/port"
  10. )
  11. type generalTestConfigures struct {
  12. server string
  13. client string
  14. expectError bool
  15. }
  16. func runClientServerTest(f *framework.Framework, configures *generalTestConfigures) {
  17. serverConf := consts.DefaultServerConfig
  18. clientConf := consts.DefaultClientConfig
  19. serverConf += fmt.Sprintf(`
  20. %s
  21. `, configures.server)
  22. tcpPortName := port.GenName("TCP")
  23. udpPortName := port.GenName("UDP")
  24. clientConf += fmt.Sprintf(`
  25. %s
  26. [tcp]
  27. type = tcp
  28. local_port = {{ .%s }}
  29. remote_port = {{ .%s }}
  30. [udp]
  31. type = udp
  32. local_port = {{ .%s }}
  33. remote_port = {{ .%s }}
  34. `, configures.client,
  35. framework.TCPEchoServerPort, tcpPortName,
  36. framework.UDPEchoServerPort, udpPortName,
  37. )
  38. f.RunProcesses([]string{serverConf}, []string{clientConf})
  39. framework.NewRequestExpect(f).PortName(tcpPortName).ExpectError(configures.expectError).Explain("tcp proxy").Ensure()
  40. framework.NewRequestExpect(f).Protocol("udp").
  41. PortName(udpPortName).ExpectError(configures.expectError).Explain("udp proxy").Ensure()
  42. }
  43. // defineClientServerTest test a normal tcp and udp proxy with specified TestConfigures.
  44. func defineClientServerTest(desc string, f *framework.Framework, configures *generalTestConfigures) {
  45. ginkgo.It(desc, func() {
  46. runClientServerTest(f, configures)
  47. })
  48. }
  49. var _ = ginkgo.Describe("[Feature: Client-Server]", func() {
  50. f := framework.NewDefaultFramework()
  51. ginkgo.Describe("Protocol", func() {
  52. supportProtocols := []string{"tcp", "kcp", "websocket"}
  53. for _, protocol := range supportProtocols {
  54. configures := &generalTestConfigures{
  55. server: fmt.Sprintf(`
  56. kcp_bind_port = {{ .%s }}
  57. protocol = %s"
  58. `, consts.PortServerName, protocol),
  59. client: "protocol = " + protocol,
  60. }
  61. defineClientServerTest(protocol, f, configures)
  62. }
  63. })
  64. ginkgo.Describe("Authentication", func() {
  65. defineClientServerTest("Token Correct", f, &generalTestConfigures{
  66. server: "token = 123456",
  67. client: "token = 123456",
  68. })
  69. defineClientServerTest("Token Incorrect", f, &generalTestConfigures{
  70. server: "token = 123456",
  71. client: "token = invalid",
  72. expectError: true,
  73. })
  74. })
  75. ginkgo.Describe("TLS", func() {
  76. supportProtocols := []string{"tcp", "kcp", "websocket"}
  77. for _, protocol := range supportProtocols {
  78. tmp := protocol
  79. defineClientServerTest("TLS over "+strings.ToUpper(tmp), f, &generalTestConfigures{
  80. server: fmt.Sprintf(`
  81. kcp_bind_port = {{ .%s }}
  82. protocol = %s
  83. `, consts.PortServerName, protocol),
  84. client: fmt.Sprintf(`tls_enable = true
  85. protocol = %s
  86. `, protocol),
  87. })
  88. }
  89. defineClientServerTest("enable tls_only, client with TLS", f, &generalTestConfigures{
  90. server: "tls_only = true",
  91. client: "tls_enable = true",
  92. })
  93. defineClientServerTest("enable tls_only, client without TLS", f, &generalTestConfigures{
  94. server: "tls_only = true",
  95. expectError: true,
  96. })
  97. })
  98. ginkgo.Describe("TLS with custom certificate", func() {
  99. supportProtocols := []string{"tcp", "kcp", "websocket"}
  100. var (
  101. caCrtPath string
  102. serverCrtPath, serverKeyPath string
  103. clientCrtPath, clientKeyPath string
  104. )
  105. ginkgo.JustBeforeEach(func() {
  106. generator := &cert.SelfSignedCertGenerator{}
  107. artifacts, err := generator.Generate("0.0.0.0")
  108. framework.ExpectNoError(err)
  109. caCrtPath = f.WriteTempFile("ca.crt", string(artifacts.CACert))
  110. serverCrtPath = f.WriteTempFile("server.crt", string(artifacts.Cert))
  111. serverKeyPath = f.WriteTempFile("server.key", string(artifacts.Key))
  112. generator.SetCA(artifacts.CACert, artifacts.CAKey)
  113. _, err = generator.Generate("0.0.0.0")
  114. framework.ExpectNoError(err)
  115. clientCrtPath = f.WriteTempFile("client.crt", string(artifacts.Cert))
  116. clientKeyPath = f.WriteTempFile("client.key", string(artifacts.Key))
  117. })
  118. for _, protocol := range supportProtocols {
  119. tmp := protocol
  120. ginkgo.It("one-way authentication: "+tmp, func() {
  121. runClientServerTest(f, &generalTestConfigures{
  122. server: fmt.Sprintf(`
  123. protocol = %s
  124. kcp_bind_port = {{ .%s }}
  125. tls_trusted_ca_file = %s
  126. `, tmp, consts.PortServerName, caCrtPath),
  127. client: fmt.Sprintf(`
  128. protocol = %s
  129. tls_enable = true
  130. tls_cert_file = %s
  131. tls_key_file = %s
  132. `, tmp, clientCrtPath, clientKeyPath),
  133. })
  134. })
  135. ginkgo.It("mutual authentication: "+tmp, func() {
  136. runClientServerTest(f, &generalTestConfigures{
  137. server: fmt.Sprintf(`
  138. protocol = %s
  139. kcp_bind_port = {{ .%s }}
  140. tls_cert_file = %s
  141. tls_key_file = %s
  142. tls_trusted_ca_file = %s
  143. `, tmp, consts.PortServerName, serverCrtPath, serverKeyPath, caCrtPath),
  144. client: fmt.Sprintf(`
  145. protocol = %s
  146. tls_enable = true
  147. tls_cert_file = %s
  148. tls_key_file = %s
  149. tls_trusted_ca_file = %s
  150. `, tmp, clientCrtPath, clientKeyPath, caCrtPath),
  151. })
  152. })
  153. }
  154. })
  155. ginkgo.Describe("TLS with custom certificate and specified server name", func() {
  156. var (
  157. caCrtPath string
  158. serverCrtPath, serverKeyPath string
  159. clientCrtPath, clientKeyPath string
  160. )
  161. ginkgo.JustBeforeEach(func() {
  162. generator := &cert.SelfSignedCertGenerator{}
  163. artifacts, err := generator.Generate("example.com")
  164. framework.ExpectNoError(err)
  165. caCrtPath = f.WriteTempFile("ca.crt", string(artifacts.CACert))
  166. serverCrtPath = f.WriteTempFile("server.crt", string(artifacts.Cert))
  167. serverKeyPath = f.WriteTempFile("server.key", string(artifacts.Key))
  168. generator.SetCA(artifacts.CACert, artifacts.CAKey)
  169. _, err = generator.Generate("example.com")
  170. framework.ExpectNoError(err)
  171. clientCrtPath = f.WriteTempFile("client.crt", string(artifacts.Cert))
  172. clientKeyPath = f.WriteTempFile("client.key", string(artifacts.Key))
  173. })
  174. ginkgo.It("mutual authentication", func() {
  175. runClientServerTest(f, &generalTestConfigures{
  176. server: fmt.Sprintf(`
  177. tls_cert_file = %s
  178. tls_key_file = %s
  179. tls_trusted_ca_file = %s
  180. `, serverCrtPath, serverKeyPath, caCrtPath),
  181. client: fmt.Sprintf(`
  182. tls_enable = true
  183. tls_server_name = example.com
  184. tls_cert_file = %s
  185. tls_key_file = %s
  186. tls_trusted_ca_file = %s
  187. `, clientCrtPath, clientKeyPath, caCrtPath),
  188. })
  189. })
  190. ginkgo.It("mutual authentication with incorrect server name", func() {
  191. runClientServerTest(f, &generalTestConfigures{
  192. server: fmt.Sprintf(`
  193. tls_cert_file = %s
  194. tls_key_file = %s
  195. tls_trusted_ca_file = %s
  196. `, serverCrtPath, serverKeyPath, caCrtPath),
  197. client: fmt.Sprintf(`
  198. tls_enable = true
  199. tls_server_name = invalid.com
  200. tls_cert_file = %s
  201. tls_key_file = %s
  202. tls_trusted_ca_file = %s
  203. `, clientCrtPath, clientKeyPath, caCrtPath),
  204. expectError: true,
  205. })
  206. })
  207. })
  208. ginkgo.Describe("TLS with disable_custom_tls_first_byte", func() {
  209. supportProtocols := []string{"tcp", "kcp", "websocket"}
  210. for _, protocol := range supportProtocols {
  211. tmp := protocol
  212. defineClientServerTest("TLS over "+strings.ToUpper(tmp), f, &generalTestConfigures{
  213. server: fmt.Sprintf(`
  214. kcp_bind_port = {{ .%s }}
  215. protocol = %s
  216. `, consts.PortServerName, protocol),
  217. client: fmt.Sprintf(`
  218. tls_enable = true
  219. protocol = %s
  220. disable_custom_tls_first_byte = true
  221. `, protocol),
  222. })
  223. }
  224. })
  225. ginkgo.Describe("IPv6 bind address", func() {
  226. supportProtocols := []string{"tcp", "kcp", "websocket"}
  227. for _, protocol := range supportProtocols {
  228. tmp := protocol
  229. defineClientServerTest("IPv6 bind address: "+strings.ToUpper(tmp), f, &generalTestConfigures{
  230. server: fmt.Sprintf(`
  231. bind_addr = ::
  232. kcp_bind_port = {{ .%s }}
  233. protocol = %s
  234. `, consts.PortServerName, protocol),
  235. client: fmt.Sprintf(`
  236. tls_enable = true
  237. protocol = %s
  238. disable_custom_tls_first_byte = true
  239. `, protocol),
  240. })
  241. }
  242. })
  243. })