- 來源 | 願碼(ChainDesk.CN)內容編輯
- 願碼Slogan | 鏈接每一個程序員的故事
- 網站 | http://chaindesk.cn
- 願碼願景 | 打造全學科IT系統免費課程,助力小白用戶、初級工程師0成本免費系統學習、低成本進階,幫助BAT一線資深工程師成長並利用自身優點創造睡後收入。
- 官方公衆號 | 願碼 | 願碼服務號 | 區塊鏈部落
- 免費加入願碼全思惟工程師社羣 | 任一公衆號回覆「願碼」兩個字獲取入羣二維碼
本文閱讀時長:11min程序員
身份驗證回答了問題:誰是用戶?PostgreSQL支持一些 身份驗證方法,包括如下內容:web
· Trust認證:任何能夠鏈接到服務器的人都有權使用訪問pg_hba.conf配置文件中指定的數據庫/數據庫。一般用於容許在單個用戶計算機上使用Unix域套接字進行鏈接以訪問數據庫。此方法也能夠與TCP / IP一塊兒使用,但不多容許從本地主機之外的任何IP地址進行鏈接。 sql
· Ident認證:這經過從ident服務器獲取客戶端的操做系統用戶名而後使用它來訪問數據庫服務器來工做。這個方法建議用於客戶端計算機受系統管理員嚴格控制的封閉網絡。數據庫
· Peer認證:這相似於身份,但客戶端操做系統用戶名是從內核得到的。json
· GSSAPI認證:GSSAPI是RFC2743中定義的行業標準。它提供自動身份驗證(單點登陸)。安全
· LDAP認證: LDAP服務器僅用於驗證用戶名/密碼對。服務器
· 密碼認證:有如下三種方法網絡
o SCRAM-SHA-256:PostgreSQL 10中引入的最強的身份驗證方法。此方法可防止對不受信任的鏈接進行密碼嗅探。默認密碼驗證方法是MD5使用此功能,配置參數 password_encryption應更改成 scram-sha-256session
o MD5:MD5具備已知的限制,例如:預先計算的查找表以破解密碼哈希。此外,MD5只有40億個獨特的哈希值。最後,MD5計算速度很是快,所以暴力密碼猜想不須要大量的CPU資源。對於新應用程序,建議僅使用scram-sha-256。此外,PostgreSQL提供了從scram-sha-256遷移的方法。架構
o Password:建議不要使用此密碼,由於密碼以明文格式發送到服務器。
要了解身份驗證,您須要具備如下信息:
· 身份驗證經過pg_hba.conf文件控制,其中hba表明基於主機的身份驗證。
· 最好了解PostgreSQL發行版附帶的默認初始身份驗證設置
· pg_hba.conf文件一般位於數據目錄中,但也能夠在postgresql.conf配置文件中指定。
更改身份驗證時,您須要發送一個SIGHUP信號,這是經過基於PostgreSQL平臺的幾種方法完成的。注意,發送信號的用戶應該是超級用戶、Postgres或Linux發行版上的根系統用戶;一樣,這取決於平臺。如下是從新加載PostgreSQL配置的幾種方法的示例:
psql -U postgres -c "SELECT pg_reload_conf();" sudo service postgresql reload sudo /etc/init.d/postgresql reload sudo Kill -HUP sudo systemctl reload postgresql-11.service
· 該訂單的 pg_hba.conf記錄或條目是很是重要的。將會話鏈接pg_hba.conf逐個與記錄進行比較, 直到它被拒絕或到達配置文件的末尾。
· 最後,檢查PostgreSQL日誌文件以肯定配置從新加載後是否存在錯誤是很是重要的。
與postgresql.conf同樣,pg_hba.conf文件由一組記錄組成,可使用哈希符號註釋行,而且忽略空格。pg_hba.conf文件記錄的結構以下:
host_type database user [IP-address| address] [IP-mask] auth-method [auth-options]
host_type查詢的部分能夠是如下內容:
· Local:在 Linux系統中使用,容許用戶使用Unix域套接字鏈接訪問PostgreSQL。
· Host:這是爲了容許來自其餘主機的鏈接,基於地址或IP地址,使用帶有和不帶SSL加密的TCP / IP。
· Hostssl:這與主機相似,但應使用SSL加密鏈接。
· Hostnossl:這也與主機相似,但不該加密鏈接。
查詢的數據庫部分是用戶想要鏈接的數據庫的名稱。爲了提升靈活性,您還可使用以逗號分隔的列表來指定多個數據庫,或者能夠all用來指示用戶能夠訪問數據庫集羣中的全部數據庫。此外,可使用相同的用戶和相同的角色值來指示數據庫名稱與用戶名相同,或者用戶是與數據庫同名的角色的成員。
查詢的用戶部分指定數據庫用戶的名稱; 一樣,all值與全部用戶匹配。IP地址,地址和IP子網掩碼用於標識用戶所在的主機嘗試鏈接。可使用無類別域間路由(CIDR)或點十進制表示法指定IP地址。最後,密碼驗證方法能夠信任,MD5,拒絕等。
如下是配置PostgreSQL身份驗證的一些典型示例:
· 示例1:PostgreSQL集羣上的任何用戶均可以使用Unix域套接字訪問任何數據庫,如如下數據庫表所示:
#TYPE DATABASE USER ADDRESS METHOD Local all all trust
· 示例2:PostgreSQL集羣上的任何用戶均可以使用本地環回IP地址訪問任何數據庫,如如下數據庫表所示:
#TYPE DATABASE USER ADDRESS METHOD Host all all 127.0.0.1/32 trust host all all ::1/128 trust
· 示例3:192.168.0.53拒絕來自IP地址的全部鏈接 ,來自192.168.0.1/24範圍的鏈接被接受,以下數據庫表所示:
#TYPE DATABASE USER ADDRESS METHOD Host all all 192.168.0.53/32 reject Host all all 192.168.0.1/24 trust
PostgreSQL提供了一種很是方便的方法來查看pg_hba.conf文件中定義的規則,方法是提供一個名爲pg_hba_file_rules的視圖,以下所示:
postgres=# SELECT row_to_json(pg_hba_file_rules, true) FROM pg_hba_file_rules limit 1; row_to_json ------------------------- {"line_number":84, + "type":"local", + "database":["all"], + "user_name":["all"], + "address":null, + "netmask":null, + "auth_method":"trust",+ "options":null, + "error":null} (1 row)
該listen_addresses 選項定義於postgresql.conf。PostgreSQL listen_addresses鏈接設置用於標識服務器應從客戶端應用程序偵聽的IP地址列表。這些listen_addresses是以逗號分隔的主機名或IP地址列表。更改這個值須要重啓服務器。此外,還應注意如下幾點:
· 默認值爲localhost,它限制從網絡到PostgreSQL集羣的直接鏈接。
· 給出一個空列表意味着服務器應該只接受Unix套接字鏈接
· 該值*表示所有
對於新加入PostgreSQL的開發人員來講,忘記更改偵聽地址是一個常見的錯誤。若是開發人員忘記更改,並嘗試使用網絡中的TCP/IP鏈接到PostgreSQL,則會出現如下錯誤:
Connection refused
Is the server running on host and accepting
TCP/IP connections on port 5432?
身份驗證最佳實踐取決於整個基礎架構設置,應用程序的性質,用戶的特徵,數據敏感性等。例如,如下設置對於初創公司很常見:數據庫應用程序(包括數據庫服務器)託管在同一臺計算機上,而且僅由公司內部用戶從一個物理位置使用。
一般,數據庫服務器使用防火牆與世界隔離;在這種狀況下,您可使用SCRAM-SHA-256身份驗證方法並限制IP地址,以便數據庫服務器接受特定範圍或集合內的鏈接。請注意,重要的是不要使用超級用戶或數據庫全部者賬戶鏈接到數據庫,由於若是此賬戶被黑客入侵,則整個數據庫集羣將被暴露。
若是是應用服務器 - 業務邏輯 - 和數據庫服務器不在同一臺機器上,您可使用強大的身份驗證方法,例如LDAP和Kerberos。可是,對於數據庫服務器和應用程序位於同一臺計算機上的小型應用程序,SCRAM-SHA-256身份驗證方法以及將偵聽地址限制爲localhost可能就足夠了。
要對應用程序進行身份驗證,建議僅使用一個用戶,並嘗試使用鏈接池軟件減小容許的最大鏈接數,以便更好地調整PostgreSQL資源。在應用業務邏輯時可能須要另外一級別的安全性來區分不一樣的登陸用戶。對於真實用戶,更須要LDAP或Kerberos身份驗證。
此外,若是從外部世界訪問數據庫服務器,則使用SSL證書加密會話以免數據包嗅探頗有用。
您還應該記住保護信任全部localhost鏈接的數據庫服務器,由於訪問localhost的任何人均可以訪問數據庫服務器。
一般,在設計應用程序時,登陸角色用於配置數據庫鏈接和鏈接工具。須要實現另外一級安全性以確保使用該應用程序的用戶被受權執行某項任務。該邏輯一般在應用程序業務邏輯中實現。
在使用事務塊中的SET SESSION AUTHORIZATION 語句或SET ROLE命令創建或重用鏈接後,經過將身份驗證委派給另外一個角色,數據庫的角色系統也可用於部分實現此邏輯,以下所示:
postgres=# SELECT session_user, current_user; session_user | current_user --------------+-------------- postgres | postgres (1 row) postgres=# SET SESSION AUTHORIZATION test_user; SET postgres=> SELECT session_user, current_user; session_user | current_user --------------+-------------- test_user | test_user (1 row)
設置角色須要角色成員資格,而設置會話受權須要超級用戶權限。容許應用程序做爲超級用戶進行鏈接是危險的,由於能夠分別使用reset role和reset session命令重置set session authorization和set role命令,從而容許應用程序得到超級用戶權限。
爲了瞭解如何使用PostgreSQL角色系統來實現身份驗證和受權,咱們將使用角色系統和汽車門戶應用程序。在汽車門戶應用程序中,能夠將多組用戶分類爲web-app-user、public-user、registered-user、seller-user和admin-user。web應用程序用戶用於配置業務邏輯鏈接工具;公共用戶、註冊用戶和賣家用戶用於區分用戶。公共用戶組只能訪問公共信息,如廣告,但不能做爲註冊用戶添加評級,也不能建立廣告,由於賣家用戶。管理員用戶是管理應用程序全部內容的超級角色,例如過濾垃圾郵件和刪除不遵照網站策略的用戶。當汽車門戶網站應用程序鏈接到數據庫時,將使用Web用戶。以後,car_portal將根據用戶類調用set role命令。這種身份驗證方法稱爲代理身份驗證。
如下示例演示瞭如何使用角色系統來實現代理身份驗證。第一步是建立角色並分配角色成員身份和權限,以下所示:
CREATE ROLE web_app_user LOGIN NOINHERIT; CREATE ROLE public_user NOLOGIN; GRANT SELECT ON car_portal_app.advertisement_picture, car_portal_app.advertisement_rating , car_portal_app.advertisement TO public_user; GRANT public_user TO web_app_user; GRANT USAGE ON SCHEMA car_portal_app TO web_app_user, public_user;
該NOINHERIT選項web_app_user 不容許用戶繼承角色成員資格的權限;可是,web_app_user能夠將角色更改成公共用戶,如如下示例所示:
$ psql car_portal -U web_app_user car_portal=> SELECT * FROM car_portal_app.advertisement; ERROR: permission denied for relation advertisement car_portal=> SET ROLE public_user; SET car_portal=> SELECT * FROM car_portal_app.advertisement; advertisement_id | advertisement_date | car_id | seller_account_id ------------------+--------------------+--------+------------------- (0 rows) car_portal=> SELECT session_user, current_user; session_user | current_user --------------+-------------- web_app_user | public_user (1 row)