MariaDB / mariadb-docker

Docker Official Image packaging for MariaDB
https://mariadb.org
GNU General Public License v2.0
759 stars 438 forks source link

[Request] Add possibility to set password hash #458

Closed TheAlgorythm closed 1 year ago

TheAlgorythm commented 1 year ago

It would be nice if I could provide a MARIADB_ROOT_PASSWORD_HASH and MARIADB_PASSWORD_HASH. This would greatly simplify credential management as a password hash isn't as critical as the password itself.

There is a corresponding MariaDB functionality: https://mariadb.com/kb/en/create-user/#identified-by-password-password_hash

https://github.com/MariaDB/mariadb-docker/blob/master/docker-entrypoint.sh#L353 could be extended with a case like

CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$userPasswordHashEscaped';

https://github.com/MariaDB/mariadb-docker/blob/master/docker-entrypoint.sh#L291 could be changed in the same way.

grooverdan commented 1 year ago

I'm ok with the concept. Its even easier as the hash doesn't need to be escaped as nothing in the hash falls into the special SQL handling category. Did you want to create a PR?

TheAlgorythm commented 1 year ago

I can try to create a PR.

Should I change the docker-entrypoint.sh of the root?

grooverdan commented 1 year ago

Added to coming release https://github.com/docker-library/official-images/pull/13184

TheAlgorythm commented 1 year ago

Thank you for your help to implement this significant security feature.

TheAlgorythm commented 1 year ago

What is the standard way to update the README of Dockerhub?

martadinata666 commented 1 year ago

Im seeing this and pretty interesting, is there a way generate the hash?

TheAlgorythm commented 1 year ago

is there a way generate the hash?

@martadinata666

The Hash is basically two encapsulated SHA-1 hashes where the outer digest is binary. In Python it would be something like this:

import hashlib, getpass

def mysql_hash(pw: str) -> str:
    pw = pw.encode()
    mid = hashlib.sha1(pw).digest()
    inner = hashlib.sha1(mid).hexdigest()
    return '*' + inner.upper()

assert mysql_hash('mariadb') == '*54958E764CE10E50764C2EECBB71D01F08549980'

print(mysql_hash(getpass.getpass('Password: ')))
yosifkit commented 1 year ago

What is the standard way to update the README of Dockerhub?

The Docker Hub docs are over here: https://github.com/docker-library/docs/ (likely just an edit to mariadb/content.md).

grooverdan commented 1 year ago

The more direct way is SELECT PASSWORD('bob') as a query. I hadn't forgotten about docs, but if you have time to add a PR that would be much appreciated.

TheAlgorythm commented 1 year ago

The more direct way with SQL is definitely easier. But the script has the advantage to generate the hash without exposing the password in cleartext. Maybe it should be considered to include the script in the image so that it's possible to generate the hash via docker exec. Or is this considered bloat?

TheAlgorythm commented 1 year ago

I've created a PR (https://github.com/docker-library/docs/pull/2203), but I don't know how much documentation should be added.

grooverdan commented 1 year ago

Maybe it should be considered to include the script in the image

pulling in python would be a too much,

Using the existing openssl binary and being a lot more careful about shell escaping could be possible to make a script.

root@07b740fd49ee:/# pw='mariadb'
root@07b740fd49ee:/# mid=$(echo $pw | openssl sha1 -binary)
root@07b740fd49ee:/# inner=$(echo $mid | openssl sha1 -hex)
root@07b740fd49ee:/# inner=${inner#* }
root@07b740fd49ee:/# echo "*${inner^^*}"
TheAlgorythm commented 1 year ago

Good idea. I've shortened it to an one liner. As it just uses pipes, shell escaping shouldn't be a problem.

echo -n "Password: " && (stty -echo && head -n 1 | tr -d '\n' && stty echo) | openssl sha1 -binary | openssl sha1 -hex | awk '{print "*"toupper($0)}'