From 14628df63c4ad44888042622a4898db6d0dde767 Mon Sep 17 00:00:00 2001 From: fatedier Date: Tue, 23 Jun 2026 00:04:38 +0800 Subject: [PATCH] test: cover tls2raw proxy protocol header (#5376) --- test/e2e/v1/plugin/client.go | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/test/e2e/v1/plugin/client.go b/test/e2e/v1/plugin/client.go index 1ea25a6e..f2afad41 100644 --- a/test/e2e/v1/plugin/client.go +++ b/test/e2e/v1/plugin/client.go @@ -1,18 +1,24 @@ package plugin import ( + "bufio" "crypto/tls" "fmt" + "io" + "net" "net/http" "strconv" "strings" "github.com/onsi/ginkgo/v2" + pp "github.com/pires/go-proxyproto" "github.com/fatedier/frp/pkg/transport" + "github.com/fatedier/frp/pkg/util/log" "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/cert" "github.com/fatedier/frp/test/e2e/pkg/port" "github.com/fatedier/frp/test/e2e/pkg/request" @@ -450,4 +456,85 @@ var _ = ginkgo.Describe("[Feature: Client-Plugins]", func() { ExpectResp([]byte("test")). Ensure() }) + + ginkgo.It("tls2raw with proxy protocol v2", func() { + generator := &cert.SelfSignedCertGenerator{} + artifacts, err := generator.Generate("example.com") + framework.ExpectNoError(err) + crtPath := f.WriteTempFile("tls2raw_proxy_protocol_server.crt", string(artifacts.Cert)) + keyPath := f.WriteTempFile("tls2raw_proxy_protocol_server.key", string(artifacts.Key)) + + serverConf := consts.DefaultServerConfig + vhostHTTPSPort := f.AllocPort() + serverConf += fmt.Sprintf(` + vhostHTTPSPort = %d + `, vhostHTTPSPort) + + localPort := f.AllocPort() + clientConf := consts.DefaultClientConfig + fmt.Sprintf(` + [[proxies]] + name = "tls2raw-proxy-protocol-test" + type = "https" + customDomains = ["example.com"] + transport.proxyProtocolVersion = "v2" + [proxies.plugin] + type = "tls2raw" + localAddr = "127.0.0.1:%d" + crtPath = "%s" + keyPath = "%s" + `, localPort, crtPath, keyPath) + + f.RunProcesses(serverConf, []string{clientConf}) + + localServer := streamserver.New(streamserver.TCP, streamserver.WithBindPort(localPort), + streamserver.WithCustomHandler(func(c net.Conn) { + defer c.Close() + + writeResp := func(body string) { + _, _ = fmt.Fprintf(c, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nConnection: close\r\n\r\n%s", len(body), body) + } + + rd := bufio.NewReader(c) + ppHeader, err := pp.Read(rd) + if err != nil { + log.Errorf("read proxy protocol error: %v", err) + writeResp("missing proxy protocol") + return + } + if ppHeader.Version != 2 { + log.Errorf("unexpected proxy protocol version: %d", ppHeader.Version) + writeResp("unexpected proxy protocol version") + return + } + srcAddr, ok := ppHeader.SourceAddr.(*net.TCPAddr) + if !ok || srcAddr.IP.String() != "127.0.0.1" { + log.Errorf("unexpected proxy protocol source address: %v", ppHeader.SourceAddr) + writeResp("unexpected proxy protocol source address") + return + } + + req, err := http.ReadRequest(rd) + if err != nil { + log.Errorf("read http request after proxy protocol error: %v", err) + writeResp("missing http request") + return + } + _, _ = io.Copy(io.Discard, req.Body) + _ = req.Body.Close() + + writeResp("test") + })) + f.RunServer("", localServer) + + framework.NewRequestExpect(f). + Port(vhostHTTPSPort). + RequestModify(func(r *request.Request) { + r.HTTPS().HTTPHost("example.com").TLSConfig(&tls.Config{ + ServerName: "example.com", + InsecureSkipVerify: true, + }) + }). + ExpectResp([]byte("test")). + Ensure() + }) })