PostgreSQL / 認証と認可
PostgreSQL ユーザー認証の設定
はじめに
PostgreSQL データベースの操作を始めるにあたって最初に考えることの 1 つは、データベースインスタンスに接続して対話する方法です。これには、データベースクライアント(データベースとの対話に使用するコンポーネント)とデータベースサーバー(データを保存、整理、およびアクセスを提供する実際の PostgreSQL インスタンス)間の連携が必要です。
これを正常に管理するには、必要なタイプのアクセスおよび認証メソッドを許可するように PostgreSQL インスタンスを設定する方法を知る必要があります。このガイドでは、環境の要件に合わせてデータベースサーバーの認証メカニズムを変更する方法について説明します。
コンパニオンガイドでは、データベースクライアントを使用して PostgreSQL インスタンスに接続する方法について説明しています。PostgreSQL での認証の仕組みをより完全に理解するために、両方のガイドを読むことを検討してください。
PostgreSQL の認証ファイルについて
ユーザーが PostgreSQL インスタンスに対して認証する方法を決定するルールを変更したい場合は、サーバーの設定を変更することで実行できます。
変更する必要がある特定のファイルは、pg_hba.conf
と呼ばれます。
新しい認証設定を有効にするには、PostgreSQL インスタンスを再起動する必要があることに注意してください。オペレーティングシステムが異なると、これの処理方法も異なります。ほとんどの Linux ディストリビューションでは、
sudo systemctl restart postgresql
と入力できます。brew
を介して PostgreSQL をインストールした場合は、brew services restart postgresql
と入力してみてください。より広範なシステムで機能する可能性のある代替手段は、pg_ctl restart
です。
pg_hba.conf
ファイルを見つける
サーバー上の pg_hba.conf
ファイルを見つけるには、PostgreSQL 設定ディレクトリを探します。具体的な場所は、使用しているオペレーティングシステムと PostgreSQL のバージョンによって異なります。
認証設定ファイルの場所が不明で、データベースへのアクセス権がある場合は、Craig Ringer がこの投稿で実証しているように、PostgreSQL にファイルの場所をクエリできます。
コマンドラインを使用している場合は、以下を入力できます。これは、pg_hba.conf
ファイルの場所をクエリし、PostgreSQL に書式設定なしでファイルの場所のみを出力するように指示します。
psql -t -P format=unaligned -c 'SHOW hba_file;'
/etc/postgresql/10/main/pg_hba.conf
PostgreSQL セッションがすでに開いている場合は、単に次のように入力できます。
SHOW hba_file;
hba_file-------------------------------------/etc/postgresql/10/main/pg_hba.conf(1 row)
pg_hba.conf
ファイルの場所がわかったら、テキストエディタで開いて設定を表示し、変更を加えます。
vim /etc/postgresql/10/main/pg_hba.conf
デフォルトでは、ファイルには現在の設定と、多くの役立つコメントが含まれています。
pg_hba.conf
ファイル形式について
pg_hba.conf
ファイルは、プレーンテキストで実装されたテーブルのような構造を使用します。空白行とコメントを削除すると、基本的なファイルは次のようになります。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal all postgres peerlocal all all peerhost all all 127.0.0.1/32 md5host all all ::1/128 md5local replication all peerhost replication all 127.0.0.1/32 md5host replication all ::1/128 md5
さまざまなフィールドの意味と、ファイルの内容がどのように解釈されるかを見てみましょう。
pg_hba.conf
ファイルの構造と解釈方法
pg_hba.conf
ファイルの各行は、クライアントがシステムに対して認証を行う方法を記述しています。各行の大部分は、受信接続要求との比較に使用される一致条件を記述しています。最後のコンポーネントは、許可される認証方法と、認証に必要なオプションを指定します。
PostgreSQL は、認証ルールに対して接続要求を評価するとき、上から下へ順番に実行します。行の設定が接続要求の特性と一致する場合、PostgreSQL は行に指定された認証情報を使用して、クライアントを認証するかどうかを決定します。
クライアントが正常に認証されると、接続が確立されます。認証に失敗した場合、接続は拒否されます。PostgreSQL は、他のルールが要求に一致するかどうかを確認するために処理を続行しません。このため、ルールの順序は重要です。
各行内で、フィールドは空白文字(スペースまたはタブ)で区切られています。通常、これらのフィールドを列に整形すると視覚的にわかりやすくなりますが、PostgreSQL では必須ではありません。
pg_hba.conf
ファイルの各フィールドの意味
ファイルの構造と解釈方法について少し理解できたので、各フィールドの意味について説明を始めましょう。
説明するフィールドは次のとおりです。
- 接続タイプ
- データベース
- ユーザー名
- アドレス
- 認証方法
- 認証方法のオプション
接続タイプ
各レコードの最初のフィールドは、一致させる接続要求のタイプを指定します。指定された接続を使用する接続のみが各ルールに一致します。
接続タイプは、次のいずれかである必要があります。
local
:local
を持つレコードは、ネットワーク経由ではなく、ローカル Unix ドメインソケットファイル経由で行われた接続に一致します。ローカル接続は、セキュリティとパフォーマンス上の理由から、可能な場合は優先されます。host
:host
で始まる行は、ネットワーク経由で行われたすべての接続要求に一致します。これは、ネットワーク接続の一般的な包括的なものです。より詳細な一致は、次のタイプで使用できます。hostssl
:hostssl
接続タイプは、TLS/SSL 暗号化を使用してネットワーク経由で行われたすべての接続に一致します。これは通常、外部接続を許可する場合に使用するのに最適な接続タイプです。hostnossl
:hostnossl
タイプは、TLS/SSL で保護されていないすべてのネットワーク接続に一致します。
PostgreSQL 12 以降では、GSSAPI 接続のサポートも追加され、次の追加オプションが導入されました。
hostgssenc
:hostgssenc
接続タイプは、GSSAPI 暗号化を使用するすべてのネットワーク接続に一致します。このオプションは、セキュリティのためにすでに GSSAPI を使用しているユーザーにのみ意味があります。hostnogssenc
:hostnogssen
タイプは、GSSAPI 暗号化を使用しないすべてのネットワーク接続に一致します。
データベース
次のフィールドは、要求がアクセスしようとしているデータベースを指定します。接続要求で指定されたデータベースは、行を一致させるために、この列にある値を満たす必要があります。
値には、次のいずれかを指定できます。
all
:all
のデータベース値は、要求されたすべてのデータベースに一致する包括的な値です。これは、現在のマッチングルールでデータベース値を評価したくない場合に役立ちます。sameuser
:sameuser
値は、要求されたデータベースとユーザー名が同じ接続に一致します。samerole
:samerole
データベース値は、指定されたユーザーが、要求されたデータベースと同じ名前のロールのメンバーである場合に接続に一致します。replication
:replication
の値を使用すると、データベースレプリケーションに使用されるすべての受信接続に一致します。レプリケーションに使用される接続はデータベースターゲットを提供しないため、代わりにレプリケーション要求に一致します。- [特定のデータベース名]: 一致させる 1 つまたは複数の特定のデータベース名を指定することもできます。これらは、リストされたデータベースのいずれかを要求する場合にのみ接続に一致します。複数のデータベース名をコンマで区切るか、ファイル名の先頭に
@
記号を付けることで、名前を読み取るファイルを指定できます。
ユーザー
次のフィールドは、接続要求によって提供されたユーザーと照合するために使用されます。接続のユーザー値は、ルールを一致させるために、ルールのユーザーフィールドを満たす必要があります。
ユーザーフィールドには、次のオプションを指定できます。
all
:all
の値は、接続のユーザーパラメーターの任意の値がこのルールのユーザー要件を満たすことを PostgreSQL に指示します。- [特定のユーザーまたはグループ名]: ユーザーフィールドの唯一の他のオプションは、特定のユーザー、ユーザーのリスト、またはグループを提供することです。複数のユーザーは、値をコンマで区切って指定できます。名前が
+
記号で始まる場合、ユーザー名ではなくグループ名として解釈されます。この場合、ルールは、要求されたユーザーがルールで指定されたグループのメンバーである場合に一致します。繰り返しますが、@
記号を前に付けたファイル名を指定することで、値をインラインで指定する代わりに、ファイルから値を読み取るように PostgreSQL に指示できます。
アドレス
host
(host
、hostssl
、hostnossl
、および PostgreSQL 12 以降の hostgssenc
と hostnogssenc
) で始まるすべての接続タイプの場合、アドレスフィールドが次に続きます。local
接続の場合、このフィールドはスキップされます。
アドレスフィールドは、接続のアドレスと照合するクライアントマシンアドレスまたはパターンを指定します。これは、接続がどこから発信されているかに応じて評価されることを意味します。接続の発信元は、ルールを一致させるために、ルールのアドレス値を満たす必要があります。
アドレスフィールドには、次のいずれかを指定できます。
all
:all
のアドレス値は、すべてのクライアントアドレスがこの条件を満たすことを PostgreSQL に指示します。samehost
: 値samehost
は、サーバー自身の IP アドレスの 1 つから発信されたすべてのネットワーク接続が一致することを示すために使用されます。samenet
:samenet
値は、サーバーのネットワークサブネットからのすべての IP アドレスが一致することを示します。- [CIDR IP アドレス範囲]: CIDR 表記を使用して IP アドレス範囲を指定することもできます。これにより、単一の IP アドレス (
/32
サブネットを IPv4 アドレスに使用するか、/128
サブネットを IPv6 アドレスに使用) またはより広範な CIDR マスクを提供することによりアドレス範囲を指定できます。IP アドレス範囲は、指定された IP プロトコルを使用して、指定された範囲内から行われたクライアント接続にのみ一致します。 - [ホスト名]: ホスト名を直接指定することもできます。この場合、クライアントのホスト名は、期待どおりに解決されることを確認するために、正引きおよび逆引き DNS クエリを使用して評価されます。指定されたホスト名がドットで始まる場合、そのドメインで正しく解決されるすべてのホストが要件を満たします。
認証方法
接続が以前のすべての一致基準を満たしている場合、指定された認証方法が適用されます。これは、各行の次のフィールドです。
認証方法とは、PostgreSQL がルールに一致する接続を受け入れるかどうかを決定する方法です。次のいずれかの選択肢に設定できます。
trust
:trust
の値は、追加の要件なしで接続をすぐに受け入れます。これは、他の外部認証方法が整っていることを前提としています。ほとんどの場合、推奨されません。reject
:reject
の値は、接続をすぐに拒否します。これは主に、不要なパターンに一致する接続を除外するために使用されます。scram-sha-256
:scram-sha-256
メソッドは、SCRAM-SHA-256
認証を使用してユーザーが提供したパスワードをチェックします。すべてのクライアントがサポートしている場合、これは現在パスワード認証で最も安全なオプションです。md5
:md5
メソッドもユーザーパスワードをチェックします。この方法はscram-sha-256
よりも安全ではありませんが、より広くサポートされています。現在の実装では、パスワードが SCRAM で暗号化されている場合、md5
が指定されていても、自動的にscram-sha-256
が使用されます。password
:password
メソッドは、最も安全でないパスワード認証方法です。パスワードをプレーンテキストで送信するため、接続が TLS/SSL を使用して接続全体を暗号化している場合を除き、使用しないでください。gss
:gss
メソッドは、認証に GSSAPI を使用します。これは、接続に GSSAPI 暗号化が使用されているかどうかに関係なく、認証に使用できます。これにより、Kerberos や同様のソフトウェアを介した認証が可能になります。sspi
:sspi
メソッドは、Windows 専用の Security Support Provider Interface API を使用してクライアントを認証します。ident
:ident
メソッドは、接続を開始したユーザーのクライアントの ident サーバーでチェックします。これはクライアントマシンに依存するため、クライアントマシンが厳密に管理されている信頼できるネットワークでのみ使用する必要があります。peer
:peer
認証方法は、ローカル接続に使用されます。ローカルオペレーティングシステムにクライアントのシステムユーザー名を要求します。名前が要求されたデータベース名と一致するかどうかをチェックします。ldap
:ldap
メソッドは、LDAP サーバーを使用してユーザー名とパスワードを検証することにより認証します。radius
: ユーザー名とパスワードの組み合わせをチェックするためにRADIUS サーバーを使用するには、radius
を選択します。cert
:cert
メソッドは、TLS/SSL クライアント証明書を使用してクライアントを認証します。これは TLS/SSL 接続でのみ使用できます。クライアント証明書は、有効で信頼された証明書である必要があります。pam
:pam
オプションは、認証をオペレーティングシステムのPAM サービスに委ねます。bsd
:bsd
メソッドは、BSD 認証サービスを使用してユーザー名とパスワードを検証します。このメソッドは、OpenBSD ホストでのみ使用できます。
上記のメソッドの一部は、特定のタイプの接続、または追加のインフラストラクチャが整っている場合にのみ適用できます。ほとんどのデプロイメントでは、reject
、peer
、および scram-sha-256
または md5
で開始するのに十分であり、インフラストラクチャに応じて ldap
などの追加のメソッドも使用できます。
認証オプション
認証方法の後に、認証方法の追加オプションを提供するための最後のオプションの列が存在する場合があります。この列の使用は、選択した認証方法のタイプに大きく依存します。
外部サーバーを参照する認証方法の場合、これらのオプションは、PostgreSQL が認証サービスを正常にクエリできるように、ホストと接続情報を指定することがよくあります。非常に多くの認証方法に共通するもう 1 つのオプションは、システムユーザー名と PostgreSQL データベースユーザー名の間を変換できる map
パラメーターです。
各認証方法には、独自の有効なオプションセットがあります。PostgreSQL ドキュメントの各メソッドのページで、適用可能なオプションを必ず確認してください。
一般的な認証ポリシーの設定
いくつかの主要な認証オプションを紹介しましたが、これらを使用して適切なポリシーを実装するにはどうすればよいでしょうか。このセクションでは、最も一般的な認証ポリシーのいくつかを設定する方法について説明します。
ローカルユーザーが一致するデータベースに接続できるようにする
同じマシンマシン上のユーザーが同じ PostgreSQL ユーザー名に対して認証できるように PostgreSQL を設定するのが一般的です。たとえば、peer
認証を使用すると、オペレーティングシステムユーザー john
は、PostgreSQL にも john
というユーザー名がある場合、パスワードなしで自動的にログインできます。
これは、PostgreSQL ソケットファイルを使用して行われたローカル接続に対して機能します。127.0.0.1
ローカルループバックデバイスであっても、ネットワークアドレスを指定すると、接続はソケットを使用せず、peer
認証行と一致しません。ただし、localhost
への接続はソケットファイルを使用し、これらの行と一致します。
すべての PostgreSQL ユーザーが一致するオペレーティングシステムユーザーから認証できるようにするには、local
接続タイプに一致し、すべてのデータベースとユーザー名を許可し、peer
認証を使用する行を追加します。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal all all peer
これを john
および sue
PostgreSQL ユーザーのみがこの方法で認証できるように制限する場合は、USER
列の範囲を制限します。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal all john,sue peer
オペレーティングシステムユーザー sue
がデータベースユーザー susan
に対して認証できるようにする必要がある場合は、行の最後に map
オプションを指定できます。このマッピングを識別するためのマップ名を選択します。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal all john,sue peer map=my-map-name
次に、同じディレクトリにある pg_ident.conf
ファイルを開いてユーザーをマッピングできます。
vim pg_ident.conf
選択したマップ名、オペレーティングシステムのユーザー名、および PostgreSQL のユーザー名をスペースで区切ってこのファイルに行を追加することにより、必要なマップを作成します。
# MAPNAME SYSTEM-USERNAME PG-USERNAMEmy-map-name sue susan
これで、sue
オペレーティングシステムは、一致する場合と同様に、peer
認証を使用して susan
PostgreSQL ユーザーに対して認証できるようになります。
パスワードを使用した同一マシンからのネットワーク接続を許可する
PostgreSQLサーバーのマシンからのネットワーク接続(非ソケット接続)をパスワードで認証するには、local
ではなく host
接続タイプに一致させる必要があります。その後、許容されるアドレスをローカルループバックデバイスに制限し、ユーザーが md5
または scram-sha-256
を使用して認証できるようにすることができます。
たとえば、PostgreSQLがホストされているマシン上のユーザーがホストとして 127.0.0.1
を指定して接続しようとすると、PostgreSQLはパスワード認証を実行できます。
これを設定するには、host
接続タイプを使用する必要があります。次に、許容されるアドレスの範囲を指定する必要があります。このルールはローカル接続のみに一致する必要があるため、ローカルループバックデバイスを指定します。IPv4およびIPv6ループバックデバイスに一致させるために、2つの別々の行を追加する必要があります。
その後、認証に使用するパスワード方式を指定できます。scram-sha-256
方式の方が安全ですが、md5
方式の方が広くサポートされています。
完成した認証行は次のようになります。
# TYPE DATABASE USER ADDRESS METHOD OPTIONShost all all 127.0.0.1/32 md5host all all ::1/128 md5
この方法を使用して認証を許可するデータベースまたはユーザーを制限するには、適切な列を all
から特定のエンティティのカンマ区切りリストに変更します。
自動メンテナンスを許可する
自動メンテナンス作業の詰め合わせが定期的に実行されます。これらの操作が期待どおりに認証および実行されるようにするには、管理者アカウントが非対話的に認証できることを確認する必要があります。
デフォルトでは、postgres
アカウントはこのロールに対して peer
認証を使用して構成されています。この行は、pg_hba.conf
ファイルにすでに存在している可能性が非常に高いです。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal all postgres peer
特に他の多くの認証方法を変更する場合は、この行または同様の行がファイルに存在することを確認してください。
レプリケーションに使用される接続を許可する
レプリケーションは、あるデータベースから別のデータベースにデータをコピーする特別なプロセスであり、通常は頻繁に実行されます。他のタイプの接続とは異なり、レプリケーション接続は接続先の特定のデータベースを指定しません。
データベース列の replication
キーワードは、これらのレプリケーション接続に一致するために使用されます。レプリケーション権限を持つユーザーは誰でもレプリケーション接続を確立できます。
すべてのローカルレプリケーション接続を許可するために、通常の接続の以前の値 (peer
はUnixソケット経由の接続、md5
はローカルネットワーク経由の接続) を反映する方法で、次の行を追加できます。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal replication all peerhost replication all 127.0.0.1/32 md5host replication all ::1/128 md5
追加の場所からのレプリケーションを許可するには、アドレスを追加できます。たとえば、ローカルの 192.0.2.0/24
ネットワーク上の任意のマシンからのレプリケーションを許可するには、次のような行を追加できます。
# TYPE DATABASE USER ADDRESS METHOD OPTIONShost replication all 192.0.2.0/24 md5
これにより、そのネットワーク内のマシンからのレプリケーション接続は、md5
で暗号化されたパスワードを使用して認証できるようになります。
パスワードを使用したローカルネットワークからの接続を許可する
上記では、ローカルレプリケーション接続のパスワード認証を構成する方法を示しました。これは、任意のローカルネットワーク接続のパスワード認証を許可するように一般化できます。
ローカルの 192.0.2.0/24
ネットワークからの接続に対して md5
パスワード認証を許可するには、次のような行を追加できます。
# TYPE DATABASE USER ADDRESS METHOD OPTIONShost all all 192.0.2.0/24 md5
これにより、192.0.2.0/24
ネットワーク内のすべてのホストが、ネットワーク経由で md5
で暗号化されたパスワードを使用してPostgreSQLを認証できるようになります。
SSLとパスワードを使用したリモート接続を許可する
信頼できるネットワークの外部からの接続を許可するには、常にTLS/SSLなどの安全な暗号化を介して接続をトンネリングする必要があります。これらの接続を許可する必要がある場合は、hostssl
接続タイプに対して一致させる必要があります。
たとえば、データベースサーバーに接続できる任意の場所からのパスワード認証を許可するが、TLS/SSLが使用されている場合にのみ許可するには、認証ファイルに次のような行を追加できます。
# TYPE DATABASE USER ADDRESS METHOD OPTIONShostssl all all all md5
これにより、TLS/SSLを使用する外部接続は、md5
で暗号化されたパスワードを使用して認証できるようになります。より制限の厳しいアドレスを指定することで、アクセスを簡単に制限できます。
hostssl
接続タイプを使用する場合は、PostgreSQLインスタンスのSSLを構成する必要があります。SSL証明書、SSLキー、およびSSLルート証明書を生成または取得し、SSL構成に関するPostgreSQLドキュメントで指定されているように、postgresql.conf
構成ファイルを変更する必要があります。
SSLとSSLクライアント証明書を使用したリモート接続を許可する
外部接続にSSLを強制的に適用している場合は、パスワードの代わりに認証にSSLクライアント証明書を使用することを検討できます。これにより、クライアントはクライアントSSL証明書を提示できます。サーバーは、それが有効であり、信頼できる認証局によって署名されていることを確認します。その場合、提供されたルールに従って認証が許可されます。
SSLクライアント認証を設定するには、以前に使用した行と同様の行を使用できます。
# TYPE DATABASE USER ADDRESS METHOD OPTIONShostssl all all all cert
この構成では、サーバーはユーザーにパスワードを要求しませんが、代わりに有効なSSL証明書を要求します。証明書の共通名 (CN) フィールドは、要求されているデータベースユーザーと一致するか、map
ファイルで構成されている必要があります。
たとえば、CNが katherine
の証明書が kate
という名前のPostgreSQLユーザーに対して認証するには、pg_hba.conf
ファイルにマップファイルを指定する必要があります。
# TYPE DATABASE USER ADDRESS METHOD OPTIONShostssl all all all cert map=my-map-name
その後、pg_ident.conf
ファイルを編集して、それらの2人のユーザーを明示的にマッピングします。
vim pg_ident.conf
# MAPNAME SYSTEM-USERNAME PG-USERNAMEmy-map-name katherine kate
クライアント証明書を作成および構成する方法については、TLS/SSLクライアント証明書に関するPostgreSQLのドキュメントを参照してください。
結論
このガイドでは、サーバー側のPostgreSQL認証について説明しました。クライアントの認証方法を変更するためにPostgreSQLインスタンスの構成を変更する方法を示しました。認証ファイルで使用可能なさまざまなオプションについて説明した後、以前に学んだことを使用して、いくつかの一般的な認証戦略を実装する方法について説明しました。
認証を構成する方法を知っていることは、PostgreSQLクライアントとの接続方法の理解と組み合わせることで、正当なクライアントへのアクセスを許可しながら、不要な接続から保護することができます。この構成は、データベースインスタンスを保護し、業務を妨げる可能性のある破壊的なログイン問題を防止するための重要な部分です。