// runCreateClientCert generates key pair and CA certificate and writes them // to their corresponding files. func runCreateClientCert(cmd *cobra.Command, args []string) { err := security.RunCreateClientCert(Context.Certs, keySize, args[0]) if err != nil { fmt.Fprintf(osStderr, "failed to generate clent certificate: %s\n", err) osExit(1) return } }
// runCreateClientCert generates key pair and CA certificate and writes them // to their corresponding files. func runCreateClientCert(cmd *cobra.Command, args []string) error { if len(args) != 1 { mustUsage(cmd) return errMissingParams } if err := security.RunCreateClientCert(context.Certs, keySize, args[0]); err != nil { return fmt.Errorf("failed to generate clent certificate: %s", err) } return nil }
// runCreateClientCert generates key pair and CA certificate and writes them // to their corresponding files. func runCreateClientCert(cmd *cobra.Command, args []string) error { if len(args) != 1 { mustUsage(cmd) return errMissingParams } if len(baseCtx.SSLCA) == 0 || len(baseCtx.SSLCAKey) == 0 || len(baseCtx.SSLCert) == 0 || len(baseCtx.SSLCertKey) == 0 { mustUsage(cmd) return errMissingParams } if err := security.RunCreateClientCert(baseCtx.SSLCA, baseCtx.SSLCAKey, baseCtx.SSLCert, baseCtx.SSLCertKey, keySize, args[0]); err != nil { return fmt.Errorf("failed to generate clent certificate: %s", err) } return nil }
// Start starts the cluster. func (l *LocalCluster) Start() { defer l.stopOnPanic() l.mu.Lock() defer l.mu.Unlock() l.runDockerSpy() l.initCluster() l.createCACert() l.createNodeCerts() maybePanic(security.RunCreateClientCert(l.CertsDir, 512, security.RootUser)) l.monitorStopper = make(chan struct{}) go l.monitor(l.monitorStopper) l.Nodes = make([]*Container, l.numLocal) for i := range l.Nodes { l.Nodes[i] = l.startNode(i) } }
// Start starts the cluster. func (l *LocalCluster) Start() { defer l.stopOnPanic() l.mu.Lock() defer l.mu.Unlock() l.runDockerSpy() l.initCluster() log.Infof("creating certs (%dbit) in: %s", keyLen, l.CertsDir) l.createCACert() l.createNodeCerts() maybePanic(security.RunCreateClientCert(l.CertsDir, 512, security.RootUser)) l.monitorCtx, l.monitorCtxCancelFunc = context.WithCancel(context.Background()) go l.monitor() l.Nodes = make([]*Container, l.numLocal) for i := range l.Nodes { l.Nodes[i] = l.startNode(i) } }
// Start starts the cluster. func (l *LocalCluster) Start() { defer l.stopOnPanic() l.mu.Lock() defer l.mu.Unlock() l.createNetwork() l.initCluster() log.Infof("creating certs (%dbit) in: %s", keyLen, l.CertsDir) l.createCACert() l.createNodeCerts() maybePanic(security.RunCreateClientCert(l.CertsDir, 512, security.RootUser)) l.monitorCtx, l.monitorCtxCancelFunc = context.WithCancel(context.Background()) go l.monitor() for _, node := range l.Nodes { l.startNode(node) } }
// TestMultiuser starts up an N node cluster and performs various ops // using different users. func TestMultiuser(t *testing.T) { l := localcluster.Create(*numNodes, stopper) l.Start() defer l.Stop() // Create client certificates for "foo" and "other". if err := security.RunCreateClientCert(l.CertsDir, 512, "foo"); err != nil { t.Fatal(err) } if err := security.RunCreateClientCert(l.CertsDir, 512, "other"); err != nil { t.Fatal(err) } checkRangeReplication(t, l, 20*time.Second) // Make clients. rootClient := makeDBClientForUser(t, l, "root", 0) fooClient := makeDBClientForUser(t, l, "foo", 0) otherClient := makeDBClientForUser(t, l, "other", 0) // Set permissions configs. configs := []struct { prefix string readers []string writers []string }{ // Good to know: "root" is always allowed to read and write. {"foo", []string{"foo"}, []string{"foo"}}, {"foo/public", []string{"foo", "other"}, []string{"foo"}}, {"tmp", []string{"foo", "other"}, []string{"foo", "other"}}, } for i, cfg := range configs { protoConfig := &config.PermConfig{Read: cfg.readers, Write: cfg.writers} if err := putPermConfig(rootClient, cfg.prefix, protoConfig); err != nil { t.Fatalf("#%d: failed to write config %+v for prefix %q: %v", i, protoConfig, cfg.prefix, err) } } // Write some data. The value is just the key. writes := []struct { key string db *client.DB success bool }{ {"some-file", rootClient, true}, {"some-file", fooClient, false}, {"some-file", otherClient, false}, {"foo/a", rootClient, true}, {"foo/a", fooClient, true}, {"foo/a", otherClient, false}, {"foo/public/b", rootClient, true}, {"foo/public/b", fooClient, true}, {"foo/public/b", otherClient, false}, {"tmp/c", rootClient, true}, {"tmp/c", fooClient, true}, {"tmp/c", otherClient, true}, } for i, w := range writes { err := w.db.Put(w.key, w.key) if (err == nil) != w.success { t.Errorf("test case #%d: %+v, got err=%v", i, w, err) } } // Read the previously-written files. They all succeeded at least once. reads := []struct { key string db *client.DB success bool }{ {"some-file", rootClient, true}, {"some-file", fooClient, false}, {"some-file", otherClient, false}, {"foo/a", rootClient, true}, {"foo/a", fooClient, true}, {"foo/a", otherClient, false}, {"foo/public/b", rootClient, true}, {"foo/public/b", fooClient, true}, {"foo/public/b", otherClient, true}, {"tmp/c", rootClient, true}, {"tmp/c", fooClient, true}, {"tmp/c", otherClient, true}, } for i, r := range reads { _, err := r.db.Get(r.key) if (err == nil) != r.success { t.Errorf("test case #%d: %+v, got err=%v", i, r, err) } } }
// This is a fairly high-level test of CA and node certificates. // We construct SSL server and clients and use the generated certs. func TestUseCerts(t *testing.T) { defer leaktest.AfterTest(t)() // Do not mock cert access for this test. security.ResetReadFileFn() defer ResetTest() certsDir := util.CreateTempDir(t, "certs_test") defer util.CleanupDir(certsDir) err := security.RunCreateCACert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), 512) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateNodeCert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey), 512, []string{"127.0.0.1"}) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateClientCert( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedCAKey), filepath.Join(certsDir, security.EmbeddedRootCert), filepath.Join(certsDir, security.EmbeddedRootKey), 512, security.RootUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Load TLS Configs. This is what TestServer and HTTPClient do internally. _, err = security.LoadServerTLSConfig( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey)) if err != nil { t.Fatalf("Expected success, got %v", err) } _, err = security.LoadClientTLSConfig( filepath.Join(certsDir, security.EmbeddedCACert), filepath.Join(certsDir, security.EmbeddedNodeCert), filepath.Join(certsDir, security.EmbeddedNodeKey)) if err != nil { t.Fatalf("Expected success, got %v", err) } // Start a test server and override certs. // We use a real context since we want generated certs. params := base.TestServerArgs{ SSLCA: filepath.Join(certsDir, security.EmbeddedCACert), SSLCert: filepath.Join(certsDir, security.EmbeddedNodeCert), SSLCertKey: filepath.Join(certsDir, security.EmbeddedNodeKey), } s, _, _ := serverutils.StartServer(t, params) defer s.Stopper().Stop() // Insecure mode. clientContext := testutils.NewNodeTestBaseContext() clientContext.Insecure = true httpClient, err := clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } req, err := http.NewRequest("GET", s.AdminURL()+"/_admin/v1/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err := httpClient.Do(req) if err == nil { resp.Body.Close() t.Fatalf("Expected SSL error, got success") } // Secure mode but no Certs: permissive config. clientContext = testutils.NewNodeTestBaseContext() clientContext.Insecure = false clientContext.SSLCert = "" httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } // Endpoint that does not enforce client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", s.AdminURL()+"/_admin/v1/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } // New client. With certs this time. clientContext = testutils.NewNodeTestBaseContext() clientContext.SSLCA = filepath.Join(certsDir, security.EmbeddedCACert) clientContext.SSLCert = filepath.Join(certsDir, security.EmbeddedNodeCert) clientContext.SSLCertKey = filepath.Join(certsDir, security.EmbeddedNodeKey) httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatalf("Expected success, got %v", err) } req, err = http.NewRequest("GET", s.AdminURL()+"/_admin/v1/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } }
// This is a fairly high-level test of CA and node certificates. // We construct SSL server and clients and use the generated certs. func TestUseCerts(t *testing.T) { defer leaktest.AfterTest(t) // Do not mock cert access for this test. security.ResetReadFileFn() defer ResetTest() certsDir := util.CreateTempDir(t, "certs_test") defer util.CleanupDir(certsDir) err := security.RunCreateCACert(certsDir, 512) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateNodeCert(certsDir, 512, []string{"127.0.0.1"}) if err != nil { t.Fatalf("Expected success, got %v", err) } err = security.RunCreateClientCert(certsDir, 512, security.RootUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Load TLS Configs. This is what TestServer and HTTPClient do internally. _, err = security.LoadServerTLSConfig(certsDir, "node") if err != nil { t.Fatalf("Expected success, got %v", err) } _, err = security.LoadClientTLSConfig(certsDir, security.NodeUser) if err != nil { t.Fatalf("Expected success, got %v", err) } // Start a test server and override certs. // We use a real context since we want generated certs. testCtx := server.NewContext() testCtx.Certs = certsDir testCtx.User = security.NodeUser testCtx.Addr = "127.0.0.1:0" testCtx.PGAddr = "127.0.0.1:0" s := &server.TestServer{Ctx: testCtx} if err := s.Start(); err != nil { t.Fatal(err) } defer s.Stop() // Insecure mode. clientContext := testutils.NewNodeTestBaseContext() clientContext.Insecure = true httpClient, err := clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } req, err := http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err := httpClient.Do(req) if err == nil { resp.Body.Close() t.Fatalf("Expected SSL error, got success") } // Secure mode but no Certs directory: permissive config. clientContext = testutils.NewNodeTestBaseContext() clientContext.Certs = "" httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatal(err) } // Endpoint that does not enforce client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } // Endpoint that enforces client auth (see: server/authentication_test.go) req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+driver.Endpoint, nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusUnauthorized { t.Fatalf("Expected status code %d, got: %d", http.StatusUnauthorized, resp.StatusCode) } // New client. With certs this time. clientContext = testutils.NewNodeTestBaseContext() clientContext.Certs = certsDir httpClient, err = clientContext.GetHTTPClient() if err != nil { t.Fatalf("Expected success, got %v", err) } req, err = http.NewRequest("GET", "https://"+s.ServingAddr()+"/_admin/health", nil) if err != nil { t.Fatalf("could not create request: %v", err) } resp, err = httpClient.Do(req) if err != nil { t.Fatalf("Expected success, got %v", err) } resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("Expected OK, got: %d", resp.StatusCode) } }
func (l *Cluster) createClientCerts() { log.Infof("creating client certs") maybePanic(security.RunCreateClientCert(l.CertsDir, 512, security.RootUser)) }