暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

修复没有超级用户的 PostgreSQL 集群

原创 小小亮 2022-10-18
1006

通常在新创建的 PostgreSQL 数据库集群中,有一个具有“超级用户”权限的全能管理角色(用户),通常命名为postgres,尽管它可以有任何名称。

在初始集群设置之后,您可以根据需要创建其他角色。您可以选择授予一个或多个新角色超级用户权限,但最好避免将超级用户授予任何其他角色,因为您和您的应用程序通常应作为具有较低权限的角色连接,以减少意外或恶意损坏的风险你的数据库。

让我们打破一些东西😎

假设您有一个具有两个或多个超级用户角色的集群。如果您不小心从一个角色中删除了超级用户权限,您可以简单地以另一个超级用户身份连接并重新授予它。

但是,如果您有一个集群,其中只有一个postgres角色是超级用户,如果您以该角色连接并尝试删除其超级用户权限会发生什么?

$ psql -U postgres postgres
psql (14.1)
Type "help" for help.

postgres=# \du
                       List of roles
 Role name |            Attributes             | Member of
-----------+-----------------------------------+-----------
 postgres  | Superuser, Create role, Create DB | {}
 somebody  | Create DB                         | {}

postgres=> \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/tmp" at port "5432".
postgres=# ALTER ROLE postgres NOSUPERUSER;
ALTER ROLE
postgres=# \du
                 List of roles
 Role name |       Attributes       | Member of
-----------+------------------------+-----------
 postgres  | Create role, Create DB | {}
 somebody  | Create DB              | {}

postgres=# ALTER ROLE postgres SUPERUSER;
ERROR:  must be superuser to alter superuser roles or change superuser attribute
postgres=# \q

PostgreSQL 很乐意让我们这样做,现在我们没有超级用户,因此我们不能重新授予该角色或任何其他角色的权限!

自制 PostgreSQL 问题

除了如此严重的操作员错误之外,在其他情况下您可能会发现不存在超级用户。我最近在尝试使用 Homebrew 在 macOS 上安装的 PostgreSQL 时发生了一件事情。

我使用 Homebrew 进行安装postgresql@14,后来注意到它给我留下了一个以我的操作系统用户命名的角色,而且它不是超级用户。它甚至无法创建其他角色。我不确定这是怎么发生的,可能是由于postgresql在同一台计算机上的早期安装造成的,但事实就是如此。

由于那里还没有任何数据,我可以简单地删除现有的 PostgreSQL 集群并创建一个新集群。但在其他情况下,那里可能有我需要保留的数据,我的一个权限较低的用户无法访问这些数据,并导致pg_dumpall.

那么我们怎样才能以正确的方式解决这个问题呢?

一、停止服务器

我们需要获得对我们数据库的较低级别的访问权限。为此,首先我们停止正在运行的数据库服务器。

在运行 systemd 的典型现代 Linux 服务器上,如下所示:

# systemctl stop postgresql-14

在使用 Homebrew 服务的 macOS 上,可能是:

$ brew services stop postgresql

或者在我使用 Homebrew 的实验案例中,使用我在这里展示的临时 Postgres 服务器:

$ pg_ctl -D /opt/homebrew/var/postgresql@14 stop
waiting for server to shut down.... done
server stopped

接下来,启动 PostgreSQL 单机后端

接下来,我们启动“独立后端”,单个用户可以直接与之交互,而不是使用单独的客户端。

这里没有进行权限检查,因此我们可以将超级用户权限重新授予我们的postgres角色。

有趣的是,这里输入的 SQL 语句以换行符结尾,;不需要,尽管添加一个也没有什么坏处。并且这里的语句不能跨越多行而不\在每个中间行的末尾继续。

在下面的命令中,注意--single选项必须先出现,postgres命令末尾的是我们要连接的数据库的名称:

$ postgres --single -D /opt/homebrew/var/postgresql@14 postgres

PostgreSQL stand-alone backend 14.1
backend> ALTER ROLE postgres SUPERUSER
2022-01-07 20:32:51.321 MST [27246] LOG:  statement: ALTER ROLE postgres SUPERUSER

2022-01-07 20:32:51.322 MST [27246] LOG:  duration: 1.242 ms
backend>

postgres服务器独立提示没有psql包括行编辑功能、历史记录和反斜杠元命令(例如退出)的所有细节\q,因此我们在此处键入 control-D 以在输入流上标记“文件结尾”并退出程序.

恢复正常

现在我们可以再次启动普通的多用户客户端/服务器 PostgreSQL 服务:

$ pg_ctl -D /opt/homebrew/var/postgresql@14 start
waiting for server to start.... done
server started

最后我们可以连接到服务器并确认我们的更改仍然存在:

$ psql -U postgres postgres
psql (14.1)
Type "help" for help.

postgres=# \du
                       List of roles
 Role name |            Attributes             | Member of
-----------+-----------------------------------+-----------
 postgres  | Superuser, Create role, Create DB | {}
 somebody  | Create DB                         | {}

postgres=#



原文标题:Fixing a PostgreSQL cluster that has no superuser

原文作者:Josh Tolley

原文链接:https://www.endpointdev.com/blog/2022/01/postgresql-no-superuser-fix/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论