导语
PostgreSQL 用户密码的设定通常有两种。
一是创建用户时直接指定用户密码。
create user shawnyan password 'test';
二是创建用户后更新用户密码。
alter user shawnyan password 'test';
PostgreSQL 将用户信息存储在系统表 pg_catalog.pg_authid 中。
select rolname as user, left(rolpassword,20) as passwd
from pg_catalog.pg_authid
where rolname = 'shawnyan';
user | passwd
----------+----------------------
shawnyan | SCRAM-SHA-256$4096:E
(1 row)
接下来将基于 PostgreSQL 16.2 介绍扩展 pgpasswd。
postgres=# select version();
version
-------------------------------------------------------------------------------------------------------------------
PostgreSQL 16.2-ShawnYan on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.4.1 20230605 (Red Hat 11.4.1-2), 64-bit
(1 row)
pgpasswd
类似于 Linux 中的 passwd 命令,使用 pgpasswd 可以从 Linux 命令行更改 PostgreSQL 帐户密码,无需输入任何 SQL 语句。
pgpasswd 是 PostgreSQL 扩展和独立可执行文件(无需在数据库中安装任何内容,无需运行 CREATE EXTENSION)。
下载源码:
git clone https://github.com/shawn0915/pgpasswd.git
目录结构比较简洁:
[postgres@rocky9 pgpasswd]$ ls
LICENSE Makefile META.json pgpasswd.c README.md
- LICENSE: 是本软件的许可。pgpasswd 软件根据 PostgreSQL 许可证的条款发布。许可中规定,允许任何人出于任何目的,免费使用、复制、修改和分发该软件及其文档。
- Makefile:用于自动化构建和管理软件项目,它由一系列规则和命令组成。在本工程中,提供了
all,install,clean,pgxn等四种命令。 - META.json:包含 pgpasswd 项目的元数据。元数据中包括项目名称、版本信息、维护者、许可证、要求的 PostgreSQL 版本等信息。
- pgpasswd.c:该工程的主文件,包含了项目用法的具体实现,以及一些约束条件。
- README.md:描述 pgpasswd 项目的内容和如何编译、安装、使用项目,帮助用户快速了解项目的功能和用法,从而提高项目的可用性和传播性。
其中,在项目中,我们可以看到 PASSWORD_MAX_LENGTH=30 约束,意味着密码长度不能超过 30。
工程直接编译、安装即可:
[postgres@rocky9 pgpasswd]$ make
gcc -I/opt/pgsql/include -I/opt/pgsql/include/server -c pgpasswd.c -Wall
gcc -I/opt/pgsql/include -L/opt/pgsql/lib -lpq -o pgpasswd pgpasswd.o
[postgres@rocky9 pgpasswd]$ make install
install pgpasswd /opt/pgsql/bin
可以看到将编译好的二进制文件 pgpasswd 安装到了 bin 目录下。
使用方式:
需要指定参数 -U 需要修改密码的用户名,-h 数据库连接地址,-p 数据库端口,-d postgres 系统库,否则,会提示报错 Missing parameters。
此外,可以加 -v 参数打印更多信息,比如客户端版本信息 PG libpq version,连接信息 conninfo,以及 PG 服务器的版本信息 PG server version。
[postgres@rocky9 ~]$ pgpasswd -U shawnyan -h 127.1 -p 5432 -d postgres -v
Password:
PG libpq version: 160002
conninfo: user=shawnyan host=127.1 port=5432 dbname=postgres password=test
PG server version: 160002
New password:
Confirm new password:
stmt=ALTER USER shawnyan PASSWORD 'test1'
Password changed.
用新密码测试连接:
[postgres@rocky9 ~]$ psql -U shawnyan -h 127.1
Password for user shawnyan:
psql (16.2-ShawnYan)
Type "help" for help.
postgres=>
到此,PG 扩展 pgpasswd 介绍到这里,欢迎“品尝”。
再討論:PG 密碼長度
在上文中提到,pgpasswd 只允許密碼設定長度為 30,
如果原始密碼或新密碼都超過 30,那麽程序會異常退出,無法修改密碼。
畢竟是個 TOY,不要在意這些細節,keep going…
那麽,問題來了,在 PostgreSQL 服務器中,用戶密碼最長可以設定為多少呢?
以 PostgreSQL v16 為例,用戶密碼字段為 text,
(postgres@[local]) [postgres] 20:57:41# \d pg_catalog.pg_authid
Table "pg_catalog.pg_authid"
Column | Type | Collation | Nullable | Default
----------------+--------------------------+-----------+----------+---------
oid | oid | | not null |
rolname | name | | not null |
rolsuper | boolean | | not null |
rolinherit | boolean | | not null |
rolcreaterole | boolean | | not null |
rolcreatedb | boolean | | not null |
rolcanlogin | boolean | | not null |
rolreplication | boolean | | not null |
rolbypassrls | boolean | | not null |
rolconnlimit | integer | | not null |
rolpassword | text | C | |
rolvaliduntil | timestamp with time zone | | |
Indexes:
"pg_authid_oid_index" PRIMARY KEY, btree (oid), tablespace "pg_global"
"pg_authid_rolname_index" UNIQUE CONSTRAINT, btree (rolname), tablespace "pg_global"
Tablespace: "pg_global"
這意味著,對與密碼的最大長度,PostgreSQL 并沒有一個硬性的限制。
最開始就是這樣的麽?并不是。
2020-0-03, Remove arbitrary restrictions on password length.
该补丁最初的目标是协调各种任意的密码长度受到限制,但过了一段时间,一个更好的想法出现了:
让我们摆脱那些固定的限制。
這裏的限制是指之前版本中的 100 位密碼,從 PG 14 開始,
隨著 67a472d
patch 被 merge 到 master,這一限制也被取消掉了。
當然,現在 PG 默認的加密算法為 SCRAM-SHA-256,密碼加密后,
實際表中存儲的密碼并不會很長很長很長。
更多討論:
再補充一點:
建議使用 scram-sha-256 密碼驗證方法,而不是 md5 和 password。
建議自行對用戶名和用戶密碼設立規範,比如用戶名命名規則,密碼複雜度和長度等。
– END –





