19.2. 認證方法

下面更詳細地描述認證方法。

19.2.1. 信任認證

如果聲明了 trust (信任)認證模式, PostgreSQL 就假設任何可以聯接到 服務器的人都可以以任何他聲明的數據庫用戶(包括數據庫超級用戶) 這個方法應該用于那些在聯接到服務器已經有足夠操作系統層次保護 的環境裡。

trust 認證對于單用戶工作站的本地聯接是非常合適和方便的。 通常它本身並適用于多用戶環境的機器。 不過,即使在多用戶的機器上,你也可以使用 trust, 只要你利用文件系統權限限制了對服務器的 Unix 域套接字文件的訪問。 要做這些限制,你可以設置 參數 unix_socket_permissions (以及可能還有 unix_socket_group),就象 Section 16.4.1 裡描述的那樣。或者你可以 設置 unix_socket_directory,把Unix 域套接字文件放在 一個經過恰當限制的目錄裡。

設置文件系統權限只能幫助 Unix 套接字聯接。它不會限制本地 TCP/IP 聯接; 因此,如果你想利用文件系統權限來控制本地安全,那麼刪除 pg_hba.conf 裡的 host ... 127.0.0.1 ... 行,或者把它改為一個 非 trust 的認證方法。

trust 認證模式只適合 TCP/IP 連接,只有在你信任那些在 pg_hba.conf 裡聲明為 trust,允許聯接到服務器的行上的所有機器 上面的所有用戶的時候才是合適的。很少有理由使用 trust 作為任何除來自localhost(127.0.0.1) 以外的 TCP/IP 聯接的認證方式。

19.2.2. 口令認證

以口令為基礎的認證方法包括 md5crypt, 和 password。這些方法操作上非常類似,只不過口令通過 聯接傳送的方法不同。如果你擔心口令被竊聽("sniffing"), 那麼 md5 比較合適,如果你必需支持 7.2 以前的老的客戶端, 那麼可以選 crypt。如果我們在開放的互聯網上使用, 應該盡可能避免使用 password(除非你在聯接上使用了 SSL, SSH,或者其他通訊安全的聯接封裝。)

PostgreSQL 數據庫口令與任何操作系統用戶口令無關。 各個數據庫用戶的口令是存儲在pg_shadow系統表裡面的。 口令可以用 SQL 語言命令CREATE USERALTER USER 等管理,也就是說, CREATE USER foo WITH PASSWORD 'secret';。缺省時,如果沒有明確地設置口令,存儲的口令是 空並且該用戶的口令認證總會失敗。

要限制允許訪問某數據庫的用戶集, 可以在 pg_hba.conf 中的 user 字段列出這些用戶,就像前面的小節解釋的那樣。

19.2.3. Kerberos 認證

Kerberos 是一種適用于在公共網絡上進行分布計算的工業標準的安全 認證系統。 對 Kerberos 系統的敘述遠遠的超出了本文檔的範圍; 概括說來它是相當復雜(同樣也相當強大)的系統。 Kerberos FAQMIT 雅典娜計劃 是個開始探索 的好地方。現存在好幾種Kerberos發布的源代碼。

要使用 Kerberos,對它的支持必須在制作的時候打開。 參閱 Chapter 14 獲取更多細節。 Kerberos 4 和 5 都被支持, 不過我們在一次制作中只能支持一個版本。

PostgreSQL 運行時象一個普通的 Kerberos 服務。 服務主的名字是 servicename/hostname@realm, 這裡的 servicenamepostgres (除非在配置時用 ./configure --with-krb-srvnam=whatever 選擇了一個不同的 hostname)。 hostname 是服務器及其全稱的主機名字。 服務器的域是服務器機器的優先域。

客戶主自給必須用它們自己的 PostgreSQL 用戶名作為 第一個部件,比如 pgusername/otherstuff@realm。 目前 PostgreSQL 沒有檢查客戶的域;因此如果你打開了 跨域的認證,那麼在任意域裡任何可以和你通訊的主都會被接受。

確認你的服務器的密鑰文件是可以被 PostgreSQL服務器帳戶讀取(最好就是只讀的)(又見 Section 16.1)。密鑰文件( keytab)的位置是 用運行時配置參數 krb_server_keyfile 聲明的。 (又見 Section 16.4。) 缺省時在 Kerberos 4 裡是 /etc/srvtab, Kerberos 5裡是 FILE:/usr/local/pgsql/etc/krb5.keytab (或者任何在制作的時候聲明為 sysconfdir 的目錄。)

要生成密鑰文件(keytab),可以用下面例子(對版本5)

kadmin% ank -randkey postgres/server.my.domain.org
kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org

閱讀 Kerberos 的文檔獲取詳細信息。

在和數據庫聯接的時候,請確保自己對每個主都擁有一張匹配所請求的數據庫 用戶名的門票。例子︰對于數據庫用戶 fred, 主 fred@EXAMPLE.COMfred/users.example.com@EXAMPLE.COM 都可以用于與數據庫服務器認證。

如果你在你的Apache web 服務器上使用了mod_auth_krbmod_perl, 你可以用一個mod_perl腳本進行 AuthType KerberosV5SaveCredentials。 這樣就有了一個通過 web 的安全數據庫訪問,不需要額外的口令。

19.2.4. 基于 Ident 的認證

身份(ident)認證方法的運做模式是使用一個映射文件列出許可的用戶 和對應的用戶的配對,然後通過檢查客戶端的操作系統用戶名 以及判斷許可的數據庫用戶名的方法來認證。判斷客戶端的用戶名 是非常關鍵的安全點,根據連接類型的不同,它的實現方法也略有不同。

19.2.4.1. 透過 TCP/IP 的身份認證

"Identification Protocol(標識協議)"RFC 1413 裡面描述。實際上每個類Unix的操作系統 都帶著一個缺省時偵聽113端口的身份服務器。 身份服務器的基本功能是回答類似這樣的問題: "是什麼用戶從你的端口X初始化出來 聯接到我的端口Y上來了?"。 因為在建立起物理聯接後,PostgreSQL 既知道 X 也知道 Y,因此它可以詢問 運行嘗試聯接的客戶端的主機,並且理論上可以用這個方法判斷 發起聯接的操作系統用戶。

這樣做的缺點是它取決于客戶端的完整性:如果客戶端不可信 或者被攻擊者攻破,而且它們可以在113端口上運行任何程序並且 返回他們選擇的任何用戶的話,就無法認證了。 因此這個認證方法只適用于封閉的網絡,這樣的網絡裡的每台客戶機 都處于嚴密的控制下並且數據庫和操作系統管理員可以比較方便地 聯系上。換句話說,你必須信任運行身份(ident)服務的機器。下面是警告:
 

身份標識協議並不適用于認證或者訪問控制協議。

 
--RFC 1413 

19.2.4.2. 透過本地套接字的身份認證

在支持用于 Unix 域套接字的SO_PEERCRED請求的系統上, (目前是 LinuxFreeBSDNetBSDOpenBSDBSD/OS), 身份認證也可以用于局部聯接。這個時候,使用身份認證不會增加 安全風險;實際上這也是在這種系統上使用本地聯接時的優選方法。

在沒有 SO_PEERCRED 請求的系統上,身份認證只能 通過TCP/IP連接獲取。如果需要繞開這個限制,我們可以聲明 localhost 地址 127.0.0.1,然後讓連接指向這個地址。

19.2.4.3. Ident 映射

當使用以身份為基礎的認證時,在判斷了初始化聯接的操作系統用戶 的名字後,PostgreSQL 判斷他是否可以以 他所請求的數據庫用戶的身份聯接。 這個判斷是由跟在pg_hba.conf 文件裡的 ident 關鍵字後面的身份映射控制的。 有一個預定義的身份映射是sameuser,表示任何 操作系統用戶都可以以同名數據庫用戶進行聯接(如果後者存在的 話)。其他映射必須手工創建。

sameuser 的身份映射存放在數據目錄的文件 pg_ident.conf 裡。每行的格式通常是:

map-name ident-username database-username

注釋和空白和普通情況一樣處理。map-name 是將用于 在pg_hba.conf裡引用這個映射的任意名稱。 另外兩個域聲明某個操作系統用戶被允許以哪個數據庫用戶的身份 進行聯接。同一個map-name 可以重復用于在一個映射裡聲明 更多的用戶映射。對一個操作系統用戶可以映射為多少個數據庫用戶沒有 限制,反之亦然。

在系統啟動和主服務器( postmaster )收到一個 SIGHUP 信號的時候會讀取 pg_ident.conf 文件。如果你在一台活躍的系統上 編輯該文件,那麼你需要給 postmaster 發信號 (用 pg_ctl reload 或者 kill -HUP) 令其重新讀取該文件。)

Example 19-2裡是 一個可以和在Example 19-1 裡面演示的pg_hba.conf文件 配合使用的 pg_ident.conf 文件。 在這個例子的設置裡,任何 登錄到 192.168 網絡裡的機器的用戶,如果用戶名不是 bryanhann,或 robert就不能獲準訪問。 Unix 用戶robert只有在試圖以PostgreSQL用戶 bob身份 聯接時才允許訪問,而不能是 robert 或其他什麼身份。 ann 將只允許以ann的 身份聯接。 用戶bryanh允許以他自己的 bryanh 身份 或者做為 guest1 進行聯接。

Example 19-2. 一個 pg_ident.conf 文件例子

# MAPNAME     IDENT-USERNAME    PG-USERNAME

omicron       bryanh            bryanh
omicron       ann               ann
# bob 在這台機器上的用戶名是 robert
omicron       robert            bob
# bryanh 也可以以 guest1 身份連接
omicron       bryanh            guest1

19.2.5. PAM 認證

這個認證方法操作起來類似 password, 只不過它使用 PAM(Pluggable Authentication Modules)作為 認證機制。缺省的 PAM 服務名是 postgresql。 你可以在文件 pg_hba.confpam 關鍵字後面提供自己的可選服務名。 有關 PAM 的更多信息,請閱讀 Linux-PAM頁面 Solaris PAM 頁面