Migrating from Opera DNS UI¶
Opera DNS UI (dns-ui) is a PHP interface for PowerDNS with LDAP login, per-zone access levels and a change review workflow. It talks to PowerDNS only over the HTTP API and keeps users, access and history in its own PostgreSQL database. See Migrating from Other Tools for the general approach.
There is no import tool. This page describes a manual migration. Try it on a test copy first.
Note: Several steps rely on features added in Poweradmin 4.5.0 and 4.6.0, marked where they appear. See What's New for which versions are released.
What Carries Over¶
Records live in PowerDNS. Point Poweradmin at the same PowerDNS and the zones are there. So are the RRset comments
dns-ui writes, because it stores them in PowerDNS. Poweradmin hides record comments by default; set
interface.show_record_comments to true to show them.
| Stays in PowerDNS | Must be recreated in Poweradmin |
|---|---|
| Zones and records | Users (or created on first LDAP login) |
| RRset comments | Global admin flag |
| DNSSEC keys and zone metadata | Per-zone access (administrator, operator) |
The zone "classification", in the account field |
Pending change requests |
| SOA and NS templates | |
Settings in config/config.ini |
The change log and its change comments are not migrated. dns-ui stores each change as a serialized PHP object, which no other tool can read. Keep the dns-ui database if you need the history.
Before You Start¶
Export the worklist from the dns-ui database (PostgreSQL):
-- users, with the global admin and active flags
SELECT uid, name, email, auth_realm, admin, active
FROM "user"
ORDER BY uid;
-- per-zone access; global admins see every zone without a row here
SELECT rtrim(z.name, '.') AS zone, u.uid, za.level::text AS level
FROM zone_access za
JOIN zone z ON z.id = za.zone_id
JOIN "user" u ON u.id = za.user_id
WHERE z.active
ORDER BY z.name, u.uid;
-- change requests still waiting for review
SELECT rtrim(z.name, '.') AS zone, u.uid AS requested_by, p.request_date
FROM pending_update p
JOIN zone z ON z.id = p.zone_id
LEFT JOIN "user" u ON u.id = p.author_id
ORDER BY p.request_date;
Review or reject the pending requests in dns-ui before you switch. They cannot be moved.
Also write down the [ldap] section of config/config.ini, and which scripts call the dns-ui API. Back up the
PowerDNS database and the dns-ui database.
Steps¶
1. Install Poweradmin¶
Pick a method from the Installation section. Poweradmin creates its own tables for users, groups and permissions. Do not point it at the dns-ui database.
2. Connect It to the Same PowerDNS¶
dns-ui uses only the PowerDNS API, with [powerdns] api_url and api_key. Poweradmin can do the same in API
backend mode: set dns.backend to api, plus pdns_api.url and pdns_api.key. pdns_api.url is the server
address alone, for example http://localhost:8081, not the full /api/v1/servers/localhost path dns-ui uses.
Some features are limited in this mode, see
API Backend Mode.
If Poweradmin can reach the PowerDNS database, SQL mode (the default) has the full feature set. See PowerDNS API for both modes.
Sign in as the administrator and open the zone list. You should see the existing zones.
3. Set Up Login¶
dns-ui never checks a password itself. The web server authenticates the user, usually against LDAP, and dns-ui
reads the username from REMOTE_USER. Poweradmin does not accept a login from the web server. It authenticates
against LDAP itself, see LDAP Integration.
Take the values from dns-ui's [ldap] section:
dns-ui [ldap] |
Poweradmin ldap |
|---|---|
host |
uri. There is no StartTLS setting; use an ldaps:// URI |
bind_dn, bind_password |
bind_dn, bind_password |
dn_user |
base_dn |
user_id |
user_attribute |
user_name, user_email |
fullname_attribute, email_attribute with sync_user_info |
dn_group, group_member |
groups_attribute, usually memberOf; Poweradmin reads the groups from the user entry |
admin_group_cn |
An entry in permission_template_mapping, plus allow_superuser_provisioning |
dns-ui creates a user on first login. Poweradmin does the same with auto_provision on (since 4.5.0, like the group
mappings below). Use search_filter to
limit login to the people who used dns-ui, see
Granting access to an Active Directory group.
dns-ui finds the admin group by its CN. Poweradmin's permission_template_mapping and group_mapping match the
value of groups_attribute exactly, which for memberOf is the full DN of the group, not its CN. On OpenLDAP,
memberOf needs the overlay enabled. A mapping that grants user_is_ueberuser takes effect only with
ldap.allow_superuser_provisioning set to true.
dns-ui's user_active attribute has no equivalent. Disable departed users in Poweradmin, or exclude them with
search_filter.
Two-factor login is off by default, set security.mfa.enabled to offer it, see MFA.
4. Recreate Access Levels¶
dns-ui has a global admin flag and two levels per zone:
- administrator: edits the zone directly and reviews change requests for it.
- operator: requests changes, which a zone administrator approves.
Poweradmin has the same review step since 4.6.0, see Change Requests. Turn it
on with approval.enabled. dns-ui's [web] force_change_review corresponds to approval.require_review_for_all, and
force_change_comment to logging.require_change_comment.
Poweradmin permissions come from permission templates, on the user and on each group the user belongs to. A user's rights are the combination of all of them, and an "own" right covers every zone the user owns, directly or through any group. Levels per zone therefore work through groups as long as each user holds one level:
- Create two group templates:
- "Zone administrator":
zone_content_view_own,zone_content_edit_own,zone_meta_edit_ownandzone_change_approve_own. - "Zone operator":
zone_content_view_ownandzone_change_request_own.
- "Zone administrator":
- For each team, create one group with each template, for example "web-admins" and "web-operators".
- Add the users to the groups, and give each group the zones from your
zone_accessexport. On a group's zones page you can move several zones at once.
A user who is an administrator of some zones and an operator of others gets both templates, so they edit all of
their zones directly. Review such users in the zone_access export before you start. Turning on
approval.require_review_for_all sends everyone's changes through review instead.
Global admins map to users with the user_is_ueberuser permission, through permission_template_mapping and
allow_superuser_provisioning in the LDAP settings. Give everyone else a personal template with few rights, since
their zone rights come from groups. If your LDAP groups match the teams, group_mapping keeps group membership in
step with the directory.
Only global admins may change SOA and NS records in dns-ui. In Poweradmin, editing the SOA record needs
zone_content_edit_others, so the "Zone administrator" template above cannot change it. NS records can be edited
by anyone who may edit the zone, unless their template uses zone_content_edit_own_as_client.
For a large number of zones, script the assignment with /api/v2/groups/{id}/zones, see the
API Reference.
5. Recreate Templates¶
dns-ui's SOA and NS templates fill in the zone creation form. In Poweradmin the defaults for new zones are the
dns.hostmaster, dns.ns1 to dns.ns4 and dns.soa_* settings, see
DNS Settings. For more than one set, create
DNS templates.
6. Optional Features¶
- Notifications. dns-ui mails the SOA contact and the zone administrators when a change is requested.
Poweradmin mails every user who may review the request, and the SOA contact with
notifications.change_request_soa_contact. Mail is off by default, see Notifications. - Zone deletion. dns-ui needs a second admin to confirm a deletion. In Poweradmin a deletion goes through review
only for users who request changes instead of editing directly, or for everyone with
approval.require_review_for_all. A reviewer may approve their own request. - Reverse records. dns-ui adds a PTR for each new A or AAAA record. Poweradmin offers the same as a checkbox
when
interface.add_reverse_recordis on (the default). - Classification. dns-ui shows the PowerDNS
accountfield as a free-text "classification". Poweradmin does not show it. Two settings use it, both off by default; leave them off to keep the classifications:dns.adopt_zone_owner_from_accountgives a zone whose classification matches a username to that user, anddns.sync_zone_owner_to_accountoverwrites the field with the zone owner's username. - DNSSEC. dns-ui only turns signing on and off. Poweradmin also manages keys; it is off by default, set
dnssec.enabled. Existing keys stay in PowerDNS. See DNSSEC. - Import and export. Both tools import and export BIND zone files, see Zone Import/Export.
7. Replace Scripts¶
dns-ui's API also lives under /api/v2, but it is a different API. It authenticates through the web server and
takes a list of actions in one PATCH. Poweradmin's API authenticates with an API key in the X-API-Key header
and has separate endpoints for zones and records. Rewrite scripts against API Overview and
API Authentication. Enable the API with api.enabled.
8. Switch Over¶
- Ask a few users from each team to sign in and check that they see their zones and can do what their level allowed before.
- Stop making changes in dns-ui. Both tools write to PowerDNS, so a record changed in one shows up in the other. dns-ui logs nothing for changes made elsewhere, and Poweradmin logs nothing for changes made in dns-ui.
- Turn off dns-ui's
scripts/ldap_update.phpcron job and the git-tracked export, if you used them. - Keep the dns-ui database for its change history, then shut dns-ui down.
Concept Mapping¶
| Opera DNS UI | Poweradmin |
|---|---|
Web server login (REMOTE_USER) |
LDAP, OIDC or SAML login in Poweradmin |
| User created on first login | LDAP auto_provision (4.5.0+) |
admin_group_cn |
permission_template_mapping to a template with user_is_ueberuser |
| Zone access: administrator | Group with an edit and approve template, owning the zone |
| Zone access: operator | Group with a request-only template, owning the zone |
| Pending change request | Change request, approval.enabled (4.6.0+) |
force_change_review |
approval.require_review_for_all |
force_change_comment |
logging.require_change_comment |
| RRset comment | Record comment, interface.show_record_comments |
| Change log | Record change log, not migrated |
| SOA and NS templates | dns.* defaults and DNS templates |
Classification (account) |
Kept in PowerDNS, not used by Poweradmin |
| Git-tracked export | No equivalent |
/api/v2 with web server login |
REST API /api/v2 with API keys |