発端
2024年11月某日、顧客向けに構築作業をしていた担当者から連絡。
「セットアップツールでエラーが発生する」
提供されたログを見ると、Azure Database for PostgreSQL(以下、AzurePostgres)の構築スクリプトで以下のような情報がありました。
ERROR: permission denied for function dblink_connect_u
この調査結果と対応に関する情報です。
dblink
PostgreSQLでも有名な拡張機能で、異なるデータベースに接続する機能を提供してくれます。
似た機能をもつ、そして より使い勝手のよい「postgres_fdw」もありますが、dblink にのみ ある特徴的な機能があります。
「自律型トランザクション」
弊社のシステムは20年以上Oracleで提供をしてきましたが、諸事情(特にお金)から PostgreSQL でも使用できるよう拡張しました。
Oracleの自律型トランザクションは「AUTONOMOUS_TRANSACTION」というプラグマをさせば簡単に実現できるものであり、実際に使用していました。
しかし、PostgreSQLにはこの機能がなく、調査対応した結果が dblinkでした。
つまり、dblink は もう代替手段がない 必須機能です。
なんとかしなくてはいけない!!!
原因
さて、長々と書きましたが、結論は
・2024年11月以降に作成したAzurePostgres は 関数 dblink_connect_u の アクセス権限 が ロールazuresu
になった
ということでした。
このazuresu
というロールは
・AzurePostgresのスーバーユーザ
・Microsoftの中の人だけが このロールの一部になれる(※1)
ということで、もう dblink_connect_u を使わせる気ないな、と考えました。
※PostgreSQLのマニュアルを見ると、dblink_connect_u の使用は通常推奨はされていないみたいですからね。(※2)
使っていたお前が悪い、と言われると辛い。。
対応策
関数 dblink_connect を使いましょう!
調査情報
アクセス権限の確認
※以下、初期ロールをhogehoge
で作成した場合の情報
確認用SQL
select proname, proacl from pg_proc where proname = 'dblink_connect_u';
結果:変更前
proname | proacl
------------------+------------------------------------------
dblink_connect_u | {hogehoge=X/hogehoge}
dblink_connect_u | {hogehoge=X/hogehoge}
結果:変更後
proname | proacl
------------------+---------------------
dblink_connect_u | {azuresu=X/azuresu}
dblink_connect_u | {azuresu=X/azuresu}
dblink内の関数をまとめて確認した結果
確認用SQL
select proname, proacl from pg_proc where proname like 'dblink%';
結果
proname | proacl
-------------------------+---------------------
dblink |
dblink |
dblink |
dblink |
dblink_build_sql_delete |
dblink_build_sql_insert |
dblink_build_sql_update |
dblink_cancel_query |
dblink_close |
dblink_close |
dblink_close |
dblink_close |
dblink_connect |
dblink_connect |
dblink_connect_u | {azuresu=X/azuresu}
dblink_connect_u | {azuresu=X/azuresu}
dblink_current_query |
dblink_disconnect |
dblink_disconnect |
dblink_error_message |
dblink_exec |
dblink_exec |
dblink_exec |
dblink_exec |
dblink_fdw_validator |
dblink_fetch |
dblink_fetch |
dblink_fetch |
dblink_fetch |
dblink_get_connections |
dblink_get_notify |
dblink_get_notify |
dblink_get_pkey |
dblink_get_result |
dblink_get_result |
dblink_is_busy |
dblink_open |
dblink_open |
dblink_open |
dblink_open |
dblink_send_query |
ロール情報
ロール名 | 属性
--------------------------------+--------------------------------------------------------------------------
hogehoge | ロール作成可, DB作成可, RLS のバイパス
azure_pg_admin | ログインできません
azuresu | スーパユーザ, ロール作成可, DB作成可, レプリケーション可, RLS のバイパス
replication | レプリケーション可
参考
引用
※1 セキュリティ - Azure Database for PostgreSQL - Flexible Server | Microsoft Learn
ただし、サーバー管理者アカウントは、azuresu ロール (スーパーユーザー特権を持ち、コントロール プレーン操作の実行に使用される) の一部ではありません。
このサービスは管理対象の PaaS サービスなので、Microsoft だけがスーパー ユーザー ロールの一部になります。
dblink_connect_u — リモートデータベースへの永続的な危険な接続を開きます
(その他説明はマニュアルを御確認ください。)