postgresql之用户认证

PG通过用$PGDATA目录下的pg_hba.conf文件来设置用户认证的方式。
pg_hba.conf文件的格式是一组纪录,每条一行。每条记录指定一个连接类型、一个数据库名称、一个用户名、一个客户端地址范围、认证方法。 如下所示:

local         database  user  auth-method [auth-options]
host          database  user  address     auth-method  [auth-options]
hostssl       database  user  address     auth-method  [auth-options]
hostnossl     database  user  address     auth-method  [auth-options]
hostgssenc    database  user  address     auth-method  [auth-options]
hostnogssenc  database  user  address     auth-method  [auth-options]
host          database  user  IP-address  IP-mask      auth-method  [auth-options]
hostssl       database  user  IP-address  IP-mask      auth-method  [auth-options]
hostnossl     database  user  IP-address  IP-mask      auth-method  [auth-options]
hostgssenc    database  user  IP-address  IP-mask      auth-method  [auth-options]
hostnogssenc  database  user  IP-address  IP-mask      auth-method  [auth-options]
复制代码

注意:当建立连接时,服务器将按顺序处理文件中的行,并使用与连接属性匹配的第一行来确定将使用的身份认证方法。如果验证失败,则不会考虑后续记录。

此篇,我们只关注pg它支持的auth method(身份认证方法)。

auth method 身份认证方法

Auth-method:指定连接与此条记录匹配时使用的身份认证方法。 可选项有: trust、reject、scram-sha-256、md5、password、gss、sspi、ident、peer、ldap、radius、cert、pam、bsd。

接下来我们来看几种比较常用的认证方式。

  • trust认证:即trust。只要知道数据库用户名就不需要密码或ident就能登录,建议不要在生产环境中使用。

  • 基于密码的身份验证。有:password、md5、scram-sha-256。

    • password:password以明文形式发送密码,因此很容易受到密码嗅探攻击。
    • md5:采用了一种challege-response机制,并在服务器上存储散列密码,多年来也一直是pg首选的密码散列机制。但是如果攻击者设法从服务器窃取了密码散列,则无法提供保护。md5现在被设为是不安全的认证方法。
    • scram-sha-256 :从10.0开始被引入,可以避免攻击者获得对散列的访问权时出现问题。是目前被认为安全的加密散列机制。
  • peer认证:Peer 认证方法通过从内核获得客户端的操作系统用户名并把它用作被允许的数据库用户名(和可选的用户名映射)来工作。这种方法只在本地连接上支持。

  • indent认证:从身份验证服务器获取客户端操作系统用户名,并将其用作允许的数据库用户名(具有可选的用户名映射)。这只在TCP/IP连接上支持。用法与peer认证类似。使用ident认证方式,需要具备同名用户或建立映射用户。建立映射用户需要配置pg_ident.conf文件。

从md5升级到SCRAM

上面我们提到md5是不安全的,scram-sha-256是安全的。出于安全考虑,我们也许会需要将服务器的认证方式从md5升级为scram-sha-256。

对于新上的实例我们可以使用scram-sha-256认证方法。但是存量实例应该怎么升级呢?scram-sha-256是从10.0引入的,如果想支持,需要确保服务器版本高于10.0,同时确保连接PostgreSQL数据库的客户端兼容了SCRAM。

1、修改password_encryption参数

在pg中,每个数据库用户的密码存储在pg_authid系统表中。

postgres=# select * from pg_authid where  rolname='test_user';
-[ RECORD 1 ]--+------------------------------------
oid            | 18732
rolname        | test_user
rolsuper       | f
rolinherit     | t
rolcreaterole  | f
rolcreatedb    | f
rolcanlogin    | t
rolreplication | f
rolbypassrls   | f
rolconnlimit   | -1
rolpassword    | md5c203df9125a021758e4693720bd5e8a7
rolvaliduntil  |
复制代码

我们看到test_user的rolpassword字段的前缀是md5,说明test_user的密码是采用md5方式加密的。用户的密码采用什么方式存储,取决于配置参数password_encryption。

查看下服务器password_encryption的值。

postgres=# show  password_encryption;
 password_encryption
---------------------
 md5
(1 row)
复制代码

可以看到此时password_encryption的值是md5,那么升级第一步,就是要先把这个参数修改为scram-sha-256。

postgresql.conf

password_encryption = scram-sha-256       # scram-sha-256 or md5
复制代码

reload

pg_ctl reload -D $PGDATA
复制代码

用户重新设置密码

我们将password_encryption设置为scram-she-256之后,需要将用户的密码重置,这样用户的密码将会使用scram-sha-256进行加密存储。

postgres=# select * from pg_authid where  rolname='test_user';
-[ RECORD 1 ]--+------------------------------------
oid            | 18732
rolname        | test_user
rolsuper       | f
rolinherit     | t
rolcreaterole  | f
rolcreatedb    | f
rolcanlogin    | t
rolreplication | f
rolbypassrls   | f
rolconnlimit   | -1
rolpassword    | md5c203df9125a021758e4693720bd5e8a7
rolvaliduntil  |

postgres=# show password_encryption;
-[ RECORD 1 ]-------+--------------
password_encryption | scram-sha-256

postgres=# alter user test_user password '123456';
ALTER ROLE
postgres=# select * from pg_authid where  rolname='test_user';
-[ RECORD 1 ]--+--------------------------------------------------------------------------------------------------------------------------------------
oid            | 18732
rolname        | test_user
rolsuper       | f
rolinherit     | t
rolcreaterole  | f
rolcreatedb    | f
rolcanlogin    | t
rolreplication | f
rolbypassrls   | f
rolconnlimit   | -1
rolpassword    | SCRAM-SHA-256$4096:5r2cxn7R7pBAdwuW5vmBbQ==$zTphVvxaEiIktUFESJF9mERxARhc4xg2IIGYdHs9deQ=:9qUoKlrJ/fKKM9bYIazKlcCTY6RR/mJkhaGsoXODN8k=
rolvaliduntil  |
复制代码

3、修改pg_hba.conf

修改pg_hba.conf 本地连接的method方法为scram-sha-256

local   all       all         scram-sha-256
复制代码

注意:PG为了简化从md5方法到新的SCRAM方法的转换,如果在pg_hba.conf中将认证方法设置为md5,但服务器上用户的密码是SCRAM加密的,PG会自动选择基于SCRAM的认证。

参考:
www.cybertec-postgresql.com/en/from-md5…
www.modb.pro/db/40292