※この記事にはアフィリエイト広告(プロモーション)が含まれます。
この記事の出力は PostgreSQL 18.6(Ubuntu 26.04)で採りました。
まず見る(結論)
ALTER USER app PASSWORD 'NewPass2'; -- スーパーユーザーか、権限のあるロールで
ALTER USER CURRENT_USER PASSWORD 'NewPass2'; -- 自分のパスワード
\password app -- psql のメタコマンド(2回入力を求められる)
# postgres のパスワードを忘れた(Linux・既定の pg_hba.conf)
sudo -u postgres psql
postgres=# \password postgres
パスワードは単一引用符で囲みます。二重引用符(PASSWORD "NewPass4")も syntax error です。
通らない書き方
| SQL | エラー |
|---|---|
ALTER USER app PASSWORD NewPass4 |
syntax error at or near "NewPass4" |
ALTER USER app WITH PASSWORD = 'NewPass5' |
syntax error at or near "=" |
ALTER USER app IDENTIFIED BY 'NewPass5'(MySQL・Oracle の書き方) |
unrecognized role option "identified" |
ALTER USER nosuch PASSWORD 'x' |
role "nosuch" does not exist |
WITH は付けても付けなくても同じです(ALTER ROLE app WITH PASSWORD '...' も通る)。MySQL の書き方は MySQLのパスワード変更にまとめています。
誰が誰のパスワードを変えられるか
一般ユーザー app でログインして試しました。
| SQL | 結果 |
|---|---|
ALTER USER app PASSWORD '...'(自分) |
成功 |
ALTER USER CURRENT_USER PASSWORD '...' |
成功 |
ALTER USER app2 PASSWORD '...'(他人) |
permission denied to alter role |
ALTER USER app VALID UNTIL 'infinity'(自分の有効期限) |
permission denied to alter role |
他人のパスワードを変えたときの DETAIL は To change another role's password, the current user must have the CREATEROLE attribute and the ADMIN option on the role. でした。PostgreSQL 16 からは CREATEROLE だけでは足りず、相手のロールに対する ADMIN OPTION も要ります。ロールの作り方と属性は ユーザー作成の記事に書きました。
変更したあとの動き
- 変更直後から、古いパスワードは
password authentication failed for user "app"で弾かれる。reload や再起動は要らない - ログイン済みの接続は切れない。ある接続を開いたまま別の接続からパスワードを変えても、その接続は続けて SQL を実行できた。切りたい接続は pg_terminate_backend で切る
- pg_hba.conf で
peerになっている接続(sudo -u postgres psqlなど)はパスワードを見ないので、変更の影響を受けない
パスワードの保存形式を確認する
SELECT rolname, left(rolpassword, 14) FROM pg_authid WHERE rolname = 'app';
-- app | SCRAM-SHA-256$
pg_authid はスーパーユーザーしか読めません。pg_roles の rolpassword は誰が見ても ******** です。保存されるのはハッシュで、元のパスワードは取り出せません。
md5 で保存すると SCRAM の設定でログインできない
SET password_encryption = 'md5';
ALTER USER app PASSWORD 'Md5Pass10';
-- WARNING: setting an MD5-encrypted password
-- DETAIL: MD5 password support is deprecated and will be removed in a future release of PostgreSQL.
Ubuntu の既定の pg_hba.conf は scram-sha-256 なので、md5 で保存したユーザーは正しいパスワードでも password authentication failed になりました。password_encryption を scram-sha-256 に戻して ALTER USER をやり直すと SCRAM の形式に戻ります。
サーバーログに平文が残る場面
| 状況 | サーバーログ |
|---|---|
log_statement = 'none'(既定)で成功 |
残らない |
log_statement = 'ddl' か 'all' で成功 |
LOG: statement: ALTER USER app PASSWORD 'LoggedPass21' |
文がエラーになった(例: VALID UNTIL 'bad-date' を一緒に書いた) |
STATEMENT: ALTER USER app PASSWORD 'ErrPass14' VALID UNTIL 'bad-date'; |
エラーになった文は既定の設定でもログに残ります(log_min_error_statement の既定が error)。psql の履歴ファイル ~/.psql_history にも打った文が残ります。
PostgreSQL のドキュメントによると、\password は入力したパスワードを psql 側でハッシュにしてから ALTER ROLE を送ります。ハッシュを渡しても、平文を渡したときと同じようにパスワードが設定されます。別のユーザーの rolpassword をそのまま ALTER ROLE app PASSWORD '<ハッシュ>' に渡すと、app はそのユーザーのパスワードでログインできるようになりました。
有効期限と無効化
ALTER USER app VALID UNTIL '2020-01-01'; -- 期限切れにする
ALTER USER app VALID UNTIL 'infinity'; -- 期限なしに戻す
ALTER USER app PASSWORD NULL; -- パスワードを消す
どちらもクライアントに返るのは password authentication failed だけで、理由はサーバーログの DETAIL で分かります。期限切れは User "app" has an expired password.、パスワードを消した場合は User "app" has no password assigned. でした。DETAIL の一覧は password authentication failed の記事に書きました。
postgres のパスワードを忘れたとき
Ubuntu のパッケージで入れた PostgreSQL の pg_hba.conf は、1行目が local all postgres peer です。OS の postgres ユーザーでソケットから入ればパスワードは聞かれません。
sudo -u postgres psql # peer 認証で入れる
psql -U postgres # root や別の OS ユーザーからは Peer authentication failed
psql -h 127.0.0.1 -U postgres # TCP は scram-sha-256 なのでパスワードが要る
初期状態の postgres にはパスワードが設定されていません(rolpassword が NULL)。-h 127.0.0.1 で入りたいなら、上の方法で入って \password postgres で設定します。pg_hba.conf を trust に書き換えて入る方法もあります。ただ、戻し忘れると誰でもパスワード無しで入れるので、peer で入れるならそちらを使います。
関連: PostgreSQLのユーザー作成 / password authentication failed / PostgreSQLに外部から接続できない