日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

PostgreSQL管理数据库安全

發(fā)布時(shí)間:2024/5/24 综合教程 55 生活家
生活随笔 收集整理的這篇文章主要介紹了 PostgreSQL管理数据库安全 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

隨著技術(shù)的進(jìn)步和網(wǎng)絡(luò)技術(shù)的發(fā)展,安全是任何行業(yè)都需要面對(duì)的挑戰(zhàn),如前兩年爆發(fā)的WnCry電腦病毒,數(shù)據(jù)信息被加密。因此,數(shù)據(jù)安全始終需要預(yù)防。正因?yàn)閿?shù)據(jù)庫(kù)作為存儲(chǔ)數(shù)據(jù)最重要的載體,所以除了硬件物理層面的數(shù)據(jù)安全防護(hù)之外,也需要在軟件層面加強(qiáng)數(shù)據(jù)安全防護(hù)。接下來介紹一下PostgreSQL中在數(shù)據(jù)安全層面對(duì)數(shù)據(jù)庫(kù)做防護(hù)。

目錄

一、客戶端接入認(rèn)證

二、管理用戶及安全

三、設(shè)置密碼安全策略

四、行級(jí)安全(rls)策略

一、客戶端接入認(rèn)證

PostgreSQL客戶端接入認(rèn)證的主要方式是通過pg_hba.conf文件來進(jìn)行配置。

1.1 配置客戶端接入認(rèn)證

客戶端接入認(rèn)證背景

如果主機(jī)需要遠(yuǎn)程連接數(shù)據(jù)庫(kù),必須在數(shù)據(jù)庫(kù)系統(tǒng)的配置文件中增加此主機(jī)的信息,并且進(jìn)行客戶端接入認(rèn)證。配置文件(默認(rèn)名稱為pg_hba.conf)存放在數(shù)據(jù)庫(kù)的數(shù)據(jù)目錄里。hba(host-based authentication)表示是基于主機(jī)的認(rèn)證。

PostgreSQL支持如下三種認(rèn)證方式,這三種方式都需要配置pg_hba.conf文件。

基于主機(jī)的認(rèn)證:服務(wù)器端根據(jù)客戶端的IP地址、用戶名及要訪問的數(shù)據(jù)庫(kù)來查看配置文件從而判斷用戶是否通過認(rèn)證。
口令認(rèn)證:包括遠(yuǎn)程連接的加密口令認(rèn)證和本地連接的非加密口令認(rèn)證。
SSL加密:使用openssl(通用協(xié)議平臺(tái))提供服務(wù)器端和客戶端安全連接的環(huán)境。

pg_hba.conf文件的格式是一行寫一條信息,表示一個(gè)認(rèn)證規(guī)則,空白和注釋(以#開頭)被忽略。
每個(gè)認(rèn)證規(guī)則是由若干空格和/,空格和制表符分隔的字段組成。如果字段用引號(hào)包圍,則它可以包含空白。一條記錄不能跨行存在。

pg_hba.conf文件中的每條記錄可以是下面四種格式之一

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

因?yàn)檎J(rèn)證時(shí)系統(tǒng)是為每個(gè)連接請(qǐng)求順序檢查pg_hba.conf里的記錄的,所以這些記錄的順序非常關(guān)鍵。

在配置 pg_hba.conf 文件時(shí),請(qǐng)依據(jù)通訊需求按照格式內(nèi)容從上至下配置記錄,優(yōu)先級(jí)高的需求需要配置在前面。
若服務(wù)端pg_hba.conf文件配置了hostssl,postgresql.conf中必須開啟SSL認(rèn)證模式。

因此對(duì)于認(rèn)證規(guī)則的配置建議如下:

靠前的記錄有比較嚴(yán)格的連接參數(shù)和比較弱的認(rèn)證方法。
靠后的記錄有比較寬松的連接參數(shù)和比較強(qiáng)的認(rèn)證方法。

1.2 pg_hba.conf 配置文件參數(shù)說明及認(rèn)證方式

參數(shù)說明

參數(shù)名稱 描述 取值范圍
local

表示這條記錄只接受通過Unix域套接字進(jìn)行的連接。沒有這種類型的記錄,就不允許Unix域套接字的連接。

只有在從服務(wù)器本機(jī)使用gsql連接且在不指定-U參數(shù)的情況下,才是通過Unix域套接字連接。

-
host 表示這條記錄既接受一個(gè)普通的TCP/IP套接字連接,也接受一個(gè)經(jīng)過SSL加密的TCP/IP套接字連接。 -
hostssl 表示這條記錄只接受一個(gè)經(jīng)過SSL加密的TCP/IP套接字連接。 用SSL進(jìn)行安全的連接,需要配置申請(qǐng)數(shù)字證書并配置相關(guān)參數(shù)。
hostnossl 表示這條記錄只接受一個(gè)普通的TCP/IP套接字連接。 -
DATABASE 聲明記錄所匹配且允許訪問的數(shù)據(jù)庫(kù)。

all:表示該記錄匹配所有數(shù)據(jù)庫(kù)。
sameuser:表示如果請(qǐng)求訪問的數(shù)據(jù)庫(kù)和請(qǐng)求的用戶同名,則匹配。
samerole:表示請(qǐng)求的用戶必須是與數(shù)據(jù)庫(kù)同名角色中的成員。
samegroup:與samerole作用完全一致,表示請(qǐng)求的用戶必須是與數(shù)據(jù)庫(kù)同名角色中的成員。
一個(gè)包含數(shù)據(jù)庫(kù)名的文件或者文件中的數(shù)據(jù)庫(kù)列表:文件可以通過在文件名前面加前綴@來聲明。文件中的數(shù)據(jù)庫(kù)列表以逗號(hào)或者換行符分隔。
特定的數(shù)據(jù)庫(kù)名稱或者用逗號(hào)分隔的數(shù)據(jù)庫(kù)列表。

說明:

值replication表示如果請(qǐng)求一個(gè)復(fù)制鏈接,則匹配,但復(fù)制鏈接不表示任何特定的數(shù)據(jù)庫(kù)。如需使用名為replication的數(shù)據(jù)庫(kù),需在database列使用記錄 replication 作為數(shù)據(jù)庫(kù)名。

USER 聲明記錄所匹配且允許訪問的數(shù)據(jù)庫(kù)用戶。

all:表明該記錄匹配所有用戶。
+用戶角色:表示匹配任何直接或者間接屬于這個(gè)角色的成員。

說明:

+表示前綴符號(hào)。

一個(gè)包含用戶名的文件或者文件中的用戶列表:文件可以通過在文件名前面加前綴@來聲明。文件中的用戶列表以逗號(hào)或者換行符分隔。

特定的數(shù)據(jù)庫(kù)用戶名或者用逗號(hào)分隔的用戶列表。

ADDRESS 指定與記錄匹配且允許訪問的IP地址范圍。

支持IPv4和IPv6,可以使用如下兩種形式來表示:

IP地址/掩碼長(zhǎng)度。例如,10.10.20.0/24
IP地址子網(wǎng)掩碼。例如,10.10.20.0 255.255.255.0

說明:

以IPv4格式給出的IP地址會(huì)匹配那些擁有對(duì)應(yīng)地址的IPv6連接,比如127.0.0.1將匹配IPv6地址 ::ffff:127.0.0.1

METHOD 聲明連接時(shí)使用的認(rèn)證方法。

支持如下幾種認(rèn)證方式

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

認(rèn)證方式

認(rèn)證方式 說明
trust

采用這種認(rèn)證模式時(shí),使用psql且不指定-U參數(shù)的連接,此時(shí)不需要口令。

trust認(rèn)證對(duì)于單用戶工作站的本地連接是非常合適和方便的,通常不適用于多用戶環(huán)境。如果想使用這種認(rèn)證方法,可利用文件系統(tǒng)權(quán)限限制對(duì)服務(wù)器的Unix域套接字文件的訪問。要使用這種限制有兩個(gè)方法:

設(shè)置參數(shù)unix_socket_permissions和unix_socket_group。
設(shè)置參數(shù)unix_socket_directory,將Unix域套接字文件放在一個(gè)經(jīng)過恰當(dāng)限制的目錄里。

須知:

設(shè)置文件系統(tǒng)權(quán)限只能Unix域套接字連接,它不會(huì)限制本地TCP/IP連接。

reject 無條件地拒絕連接。常用于過濾某些主機(jī)。
md5

要求客戶端提供一個(gè)md5加密的口令進(jìn)行認(rèn)證。

須知:

不推薦使用md5認(rèn)證,因?yàn)閙d5為不安全的加密算法,存在網(wǎng)絡(luò)安全風(fēng)險(xiǎn)。

scram-sha-256 md5的升級(jí)版本,要求客戶端提供一個(gè)sha256算法加密的口令進(jìn)行認(rèn)證,該口令在傳送過程中結(jié)合salt(服務(wù)器發(fā)送給客戶端的隨機(jī)數(shù))的單向sha256加密,增強(qiáng)了安全性。(推薦)
cert

客戶端證書認(rèn)證模式,此模式需進(jìn)行SSL連接配置且需要客戶端提供有效的SSL證書,不需要提供用戶密碼。

須知:

該認(rèn)證方式只支持hostssl類型的規(guī)則。

password 使用明文密碼

1.3 使用SSL進(jìn)行安全的TCP/IP連接

從CA認(rèn)證中心申請(qǐng)到正式的服務(wù)器、客戶端的證書和密鑰。(假設(shè)服務(wù)器的私鑰為server.key,證書為server.crt,客戶端的私鑰為client.key,證書為client.crt,CA根證書名稱為cacert.pem。)此處以O(shè)PENSSL生成的認(rèn)證為基礎(chǔ):

1)部署CA環(huán)境

登陸postgres用戶執(zhí)行

[postgres@PGServer2 ~]$ mkdir -p security

拷貝openssl.cnf到security目錄下

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

創(chuàng)建CA環(huán)境并授權(quán)private為777權(quán)限

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

驗(yàn)證CA環(huán)境目錄

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

創(chuàng)建serial文件,并寫入01

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

創(chuàng)建index.txt索引文件

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

修改openssl.cnf文件中的參數(shù)

[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)生成根證書請(qǐng)求文件

根證書文件名稱為server.req
輸入cakey.pem的口令test。
輸入國(guó)家名稱: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的口令,
檢查輸出的請(qǐng)求與簽名是否匹配

[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

已下發(fā)名為cacert.pem的CA根證書

5)生成服務(wù)器證書私鑰

[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)生成服務(wù)器證書請(qǐng)求文件

輸入server.key的口令
輸入系統(tǒng)要求的一些信息
其中一些字段可以不填,確保和創(chuàng)建CA時(shí)的內(nèi)容一致

[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)生成服務(wù)器證書

修改CA/index.txt.attr中的屬性為no

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

下發(fā)生成的服務(wù)器證書請(qǐng)求文件,下發(fā)成功后,會(huì)生成一個(gè)正式的服務(wù)器證書server.crt

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

檢查請(qǐng)求與簽名是否匹配

[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服務(wù)器使用ssl認(rèn)證連接

1)啟動(dòng)PostgreSQL服務(wù)器

將ssl認(rèn)證功能啟用

[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)重新啟動(dòng)PostgreSQL服務(wù)器

輸入之前ssl認(rèn)證文件配置的密碼后,數(shù)據(jù)庫(kù)即能啟動(dòng)

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

二、管理用戶及安全

2.1 默認(rèn)權(quán)限機(jī)制

數(shù)據(jù)庫(kù)對(duì)象創(chuàng)建后,進(jìn)行對(duì)象創(chuàng)建的用戶就是該對(duì)象的所有者。集群安裝后的默認(rèn)情況下,未開啟三權(quán)分立,數(shù)據(jù)庫(kù)系統(tǒng)管理員具有與對(duì)象所有者相同的權(quán)限。也就是說對(duì)象創(chuàng)建后,默認(rèn)只有對(duì)象所有者或者系統(tǒng)管理員可以查詢、修改和銷毀對(duì)象,以及通過GRANT將對(duì)象的權(quán)限授予其他用戶。

為使其他用戶能夠使用對(duì)象,必須向用戶或包含該用戶授予必要的權(quán)限。

不同的權(quán)限與不同的對(duì)象類型關(guān)聯(lián)。要撤消已經(jīng)授予的權(quán)限,可以使用REVOKE。對(duì)象所有者的權(quán)限(例如ALTER、 DROP、GRANT和REVOKE)是隱式的,無法授予或撤消。即只要擁有對(duì)象就可以執(zhí)行對(duì)象所有者的這些隱式權(quán)限。對(duì)象所有者可以撤消自己的普通權(quán)限,例如,使表對(duì)自己以及其他人只讀。

系統(tǒng)表和系統(tǒng)視圖要么只對(duì)系統(tǒng)管理員可見,要么對(duì)所有用戶可見。標(biāo)識(shí)了需要系統(tǒng)管理員權(quán)限的系統(tǒng)表和視圖只有系統(tǒng)管理員可以查詢。

數(shù)據(jù)庫(kù)提供對(duì)象隔離的特性,對(duì)象隔離特性開啟時(shí),用戶只能查看有權(quán)限訪問的對(duì)象(表、視圖、字段、函數(shù)),系統(tǒng)管理員不受影響。

2.2 用戶

使用CREATE USER 和 ALTER USER 可以創(chuàng)建和管理數(shù)據(jù)庫(kù)用戶。數(shù)據(jù)庫(kù)包含一個(gè)或者多個(gè)已命名的數(shù)據(jù)庫(kù)。用戶和角色在整個(gè)數(shù)據(jù)庫(kù)中是共享的,但是數(shù)據(jù)并不共享。即用戶可以連接到任何數(shù)據(jù)庫(kù),但當(dāng)連接成功后,任何用戶都只能訪問連接請(qǐng)求里聲明的那個(gè)數(shù)據(jù)庫(kù)。

2.2.1 管理員用戶

管理員用戶可以管理數(shù)據(jù)庫(kù)中的對(duì)象,可以通過WITH SUPERUSER關(guān)鍵詞創(chuàng)建管理員用戶

示例:創(chuàng)建具有管理員角色的用戶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 業(yè)務(wù)用戶

對(duì)于有多個(gè)業(yè)務(wù)部門,各部門間使用不同的數(shù)據(jù)庫(kù)用戶進(jìn)行業(yè)務(wù)操作,同時(shí)有一個(gè)同級(jí)的數(shù)據(jù)庫(kù)維護(hù)部門使用數(shù)據(jù)庫(kù)管理員進(jìn)行維護(hù)操作的場(chǎng)景下,業(yè)務(wù)部門可能希望在未經(jīng)授權(quán)的情況下,管理員用戶只能對(duì)各部門的數(shù)據(jù)進(jìn)行控制操作(DROP、ALTER、TRUNCATE),但是不能進(jìn)行訪問操作(INSERT、DELETE、UPDATE、SELECT、COPY)。即針對(duì)管理員用戶,表對(duì)象的控制權(quán)和訪問權(quán)要能夠分離,提高普通用戶數(shù)據(jù)安全性。

示例:創(chuàng)建普通用戶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,允許多個(gè)用戶使用同一數(shù)據(jù)庫(kù)而不相互干擾,可以將數(shù)據(jù)庫(kù)對(duì)象組織成易于管理的邏輯組,同時(shí)便于將第三方應(yīng)用添加到相應(yīng)的Schema下而不引起沖突。

每個(gè)數(shù)據(jù)庫(kù)包含一個(gè)或多個(gè)Schema。數(shù)據(jù)庫(kù)中的每個(gè)Schema包含表和其他類型的對(duì)象。數(shù)據(jù)庫(kù)創(chuàng)建初始,默認(rèn)具有一個(gè)名為public的Schema,且所有用戶都擁有此Schema的權(quán)限。可以通過Schema分組數(shù)據(jù)庫(kù)對(duì)象。Schema類似于操作系統(tǒng)目錄,但Schema不能嵌套。

相同的數(shù)據(jù)庫(kù)對(duì)象名稱可以應(yīng)用在同一數(shù)據(jù)庫(kù)的不同Schema中,而沒有沖突。例如,a_schema和b_schema都可以包含名為mytable的表。具有所需權(quán)限的用戶可以訪問數(shù)據(jù)庫(kù)的多個(gè)Schema中的對(duì)象。

在初始數(shù)據(jù)庫(kù)postgres中創(chuàng)建用戶時(shí),系統(tǒng)會(huì)自動(dòng)幫助用戶創(chuàng)建一個(gè)同名Schema。在其他數(shù)據(jù)庫(kù)中,若需要同名Schema,則需要用戶手動(dòng)創(chuàng)建。

數(shù)據(jù)庫(kù)對(duì)象是創(chuàng)建在數(shù)據(jù)庫(kù)搜索路徑中的第一個(gè)Schema內(nèi)的。

創(chuàng)建SCHEMA可以使用CREATE SCHEMA語句創(chuàng)建。

更改SCHEMA名稱或者所有者,可以使用ALTER SCHEMA語句進(jìn)行修改。

要?jiǎng)h除SCHEMA及其對(duì)象,使用DROP SCHEMA 語法可以進(jìn)行刪除。

要在SCHEMA內(nèi)創(chuàng)建表,以schema.tablename格式創(chuàng)建表。不指定schemaname時(shí),對(duì)象默認(rèn)創(chuàng)建到search_path中的第一個(gè)schema名稱。

示例1:創(chuàng)建schema對(duì)象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: 創(chuàng)建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:查看創(chuàng)建的表 st1 和 st2

--需要先設(shè)置schema的搜索路徑,否則找不到該schema1和schema2下的對(duì)象
postgres=# set search_path = public,schema1,schema2;
SET
--需要注意的是,設(shè)置search_path為多個(gè)時(shí),不要加引號(hào)
postgres=# d
         List of relations
 Schema  | Name | Type  |  Owner   
---------+------+-------+----------
 schema1 | st1  | table | postgres
 schema2 | st2  | table | postgres

示例5:為schema1和schema2下的兩張表st1和st2插入數(shù)據(jù)

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

示例6:使用之前創(chuàng)建的普通用戶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 ;
--此時(shí),user1用戶沒有足夠的權(quán)限可以使用schema1,因此需要對(duì)用戶user1授權(quán)對(duì)schema1的使用權(quán)限
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下的對(duì)象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
--此時(shí)雖然user1對(duì)schema雖然具有使用權(quán)限,但是沒有權(quán)限訪問schema1下的對(duì)象st1,
--因此還需要對(duì)schema1.st1授權(quán)user1可以訪問的權(quán)限,即select權(quán)限
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對(duì)schema1下的對(duì)象st1進(jìn)行查詢
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)

對(duì)于用戶user2,如果想要對(duì)schema2下的對(duì)象st2進(jìn)行查看,需要做上述同樣的操作。

綜上案例,可以發(fā)現(xiàn),如果一個(gè)普通用戶對(duì)于schema下的對(duì)象進(jìn)行訪問,修改等操作,首先要讓普通用戶具有對(duì)schema的使用權(quán)限,其次對(duì)schema下的對(duì)象要授權(quán)普通用戶具有訪問修改的權(quán)限。

三、設(shè)置密碼安全策略

設(shè)置賬戶的密碼安全策略

用戶密碼存儲(chǔ)在系統(tǒng)表pg_authid中,為防止用戶密碼泄露,PostgreSQL對(duì)用戶密碼進(jìn)行加密存儲(chǔ),所采用的加密算法由配置參數(shù)password_encryption_type決定。

當(dāng)參數(shù)password_encryption設(shè)置為 scram-sha-256 時(shí),表示采用 scram-sha-25 6方式對(duì)密碼加密。
當(dāng)參數(shù)password_encryption設(shè)置為 md5 時(shí),表示采用md5方式對(duì)密碼加密。md5為不安全的加密算法,不建議使用。

注意:PostgreSQL數(shù)據(jù)庫(kù)默認(rèn)采用MD5加密。該參數(shù)設(shè)置后需要重新啟動(dòng)數(shù)據(jù)庫(kù)服務(wù)器,并且需要更改原有密碼,使修改后用戶使用的密碼加密算法生效。

示例1:查看數(shù)據(jù)庫(kù)默認(rèn)加密算法

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

示例2:修改默認(rèn)加密算法為 scram-sha-256

postgres=# ALTER SYSTEM SET password_encryption = 'scram-sha-256';
ALTER SYSTEM
--重新啟動(dòng)數(shù)據(jù)庫(kù)服務(wù)器
[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:查看之前創(chuàng)建的用戶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數(shù)據(jù)庫(kù)

--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"
--此時(shí)輸入test的密碼,但是連接失敗,原因是由于在更改password_encryption為scram-sha-256之前,user1用戶的密碼存儲(chǔ)使用的加密策略為 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進(jìn)行連接
[postgres@PGServer2 ~]$ psql -U user1 -d postgres -h 10.10.20.101
Password for user user1: 
psql (10.11)
Type "help" for help.

postgres=>

密碼策略設(shè)置為scram-sha-256對(duì)數(shù)據(jù)隔離訪問具有安全性,因此生產(chǎn)環(huán)境中,建議使用scram-sha-256進(jìn)行加密。

四、行級(jí)安全(rls)策略

行級(jí)訪問控制特性將數(shù)據(jù)庫(kù)訪問控制精確到數(shù)據(jù)表行級(jí)別,使數(shù)據(jù)庫(kù)達(dá)到行級(jí)訪問控制的能力。不同用戶執(zhí)行相同的SQL查詢操作,讀取到的結(jié)果是不同的。

用戶可以在數(shù)據(jù)表創(chuàng)建行訪問控制(Row Level Security)策略,該策略是指針對(duì)特定數(shù)據(jù)庫(kù)用戶、特定SQL操作生效的表達(dá)式。當(dāng)數(shù)據(jù)庫(kù)用戶對(duì)數(shù)據(jù)表訪問時(shí),若SQL滿足數(shù)據(jù)表特定的Row Level Security策略,在查詢優(yōu)化階段將滿足條件的表達(dá)式,按照屬性(PERMISSIVE | RESTRICTIVE)類型,通過AND或OR方式拼接,應(yīng)用到執(zhí)行計(jì)劃上。

行級(jí)訪問控制的目的是控制表中行級(jí)數(shù)據(jù)可見性,通過在數(shù)據(jù)表上預(yù)定義Filter,在查詢優(yōu)化階段將滿足條件的表達(dá)式應(yīng)用到執(zhí)行計(jì)劃上,影響最終的執(zhí)行結(jié)果。當(dāng)前受影響的SQL語句包括SELECT,UPDATE,DELETE。

示例:假設(shè)一張表中存儲(chǔ)了不同用戶的數(shù)據(jù),但是不同的用戶只能看到自身相關(guān)的信息,不能訪問其它用戶的數(shù)據(jù)信息。

--創(chuàng)建用戶 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
--創(chuàng)建表 user_data,并插入不同用戶的不同數(shù)據(jù)
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,'經(jīng)理');
INSERT 0 1
postgres=#  INSERT INTO user_data  VALUES (3,'tom','男','昵稱:湯姆貓',22,'程序員');
INSERT 0 1

--將數(shù)據(jù)表user_data中讀取權(quán)限授權(quán)給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
--創(chuàng)建行訪問控制策略,當(dāng)前用戶只能查看用戶自身數(shù)據(jù)
postgres=# CREATE POLICY user_data_rls ON user_data FOR SELECT to PUBLIC USING (name = CURRENT_USER);
CREATE POLICY
--使用lily登錄查看user_data數(shù)據(jù)
 [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數(shù)據(jù)
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 | 經(jīng)理

--使用tom用戶查看user_data數(shù)據(jù)
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 | 程序員

小結(jié):

以上就是PostgreSQL數(shù)據(jù)庫(kù)中關(guān)于客戶端接入認(rèn)證,用戶級(jí)別安全和基于行安全(RLS)的內(nèi)容。

在PostgreSQL中,除了這些來控制數(shù)據(jù)庫(kù)的安全以外,還有pg_hba中的其它基于主機(jī)的訪問控制策略,數(shù)據(jù)庫(kù)訪問審計(jì)策略及對(duì)數(shù)據(jù)的加密策略。此章節(jié)中不再對(duì)涉及的其它安全訪問控制進(jìn)行一一探討。

總結(jié)

以上是生活随笔為你收集整理的PostgreSQL管理数据库安全的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。