mirror of https://github.com/grpc/grpc-go.git
Add flag guarding SPIFFE Bundle provider (#8343)
* Add flag guarding SPIFFE Bundle provider * remove the log * vet * address PR comments * add comment * fix typo * rename flag * add test * vet * add other flag check * remove check from watcher * add tests for new section where the spiffe bundle map file is set to empty string * vet
This commit is contained in:
parent
6dfe07c8c3
commit
f6bf86cc7e
|
@ -24,6 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||
"google.golang.org/grpc/internal/envconfig"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
@ -72,6 +73,9 @@ func pluginConfigFromJSON(jd json.RawMessage) (Options, error) {
|
|||
if err := json.Unmarshal(jd, cfg); err != nil {
|
||||
return Options{}, fmt.Errorf("pemfile: json.Unmarshal(%s) failed: %v", string(jd), err)
|
||||
}
|
||||
if !envconfig.XDSSPIFFEEnabled {
|
||||
cfg.SPIFFETrustBundleMapFile = ""
|
||||
}
|
||||
|
||||
opts := Options{
|
||||
CertFile: cfg.CertificateFile,
|
||||
|
|
|
@ -21,14 +21,18 @@ package pemfile
|
|||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"google.golang.org/grpc/internal/envconfig"
|
||||
"google.golang.org/grpc/internal/testutils"
|
||||
)
|
||||
|
||||
func TestParseConfig(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
input any
|
||||
wantOutput string
|
||||
wantErr bool
|
||||
desc string
|
||||
input any
|
||||
wantOutput string
|
||||
wantErr bool
|
||||
enabledSpiffe bool
|
||||
}{
|
||||
{
|
||||
desc: "non JSON input",
|
||||
|
@ -107,10 +111,38 @@ func TestParseConfig(t *testing.T) {
|
|||
}`),
|
||||
wantOutput: "file_watcher:/a/b/cert.pem:/a/b/key.pem:/a/b/ca.pem::3m20s",
|
||||
},
|
||||
{
|
||||
desc: "good config with spiffe disabled",
|
||||
input: json.RawMessage(`
|
||||
{
|
||||
"certificate_file": "/a/b/cert.pem",
|
||||
"private_key_file": "/a/b/key.pem",
|
||||
"ca_certificate_file": "/a/b/ca.pem",
|
||||
"spiffe_trust_bundle_map_file": "/a/b/spiffe_bundle.json",
|
||||
"refresh_interval": "200s"
|
||||
}`),
|
||||
wantOutput: "file_watcher:/a/b/cert.pem:/a/b/key.pem:/a/b/ca.pem::3m20s",
|
||||
},
|
||||
{
|
||||
desc: "good config with spiffe enabled",
|
||||
input: json.RawMessage(`
|
||||
{
|
||||
"certificate_file": "/a/b/cert.pem",
|
||||
"private_key_file": "/a/b/key.pem",
|
||||
"ca_certificate_file": "/a/b/ca.pem",
|
||||
"spiffe_trust_bundle_map_file": "/a/b/spiffe_bundle.json",
|
||||
"refresh_interval": "200s"
|
||||
}`),
|
||||
wantOutput: "file_watcher:/a/b/cert.pem:/a/b/key.pem:/a/b/ca.pem:/a/b/spiffe_bundle.json:3m20s",
|
||||
enabledSpiffe: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
if test.enabledSpiffe {
|
||||
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
|
||||
}
|
||||
builder := &pluginBuilder{}
|
||||
|
||||
bc, err := builder.ParseConfig(test.input)
|
||||
|
|
|
@ -63,4 +63,9 @@ var (
|
|||
// For more details, see:
|
||||
// https://github.com/grpc/proposal/blob/master/A82-xds-system-root-certs.md.
|
||||
XDSSystemRootCertsEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_SYSTEM_ROOT_CERTS", false)
|
||||
|
||||
// XDSSPIFFEEnabled controls if SPIFFE Bundle Maps can be used as roots of
|
||||
// trust. For more details, see:
|
||||
// https://github.com/grpc/proposal/blob/master/A87-mtls-spiffe-support.md
|
||||
XDSSPIFFEEnabled = boolFromEnv("GRPC_EXPERIMENTAL_XDS_MTLS_SPIFFE", false)
|
||||
)
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"google.golang.org/grpc/credentials/tls/certprovider"
|
||||
"google.golang.org/grpc/credentials/tls/certprovider/pemfile"
|
||||
"google.golang.org/grpc/internal/credentials/spiffe"
|
||||
"google.golang.org/grpc/internal/envconfig"
|
||||
)
|
||||
|
||||
// bundle is an implementation of credentials.Bundle which implements mTLS
|
||||
|
@ -64,6 +65,9 @@ func NewBundle(jd json.RawMessage) (credentials.Bundle, func(), error) {
|
|||
}
|
||||
} // Else the config field is absent. Treat it as an empty config.
|
||||
|
||||
if !envconfig.XDSSPIFFEEnabled {
|
||||
cfg.SPIFFETrustBundleMapFile = ""
|
||||
}
|
||||
if cfg.CACertificateFile == "" && cfg.CertificateFile == "" && cfg.PrivateKeyFile == "" && cfg.SPIFFETrustBundleMapFile == "" {
|
||||
// We cannot use (and do not need) a file_watcher provider in this case,
|
||||
// and can simply directly use the TLS transport credentials.
|
||||
|
|
|
@ -30,6 +30,7 @@ import (
|
|||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/internal/envconfig"
|
||||
"google.golang.org/grpc/internal/grpctest"
|
||||
"google.golang.org/grpc/internal/stubserver"
|
||||
"google.golang.org/grpc/internal/testutils"
|
||||
|
@ -237,6 +238,7 @@ func (s) TestCaReloading(t *testing.T) {
|
|||
// is performed and checked for failure, ensuring that gRPC is correctly using
|
||||
// the changed-on-disk bundle map.
|
||||
func (s) Test_SPIFFE_Reloading(t *testing.T) {
|
||||
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
|
||||
clientSPIFFEBundle, err := os.ReadFile(testdata.Path("spiffe_end2end/client_spiffebundle.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read test SPIFFE bundle: %v", err)
|
||||
|
@ -357,6 +359,7 @@ func (s) TestMTLS(t *testing.T) {
|
|||
// chain that is compatible with the client's configured SPIFFE bundle map. An
|
||||
// MTLS connection is attempted between the two and checked for success.
|
||||
func (s) Test_MTLS_SPIFFE(t *testing.T) {
|
||||
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
|
||||
tests := []struct {
|
||||
name string
|
||||
serverOption grpc.ServerOption
|
||||
|
@ -372,7 +375,7 @@ func (s) Test_MTLS_SPIFFE(t *testing.T) {
|
|||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
s := stubserver.StartTestService(t, nil, grpc.Creds(testutils.CreateServerTLSCredentialsCompatibleWithSPIFFE(t, tls.RequireAndVerifyClientCert)))
|
||||
s := stubserver.StartTestService(t, nil, tc.serverOption)
|
||||
defer s.Stop()
|
||||
|
||||
cfg := fmt.Sprintf(`{
|
||||
|
@ -403,7 +406,44 @@ func (s) Test_MTLS_SPIFFE(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test_MTLS_SPIFFE_FlagDisabled configures a client and server. The server has
|
||||
// a certificate chain that is compatible with the client's configured SPIFFE
|
||||
// bundle map. However, the XDS flag that enabled SPIFFE usage is disabled. An
|
||||
// MTLS connection is attempted between the two and checked for failure.
|
||||
func (s) Test_MTLS_SPIFFE_FlagDisabled(t *testing.T) {
|
||||
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, false)
|
||||
serverOption := grpc.Creds(testutils.CreateServerTLSCredentialsCompatibleWithSPIFFE(t, tls.RequireAndVerifyClientCert))
|
||||
s := stubserver.StartTestService(t, nil, serverOption)
|
||||
defer s.Stop()
|
||||
|
||||
cfg := fmt.Sprintf(`{
|
||||
"certificate_file": "%s",
|
||||
"private_key_file": "%s",
|
||||
"spiffe_trust_bundle_map_file": "%s"
|
||||
}`,
|
||||
testdata.Path("spiffe_end2end/client_spiffe.pem"),
|
||||
testdata.Path("spiffe_end2end/client.key"),
|
||||
testdata.Path("spiffe_end2end/client_spiffebundle.json"))
|
||||
tlsBundle, stop, err := tlscreds.NewBundle([]byte(cfg))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create TLS bundle: %v", err)
|
||||
}
|
||||
defer stop()
|
||||
conn, err := grpc.NewClient(s.Address, grpc.WithCredentialsBundle(tlsBundle), grpc.WithAuthority("x.test.example.com"))
|
||||
if err != nil {
|
||||
t.Fatalf("Error dialing: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
client := testgrpc.NewTestServiceClient(conn)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
|
||||
defer cancel()
|
||||
if _, err = client.EmptyCall(ctx, &testpb.Empty{}); err == nil {
|
||||
t.Errorf("EmptyCall(): got success want failure")
|
||||
}
|
||||
}
|
||||
|
||||
func (s) Test_MTLS_SPIFFE_Failure(t *testing.T) {
|
||||
testutils.SetEnvConfig(t, &envconfig.XDSSPIFFEEnabled, true)
|
||||
tests := []struct {
|
||||
name string
|
||||
certFile string
|
||||
|
|
Loading…
Reference in New Issue