忘記 PostgreSQL 管理員密碼時,如果主機上的程式還能正常使用資料庫,可以先檢查現有的連線設定。安裝或部署時留下的設定,有可能還保留著需要的帳密。
這次遇到的情況是:一台 Mac 上的 PostgreSQL 正常運作,SSH 也能登入,但管理員帳密已經不記得了。原本打算從遠端專案的設定檔找起,後來改查同一台主機上的 Gitea。
Gitea 的設定確實有資料庫密碼,不過那是 Gitea 專用帳號。再往下查,才確認 PostgreSQL 的超級管理員是 example_admin,密碼則保存在遠端使用者的 .pgpass。
這篇記錄找回既有帳密與確認管理員身分的過程。IP、帳號、資料庫名稱與設定檔位置均已換成示例,密碼以占位文字呈現;查證步驟與權限判斷保留。操作時請換成自己環境的資料,範例位址與帳號不能直接用來登入。
確認主機與操作位置
| 項目 | 環境與示例代稱 |
|---|---|
| 資料庫主機 | macOS |
| 主機位址 | 192.0.2.10 |
| PostgreSQL | 18.x,Homebrew 安裝 |
| PostgreSQL 連接埠 | 5432 |
| SSH 帳號 | example_admin |
| Gitea 資料庫帳號 | example_app_user |
| 查證後的 PostgreSQL 管理員 | example_admin |
先從自己的電腦登入遠端主機:
ssh example_admin@192.0.2.10
後續的檔案檢查與資料庫指令,都在這個 SSH 工作階段內執行。這裡的 ~ 是遠端登入使用者的家目錄。
SSH 帳號與 PostgreSQL 帳號分別由作業系統和資料庫管理。即使兩邊都叫 example_admin,也不能據此認定密碼相同。
當時透過 SSH 執行指令,曾遇到找不到 psql 的情況,改用安裝位置中的完整路徑後才正常執行。以下指令統一用 psql 表示;如果自己的環境也找不到它,請先確認安裝位置,再使用完整路徑執行。
psql --version
版本輸出示意如下,實際修訂版號已省略:
psql (PostgreSQL) 18.x (Homebrew)
從 Gitea 找到能登入的資料庫帳號
Gitea 的資料庫連線資訊保存在 app.ini。以下以通用路徑表示,請換成自己主機上的設定檔位置:
/path/to/gitea/app.ini
開啟檔案,查看 [database] 區段:
less /path/to/gitea/app.ini
與這次查找有關的內容如下,帳號與資料庫名稱已換成示例:
[database]
DB_TYPE = postgres
HOST = 127.0.0.1:5432
NAME = example_app_db
USER = example_app_user
PASSWD = <Gitea 資料庫密碼>
SSL_MODE = disable
這份設定告訴我們,Gitea 連到本機的 PostgreSQL,使用 example_app_user 帳號連到 example_app_db 資料庫。它提供了一個可以登入查詢的入口,但還不能證明這個帳號有管理員權限。
使用設定檔裡的密碼登入:
psql -X -W \
-h 127.0.0.1 -p 5432 \
-U example_app_user -d example_app_db
-W 會要求輸入密碼,不必把密碼直接寫在指令裡。登入後,查詢目前帳號的身分:
SELECT current_user,
current_database(),
rolsuper
FROM pg_roles
WHERE rolname = current_user;
查詢結果以下列示例代稱呈現:
| current_user | current_database | rolsuper |
|---|---|---|
| example_app_user | example_app_db | false |
rolsuper = false 表示這個帳號沒有超級管理員權限。到這一步,只找到了應用程式的帳密,還需要繼續找管理員。
查出真正的 PostgreSQL 管理員
在剛才的資料庫連線中,查詢具有超級管理員權限、而且允許登入的角色:
SELECT rolname,
rolsuper,
rolcanlogin
FROM pg_roles
WHERE rolsuper = true
AND rolcanlogin = true
ORDER BY rolname;
當時查到一筆,以下用 example_admin 代替實際帳號:
| rolname | rolsuper | rolcanlogin |
|---|---|---|
| example_admin | true | true |
因此,接下來要找的是 PostgreSQL 帳號 example_admin 的密碼。
pg_roles 可以讓一般資料庫使用者查詢角色資訊;rolsuper 表示是否具有超級管理員權限,rolcanlogin 表示是否允許登入。這個檢視不會顯示真正的密碼。PostgreSQL 官方文件:pg_roles
這也是為什麼要先查角色。管理員帳號不一定叫 postgres,應用程式可以登入,也不代表它就是管理員。
從 .pgpass 找回管理員密碼
輸入 \q 離開 psql,回到遠端主機的終端機,再檢查使用者家目錄:
ls -l ~/.pgpass
less ~/.pgpass
這次在遠端登入使用者的 ~/.pgpass 找到了管理員的連線密碼。
.pgpass 是 PostgreSQL 用戶端可以讀取的密碼檔,每一行依序放主機、連接埠、資料庫、帳號和密碼:
hostname:port:database:username:password
例如,下面是一筆格式示意,並非原始檔案的完整內容:
127.0.0.1:5432:*:example_admin:<PostgreSQL 管理員密碼>
| 欄位 | 這個例子的意思 |
|---|---|
127.0.0.1 |
連到本機 PostgreSQL |
5432 |
PostgreSQL 連接埠 |
* |
可對應任意資料庫名稱 |
example_admin |
資料庫登入帳號 |
| 最後一個欄位 | 這組連線使用的密碼 |
.pgpass 的前四個欄位可以使用 *,用戶端會選用第一筆符合連線條件的紀錄。如果密碼包含 : 或 \,檔案內會使用反斜線處理;手動輸入密碼時,要還原成原本的字元。Unix 系統上的檔案權限也必須限制為只有擁有者能存取,例如 0600,否則用戶端會忽略它。PostgreSQL 官方文件:The Password File
找到檔案後,先核對主機、連接埠與帳號。檔案裡可能有其他環境的連線資料,也可能留著已經更換的舊密碼,仍需要實際登入確認。
驗證密碼與管理員權限
使用剛才查到的 example_admin 密碼,在遠端主機上建立新的連線:
psql -X -W \
-h 127.0.0.1 -p 5432 \
-U example_admin -d postgres
這裡的 -U example_admin 指定登入帳號,-d postgres 指定連線資料庫。資料庫名稱是 postgres,不代表使用的帳號也必須叫 postgres。
登入後執行:
SELECT current_user,
current_database(),
inet_server_addr(),
inet_server_port(),
rolsuper
FROM pg_roles
WHERE rolname = current_user;
驗證結果如下,登入帳號已匿名化:
| 項目 | 結果 |
|---|---|
| 登入帳號 | example_admin |
| 連線資料庫 | postgres |
| PostgreSQL 位址 | 127.0.0.1 |
| PostgreSQL 連接埠 | 5432 |
| 超級管理員權限 | true |
還有一個需要確認的地方:登入成功時,伺服器是否真的要求密碼驗證。如果該連線使用的是免密碼規則,單靠登入成功仍無法判斷剛才輸入的密碼是否正確。
以管理員身分查詢驗證規則:
SELECT line_number,
type,
database,
user_name,
address,
netmask,
auth_method,
error
FROM pg_hba_file_rules
ORDER BY line_number;
本次檢查時,IPv4 本機連線對應的設定是:
host all all 127.0.0.1/32 scram-sha-256
這條規則要求使用 SCRAM-SHA-256 驗證密碼。搭配實際登入成功與 rolsuper = true 的結果,才確認找回的是可用的 PostgreSQL 管理員帳密。檢查規則時要依檔案順序判斷,PostgreSQL 會使用第一條符合連線條件的規則。PostgreSQL 官方文件:The pg_hba.conf File
如果沒有找到 .pgpass
.pgpass 不一定存在,也不一定保存管理員帳密。如果沒有找到,可以再檢查自己有權限存取的部署設定、備份腳本、密碼管理工具,以及資料庫管理工具保存的連線資訊。每找到一組帳密,都要確認它連到哪一個 PostgreSQL,以及登入後具有哪些權限。
直接查資料庫的角色資料,也不會得到原始明文密碼。pg_roles 會遮蔽密碼欄位;權限更高的 pg_authid 保存的是密碼驗證資料,例如 SCRAM-SHA-256 的儲存格式。PostgreSQL 官方文件:pg_authid
如果所有既有設定都沒有留下可用的管理員密碼,後續才需要另外規劃密碼重設,並確認有哪些服務使用這個帳號。本次在 .pgpass 找到的密碼仍可使用,因此查找與驗證階段沒有重設密碼,也沒有修改帳號權限。
本次找回的結果
| 項目 | 已確認內容(帳號使用示例代稱) |
|---|---|
| PostgreSQL 管理員 | example_admin |
| 密碼來源 | 遠端 ~/.pgpass |
| 管理員登入測試 | 成功登入 postgres 資料庫 |
| 管理員權限 | rolsuper = true |
| 本機連線驗證方式 | scram-sha-256 |
| Gitea 專用帳號 | example_app_user,沒有超級管理員權限 |