シェアする

概要

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 OPTIONS
local all postgres peer
local all all peer
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
local replication all peer
host replication all 127.0.0.1/32 md5
host 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以降のhosthostsslhostnossl、およびhostgssenchostnogssenc)の場合、次にアドレスフィールドが来ます。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ホストでのみ利用可能です。

上記の一部のメソッドは、特定の種類の接続または追加のインフラストラクチャが整っている場合にのみ適用可能です。ほとんどのデプロイメントでは、rejectpeer、および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 OPTIONS
local all all peer

この方法で認証できるPostgreSQLユーザーをjohnsueのみに制限したい場合は、USER列の範囲を制限します。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
local all john,sue peer

sueという名前のオペレーティングシステムユーザーがsusanという名前のデータベースユーザーに認証できるようにする必要がある場合、行の最後にmapオプションを指定できます。このマッピングを識別するマップ名を選択します。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
local all john,sue peer map=my-map-name

次に、同じディレクトリにあるpg_ident.confファイルを開いて、ユーザーをマッピングできます。

vim pg_ident.conf

このファイルに、選択したマップ名、オペレーティングシステムユーザー名、およびPostgreSQLユーザー名をスペースで区切って指定する行を追加することで、必要なマップを作成します。

# MAPNAME SYSTEM-USERNAME PG-USERNAME
my-map-name sue susan

これで、sueオペレーティングシステムは、一致しているかのようにpeer認証でsusanPostgreSQLユーザーに認証できるようになります。

同じマシンからのネットワーク接続をパスワードで許可する

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 OPTIONS
host all all 127.0.0.1/32 md5
host all all ::1/128 md5

この方法で認証を許可するデータベースやユーザーを制限するには、該当する列をallから特定のエンティティのコンマ区切りリストに変更します。

自動メンテナンスを許可する

様々な自動メンテナンス作業が定期的に実行されます。これらの操作が期待通りに認証され実行されることを確実にするには、管理者アカウントが非対話的に認証できることを確認する必要があります。

デフォルトでは、postgresアカウントはこのロールのためにpeer認証を使用して設定されています。この行は、おそらくすでにあなたのpg_hba.confファイルに存在します。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
local all postgres peer

特に他の多くの認証方法を変更する場合は、この行または類似の行がファイルに存在することを確認してください。

レプリケーションに使用される接続を許可する

レプリケーションは、通常、頻繁にデータをあるデータベースから別のデータベースにコピーする特別なプロセスです。他の種類の接続とは異なり、レプリケーション接続は接続したい特定のデータベースを指定しません。

データベース列のreplicationキーワードは、これらのレプリケーション接続に一致させるために使用されます。レプリケーション権限を持つすべてのユーザーは、レプリケーション接続を確立できます。

すべてのローカルレプリケーション接続を許可するには、通常の接続の以前の値(Unixソケット経由の接続にはpeer、ローカルネットワーク経由の接続にはmd5)を反映させるように、以下の行を追加できます。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
local replication all peer
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5

追加の場所からのレプリケーションを許可するには、追加のアドレスを追加できます。たとえば、ローカルの192.0.2.0/24ネットワーク上のすべてのマシンからのレプリケーションを許可するには、次のような行を追加します。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
host replication all 192.0.2.0/24 md5

これにより、そのネットワーク内のマシンからのすべてのレプリケーション接続が、md5で暗号化されたパスワードを使用して認証できるようになります。

ローカルネットワークからのパスワードによる接続を許可する

上記では、ローカルレプリケーション接続にパスワード認証を設定する方法を説明しました。これは、任意のローカルネットワーク接続のパスワード認証を許可するように一般化できます。

ローカルの192.0.2.0/24ネットワークから来るすべての接続に対してmd5パスワード認証を許可するには、次のような行を追加します。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
host 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 OPTIONS
hostssl 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 OPTIONS
hostssl all all all cert

この設定では、サーバーはユーザーにパスワードを要求せず、代わりに有効なSSL証明書を要求します。証明書のコモンネーム(CN)フィールドは、要求されているデータベースユーザーと一致する必要があり、そうでない場合はmapファイルで設定する必要があります。

たとえば、CNがkatherineである証明書がkateという名前のPostgreSQLユーザーに認証するには、pg_hba.confファイルにマップファイルを指定する必要があります。

# TYPE DATABASE USER ADDRESS METHOD OPTIONS
hostssl all all all cert map=my-map-name

その後、pg_ident.confファイルを編集して、これら2つのユーザーを明示的にマッピングします。

vim pg_ident.conf
# MAPNAME SYSTEM-USERNAME PG-USERNAME
my-map-name katherine kate

クライアント証明書の作成と設定方法については、PostgreSQLのTLS/SSLクライアント証明書に関するドキュメントで学ぶことができます。

まとめ

このガイドでは、サーバーサイドのPostgreSQL認証について説明しました。クライアントの認証方法を変更するためにPostgreSQLインスタンスの設定を修正する方法を実演しました。認証ファイルで利用可能なさまざまなオプションを議論した後、これまでに学んだことを使用して一般的な認証戦略をいくつか実装する方法について説明しました。

認証を設定する方法を知ることと、PostgreSQLクライアントと接続する方法の理解を組み合わせることで、正当なクライアントにアクセスを許可しつつ、不要な接続から保護することができます。この設定は、データベースインスタンスを保護し、運用を妨げる可能性のある中断的なログイン問題を防止する上で重要な部分です。

著者について
Justin Ellingwood

ジャスティン・エリングウッド

ジャスティンは2013年からデータベース、Linux、インフラストラクチャ、開発者ツールについて執筆しています。現在は妻と2匹のウサギと共にベルリンに住んでいます。彼は通常、三人称で書く必要がないため、関係者全員にとって安心です。
© . All rights reserved.