scality / metalk8s

An opinionated Kubernetes distribution with a focus on long-term on-prem deployments
Apache License 2.0
364 stars 45 forks source link

Add support for Admin password change #2075

Open Ebaneck opened 5 years ago

Ebaneck commented 5 years ago

Component:

'Documentation'

Why this is needed:

Users should be capable of changing the Dex statically defined admin user password at will.

What should be done:

Add documentation on how to Patch the password section of the Dex configMap via command line only

Implementation proposal (strongly recommended):

Test plan:

A successful password change

Ebaneck commented 5 years ago

Two main approaches to this:

or

gdemonet commented 5 years ago

Two main approaches to this:

  • Dex configurations are stored as a secret in MetalK8s meaning to patch the password, we need to do the following; Decode the secret, edit it, encode it again and then run the patch.

Let's see what a procedure would look like for this. Then we can decide whether to store user/password in pillar, or just have a script that performs the API calls for us.

or

  • Make the password in Dex configuration a pillar value, then call the right state with some pillar value set in CLI cc @TeddyAndrieux

Could be a formula, or just a script (kubectl plugin for MetalK8s could be a good candidate, not sure)

TeddyAndrieux commented 5 years ago

Note that with the current approach the password will be overrited when you upgrade/downgrade. For me we should put it somewhere editable by the user (then we load it with extenal pillar).

Same as bootstrap.yaml, but maybe it's not secure enough for us to have it directly in this file (IMO it's ok but as you want)

Ebaneck commented 5 years ago

Option one:

This depicts clearly a manual sequence of steps to be carried out by the user.

Ebaneck commented 5 years ago

Two main approaches to this:

  • Dex configurations are stored as a secret in MetalK8s meaning to patch the password, we need to do the following; Decode the secret, edit it, encode it again and then run the patch.

Let's see what a procedure would look like for this. Then we can decide whether to store user/password in pillar, or just have a script that performs the API calls for us.

@gdemonet The entire manual procedure has been documented below

or

  • Make the password in Dex configuration a pillar value, then call the right state with some pillar value set in CLI cc @TeddyAndrieux

Could be a formula, or just a script (kubectl plugin for MetalK8s could be a good candidate, not sure)

gdemonet commented 5 years ago

Note that with the current approach the password will be overrited when you upgrade/downgrade. For me we should put it somewhere editable by the user (then we load it with extenal pillar).

Indeed, keeping this value around makes sense, maybe it doesn't need to be a local file, but simply a Secret. Keeping it "manually editable" however doesn't look like a good idea to me, however. IMHO, we should never store a clear text password (or base64-encoded, for that matter), anywhere. Instead, rely on some usual encryption system, and store the encrypted string somewhere.

NicolasT commented 5 years ago

No matter what, this conversation should not be about this preprovisioned 'admin' user and its password (a user which one may want to delete from the system!), but about all statically provisioned user(s) and their creds.

Also, we shouldn't ever store any kind of non-hashed passwords anywhere whatsoever. Any design which includes such storage must be ruled out from the very start.

gdemonet commented 5 years ago
  • Backup the existing Secret by running: kubectl get secrets dex --namespace=metalk8s-auth -o yaml > dex.yaml.bak
  • Copy the backup configurations to a new file cp dex.yaml.bak dex.yaml
  • Obtain and decode the Dex configuration from the secrets by running kubectl get secrets dex -n metalk8s-auth -o 'go-template={{index .data "config.yaml"}}' | base64 --decode > patch-config.yaml

Definitely, we need some tooling to manage this configuration (it may need to go further than just the static users, we'll see). Maybe a kubectl metalk8s edit dex-config could be nice. In the meantime, let's setup something that focuses on managing static users through CLI.

  • Generate a new password in bcrypted format using

    • Install bcrypt using pip install bcrypt
    • Obtain a bcrypted password hash using the python command below

    python -c 'import bcrypt; print(bcrypt.hashpw("new-password-goes-here", bcrypt.gensalt(rounds=12)))'

We would need to provide that functionality to our users, asking for a pip install is not acceptable in offline environments (and should not be recommended anywhere in production, actually).

  • Edit the patch file patch-config.yaml replacing the field hash: << Replace_with_generated_hash_from_step_above >>
  • Encode the patch file in base64 cat patch-config.yaml | base64 > new-patch.yaml
  • Copy the content of new-patch.yaml and replace the encoded string in dex.yaml
  • Apply the new configurations by running $ kubectl patch secrets dex --patch "$(cat dex.yaml)" -n metalk8s-auth

That would be part of our tooling as well. Maybe have some simple command to replace the existing Dex configuration in this "well-known" Secret.

  • Restart the Dex pods "Crictl stop command goes here"

I think kubectl rollout restart metalk8s-auth/dex would be enough.