LoginSignup
5
0

More than 1 year has passed since last update.

PG16:Allow file inclusion in pg_hba and pg_ident files

Last updated at Posted at 2022-12-02

はじめに

にゃーん。趣味でポスグレをやっている者だ。

この記事はPostgreSQL 16 全部ぬこ Advent Calendar 2022 3日目の記事です。
今回はPostgreSQLへの認証を制御するファイルに追加された機能について書いてみます。

概要

項目 内容
タイトル Allow file inclusion in pg_hba and pg_ident files
Topic Server Features
ステータス commited
Last modified 2022-11-28
概要 pg_hba.conf, pg_ident.confに include句が追加された

変更内容

PostgreSQLの設定ファイル(postgresql.conf)には、以前から include 指定がありました。
include 指定により一部の設定を別ファイルに分離するという管理が可能になっていましたが、他のPostgreSQLの設定ファイル(pg_hba.conf, pg_ident.conf)では、include 指定は未対応でした。
以下、ホストベース認証ファイル(pg_hba.conf)を例にして、include指定の挙動を確認します。

include指定のパターン

PostgreSQL 16で追加された include のパターンは以下の3つです。

include指定 意味
include 指定されたファイルの内容を取り込む。
存在しない場合にはエラーがpg_hba_file_rulesに報告される。
include_if_exists 指定されたファイルの内容を取り込む。
存在しない場合にはスキップする。
include_dir インクルード対象のファイルが格納されたディレクトリ上のファイルを読み込む。

pg_hba.confでの指定例

例として、pg_hba.confに各inlcude指定を行ったパターンを見てみます。

検証準備

以下のロールとデータベースをてきとーに作成します。

$ createuser user_a
$ createuser user_b
$ createdb db_a
$ createdb db_b
$

include

pg_hba.confを編集します。

$ cat /data/pgdata/16/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
include /tmp/user_hba.conf
local   all             postgres                                trust
$

includeに指定したファイルの内容はこんな感じ。

$ cat /tmp/user_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   db_a            user_a                                  trust
local   db_b            user_b                                  trust
$

PostgreSQLサーバをリロードして、pg_hba_file_rulesビューを確認します。

$ pg_ctl -D /data/pgdata/16 reload
server signaled
$ psql postgres -c "TABLE pg_hba_file_rules"
 rule_number |          file_name          | line_number | type  | database | user_name  | address | netmask | auth_method | options | error
-------------+-----------------------------+-------------+-------+----------+------------+---------+---------+-------------+---------+-------
           1 | /tmp/user_hba.conf          |           2 | local | {db_a}   | {user_a}   |         |         | trust       |         |
           2 | /tmp/user_hba.conf          |           3 | local | {db_b}   | {user_b}   |         |         | trust       |         |
           3 | /data/pgdata/16/pg_hba.conf |           4 | local | {all}    | {postgres} |         |         | trust       |         |
(3 rows)

きちんとincludeしたホストベース認証の設定が反映されてますね。

一応、認証の確認をします。

$ psql -U user_a db_a
psql (16devel)
Type "help" for help.

=> \q
$ psql -U user_a db_b
psql: error: connection to server on socket "/tmp/.s.PGSQL.16001" failed: FATAL:  no pg_hba.conf entry for host "[local]", user "user_a", database "db_b", no encryption
$

問題なくホストベース認証が機能してますね。

指定したファイルが存在しないとき

includeで指定したファイルが存在しない場合にも、reload時にエラーにはなりません。
エラーにはならないのpg_hba_file_rulesビューにも記録されません。

$ pg_ctl -D /data/pgdata/16 reload
server signaled
$ psql postgres -c "SELECT file_name, line_number, error FROM pg_hba_file_rules"
          file_name          | line_number |                              error
-----------------------------+-------------+-----------------------------------------------------------------
 /data/pgdata/16/pg_hba.conf |           3 | could not open file "/tmp/hoge.conf": No such file or directory
 /data/pgdata/16/pg_hba.conf |           4 |
(2 rows)

$

include_if_exists

pg_hba.confを書き換えます。

$ cat /data/pgdata/16/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
include_if_exists /tmp/user_hba.conf
local   all             postgres                                trust
$

リロードして、pg_hba_file_rulesを確認します。

$ pg_ctl -D /data/pgdata/16 reload
server signaled
$ psql postgres -c "TABLE pg_hba_file_rules"
 rule_number |          file_name          | line_number | type  | database | user_name  | address | netmask | auth_method |
options | error
-------------+-----------------------------+-------------+-------+----------+------------+---------+---------+-------------+-
--------+-------
           1 | /tmp/user_hba.conf          |           2 | local | {db_a}   | {user_a}   |         |         | trust       |
        |
           2 | /tmp/user_hba.conf          |           3 | local | {db_b}   | {user_b}   |         |         | trust       |
        |
           3 | /data/pgdata/16/pg_hba.conf |           4 | local | {all}    | {postgres} |         |         | trust       |
        |
(3 rows)

$

存在するときの挙動はinclude指定と同じです。

指定したファイルが存在しないとき

include_exits_ifで指定したファイルが存在しない場合にも、reload時にエラーにはなりません。
また、この場合にはエラーはpg_hba_file_rulesビューにも記録されません。

$ pg_ctl -D /data/pgdata/16 reload
server signaled
$ psql postgres -c "SELECT file_name, line_number, error FROM pg_hba_file_rules"
          file_name          | line_number | error
-----------------------------+-------------+-------
 /data/pgdata/16/pg_hba.conf |           4 |
(1 row)

$

include_dir

最後に、ホストベース認証ファイルを格納しているディレクトリを指定include_dirで指定する方法を紹介します。

/tmp/user_hba_conf_dirというディレクトリに01_user_hba_b.conf, 02_user_hba_a.confという2つのファイルを用意します。

$ pwd
/tmp/user_hba_conf_dir
$ ls
01_user_hba_b.conf  02_user_hba_a.conf
$ cat 01_user_hba_b.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   db_b            user_b                                  trust
$ cat 02_user_hba_a.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   db_a            user_a                                  trust
$

pg_hba.confinclude_dir指定を書きます。

$ cat /data/pgdata/16/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
include_dir /tmp/user_hba_conf_dir
local   all             postgres                                trust
$

PostgreSQLサーバをリロードして、pg_hba_file_rulesビューを確認します。

$ pg_ctl -D /data/pgdata/16 reload
server signaled
$ psql postgres -c "TABLE pg_hba_file_rules"
 rule_number |                 file_name                 | line_number | type  | database | user_name  | address | netmask |
auth_method | options | error
-------------+-------------------------------------------+-------------+-------+----------+------------+---------+---------+-
------------+---------+-------
           1 | /tmp/user_hba_conf_dir/01_user_hba_b.conf |           2 | local | {db_b}   | {user_b}   |         |         |
trust       |         |
           2 | /tmp/user_hba_conf_dir/02_user_hba_a.conf |           2 | local | {db_a}   | {user_a}   |         |         |
trust       |         |
           3 | /data/pgdata/16/pg_hba.conf               |           4 | local | {all}    | {postgres} |         |         |
trust       |         |
(3 rows)

$

include_dirで指定したディレクトリ内に複数のファイルが存在する場合、ファイル名順に設定が反映されます(なので、01_user_b.confから反映されます。この規則を利用して、反映される順序をファイル名の付与により制御できるようですね。

おわりに

今回は、pg_hba.conf, pg_ident.confに追加されたinclude機能について書いてみました。
データベースユーザ数が多い場合の管理方法がちょっと便利になるかもしれませんね。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0