pg_hba.conf ファイル:設定からセキュリティまで
PostgreSQLデータベースサーバーへのアクセスを制御する上で、pg_hba.confファイルは最も重要かつ強力な設定ファイルです。このファイルは、どのホストから、どのユーザーが、どのデータベースに、どのような認証方法で接続できるかを定義します。適切に設定されたpg_hba.confは、データベースのセキュリティを確保するための基盤となります。
この記事では、pg_hba.confファイルの構造、各設定項目の詳細な解説、様々な認証方法、セキュリティ上のベストプラクティス、具体的な設定例、そしてよくあるトラブルシューティングについて、包括的かつ詳細に説明します。約5000語というボリュームで、この重要な設定ファイルに関するあらゆる側面を深く掘り下げていきます。
1. はじめに:pg_hba.confとは何か?その重要性
PostgreSQLは、エンタープライズレベルの信頼性と機能性を備えた強力なオープンソースデータベースシステムです。そのセキュリティ機構の中核をなすのが、ホストベース認証設定ファイルであるpg_hba.confです。
pg_hba.confは “host-based authentication”(ホストベース認証)の略で、文字通り、接続元のホスト(IPアドレスまたはホスト名)に基づいて、接続要求を許可または拒否し、許可された場合にどの認証方法を使用するかを決定します。
このファイルは、接続要求が来た際に上から順に評価され、最初にマッチしたルールが適用されます。したがって、ルールの順序は非常に重要です。
なぜpg_hba.confがこれほど重要なのでしょうか?
- セキュリティの第一線: 悪意のあるユーザーや不正なシステムからの不正アクセスを防ぐ最初の関門となります。インターネットからの不要なアクセスを制限し、信頼できるクライアントのみに接続を許可することで、攻撃対象を大幅に減らすことができます。
- 柔軟なアクセス制御: 接続元、データベース、ユーザーの組み合わせに基づいて、きめ細やかなアクセス制御を設定できます。特定の管理者には全てのデータベースへのフルアクセスを許可しつつ、アプリケーション用ユーザーには特定のデータベースへのアクセスのみを許可するといった制御が可能です。
- 多様な認証方法の選択: パスワード認証、クライアント証明書認証、Kerberos認証、LDAP認証など、様々な認証方法を選択・適用できます。これにより、組織のセキュリティポリシーや既存の認証基盤と連携させることが可能です。
このファイルを理解し、適切に設定することは、PostgreSQLサーバーを安全に運用するための必須要件と言えます。誤った設定は、セキュリティホールを開けたり、正当な接続ができなくなったりといった問題を引き起こす可能性があります。
2. pg_hba.confの基本
pg_hba.confファイルを理解するための基本的な事項から始めましょう。
2.1. ファイルの場所
pg_hba.confファイルの場所は、PostgreSQLのインストール方法やオペレーティングシステムによって異なります。一般的には、PostgreSQLのデータディレクトリ内に格納されています。
データディレクトリの場所を確認するには、PostgreSQLのpsqlクライアントで以下のコマンドを実行します。
sql
SHOW data_directory;
このコマンドの出力が、pg_hba.confファイルが格納されているディレクトリです。
一般的なデータディレクトリの場所例:
- Linux (apt/yumインストール):
/etc/postgresql/<version>/main/または/var/lib/postgresql/<version>/<cluster>/ - macOS (Homebrew):
/usr/local/var/postgres/または/opt/homebrew/var/postgres/ - Windows:
C:\Program Files\PostgreSQL\<version>\data\
多くの場合、設定ファイル群はデータディレクトリ直下、またはそのサブディレクトリ(例: conf.dなど、postgresql.confで指定されている場合)にあります。
2.2. ファイルのフォーマット
pg_hba.confファイルは、テキストファイルであり、各行が1つの認証ルールを定義します。行頭が # の行はコメントとして無視されます。空行も無視されます。
各ルール行は、通常、以下のフィールドから構成されます(フィールド間は空白文字またはタブで区切られます)。
TYPE DATABASE USER ADDRESS METHOD [OPTIONS]
これらのフィールドは、左から順番に評価されます。接続要求がこのファイル内の各行と照合され、最初にマッチした行のルールが適用されます。
例:
“`conf
TYPE DATABASE USER ADDRESS METHOD
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
host mydatabase myuser 192.168.1.0/24 md5
host all all 0.0.0.0/0 reject
“`
この例では:
1. ローカル接続(Unixドメインソケット)は、全てのデータベース、全てのユーザーに対してpeer認証で許可されます。
2. IPv4ループバックアドレスからの接続は、全てのデータベース、全てのユーザーに対してscram-sha-256認証で許可されます。
3. IPv6ループバックアドレスからの接続も同様です。
4. 192.168.1.0/24ネットワークからの接続は、mydatabaseに対するmyuserからの要求のみ、md5認証で許可されます。
5. それ以外の全てのアドレスからの接続は拒否されます。
2.3. 行の評価順序
前述の通り、pg_hba.confファイルは上から順に評価され、最初に一致したルールが適用されます。これは非常に重要な点です。
例えば、以下の設定があったとします。
“`conf
例1: 意図通りに動かない可能性のある順序
host all all 192.168.1.0/24 reject
host mydatabase myuser 192.168.1.100/32 md5
“`
この場合、192.168.1.100からのmyuserによるmydatabaseへの接続要求は、最初の行の192.168.1.0/24にマッチしてしまい、rejectされてしまいます。より具体的なルール(特定ホスト)は、より一般的なルール(ネットワーク範囲)よりも前に記述する必要があります。
正しい順序の例:
“`conf
例2: 正しい順序
host mydatabase myuser 192.168.1.100/32 md5
host all all 192.168.1.0/24 reject
“`
この順序であれば、192.168.1.100からのmyuserによるmydatabaseへの接続要求は、最初の行にマッチしてmd5認証に進みます。それ以外の192.168.1.0/24内のアドレスからの接続は、2番目の行にマッチしてrejectされます。
したがって、pg_hba.confを設定する際は、より具体的なルールをファイルのより上の方に記述するという原則を常に意識してください。
2.4. 設定変更の反映方法
pg_hba.confファイルを変更した場合、その変更を有効にするためにはPostgreSQLサーバーに設定ファイルを再読み込みさせる必要があります。これには以下の2つの方法があります。
-
設定のリロード:
bash
pg_ctl reload -D /path/to/data/directory
または、psqlからスーパーユーザーとして以下を実行します。
sql
SELECT pg_reload_conf();
多くのシステムでは、サービスの再起動ではなくリロードが推奨されます。リロードは既存の接続を中断しません。 -
サーバーの再起動:
bash
pg_ctl restart -D /path/to/data/directory
または、システムのサービス管理ツールを使用します(例:systemctl restart postgresql)。
再起動は既存の接続を全て切断します。通常、設定のリロードで十分ですが、一部のパラメータ変更は再起動が必要です(pg_hba.confはリロードで有効になります)。
設定変更後に接続が期待通りに動作しない場合は、必ず設定のリロードまたは再起動を行ったか確認してください。
3. 行の構成要素の詳細
pg_hba.confの各行を構成するフィールドについて、さらに詳しく掘り下げていきます。
3.1. TYPE (接続タイプ)
接続の種類を指定します。
local: Unixドメインソケットによる接続。PostgreSQLサーバーが稼働しているローカルマシンからの接続にのみ適用されます。ADDRESSフィールドは無視されます。host: TCP/IPソケットによる接続(SSL/TLSを使用するかどうかに関わらず)。リモートからの接続に適用されます。ADDRESSフィールドが必要です。hostssl: SSL/TLS暗号化されたTCP/IPソケットによる接続。ADDRESSフィールドが必要です。hostnossl: SSL/TLS暗号化されていないTCP/IPソケットによる接続。ADDRESSフィールドが必要です。
hostsslとhostnosslを組み合わせることで、特定のアドレス範囲からの接続に対してSSL/TLSの使用を必須または禁止することができます。
clientcert=1オプション: これはTYPEとして独立しているわけではなく、hostsslまたはhostタイプに適用できるオプションです。クライアント証明書認証を必須にする場合に指定します。詳細はOPTIONSの項で説明します。
その他、特殊なTYPEとして以下のものがあります。これらはhostなどと組み合わせて使用されることはなく、単独でルールの対象を限定するために使用できます。
samesuper: 接続ユーザーがデータベースのスーパーユーザーである場合にのみルールを適用します。samerole: 接続ユーザーが、指定されたユーザーまたはユーザーのリストと同じロールであるか、そのロールのメンバーである場合にルールを適用します。ロール階層を考慮します。sameuser: 接続ユーザーが、指定されたデータベースと同じ名前である場合にのみルールを適用します。
これらの特殊なTYPEは、データベースやユーザーの指定と組み合わせて使用します。例えば、local samesuper all peer は、ローカル接続でスーパーユーザーが全てのデータベースにpeer認証で接続することを許可します。
3.2. DATABASE (データベース名)
接続先のデータベースを指定します。
all: 全てのデータベースに適用されます。sameuser: 接続しようとしているユーザーと同じ名前のデータベースに適用されます。samesuper: 接続ユーザーがスーパーユーザーである場合、ユーザーが接続しようとしているデータベースと同じ名前のデータベースに適用されます。このオプションはlocalタイプの接続でのみ有効です。samerole: 接続ユーザーが、指定されたユーザーまたはユーザーのリストと同じロールであるか、そのロールのメンバーである場合に、そのロールと同じ名前のデータベースに適用します。PostgreSQL 14で追加されました。- 特定のデータベース名: 例:
mydatabase。複数のデータベースを指定する場合はカンマ区切りでリストします(例:db1,db2)。 - ファイル指定 (
+filename):@または+記号をプレフィックスとして使用し、ファイル名を指定します。ファイル内の各行がデータベース名として扱われます。ファイル内のデータベース名はカンマ区切りでリストすることも可能です。
例:
conf
host all all 0.0.0.0/0 reject # 全てのDBへの接続をデフォルト拒否
host production_db app_user 192.168.1.100/32 scram-sha-256 # production_dbへのapp_userからの接続のみ許可
host template1,template0 admin_user 192.168.1.0/24 md5 # 特定のDBへのadmin_userからの接続を許可
host +allowed_dbs data_analyst 10.0.0.0/8 cert # ファイルにリストされたDBへの接続を許可
3.3. USER (ユーザー名)
接続元のユーザーを指定します。
all: 全てのユーザーに適用されます。- 特定のユーザー名: 例:
myuser。複数のユーザーを指定する場合はカンマ区切りでリストします(例:user1,user2)。 - ファイル指定 (
+filename):@または+記号をプレフィックスとして使用し、ファイル名を指定します。ファイル内の各行がユーザー名として扱われます。ファイル内のユーザー名はカンマ区切りでリストすることも可能です。
例:
conf
host all all 192.168.1.0/24 md5 # 全てのユーザーからの接続を許可
host all admin_user 10.0.0.0/8 gss # admin_userからの接続のみ許可
host mydatabase +app_users 172.16.0.0/12 scram-sha-256 # ファイルにリストされたユーザーからの接続を許可
3.4. ADDRESS (クライアントアドレス)
接続元のクライアントのIPアドレスまたはホスト名を指定します。localタイプの接続では無視されます。
- IPアドレス/マスク長 (CIDR): 最も一般的で推奨される形式です。例:
192.168.1.0/24(サブネット全体),192.168.1.100/32(単一ホスト)。IPv6アドレスも同様に指定します。例:::1/128(IPv6ループバック),2001:db8::/32(IPv6サブネット)。 - IPアドレス範囲 (非推奨): ハイフンで区切られたIPアドレスの範囲。例:
192.168.1.1-192.168.1.100。CIDR表記の方が一般的で推奨されます。 - ホスト名: 例:
myclient.example.com。ホスト名で指定した場合、接続時に名前解決が行われ、そのホスト名に対応する全てのアドレスからの接続が許可されます。ただし、DNSルックアップのオーバーヘッドや、DNSスプーフィングのリスクがあるため、可能であればIPアドレス/CIDRで指定することが推奨されます。 -
予約語:
all: 全てのIPアドレスに適用されます(IPv4およびIPv6)。samehost: サーバー自身のIPアドレスに適用されます。samenet: サーバーが接続されているサブネット(ローカルネットワーク)に適用されます。
-
ファイル指定 (
+filename):@または+記号をプレフィックスとして使用し、ファイル名を指定します。ファイル内の各行がアドレスとして扱われます(CIDR、ホスト名、予約語など)。
例:
conf
host all all 127.0.0.1/32 scram-sha-256 # IPv4ループバック
host all all ::1/128 scram-sha-256 # IPv6ループバック
host all all 192.168.1.0/24 md5 # 特定のIPv4サブネット
host all all 2001:db8::/32 md5 # 特定のIPv6サブネット
host all all client.example.com gss # 特定のホスト名
host all all all reject # 全てのアドレスをデフォルト拒否
host all all +trusted_hosts.txt cert # ファイルにリストされたアドレス
hostタイプでアドレスを指定する際は、サーバーがリッスンするアドレス(listen_addressesパラメータ)と一致している必要があります。listen_addresses = '*' のように全てのアドレスをリッスンしている場合、pg_hba.confで特定のインターフェースやアドレスからの接続を許可できます。
3.5. METHOD (認証方法)
接続を許可する際に使用する認証方法を指定します。セキュリティ上、このフィールドの選択は極めて重要です。
trust: 無条件に接続を許可します。認証は行われません。非常に危険な設定であり、特別な理由がない限り使用すべきではありません。 ローカルループバック接続でのみ使用を検討できる程度です。reject: 無条件に接続を拒否します。エラーメッセージを返して接続を終了させます。特定の不正なアクセスパターンをブロックするのに便利です。md5: MD5ハッシュ化されたパスワード認証を行います。パスワード自体はネットワーク上を流れずハッシュ化されますが、MD5自体の脆弱性(衝突耐性の低さ)や、レインボーテーブル攻撃のリスクがあります。後述のscram-sha-256が推奨されます。sha256: SHA-256ハッシュ化されたパスワード認証を行います。PostgreSQL 10で導入されましたが、これも後述のscram-sha-256が推奨されます。password: 平文パスワード認証を行います。ネットワーク上を平文でパスワードが流れるため、絶対にインターネット経由や信頼できないネットワークで使用しないでください。 通常はmd5やscram-sha-256を使用すべきです。scram-sha-256: SCRAM-SHA-256認証を行います。Salted Challenge Response Authentication Mechanism (SCRAM) を使用しており、md5やsha256よりもはるかに強力で安全なパスワード認証方式です。PostgreSQL 10で導入され、推奨されるパスワード認証方法です。PostgreSQL 14以降では、サーバー側のパスワード暗号化方式のデフォルトもscram-sha-256になっています。gss: GSSAPI (Generic Security Services API) 認証を行います。Kerberos認証など、外部のセキュリティメカニズムと連携する場合に使用します。ssi: SSI (Secure Socket Interface) 認証を行います。SELinuxなどのLinuxセキュリティモジュールと連携する場合に使用します。ident: クライアントOSのユーザー名をidentプロトコル経由で取得し、要求されたPostgreSQLユーザー名と比較します。Unixドメインソケット (local) 接続や、信頼されたネットワークからの接続で使用されることがあります。identデーモンがクライアント側で動作している必要があります。セキュリティ上の懸念(identdのなりすましなど)があるため、信頼できる環境でのみ使用すべきです。peer: クライアントOSのユーザー名をgetpeereid()などのシステムコール経由で取得し、要求されたPostgreSQLユーザー名と比較します。Unixドメインソケット (local) 接続にのみ使用できます。identよりも安全な、ローカル接続の推奨認証方法です。pam: PAM (Pluggable Authentication Modules) と連携して認証を行います。OSレベルの認証メカニズムを活用できます。ldap: LDAPサーバーと連携して認証を行います。ユーザー情報をLDAPディレクトリで一元管理している場合に便利です。cert: SSLクライアント証明書認証を行います。クライアントが提示した証明書が信頼できるルート証明書によって署名されているかを確認し、さらに証明書のCommon Name (CN) やSubject Alternative Name (SAN) とPostgreSQLユーザー名を照合して認証を行います。非常に強力な認証方法であり、パスワード漏洩のリスクをなくせます。hostsslタイプと組み合わせて使用します。radius: RADIUSサーバーと連携して認証を行います。
推奨される認証方法:
- ローカル接続 (
local):peerが最も安全で推奨されます。identも利用可能ですが、peerの方が一般的に安全です。 - リモート接続 (
host,hostssl,hostnossl):- 強力なパスワード認証:
scram-sha-256が強く推奨されます。次いでmd5(非推奨になりつつある)。passwordは避けるべきです。 - 外部認証:
cert,gss,ldap,pam,radiusなど、組織の既存インフラやセキュリティ要件に応じて選択します。特にcertはパスワードレス認証として強力です。
- 強力なパスワード認証:
3.6. OPTIONS (認証方法固有のオプション)
一部の認証方法では、追加の設定オプションを指定できます。これらは、メソッドフィールドの後にスペース区切りで記述します。指定できるオプションは、選択したMETHODによって異なります。
一般的なオプションの例:
clientcert=1(cert,hostsslタイプ): SSLクライアント証明書認証を必須にします。これがない場合でも、クライアント証明書を提示すればcert認証を試みますが、証明書がない場合は他の認証方法(例:md5)にフォールバックする可能性があります。clientcert=1を指定すると、証明書がない接続は即座に拒否されます。certname: クライアント証明書のどのフィールドをPostgreSQLユーザー名として使用するかを指定します(例:certname=common_name)。krb_realm(gss): Kerberosレルムを指定します。krb_service(gss): GSSAPIサービス名。ldapserver,ldapport,ldapbinddn,ldapbindpasswd,ldapsearchattribute,ldapbasedn,ldapscheme,ldaptls,ldapurl(ldap): LDAP認証サーバーへの接続情報や検索パラメータを指定します。pamservice(pam): PAMサービス名を指定します。radiusserver,radiusport,radiussecret,radiusfailback_dsn(radius): RADIUSサーバーへの接続情報や共有シークレットを指定します。ident: ident認証で使用するidentマップ名を指定します(デフォルトは使用しない)。include_if_not_disabled: このオプションを持つルールは、スーパーユーザーによってそのルールが無効化されている場合(ALTER SYSTEM … SET hba_file=’…’など)を除き、常に含まれます。通常、このオプションはコメントで記述されますが、特定のPostgreSQLバージョンやパッチでは機能する場合があります(公式ドキュメントを確認してください)。これは主に自動ツールが管理するHBAファイルで、手動変更がリロード時に消えないようにするために使われることがありますが、標準的な使い方ではありません。
例:
conf
hostssl all all 192.168.1.100/32 cert clientcert=1 certname=common_name # 特定ホストからの証明書認証を必須に
host all all 10.0.0.0/8 ldap ldapserver=ldap.example.com ldapbinddn="cn=admin,dc=example,dc=com" ldapbindpasswd="mypassword" ldapsearchattribute="uid" ldapbasedn="ou=people,dc=example,dc=com"
4. セキュリティのベストプラクティス
安全なpg_hba.confを設定するための主要なベストプラクティスを挙げます。
4.1. 最小権限の原則
データベースアクセス制御の基本は、ユーザーが必要とする最小限の権限のみを付与することです。これはpg_hba.confにも当てはまります。
ADDRESSの制限: 不要なIPアドレスやネットワークからの接続は許可しない。信頼できるクライアント、アプリケーションサーバー、管理ホストなど、必要なアドレスのみを明示的に許可し、それ以外はrejectするルールを最後に配置します。DATABASEとUSERの制限: アプリケーション用ユーザーにはアプリケーションが使用する特定のデータベースのみへのアクセスを許可し、全てのデータベース (all) へのアクセスは許可しない。管理者ユーザーや特別な目的のユーザーのみに広範なアクセスを許可します。- スーパーユーザー接続の制限:
postgresなどスーパーユーザーアカウントへのリモート接続は、可能な限り制限すべきです。特定の信頼できる管理ホストからのみ許可するか、あるいはローカル接続 (local) のみ許可し、必要に応じてsu - postgresなどでサーバーにログインしてからpsqlを使用するようにします。
4.2. 強力な認証方法の選択
安全性の低い認証方法は使用しないようにします。
trustの使用は避ける:trustは認証を行わないため、絶対にインターネットからの接続や信頼できないネットワークからの接続に設定してはいけません。ローカルループバックアドレスからの接続など、OSレベルでアクセスが厳密に制御されている環境でのみ限定的に使用を検討できますが、それでもpeerやscram-sha-256などの認証方法を使用する方が安全です。passwordの使用は避ける: パスワードが平文で流れるため、中間者攻撃(Man-in-the-Middle Attack)に対して脆弱です。scram-sha-256を推奨: パスワード認証を使用する場合は、最も安全なscram-sha-256を選択します。PostgreSQL 10以降で使用可能です。- パスワード以外の認証方法: 可能であれば、クライアント証明書認証 (
cert) やKerberos (gss)、LDAP (ldap) など、パスワード漏洩のリスクがない認証方法の導入を検討します。cert認証は特に強力です。
4.3. SSL/TLSの利用 (hostssl)
TCP/IP接続を行う場合は、可能な限りSSL/TLSを使用して接続を暗号化すべきです。これにより、パスワードや送信データがネットワーク上で傍受されるのを防ぎます。
pg_hba.confでhostsslタイプを使用することで、特定の接続に対してSSL/TLSの使用を必須にできます。- サーバー側のSSL設定 (
ssl = oninpostgresql.conf、証明書ファイルの設定など) も必要です。
4.4. クライアント証明書認証の強化 (clientcert=1)
hostsslタイプとcert認証を組み合わせることで、クライアント証明書による強力な認証を設定できます。さらに、clientcert=1オプションを追加することで、クライアント証明書の提示自体を必須にできます。これにより、有効なクライアント証明書を持たないクライアントは接続できなくなります。
4.5. rejectエントリの活用
rejectエントリを適切に配置することで、意図しないアクセスパターンを明示的にブロックできます。例えば、全てのアドレスからの広範なアクセスを許可する前に、特定のブロックすべきアドレス範囲からのアクセスをrejectするルールを記述することができます。
4.6. ローカル接続 (local) の設定
Unixドメインソケットによるローカル接続は、ネットワーク経由の接続とは異なるセキュリティコンテキストで扱われます。通常、ローカル接続は信頼性が高いと見なされますが、サーバー上で実行される全てのプロセスが接続を試みる可能性があるため、ここでも適切な認証方法(peerまたはident)を使用すべきです。特に、スーパーユーザーへのローカル接続をtrustに設定するのは避けるべきです。
4.7. ログの監視
postgresql.confでlog_connections = onおよびlog_disconnections = onを設定し、接続試行や切断に関するログを記録・監視します。これにより、不正な接続試行を早期に検知できます。
4.8. デフォルト設定のレビュー
PostgreSQLのデフォルトのpg_hba.confは、多くの場合、ローカル接続やループバックアドレスからの接続のみを許可し、それ以外は拒否するようになっています。これは安全な初期設定ですが、リモートからのアクセスが必要な場合は、このデフォルト設定をレビューし、必要最小限の変更を加えるようにします。特に、0.0.0.0/0からの接続を安易に許可しないように注意が必要です。
5. 具体的な設定例
様々なシナリオに対応するpg_hba.confの設定例をいくつか紹介します。これらの例は、上記のセキュリティベストプラクティスを反映しています。
5.1. 安全なデフォルト設定(ローカル接続のみ許可)
最も安全な設定は、ローカル接続(Unixソケット)とループバックアドレスからの接続のみを許可し、それ以外を全て拒否する設定です。
“`conf
TYPE DATABASE USER ADDRESS METHOD
ローカル接続 (Unixソケット) は OS ユーザー名に基づいて認証 (peer)
local all all peer
IPv4 ループバックアドレスからの接続は強力なパスワード認証 (SCRAM-SHA-256)
host all all 127.0.0.1/32 scram-sha-256
IPv6 ループバックアドレスからの接続は SCRAM-SHA-256 認証
host all all ::1/128 scram-sha-256
上記以外のアドレスからの全ての接続を拒否
host all all 0.0.0.0/0 reject
host all all ::/0 reject
“`
この設定では、サーバーマシン上でpsqlを実行するか、SSHトンネルなどを使ってローカルに接続する必要があります。
5.2. 特定のネットワークからの接続をパスワード認証で許可
社内ネットワークなど、信頼できる特定のIPアドレス範囲からの接続を許可し、パスワード認証(推奨はscram-sha-256)を使用する設定です。
“`conf
TYPE DATABASE USER ADDRESS METHOD
ローカル接続 (Unixソケット)
local all all peer
IPv4/IPv6 ループバックアドレスからの接続
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
信頼できるネットワーク 192.168.1.0/24 からの接続を SCRAM-SHA-256 で許可
host all all 192.168.1.0/24 scram-sha-256
信頼できるネットワーク 2001:db8::/32 からの接続を SCRAM-SHA-256 で許可
host all all 2001:db8::/32 scram-sha-256
上記以外のアドレスからの全ての接続を拒否
host all all 0.0.0.0/0 reject
host all all ::/0 reject
“`
5.3. アプリケーションサーバーからの接続を特定のユーザー/DBに限定
アプリケーションサーバー(例: IPアドレス 192.168.1.100)からの接続に対して、特定のデータベース (app_db) への特定のユーザー (app_user) による接続のみを許可する設定です。他の接続は拒否します。
“`conf
TYPE DATABASE USER ADDRESS METHOD
アプリケーションサーバー (192.168.1.100) から app_db への app_user による接続を許可
強力な SCRAM-SHA-256 認証を使用し、SSL接続を必須とする (hostssl)
hostssl app_db app_user 192.168.1.100/32 scram-sha-256
ローカル接続は通常通り許可
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
それ以外のアドレス、ユーザー、DB の組み合わせは全て拒否
host all all 0.0.0.0/0 reject
host all all ::/0 reject
``hostssl`を使用することで、この特定の接続がSSLで暗号化されることを必須にしています。
この例では、
5.4. 管理者接続の制限とSSL必須
管理者ユーザー (admin_user) による接続を特定の管理用ホスト (192.168.1.50) からのみ許可し、SSL接続を必須とする設定です。その他の接続は通常通り許可/拒否ルールに従います。
“`conf
TYPE DATABASE USER ADDRESS METHOD
管理用ホスト (192.168.1.50) からの admin_user による接続を SSL必須 SCRAM-SHA-256 で許可
hostssl all admin_user 192.168.1.50/32 scram-sha-256
その他の接続ルール (例: アプリケーションからの接続、ローカル接続など)
… (前述の例などを参照)
例: 信頼できるネットワークからの一般ユーザー接続
host all !admin_user 192.168.1.0/24 scram-sha-256 # admin_user以外
``!admin_user
この例では、のようにユーザー名の前に!`を付けることで、特定のユーザー以外を対象にすることも可能です。
5.5. クライアント証明書認証を使用する
特定の信頼できるクライアントからの接続に対して、クライアント証明書認証(certメソッド)を使用し、証明書の提示を必須 (clientcert=1) とする設定です。
まず、PostgreSQLサーバー側でSSLが有効になっており、信頼できるクライアント認証局の証明書が指定されている必要があります (ssl=on, ssl_ca_file in postgresql.conf)。
“`conf
TYPE DATABASE USER ADDRESS METHOD
特定のネットワークからの SSL/TLS 接続に対してクライアント証明書認証を必須とする
証明書の Common Name (CN) が PostgreSQL ユーザー名と一致する場合に認証成功
hostssl all all 192.168.1.0/24 cert clientcert=1 certname=common_name
その他の接続ルール
… (パスワード認証が必要な他の接続など)
``192.168.1.0/24`からのSSL接続要求に対して、クライアントは有効なクライアント証明書を提示する必要があり、その証明書のCNが要求されたPostgreSQLユーザー名と一致した場合に接続が許可されます。
この設定では、
5.6. ファイルを使用したユーザー/アドレスリストの管理
許可するユーザーやIPアドレスのリストが長くなる場合、それらを外部ファイルに記述し、pg_hba.confから参照することができます。これにより、pg_hba.confファイル自体を簡潔に保ち、リストの管理を容易にできます。
例:allowed_users.txt というファイルに許可するユーザー名を1行に1つ記述する。
app_user
batch_user
report_user
例:trusted_networks.txt というファイルに許可するCIDRアドレスを1行に1つ記述する。
192.168.1.0/24
10.0.0.0/8
172.16.0.0/12
pg_hba.confでの設定:
“`conf
TYPE DATABASE USER ADDRESS METHOD
ファイルにリストされたユーザーからの、ファイルにリストされたネットワークからの接続を許可
host all +allowed_users +trusted_networks scram-sha-256
その他の接続ルール
…
``pg_hba.conf`ファイルからの相対パス、または絶対パスで指定できます。PostgreSQLデータディレクトリ内など、適切な場所に配置します。
ファイルパスは、
5.7. rejectルールの活用
特定の不正なIPアドレスやネットワークからの接続を明示的に拒否する設定です。これは、広範な許可ルールの前に記述する必要があります。
“`conf
TYPE DATABASE USER ADDRESS METHOD
不正アクセス試行が確認された特定の IP アドレスからの接続を拒否
host all all 203.0.113.1/32 reject
広範なネットワークからの一般的な接続を許可するルール (この前にrejectルールを書く)
host all all 192.168.1.0/24 scram-sha-256
… その他のルール
“`
6. トラブルシューティング
pg_hba.confに関する問題は、通常、接続拒否や認証エラーとして現れます。よくある問題とその診断・解決方法を説明します。
6.1. 設定変更が反映されない
原因: pg_hba.confファイルを変更した後、PostgreSQLサーバーに設定を再読み込みさせるのを忘れている。
解決策: pg_ctl reload または SELECT pg_reload_conf(); を実行します。再起動が必要な場合は、サーバーを再起動します。
6.2. 接続拒否エラー (no pg_hba.conf entry)
クライアント側で以下のようなエラーメッセージが表示される場合:
psql: error: FATAL: no pg_hba.conf entry for host "X.X.X.X", user "myuser", database "mydatabase", SSL off/on
原因: 接続しようとしているクライアントのIPアドレス、ユーザー名、データベース名、およびSSLの使用状況の組み合わせに一致するルールがpg_hba.confファイルに見つからなかった。rejectルールにマッチした可能性もありますが、通常はマッチするルールが全くない場合にこのエラーが表示されます。
診断:
1. サーバー上のpg_hba.confファイルを開きます。
2. エラーメッセージに示されている接続情報 (host "X.X.X.X", user "myuser", database "mydatabase", SSL off/on) を正確に確認します。
3. ファイルの先頭から順に、各ルールとこの接続情報がマッチするかどうかをチェックします。
4. 全くマッチするルールがないか、意図しないルールにマッチしてしまっているかを確認します。
5. ADDRESSフィールドのCIDR表記が正しいか、クライアントのIPアドレスがその範囲に含まれているか確認します。
6. DATABASEやUSERの指定が正しいか、大文字/小文字の違いがないか確認します(ユーザー名は大文字/小文字を区別します)。
7. SSLの使用状況 (SSL off/on) とTYPEフィールド (host, hostssl, hostnossl) が一致しているか確認します。
8. ファイルの最後に、広範なrejectルール(例: host all all 0.0.0.0/0 reject)がないか確認します。そのルールよりも前に、意図した許可ルールが記述されている必要があります。
解決策: エラーメッセージの接続情報に正確にマッチするルールを追加するか、既存のルールを修正します。修正後は設定をリロードします。
6.3. 認証方法エラー (authentication failed)
クライアント側で以下のようなエラーメッセージが表示される場合:
psql: error: FATAL: password authentication failed for user "myuser"
または
psql: error: FATAL: peer authentication failed for user "myuser"
原因: pg_hba.confで指定された認証方法を使用したが、認証が失敗した。
診断:
1. pg_hba.confで、該当する接続情報(IPアドレス、ユーザー、DB、SSL)にマッチしたルールを見つけます。
2. そのルールで指定されているMETHODを確認します(例: scram-sha-256, peer, certなど)。
3. 選択されたメソッドについて、以下の点をチェックします。
* パスワード認証 (md5, sha256, scram-sha-256): クライアントが入力したパスワードが、サーバー側のデータベースに設定されているユーザーのパスワードと一致しない。サーバー側のパスワードが正しく設定されているか、ユーザーが正しいパスワードを入力しているか確認します。ユーザーのパスワードはpsqlで \du コマンドなどで確認できます。
* peer認証: クライアントを起動したOSユーザー名と、接続しようとしているPostgreSQLユーザー名が一致しない。または、OSユーザーとDBユーザーのマッピングがpg_ident.confで設定されており、それが一致しない。
* ident認証: クライアント側のidentデーモンが正しく動作していないか、報告されたOSユーザー名が期待と異なる。または、pg_ident.confの設定が一致しない。
* cert認証: クライアント証明書が無効、信頼されていない認証局によって署名されている、または証明書のCN/SANフィールドが要求されたPostgreSQLユーザー名と一致しない。clientcert=1オプションが指定されているのに証明書が提示されていない。
* LDAP, GSS, PAMなど: 外部認証システムとの連携設定(pg_hba.confのオプション、postgresql.confの関連パラメータ、外部サーバーの設定)が正しくない。
解決策: 認証方法の原因に応じた修正を行います。パスワードの再設定、OSユーザー名とDBユーザー名の確認、証明書や外部認証システム設定の見直しなどを行います。パスワード認証の場合は、PostgreSQLユーザーのパスワードをALTER USER myuser PASSWORD 'new_password';で再設定してみます。
6.4. ファイル構文エラー
pg_hba.confファイルにタイプミス、フィールド数の間違い、不正な文字などが含まれている場合、PostgreSQLサーバーの起動時や設定リロード時にエラーが発生します。
診断: PostgreSQLサーバーのログファイルを確認します。ログファイルにFATAL: could not load pg_hba.confや、特定の行番号とエラー内容を示すメッセージが出力されているはずです。
解決策: エラーメッセージに示された行番号を確認し、その行の構文を修正します。各フィールドが正しく、区切り文字が適切に使用されているか確認します。修正後は設定をリロードまたはサーバーを再起動します。
6.5. listen_addresses の問題
pg_hba.confでリモートからの接続を許可するルールがあっても、postgresql.confのlisten_addressesパラメータが適切に設定されていない場合、サーバーはリモートからの接続要求自体を受け付けません。
診断:
1. postgresql.confファイルを開き、listen_addressesパラメータを確認します。
2. デフォルトは通常localhost(ループバックアドレスのみをリッスン)です。リモートからの接続を受け付けるには、サーバーのIPアドレス、*(全てのアドレス)、または特定のネットワークインターフェースのIPアドレスを指定する必要があります。
3. listen_addresses = '*' と設定するのが最も柔軟ですが、これにより全てのネットワークインターフェースでPostgreSQLが待機するため、pg_hba.confによるアクセス制御がより一層重要になります。
解決策: listen_addressesを適切に設定します(例: listen_addresses = '*')。このパラメータの変更は、PostgreSQLサーバーの再起動が必要です。
7. 高度なトピック
より複雑なシナリオに対応するためのpg_hba.confの応用的な使い方や、あまり知られていない機能について触れます。
7.1. samesuper, samerole, sameuser の活用
これらの特別なTYPEは、ルールの対象を特定のユーザーやロールとの関係で制限したい場合に役立ちます。
local samesuper all peer: ローカル接続で、接続ユーザーがスーパーユーザーである場合に、全てのデータベースに対してpeer認証で接続を許可します。これは、postgresユーザーがローカルで操作する際に便利です。local sameuser all peer: ローカル接続で、接続ユーザーのOSユーザー名とPostgreSQLユーザー名が一致する場合に、全てのデータベースに対してpeer認証で接続を許可します。host samerole replicator replication 192.168.1.0/24 scram-sha-256: 接続ユーザーがreplicatorロールのメンバーである場合に、replicationデータベース(ストリーミングレプリケーション用)への接続を許可します。この設定は、レプリケーションユーザーに限定的な権限を与えたい場合に有効です。
7.2. +filename オプションの詳細な使い方
DATABASE, USER, ADDRESSフィールドでファイルを使用する場合、ファイル内の各行は単一の項目として扱われます。コメント行 (#) や空行は無視されます。ファイル内の項目はカンマ区切りで複数記述することも可能です。
例:allowed_users.txtファイルの内容
“`
user1
user2,user3 # user2 and user3
This is a comment
user4
``user1
このファイルを参照するルールは、,user2,user3,user4` のいずれかに一致します。
ファイルを使用すると、pg_hba.confファイルを頻繁に編集することなく、許可リストを更新できます。ただし、ファイルの変更もpg_hba.confのリロードが必要です。また、ファイルはpg_hba.confと同じ権限でPostgreSQLプロセスから読み取れる必要があります。
7.3. 複雑な組み合わせルールの考え方
pg_hba.confのルールは、TYPE, DATABASE, USER, ADDRESSの全てのフィールドがマッチした場合に適用されます。この組み合わせを利用して、非常にきめ細やかなアクセス制御を実現できます。
例:
* 開発環境からの接続 (特定のIP範囲 192.168.10.0/24) は、開発用ユーザー (dev_user) のみ、開発データベース (dev_db) への接続を許可する。
* 本番環境からの接続 (特定のIP範囲 192.168.20.0/24) は、アプリケーションユーザー (app_user) のみ、本番データベース (prod_db) への接続を許可する。
* 特定のIPアドレス (192.168.1.50) からの管理者ユーザー (admin_user) による接続は、全てのデータベースへのアクセスを許可する。
“`conf
TYPE DATABASE USER ADDRESS METHOD
管理者接続 (最優先で記述)
hostssl all admin_user 192.168.1.50/32 scram-sha-256
本番環境からのアプリケーション接続
hostssl prod_db app_user 192.168.20.0/24 scram-sha-256
開発環境からの開発者接続
host dev_db dev_user 192.168.10.0/24 md5 # 開発環境はmd5でも良いかもしれないが、scram-sha-256が望ましい
ローカル接続
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
その他全てを拒否 (最後に記述)
host all all 0.0.0.0/0 reject
host all all ::/0 reject
“`
このように、より具体的なルールをファイルの上部に、より一般的なルールや拒否ルールを下部に配置することが重要です。
8. まとめ
pg_hba.confファイルは、PostgreSQLデータベースへのアクセスを制御するための最も基本的かつ重要な設定ファイルです。その構造、各フィールドの意味、そしてルールの評価順序を理解することは、データベースのセキュリティを確保するために不可欠です。
安全なpg_hba.conf設定のポイントは以下の通りです。
- 最小権限の原則: 必要なユーザー、必要なデータベース、必要なアドレスからの接続のみを許可し、それ以外は全て拒否します。
- 強力な認証方法の選択: パスワード認証の場合は
scram-sha-256を強く推奨します。trustやpasswordの使用は避けるべきです。可能であれば、certなどのパスワード以外の認証方法を検討します。 - SSL/TLSの利用: リモート接続では、データの盗聴を防ぐために必ずSSL/TLSを使用します (
hostsslタイプ)。 - ルールの順序: より具体的なルールをファイルの上部に記述し、より一般的なルールや
rejectルールを下部に配置します。 - 設定の反映: ファイル変更後は必ず
pg_ctl reloadまたはSELECT pg_reload_conf();を実行します。 - ログの確認:
log_connectionsを有効にし、接続ログを定期的に確認します。
pg_hba.confは強力なツールですが、その設定は慎重に行う必要があります。設定を誤ると、セキュリティ上の脆弱性を生み出すだけでなく、正当な接続を妨害する可能性もあります。常に最小限の変更から始め、テスト環境で十分に動作確認を行ってから本番環境に適用することを強く推奨します。
この詳細な解説が、あなたのPostgreSQL環境におけるpg_hba.confファイルの理解と、より安全なデータベース運用の助けとなれば幸いです。