以下の小節では、認証方式について詳細に説明します。
trust
認証が指定されるとPostgreSQLは、サーバに接続できる全ての人に対して
(データベーススーパーユーザさえも)その人が指定する任意のデータベースユーザ名としてのアクセス権限が付与されていると想定します。
当然ながらdatabase
とuser
列にある制限は適用されます。
この方式はサーバに接続する際に適切なオペレーティングシステムレベルの保護が掛けられている場合にのみ使用すべきです。
trust
認証はユーザが1人のみのワークステーション上でローカル接続を行う場合は適切であると同時に非常に便利です。
複数ユーザが存在するマシン上では一般的に適切ではありません。
とは言っても、ファイルシステムの許可属性を使ってサーバのUnixドメインソケットファイルへのアクセスを制限すればtrust
認証を複数ユーザのマシン上で使用することも可能です。
その方法は、18.3. 接続と認証に記載されているようにunix_socket_permissions
(およびunix_socket_group
パラメータの可能性もあります)パラメータを設定します。
もしくは、unix_socket_directories
設定パラメータでソケットファイルをそれに相応しく制限されているディレクトリにします。
Unixソケット接続を行うただ1つの方法は、ファイルシステムの許可を設定することです。
ローカルのTCP/IP接続は、ファイルシステムにより制限はされていません。
よってローカルでファイルシステムの許可を使用したい場合はpg_hba.conf
から
host ... 127.0.0.1 ...
の行を削除するか、trust
認証とは異なる方法に変更する必要があります。
TCP/IP接続におけるtrust
認証は、trust
を指定するpg_hba.conf
の行によってサーバに接続を許可される全てのマシン上の全てのユーザを信用(trust)できる場合にのみ相応しいものです。
ローカルホスト(127.0.0.1)以外からのTCP/IP接続にtrust
認証を用いる理由はほとんど見当たりません。
パスワードをベースにした認証方式には md5
およびpassword
があります。
これらの方式はパスワードが接続間でどのように送信されるか(すなわち、それぞれMD5-hashed、平文)を別にすれば似たような動作をします。
もしパスワード「盗聴」攻撃に最大の関心があればmd5
を使うのがよいでしょう。
可能ならば、平文のpassword
の使用は常に避けなければなりません。
しかしmd5
はdb_user_namespace機能といっしょに使用することはできません。
接続がSSL暗号化により保護されているのであれば、password
を安全に使用することができます。
(ただしSSLの使用に依存するという点では、SSL証明書認証を使用した方が良いかもしれません。)
PostgreSQLデータベースパスワードはオペレーティングシステムのユーザパスワードとも別のものです。
各データベースユーザのパスワードはpg_authid
システムカタログテーブルの中に格納されます。
CREATE USER foo WITH PASSWORD 'secret';
のように、パスワードはSQLコマンドCREATE USERとALTER ROLEを使って管理できます。
もしユーザに対してパスワードが設定されない場合、格納されるパスワードはNULLとなり、そのユーザのパスワード認証は常に失敗します。
GSSAPIは、RFC 2743で定義されている安全な認証のための業界標準のプロトコルです。 PostgreSQLは、RFC 1964によりKerberos認証でのGSSAPIをサポートします。 GSSAPIは、GSSAPIをサポートしているシステムに対して自動認証(シングルサインオン)を提供します。 認証自体は安全ですが、データベース接続を通じて送信されるデータは、SSLが使用されていない場合は平文となります。
GSSAPIサポートは、PostgreSQLを構築する時に有効にしなければなりません。詳細は、15章 ソースコードからインストールを参照してください。
GSSAPIがKerberosを使用しているとき、GSSAPIは、
という書式の標準のプリンシパルを使用します。
[訳注:プリンシパルとは大雑把に2つのものを指します。1つはサービスを受けるクライアントで、もう1つはサービスを提供するサーバアプリケーションです。どちらも、認証に関してはKerberosのKDCから見るとクライアントになります]
PostgreSQLサーバはサーバにより使われるkeytabに含まれるいかなるプリンシパルも受け付けますが、servicename
/hostname
@realm
krbsrvname
接続パラメータを使ってクライアントから接続する場合には、プリンシパルの詳細を正確に指定することに注意を払う必要があります。
(31.1.2. パラメータキーワードも参照してください。)
ビルド時に./configure --with-krb-srvnam=whatever
を使用することで、インストール時のデフォルトはデフォルトのpostgres
から変更が可能です。
多くの環境では、このパラメータは変更する必要はないでしょう。
いくつかのKerberosの実装では、異なるサービス名が必要になります。Microsoftアクティブディレクトリではサービス名は(POSTGRES
)のように大文字にする必要があります。
hostname
はサーバマシンの完全修飾されたホスト名です。
サービスプリンシパルのrealmはサーバマシンが提起したrealmです。
クライアントのプリンシパルはpg_ident.conf
で異なるPostgreSQLのデータベースユーザ名にマップできます。
例えば、pgusername@realm
を単なるpgusername
にマップできます。
もう1つの方法として、プリンシパル名全体username@realm
をPostgreSQLのロール名としてマッピングなしに使うこともできます。
PostgreSQLはプリンシパルからrealmを外すパラメータもサポートしています。
この方法は後方互換のためにサポートされているものであり、異なるrealmから来た同じユーザ名の異なるユーザを区別することができませんので、使用しないことを強く薦めます。
この方法を有効にするにはinclude_realm
を0に設定してください。
単純な単一realmの設定では、(指定されたrealmがkrb_realm
パラメータ内のものと正確に一致するか確認する)krb_realm
パラメータと組み合わされたinclude_realm
で安全でしょうが、pg_ident.conf
で明示的なマッピングを指定するのに比べてあまり適切でない選択でしょう。
サーバ鍵ファイルがPostgreSQLサーバアカウントによって読み込み可能(そしてできれば読み込み専用)であることを確認してください。
(17.1. PostgreSQLユーザアカウントを参照してください。)
鍵ファイルの保存場所はkrb_server_keyfile設定パラメータで指定されます
デフォルトは、/usr/local/pgsql/etc/krb5.keytab
(もしくはビルド時にsysconfdir
で指定されたディレクトリ)です。
セキュリティ上の理由から、システムkeytabファイルで許可するよりも、PostgreSQLサーバ用に別のkeytabファイルを使うことをお薦めします。
keytabファイルはKerberosのソフトウェアによって作成されます。詳細はKerberosのドキュメントを参照してください。 MIT互換のKerberos5実装の例を以下に示します。
kadmin%
ank -randkey postgres/server.my.domain.org
kadmin%
ktadd -k krb5.keytab postgres/server.my.domain.org
データベースに接続しようとしている時要求されるデータベースユーザ名に一致するプリンシパルのチケットを所有しているか確認してください。
例えば、データベースユーザ名fred
に対し、fred@EXAMPLE.COM
のプリンシパルは接続できるでしょう。
fred/users.example.com@EXAMPLE.COM
のプリンシパルも許可するためには19.2. ユーザ名マップ内に記述されているユーザ名マップを使用して下さい。
次の設定オプションはGSSAPIのためにサポートされています。
include_realm
0に設定されている場合は、認証されたユーザプリンシパルからのrealm名が、ユーザ名マッピング(19.2. ユーザ名マップ)で渡されるシステムユーザ名から外されています。
krb_realm
も一緒に使われていない限り、これは複数realm環境で安全ではありませんので、非推奨であり、主に後方互換性のために利用できます。
include_realmをデフォルト(1)にしたまま、pg_ident.conf
で明示的なマッピングを指定することをお薦めします。
map
システムとデータベースの間のマッピングを許可します。詳細は19.2. ユーザ名マップを参照してください。
GSSAPI/Kerberosプリンシパルusername@EXAMPLE.COM
(もしくは、あまり一般的ではありませんがusername/hostbased@EXAMPLE.COM
)に対しては、もしinclude_realm
が0に設定されていない限り、マッピングに使われるユーザ名はusername@EXAMPLE.COM
(もしくはusername/hostbased@EXAMPLE.COM
)です。
0に設定されている場合には、username
(もしくはusername/hostbased
)がマッピング時のシステムユーザ名です。
krb_realm
realmをユーザプリンシパル名に一致するように設定します。 もしこのパラメータが設定されている場合はそのrealmのユーザのみが受け付けられます。 もしこれが設定されていない場合は、どのようなrealmのユーザも接続可能で、ユーザ名マッピングが設定されていれば、どれでも影響を受けます。
SSPIは、シングルサインオンで安全な認証を行うためのWindowsの技術です。
PostgreSQLは、negotiate
モードにおいてSSPIを使用します。
これは、可能な場合はKerberosを使用し、他の場合については自動的にNTLMを使用することを意味しています。
SSPI認証は、サーバ、クライアントが共にWindows上もしくはGSSAPIが利用可能な場合はWindowsではないプラットフォームで稼動しているときにのみ動作します。
Kerberos認証を使用しているとき、 SSPIは、GSSAPIと同じように動作します。 詳細は19.3.3. GSSAPI認証を参照してください。
次の設定オプションはSSPIのためにサポートされています。
include_realm
0に設定されている場合は、認証されたユーザプリンシパルからのrealm名が、ユーザ名マッピング(19.2. ユーザ名マップ)で渡されるシステムユーザ名から外されています。
krb_realm
も一緒に使われていない限り、これは複数realm環境で安全ではありませんので、非推奨であり、主に後方互換性のために利用できます。
include_realmをデフォルト(1)にしたまま、pg_ident.conf
で明示的なマッピングを指定することをお薦めします。
map
システムとデータベースユーザ名の間のマッピングを許可します。
詳細は19.2. ユーザ名マップを参照してください。
GSSAPI/Kerberosプリンシパルusername@EXAMPLE.COM
(もしくは、あまり一般的ではありませんがusername/hostbased@EXAMPLE.COM
)に対しては、もしinclude_realm
が0に設定されていない限り、マッピングに使われるユーザ名はusername@EXAMPLE.COM
(もしくはusername/hostbased@EXAMPLE.COM
)です。
0に設定されている場合には、username
(もしくはusername/hostbased
)がマッピング時のシステムユーザ名です。
krb_realm
realmをユーザプリンシパル名に一致するように設定します。もしこのパラメータが設定されている場合は realmのユーザのみが受け付けられます。もしこれが設定されていない場合は、 どのようなrealmのユーザも接続可能で、ユーザ名マッピングが設定されていれば、どれでも影響を受けます。
ident認証方式は、クライアントのオペレーティングシステムのユーザ名をidentサーバから入手し、それを(オプションのユーザ名マップとともに)許可されているデータベースのユーザ名として使用します。 これはTCP/IP接続のみサポートされます。
identが(TCP/IPではない)ローカル接続で指定されている場合、 ピア認証(19.3.6. Peer認証を参照してください)が代わりに使用されます。
次の設定オプションはidentのためにサポートされています。
map
システムとデータベースユーザ名の間のマッピングを許可します。 詳細は19.2. ユーザ名マップを参照してください。
「身元特定(Identification)プロトコル」についてはRFC 1413で説明されています。
事実上全てのUnix系のオペレーティングシステムの配布には、デフォルトでTCPポート113を監視するidentサーバが付属しています。
identサーバの基本的な機能は「どのユーザがポートX
からの接続を開始し、自分のポートY
への接続を初期化したのか?」というような質問に答えることです。
PostgreSQLは物理的な接続が確立された時にX
とY
の両方を認識するので、接続するクライアントのホスト上のidentサーバに応答指令信号を送ることができ、理論的には与えられたどの接続にもオペレーティングシステムユーザを決定できます。
この手続きの欠点は、クライアントの正直さに頼るところが大きいということです。 もしクライアントマシンが信用されない、もしくは危険に晒されている場合、攻撃者はポート113上でほぼどんなプログラムでも実行することができ、どのユーザ名でも好きに選んで返すことができます。 したがってこの認証方式は、各々のクライアントマシンが厳格な管理下にあり、データベースとシステム管理者が密接に連絡を取り合って動作している、外界から閉ざされたネットワークにのみ適していると言えます。 言い換えると、identサーバが稼働しているマシンを信用しなければなりません。 次の警告に注意してください。
身元特定プロトコルは、認証、あるいはアクセス管理プロトコルには意図されていません。 | ||
--RFC 1413 |
いくつかの身元特定サーバは、ユーザ名を(マシンの管理者のみが知っているキーで)暗号化して返すような非標準のオプションを持っています。 このオプションは、身元特定サーバとPostgreSQLとを一緒に使用する場合には、使用してはいけません。 理由はPostgreSQLは、返された文字列を復号化して本当のユーザを決定するための手段を持っていないためです。
peer認証方式はカーネルからクライアント上のオペレーティングシステムのユーザ名を取得し、 それをデータベースユーザ名(オプションのユーザ名マップとともに)として使用することにより動作します。この方法はローカル接続でのみ使用可能です。
次の設定オプションはpeerのためにサポートされています。
map
システムとデータベースのユーザ名のマッピングを許可します。詳細は19.2. ユーザ名マップを参照してください。
Peer認証はオペレーティングシステムが、getpeereid()
関数、SO_PEERCRED
のソケットパラメータ、もしくは同じような仕組みを提供しているときにのみ使用可能です。現状では、Linux、OS Xを含むBSD系、そしてSolarisに含まれています。
この認証方式はpassword
と似ていますが、パスワード確認にLDAPを使用する点が異なります。
LDAPはユーザの名前とパスワードの組み合わせの検証のみに使用されます。
そのため、LDAPを使用して認証を行うようにする前に、ユーザはデータベースに存在しなければなりません。
LDAP認証は2つのモードで動作します。1つ目のモードでは、それは単なるバインド・モードを呼び出すものですが、
サーバはprefix
username
suffix
として区別された名前にバインドします。
一般的に、prefix
パラメータはActive Directory環境でのcn=
やDOMAIN
\
を特定するために使用されます。
suffix
は、Active Directory環境ではない場合でのDNの残りの部分を特定するために使用されます。
2つ目のモードでは、それはsearch/bindモードを呼び出すもので、サーバは最初にldapbinddn
とldapbindpasswd
で指定された、
固定されたユーザ名とパスワードを使用してLDAPディレクトリにバインドします。
それからデータベースにログインしようとしているユーザを検索します。
もしユーザとパスワードが指定されていなかった場合は、ディレクトリに対して匿名でバインドします。
検索はldapbasedn
のサブツリーまで行われ、ldapsearchattribute
で指定された属性に正確に一致するかどうかまで行われます。
この検索において、一度ユーザが見つかるとサーバは切断して、クライアントで指定されたパスワードを使用してこのユーザとして再度ディレクトリにバインドします。これはそのログインが正しいかどうかを検証するためです。
このモードはApache mod_authnz_ldap
およびpam_ldap
のように他のソフトウェアと同じように、LDAP認証の仕組みで使用されるものと同じです。
この方法は、ユーザオブジェクトがディレクトリに配置されている場合に、かなりの柔軟性があります。
しかし、LDAPサーバへの2つの分離した接続が作成されます。
次の設定オプションは両方のモードで使用されます。
ldapserver
接続するLDAPサーバの名称もしくはIPアドレスの名称。空白で区切ることで複数のサーバを指定できます。
ldapport
LDAPサーバに接続するためのポート番号。もしポートが指定されていない場合は LDAPライブラリ内のデフォルトポート設定が使用されます。
ldaptls
1に設定すると、PostgreSQLとLDAPサーバ間の接続にTLSによる暗号化を使用します。 これはLDAPサーバへのトラフィックのみを暗号化することに注意してください。— クライアントへの接続はSSLを使用しない限り暗号化されません。
以下のオプションは単純バインド・モードのみで使用されます。
ldapprefix
単純なバインド認証を行う場合のDNを生成する際にユーザ名の前に追加する文字列
ldapsuffix
単純なバインド認証を行う場合のDNを生成する際にユーザ名の後に追加する文字列
以下のオプションはsearch/bindモードのみで使用されます。
ldapbasedn
検索とバインドの認証を行う場合のユーザ名がログインするための検索を始めるためのルートDN
ldapbinddn
検索とバインドの認証を行う場合のディレクトリと検索をバインドするためのユーザのDN
ldapbindpasswd
検索とバインドの認証を行う場合のディレクトリと検索をバインドするためのユーザのパスワード
ldapsearchattribute
検索とバインドの認証を行う場合の検索時のユーザ名に対して一致させる属性。
属性が指定されない場合、属性uid
が使用されます。
ldapurl
RFC 4516 LDAP URL。これはその他いくつかのLDAPオプションをより簡潔、かつ一般的な形式で記述する別の方法です。 フォーマットは以下のようになっています。
ldap://host
[:port
]/basedn
[?[attribute
][?[scope
]]]
scope
はbase
、one
,、sub
のいずれかでなくてはならず、一般的には最後のものです。
非匿名バインド(non-anonymous bind)に対し、ldapbinddn
およびldapbindpasswd
は個別のオプションとして指定されなければなりません。
暗号化されたLDAP接続を使用するには、ldapurl
に加えldaptls
オプションを使用しなければなりません。ldaps
URLの仕組み(直接SSL接続)はサポートされていません。
現在の所、LDAP URLはWindows上ではなく、OpenLDAPのみでサポートされています。
seartch/bindオプションと単純バインドに対するオプションの設定を混在させるのはエラーです。
以下に単純バインドLDAP設定の例を示します。
host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
データベースのユーザ、someuser
からデータベースサーバに接続を要求された場合、PostgreSQLはDN cn=someuser, dc=example, dc=net
およびクライアントから提供されたパスワードを用いてLDAPサーバにバインドを試みます。
その接続が成功すればデータベースへのアクセスが認められます。
以下はsearch/bind設定の例です。
host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid
データベースユーザsomeuser
としてデータベースに接続するとき、PostgreSQLは(ldapbinddn
が指定されていないので)匿名的にバインドを試み、指定されたベースDNの基で(uid=someuser)
の検索を行います。あるエントリが見つかると、見つかった情報とクライアントから与えられたパスワードを用いて、その結果バインドを試みます。その二番目の接続が成功するとデータベースアクセスが認められます。
URLとして記述した同じsearch/bind設定の例です。
host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
LDAPに対し認証をサポートする幾つかの他のソフトウェアは同じURLフォーマットを使用します。 従って、設定をより簡易に共有することができます。
LDAPはDNの異なる構成要素を区別するため往々にしてコンマとスペースを使用します。 例で示されたように、LDAPオプションを設定する場合、二重引用符で括られたパラメータ値を使用することが必須となることがしばしば必須となります。
この認証方法は、RADIUSをパスワード検証として使用するという点を除いてpassword
と似た動作をします。
RADIUSはユーザ名/パスワードの組のみを検証するために使用されます。
よってユーザはRADIUSが認証に使用される以前にデータベースにすでに存在していなければいけません。
RADIUS認証を使用する場合に、設定されたRADIUSサーバにアクセスリクエストメッセージが送信されます。
このリクエストはAuthenticate Only
の形式になり、ユーザ名
, (暗号化された)パスワード
、NAS識別子
を含んでいます。
リクエストはサーバと共有している秘密を用いて暗号化されます。
RADIUSサーバは、このサーバに対してAccess Accept
もしくはAccess Reject
を返します。
RADIUSアカウントのサポートはありません。
RADIUSのために次の設定オプションがサポートされています。
radiusserver
接続するRADIUSサーバの名称もしくはIPアドレス。このパラメータは必要です。
radiussecret
RADIUSサーバとのやり取りに使用される共有の秘密。これはPostgreSQLとRADIUSサーバにおいて 厳密に同じ値にする必要があります。少なくとも16文字以上の文字列が推奨されます。このパラメータは必要です。
使用されている暗号化ベクターはPostgreSQLがOpenSSLをサポートするよう構築している場合にのみ暗号論的に強力です。 他の場合にはRADIUSサーバへの伝送は難読化されているだけで、安全ではなく必要な場合は外部のセキュリティ方法を適用すべきです。
radiusport
接続するRADIUSサーバのポート番号。もしポート番号が指定されていない場合は、デフォルトポートである1812
が使用されます。
radiusidentifier
RADIUSリクエスト内でNAS Identifier
として使用されている文字列。
ユーザがどのデータベースユーザに対して認証しようとしているか、RADIUSサーバにおいてポリシーを一致させるために何が使用されるか、
を識別するために、このパラメータは2番目のパラメータとして使用されます。
もし識別子が指定されていない場合は、デフォルトのpostgresql
が使用されます。
この認証方法は、認証のためにSSLクライアント証明書を使用します。
よってこの方法は、SSL接続を使用します。
この認証方法を使用する際は、サーバはクライアントが有効な証明書を提供することを要求します。
パスワードのプロンプトはクライアントに送信されません。
証明書のcn
(Common Name)属性は、要求されたデータベースユーザ名と比較されます。
もしそれらが一致した場合はログインが許可されます。ユーザ名マッピングは、cn
がデータベースユーザ名と異なるものであることを許可するために使用されます。
次の設定オプションはSSL証明書認証のためにサポートされています。
map
システムとデータベースユーザ名の間のマッピングを許可します。 詳細は19.2. ユーザ名マップを参照してください。
この認証方式は認証機構としてPAM(Pluggable Authentication Modules)を使用することを除いてpasswordのように動作します。
デフォルトのPAMサービス名はpostgresql
です。
PAMはユーザ名/パスワードの組を承認するためだけに使用されます。
PAMについての詳細はLinux-PAMページを読んでください。
次の設定オプションはPAMのためにサポートされています。
pamservice
PAMサービス名。
PAMが/etc/shadow
を読み取るように設定されている場合は、PostgreSQLがルートユーザで起動されていないため、認証は失敗するでしょう。
しかしPAMがLDAPや他の認証方法を使用するように設定されている場合は、これは問題ではありません。