Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostgreSQL backend: make powerdns a database owner #173

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nixargh
Copy link

@nixargh nixargh commented Jan 10, 2025

Setup

  • Ubuntu 24.04
  • PostgreSQL 16

Why?

I faced permissions issue that leads to:

  • failed schema application
  • issuficient priviledges for further changes from powerdns

I've fixed it manually by doing these queries:

GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO powerdns;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO powerdns;

Then I diged dipper to find how to puppetize them and came to that solution (making powerdns user an owner of powerdns db).

If it looks dangerous it may be fixed by adding these resources:

  # Add some extra database priviledges that required by modern PostgreSQL.
  #
  postgresql::server::default_privileges { 'all-tables':
    role        => $powerdns::db_username,
    db          => $powerdns::db_name,
    privilege   => 'ALL',
    object_type => 'TABLES',
    schema      => 'public',
    require     => Class['postgresql::server'],
  }

  postgresql::server::default_privileges { 'all-sequences':
    role        => $powerdns::db_username,
    db          => $powerdns::db_name,
    privilege   => 'ALL',
    object_type => 'SEQUENCES',
    schema      => 'public',
    require     => Class['postgresql::server'],
  }

Details

pdns can't start:

systemd[1]: Starting pdns.service - PowerDNS Authoritative Server...
pdns_server[42858]: Loading '/usr/lib/x86_64-linux-gnu/pdns/libgpgsqlbackend.so'
pdns_server[42858]: This is a standalone pdns
pdns_server[42858]: Listening on controlsocket in '/run/pdns/pdns.controlsocket'
pdns_server[42858]: UDP server bound to 127.0.0.3:53
pdns_server[42858]: TCP server bound to 127.0.0.3:53
pdns_server[42858]: PowerDNS Authoritative Server 4.8.3 (C) 2001-2022 PowerDNS.COM BV
pdns_server[42858]: Using 64-bits mode. Built using gcc 13.2.0.
pdns_server[42858]: PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
pdns_server[42858]: [webserver] Listening for HTTP requests on 10.92.73.5:80
pdns_server[42858]: PDNSException while filling the zone cache: Database error trying to retrieve all domains:Fatal error during prePQpreparepare: select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check, domains.account from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=false OR $1: ERROR:  relation "domains" does not exist
pdns_server[42858]: LINE 1: ..._serial, domains.last_check, domains.account from domains LE...
pdns_server[42858]:                                                              ^
systemd[1]: pdns.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: pdns.service: Failed with result 'exit-code'.
systemd[1]: Failed to start pdns.service - PowerDNS Authoritative Server.

Because puppet keeps trying to load SQL with schema on every run:

Debug: Executing with uid=postgres gid=postgres: 'psql -t -X -c SELECT COUNT(*) FROM (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'domains') count'
Debug: /Stage[main]/Powerdns::Backends::Postgresql/Postgresql_psql[Load SQL schema]/unless: Found 0 row(s) executing 'unless' clause
Debug: Executing with uid=postgres gid=postgres: 'psql -t -X -c \i /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql'
Notice: /Stage[main]/Powerdns::Backends::Postgresql/Postgresql_psql[Load SQL schema]/command: command changed 'notrun' to '\i /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql' (corrective)

But it can't as I can see:

~# sudo -u postgres psql -t -X -c "SELECT COUNT(*) FROM (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'domains') count;"
     0

Trying to load schema dump manually from powerdns user:

~# psql -h localhost -U powerdns -W powerdns -t -X -c "\i /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql"
Password:
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:12: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE domains (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:14: ERROR:  relation "domains" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:15: ERROR:  relation "domains" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:33: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE records (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:35: ERROR:  relation "records" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:36: ERROR:  relation "records" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:37: ERROR:  relation "records" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:38: ERROR:  relation "records" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:46: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE supermasters (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:61: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE comments (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:63: ERROR:  relation "comments" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:64: ERROR:  relation "comments" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:65: ERROR:  relation "comments" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:73: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE domainmetadata (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:75: ERROR:  relation "domainmetadata" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:85: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE cryptokeys (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:87: ERROR:  relation "cryptokeys" does not exist
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:96: ERROR:  permission denied for schema public
LINE 1: CREATE TABLE tsigkeys (
                     ^
psql:/usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql:98: ERROR:  relation "tsigkeys" does not exist

OK, now I do the same as postgres user and it works:

~# sudo -u postgres psql powerdns -t -X -c "\i /usr/share/doc/pdns-backend-pgsql/schema.pgsql.sql"
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TABLE
CREATE TABLE
CREATE INDEX
CREATE INDEX
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX
CREATE TABLE
CREATE INDEX

But pdns can't start again because of insufficient priviledges:

systemd[1]: Starting pdns.service - PowerDNS Authoritative Server...
pdns_server[46499]: Loading '/usr/lib/x86_64-linux-gnu/pdns/libgpgsqlbackend.so'
pdns_server[46499]: This is a standalone pdns
pdns_server[46499]: Listening on controlsocket in '/run/pdns/pdns.controlsocket'
pdns_server[46499]: UDP server bound to 127.0.0.3:53
pdns_server[46499]: TCP server bound to 127.0.0.3:53
pdns_server[46499]: PowerDNS Authoritative Server 4.8.3 (C) 2001-2022 PowerDNS.COM BV
pdns_server[46499]: Using 64-bits mode. Built using gcc 13.2.0.
pdns_server[46499]: PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
pdns_server[46499]: [webserver] Listening for HTTP requests on 10.92.73.5:80
pdns_server[46499]: PDNSException while filling the zone cache: Database error trying to retrieve all domains:Fatal error during query: select domains.id, domains.name, records.content, domains.type, domains.master, domains.notified_serial, domains.last_check, domains.account from domains LEFT JOIN records ON records.domain_id=domains.id AND records.type='SOA' AND records.name=domains.name WHERE records.disabled=false OR $1: ERROR:  permission denied for table domains
systemd[1]: pdns.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: pdns.service: Failed with result 'exit-code'.
systemd[1]: Failed to start pdns.service - PowerDNS Authoritative Server.

I'm not a PostgreSQL ninja but I duckduckgo'ed a solution that I mentioned above and look like it's somethin new at PostgreSQL 16 or so. Making powerdns user an owner of database works as well.

@ju5t
Copy link
Collaborator

ju5t commented Jan 11, 2025

I cannot tell if this would be dangerous or not as I don't know enough about PostgreSQL. I do think it would be helpful to include the error messages in this PR if you can.

@brigriffin not sure if you're still around but if you can, could you have a look at this?

@nixargh
Copy link
Author

nixargh commented Jan 12, 2025

I cannot tell if this would be dangerous or not as I don't know enough about PostgreSQL. I do think it would be helpful to include the error messages in this PR if you can.

You are right, I've updated my post with details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants