19.2. 認證方法

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

19.2.1. 信任認證

如果聲明了 trust (信任)認證模式, PostgreSQL 就假設任何可以連線到伺服器的人都可以以任何他聲明的資料庫用戶(包括資料庫超級用戶)連接。 當然,在 databaseuser 字串裡面的限制仍然適用。 這個方法應該用於那些在連線到伺服器已經有足夠操作系統層次保護的環境裡。

trust 認證對於單用戶工作站的本地連線是非常合適和方便的。 通常它本身並適用於多用戶環境的機器。 不過,即使在多用戶的機器上,您也可以使用 trust, 只要您利用文件系統權限限制了對伺服器的 Unix 域套接字文件的訪問。 要做這些限制,您可以設置 參數 unix_socket_permissions (以及可能還有 unix_socket_group),就像 Section 16.4.2 裡描述的那樣。 或者您可以設置 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。這些方法操作上非常類似,只不過指令透過連線傳送的方法不同。 但是只有 md5 支援加密的指令儲存在 pg_shadow 裡; 其它兩種方法要求在該資料表中儲存未加密的指令。

如果您擔心指令被竊聽("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里是 /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, 並且預設存放在集群的資料目錄裡。 (不過,我們可以把映射文件放在其它地方,參閱 ident_file 配置參數。) 身份映射文件包含下面通用的格式:

map-name ident-username database-username

註釋和空白和 pg_hba.conf 文件裡的一樣處理。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 頁面