PostgreSQL管理数据库安全
前言
隨著技術(shù)的進(jìn)步和網(wǎng)絡(luò)技術(shù)的發(fā)展,安全是任何行業(yè)都需要面對的挑戰(zhàn),如前兩年爆發(fā)的WnCry電腦病毒,數(shù)據(jù)信息被加密。因此,數(shù)據(jù)安全始終需要預(yù)防。正因為數(shù)據(jù)庫作為存儲數(shù)據(jù)最重要的載體,所以除了硬件物理層面的數(shù)據(jù)安全防護之外,也需要在軟件層面加強數(shù)據(jù)安全防護。接下來介紹一下PostgreSQL中在數(shù)據(jù)安全層面對數(shù)據(jù)庫做防護。
目錄
一、客戶端接入認(rèn)證
二、管理用戶及安全
三、設(shè)置密碼安全策略
四、行級安全(rls)策略
一、客戶端接入認(rèn)證
PostgreSQL客戶端接入認(rèn)證的主要方式是通過pg_hba.conf文件來進(jìn)行配置。
1.1 配置客戶端接入認(rèn)證
客戶端接入認(rèn)證背景
如果主機需要遠(yuǎn)程連接數(shù)據(jù)庫,必須在數(shù)據(jù)庫系統(tǒng)的配置文件中增加此主機的信息,并且進(jìn)行客戶端接入認(rèn)證。配置文件(默認(rèn)名稱為pg_hba.conf)存放在數(shù)據(jù)庫的數(shù)據(jù)目錄里。hba(host-based authentication)表示是基于主機的認(rèn)證。
PostgreSQL支持如下三種認(rèn)證方式,這三種方式都需要配置pg_hba.conf文件。
基于主機的認(rèn)證:服務(wù)器端根據(jù)客戶端的IP地址、用戶名及要訪問的數(shù)據(jù)庫來查看配置文件從而判斷用戶是否通過認(rèn)證。
口令認(rèn)證:包括遠(yuǎn)程連接的加密口令認(rèn)證和本地連接的非加密口令認(rèn)證。
SSL加密:使用openssl(通用協(xié)議平臺)提供服務(wù)器端和客戶端安全連接的環(huán)境。
pg_hba.conf文件的格式是一行寫一條信息,表示一個認(rèn)證規(guī)則,空白和注釋(以#開頭)被忽略。
每個認(rèn)證規(guī)則是由若干空格和/,空格和制表符分隔的字段組成。如果字段用引號包圍,則它可以包含空白。一條記錄不能跨行存在。
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]
因為認(rèn)證時系統(tǒng)是為每個連接請求順序檢查pg_hba.conf里的記錄的,所以這些記錄的順序非常關(guān)鍵。
在配置 pg_hba.conf 文件時,請依據(jù)通訊需求按照格式內(nèi)容從上至下配置記錄,優(yōu)先級高的需求需要配置在前面。
若服務(wù)端pg_hba.conf文件配置了hostssl,postgresql.conf中必須開啟SSL認(rèn)證模式。
因此對于認(rèn)證規(guī)則的配置建議如下:
靠前的記錄有比較嚴(yán)格的連接參數(shù)和比較弱的認(rèn)證方法。
靠后的記錄有比較寬松的連接參數(shù)和比較強的認(rèn)證方法。
1.2 pg_hba.conf 配置文件參數(shù)說明及認(rèn)證方式
參數(shù)說明
| 參數(shù)名稱 | 描述 | 取值范圍 |
| local |
表示這條記錄只接受通過Unix域套接字進(jìn)行的連接。沒有這種類型的記錄,就不允許Unix域套接字的連接。 只有在從服務(wù)器本機使用gsql連接且在不指定-U參數(shù)的情況下,才是通過Unix域套接字連接。 |
- |
| host | 表示這條記錄既接受一個普通的TCP/IP套接字連接,也接受一個經(jīng)過SSL加密的TCP/IP套接字連接。 | - |
| hostssl | 表示這條記錄只接受一個經(jīng)過SSL加密的TCP/IP套接字連接。 | 用SSL進(jìn)行安全的連接,需要配置申請數(shù)字證書并配置相關(guān)參數(shù)。 |
| hostnossl | 表示這條記錄只接受一個普通的TCP/IP套接字連接。 | - |
| DATABASE | 聲明記錄所匹配且允許訪問的數(shù)據(jù)庫。 |
all:表示該記錄匹配所有數(shù)據(jù)庫。 說明: 值replication表示如果請求一個復(fù)制鏈接,則匹配,但復(fù)制鏈接不表示任何特定的數(shù)據(jù)庫。如需使用名為replication的數(shù)據(jù)庫,需在database列使用記錄 replication 作為數(shù)據(jù)庫名。 |
| USER | 聲明記錄所匹配且允許訪問的數(shù)據(jù)庫用戶。 |
all:表明該記錄匹配所有用戶。 說明: +表示前綴符號。 一個包含用戶名的文件或者文件中的用戶列表:文件可以通過在文件名前面加前綴@來聲明。文件中的用戶列表以逗號或者換行符分隔。 特定的數(shù)據(jù)庫用戶名或者用逗號分隔的用戶列表。 |
| ADDRESS | 指定與記錄匹配且允許訪問的IP地址范圍。 |
支持IPv4和IPv6,可以使用如下兩種形式來表示: IP地址/掩碼長度。例如,10.10.20.0/24 說明: 以IPv4格式給出的IP地址會匹配那些擁有對應(yīng)地址的IPv6連接,比如127.0.0.1將匹配IPv6地址 ::ffff:127.0.0.1 |
| METHOD | 聲明連接時使用的認(rèn)證方法。 |
支持如下幾種認(rèn)證方式 trust |
認(rèn)證方式
| 認(rèn)證方式 | 說明 |
| trust |
采用這種認(rèn)證模式時,使用psql且不指定-U參數(shù)的連接,此時不需要口令。 trust認(rèn)證對于單用戶工作站的本地連接是非常合適和方便的,通常不適用于多用戶環(huán)境。如果想使用這種認(rèn)證方法,可利用文件系統(tǒng)權(quán)限限制對服務(wù)器的Unix域套接字文件的訪問。要使用這種限制有兩個方法: 設(shè)置參數(shù)unix_socket_permissions和unix_socket_group。 須知: 設(shè)置文件系統(tǒng)權(quán)限只能Unix域套接字連接,它不會限制本地TCP/IP連接。 |
| reject | 無條件地拒絕連接。常用于過濾某些主機。 |
| md5 |
要求客戶端提供一個md5加密的口令進(jìn)行認(rèn)證。 須知: 不推薦使用md5認(rèn)證,因為md5為不安全的加密算法,存在網(wǎng)絡(luò)安全風(fēng)險。 |
| scram-sha-256 | md5的升級版本,要求客戶端提供一個sha256算法加密的口令進(jìn)行認(rèn)證,該口令在傳送過程中結(jié)合salt(服務(wù)器發(fā)送給客戶端的隨機數(shù))的單向sha256加密,增強了安全性。(推薦) |
| cert |
客戶端證書認(rèn)證模式,此模式需進(jìn)行SSL連接配置且需要客戶端提供有效的SSL證書,不需要提供用戶密碼。 須知: 該認(rèn)證方式只支持hostssl類型的規(guī)則。 |
| password | 使用明文密碼 |
1.3 使用SSL進(jìn)行安全的TCP/IP連接
從CA認(rèn)證中心申請到正式的服務(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/
驗證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)生成根證書請求文件
根證書文件名稱為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
已下發(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ù)器證書請求文件
輸入server.key的口令
輸入系統(tǒng)要求的一些信息
其中一些字段可以不填,確保和創(chuàng)建CA時的內(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ù)器證書請求文件,下發(fā)成功后,會生成一個正式的服務(wù)器證書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服務(wù)器使用ssl認(rèn)證連接
1)啟動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)重新啟動PostgreSQL服務(wù)器
輸入之前ssl認(rèn)證文件配置的密碼后,數(shù)據(jù)庫即能啟動
[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)限機制
數(shù)據(jù)庫對象創(chuàng)建后,進(jìn)行對象創(chuàng)建的用戶就是該對象的所有者。集群安裝后的默認(rèn)情況下,未開啟三權(quán)分立,數(shù)據(jù)庫系統(tǒng)管理員具有與對象所有者相同的權(quán)限。也就是說對象創(chuàng)建后,默認(rèn)只有對象所有者或者系統(tǒng)管理員可以查詢、修改和銷毀對象,以及通過GRANT將對象的權(quán)限授予其他用戶。
為使其他用戶能夠使用對象,必須向用戶或包含該用戶授予必要的權(quán)限。
不同的權(quán)限與不同的對象類型關(guān)聯(lián)。要撤消已經(jīng)授予的權(quán)限,可以使用REVOKE。對象所有者的權(quán)限(例如ALTER、 DROP、GRANT和REVOKE)是隱式的,無法授予或撤消。即只要擁有對象就可以執(zhí)行對象所有者的這些隱式權(quán)限。對象所有者可以撤消自己的普通權(quán)限,例如,使表對自己以及其他人只讀。
系統(tǒng)表和系統(tǒng)視圖要么只對系統(tǒng)管理員可見,要么對所有用戶可見。標(biāo)識了需要系統(tǒng)管理員權(quán)限的系統(tǒng)表和視圖只有系統(tǒng)管理員可以查詢。
數(shù)據(jù)庫提供對象隔離的特性,對象隔離特性開啟時,用戶只能查看有權(quán)限訪問的對象(表、視圖、字段、函數(shù)),系統(tǒng)管理員不受影響。
2.2 用戶
使用CREATE USER 和 ALTER USER 可以創(chuàng)建和管理數(shù)據(jù)庫用戶。數(shù)據(jù)庫包含一個或者多個已命名的數(shù)據(jù)庫。用戶和角色在整個數(shù)據(jù)庫中是共享的,但是數(shù)據(jù)并不共享。即用戶可以連接到任何數(shù)據(jù)庫,但當(dāng)連接成功后,任何用戶都只能訪問連接請求里聲明的那個數(shù)據(jù)庫。
2.2.1 管理員用戶
管理員用戶可以管理數(shù)據(jù)庫中的對象,可以通過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ù)用戶
對于有多個業(yè)務(wù)部門,各部門間使用不同的數(shù)據(jù)庫用戶進(jìn)行業(yè)務(wù)操作,同時有一個同級的數(shù)據(jù)庫維護部門使用數(shù)據(jù)庫管理員進(jìn)行維護操作的場景下,業(yè)務(wù)部門可能希望在未經(jīng)授權(quán)的情況下,管理員用戶只能對各部門的數(shù)據(jù)進(jìn)行控制操作(DROP、ALTER、TRUNCATE),但是不能進(jìn)行訪問操作(INSERT、DELETE、UPDATE、SELECT、COPY)。即針對管理員用戶,表對象的控制權(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,允許多個用戶使用同一數(shù)據(jù)庫而不相互干擾,可以將數(shù)據(jù)庫對象組織成易于管理的邏輯組,同時便于將第三方應(yīng)用添加到相應(yīng)的Schema下而不引起沖突。
每個數(shù)據(jù)庫包含一個或多個Schema。數(shù)據(jù)庫中的每個Schema包含表和其他類型的對象。數(shù)據(jù)庫創(chuàng)建初始,默認(rèn)具有一個名為public的Schema,且所有用戶都擁有此Schema的權(quán)限。可以通過Schema分組數(shù)據(jù)庫對象。Schema類似于操作系統(tǒng)目錄,但Schema不能嵌套。
相同的數(shù)據(jù)庫對象名稱可以應(yīng)用在同一數(shù)據(jù)庫的不同Schema中,而沒有沖突。例如,a_schema和b_schema都可以包含名為mytable的表。具有所需權(quán)限的用戶可以訪問數(shù)據(jù)庫的多個Schema中的對象。
在初始數(shù)據(jù)庫postgres中創(chuàng)建用戶時,系統(tǒng)會自動幫助用戶創(chuàng)建一個同名Schema。在其他數(shù)據(jù)庫中,若需要同名Schema,則需要用戶手動創(chuàng)建。
數(shù)據(jù)庫對象是創(chuàng)建在數(shù)據(jù)庫搜索路徑中的第一個Schema內(nèi)的。
創(chuàng)建SCHEMA可以使用CREATE SCHEMA語句創(chuàng)建。
更改SCHEMA名稱或者所有者,可以使用ALTER SCHEMA語句進(jìn)行修改。
要刪除SCHEMA及其對象,使用DROP SCHEMA 語法可以進(jìn)行刪除。
要在SCHEMA內(nèi)創(chuàng)建表,以schema.tablename格式創(chuàng)建表。不指定schemaname時,對象默認(rèn)創(chuàng)建到search_path中的第一個schema名稱。
示例1:創(chuàng)建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: 創(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下的對象
postgres=# set search_path = public,schema1,schema2;
SET
--需要注意的是,設(shè)置search_path為多個時,不要加引號
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 ; --此時,user1用戶沒有足夠的權(quán)限可以使用schema1,因此需要對用戶user1授權(quán)對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下的對象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雖然具有使用權(quán)限,但是沒有權(quán)限訪問schema1下的對象st1, --因此還需要對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對schema1下的對象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)
對于用戶user2,如果想要對schema2下的對象st2進(jìn)行查看,需要做上述同樣的操作。
綜上案例,可以發(fā)現(xiàn),如果一個普通用戶對于schema下的對象進(jìn)行訪問,修改等操作,首先要讓普通用戶具有對schema的使用權(quán)限,其次對schema下的對象要授權(quán)普通用戶具有訪問修改的權(quán)限。
三、設(shè)置密碼安全策略
設(shè)置賬戶的密碼安全策略
用戶密碼存儲在系統(tǒng)表pg_authid中,為防止用戶密碼泄露,PostgreSQL對用戶密碼進(jìn)行加密存儲,所采用的加密算法由配置參數(shù)password_encryption_type決定。
當(dāng)參數(shù)password_encryption設(shè)置為 scram-sha-256 時,表示采用 scram-sha-25 6方式對密碼加密。
當(dāng)參數(shù)password_encryption設(shè)置為 md5 時,表示采用md5方式對密碼加密。md5為不安全的加密算法,不建議使用。
注意:PostgreSQL數(shù)據(jù)庫默認(rèn)采用MD5加密。該參數(shù)設(shè)置后需要重新啟動數(shù)據(jù)庫服務(wù)器,并且需要更改原有密碼,使修改后用戶使用的密碼加密算法生效。
示例1:查看數(shù)據(jù)庫默認(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 --重新啟動數(shù)據(jù)庫服務(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ù)庫
--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進(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對數(shù)據(jù)隔離訪問具有安全性,因此生產(chǎn)環(huán)境中,建議使用scram-sha-256進(jìn)行加密。
四、行級安全(rls)策略
行級訪問控制特性將數(shù)據(jù)庫訪問控制精確到數(shù)據(jù)表行級別,使數(shù)據(jù)庫達(dá)到行級訪問控制的能力。不同用戶執(zhí)行相同的SQL查詢操作,讀取到的結(jié)果是不同的。
用戶可以在數(shù)據(jù)表創(chuàng)建行訪問控制(Row Level Security)策略,該策略是指針對特定數(shù)據(jù)庫用戶、特定SQL操作生效的表達(dá)式。當(dāng)數(shù)據(jù)庫用戶對數(shù)據(jù)表訪問時,若SQL滿足數(shù)據(jù)表特定的Row Level Security策略,在查詢優(yōu)化階段將滿足條件的表達(dá)式,按照屬性(PERMISSIVE | RESTRICTIVE)類型,通過AND或OR方式拼接,應(yīng)用到執(zhí)行計劃上。
行級訪問控制的目的是控制表中行級數(shù)據(jù)可見性,通過在數(shù)據(jù)表上預(yù)定義Filter,在查詢優(yōu)化階段將滿足條件的表達(dá)式應(yīng)用到執(zhí)行計劃上,影響最終的執(zhí)行結(jié)果。當(dāng)前受影響的SQL語句包括SELECT,UPDATE,DELETE。
示例:假設(shè)一張表中存儲了不同用戶的數(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ù)庫中關(guān)于客戶端接入認(rèn)證,用戶級別安全和基于行安全(RLS)的內(nèi)容。
在PostgreSQL中,除了這些來控制數(shù)據(jù)庫的安全以外,還有pg_hba中的其它基于主機的訪問控制策略,數(shù)據(jù)庫訪問審計策略及對數(shù)據(jù)的加密策略。此章節(jié)中不再對涉及的其它安全訪問控制進(jìn)行一一探討。
總結(jié)
以上是生活随笔為你收集整理的PostgreSQL管理数据库安全的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows系统怎么安装新字体如何给电
- 下一篇: 腾达路由器如何开启WPS腾达路由器如何打