PostgreSQL database security management

Foreword

With the advancement of technology and network technology, security is a challenge in any industry have to face, such as two years before the outbreak of WnCry computer viruses, data information is encrypted. Therefore, data security is always in need of prevention. Because the database is stored as the most important carrier of data, in addition to the physical hardware level of data security, but also need to strengthen data security at the software level. Next, tell us about the protection of the database as PostgreSQL in data security level.

table of Contents

A client access authentication

Second, user management and security

Third, set a password security policy

Fourth, row-level security (rls) Strategy

 

A client access authentication

The main way PostgreSQL client access authentication is carried out by pg_hba.conf configuration file.

1.1 Configuration Client access authentication

Client access authentication background

If the remote host needs to connect to the database, this information must be increased in the host database system configuration file, and performs access authentication client. Configuration file (the default name for the pg_hba.conf) stored in the database's data directory. hba (host-based authentication) is represented by the host-based authentication.

  • PostgreSQL supports the following three types of authentication, which requires three ways pg_hba.conf configuration file.
  1. Host-based authentication: server based on IP address, user name, and the database to be accessed by a client to view the configuration file to determine whether the user is authenticated.
  2. Password Authentication: remote connection comprises an encrypted password authentication and non-authentication encrypted password locally connected.
  3. SSL encryption: Use openssl (common protocol platform) to provide server and client environment secure connections.
  • Pg_hba.conf file format is one line Write a message indicating that a certification rules, whitespace and comments are ignored (starting with #).
  • Each rule is composed of a number of authentication and space / spaces and tab-delimited fields. If the field value is quoted, it may contain gaps. A record can not span exists.

Each record pg_hba.conf file can be one of the following four formats

# local      DATABASE  USER  METHOD  [OPTIONS]
# host      DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
# hostssl    DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
# hostnossl  DATABASE  USER  ADDRESS  METHOD  [OPTIONS]

Because the authentication system checks pg_hba.conf, and recorded for each connection request order, the order of the records is critical.

  • When configuring pg_hba.conf file, according to the communication needs in accordance with the format of the content configuration records from top to bottom, higher priority needs to configure the front.
  • If the server configuration file pg_hba.conf a hostssl, postgresql.conf must enable SSL authentication mode.

It is recommended to configure authentication rules are as follows:

  • Earlier records have more stringent connection parameters and weaker authentication method.
  • Records will have a looser connection parameters and stronger authentication method.

1.2 pg_hba.conf configuration file parameters and authentication instructions

Parameter Description

parameter name description Ranges
local

This record represents only accepts connections via Unix domain socket. No record of this type, it is not allowed to connect the Unix domain socket.

Only in the case of connection from the server machine and gsql without specifying -U parameter, is connected via Unix domain socket.
-
host This record represents both receive a common TCP / IP socket connection, accept a SSL encrypted TCP / IP socket connection. -
hostssl This record represents only accept a SSL encrypted TCP / IP socket connection. Connect securely using SSL, you need to configure request a digital certificate and configuration parameters.
hostnossl This record represents only accept a normal TCP / IP socket connection. -
DATABASE This record matches and allows database access.
  • all: it indicates that the record matches all databases.
  • sameuser: if the request indicates the same user name and requesting access to a database, the match.
  • samerole: indicates that the user requests must be members of the same name as the role of the database.
  • samegroup: samerole with exactly the same effect, indicating that the request must be a member of a user role with the same name in the database.
  • Database file or a file containing a list of names in the database: files can be prefixed by @ in front of the file name to the statement. Database file list separated by commas or line breaks.
  • Specific database name or a comma-separated list of databases.

Description:

Value replication means that if a request to copy the link, the match, but copy the link does not represent any specific database. To use the database, called replication, to be recorded in the database using column replication as the database name.
USER This record matches and allows users to access the database.
  • all: the record shows that match all users.
  • + User role: that match any direct or indirect member of this role.

Description:

+ Represents the prefix sign.

  • User list of files or file containing user names: File can be prefixed by @ in front of the file name to the statement. File list of users separated by commas or line breaks.
Specific database user name or a comma-separated list of users.
ADDRESS It matches the record specified range of IP addresses and allow access.

Support for IPv4 and IPv6, you can use the following two forms, said:

  • IP address / mask length. For example, 10.10.20.0 / 24
  • IP address subnet mask. For example, 10.10.20.0 255.255.255.0

Description:

IP addresses given in IPv4 format will match the corresponding IPv6 address has a connection, such as 127.0.0.1 match the IPv6 address :: ffff: 127.0.0.1
METHOD Authentication method used to declare a connection.

It supports the following authentication methods

  • trust
  • reject
  • md5
  • scram-sha-256
  • cert
  • peer | ident
  • ldap
  • password
  • gss
  • gssapi
  • radius

 

verification method

verification method Explanation
trust

With this authentication mode, the specified connection does not use psql -U parameter, in which case no password.

trust认证对于单用户工作站的本地连接是非常合适和方便的,通常不适用于多用户环境。如果想使用这种认证方法,可利用文件系统权限限制对服务器的Unix域套接字文件的访问。要使用这种限制有两个方法:

须知:

设置文件系统权限只能Unix域套接字连接,它不会限制本地TCP/IP连接。
reject 无条件地拒绝连接。常用于过滤某些主机。
md5

要求客户端提供一个md5加密的口令进行认证。

须知:

不推荐使用md5认证,因为md5为不安全的加密算法,存在网络安全风险。
scram-sha-256 md5的升级版本,要求客户端提供一个sha256算法加密的口令进行认证,该口令在传送过程中结合salt(服务器发送给客户端的随机数)的单向sha256加密,增强了安全性。(推荐)
cert

客户端证书认证模式,此模式需进行SSL连接配置且需要客户端提供有效的SSL证书,不需要提供用户密码。

须知:

该认证方式只支持hostssl类型的规则。
password 使用明文密码

1.3 使用SSL进行安全的TCP/IP连接

从CA认证中心申请到正式的服务器、客户端的证书和密钥。(假设服务器的私钥为server.key,证书为server.crt,客户端的私钥为client.key,证书为client.crt,CA根证书名称为cacert.pem。)此处以OPENSSL生成的认证为基础:

1)部署CA环境

登陆postgres用户执行

[postgres@PGServer2 ~]$ mkdir -p security

拷贝openssl.cnf到security目录下

[postgres@PGServer2 ~]$ cp /etc/pki/tls/openssl.cnf ~/security/

创建CA环境并授权private为777权限

[postgres@PGServer2 ~]$ mkdir -p security/CA/{certs,private}
[postgres@PGServer2 ~]$ chmod 777 security/CA/private/

验证CA环境目录

[postgres@PGServer2 ~]$ tree security/
security/
├── CA
│   ├── certs
│   └── private
└── openssl.cnf

创建serial文件,并写入01

[postgres@PGServer2 ~]$ echo '01' > security/CA/serial

创建index.txt索引文件

[postgres@PGServer2 ~]$ touch security/CA/index.txt

修改openssl.cnf文件中的参数

[postgres@PGServer2 ~]$ vi security/openssl.cnf
[postgres@PGServer2 ~]$ cat security/openssl.cnf  | egrep "security|default_md|new_certs_dir" | awk '{print $1,$2,$3}'
dir = /home/postgres/security/CA
new_certs_dir = $dir/certs
default_md = sha256

2)生成根私钥

生成2048位的CA私钥:输入密码test

[postgres@PGServer2 ~]$ openssl  genrsa -aes256 -out security/CA/private/cakey.pem 2048
Generating RSA private key, 2048 bit long modulus
.+++
....+++
e is 65537 (0x10001)
Enter pass phrase for security/CA/private/cakey.pem:
Verifying - Enter pass phrase for security/CA/private/cakey.pem:

3)生成根证书请求文件

根证书文件名称为server.req
输入cakey.pem的口令test。
输入国家名称:CN
输入省份:Jiangsu
输入城市:NanJing
输入组织名称:gs
其中有些可以省略不填

[postgres@PGServer2 ~]$ openssl req -config security/openssl.cnf -new -key security/CA/private/cakey.pem -out security/CA/careq.pem
Enter pass phrase for security/CA/private/cakey.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Jiangsu
Locality Name (eg, city) [Default City]:Nanjing
Organization Name (eg, company) [Default Company Ltd]:gs
Organizational Unit Name (eg, section) []:gs
Common Name (eg, your name or your server's hostname) []:shaohua
Email Address []: 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:Postgres@DB
An optional company name []:
[postgres@PGServer2 ~]$

4)生成自签名根证书

使用openssl.cnf中的配置
输入cakey.pem的口令,
检查输出的请求与签名是否匹配

[postgres@PGServer2 ~]$ openssl ca -config security/openssl.cnf -out security/CA/cacert.pem -keyfile security/CA/private/cakey.pem  -selfsign -infiles security/CA/careq.pem
Using configuration from security/openssl.cnf
Enter pass phrase for security/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Mar 30 07:16:21 2020 GMT
            Not After : Mar 30 07:16:21 2021 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Jiangsu
            organizationName          = gs
            organizationalUnitName    = gs
            commonName                = shaohua
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                B2:5E:02:8B:7E:8C:19:56:D3:00:17:71:9C:BF:B5:DA:33:C3:21:4F
            X509v3 Authority Key Identifier: 
                keyid:B2:5E:02:8B:7E:8C:19:56:D3:00:17:71:9C:BF:B5:DA:33:C3:21:4F

Certificate is to be certified until Mar 30 07:16:21 2021 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

已下发名为cacert.pem的CA根证书

5)生成服务器证书私钥

[postgres@PGServer2 security]$ openssl genrsa -aes256 -out server.key 2048
Generating RSA private key, 2048 bit long modulus
..................................................................................................................................+++
.......................................................+++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

6)生成服务器证书请求文件

输入server.key的口令
输入系统要求的一些信息
其中一些字段可以不填,确保和创建CA时的内容一致

[postgres@PGServer2 security]$ openssl req -config openssl.cnf -new -key server.key -out server.req
Enter pass phrase for server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Jiangsu
Locality Name (eg, city) [Default City]:Nanjing
Organization Name (eg, company) [Default Company Ltd]:gs
Organizational Unit Name (eg, section) []:gs
Common Name (eg, your name or your server's hostname) []:shaohua
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:Postgres@DB
An optional company name []:

7)生成服务器证书

修改CA/index.txt.attr中的属性为no

[postgres@PGServer2 security]$ vi CA/index.txt.attr 
[postgres@PGServer2 security]$ cat CA/index.txt.attr 
unique_subject = no

下发生成的服务器证书请求文件,下发成功后,会生成一个正式的服务器证书server.crt

使用openssl.cnf中的配置,输入cakey.pem中的口令

检查请求与签名是否匹配

[postgres@PGServer2 security]$ openssl ca -config openssl.cnf -in server.req -out server.crt -days 3650 -md sha256
Using configuration from openssl.cnf
Enter pass phrase for /home/postgres/security/CA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Mar 30 07:26:57 2020 GMT
            Not After : Mar 28 07:26:57 2030 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = Jiangsu
            organizationName          = gs
            organizationalUnitName    = gs
            commonName                = shaohua
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                64:96:2B:B7:1E:CC:DD:22:D9:0D:07:79:A7:22:FC:23:FB:66:86:FC
            X509v3 Authority Key Identifier: 
                keyid:B2:5E:02:8B:7E:8C:19:56:D3:00:17:71:9C:BF:B5:DA:33:C3:21:4F

Certificate is to be certified until Mar 28 07:26:57 2030 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

1.4     PostgreSQL服务器使用ssl认证连接 

1)启动PostgreSQL服务器

将ssl认证功能启用

[postgres@PGServer2 ~]$ pg_ctl  start -D $PGDATA -l /tmp/logfile
waiting for server to start.... done
server started
[postgres@PGServer2 security]$ psql
psql (12.2)
Type "help" for help.

postgres=# show ssl;
 ssl 
-----
 off
(1 row)

postgres=# alter system set ssl = on;
ALTER SYSTEM

2)配置server.key和server.crt文件的位置

[postgres@PGServer2 ~]$ cat $PGDATA/postgresql.conf  | egrep -v "^#" | egrep "ssl_key_file|ssl_cert_file"
ssl_cert_file = '/home/postgres/security/server.crt'
ssl_key_file = '/home/postgres/security/server.key'

3)重新启动PostgreSQL服务器

输入之前ssl认证文件配置的密码后,数据库即能启动

[postgres@PGServer2 ~]$ pg_ctl  start -D $PGDATA -l /tmp/logfile
waiting for server to start....Enter PEM pass phrase:.
 done
server started

二、管理用户及安全

2.1 默认权限机制

数据库对象创建后,进行对象创建的用户就是该对象的所有者。集群安装后的默认情况下,未开启三权分立,数据库系统管理员具有与对象所有者相同的权限。也就是说对象创建后,默认只有对象所有者或者系统管理员可以查询、修改和销毁对象,以及通过GRANT将对象的权限授予其他用户。

为使其他用户能够使用对象,必须向用户或包含该用户授予必要的权限。

不同的权限与不同的对象类型关联。要撤消已经授予的权限,可以使用REVOKE。对象所有者的权限(例如ALTER、 DROP、GRANT和REVOKE)是隐式的,无法授予或撤消。即只要拥有对象就可以执行对象所有者的这些隐式权限。对象所有者可以撤消自己的普通权限,例如,使表对自己以及其他人只读。

系统表和系统视图要么只对系统管理员可见,要么对所有用户可见。标识了需要系统管理员权限的系统表和视图只有系统管理员可以查询。

数据库提供对象隔离的特性,对象隔离特性开启时,用户只能查看有权限访问的对象(表、视图、字段、函数),系统管理员不受影响。

2.2 用户

使用CREATE USER 和 ALTER USER 可以创建和管理数据库用户。数据库包含一个或者多个已命名的数据库。用户和角色在整个数据库中是共享的,但是数据并不共享。即用户可以连接到任何数据库,但当连接成功后,任何用户都只能访问连接请求里声明的那个数据库。

2.2.1 管理员用户

管理员用户可以管理数据库中的对象,可以通过WITH SUPERUSER关键词创建管理员用户

示例:创建具有管理员角色的用户admin1和admin2

postgres=# CREATE USER admin1 WITH SUPERUSER ENCRYPTED PASSWORD 'admin1';
CREATE ROLE
postgres=# CREATE USER admin2 WITH SUPERUSER ENCRYPTED PASSWORD 'admin2';
CREATE ROLE

2.2.2 业务用户

对于有多个业务部门,各部门间使用不同的数据库用户进行业务操作,同时有一个同级的数据库维护部门使用数据库管理员进行维护操作的场景下,业务部门可能希望在未经授权的情况下,管理员用户只能对各部门的数据进行控制操作(DROP、ALTER、TRUNCATE),但是不能进行访问操作(INSERT、DELETE、UPDATE、SELECT、COPY)。即针对管理员用户,表对象的控制权和访问权要能够分离,提高普通用户数据安全性。

示例:创建普通用户user1和user2

postgres=# CREATE USER user1 WITH ENCRYPTED PASSWORD 'user1';
CREATE ROLE
postgres=# CREATE USER user2 WITH ENCRYPTED PASSWORD 'user2';
CREATE ROLE

2.3 模式

Schema又称作模式。通过管理Schema,允许多个用户使用同一数据库而不相互干扰,可以将数据库对象组织成易于管理的逻辑组,同时便于将第三方应用添加到相应的Schema下而不引起冲突。

每个数据库包含一个或多个Schema。数据库中的每个Schema包含表和其他类型的对象。数据库创建初始,默认具有一个名为public的Schema,且所有用户都拥有此Schema的权限。可以通过Schema分组数据库对象。Schema类似于操作系统目录,但Schema不能嵌套。

相同的数据库对象名称可以应用在同一数据库的不同Schema中,而没有冲突。例如,a_schema和b_schema都可以包含名为mytable的表。具有所需权限的用户可以访问数据库的多个Schema中的对象。

在初始数据库postgres中创建用户时,系统会自动帮助用户创建一个同名Schema。在其他数据库中,若需要同名Schema,则需要用户手动创建。

数据库对象是创建在数据库搜索路径中的第一个Schema内的。

创建SCHEMA可以使用CREATE SCHEMA语句创建。

更改SCHEMA名称或者所有者,可以使用ALTER SCHEMA语句进行修改。

要删除SCHEMA及其对象,使用DROP SCHEMA 语法可以进行删除。

要在SCHEMA内创建表,以schema.tablename格式创建表。不指定schemaname时,对象默认创建到search_path中的第一个schema名称。

示例1:创建schema对象s1和s2

postgres=# CREATE SCHEMA s1;
CREATE SCHEMA
postgres=# CREATE SCHEMA s2;
CREATE SCHEMA

示例2:修改schema s1为schema1,s2为schema2

postgres=# ALTER SCHEMA  s1 RENAME TO schema1;
ALTER SCHEMA
postgres=# ALTER SCHEMA  s2 RENAME TO schema2;
ALTER SCHEMA

示例3: 创建schema1下的表 st1 ,schema t2下的表为st2

postgres=# CREATE TABLE schema1.st1(id int,name varchar(20));
CREATE TABLE
postgres=# CREATE TABLE schema2.st2(id int,name varchar(20));
CREATE TABLE

示例4:查看创建的表 st1 和 st2

--需要先设置schema的搜索路径,否则找不到该schema1和schema2下的对象
postgres=# set search_path = public,schema1,schema2;
SET
--需要注意的是,设置search_path为多个时,不要加引号
postgres=# \d
         List of relations
 Schema  | Name | Type  |  Owner   
---------+------+-------+----------
 schema1 | st1  | table | postgres
 schema2 | st2  | table | postgres

示例5:为schema1和schema2下的两张表st1和st2插入数据

postgres=# INSERT INTO schema1.st1 VALUES(1,'PostgreSQL');
INSERT 0 1
postgres=# INSERT INTO schema2.st2 VALUES(1,'MySQL');
INSERT 0 1

示例6:使用之前创建的普通用户user1和user2访问schema1和schema2下的表

postgres=# \c postgres user1;
You are now connected to database "postgres" as user "user1".
postgres=> SELECT * FROM schema1.st1 ;
ERROR:  permission denied for schema schema1
LINE 1: SELECT * FROM schema1.st1 ;
--此时,user1用户没有足够的权限可以使用schema1,因此需要对用户user1授权对schema1的使用权限
postgres=# \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# GRANT USAGE ON SCHEMA schema1 TO user1;
GRANT
--再次使用user1查看schema1下的对象st1
postgres=# \c postgres user1;
You are now connected to database "postgres" as user "user1".
postgres=> SELECT * FROM schema1.st1 ;
ERROR:  permission denied for relation st1
--此时虽然user1对schema虽然具有使用权限,但是没有权限访问schema1下的对象st1,
--因此还需要对schema1.st1授权user1可以访问的权限,即select权限
postgres=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# GRANT SELECT ON TABLE schema1.st1 TO user1;
GRANT
--再次使用user1对schema1下的对象st1进行查询
postgres=# \c postgres user1;
You are now connected to database "postgres" as user "user1".
postgres=> SELECT * FROM schema1.st1 ;
 id |    name    
----+------------
  1 | PostgreSQL
(1 row)

对于用户user2,如果想要对schema2下的对象st2进行查看,需要做上述同样的操作。

综上案例,可以发现,如果一个普通用户对于schema下的对象进行访问,修改等操作,首先要让普通用户具有对schema的使用权限,其次对schema下的对象要授权普通用户具有访问修改的权限。

三、设置密码安全策略

设置账户的密码安全策略

用户密码存储在系统表pg_authid中,为防止用户密码泄露,PostgreSQL对用户密码进行加密存储,所采用的加密算法由配置参数password_encryption_type决定。

  • 当参数password_encryption设置为 scram-sha-256 时,表示采用 scram-sha-25 6方式对密码加密。
  • 当参数password_encryption设置为 md5 时,表示采用md5方式对密码加密。md5为不安全的加密算法,不建议使用。

注意:PostgreSQL数据库默认采用MD5加密。该参数设置后需要重新启动数据库服务器,并且需要更改原有密码,使修改后用户使用的密码加密算法生效。

示例1:查看数据库默认加密算法

postgres=# SHOW password_encryption ;
 password_encryption 
---------------------
 md5

示例2:修改默认加密算法为 scram-sha-256

postgres=# ALTER SYSTEM SET password_encryption = 'scram-sha-256';
ALTER SYSTEM
--重新启动数据库服务器
[postgres@PGServer2 ~]$ pg_ctl  stop -D $PGDATA -l /tmp/logfile && pg_ctl start -D $PGDATA -l /tmp/logfile
waiting for server to shut down.... done
server stopped
waiting for server to start....Enter PEM pass phrase:.
 done
server started

示例3:查看之前创建的用户user1使用的密码加密策略

postgres=# SELECT rolname,rolpassword FROM pg_authid  WHERE rolname = 'user1';
 rolname |             rolpassword             
---------+-------------------------------------
 user1   | md57d1b5a4329b6478e976508ab9a49ee3d

示例4:配置pg_hba.conf中的METHOD为 scram-sha-256

[postgres@PGServer2 ~]$ cat $PGDATA/pg_hba.conf  | grep 10
host    all             all             10.10.20.0/24           scram-sha-256

示例5:使用user1连接到postgres数据库

--user1的密码为 test
[postgres@PGServer2 ~]$ psql -h 10.10.20.101 -p 5432 -U user1 -d postgres
Password for user user1: 
psql: FATAL:  password authentication failed for user "user1"
FATAL:  password authentication failed for user "user1"
--此时输入test的密码,但是连接失败,原因是由于在更改password_encryption为scram-sha-256之前,user1用户的密码存储使用的加密策略为 md5 加密,示例3可以查看到user1采用md5加密
--解决方法:重新修改user1的密码
postgres=# ALTER USER user1 WITH ENCRYPTED PASSWORD 'user1';
ALTER ROLE
--查看修改后的user1的密码加密策略为scram-sha-256
postgres=# SELECT rolname,rolpassword FROM pg_authid  WHERE rolname = 'user1';
 rolname |                                                              rolpassword                                                              
---------+---------------------------------------------------------------------------------------------------------------------------------------
 user1   | SCRAM-SHA-256$4096:oAK38X5JC7XJLanDu+WBBQ==$ErZytCUN6ot/qfXnnxNnTneM0MmQVLvepghMP0bAJlg=:uUy8CiCgCU6E4+fbZdUPhofvFSLb53zHJDJUGQTdG+w=
--重新使用密码user1进行连接
[postgres@PGServer2 ~]$ psql -U user1 -d postgres -h 10.10.20.101
Password for user user1: 
psql (10.11)
Type "help" for help.

postgres=>

密码策略设置为scram-sha-256对数据隔离访问具有安全性,因此生产环境中,建议使用scram-sha-256进行加密。 

四、行级安全(rls)策略

行级访问控制特性将数据库访问控制精确到数据表行级别,使数据库达到行级访问控制的能力。不同用户执行相同的SQL查询操作,读取到的结果是不同的。

用户可以在数据表创建行访问控制(Row Level Security)策略,该策略是指针对特定数据库用户、特定SQL操作生效的表达式。当数据库用户对数据表访问时,若SQL满足数据表特定的Row Level Security策略,在查询优化阶段将满足条件的表达式,按照属性(PERMISSIVE | RESTRICTIVE)类型,通过AND或OR方式拼接,应用到执行计划上。

行级访问控制的目的是控制表中行级数据可见性,通过在数据表上预定义Filter,在查询优化阶段将满足条件的表达式应用到执行计划上,影响最终的执行结果。当前受影响的SQL语句包括SELECT,UPDATE,DELETE。

示例:假设一张表中存储了不同用户的数据,但是不同的用户只能看到自身相关的信息,不能访问其它用户的数据信息。

--创建用户 lily,lucy,tom
postgres=# CREATE USER lily WITH ENCRYPTED PASSWORD 'lily';
CREATE ROLE
postgres=# CREATE USER lucy WITH ENCRYPTED PASSWORD 'lucy';
CREATE ROLE
postgres=# CREATE USER tom WITH ENCRYPTED PASSWORD 'tom';
CREATE ROLE
--创建表 user_data,并插入不同用户的不同数据
postgres=# postgres=# CREATE TABLE user_data(id int primary key,name varchar(20),gender varchar(6),nickname varchar(20),age int2,carrer varchar(20));
CREATE TABLE
postgres=#  INSERT INTO user_data  VALUES (1,'lily','女','昵称:丽丽',20,'销售');
INSERT 0 1
postgres=#  INSERT INTO user_data  VALUES (2,'lucy','女','昵称:路西',23,'经理');
INSERT 0 1
postgres=#  INSERT INTO user_data  VALUES (3,'tom','男','昵称:汤姆猫',22,'程序员');
INSERT 0 1

--将数据表user_data中读取权限授权给lily,lucy和tom
postgres=# GRANT SELECT ON user_data TO lily,lucy,tom;
GRANT
--启用行访问控制策略
postgres=# ALTER TABLE user_data ENABLE ROW LEVEL SECURITY ;
ALTER TABLE
--创建行访问控制策略,当前用户只能查看用户自身数据
postgres=# CREATE POLICY user_data_rls ON user_data FOR SELECT to PUBLIC USING (name = CURRENT_USER);
CREATE POLICY
--使用lily登录查看user_data数据
 [postgres@PGServer2 ~]$ psql -U lily -d postgres -h 10.10.20.101
Password for user lily: 
psql (10.11)
Type "help" for help.

postgres=> select * from user_data ;
 id | name | gender | nickname  | age | carrer 
----+------+--------+-----------+-----+--------
  1 | lily | 女     | 昵称:丽丽 |  20 | 销售
(1 row)

使用lucy登录查看user_data数据
postgres=> \c postgres lucy 10.10.20.101
Password for user lucy: 
You are now connected to database "postgres" as user "lucy".
postgres=> select * from user_data ;
 id | name | gender | nickname  | age | carrer 
----+------+--------+-----------+-----+--------
  2 | lucy | 女     | 昵称:路西 |  23 | 经理

--使用tom用户查看user_data数据
postgres=> \c postgres tom 10.10.20.101
Password for user tom: 
You are now connected to database "postgres" as user "tom".
postgres=> select * from user_data ;
 id | name | gender |  nickname   | age | carrer 
----+------+--------+-------------+-----+--------
  3 | tom  | 男     | 昵称:汤姆猫 |  22 | 程序员

小结:

以上就是PostgreSQL数据库中关于客户端接入认证,用户级别安全和基于行安全(RLS)的内容。

在PostgreSQL中,除了这些来控制数据库的安全以外,还有pg_hba中的其它基于主机的访问控制策略,数据库访问审计策略及对数据的加密策略。此章节中不再对涉及的其它安全访问控制进行一一探讨。

Guess you like

Origin www.cnblogs.com/sandata/p/12659913.html