はじめに
にゃーん。趣味でポスグレをやっている者だ。
この記事は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.conf
にinclude_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機能について書いてみました。
データベースユーザ数が多い場合の管理方法がちょっと便利になるかもしれませんね。