Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: make bcrypt-cost configurable #9633

Closed
wants to merge 25 commits into from
Closed

Conversation

jxuan
Copy link

@jxuan jxuan commented Apr 26, 2018

This change is to implement the feature request in #9615

@heyitsanthony
Copy link
Contributor

@jxuan There's no consensus enforcing the cost; snapshot exchange between members with different costs would break auth. Keep separate buckets for each bcrypt level? Store initial cost and always use that? Presumably not something to plumb through raft. @mitake?

@mitake
Copy link
Contributor

mitake commented Apr 26, 2018

@heyitsanthony @jxuan I see, the possible inconsistent state (the diverged bcrypt costs) is similar to #9475 . How about adding a new option for configuring the cost to etcdctl auth enable? The RPC of enabling auth goes through Raft so the inconsistent state can be avoided.

@heyitsanthony
Copy link
Contributor

heyitsanthony commented Apr 26, 2018

@mitake I checked the bcrypt code and the problem I was worried about isn't an issue. It can check bcrypt.Cost to see if it should recompute/write the new hash if CompareHashAndPassword succeeds (outside the raft path). Different members may have different costs / password hashes, but the cluster wouldn't break. Setting cost via RPC could get bit equivalence across members, but cost upgrade/downgrade for existing passwords seems impractical for that case.

@mitake
Copy link
Contributor

mitake commented Apr 26, 2018

@heyitsanthony Ah I see. Then the inconsistent state is acceptable. Thanks for checking!

Copy link
Contributor

@mitake mitake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes are good, thanks! Could you fix the trivial problem I pointed out? Also please fix the commit title for following the standard style e.g. *: make bcrypt cost configurable

@@ -36,3 +37,33 @@ func TestStartEtcdWrongToken(t *testing.T) {
t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err)
}
}

// TestStartEtcdLargeBcryptCost ensures that StartEtcd with good configs returns with error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivial nit: good configs should be bad configs?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@jxuan
Copy link
Author

jxuan commented Apr 26, 2018

@mitake the code is updated based on your feedback. Please check

@heyitsanthony Thank you for checking.

@jxuan jxuan changed the title Make bcrypt-cost configurable *: Make bcrypt-cost configurable Apr 26, 2018
@jxuan jxuan changed the title *: Make bcrypt-cost configurable *: make bcrypt-cost configurable Apr 26, 2018
@jxuan
Copy link
Author

jxuan commented Apr 26, 2018

@mitake The CI errors are not related to my code change. I ran those tests manually on my mac and they all pass. Anyway to re-trigger these tests?

Copy link
Contributor

@gyuho gyuho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please reformat the git commit title to *: make bcrypt .... And rebase from current master branch. Defer to @mitake @heyitsanthony

auth/store.go Outdated
plog.Errorf("Invalid bcrypt-cost: %d", bcryptCost)
return nil, ErrInvalidAuthOpts
}
BcryptCost = bcryptCost
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth should pass around bcyptCost values rather than sharing a global BcryptCost (racey as CI fails).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will make it private. BcryptCost is only referenced in clientv3/main_test.go and clientv3/main_test.go does not trigger anything related to bcrypt.

auth/store.go Outdated
tokenType, typeSpecificOpts, err := decomposeOpts(tokenOpts)
if err != nil {
return nil, ErrInvalidAuthOpts
}

if bcryptCost < bcrypt.MinCost || bcryptCost > bcrypt.MaxCost {
plog.Errorf("Invalid bcrypt-cost: %d", bcryptCost)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if lg != nil {
  lg.Warn(
    "invalid bcrypt cost",
    zap.Int("min-cost", bcrypt.MinCost),
    zap.Int("max-cost", bcrypt.MaxCost),
    zap.Int("given-cost", bcryptCost),
  )
}

@@ -36,3 +37,33 @@ func TestStartEtcdWrongToken(t *testing.T) {
t.Fatalf("expected %v, got %v", auth.ErrInvalidAuthOpts, err)
}
}

// TestStartEtcdLargeBcryptCost ensures that StartEtcd with invalid large bcrypt-cost returns with error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests in embed are no needed. Just unit tests around NewTokenProvider should be enough.

@@ -237,6 +237,7 @@ func newConfig() *config {

// auth
fs.StringVar(&cfg.ec.AuthToken, "auth-token", cfg.ec.AuthToken, "Specify auth token specific options.")
fs.UintVar(&cfg.ec.BcryptCost, "bcrypt-cost", cfg.ec.BcryptCost, "Bcrypt algorithm cost / strength for hashing auth passwords")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Specify bcrypt algorithm cost factor for auth password hashing."

etcdmain/help.go Outdated
@@ -148,6 +148,8 @@ Security:
Auth:
--auth-token 'simple'
Specify a v3 authentication token type and its options ('simple' or 'jwt').
--bcrypt-cost 10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+ fmt.Sprintf("%d", bcrypt.DefaultCost) +?

@@ -123,6 +123,7 @@ type etcdProcessClusterConfig struct {
noStrictReconfig bool
initialCorruptCheck bool
authTokenOpts string
bcryptCost int
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove changes from tests/e2e.

@@ -605,6 +606,7 @@ func mustNewMember(t *testing.T, mcfg memberConfig) *member {
m.MaxRequestBytes = embed.DefaultMaxRequestBytes
}
m.AuthToken = "simple" // for the purpose of integration testing, simple token is enough
m.BcryptCost = uint(bcrypt.MinCost)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed when we have unit tests inside auth package.

Copy link
Author

@jxuan jxuan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback. Fixed in new version.

auth/store.go Outdated
plog.Errorf("Invalid bcrypt-cost: %d", bcryptCost)
return nil, ErrInvalidAuthOpts
}
BcryptCost = bcryptCost
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will make it private. BcryptCost is only referenced in clientv3/main_test.go and clientv3/main_test.go does not trigger anything related to bcrypt.

@jxuan
Copy link
Author

jxuan commented Apr 30, 2018

@mitake @gyuho Code updated based on your feedback. Please review again. Thanks

@gyuho
Copy link
Contributor

gyuho commented Apr 30, 2018

@jxuan Can you squash commits? Or separate per package levels?

@jxuan
Copy link
Author

jxuan commented Apr 30, 2018

Sure. Once all tests pass, I will squash everything into one commit.

@jxuan
Copy link
Author

jxuan commented May 2, 2018

@mitake @gyuho Commit d923b1d is a squashed version of everything. Can you please review it?

@gyuho
Copy link
Contributor

gyuho commented May 2, 2018

@jxuan gofmt -w *.go should work?

@jxuan
Copy link
Author

jxuan commented May 2, 2018

To squash commits, do you recommend starting a new branch?

@gyuho
Copy link
Contributor

gyuho commented May 2, 2018

@jxuan You can just cherry-pick commits to your local branch and force push. Or just keep rebasing from latest master branch, and force push to your local branch. We don't include merge commits.

@jxuan
Copy link
Author

jxuan commented May 2, 2018

Right now it only fails on the title format check

'commit_title' started at Wed May 2 21:50:52 UTC 2018
e1d05d0 Fix format...
Expected commit title format '{", "}: '

Can you start to review to code and see if there is anything else that you would like to change? In the mean time, I am working on a squashed version for submission. Thanks,

@jxuan
Copy link
Author

jxuan commented May 3, 2018

I created a squashed version in #9687

@gyuho
Copy link
Contributor

gyuho commented May 3, 2018

@jxuan Thanks. Let's close this in favor of #9687.

@gyuho gyuho closed this May 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants