diff --git a/docs/user-guide/grpc.md b/docs/user-guide/grpc.md index 53126c3ec..f4f609d92 100644 --- a/docs/user-guide/grpc.md +++ b/docs/user-guide/grpc.md @@ -3,7 +3,7 @@ This section explains how to use Traefik as reverse proxy for gRPC application with self-signed certificates. !!! warning - As gRPC needs HTTP2, we need valid HTTPS certificates on both gRPC Server and Træfik. + As gRPC needs HTTP2, we need HTTPS certificates on both gRPC Server and Træfik.

gRPC architecture @@ -76,9 +76,12 @@ RootCAs = [ "./backend.cert" ] rule = "Host:frontend.local" ``` +!!! warning + With some backends, the server URLs use the IP, so you may need to configure `InsecureSkipVerify` instead of the `RootCAS` to activate HTTPS without hostname verification. + ## Conclusion -We don't need specific configuration to use gRPC in Træfik, we just need to be careful that all the exchanges (between client and Træfik, and between Træfik and backend) are valid HTTPS communications (without `InsecureSkipVerify` enabled) because gRPC use HTTP2. +We don't need specific configuration to use gRPC in Træfik, we just need to be careful that all the exchanges (between client and Træfik, and between Træfik and backend) are HTTPS communications because gRPC uses HTTP2. ## A gRPC example in go diff --git a/integration/fixtures/grpc/config_insecure.toml b/integration/fixtures/grpc/config_insecure.toml new file mode 100644 index 000000000..66285ce06 --- /dev/null +++ b/integration/fixtures/grpc/config_insecure.toml @@ -0,0 +1,29 @@ +defaultEntryPoints = ["https"] + +InsecureSkipVerify = true + +[entryPoints] + [entryPoints.https] + address = ":4443" + [entryPoints.https.tls] + [[entryPoints.https.tls.certificates]] + CertFile = """{{ .CertContent }}""" + KeyFile = """{{ .KeyContent }}""" + + +[web] + address = ":8080" + +[file] + +[backends] + [backends.backend1] + [backends.backend1.servers.server1] + url = "https://127.0.0.1:{{ .GRPCServerPort }}" + + +[frontends] + [frontends.frontend1] + backend = "backend1" + [frontends.frontend1.routes.test_1] + rule = "Host:127.0.0.1" diff --git a/integration/grpc_test.go b/integration/grpc_test.go index f9ec89b7b..d597b289c 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -113,3 +113,45 @@ func (s *GRPCSuite) TestGRPC(c *check.C) { c.Assert(err, check.IsNil) c.Assert(response, check.Equals, "Hello World") } + +func (s *GRPCSuite) TestGRPCInsecure(c *check.C) { + lis, err := net.Listen("tcp", ":0") + _, port, err := net.SplitHostPort(lis.Addr().String()) + c.Assert(err, check.IsNil) + + go func() { + err := startGRPCServer(lis) + c.Log(err) + c.Assert(err, check.IsNil) + }() + + file := s.adaptFile(c, "fixtures/grpc/config_insecure.toml", struct { + CertContent string + KeyContent string + GRPCServerPort string + }{ + CertContent: string(LocalhostCert), + KeyContent: string(LocalhostKey), + GRPCServerPort: port, + }) + + defer os.Remove(file) + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + + err = cmd.Start() + c.Assert(err, check.IsNil) + defer cmd.Process.Kill() + + // wait for Traefik + err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("Host:127.0.0.1")) + c.Assert(err, check.IsNil) + var response string + err = try.Do(1*time.Second, func() error { + response, err = callHelloClientGRPC() + return err + }) + + c.Assert(err, check.IsNil) + c.Assert(response, check.Equals, "Hello World") +} diff --git a/server/server.go b/server/server.go index a25283e33..25b990a52 100644 --- a/server/server.go +++ b/server/server.go @@ -154,8 +154,8 @@ func createHTTPTransport(globalConfiguration configuration.GlobalConfiguration) transport.TLSClientConfig = &tls.Config{ RootCAs: createRootCACertPool(globalConfiguration.RootCAs), } - http2.ConfigureTransport(transport) } + http2.ConfigureTransport(transport) return transport }