123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- package features
- import (
- "crypto/tls"
- "fmt"
- "time"
- "github.com/onsi/ginkgo/v2"
- "github.com/fatedier/frp/pkg/transport"
- "github.com/fatedier/frp/test/e2e/framework"
- "github.com/fatedier/frp/test/e2e/framework/consts"
- "github.com/fatedier/frp/test/e2e/mock/server/httpserver"
- "github.com/fatedier/frp/test/e2e/mock/server/streamserver"
- "github.com/fatedier/frp/test/e2e/pkg/request"
- "github.com/fatedier/frp/test/e2e/pkg/ssh"
- )
- var _ = ginkgo.Describe("[Feature: SSH Tunnel]", func() {
- f := framework.NewDefaultFramework()
- ginkgo.It("tcp", func() {
- sshPort := f.AllocPort()
- serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
- sshTunnelGateway.bindPort = %d
- `, sshPort)
- f.RunProcesses([]string{serverConf}, nil)
- localPort := f.PortByName(framework.TCPEchoServerPort)
- remotePort := f.AllocPort()
- tc := ssh.NewTunnelClient(
- fmt.Sprintf("127.0.0.1:%d", localPort),
- fmt.Sprintf("127.0.0.1:%d", sshPort),
- fmt.Sprintf("tcp --remote-port %d", remotePort),
- )
- framework.ExpectNoError(tc.Start())
- defer tc.Close()
- time.Sleep(time.Second)
- framework.NewRequestExpect(f).Port(remotePort).Ensure()
- })
- ginkgo.It("http", func() {
- sshPort := f.AllocPort()
- vhostPort := f.AllocPort()
- serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
- vhostHTTPPort = %d
- sshTunnelGateway.bindPort = %d
- `, vhostPort, sshPort)
- f.RunProcesses([]string{serverConf}, nil)
- localPort := f.PortByName(framework.HTTPSimpleServerPort)
- tc := ssh.NewTunnelClient(
- fmt.Sprintf("127.0.0.1:%d", localPort),
- fmt.Sprintf("127.0.0.1:%d", sshPort),
- "http --custom-domain test.example.com",
- )
- framework.ExpectNoError(tc.Start())
- defer tc.Close()
- time.Sleep(time.Second)
- framework.NewRequestExpect(f).Port(vhostPort).
- RequestModify(func(r *request.Request) {
- r.HTTP().HTTPHost("test.example.com")
- }).
- Ensure()
- })
- ginkgo.It("https", func() {
- sshPort := f.AllocPort()
- vhostPort := f.AllocPort()
- serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
- vhostHTTPSPort = %d
- sshTunnelGateway.bindPort = %d
- `, vhostPort, sshPort)
- f.RunProcesses([]string{serverConf}, nil)
- localPort := f.AllocPort()
- testDomain := "test.example.com"
- tc := ssh.NewTunnelClient(
- fmt.Sprintf("127.0.0.1:%d", localPort),
- fmt.Sprintf("127.0.0.1:%d", sshPort),
- fmt.Sprintf("https --custom-domain %s", testDomain),
- )
- framework.ExpectNoError(tc.Start())
- defer tc.Close()
- tlsConfig, err := transport.NewServerTLSConfig("", "", "")
- framework.ExpectNoError(err)
- localServer := httpserver.New(
- httpserver.WithBindPort(localPort),
- httpserver.WithTLSConfig(tlsConfig),
- httpserver.WithResponse([]byte("test")),
- )
- f.RunServer("", localServer)
- time.Sleep(time.Second)
- framework.NewRequestExpect(f).
- Port(vhostPort).
- RequestModify(func(r *request.Request) {
- r.HTTPS().HTTPHost(testDomain).TLSConfig(&tls.Config{
- ServerName: testDomain,
- InsecureSkipVerify: true,
- })
- }).
- ExpectResp([]byte("test")).
- Ensure()
- })
- ginkgo.It("tcpmux", func() {
- sshPort := f.AllocPort()
- tcpmuxPort := f.AllocPort()
- serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
- tcpmuxHTTPConnectPort = %d
- sshTunnelGateway.bindPort = %d
- `, tcpmuxPort, sshPort)
- f.RunProcesses([]string{serverConf}, nil)
- localPort := f.AllocPort()
- testDomain := "test.example.com"
- tc := ssh.NewTunnelClient(
- fmt.Sprintf("127.0.0.1:%d", localPort),
- fmt.Sprintf("127.0.0.1:%d", sshPort),
- fmt.Sprintf("tcpmux --mux=httpconnect --custom-domain %s", testDomain),
- )
- framework.ExpectNoError(tc.Start())
- defer tc.Close()
- localServer := streamserver.New(
- streamserver.TCP,
- streamserver.WithBindPort(localPort),
- streamserver.WithRespContent([]byte("test")),
- )
- f.RunServer("", localServer)
- time.Sleep(time.Second)
- // Request without HTTP connect should get error
- framework.NewRequestExpect(f).
- Port(tcpmuxPort).
- ExpectError(true).
- Explain("request without HTTP connect expect error").
- Ensure()
- proxyURL := fmt.Sprintf("http://127.0.0.1:%d", tcpmuxPort)
- // Request with incorrect connect hostname
- framework.NewRequestExpect(f).RequestModify(func(r *request.Request) {
- r.Addr("invalid").Proxy(proxyURL)
- }).ExpectError(true).Explain("request without HTTP connect expect error").Ensure()
- // Request with correct connect hostname
- framework.NewRequestExpect(f).RequestModify(func(r *request.Request) {
- r.Addr(testDomain).Proxy(proxyURL)
- }).ExpectResp([]byte("test")).Ensure()
- })
- ginkgo.It("stcp", func() {
- sshPort := f.AllocPort()
- serverConf := consts.DefaultServerConfig + fmt.Sprintf(`
- sshTunnelGateway.bindPort = %d
- `, sshPort)
- bindPort := f.AllocPort()
- visitorConf := consts.DefaultClientConfig + fmt.Sprintf(`
- [[visitors]]
- name = "stcp-test-visitor"
- type = "stcp"
- serverName = "stcp-test"
- secretKey = "abcdefg"
- bindPort = %d
- `, bindPort)
- f.RunProcesses([]string{serverConf}, []string{visitorConf})
- localPort := f.PortByName(framework.TCPEchoServerPort)
- tc := ssh.NewTunnelClient(
- fmt.Sprintf("127.0.0.1:%d", localPort),
- fmt.Sprintf("127.0.0.1:%d", sshPort),
- "stcp -n stcp-test --sk=abcdefg --allow-users=\"*\"",
- )
- framework.ExpectNoError(tc.Start())
- defer tc.Close()
- time.Sleep(time.Second)
- framework.NewRequestExpect(f).
- Port(bindPort).
- Ensure()
- })
- })
|