通过 pg_hba.conf 文件之外的 IP 地址限制 Postgres 角色

Bra*_*rth 7 mysql postgresql permissions

我目前正在向目前仅支持 MySQL 的部署工具添加 Postgres 支持。该工具动态提供和配置数据库等。

在 MySQL 中,我们可以使用 SQL 将用户限制为一组特定的 IP 地址,作为授权命令的一部分,如下所示:

GRANT ALL PRIVILEGES ON my_database_name.* TO 'my_user_name'@'192.168.101.%' IDENTIFIED BY 'my_secret_password'
GRANT ALL PRIVILEGES ON my_database_name.* TO 'my_user_name'@'internal.example.com' IDENTIFIED BY 'my_secret_password'
Run Code Online (Sandbox Code Playgroud)

在 Postgres 中,似乎设置类似安排的唯一方法是首先无限制地创建用户:

CREATE USER "my_user_name" WITH PASSWORD 'my_secret_password'
Run Code Online (Sandbox Code Playgroud)

我已经整理出如何以编程方式将此角色限制到特定数据库,但似乎通过主机限制 Postgres 用户的唯一方法是在 pg_hba.conf 文件中创建条目。

这是有问题的,因为没有文件系统访问权限的代理以编程方式创建了许多用户/主机。

看起来我们围绕这个的唯一三个选择是:

  1. 在使用 SQL 创建角色后,不使用 SQL 来操作 pg_hba.conf 来限制角色
  2. 对于允许的主机,允许“所有”,而不是特定用户
  3. 仅限制对 localhost 的访问,并使用 ssh 隧道进行连接

这似乎不太理想,让我怀疑我是否忽略了一个明显的解决方案。是否可以仅使用 SQL 命令通过 IP 地址限制 Postgres 角色?

3ma*_*uek 5

PostgreSQL 中的本机 SQL 无法做到这一点。此外,Postgres 管理权限和访问的方式与 MySQL 非常不同。

我构建了一个非常基本的函数(需要大量调整和解决方法,特别是当用户已经存在时的处理程序),它直接将用户添加到 pg_hba 文件中,创建用户并授予对数据库的访问权限。

CREATE OR REPLACE FUNCTION addRemoteUser(
  username text,
  iptarget text DEFAULT '0.0.0.0/0',
  dbtarget text DEFAULT 'all',
  passtext text DEFAULT 'CHANGEME',
  methodauth text DEFAULT 'md5')
  RETURNS boolean
AS $$
  import os
  hbaLine = "host " + str(dbtarget) + "\t" + str(username) + "\t" + str(iptarget) + "\t" + str(methodauth)
  createuser = "CREATE USER " + str(username) + " WITH PASSWORD '" + str(passtext) + "'"
  grantuser = "GRANT connect ON DATABASE " + str(dbtarget) + " TO " + str(username)
  hbaFilePath = plpy.execute("select setting from pg_settings where name = 'hba_file'", 1)
  hs = open(hbaFilePath[0]['setting'],"a")
  hs.write(hbaLine + "\n")
  addUserCommand = plpy.execute(createuser, 1)
  grantUserCommand = plpy.execute(grantuser, 1)
  reload = plpy.execute("select pg_reload_conf()", 1)
  hs.close()
  return True
$$ LANGUAGE plpythonu;
Run Code Online (Sandbox Code Playgroud)

(也发布GitHub 上。)

显然还没有用于生产,但至少您可以大致了解如何构建该功能来实现这一点。对于这个特定示例,数据库需要 PL/Python。

我知道这对于这种特殊情况来说并不理想,但我认为这是一个关于如何扩展 Postgres 安装的有效示例。

然后,一旦函数编译完成,就可以使用 SQL 来调用该函数:

SELECT addRemoteUser('mynewuser');