pg_hba.conf
ファイル #
クライアント認証はデータベースクラスタのデータディレクトリ内の、伝統的にpg_hba.conf
という名前の設定ファイルで管理されています
(HBAとは、host-based authentication: ホストベース認証の略です)。
デフォルトのpg_hba.conf
ファイルは、データディレクトリがinitdbで初期化される時にインストールされます。
しかし、この認証設定ファイルを他の場所に設置することができます。
hba_file設定パラメータを参照してください。
pg_hba.conf
ファイルの一般的な書式は、1行につき1つのレコードというレコードの集合です。
空行はコメント用の#
文字以降の文字と同じく無視されます。
行の最後をバックスラッシュで終えることによりレコードを次の行に継続できます。(行の最後を除き、バックスラッシュは特別扱いされません。)
レコードはスペースもしくはタブ、もしくはその両方で区切られた、複数のフィールドで構成されています。
フィールドには、フィールド値が二重引用符付きの場合空白文字を含むことができます。
データベース、ユーザもしくはアドレスフィールド内のキーワード(例:all
またはreplication
)の一つを引用するとその特別な意味が失われ、その名称のデータベース、ユーザもしくはホストと一致するようになります。
引用テキストあるいはコメントもバックスラッシュで行を継続できます。
それぞれの認証レコードは接続形式、(接続形式に対して意味を持つのであれば)クライアントのIPアドレス範囲、データベースの名前、ユーザ名およびこれらのパラメータに一致する接続で使用される認証方法を指定します。 接続形式、クライアントアドレス、要求されたデータベース、およびユーザ名に一致する最初のレコードが認証処理に使用されます。 「失敗時の継続」や、 あるいは「バックアップ」はありません。 これは、もしあるレコードが選択されて認証に失敗した場合、後続のレコードは考慮されないということです。 どのレコードも一致しない時はアクセスが拒否されます。
各レコードは、includeディレクティブまたは認証レコードにできます。
includeディレクティブは、追加レコードを含むインクルード可能なファイルを指定します。
レコードは、includeディレクティブの代わりに挿入されます。
includeディレクティブには以下の2つのフィールドのみが含まれます。include
、include_if_exists
またはinclude_dir
ディレクティブと、インクルードするファイルまたはディレクトリです。
ファイルまたはディレクトリは、相対または絶対パスにでき、二重引用符で囲むことができます。
include_dir
形式の場合、.
で始まらず.conf
で終わるすべてのファイルがインクルードされます。
インクルードディレクトリ内の複数のファイルは、ファイル名の順(Cロケールの規則に従って、すなわち、文字より先に数字、小文字より先に大文字)に処理されます。
レコードはいくつかの形式があります。
localdatabase
user
auth-method
[auth-options
] hostdatabase
user
address
auth-method
[auth-options
] hostssldatabase
user
address
auth-method
[auth-options
] hostnossldatabase
user
address
auth-method
[auth-options
] hostgssencdatabase
user
address
auth-method
[auth-options
] hostnogssencdatabase
user
address
auth-method
[auth-options
] hostdatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostssldatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostnossldatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostgssencdatabase
user
IP-address
IP-mask
auth-method
[auth-options
] hostnogssencdatabase
user
IP-address
IP-mask
auth-method
[auth-options
] includefile
include_if_existsfile
include_dirdirectory
フィールドの意味は以下のようになっています。
local
このレコードはUnixドメインソケットを使用する接続に対応します。 この種類のレコードを使用しないと、Unixドメインソケット経由の接続は拒否されます。
host
このレコードは、TCP/IPを使用した接続に対応します。
host
レコードは、SSLまたは非SSL接続、GSSAPI暗号化、非GSSAPI暗号化のいずれかに対応します。
サーバのデフォルトの動作は、ローカルループバックアドレスであるlocalhost
のみTCP/IP接続を監視しています。
よってサーバにおいてlisten_addressesパラメータが適切な値に設定された状態で起動されていない限り、リモートのTCP/IP接続はできません。
hostssl
このレコードは、接続がSSLで暗号化されている場合にのみTCP/IPネットワークを使用する接続に対応します。
このオプションを使用するためには、サーバはSSLサポートができるように構築されていなければいけません。
また、 SSLはsslパラメータを設定することによりサーバの起動時に有効になっていなくてはなりません(詳細は19.9を参照してください)。
そうでなければ、どのような接続にも対応していないという警告が表示されることを除き、hostssl
レコードは無視されます。
hostnossl
このレコードは、hostssl
と反対の動作で、SSLを使用していないTCP/IPの接続のみに対応します。
hostgssenc
このレコードは、TCP/IPを使用した接続に対応しますが、GSSAPI暗号化を使用して接続が行われた場合に限ります。
このオプションを使用するためには、サーバはGSSAPIサポートができるように構築されていなければいけません。
そうでなければ、どのような接続にも対応していないという警告が表示されることを除き、hostgssenc
レコードは無視されます。
hostnogssenc
このレコードは、hostgssenc
とは反対の動作で、GSSAPI暗号化を使用していないTCP/IPの接続のみに対応します。
database
このレコードで対応するデータベース名を指定します。
all
という値は、全てのデータベースと対応することを指定します。
sameuser
という値は、要求されたデータベースが要求ユーザと同じ名前を持つ場合にレコードが対応することを指定します。
samerole
という値は、要求ユーザが要求されたデータベースと同じ名前のロールのメンバでなければならないことを指定します。
(以前はsamegroup
と書いていましたが、samerole
と記述してください)
スーパーユーザは、直接的であれ間接的であれ、明示的にsameroleのメンバでない限りsameroleのメンバとはみなされません。
また、スーパーユーザであるからといってsamerole
のメンバとはみなされません。
replication
という値は、もし物理レプリケーション接続が要求された場合にレコードが一致することを指定します。
しかし、論理レプリケーションによる接続には一致しません。
物理レプリケーション接続は特定のデータベースを指定しないのに対し、論理レプリケーション接続は特定のデータベースを指定することに注意してください。
それ以外の場合には、特定のPostgreSQLデータベースの名前または正規表現になります。
データベースの名前や正規表現はカンマで区切ることで複数指定できます。
データベース名がスラッシュ(/
)で始まる場合、名前の残りの部分は正規表現として扱われます。
(PostgreSQLの正規表現構文の詳細については、9.7.3.1を参照してください。)
データベース名や正規表現を含む別のファイルを、そのファイル名の前に@
を付けることで指定できます。
user
このレコードで対応するデータベースユーザ名を指定します。
all
という値は、全てのユーザが対応することを指定します。
それ以外の場合には特定のデータベースユーザの名前、(スラッシュ(/
)で始まる場合には)正規表現、もしくは+
で始まるグループ名のいずれかになります。
(PostgreSQLではユーザとグループの明確な区別がないことを思い出してください。
+
のマークは実のところ、「このロールの直接的もしくは間接的なメンバのどちらかに一致していること」を意味しています。
一方、+
のマークがない名前はその特定のロールにのみ一致します。)
このため、スーパーユーザは、直接的であれ間接的であれ明示的にロールのメンバである場合にのみ、ロールのメンバとみなされます。
スーパーユーザであるからといってロールのメンバとはみなされません。
ユーザ名や正規表現は、カンマで区切ることで複数指定できます。
ユーザ名がスラッシュ(/
)で始まる場合、名前の残りの部分は正規表現として扱われます。
(PostgreSQLの正規表現構文の詳細については、9.7.3.1を参照してください。)
ユーザ名や正規表現を含む別のファイルを、そのファイル名の前に@
を付けることで指定できます。
address
このレコードに対応しているクライアントマシンのアドレス。 このフィールドはホスト名、IPアドレスの範囲、もしくは下記の特別なキーワードの1つを含んでいます。
IPアドレスの範囲は、範囲の開始アドレス、続いてスラッシュ(/
)とCIDRマスクの長さという標準の数値表記で指定されます。
CIDRマスク長とは、クライアントIPアドレスが一致しなければならない、高位のビット数を表すものです。
指定するIPアドレスのこれより右側のビットには、0を指定しなければなりません。
IPアドレスと/
、およびCIDRマスク長の間に空白を入れてはいけません。
典型的なIPv4アドレス範囲の例は、単一のホストでは172.20.143.89/32
、小規模ネットワークでは172.20.143.0/24
、大規模ネットワークでは10.6.0.0/16
のようなものです。
IPv6アドレスの範囲は、単一のホストでは::1/128
(この場合はIPv6ループバックアドレス)、小規模ネットワークではfe80::7a31:c1ff:0000:0000/96
のようなものです。
0.0.0.0/0
は全てのIPv4アドレスを意味します。また、::0/0
は全てのIPv6アドレスを意味しています。
単一ホストを指定するには、IPv4では32、IPv6では128というマスク長を使用してください。
ネットワークアドレスでは末尾の0を省略できません。
IPv4書式で与えられたエントリは、IPv4接続のみに対応し、IPv6書式で与えられた項目は、たとえそのアドレスがIPv6内のIPv4の範囲内であったとしてもIPv6接続のみに対応します。
どのIPアドレスにも一致するようにall
と書くこともできますし、
サーバ自身のIPアドレスのいずれかにも一致するようにsamehost
と書くこともできます。
もしくは、サーバが直接接続されているサブネット内のアドレスのいずれかにも一致するようにsamenet
と書くことができます。
もし、ホスト名(IPアドレスの範囲ではない場合の全て、もしくはホスト名として処理される特別なキーワード)が指定されている場合は、その名前は、クライアントのIPアドレスの逆引き名前解決の結果と比較されます(例えば、もしDNSが使用されている場合は逆引きDNS検索により解決されます)。
ホスト名の比較は、大文字小文字が区別されません。
もし一致するものがあった場合は、解決された、どのアドレスもクライアントのIPアドレスと等しいか否かをチェックするために(例えば、正引きDNS検索のような)ホスト名の正引き名前解決が実行されます。
もし正引き、逆引きの両方で一致した場合は、エントリは一致するものとみなされます。
(pg_hba.conf
内で使用されているホスト名は、クライアントのIPアドレスのアドレス-名前解決が返すホスト名の1つでなければいけません。
もしそうでなければこの行は一致しません。
1つのIPアドレスを複数のホスト名に関連付けるホスト名データベースもありますが、IPアドレスの解決を要求された場合にオペレーティングシステムは1つのホスト名のみを返します。)
ドット(.
)で始まるホスト名の特定は実際のホスト名のサフィックスに一致します。
よって、.example.com
は、foo.example.com
に一致します
(example.com
だけでは一致しません)。
ホスト名がpg_hba.conf
内で指定されている場合、名前解決が適度に早いことを
確かめてください。
nscd
のようなローカル名前解決のキャッシュを設定すると便利です。
また、クライアントのIPアドレスの代わりにホスト名がログで見られるように、log_hostname
の
設定パラメータを有効化することもできます。
これらのフィールドはlocal
レコードに適用されません。
時折、ユーザは、クライアントのIPアドレスの逆引きを含む2つの名前解決が必要になる、というような一見複雑に見える方法でなぜホスト名が扱われるのか不思議に思うことがあります。
このため、クライアントの逆引きDNSエントリが設定されていなかったり、いくつかの望ましくないホスト名を生成する場合にこの機能の使用が複雑になります。
これは主に効率のために行われます。このように、接続要求では最大2つのリゾルバの検索、1つは逆引き、1つは正引き、が必要になります。
もしリゾルバにおいて、アドレスに問題があった場合、クライアントのみの問題となります。
正引き検索のみを行うような実装を仮に行っていると、全ての接続要求においてpg_hba.conf
内に記載された全てのホスト名を解決しなくてはいけなくなります。
これは、多くの名前が列挙されていた場合にかなり遅くなります。
また、リゾルバにおいて1つのホスト名に問題があった場合、全員の問題となってしまいます。
さらに、逆引き検索はサフィックス一致の機能を実装するために必要です。というのも実際のクライアントのホスト名は ホスト名がパターンに対して一致するために、知られる必要があるためです。
このふるまいは、Apache HTTPサーバやTCPラッパーのような他のよくあるホスト名ベースのアクセス制御の実装と 一致していることに注意してください。
IP-address
IP-mask
この2つのフィールドはIP-address
/
mask-length
表記の代替として使用可能です。
マスク長を指定する代わりに、実際のマスクを分離した列で指定します。
例えば255.0.0.0
はIPv4のCIDRマスク長8を意味し、255.255.255.255
はCIDRマスク長32を意味しています。
これらのフィールドはlocal
レコードに適用されません。
auth-method
接続がこのレコードに一致する場合に使用する認証方式を指定します。
使用できる選択肢は以下にまとめていますが、詳しくは21.3を参照してください。
すべてのオプションは小文字で、大文字小文字の区別が認識されます。ですから、ldap
のような頭文字であっても小文字で指定しなければなりません。
trust
接続を無条件で許可します。 この方式は、PostgreSQLデータベースサーバに接続できる全てのユーザが、任意のPostgreSQLユーザとしてパスワードや他の認証なしでログインすることを許可します。 詳細は21.4を参照してください。
reject
接続を無条件に拒否します。
特定のホストをあるグループから「除外」するために便利です。
例えば、1行のreject
は特定のホストが接続することを拒否します。一方、
後ろの行では特定のネットワーク内の残りのホストが接続することを許可します。
scram-sha-256
ユーザのパスワードを検証するためにSCRAM-SHA-256認証を実行します。 詳細は21.5をご覧ください。
md5
ユーザのパスワードを検証するために、SCRAM-SHA-256あるいはMD5認証を実行します。 詳細は21.5を参照してください。
password
クライアントに対して認証時に平文のパスワードを要求します。 パスワードはネットワークを通じて普通のテキスト形式で送られますので、信頼されていないネットワークでは使用しないでください。 詳細は21.5を参照してください。
gss
ユーザの認証にGSSAPIを使用します。 これはTCP/IP接続を使用するときのみ使用可能です。 詳細は21.6を参照してください。 GSSAPI暗号化と組み合わせて使用できます。
sspi
ユーザの認証にSSPIを使用します。 これはWindowsを使用するときのみ使用可能です。 詳細は21.7を参照してください。
ident
クライアントのオペレーティングシステムにおけるユーザ名をクライアント上のidentサーバに尋ねてユーザ名が要求されたデータベースユーザ名と一致するか検査します。 ident認証は、TCP/IP接続でのみ使用可能です。ローカル接続が指定されている場合は、peer認証が代わりに使用されます。 詳細は21.8を参照してください。
peer
クライアントのオペレーティングシステムにおけるユーザ名をオペレーティングシステムから取得し、ユーザ名が要求されたデータベースユーザ名と一致するか検査します。 これはローカル接続の時にのみ使用可能です。詳細は21.9を参照してください。
ldap
LDAPサーバを使用して認証します。 詳細は21.10を参照してください。
radius
RADIUSサーバを使用して認証します。 詳細は21.11を参照してください。
cert
SSLクライアント証明書を使用して認証します。 詳細は21.12を参照してください。
pam
オペレーティングシステムによって提供されるPAM(Pluggable Authentication Modules)サービスを使用した認証です。 詳細は21.13を参照してください。
bsd
オペレーティングシステムによって提供されたBSD認証サービスを使用して認証します。 詳細は21.14を参照してください。
auth-options
auth-method
フィールドの後ろに、
認証方式のオプションを指定する、name
=
value
の形式のフィールドが存在する可能性があります。
どのオプションがどの認証方式に使用できるのか、についての詳細は以下で説明します。
以下に示された方式特定のオプションに加えて、方式に依存しないのひとつの認証オプションclientcert
があり、hostssl
レコードで指定できます。
このオプションは、verify-ca
またはverify-full
に設定できます。
どちらのオプションも、クライアントに有効な(信頼された)SSL証明書の提出を要求し、verify full
は、証明書のcn
(Common Name)がユーザー名または適用可能なマッピングと一致することをさらに強制します。
この動作はcert
認証方式(詳細は21.12を参照してください)に似ていますが、クライアント証明書の検証をhostssl
エントリをサポートする任意の認証方式と組み合わせることができます。
クライアント証明書認証を使用するすべてのレコード(つまり、cert
認証方式あるいはclientcert
オプションを使用している)では、clientname
オプションを使ってクライアント証明書資格情報のどの部分を照合するかを指定できます。
このオプションは2つの値のうち1つを持つことができます。
デフォルトであるclientname=CN
を指定すると、ユーザ名は証明書のCommon Name (CN)
と照合されます。
その代わりにclientname=DN
を指定すると、ユーザ名は証明書のDistinguished Name (DN)
全体と照合されます。
このオプションはおそらくユーザ名マップとともに使うのが最善です。
RFC 2253のDN
と比較されます。
この形式のクライアント証明書のDN
を参照するには以下のようにしてください。
openssl x509 -in myclient.crt -noout -subject -nameopt RFC2253 | sed "s/^subject=//"
このオプションを使ってDN
に対して正規表現を使った比較を行う際にはとりわけ注意が必要です。
include
この行は、指定したファイルの内容に置き換えられます。
include_if_exists
ファイルが存在する場合、この行は指定したファイルの内容に置き換えられます。 存在しない場合は、ファイルがスキップされたことを示すメッセージが記録されます。
include_dir
ファイル名が.
で始まらず、.conf
で終わる場合、この行は、そのディレクトリで見つかったすべてのファイルの内容に置き換えられ、ファイル名の順(Cロケールの規則に従って、すなわち、文字より先に数字、小文字より先に大文字)に処理されます。
@
式により含められるファイルは、空白文字あるいはカンマのどちらかで区切られた名前の列挙として読み込まれます。
コメントは、pg_hba.conf
と同様に#
から始まります。
また、@
式を入れ子にすることもできます。
@
の後のファイル名が絶対パスでない限り、参照元ファイルが存在するディレクトリから見た相対パスであるとみなされます。
pg_hba.conf
レコードは接続が試みられる度に順番に検査されますので、レコードの順序はとても大切です。
典型的には、始めの方のレコードには厳しい接続照合パラメータと緩い認証方式があるのに対し、終わりの方のレコードにはより緩い照合パラメータとより厳しい認証方式があります。
例えば、ローカルTCP接続ではtrust
認証方式、リモートTCP接続に対してはパスワードを要求したいとします。
この場合、広範囲にわたって許可されるクライアントのIPアドレスに対するパスワード認証を指定するレコードの前に127.0.0.1からの接続に対するtrust
認証指定のレコードが置かれなければなりません。
pg_hba.conf
ファイルは起動時と、主サーバプロセスがSIGHUPシグナルを受け取った時に読み込まれます。
稼働中のシステムでファイルを編集した場合は、(pg_ctl reload
の使用、SQL関数のpg_reload_conf()
の呼び出し、またはkill -HUP
を使用して)postmasterにファイルをもう一度読み込むようにシグナルを出さなければなりません。
上記はマイクロソフトWindowsに対して当てはまりません。
つまり、pg_hba.conf
に対する変更は、ただちにそれ以降の新しい接続に反映されます。
pg_hba.conf
に対する変更を事前にテストする際、あるいはそのファイルをロードしても期待していた結果が得られなかった場合には、システムビューpg_hba_file_rules
が役に立ちます。
そのビューのerror
フィールドがNULLでない行は、そのファイルの該当行に問題があることを示しています。
特定のデータベースに接続するためには、ユーザはpg_hba.conf
による検査を通過しなければならない他、そのデータベースに対するCONNECT
権限を持たなければなりません。
どのユーザがどのデータベースに接続できるかを制限したければ、通常、pg_hba.conf
項目に規則を追加するよりも、CONNECT
権限の付与・削除を行う方が簡単です。
pg_hba.conf
ファイルの例をいくつか例 21.1に示します。
各種認証方式の詳細についてはその後で説明します。
例21.1 pg_hba.conf
の項目の例
# ローカルシステム上の全てのユーザが、任意のデータベースに # 任意のデータベースユーザ名でUnixドメインソケットを使用して接続することを許可 # (ローカル接続ではデフォルト)。 # # TYPE DATABASE USER ADDRESS METHOD local all all trust # 上記と同じことをローカルループバックのTCP/IP接続を使って行う。 # # TYPE DATABASE USER ADDRESS METHOD host all all 127.0.0.1/32 trust # 上記と同じだが、独立したネットマスク列を使用する # # TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD host all all 127.0.0.1 255.255.255.255 trust # IPv6で上記と同じことを行う。 # # TYPE DATABASE USER ADDRESS METHOD host all all ::1/128 trust # ホスト名を使用して上記と同じことを行う(通常はIPv4とIPv6の両方をカバーします)。 # # TYPE DATABASE USER ADDRESS METHOD host all all localhost trust # DATABASEに対して正規表現を使って同じことを行う。(「db1234」や「db12」のような) # 「db」で始まり、2から4個の数字を使った番号で終わるデータベースへ接続することを許可。 # # TYPE DATABASE USER ADDRESS METHOD host "/^db\d{2,4}$" all localhost trust # IPアドレス192.168.93.xを持つ全てのホストの全てのユーザが、 # identがその接続について報告するのと同じユーザ名(典型的にはオペレーティングシステムのユーザ名)で # データベース「postgres」へ接続することを許可。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.93.0/24 ident # ユーザのパスワードが正しく入力された場合、 # ホスト192.168.12.10からのどのようなユーザでもデータベース「postgres」へ接続することを許可。 # # TYPE DATABASE USER ADDRESS METHOD host postgres all 192.168.12.10/32 scram-sha-256 # ユーザのパスワードが正しく指定された場合は、 # example.comドメイン内のホストからの、どのユーザからのデータベース接続も許可する。 # # Require SCRAM authentication for most users, but make an exception # for user 'mike', who uses an older client that doesn't support SCRAM # authentication. # # TYPE DATABASE USER ADDRESS METHOD host all mike .example.com md5 host all all .example.com scram-sha-256 # 先行する「host」行がなければ、これら3行によって、 # 192.168.54.1からの接続の試みを全て拒否(この項目が最初に照合されるため)、 # ただし、インターネット上の他の全ての場所からのGSSAPI接続は許可。 # ゼロマスクは、ホストIPアドレスのビットが考慮されずに # どのホストでも照合できることになる。 # 暗号化されていないGSSAPI接続(「hostgssenc」は暗号化されたGSSAPI接続 # にのみに一致するので、3行目までは「通過」)は許可されるが、192.168.12.10からのみ許可。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject hostgssenc all all 0.0.0.0/0 gss host all all 192.168.12.10/32 gss # 192.168.x.xホストからのユーザが、ident検査に通る場合、 # どのデータベースにでも接続を許可。もし、例えば、identが「bryanh」と認定し # 「bryanh」がPostgreSQLのユーザ「guest1」として # 接続要求を出す場合、「bryanh」は「guest1」として接続が許可されるという # マップ「omicron」に対する記載事項がpg_ident.confにあれば接続を許可。 # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.0.0/16 ident map=omicron # ローカル接続に対して、以下のたった4行しか記載がない場合、ローカルユーザは # 自分のデータベース(データベースユーザ名と同じ名前のデータベース)にのみ接続許可。 # ただし、名前が「helpdesk」で終わるユーザ、管理者、ロール「support」のメンバは # 全てのデータベースに接続可能。$PGDATA/adminsファイルは管理者のリストを含む。 # 全ての場合にパスワードが必要。 # # TYPE DATABASE USER ADDRESS METHOD local sameuser all md5 local all /^.*helpdesk$ md5 local all @admins md5 local all +support md5 # 上記の最後の2行は1つの行にまとめることが可能。 local all @admins,+support md5 # データベースの列にはリストやファイル名も使用できる。 local db1,db2,@demodbs all md5