PostgreSQL的用戶登錄


轉載文章: https://www.lijiaocn.com/技巧/2018/09/28/postgres-user-manage.html

PostgreSQL的用戶登錄

說明

PostgreSQL數據庫的用法和MySQL很不一樣,新創建的用戶的創建要和pg_hba.conf中的配置對應才能成功登陸。很多人在這個地方卡殼,用Google或者Baidu搜索到一些資料,說得也不清楚。這里特別闡述一下。

PostgresSQL數據庫的基本使用——新手入門

PostgreSQL的用戶到底是這么回事?新建用戶怎樣才能用密碼登陸?

User與Role

創建用戶使用的是PostgreSQL的CREATE USER命令。在CREATE USER的命令手冊中有這樣一個說明:

CREATE USER is now an alias for CREATE ROLE. 
The only difference is that when the command is spelled CREATE USER, LOGIN is assumed by default,
whereas NOLOGIN is assumed when the command is spelled CREATE ROLE.

首先記住一點:創建User就是在創建Role

那么PostgreSQL的Role是什么?

PostgreSQL Documentation: Database Roles中有五節關於role的內容。簡單說在PostgreSQL中權限控制的目標是Role,這個Role相當於MySQL中的用戶。

可以為Role設置多種屬性,控制Role能夠執行的操作,這些屬性可以在創建的時候指定,PostgreSQL SQL Commands: CREATE ROLE:

CREATE ROLE name [ [ WITH ] option [ ... ] ]

where option can be:

      SUPERUSER | NOSUPERUSER
    | CREATEDB | NOCREATEDB
    | CREATEROLE | NOCREATEROLE
    | CREATEUSER | NOCREATEUSER
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | REPLICATION | NOREPLICATION
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
    | VALID UNTIL 'timestamp'
    | IN ROLE role_name [, ...]
    | IN GROUP role_name [, ...]
    | ROLE role_name [, ...]
    | ADMIN role_name [, ...]
    | USER role_name [, ...]
    | SYSID uid

也可以創建后,用alter修改,PostgreSQL SQL Commands: ALTER ROLE

ALTER ROLE name [ [ WITH ] option [ ... ] ]

where option can be:

      SUPERUSER | NOSUPERUSER
    | CREATEDB | NOCREATEDB
    | CREATEROLE | NOCREATEROLE
    | CREATEUSER | NOCREATEUSER
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | REPLICATION | NOREPLICATION
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
    | VALID UNTIL 'timestamp'

ALTER ROLE name RENAME TO new_name

ALTER ROLE name [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT }
ALTER ROLE name [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT
ALTER ROLE name [ IN DATABASE database_name ] RESET configuration_parameter
ALTER ROLE name [ IN DATABASE database_name ] RESET ALL

這些屬性當中有一個名字為LOGIN的屬性,只有擁有這個屬性的Role才能登陸PostgreSQL。

CREATE USER創建的就是一個帶有LOGIN屬性的Role

CREATE USER name [ [ WITH ] option [ ... ] ]

where option can be:

      SUPERUSER | NOSUPERUSER
    | CREATEDB | NOCREATEDB
    | CREATEROLE | NOCREATEROLE
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | REPLICATION | NOREPLICATION
    | BYPASSRLS | NOBYPASSRLS
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED ] PASSWORD 'password'
    | VALID UNTIL 'timestamp'
    | IN ROLE role_name [, ...]
    | IN GROUP role_name [, ...]
    | ROLE role_name [, ...]
    | ADMIN role_name [, ...]
    | USER role_name [, ...]
    | SYSID uid

也正是因為如此,\du命令看到的都是Role

postgres=# \du
                              List of roles
  Role name  |                   Attributes                   | Member of
-------------+------------------------------------------------+-----------
 local_user1 |                                                | {}
 postgres    | Superuser, Create role, Create DB, Replication | {}

帶有LOGIN的屬性的Role是否就一定能成功登陸呢?不是!請繼續往下看。

pg_hba.conf對認證方式的限制

PostgreSQL中用pg_hba.conf文件控制用戶登陸時的認證方式,這個文件和數據庫的數據文件在同一個目錄中。 在CentOS7中的位置是/var/lib/pgsql/data/pg_hba.conf

pg_hba.conf文件內容如下:

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident

它的語法規則是這樣的:

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]
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]

第一列是連接的方式,local是通過本地的unix socket連接,host是通過IP地址連接。

第二列是目標數據庫,第三列是用戶。

最后一列是認證方式,總共支持11種認證方式(2018-09-29 10:04:36):

20.3.1. Trust Authentication
20.3.2. Password Authentication
20.3.3. GSSAPI Authentication
20.3.4. SSPI Authentication
20.3.5. Ident Authentication
20.3.6. Peer Authentication
20.3.7. LDAP Authentication
20.3.8. RADIUS Authentication
20.3.9. Certificate Authentication
20.3.10. PAM Authentication
20.3.11. BSD Authentication

其中最常接觸到的是peeridentpaasword

address樣式是127.0.0.1/32::1/128,如果要表示任意IP,使用0.0.0.0/0::0/0

提前填坑:如果同時匹配了pg_hba.conf中的多個規則,選用第一個

如果登陸操作同時滿足pg_hba.conf中的多個規則,會出現什么情況?

例如配置文件如下時,用戶kong登陸名為kong數據庫時,使用哪種認證方式?

試驗發現,會選擇第一個匹配的規則,上面的配置中會選用ident的方式,如果要使用md5方式,要調整規則順序:

host    kong            kong            127.0.0.1/32            md5
host    all             all             127.0.0.1/32            ident

這是一個很隱蔽的坑,一定要注意。

Peer和Ident認證: 使用操作系統上的用戶登陸

上一節給出的pg_hba.conf配置中的第一項設置的意思是:本地用戶通過unix socket登陸時,使用peer方式認證。

# "local" is for Unix domain socket connections only
local   all             all                                     peer

peer是用PostgreSQL所在的操作系統上的用戶登陸。

peer方式中,client必須和PostgreSQL在同一台機器上。只要當前系統用戶和要登陸到PostgreSQL的用戶名相同,就可以登陸。

在剛部署PostgreSQL之后,切換到系統的postgres用戶后,直接執行psql就能進入PostgreSQL就是這個原因(當前系統用戶為名postgre,PostgreSQL中的用戶名也是postgre)。

上一節給出的pg_hba.conf配置中的后兩項,第一列是host,表示通過IP地址訪問時,使用ident認證:

# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident

ident與peer類似,不過peer只能在PostgreSQL本地使用,ident則可以跨主機使用。

需要注意,host方式需要在通過psql登陸時,用-h指定要登陸的postgreSQL的IP,如果不指定IP,默認使用的unix socket。

host方式,即使在PostgreSQL本地登陸,也要用-h指定IP地址:-h 127.0.0.1

Peer方式演示

在PostgreSQL中創建一個沒有密碼的用戶:

create user local_user1;

在PostgreSQL所在的機上,創建一個同名的用戶:

useradd local_user1;

切換到local_user1用戶后,就可以直接通過unix_socket登陸PostgreSQL:

# su - local_user1
[local_user1@10 ~]$ psql postgres     
psql (9.2.24)
Type "help" for help.

postgres=>

注意:要指定數據庫名,如果不指定默認使用與用戶同名的數據庫。

peer和ident這兩種方式都不是常用的方式!最常用的方式是通過密碼遠程登陸。

password提供這樣的功能,見下一節。

密碼認證:使用PostgreSQL的用戶(Role)和密碼登陸

password認證分為三種方式:

scram-sha-256
md5
password

這三種方式都用密碼認證,區別是密碼在PostgreSQL上存儲的形式和登陸時密碼的傳輸形式。

scram-sha-256md5分別用sha-256和md5算法對設置的密碼進行保護,傳輸和保存的都是難以逆向破解的散列字符串,password方式傳輸和保存的則都是原始的明文密碼。

無論使用哪種方式,都需要在pg_hba.conf中設置:

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

上面配置中的后兩項,將通過IP連接時的登陸方式修改為md5(修改pg_hba.conf之后,要重啟PostgreSQL,新的配置文件才能生效),表示用密碼進行認證。

修改了認證方式之后,還要為用戶(Role)設置密碼,密碼可以在創建用戶(Role)的時候就設置:

CREATE USER name [ [ WITH ] option [ ... ] ]

where option can be:
...
    | [ ENCRYPTED ] PASSWORD 'password'
...


CREATE ROLE name [ [ WITH ] option [ ... ] ]

where option can be:
...
    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
...

也可以創建后用alter修改:

ALTER ROLE name [ [ WITH ] option [ ... ] ]

where option can be:

      SUPERUSER | NOSUPERUSER
    | CREATEDB | NOCREATEDB
    | CREATEROLE | NOCREATEROLE
    | CREATEUSER | NOCREATEUSER
    | INHERIT | NOINHERIT
    | LOGIN | NOLOGIN
    | REPLICATION | NOREPLICATION
    | CONNECTION LIMIT connlimit
    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
    | VALID UNTIL 'timestamp'

ALTER ROLE name RENAME TO new_name

ALTER ROLE name [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT }
ALTER ROLE name [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT
ALTER ROLE name [ IN DATABASE database_name ] RESET configuration_parameter
ALTER ROLE name [ IN DATABASE database_name ] RESET ALL

在為Role設置密碼的時候,可以指定密碼是否加密存儲:

[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'

如果沒有指定,則根據配置的password_encryption參數決定,默認是加密的。

Create User是沒有UNENCRYPTED選項的,只能使用加密或者默認方式:

create user user1 with encrypted password '123';     //加密
create user user1 with password '123';               //默認

在pg_hda.conf中設置了密碼認證,並在PostgreSQL中創建了有密碼的用戶(Role)之后,就可以通過用戶名(Role)和密碼登陸了:

psql -h 127.0.0.1 -U user_password1  postgres -W

注意,必須用-h指定IP,否則就用unix socket鏈接,使用peer的方式認證了。

pg_hba.conf中配置的認證方式和實際登陸方式不匹配,則會登陸失敗。

例如當pg_hda.conf中配置的是:

host    all             all             127.0.0.1/32           ident

這時候登陸,會提示認證失敗:

$ psql -h 127.0.0.1  -U user_password1  postgres -W
Password for user user_password1:
psql: FATAL:  Ident authentication failed for user "user_password1"

注意:修改了pg_hba.conf之后,需要重啟PostgreSQL,才會應用新配置。

為不同數據庫、不同用戶設置不同的認證方式

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]
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]

可以分別為某個數據庫、某個用戶、某個來源IP指定認證方式,例如:

host       postgre  user  10.10.10.1/24 password

可以自行實驗。

參考

  1. PostgreSQL SQL Commands:CREATE USER
  2. PostgreSQL 9.1.24 Documentation: Database Roles
  3. PostgreSQL SQL Commands: CREATE ROLE
  4. PostgreSQL SQL Commands: ALTER ROLE
  5. PostgreSQL: The pg_hba.conf File
  6. PostgreSQL: Authentication Methods
  7. PostgreSQL SQL Commands: ALTER ROLE
  8. PostgreSQL數據庫的基本使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM