1. 程式人生 > >從pg_hba.conf檔案談談postgresql的連線認證

從pg_hba.conf檔案談談postgresql的連線認證

文章引用

最近一直在弄postgresql的東西,搭建postgresql資料庫叢集環境什麼的。操作資料庫少不得要從遠端主機訪問資料庫環境,例如資料庫管理員的遠端管理資料庫,遠端的客戶存取資料庫檔案。

而在postgresql中配置檔案pg_hba.conf就是用來設定訪問認證的重要檔案。這裡重點談談pg_hba.conf這個檔案。

首先宣告,本文說明的內容基於postgresql的9.5.4版本,可能和某些低版本的說明有出入,這是postgresql官方自己更新的,如果想看低版本的,可以自己檢視下那個對應版本的使用者手冊。

1.pg_hba.conf檔案

在pg_hba.conf檔案中,每條記錄佔一行,指定一條訪問認證規則。

總的來說訪問控制記錄大致有以下7種形式:

local      database  user  auth-method  [auth-options]
host       database  user  address  auth-method  [auth-options]
hostssl    database  user  address  auth-method  [auth-options]
hostnossl  database  user  address  auth-method  [auth-options]
host       database  user  IP
-address IP-mask auth-method [auth-options] hostssl database user IP-address IP-mask auth-method [auth-options] hostnossl database user IP-address IP-mask auth-method [auth-options]

下面對每個欄位分別進行說明。

連線方式(type)

連線方式有四種:local 、host、hostssl、hostnossl

  1. local
    這條記錄匹配通過 Unix 域套接字進行的聯接企圖, 沒有這種型別的記錄,就不允許 Unix 域套接字的聯接。
  2. host
    這條記錄匹配通過TCP/IP網路進行的聯接嘗試.他既匹配通過ssl方式的連線,也匹配通過非ssl方式的連線。
    注意:要使用該選項你要在postgresql.conf檔案裡設定listen_address選項,不在listen_address裡的IP地址是無法匹配到的。因為預設的行為是隻在localhost上監聽本地連線。
  3. hostssl
    這條記錄匹配通過在TCP/IP上進行的SSL聯接企圖。
  4. hostnossl
    這個和上面的hostssl相反,只匹配通過在TCP/IP上進行的非SSL聯接企圖。

資料庫(database)

宣告記錄所匹配的資料庫。

值 all 表明該記錄匹配所有資料庫;

值 sameuser表示如果被請求的資料庫和請求的使用者同名,則匹配;

值samegroup 表示請求的使用者必須是一個與資料庫同名的組中的成員;

值 replication 表示匹配一條replication連線,它不指定一個特定的資料庫,一般在流複製中使用;

在其他情況裡,這就是一個特定的 PostgreSQL 資料庫的名字。 我們可以通過用逗號分隔的方法宣告多個數據庫。 一個包含資料庫名的檔案可以通過對該檔案字首 @ 來宣告.該檔案必需和 pg_hba.conf 在同一個目錄。

使用者名稱(user)

為這條記錄宣告所匹配的 PostgreSQL 使用者,值 all 表明它匹配 於所有使用者。否則,它就是特定 PostgreSQL 使用者的名字,多個使用者名稱可以通過用逗號分隔的方法宣告,在名字前面加上+代表匹配該使用者組的所有使用者。一個包含使用者名稱的檔案可以 通過在檔名前面字首 @ 來宣告,該檔案必需和 pg_hba.conf 在同一個目錄。

主機地址(address)

指定匹配的客戶端的地址,它可以是一個主機名,一個IP地址範圍,或者下面提到的這些選項。

一個IP地址範圍是一個標準的點分十進位制表示的 IP地址/掩碼值。注意, 在’IP地址’,’/’和’掩碼值’之間不要有任何的空白字元。

比如對於IPv4地址來說, 172.20.143.89/32指定單個主機的IP,172.20.143.0/24代表一個小的子網。對於IPv6地址來說,::1/128指定單個主機(這裡是本機環回地址),fe80::7a31:c1ff:0000:0000/96 指定一個IPv6的子網。0.0.0.0/0代表所有IPv4地址,::0/0代表所有IPv6地址。

一個IPv4地址選項只能匹配IPv4地址,一個IPv6地址選項只能匹配IPv6地址,即使給出的地址選項在IPV4和IPv6中同時存在。

當然你可以使用 all 選項來匹配所有的IP地址,使用 samehost 匹配伺服器自己所有的IP地址,samenet來匹配伺服器直接接入的子網。

如果指定的是主機名(既不是IP地址也不是上面提到的選項),這個主機名將會和發起連線請求的客戶端的IP地址的反向名稱解析結果(即通過客戶端的IP解析其主機名,比如使用反向DNS查詢)進行比對,如果存在匹配,再使用正向名稱解析(例如DNS查詢)將主機名解析為IP地址(可能有多個IP地址),再判斷客戶端的IP地址是否在這些IP地址中。如果正向和反向解析都成功匹配,那麼就真正匹配這個地址(所以在pg_nba.conf檔案裡的主機地址必須是客戶端IP的 address-to-name 解析返回的那個主機名。一些主機名資料庫允許將一個IP地址和多個主機名繫結,但是在解析IP地址時,作業系統只會返回一個主機名)。

有些主機名以點(.)開頭,匹配那些具有相同字尾的主機名,比如.example.com匹配foo.example.com(當然不僅僅只匹配foo.example.com)。

還有,在pg_hba.conf檔案中使用主機名的時候,你最好能保證主機名的解析比較快,一個好的建議就是建立一個本地的域名解析快取(比如nscd)。

本選項只能在連線方式是host,hostssl或者hostnossl的時候指定。

ip地址(ip-address)、子網掩碼(ip-mask)

這兩個欄位包含可以看成是標準點分十進位制表示的 IP地址/掩碼值的一個替代。例如。使用255.255.255.0 代表一個24位的子網掩碼。它們倆放在一起,聲明瞭這條記錄匹配的客戶機的 IP 地址或者一個IP地址範圍。本選項只能在連線方式是host,hostssl或者hostnossl的時候指定。

認證方法(authentication method)

trust
無條件地允許聯接,這個方法允許任何可以與PostgreSQL 資料庫聯接的使用者以他們期望的任意 PostgreSQL 資料庫使用者身份進行聯接,而不需要口令。

reject
聯接無條件拒絕,常用於從一個組中”過濾”某些主機。

md5
要求客戶端提供一個 MD5 加密的口令進行認證,這個方法是允許加密口令儲存在pg_shadow裡的唯一的一個方法。

password
和”md5”一樣,但是口令是以明文形式在網路上傳遞的,我們不應該在不安全的網路上使用這個方式。

gss
使用GSSAPI認證使用者,這隻適用於 TCP/IP 連線。

sspi
使用SSPI認證使用者,這隻適用於 Windows 連線。

peer
獲取客戶端的作業系統的使用者名稱並判斷他是否匹配請求的資料庫名,這隻適用於本地連線。

ldap
使用LDAP服務進行驗證。

radius
使用RADIUS服務進行驗證。

cert
使用SSL服務進行驗證。

pam
使用作業系統提供的可插入的認證模組服務 (Pluggable Authentication Modules)(PAM)來認證。

認證配置(authentication-option)

這個可選的欄位的含義取決與選擇的認證方法。手冊上也沒有具體的說明,但是給出瞭如下的例子供參考。

# Allow any user on the local system to connect to any database with
# any database user name using Unix-domain sockets (the default for local
# connections).
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     trust

# The same using local loopback TCP/IP connections.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             127.0.0.1/32            trust

# The same as the previous line, but using a separate netmask column
#
# TYPE  DATABASE        USER            IP-ADDRESS      IP-MASK             METHOD
host    all             all             127.0.0.1       255.255.255.255     trust

# The same over IPv6.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             ::1/128                 trust

# The same using a host name (would typically cover both IPv4 and IPv6).
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             localhost               trust

# Allow any user from any host with IP address 192.168.93.x to connect
# to database "postgres" as the same user name that ident reports for
# the connection (typically the operating system user name).
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    postgres        all             192.168.93.0/24         ident

# Allow any user from host 192.168.12.10 to connect to database
# "postgres" if the user's password is correctly supplied.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    postgres        all             192.168.12.10/32        md5

# Allow any user from hosts in the example.com domain to connect to
# any database if the user's password is correctly supplied.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             .example.com            md5

# In the absence of preceding "host" lines, these two lines will
# reject all connections from 192.168.54.1 (since that entry will be
# matched first), but allow GSSAPI connections from anywhere else
# on the Internet.  The zero mask causes no bits of the host IP
# address to be considered, so it matches any host.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             192.168.54.1/32         reject
host    all             all             0.0.0.0/0               gss

# Allow users from 192.168.x.x hosts to connect to any database, if
# they pass the ident check.  If, for example, ident says the user is
# "bryanh" and he requests to connect as PostgreSQL user "guest1", the
# connection is allowed if there is an entry in pg_ident.conf for map
# "omicron" that says "bryanh" is allowed to connect as "guest1".
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             192.168.0.0/16          ident map=omicron

# If these are the only three lines for local connections, they will
# allow local users to connect only to their own databases (databases
# with the same name as their database user name) except for administrators
# and members of role "support", who can connect to all databases.  The file
# $PGDATA/admins contains a list of names of administrators.  Passwords
# are required in all cases.
#
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   sameuser        all                                     md5
local   all             @admins                                 md5
local   all             +support                                md5

# The last two lines above can be combined into a single line:
local   all             @admins,+support                        md5

# The database column can also use lists and file names:
local   db1,db2,@demodbs  all                                   md5

2.一些tips和建議

pg_hba.conf檔案是如此重要,我們最好在建立資料庫的時候就將它配置好,免得後來配置環境時出一些奇奇怪怪的錯誤。在修改pg_hba.conf檔案後一定要記得pg_ctl reload一下。當然,還要做好備份。

可能是強迫症,我每次配置都是儘量最小配置(實際上也應該這麼做),比如指定使用者名稱,資料庫和可訪問IP地址的時候,就只給最小許可權,最小範圍就好了,避免自己誤操作是一回事,同時,把資料庫暴露在太多人面前總覺得不安全。

對於訪問認證的控制,除了在pg_hba.conf裡面設定外,也應該在資料庫裡再進一步設定,比如給某個使用者只授予所需的最低許可權,比如對查詢使用者就只給所需的某幾個資料庫資料庫的讀許可權,其他的只給資料庫表的增刪改查許可權等,這裡不贅述。

慎用trust認證方式,不要怕偷懶輸密碼,對於珍貴的資料來說多小心一點總沒錯,不然的話請閱讀《postgresql刪庫與跑路》(haha,just for fun~),當然實在怕懶可以設定下.pgpass這個檔案,懂得自然懂。

最後,對於系統資料庫最好還是設定下reject的吧。都不要亂動哈哈。