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
で始まるすべての接続タイプ(PostgreSQL 12以降のhost
、hostssl
、hostnossl
、およびhostgssenc
とhostnogssenc
)の場合、次にアドレスフィールドが来ます。local
接続の場合、このフィールドはスキップされます。
アドレスフィールドは、接続のアドレスと照合するクライアントマシンのアドレスまたはパターンを指定します。これは、接続がどこから発信されているかに応じて評価されることを意味します。ルールが一致するには、接続の発信元がルールの示すアドレス値を満たす必要があります。
アドレスフィールドには以下のいずれかを設定できます。
all
: アドレス値all
は、任意のクライアントアドレスがこの条件を満たすことをPostgreSQLに伝えます。samehost
:samehost
の値は、サーバー自身のIPアドレスのいずれかから発信されたネットワーク接続に一致することを示します。samenet
:samenet
値は、サーバーのネットワークサブネット内の任意のIPアドレスに一致することを示します。- [CIDR IPアドレス範囲]: CIDR表記を使用してIPアドレス範囲を指定することもできます。これにより、単一のIPアドレス(IPv4アドレスの場合は
/32
サブネット、IPv6アドレスの場合は/128
サブネットを使用)または、より広範な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
認証を使用すると、PostgreSQLにもjohn
というユーザー名がある場合、john
という名前のオペレーティングシステムユーザーはパスワードなしで自動的にログインできます。
これは、PostgreSQLソケットファイルを使用して行われたすべてのローカル接続に機能します。127.0.0.1
のローカルループバックデバイスであっても、ネットワークアドレスを指定した場合、接続はソケットを使用せず、peer
認証行には一致しません。ただし、localhost
への接続はソケットファイルを使用し、これらの行に一致します。
すべてのPostgreSQLユーザーが一致するオペレーティングシステムユーザーから認証できるようにするには、local
接続タイプに一致し、すべてのデータベースとユーザー名を許可し、peer
認証を使用する行を追加します。
# TYPE DATABASE USER ADDRESS METHOD OPTIONSlocal all all peer
この方法で認証できるPostgreSQLユーザーをjohn
とsue
のみに制限したい場合は、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
キーワードは、これらのレプリケーション接続に一致させるために使用されます。レプリケーション権限を持つすべてのユーザーは、レプリケーション接続を確立できます。
すべてのローカルレプリケーション接続を許可するには、通常の接続の以前の値(Unixソケット経由の接続にはpeer
、ローカルネットワーク経由の接続には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ルート証明書を生成または取得し、その後、PostgreSQLのSSL設定に関するドキュメントに指定されているように、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
クライアント証明書の作成と設定方法については、PostgreSQLのTLS/SSLクライアント証明書に関するドキュメントで学ぶことができます。
まとめ
このガイドでは、サーバーサイドのPostgreSQL認証について説明しました。クライアントの認証方法を変更するためにPostgreSQLインスタンスの設定を修正する方法を実演しました。認証ファイルで利用可能なさまざまなオプションを議論した後、これまでに学んだことを使用して一般的な認証戦略をいくつか実装する方法について説明しました。
認証を設定する方法を知ることと、PostgreSQLクライアントと接続する方法の理解を組み合わせることで、正当なクライアントにアクセスを許可しつつ、不要な接続から保護することができます。この設定は、データベースインスタンスを保護し、運用を妨げる可能性のある中断的なログイン問題を防止する上で重要な部分です。