Open monok0 opened 7 months ago
Добрый день! Как-то всего много и сразу.. Я не изучал тему, но всё-таки, а что dblink не поддерживает TLS? Какой смысл защищаться от владельца pg_profile, если его задача - только автоматическое выполенние снимков. Живые люди не должны работать с этой ролью. Для сбора отчётов достаточно привилегии pg_read_all_stats, и быть владельцем pg_profile не обязательно. Можно даже использовать роль public, но некоторые данные в отчёте тогда будут не видны.
Foreign server, насколько я понимаю, не подойдёт для наших целей, поскольку профайлу надо подставлять туда имя базы данных для сбора данных по объектам схем разных баз кластера.
Короче, надо больше подробностей.
Добрый день. Тогда подробности по пунктам:
CREATE SERVER if not exists server_name FOREIGN DATA WRAPPER dblink_fdw OPTIONS (hostaddr '%s', dbname '%s', port '%s')
). Он, цитируя доки, "can have the same options that libpq accepts in connection strings" за исключением нескольких полей, которые уже хранятся в маппинге конкретного пользователя (см. подробнее). Т.е. это почти полный эквивалент строки подключения для dblink, но, при использовании через суперпользователя, это позволяет хранить пароли не в базе, а в файле .pgpass, куда он полезет, если не увидит пароля в маппинге пользователя.
Если же речь про то, что профайлу нужно вытаскивать имя базы, то можно дернуть их, опять же, из опций сервера
select
srvname as name,
srvoptions as options
from pg_foreign_server;
Готов ответить на любые дополнительные вопросы.
Мне создание такого функционала кажется вполне возможным, но я всё еще не вполне понимаю от какой угрозы вы пытаетесь защититься с её помощью.
Я правильно понимаю, что вы не можете исполнять снимки pg_profile от суперпользователя, но при этом хотите чтобы он мог работать без упоминания каких-либо паролей?
Что касается файла .pgpass, то dblink, по идее тоже должен уметь им пользоваться, другой вопрос, что этим же файлом сможет воспользоваться любой серверный процесс. По поводу fdw основной вопрос был в необходимости смены баз данных в ходе исполнения снимка. Поскольку в кластере может быть несколько баз данных, профайлу надо зайти в каждую для сбора статистик объектов, а FDW, насколько я знаю, прибит к конкретной базе.
На данный момент дополнение использует обычный dblink_connect, который требует пароль при использовании не от имени суперпользователя.
Рассматривался ли вариант с возможность обнаруживать наличие строго определенной SECURITY DEFINER функции, которая должна будет вызывать только dblink_connect с передаваемыми в нее аргументами соединения, а возвращать имя созданного подключения? Права суперпользователя нужны будут только для открытия соединения, после этого пользоваться им может любой пользователь. Это позволит использовать почти любые методы аутентификации, в том числе TLS.
Пользователь сможет создать такую функцию в схеме pg_profile под супером, выдав пользователю-владельцу pg_profile права на execute. Если функция не будет обнаружена, то использовать обычный вызов dblink_connect как сейчас.
Для безопасности можно также требовать, чтобы у функции был строго определенный код, проверять, например, через routine_definition из information_schema.routines.
Если реализация будет рассматриваться, то хотелось бы еще попросить поддержать указание параметров подключения в виде имени foreign server. Сейчас при попытке это сделать падает парсинг строки подключения из таблицы серверов, т.к. он ждет пару "ключ=значение," а при использовании имени сервера нужно только имя, т.е. "значение".