PostgreSQL RDS 在使用 dblink_connect() 时避免硬编码连接密码
PostgreSQL RDS avoid hard coding the connection password when using dblink_connect()
我有一个 PostgreSQL 的 AWS RDS 实例,我需要在使用 dblink_connect(text)
和 dblink_exec(text)
的函数中执行 SQL
语句] 角色(我创建的)。
CREATE OR REPLACE FUNCTION application.create_tenant_schemas(first integer, last integer) RETURNS void AS
DECLARE
tenant VARCHAR;
sql VARCHAR;
BEGIN
FOR index IN first..last LOOP
tenant := 'tenant_' || to_char(index, 'FM00000');
sql := 'CREATE SCHEMA ' || quote_ident(tenant);
RAISE NOTICE '%', sql;
PERFORM dblink_connect('dbname=application user=postgres');
PERFORM dblink_exec(sql);
PERFORM dblink_disconnect();
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
dblink_exec()
正在生成以下错误消息:
[2F003] ERROR: password is required
Detail: Non-superusers must provide a password in the connection string.
Where: SQL statement "SELECT dblink_connect('dbname=application user=postgres')"
我发现一个 answer 建议使用 dblink_connect_u(text)
。当我尝试这样做时,我收到以下错误消息:
[42501] ERROR: permission denied for function dblink_connect_u
Where: SQL statement "SELECT dblink_connect_u('dbname=application user=postgres')"
在 AWS 上,如何授予创建 RDS 实例的用户执行函数 dblink_connect_u()
的权限?我尝试了以下但没有成功:
GRANT EXECUTE ON FUNCTION dblink_connect_u(text) TO postgres;
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO postgres;
我的 postgres
用户似乎需要 superuser
权限,而我显然无法在 AWS 上获得这些权限。
我也尝试过使用 %APPDATA%\postgresql\pgpass.conf
(在 Windows 上)为 dblink_connect(text)
提供密码,但 dblink_connect(text)
显然忽略了这个文件。
我能够使用硬编码的密码字符串来调用 dblink_connect(text)
,如下所示:
PERFORM "pascal"."dblink_connect_u"('dbname=pascal user=postgres password=secret');
...最终,由于密码的硬编码,这不是一个可接受的解决方案。
有没有人对如何让 RDS PostgreSQL 使用密码文件或允许我GRANT EXECUTE ON FUNCTION dblink_connect_u(text)
有什么建议,或者还有其他我没有遇到过的选择吗?
更新
PostgreSQL 文档的链接,用于尝试设置外部数据包装器/服务器,用于存储正在执行 dblink_connect(text)
的用户的密码
结论
CREATE SERVER "password_server" FOREIGN DATA WRAPPER "dblink_fdw"
OPTIONS (dbname 'application');
CREATE USER MAPPING FOR "postgres"
SERVER "password_server"
OPTIONS (user 'postgres', password 'pa55VV0&d');
...不同的源文件...
CREATE OR REPLACE FUNCTION application.create_tenant_schemas(first integer, last integer) RETURNS VOID AS $$
DECLARE
tenant VARCHAR;
sql VARCHAR;
BEGIN
FOR index IN first..last LOOP
tenant := 'tenant_' || to_char(index, 'FM00000');
sql := 'CREATE SCHEMA ' || quote_ident(tenant);
RAISE NOTICE '%', sql;
PERFORM "dblink_connect"('password_server');
PERFORM "dblink_exec"(sql);
PERFORM "dblink_disconnect"();
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
您可以创建用户映射:
create server application_srv foreign data wrapper dblink_fdw OPTIONS (...
;
create user mapping FOR app_user SERVER application_srv OPTIONS (user 'user_to_connect', password 'password goes here');
- 在 dblink 连接名称中使用
application_srv
:
.
t# select * from dblink('application_srv','select max(t) from t') as t(m timestamp(0));
m
---------------------
2017-06-13 11:41:05
(1 row)
现在密码将在pg_user_mappings
中显示为纯文本(pg_user_mapping
应该对RDS中的任何人都不能选择),但实际密码将仅显示给rds_superuser
我有一个 PostgreSQL 的 AWS RDS 实例,我需要在使用 dblink_connect(text)
和 dblink_exec(text)
的函数中执行 SQL
语句] 角色(我创建的)。
CREATE OR REPLACE FUNCTION application.create_tenant_schemas(first integer, last integer) RETURNS void AS
DECLARE
tenant VARCHAR;
sql VARCHAR;
BEGIN
FOR index IN first..last LOOP
tenant := 'tenant_' || to_char(index, 'FM00000');
sql := 'CREATE SCHEMA ' || quote_ident(tenant);
RAISE NOTICE '%', sql;
PERFORM dblink_connect('dbname=application user=postgres');
PERFORM dblink_exec(sql);
PERFORM dblink_disconnect();
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
dblink_exec()
正在生成以下错误消息:
[2F003] ERROR: password is required
Detail: Non-superusers must provide a password in the connection string.
Where: SQL statement "SELECT dblink_connect('dbname=application user=postgres')"
我发现一个 answer 建议使用 dblink_connect_u(text)
。当我尝试这样做时,我收到以下错误消息:
[42501] ERROR: permission denied for function dblink_connect_u
Where: SQL statement "SELECT dblink_connect_u('dbname=application user=postgres')"
在 AWS 上,如何授予创建 RDS 实例的用户执行函数 dblink_connect_u()
的权限?我尝试了以下但没有成功:
GRANT EXECUTE ON FUNCTION dblink_connect_u(text) TO postgres;
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO postgres;
我的 postgres
用户似乎需要 superuser
权限,而我显然无法在 AWS 上获得这些权限。
我也尝试过使用 %APPDATA%\postgresql\pgpass.conf
(在 Windows 上)为 dblink_connect(text)
提供密码,但 dblink_connect(text)
显然忽略了这个文件。
我能够使用硬编码的密码字符串来调用 dblink_connect(text)
,如下所示:
PERFORM "pascal"."dblink_connect_u"('dbname=pascal user=postgres password=secret');
...最终,由于密码的硬编码,这不是一个可接受的解决方案。
有没有人对如何让 RDS PostgreSQL 使用密码文件或允许我GRANT EXECUTE ON FUNCTION dblink_connect_u(text)
有什么建议,或者还有其他我没有遇到过的选择吗?
更新
PostgreSQL 文档的链接,用于尝试设置外部数据包装器/服务器,用于存储正在执行 dblink_connect(text)
结论
CREATE SERVER "password_server" FOREIGN DATA WRAPPER "dblink_fdw"
OPTIONS (dbname 'application');
CREATE USER MAPPING FOR "postgres"
SERVER "password_server"
OPTIONS (user 'postgres', password 'pa55VV0&d');
...不同的源文件...
CREATE OR REPLACE FUNCTION application.create_tenant_schemas(first integer, last integer) RETURNS VOID AS $$
DECLARE
tenant VARCHAR;
sql VARCHAR;
BEGIN
FOR index IN first..last LOOP
tenant := 'tenant_' || to_char(index, 'FM00000');
sql := 'CREATE SCHEMA ' || quote_ident(tenant);
RAISE NOTICE '%', sql;
PERFORM "dblink_connect"('password_server');
PERFORM "dblink_exec"(sql);
PERFORM "dblink_disconnect"();
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
您可以创建用户映射:
create server application_srv foreign data wrapper dblink_fdw OPTIONS (...
;create user mapping FOR app_user SERVER application_srv OPTIONS (user 'user_to_connect', password 'password goes here');
- 在 dblink 连接名称中使用
application_srv
:
.
t# select * from dblink('application_srv','select max(t) from t') as t(m timestamp(0));
m
---------------------
2017-06-13 11:41:05
(1 row)
现在密码将在pg_user_mappings
中显示为纯文本(pg_user_mapping
应该对RDS中的任何人都不能选择),但实际密码将仅显示给rds_superuser