diff --git a/protocol/cloudflare/dispatch.go b/protocol/cloudflare/dispatch.go index b33dea97c..8572e437e 100644 --- a/protocol/cloudflare/dispatch.go +++ b/protocol/cloudflare/dispatch.go @@ -156,6 +156,7 @@ func (i *Inbound) resolveHTTPService(requestURL string) (ResolvedService, string return ResolvedService{}, "", err } service.BaseURL = helloURL + service.OriginRequest.NoTLSVerify = true } originURL, err := service.BuildRequestURL(requestURL) if err != nil { diff --git a/protocol/cloudflare/inbound.go b/protocol/cloudflare/inbound.go index 5e30b89d1..fd6a0f0b5 100644 --- a/protocol/cloudflare/inbound.go +++ b/protocol/cloudflare/inbound.go @@ -4,6 +4,7 @@ package cloudflare import ( "context" + stdTLS "crypto/tls" "encoding/base64" "io" "math/rand" @@ -17,6 +18,7 @@ import ( "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter/inbound" boxDialer "github.com/sagernet/sing-box/common/dialer" + boxTLS "github.com/sagernet/sing-box/common/tls" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" @@ -227,12 +229,20 @@ func (i *Inbound) ensureHelloWorldURL() (*url.URL, error) { if err != nil { return nil, E.Cause(err, "listen hello world server") } + certificate, err := boxTLS.GenerateKeyPair(nil, nil, time.Now, "localhost") + if err != nil { + _ = listener.Close() + return nil, E.Cause(err, "generate hello world certificate") + } + tlsListener := stdTLS.NewListener(listener, &stdTLS.Config{ + Certificates: []stdTLS.Certificate{*certificate}, + }) server := &http.Server{Handler: mux} - go server.Serve(listener) + go server.Serve(tlsListener) i.helloWorldServer = server i.helloWorldURL = &url.URL{ - Scheme: "http", + Scheme: "https", Host: listener.Addr().String(), } return i.helloWorldURL, nil diff --git a/protocol/cloudflare/ingress_test.go b/protocol/cloudflare/ingress_test.go index 03a91f0f0..e4432cf32 100644 --- a/protocol/cloudflare/ingress_test.go +++ b/protocol/cloudflare/ingress_test.go @@ -151,3 +151,29 @@ func TestResolveHTTPServiceStatus(t *testing.T) { t.Fatalf("status service should keep request URL, got %s", requestURL) } } + +func TestResolveHTTPServiceHelloWorld(t *testing.T) { + inboundInstance := newTestIngressInbound(t) + inboundInstance.configManager.activeConfig = RuntimeConfig{ + Ingress: []compiledIngressRule{ + {Service: mustResolvedService(t, "hello_world")}, + }, + } + + service, requestURL, err := inboundInstance.resolveHTTPService("https://hello.example.com/path") + if err != nil { + t.Fatal(err) + } + if service.Kind != ResolvedServiceHelloWorld { + t.Fatalf("expected hello world service, got %#v", service) + } + if service.BaseURL == nil || service.BaseURL.Scheme != "https" { + t.Fatalf("expected hello world base URL to be https, got %#v", service.BaseURL) + } + if !service.OriginRequest.NoTLSVerify { + t.Fatal("expected hello world to force no_tls_verify") + } + if requestURL == "" || requestURL[:8] != "https://" { + t.Fatalf("expected https request URL, got %s", requestURL) + } +}