動かざることバグの如し

近づきたいよ 君の理想に

ZabbixログインパスワードをDBから初期化する

環境

  • Zabbix 7.0 LTS

やりたいこと

Zabbixにパスワード忘れてログインできなくなった。Adminなので他のユーザーで入って初期化、ということもできない。

こういうときはデータベースから直接パスワードリセットが一番早い。

コマンド

Zabbixのログインパスワードはデータベースのusers.passwdにハッシュで保存されている。Adminでログインできない状態なら、DBに直接入ってAdminのハッシュを差し替えるのが早い。

DBに接続

mysql -u root -p zabbix

対象ユーザーを確認(Zabbix 5.0以降)

SELECT username, passwd FROM users WHERE username = 'Admin';

ここでは「MyNewPass123」を作る例とする。

python3 -c "import bcrypt; print(bcrypt.hashpw(b'MyNewPass123', bcrypt.gensalt(rounds=10)).decode())"

生成したハッシュを貼り付けて更新

UPDATE users SET passwd = '$2a$10$...' WHERE username = 'Admin';

備考 なぜ毎回ハッシュ結果が変わるのか

bcryptは「同じパスワードでも毎回違うハッシュが出る」のが仕様だ。内部でランダムなソルトを生成して、それをハッシュ文字列に埋め込むからである($2a$10$...の中にコストやソルト情報が入っている)。

そのため、パスワードが同じでもハッシュが一致する必要はない。ログイン時は「入力したパスワード」と「DBに入っているハッシュ(ソルト込み)」から再計算して一致判定する。

動作確認用の簡単なスクリプトを用意した。

python3 - <<'PY'
import bcrypt
pw = b'hogehoge'
h1 = bcrypt.hashpw(pw, bcrypt.gensalt(rounds=10))
h2 = bcrypt.hashpw(pw, bcrypt.gensalt(rounds=10))
print(h1.decode())
print(h2.decode())
print("h1==h2:", h1 == h2)
print("check1:", bcrypt.checkpw(pw, h1))
print("check2:", bcrypt.checkpw(pw, h2))
PY

実行結果 当然両方ともtrueになる。

$2b$10$sbxFAbKtaqvhcIH3XR2HTuXRczfQ81AsBg/U.mfpH164EztW3O8Zm
$2b$10$jGo/TeMJp.mApELuN7jUC.01ATc1pYC67Ze32HI0mQyhCD/gpLOr.
h1==h2: False
check1: True
check2: True

参考リンク