Chapter 4. 使用者認証

Table of Contents
4.1. pg_hba.conf 文件
4.2. 認証方法
4.2.1. 信任認証
4.2.2. 密碼認証
4.2.3. Kerberos 認証
4.2.4. 基於 Ident 的認証
4.2.5. PAM 認証
4.3. 認証問題

當一個客戶端應用與資料庫伺服器進行連結時,它宣告 它將以哪個 PostgreSQL 使用者的名稱進行連結, 就象我們登錄一台 Unix 計算機 一樣.在 SQL 環境裡,活躍的資料庫使用者名決定資料庫物件的各種存取 權限--參閱Chapter 6獲取更多資訊.因此, 實際上我們要限制的是使用者可以連結的資料庫.

認証 是資料庫伺服器建立客戶端應用的標識, 然後通過一些手段判斷是否允許此客戶端應用(或者運行這個客戶端應用的 使用者)與它所要求的使用者名進行連結的過程.

PostgreSQL 提供多種不同的客戶端認証方式.認証某個特定客戶端連結所使用的方法可以通過基於 (客戶端)的主機位址,資料庫和使用者的方式進行選擇﹔ 一些認証方法還允許你通過使用者名進行限制.

PostgreSQL 使用者名在邏輯上是和 伺服器運行的操作系統使用者名相互獨立的. 如果某個伺服器的所有使用者在那台伺服器機器上也有帳號, 那麼給資料庫使用者賦與操作系統使用者名是有意義的.不過, 一個接收遠程存取的伺服器很有可能有許多沒有本地帳號的使用者, 因而在這種情況下資料庫使用者和操作系統使用者名之間不必有任何聯系.

4.1. pg_hba.conf 文件

客戶端認証是由資料目錄裡的文件pg_hba.conf 控制的,比如, /usr/local/pgsql/data/pg_hba.conf. (HBA 的意思是 host-based authentication:基於主機的認証.) 在initdb初始化資料目錄的時候,它會 安裝一個預設的文件.

文件 pg_hba.conf 的常用格式是一套記錄, 每行一條。空白行行被忽略,井號( "#" )開頭的註釋 也被忽略。一條記錄是由數個用空格和/或 tab 分隔的欄位組成。 如果欄位用引號包圍,那麼它可以包含空白.記錄不能夸行存在.

每條記錄宣告一種連結類型,一個客戶端 IP 位址範圍 (如果和連結類型相關的話),一個資料庫名,一個使用者名字, 以及對相符這些參數的連結使用的認証方法. 相符連結類型,客戶端位址和連結企圖請求的資料庫名和使用者名的第一條記錄 將用於執行認証.這個處理過程沒有"跨越"或者 "回頭"的說法︰如果選擇了一條記錄而且認証失敗,那麼 將不考慮後面的記錄.如果沒有相符的記錄,那麼存取將被拒絕.

每條記錄可以下面三種格式之一

local   database  user  authentication-method  [authentication-option]
host    database  user  IP-address  IP-mask  authentication-method  [authentication-option]
hostssl  database  user  IP-address  IP-mask  authentication-method  [authentication-option]
    

各個欄位的含義如下:

local

這條記錄相符通過 Unix 域通訊端進行的連結企圖. 沒有這種類型的記錄,就不允許 Unix 域通訊端的連結。

host

這條記錄相符通過 TCP/IP 網路進行的連結嘗試.請注意,除非伺服器是 帶著 -i 選項或者打開了 postgresql.conf 裡面的 tcpip_socket 配置參數集啟動的,否則 TCP/IP 連結是被禁止掉的.

hostssl

這條記錄相符通過在 TCP/IP 上進行的 SSL 連結企圖. host 記錄可以相符 SSL 和非 SSL 的連結企圖, 但 hostssl 記錄需要 SSL 連結。

要使用這個選項,制作伺服器的時候必須打開 SSL 支援.而且在伺服器啟動的時候, 必須打開在postgresql.conf裡的ssl選項。 (參閱 Section 3.4)。

database

宣告記錄所相符的資料庫。值 all 表明該記錄相符所有資料庫, 值 sameuser表示如果被請求的資料庫和請求的使用者同名,則相符。 samegroup 表示請求的使用者必須是一個與資料庫同名的組中的成員。 在其他情況裡,這就是一個特定的 PostgreSQL 的名字。 我們可以通過用逗號分隔的方法宣告多個資料庫。 一個包含資料庫名的文件可以 通過對該文件前綴 @ 來宣告.該文件必需和 pg_hba.conf 在同一個目錄.

user

為這條記錄宣告所相符的PostgreSQL使用者.值 all 表明它相符 於所有使用者.否則,它就是特定 PostgreSQL 使用者的名字.多個使用者名可以通過用逗號分隔的方法宣告.組名字 可以通過用 + 做組名字前綴來宣告.一個包含使用者名的文件可以 通過在文件名前面前綴 @ 來宣告.該文件必需和 pg_hba.conf 在同一個目錄.

IP-address
IP-mask

這兩個欄位包含標準的點分十進制表示的 IP位址/遮罩值。 (IP位址只能用數位的方式宣告,而不能用域名或者主機名。) 它們倆放在一起,宣告了這條記錄相符的客戶機的 IP 位址。 準確的邏輯是

(actual-IP-address xor IP-address-field) and IP-mask-field

對於要相符的記錄必需為零. (當然,IP位址是可以欺騙的,但是這個考慮在 PostgreSQL 的範圍之外。)

這些域只適用於 hosthostssl 記錄。

authentication-method(認証方法)

宣告通過這條記錄連結的時候使用的認証方法. 可能的選擇在下面簡介,詳細情況在 Section 4.2

trust

無條件地允許連結.這個方法允許任何可以與PostgreSQL 資料庫連結的使用者以他們期望的任意 PostgreSQL 資料庫使用者身份進行連結,而不需要密碼。 參閱 Section 4.2.1 獲取細節。

reject

連結無條件拒絕.常用於從一個組中"過濾"某些主機.

md5

要求客戶端提供一個 MD5 加密的密碼進行認証. 這個方法是允許加密密碼儲存在pg_shadow裡的唯一的一個方法. 參閱 Section 4.2.2 獲取細節。

crypt

類似 md5 方法,只是用的是老式的 crypt 加密認証, 用於 7.2 以前的客戶端.對於 7.2 以及以後的客戶端,我們建議使用 md5. 參閱 Section 4.2.2 獲取細節。

password

和"md5"一樣,但是密碼是以明文形式在網路上傳遞的. 我們不應該在不安全的網路上使用這個方式. 參閱 Section 4.2.2 獲取細節。

krb4

用 Kerberos V4 認証使用者.只有在進行 TCP/IP 連結的時候才能用. 參閱 Section 4.2.3 獲取細節。 (譯注:Kerberos,"克爾波洛斯",故希臘神話冥王哈得斯的多頭看門狗. Kerberos 是 MIT 開發出來的基與對稱加密算法的認証協定和/或密鑰 交換方法.其特點是需要兩個不同用途的伺服器,一個用於認証身份, 一個用於通道兩端使用者的密鑰交換.同時 Kerberos 對網路時間同步 要求比較高,以防止回放攻擊,因此通常伴隨 NTP 服務.)

krb5

用 Kerberos V5 認証使用者.只有在進行 TCP/IP 連結的時候才能用. 參閱 Section 4.2.3 獲取細節。 (譯注:Kerberos V5 是上面 V4 的改良,主要是不再依賴 DES 算法, 同時增加了一些新特性.)

ident

獲取客戶的操作系統名(對於 TCP/IP 連結,使用者的身份是通過與運行在客戶端上的 ident 伺服器連結進行判斷的,對於本地連結,它是從操作系統獲取的。) 然後檢查一下,看看使用者是否允許以要求的資料庫使用者進行連結, 方法是參照在 ident 關鍵字後面宣告的映射。

如果你使用了 sameuser 映射,那麼假設使用者名 是相等的。如果沒有宣告這個關鍵字,則在與 pg_hba.conf 同目錄的 pg_ident.conf 文件中找出映射名。如果這個文件裡包含一條記錄標識著ident提供的使用者名 和請求的 PostgreSQL 使用者名的映射, 那麼連結被接受。

對於本地連結,只有在系統支援Unix域通訊端信任証的情況下 才能使用(目前是 LinuxFreeBSDNetBSDOpenBSD, 和 BSD/OS)。

見下文Section 4.2.4獲取細節。

pam

使用操作系統提供的可插入的認証模組服務 (Pluggable Authentication Modules) (PAM)來認証。參閱 Section 4.2.5 獲取細節。

authentication-option

這個可選的欄位的含義取決與選擇的認証方法,它的描述在下一節裡。

因為認証時系統是為每個連結請求順序檢查 pg_hba.conf 裡的記錄的,所以這些記錄的順序 是非常關鍵的.通常,靠前的記錄有比較嚴的連結相符參數和比較弱的 認証方法,而靠後的記錄有比較松的相符參數和比較嚴的認証方法. 比如,我們一般都希望對本地 TCP 連結使用 trust 認証, 而對遠端的 TCP 連結要求密碼.在這種情況下我們將 trust 認証方法用於來自 127.0.0.1 的連結,這條記錄將出現在 允許更廣泛的客戶端 IP 位址的使用密碼認証的記錄前面.

Important: 不要禁止超級使用者存取 template1 資料庫。各種工具命令都 需要存取 template1。

在啟動和 postmaster 收到SIGHUP 信號的時候, 系統都會重新裝載 pg_hba.conf 文件. 如果你在活躍的系統上編輯了該文件,你就需要用 killpostmaster 發一個 SIGHUP信號,好讓它重新讀取該文件.

Example 4-1 裡是 pg_hba.conf 的一個範例. 閱讀下文理解不同認証方法的細節.

Example 4-1. 一個 pg_hba.conf 文件的範例

# 允許在本機上的任何使用者使用 Unix 域通訊端(本地連線的預設)
# 以任何身份連結任何資料庫
# 
#
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
local   all         all                                             trust


# 和上面相同,但是使用的是自環的(loopback)TCP/IP 連線
# 
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
host         all         all        127.0.0.1     255.255.255.255    trust

# 同樣,但用的是 Unix-通訊端連結

local        all         all                                         trust

# 允許 IP 位址為 192.168.93.x 的任何主機與資料庫
# "template1" 相連,用與他們在自己的主機上相同 ident 的使用者名標識他自己
# (通常是他的 Unix 使用者名)
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
host         template1   all        192.168.93.0  255.255.255.0      ident sameuser

# 允許來自主機 192.168.12.10 的使用者與 "template1" 資料庫連結,
# 只要該使用者提供了在正確的密碼.
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
host         template1   all        192.168.12.10 255.255.255.255    md5

# 如果前面沒有其它 "host" 行,那麼下面兩行將拒絕所有來自
# 192.168.54.1 的連結請求 (因為前面的記錄先相符
# 但是允許來自互聯網上其它任何地方的有效的 Kerberos V5 認証的連結
# 零遮罩表示不考慮主機 IP 的任何位.因此它相符任何主機:
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
host         all        all         192.168.54.1   255.255.255.255    reject
host         all        all         0.0.0.0        0.0.0.0            krb5

# 允許來自 192.168.x.x 的任何使用者與任意資料庫連結,只要他們通過 ident 檢查
# 但如果 ident 說該使用者是 "bryanh" 而他要求以 PostgreSQL 使用者 "guest1" 連結,
# 那麼只有在 `pg_ident.conf' 裡有 "omicron" 的映射,說 "bryanh" 允許以
#  "guest1" 進行連結時才真正可以進行連結.
#
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
host         all        all         192.168.0.0    255.255.0.0        ident omicron

# 如果下面是用於本地連結的僅有的三行,那麼它們將允許本地使用者
# 只和它們自己的資料庫連結(資料庫名和使用者名同名),
# 只有管理員和組"support"裡的成員例外,他們可以連結到任何資料庫。
# 文件 $PGDATA/admins 列出了那些允許與所有資料庫連結的使用者名.
# 在所有情況下都需要密碼。
# TYPE  DATABASE    USER        IP-ADDRESS        IP-MASK           METHOD
local   sameuser    all                                             md5
local   all         @admins                                         md5
local   all         +support                                        md5

# 上面最後兩行可以合起來寫成一行
local   all         @admins,+support                                md5

# 資料庫欄位也可以使用清單和文件名,但組不行:
local   db1,db2,@demodbs  all                                       md5