automate certificate signing in storage node setup (#954)
This commit is contained in:
parent
5984bc9549
commit
b6611e2800
@ -73,6 +73,11 @@ matrix:
|
|||||||
script:
|
script:
|
||||||
- make test-captplanet
|
- make test-captplanet
|
||||||
|
|
||||||
|
### certificate signing tests ###
|
||||||
|
- env: MODE=integration
|
||||||
|
script:
|
||||||
|
- make test-certificate-signing
|
||||||
|
|
||||||
### docker tests ###
|
### docker tests ###
|
||||||
- env: MODE=docker
|
- env: MODE=docker
|
||||||
services:
|
services:
|
||||||
|
5
Makefile
5
Makefile
@ -77,6 +77,11 @@ test-captplanet: ## Test source with captain planet (travis)
|
|||||||
@echo "Running ${@}"
|
@echo "Running ${@}"
|
||||||
@./scripts/test-captplanet.sh
|
@./scripts/test-captplanet.sh
|
||||||
|
|
||||||
|
.PHONY: test-certificate-signing
|
||||||
|
test-certificate-signing: ## Test certificate signing service and storagenode setup (travis)
|
||||||
|
@echo "Running ${@}"
|
||||||
|
@./scripts/test-certificate-signing.sh
|
||||||
|
|
||||||
.PHONY: test-docker
|
.PHONY: test-docker
|
||||||
test-docker: ## Run tests in Docker
|
test-docker: ## Run tests in Docker
|
||||||
docker-compose up -d --remove-orphans test
|
docker-compose up -d --remove-orphans test
|
||||||
|
@ -38,9 +38,10 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupCmd = &cobra.Command{
|
setupCmd = &cobra.Command{
|
||||||
Use: "setup",
|
Use: "setup",
|
||||||
Short: "Setup a certificate signing server",
|
Short: "Setup a certificate signing server",
|
||||||
RunE: cmdSetup,
|
RunE: cmdSetup,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
}
|
}
|
||||||
|
|
||||||
runCmd = &cobra.Command{
|
runCmd = &cobra.Command{
|
||||||
@ -77,8 +78,9 @@ var (
|
|||||||
// NB: cert and key paths overridden in setup
|
// NB: cert and key paths overridden in setup
|
||||||
CA identity.CASetupConfig
|
CA identity.CASetupConfig
|
||||||
// NB: cert and key paths overridden in setup
|
// NB: cert and key paths overridden in setup
|
||||||
Identity identity.SetupConfig
|
Identity identity.SetupConfig
|
||||||
certificates.CertSignerConfig
|
Signer certificates.CertSignerConfig
|
||||||
|
Overwrite bool `default:"false" help:"if true ca, identity, and authorization db will be overwritten/truncated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
runCfg struct {
|
runCfg struct {
|
||||||
@ -105,11 +107,20 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfDir = fpath.ApplicationDir("storj", "cert-signing")
|
defaultConfDir = fpath.ApplicationDir("storj", "cert-signing")
|
||||||
|
confDir *string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
dirParam := cfgstruct.FindConfigDirParam()
|
||||||
|
if dirParam != "" {
|
||||||
|
defaultConfDir = dirParam
|
||||||
|
}
|
||||||
|
confDir = rootCmd.PersistentFlags().String("config-dir", defaultConfDir, "main directory for captplanet configuration")
|
||||||
|
|
||||||
rootCmd.AddCommand(setupCmd)
|
rootCmd.AddCommand(setupCmd)
|
||||||
cfgstruct.Bind(setupCmd.Flags(), &setupCfg, cfgstruct.ConfDir(defaultConfDir))
|
cfgstruct.Bind(setupCmd.Flags(), &setupCfg, cfgstruct.ConfDir(defaultConfDir))
|
||||||
|
rootCmd.AddCommand(runCmd)
|
||||||
|
cfgstruct.Bind(runCmd.Flags(), &runCfg, cfgstruct.ConfDir(defaultConfDir))
|
||||||
rootCmd.AddCommand(authCmd)
|
rootCmd.AddCommand(authCmd)
|
||||||
authCmd.AddCommand(authCreateCmd)
|
authCmd.AddCommand(authCreateCmd)
|
||||||
cfgstruct.Bind(authCreateCmd.Flags(), &authCreateCfg, cfgstruct.ConfDir(defaultConfDir))
|
cfgstruct.Bind(authCreateCmd.Flags(), &authCreateCfg, cfgstruct.ConfDir(defaultConfDir))
|
||||||
@ -120,7 +131,12 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cmdSetup(cmd *cobra.Command, args []string) error {
|
func cmdSetup(cmd *cobra.Command, args []string) error {
|
||||||
setupDir, err := filepath.Abs(defaultConfDir)
|
setupDir, err := filepath.Abs(*confDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.MkdirAll(setupDir, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -134,21 +150,21 @@ func cmdSetup(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := setupCfg.NewAuthDB(); err != nil {
|
if setupCfg.Overwrite {
|
||||||
return err
|
setupCfg.CA.Overwrite = true
|
||||||
|
setupCfg.Identity.Overwrite = true
|
||||||
|
setupCfg.Signer.Overwrite = true
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.MkdirAll(setupDir, 0700)
|
if _, err := setupCfg.Signer.NewAuthDB(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
setupCfg.CA.CertPath = filepath.Join(setupDir, "ca.cert")
|
setupCfg.CA.CertPath = filepath.Join(setupDir, "ca.cert")
|
||||||
setupCfg.CA.KeyPath = filepath.Join(setupDir, "ca.key")
|
setupCfg.CA.KeyPath = filepath.Join(setupDir, "ca.key")
|
||||||
setupCfg.Identity.CertPath = filepath.Join(setupDir, "identity.cert")
|
setupCfg.Identity.CertPath = filepath.Join(setupDir, "identity.cert")
|
||||||
setupCfg.Identity.KeyPath = filepath.Join(setupDir, "identity.key")
|
setupCfg.Identity.KeyPath = filepath.Join(setupDir, "identity.key")
|
||||||
|
|
||||||
err = identity.SetupCA(process.Ctx(cmd), setupCfg.CA)
|
err = identity.SetupIdentity(process.Ctx(cmd), setupCfg.CA, setupCfg.Identity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -158,6 +174,7 @@ func cmdSetup(cmd *cobra.Command, args []string) error {
|
|||||||
"ca.key-path": setupCfg.CA.KeyPath,
|
"ca.key-path": setupCfg.CA.KeyPath,
|
||||||
"identity.cert-path": setupCfg.Identity.CertPath,
|
"identity.cert-path": setupCfg.Identity.CertPath,
|
||||||
"identity.key-path": setupCfg.Identity.KeyPath,
|
"identity.key-path": setupCfg.Identity.KeyPath,
|
||||||
|
"log.level": "info",
|
||||||
}
|
}
|
||||||
return process.SaveConfig(runCmd.Flags(),
|
return process.SaveConfig(runCmd.Flags(),
|
||||||
filepath.Join(setupDir, "config.yaml"), o)
|
filepath.Join(setupDir, "config.yaml"), o)
|
||||||
@ -306,7 +323,7 @@ func cmdExportAuth(cmd *cobra.Command, args []string) error {
|
|||||||
return errs.New("Either use `--emails-path` or positional args, not both.")
|
return errs.New("Either use `--emails-path` or positional args, not both.")
|
||||||
}
|
}
|
||||||
emails = args
|
emails = args
|
||||||
} else if authExportCfg.All {
|
} else if len(args) == 0 || authExportCfg.All {
|
||||||
emails, err = authDB.UserIDs()
|
emails, err = authDB.UserIDs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -327,6 +344,9 @@ func cmdExportAuth(cmd *cobra.Command, args []string) error {
|
|||||||
case "-":
|
case "-":
|
||||||
output = os.Stdout
|
output = os.Stdout
|
||||||
default:
|
default:
|
||||||
|
if err := os.MkdirAll(filepath.Dir(authExportCfg.Out), 0600); err != nil {
|
||||||
|
return errs.Wrap(err)
|
||||||
|
}
|
||||||
output, err = os.OpenFile(authExportCfg.Out, os.O_CREATE, 0600)
|
output, err = os.OpenFile(authExportCfg.Out, os.O_CREATE, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"storj.io/storj/internal/fpath"
|
"storj.io/storj/internal/fpath"
|
||||||
|
"storj.io/storj/pkg/certificates"
|
||||||
"storj.io/storj/pkg/cfgstruct"
|
"storj.io/storj/pkg/cfgstruct"
|
||||||
"storj.io/storj/pkg/identity"
|
"storj.io/storj/pkg/identity"
|
||||||
"storj.io/storj/pkg/kademlia"
|
"storj.io/storj/pkg/kademlia"
|
||||||
@ -64,6 +65,7 @@ var (
|
|||||||
setupCfg struct {
|
setupCfg struct {
|
||||||
CA identity.CASetupConfig
|
CA identity.CASetupConfig
|
||||||
Identity identity.SetupConfig
|
Identity identity.SetupConfig
|
||||||
|
Signer certificates.CertSigningConfig
|
||||||
Overwrite bool `default:"false" help:"whether to overwrite pre-existing configuration files"`
|
Overwrite bool `default:"false" help:"whether to overwrite pre-existing configuration files"`
|
||||||
}
|
}
|
||||||
diagCfg struct {
|
diagCfg struct {
|
||||||
@ -137,14 +139,28 @@ func cmdSetup(cmd *cobra.Command, args []string) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is only applicable once we stop deleting the entire config dir on overwrite
|
||||||
|
// (see https://storjlabs.atlassian.net/browse/V3-1013)
|
||||||
|
// (see https://storjlabs.atlassian.net/browse/V3-949)
|
||||||
|
if setupCfg.Overwrite {
|
||||||
|
setupCfg.CA.Overwrite = true
|
||||||
|
setupCfg.Identity.Overwrite = true
|
||||||
|
}
|
||||||
setupCfg.CA.CertPath = filepath.Join(setupDir, "ca.cert")
|
setupCfg.CA.CertPath = filepath.Join(setupDir, "ca.cert")
|
||||||
setupCfg.CA.KeyPath = filepath.Join(setupDir, "ca.key")
|
setupCfg.CA.KeyPath = filepath.Join(setupDir, "ca.key")
|
||||||
setupCfg.Identity.CertPath = filepath.Join(setupDir, "identity.cert")
|
setupCfg.Identity.CertPath = filepath.Join(setupDir, "identity.cert")
|
||||||
setupCfg.Identity.KeyPath = filepath.Join(setupDir, "identity.key")
|
setupCfg.Identity.KeyPath = filepath.Join(setupDir, "identity.key")
|
||||||
|
|
||||||
err = identity.SetupIdentity(process.Ctx(cmd), setupCfg.CA, setupCfg.Identity)
|
if setupCfg.Signer.AuthToken != "" && setupCfg.Signer.Address != "" {
|
||||||
if err != nil {
|
err = setupCfg.Signer.SetupIdentity(process.Ctx(cmd), setupCfg.CA, setupCfg.Identity)
|
||||||
return err
|
if err != nil {
|
||||||
|
zap.S().Warn(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = identity.SetupIdentity(process.Ctx(cmd), setupCfg.CA, setupCfg.Identity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overrides := map[string]interface{}{
|
overrides := map[string]interface{}{
|
||||||
|
@ -64,16 +64,16 @@ type CertSigningConfig struct {
|
|||||||
|
|
||||||
// CertSignerConfig is a config struct for use with a certificate signing service server
|
// CertSignerConfig is a config struct for use with a certificate signing service server
|
||||||
type CertSignerConfig struct {
|
type CertSignerConfig struct {
|
||||||
Overwrite bool `help:"if true, overwrites config AND authorization db is truncated" default:"false"`
|
Overwrite bool `default:"false" help:"if true, overwrites config AND authorization db is truncated"`
|
||||||
AuthorizationDBURL string `help:"url to the certificate signing authorization database" default:"bolt://$CONFDIR/authorizations.db"`
|
AuthorizationDBURL string `default:"bolt://$CONFDIR/authorizations.db" help:"url to the certificate signing authorization database"`
|
||||||
MinDifficulty uint `help:"minimum difficulty of the requester's identity required to claim an authorization"`
|
MinDifficulty uint `default:"16" help:"minimum difficulty of the requester's identity required to claim an authorization"`
|
||||||
CA provider.FullCAConfig
|
CA identity.FullCAConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertificateSigner implements pb.CertificatesServer
|
// CertificateSigner implements pb.CertificatesServer
|
||||||
type CertificateSigner struct {
|
type CertificateSigner struct {
|
||||||
Logger *zap.Logger
|
Log *zap.Logger
|
||||||
Signer *provider.FullCertificateAuthority
|
Signer *identity.FullCertificateAuthority
|
||||||
AuthDB *AuthorizationDB
|
AuthDB *AuthorizationDB
|
||||||
MinDifficulty uint16
|
MinDifficulty uint16
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ type ClaimOpts struct {
|
|||||||
type Claim struct {
|
type Claim struct {
|
||||||
Addr string
|
Addr string
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
Identity *provider.PeerIdentity
|
Identity *identity.PeerIdentity
|
||||||
SignedChainBytes [][]byte
|
SignedChainBytes [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a new certificate signing grpc client
|
// NewClient creates a new certificate signing grpc client
|
||||||
func NewClient(ctx context.Context, ident *provider.FullIdentity, address string) (*Client, error) {
|
func NewClient(ctx context.Context, ident *identity.FullIdentity, address string) (*Client, error) {
|
||||||
tc := transport.NewClient(ident)
|
tc := transport.NewClient(ident)
|
||||||
conn, err := tc.DialAddress(ctx, address)
|
conn, err := tc.DialAddress(ctx, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -191,6 +191,94 @@ func ParseToken(tokenString string) (*Token, error) {
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupIdentity loads or creates a CA and identity and submits a certificate
|
||||||
|
// signing request request for the CA; if successful, updated chains are saved.
|
||||||
|
func (c CertSigningConfig) SetupIdentity(
|
||||||
|
ctx context.Context,
|
||||||
|
caConfig identity.CASetupConfig,
|
||||||
|
identConfig identity.SetupConfig,
|
||||||
|
) error {
|
||||||
|
caStatus := caConfig.Status()
|
||||||
|
var (
|
||||||
|
ca *identity.FullCertificateAuthority
|
||||||
|
ident *identity.FullIdentity
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if caStatus == identity.CertKey && !caConfig.Overwrite {
|
||||||
|
ca, err = caConfig.FullConfig().Load()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if caStatus != identity.NoCertNoKey && !caConfig.Overwrite {
|
||||||
|
return identity.ErrSetup.New("certificate authority file(s) exist: %s", caStatus)
|
||||||
|
} else {
|
||||||
|
t, err := time.ParseDuration(caConfig.Timeout)
|
||||||
|
if err != nil {
|
||||||
|
return errs.Wrap(err)
|
||||||
|
}
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, t)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
ca, err = caConfig.Create(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
identStatus := identConfig.Status()
|
||||||
|
if identStatus == identity.CertKey && !identConfig.Overwrite {
|
||||||
|
ident, err = identConfig.FullConfig().Load()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if identStatus != identity.NoCertNoKey && !identConfig.Overwrite {
|
||||||
|
return identity.ErrSetup.New("identity file(s) exist: %s", identStatus)
|
||||||
|
} else {
|
||||||
|
ident, err = identConfig.Create(ca)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
signedChainBytes, err := c.Sign(ctx, ident)
|
||||||
|
if err != nil {
|
||||||
|
return errs.New("error occured while signing certificate: %s\n(identity files were still generated and saved, if you try again existnig files will be loaded)", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
signedChain, err := identity.ParseCertChain(signedChainBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ca.Cert = signedChain[0]
|
||||||
|
ca.RestChain = signedChain[1:]
|
||||||
|
err = identity.FullCAConfig{
|
||||||
|
CertPath: caConfig.FullConfig().CertPath,
|
||||||
|
}.Save(ca)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ident.RestChain = signedChain[1:]
|
||||||
|
err = identity.Config{
|
||||||
|
CertPath: identConfig.FullConfig().CertPath,
|
||||||
|
}.Save(ident)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign submits a certificate signing request given the config
|
||||||
|
func (c CertSigningConfig) Sign(ctx context.Context, ident *identity.FullIdentity) ([][]byte, error) {
|
||||||
|
client, err := NewClient(ctx, ident, c.Address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.Sign(ctx, c.AuthToken)
|
||||||
|
}
|
||||||
|
|
||||||
// Sign claims an authorization using the token string and returns a signed
|
// Sign claims an authorization using the token string and returns a signed
|
||||||
// copy of the client's CA certificate
|
// copy of the client's CA certificate
|
||||||
func (c Client) Sign(ctx context.Context, tokenStr string) ([][]byte, error) {
|
func (c Client) Sign(ctx context.Context, tokenStr string) ([][]byte, error) {
|
||||||
@ -216,7 +304,8 @@ func (c CertSignerConfig) NewAuthDB() (*AuthorizationDB, error) {
|
|||||||
authDB := new(AuthorizationDB)
|
authDB := new(AuthorizationDB)
|
||||||
switch driver {
|
switch driver {
|
||||||
case "bolt":
|
case "bolt":
|
||||||
if c.Overwrite {
|
_, err := os.Stat(source)
|
||||||
|
if c.Overwrite && err == nil {
|
||||||
if err := os.Remove(source); err != nil {
|
if err := os.Remove(source); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -264,13 +353,26 @@ func (c CertSignerConfig) Run(ctx context.Context, server *provider.Provider) (e
|
|||||||
}
|
}
|
||||||
|
|
||||||
srv := &CertificateSigner{
|
srv := &CertificateSigner{
|
||||||
Logger: zap.L(),
|
Log: zap.L(),
|
||||||
Signer: signer,
|
Signer: signer,
|
||||||
AuthDB: authDB,
|
AuthDB: authDB,
|
||||||
MinDifficulty: uint16(c.MinDifficulty),
|
MinDifficulty: uint16(c.MinDifficulty),
|
||||||
}
|
}
|
||||||
pb.RegisterCertificatesServer(server.GRPC(), srv)
|
pb.RegisterCertificatesServer(server.GRPC(), srv)
|
||||||
|
|
||||||
|
srv.Log.Info(
|
||||||
|
"Certificate signing server running",
|
||||||
|
zap.String("address", server.Addr().String()),
|
||||||
|
)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
done := ctx.Done()
|
||||||
|
<-done
|
||||||
|
if err := server.Close(); err != nil {
|
||||||
|
srv.Log.Error("closing server", zap.Error(err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
return server.Run(ctx)
|
return server.Run(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,7 +872,7 @@ func TestCertificateSigner_Sign(t *testing.T) {
|
|||||||
peerCtx := peer.NewContext(ctx, grpcPeer)
|
peerCtx := peer.NewContext(ctx, grpcPeer)
|
||||||
|
|
||||||
certSigner := &CertificateSigner{
|
certSigner := &CertificateSigner{
|
||||||
Logger: zap.L(),
|
Log: zap.L(),
|
||||||
Signer: signingCA,
|
Signer: signingCA,
|
||||||
AuthDB: authDB,
|
AuthDB: authDB,
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,14 @@ func (caS CASetupConfig) Create(ctx context.Context) (*FullCertificateAuthority,
|
|||||||
return ca, caC.Save(ca)
|
return ca, caC.Save(ca)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FullConfig converts a `CASetupConfig` to `FullCAConfig`
|
||||||
|
func (caS CASetupConfig) FullConfig() FullCAConfig {
|
||||||
|
return FullCAConfig{
|
||||||
|
CertPath: caS.CertPath,
|
||||||
|
KeyPath: caS.KeyPath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load loads a CA from the given configuration
|
// Load loads a CA from the given configuration
|
||||||
func (fc FullCAConfig) Load() (*FullCertificateAuthority, error) {
|
func (fc FullCAConfig) Load() (*FullCertificateAuthority, error) {
|
||||||
p, err := fc.PeerConfig().Load()
|
p, err := fc.PeerConfig().Load()
|
||||||
|
@ -195,6 +195,14 @@ func (is SetupConfig) Create(ca *FullCertificateAuthority) (*FullIdentity, error
|
|||||||
return fi, ic.Save(fi)
|
return fi, ic.Save(fi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FullConfig converts a `SetupConfig` to `Config`
|
||||||
|
func (is SetupConfig) FullConfig() Config {
|
||||||
|
return Config{
|
||||||
|
CertPath: is.CertPath,
|
||||||
|
KeyPath: is.KeyPath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load loads a FullIdentity from the config
|
// Load loads a FullIdentity from the config
|
||||||
func (ic Config) Load() (*FullIdentity, error) {
|
func (ic Config) Load() (*FullIdentity, error) {
|
||||||
c, err := ioutil.ReadFile(ic.CertPath)
|
c, err := ioutil.ReadFile(ic.CertPath)
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zeebo/errs"
|
"github.com/zeebo/errs"
|
||||||
"go.uber.org/zap"
|
|
||||||
|
|
||||||
"storj.io/storj/pkg/utils"
|
"storj.io/storj/pkg/utils"
|
||||||
"storj.io/storj/storage"
|
"storj.io/storj/storage"
|
||||||
@ -421,13 +420,11 @@ func NewRevDB(revocationDBURL string) (*RevocationDB, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrRevocationDB.Wrap(err)
|
return nil, ErrRevocationDB.Wrap(err)
|
||||||
}
|
}
|
||||||
zap.S().Info("Starting overlay cache with BoltDB")
|
|
||||||
case "redis":
|
case "redis":
|
||||||
db, err = NewRevocationDBRedis(revocationDBURL)
|
db, err = NewRevocationDBRedis(revocationDBURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrRevocationDB.Wrap(err)
|
return nil, ErrRevocationDB.Wrap(err)
|
||||||
}
|
}
|
||||||
zap.S().Info("Starting overlay cache with Redis")
|
|
||||||
default:
|
default:
|
||||||
return nil, ErrRevocationDB.New("database scheme not supported: %s", driver)
|
return nil, ErrRevocationDB.New("database scheme not supported: %s", driver)
|
||||||
}
|
}
|
||||||
|
79
scripts/test-certificate-signing.sh
Executable file
79
scripts/test-certificate-signing.sh
Executable file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -o errexit
|
||||||
|
|
||||||
|
trap "echo ERROR: exiting due to error; exit" ERR
|
||||||
|
trap "exit" INT TERM
|
||||||
|
trap "kill 0" EXIT
|
||||||
|
|
||||||
|
. $(dirname $0)/utils.sh
|
||||||
|
|
||||||
|
user_id="user@example.com"
|
||||||
|
signer_address="127.0.0.1:8888"
|
||||||
|
difficulty=16
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if [[ -z ${bg+x} ]]; then
|
||||||
|
kill ${bg}
|
||||||
|
fi
|
||||||
|
|
||||||
|
dirs="$tmp $tmp_build_dir"
|
||||||
|
for dir in ${dirs}; do
|
||||||
|
if [[ ! -z ${dir+x} ]]; then
|
||||||
|
rm -rf ${dir}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
temp_build storagenode certificates
|
||||||
|
tmp=$(mktemp -d)
|
||||||
|
trap "rm -rf ${tmp} ${tmp_build_dir}; cleanup" EXIT
|
||||||
|
|
||||||
|
certificates_dir=${tmp}/cert-signing
|
||||||
|
storagenode_dir=${tmp}/storagenode
|
||||||
|
|
||||||
|
# TODO: create separate signer CA and use `--signer.ca` options
|
||||||
|
# --signer.ca.cert-path ${signer_cert} \
|
||||||
|
# --signer.ca.key-path ${signer_key} \
|
||||||
|
|
||||||
|
echo "setting up certificate signing server"
|
||||||
|
$certificates setup --config-dir ${certificates_dir} \
|
||||||
|
--signer.min-difficulty ${difficulty}
|
||||||
|
|
||||||
|
echo "creating test authorization"
|
||||||
|
$certificates auth create --config-dir ${certificates_dir} \
|
||||||
|
1 ${user_id} >/dev/null 2>&1
|
||||||
|
|
||||||
|
export_tokens() {
|
||||||
|
$certificates auth export --config-dir ${certificates_dir} \
|
||||||
|
--out -
|
||||||
|
}
|
||||||
|
token=$(export_tokens 2>&1|cut -d , -f 2|grep -oE "$user_id:\w+")
|
||||||
|
|
||||||
|
echo "starting certificate signing server"
|
||||||
|
$certificates run --config-dir ${certificates_dir} \
|
||||||
|
--server.address ${signer_address} &
|
||||||
|
bg=$!
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
echo "setting up storage node"
|
||||||
|
$storagenode setup --config-dir ${storagenode_dir} \
|
||||||
|
--ca.difficulty ${difficulty} \
|
||||||
|
--signer.address ${signer_address} \
|
||||||
|
--signer.auth-token ${token}
|
||||||
|
|
||||||
|
ca_chain_len=$(cat ${storagenode_dir}/ca.cert|grep "BEGIN CERTIFICATE"|wc -l)
|
||||||
|
ident_chain_len=$(cat ${storagenode_dir}/identity.cert|grep "BEGIN CERTIFICATE"|wc -l)
|
||||||
|
failures=0
|
||||||
|
if [[ ! ${ca_chain_len} == 2 ]]; then
|
||||||
|
echo "FAIL: incorrect storage node CA chain length; expected: 2; actual: ${ca_chain_len}"
|
||||||
|
failures=$((failures+1))
|
||||||
|
fi
|
||||||
|
if [[ ! ${ident_chain_len} == 3 ]]; then
|
||||||
|
echo "FAIL: incorrect storage node identty chain length; expected: 2; actual: ${ident_chain_len}"
|
||||||
|
failures=$((failures+1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${failures} == 0 ]]; then
|
||||||
|
echo "SUCCESS: all expectations met!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit ${failures}
|
@ -33,8 +33,8 @@ build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
temp_build() {
|
temp_build() {
|
||||||
tmp_dir=$(mktemp -d)
|
declare -g tmp_build_dir=$(mktemp -d)
|
||||||
build ${tmp_dir} $@
|
build ${tmp_build_dir} $@
|
||||||
}
|
}
|
||||||
|
|
||||||
check_help() {
|
check_help() {
|
||||||
|
Loading…
Reference in New Issue
Block a user