1
0

client_server.go 8.0 KB

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