postgresql 安全问题的认识

Postgresql安全

分类:连接安全、账户安全(个人理解)

一、       连接安全:

1、          客户端接入认证的主要方式是通过pg_hba.conf文件来进行配置。

2、     

3、          具体参数说明:

3.1、TYPE定义了多种连接PostgreSQL的方式,分别是:

“local”使用本地unix套接字,

“host”使用TCP/IP连接(包括SSL和非SSL),“host”结合“IPv4地址”使用IPv4方式,结合“IPv6地址”则使用IPv6方式,

“hostssl”只能使用SSL TCP/IP连接,

“hostnossl”不能使用SSL TCP/IP连接。

3.2、DATABASE指定哪个数据库,多个数据库,库名间以逗号分隔。“all”只有在没有其他的符合条目时才代表“所有”,如果有其他的符合条目则代表“除了该条之外的”,因为“all”的优先级最低。

 

这两条都是指定local访问方式,因为前一条指定了特定的数据库db1,所以后一条的all代表的是除了db1之外的数据库,同理用户的all也是这个道理。

注意:all` ,`sameuser`,`samerole`,`replication`,`数据库名称` ,或者多个

数据库名称用 `逗号`,值 all 表明该记录匹配所有数据库; 不匹配 replication。

值 sameuser表示如果被请求的数据库和请求的用户同名,则匹配;

值samerole指定所请求的用户必须是与所请求的数据库同名的角色成员。

值 replication 表示匹配一条replication连接,它不指定一个特定的数据库,一般在流复制中使用;

3.3、USER指定哪个数据库用户(PostgreSQL正规的叫法是角色,role)。多个用户以逗号分隔。

3.4、ADDRESS项可以是IPv4地址或IPv6地址,可以定义某台主机或某个网段。举例: IPv4 地址范围的典型示例是对于单个主机为172.20.143.89/32;

对于小型网络为172.20.143.0/24对于较大网络为10.6.0.0/16;0.0.0.0/0代表所有IPv4地址,::0/0代表所有IPv6地址,当然你可以使用 all 选项来匹配所有的IP地址

3.5、METHOD指定如何处理客户端的认证。常用的有ident,md5,password,trust,reject,cert,scram-sha-256

ident是Linux下PostgreSQL默认的local认证方式,凡是能正确登录服务器的操作系统用户(注:不是数据库用户)就能使用本用户映射的数据库用户不需密码登录数据库。用户映射文件为pg_ident.conf,这个文件记录着与操作系统用户匹配的数据库用户,如果某操作系统用户在本文件中没有映射用户,则默认的映射数据库用户与操作系统用户同名。比如,服务器上有名为user1的操作系统用户,同时数据库上也有同名的数据库用户,user1登录操作系统后可以直接输入psql,以user1数据库用户身份登录数据库且不需密码。

md5是常用的密码认证方式,如果你不使用ident,最好使用md5。密码是以md5形式传送给数据库,较安全,且不需建立同名的操作系统用户。

password是以明文密码传送给数据库,建议不要在生产环境中使用。

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

reject是拒绝认证。

cert使用SSL服务进行验证

案例:md5升级到scram-sha-256, 在postgresql.conf中设置 password_encryption = 'scram-sha-256', 让所有用户设置新密码,并将pg_hba.conf 中的认证方法声明更改为scram-sha-256

 

 

Ssl案例:https://www.cnblogs.com/sandata/p/12659913.html

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

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

1)部署CA环境

登陆postgres用户执行

1

[postgres@PGServer2 ~]$ mkdir -p security

拷贝openssl.cnf到security目录下

1

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

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

1

2

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

[postgres@PGServer2 ~]$ chmod 777 security/CA/private/

验证CA环境目录

1

2

3

4

5

6

[postgres@PGServer2 ~]$ tree security/

security/

├── CA

│   ├── certs

│   └── private

└── openssl.cnf

创建serial文件,并写入01

1

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

创建index.txt索引文件

1

[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

1

2

 

3

4

5

[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

1

2

3

4

5

6

7

[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
其中有些可以省略不填

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

[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的口令,
检查输出的请求与签名是否匹配

1

 

 

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

[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)生成服务器证书私钥

1

2

3

4

5

6

7

[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时的内容一致

1

 

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

[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

1

2

3

[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中的口令

检查请求与签名是否匹配

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

[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认证连接 

将ssl认证功能启用

postgres=# show ssl;

          ssl

-----

          off

(1 row)

postgres=# alter system set ssl = on;

ALTER SYSTEM

2)配置server.keyserver.crt文件的位置

1

 

2

3

[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认证文件配置的密码后,数据库即能启动

1

2

3

4

[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将对象的权限授予其他用户。

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名称。

postgres=# CREATE SCHEMA s1;

CREATE SCHEMA

postgres=# CREATE SCHEMA s2;

CREATE SCHEMA

修改schema s1为schema1,s2为schema2

postgres=# ALTER SCHEMA  s1 RENAME TO schema1;

ALTER SCHEMA

postgres=# ALTER SCHEMA  s2 RENAME TO schema2;

ALTER SCHEMA

创建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

原文地址:https://www.cnblogs.com/zxg-blog/p/13613928.html