Installing PowerDNS with PowerDNS-Admin on Debian 12
What is PowerDNS and How Can I Harness this Power
PowerDNS is a powerful, flexible authoritative DNS server that can be used to manage your domain’s DNS records programmatically. But sometimes you dont want to look at text and use a GUI instead. PowerDNS can be paired paired with PowerDNS-Admin, so you get a modern web interface for your DNS management.
In this write-up, we’ll walk through installing both PowerDNS and PowerDNS-Admin on Debian 12 (Bookworm). We’ll be using MariaDB to provide a database for both these services.
Proxmox’s new SDN uses PowerDNS for it’s DNS features, and so a PowerDNS LXC should be standard on most Proxmox multi-client/doamin setups.
And that’s what we’re doing today! By the end of this write-up, you’ll have a fully functional DNS server with a web-based management interface, complete with API access for Proxmox SDN’s DNS automation.
What Does This Write Up Talk About
- PowerDNS Authoritative Server: A local DNS server, NOT one that does global lookups on the internet!
- MariaDB Database: Backend storage for DNS records and application data
- PowerDNS-Admin: A modern web interface for managing your DNS zones
- REST API: Programmatic access to your DNS infrastructure, essential for Proxmox SDN’s DNS automation with PowerDNS
- Multi-tenant Support: Ready for Proxmox multi-client and Proxmox multi-domain deployments
🏁 Speedrun This Process with a Script
If like to download scripts from the internet - you’re in luck!
I have, at the bottom of this post, a - 🎚️ PowerDNS EZ-MODE script.
This script will complete the entire write-up for you! Just be sure to change the config variables first.
Please continue on to go through the steps of setting up PowerDNS to use MariaDB, then PowerDNS-Admin.
Part 1: System Preparation and MariaDB Installation
Step 1: Update Your System
Let’s start by ensuring your system is up to date:
1
apt update && apt upgrade -y
Step 2: Install Essential Dependencies
Install the core packages we’ll need throughout this process:
1
apt install -y sudo curl git libpq-dev software-properties-common gnupg2
Step 3: Install MariaDB
MariaDB will serve as the database backend for both PowerDNS (storing DNS records for your Proxmox multi-domain environments) and PowerDNS-Admin (storing users and settings).
First, download and install the official MariaDB repository setup script:
1
curl -LsS -o mariadb_repo_setup https://downloads.mariadb.com/MariaDB/mariadb_repo_setup && echo "$(curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup.sha256)" > mariadb_repo_setup.sha256 && sha256sum -c mariadb_repo_setup.sha256 && sudo bash mariadb_repo_setup && rm mariadb_repo_setup mariadb_repo_setup.sha256
Now install MariaDB server and client:
1
sudo apt update && sudo apt install -y mariadb-server mariadb-client
Start and enable the MariaDB service to run on boot:
1
sudo systemctl enable --now mariadb
Step 4: Secure Your MariaDB Installation
For new MariaDB installations, the next step is to run a security script. This script changes some of the less secure default options for things like remote root logins and sample users.
Optionally, run the security script to improve your database security posture:
1
sudo mysql_secure_installation
I answered, no
to the first two, defaults for everything else.
I used the following answers:
1
2
3
4
5
6
Switch to unix_socket authentication [Y/n] n
Change the root password? [Y/n] n
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y
Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y
Step 5: Create Database and User
Now we’ll create the databases and user account that PowerDNS and PowerDNS-Admin will use.
Important Note: Avoid special characters in the password, as PowerDNS has been known to have issues with certain special characters, which can result in authentication errors: “Access denied for user ‘powerdns_user’@’localhost’ (using password: YES)“
For this guide, we’ll use:
- Username:
powerdnsmariaccessuser
- Password:
MikeJohnsonLikes9091Hamburgers
- PowerDNS Database:
powerdns
- PowerDNS-Admin Database:
powerdnsadmin
Log into MariaDB as root:
1
sudo mysql -u root
Execute the following SQL commands:
1
2
3
4
5
6
7
8
9
CREATE DATABASE powerdns;
CREATE DATABASE powerdnsadmin;
CREATE USER 'powerdnsmariaccessuser'@'localhost' IDENTIFIED BY 'MikeJohnsonLikes9091Hamburgers';
GRANT ALL PRIVILEGES ON *.* TO 'powerdnsmariaccessuser'@'localhost';
FLUSH PRIVILEGES;
EXIT
Part 2: Installing PowerDNS
Step 6: Add the PowerDNS Repository
To get the latest version of PowerDNS (version 5.0 as of writing), we’ll add the official PowerDNS repository. This ensures we’re running the most current and secure version: https://doc.powerdns.com/authoritative/installation.html
You have to install their repository:
https://repo.powerdns.com/
Create the repository configuration:
1
2
3
printf "deb [signed-by=/etc/apt/keyrings/auth-50-pub.asc] http://repo.powerdns.com/debian bookworm-auth-50 main" > /etc/apt/sources.list.d/pdns.list
printf "Package: pdns-*\nPin: origin repo.powerdns.com\nPin-Priority: 600" > /etc/apt/preferences.d/auth-50
Add the GPG key and install PowerDNS:
1
2
3
4
sudo install -d /etc/apt/keyrings; curl https://repo.powerdns.com/FD380FBB-pub.asc | sudo tee /etc/apt/keyrings/auth-50-pub.asc &&
sudo apt-get update &&
sudo apt-get install pdns-server
Step 7: Verify PowerDNS is Running
Verify the port 53 is open for PowerDNS to provide DNS:
1
sudo ss -alnp4 | grep pdns
You should see output showing PowerDNS listening on port 53.
Part 3: Configuring PowerDNS with MariaDB
Step 8: Install the MariaDB Backend
PowerDNS supports multiple database backends. Install the MariaDB/MySQL backend to enable an easy-to-backup database for your Proxmox multi-domain DNS zones:
1
sudo apt install pdns-backend-mysql
Step 9: Initialize the PowerDNS Database Schema
Import the database schema that PowerDNS needs to store DNS records:
1
2
3
mariadb --user=powerdnsmariaccessuser \
--password=MikeJohnsonLikes9091Hamburgers \
--database=powerdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql
Verify the schema was imported successfully:
1
2
3
4
sudo mysql -u root
use powerdns;
show tables;
exit
You should see several tables including domains
, records
, and cryptokeys
.
Step 10: Configure PowerDNS Database Connection
Create a configuration file that tells PowerDNS how to connect to MariaDB:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo bash -c 'cat <<EOF > /etc/powerdns/pdns.d/pdns.local.gmysql.conf
# MySQL Configuration
# Launch gmysql backend
launch+=gmysql
# gmysql parameters
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdnsmariaccessuser
gmysql-password=MikeJohnsonLikes9091Hamburgers
#gmysql-dnssec=yes
# gmysql-socket=
EOF'
Set the appropriate permissions on this configuration file:
1
2
sudo chown pdns: /etc/powerdns/pdns.d/pdns.local.gmysql.conf
sudo chmod 640 /etc/powerdns/pdns.d/pdns.local.gmysql.conf
Step 11: Test the Database Connection
Stop the PowerDNS service:
1
sudo systemctl stop pdns.service
Run PowerDNS in the foreground with verbose logging to verify the database connection:
1
sudo pdns_server --daemon=no --guardian=no --loglevel=9
You should see log output indicating a successful database connection. Press Ctrl+C
to stop the server.
If successful, restart PowerDNS as a service and enable it to start on boot:
1
sudo systemctl restart pdns && sudo systemctl enable --now pdns
Step 12: Verify PowerDNS is Working
Check that PowerDNS is responding to DNS queries:
1
dig @127.0.0.1
Part 4: Installing PowerDNS-Admin
PowerDNS-Admin is a web-based interface that makes managing your DNS server much easier, especially in Proxmox multi-client environments where multiple administrators need access. It’s built with Python Flask and requires Node.js for asset compilation.
Step 13: Install Python and Build Dependencies
Install the necessary packages for building alllllllll the Python libraries:
1
sudo apt install -y apt-transport-https build-essential curl git libffi-dev libldap2-dev libmariadb-dev libpq-dev libsasl2-dev libssl-dev libxml2-dev libxmlsec1-dev libxslt1-dev pkg-config python3-dev python3-flask python3-venv virtualenv
Step 14: Install Node.js
Add the NodeSource repository for Node.js 20.x to get npm:
1
curl -sL https://deb.nodesource.com/setup_20.x | sudo -E bash -
Install Node.js (npm is included automatically):
1
sudo apt install -y nodejs
Important: Do not install npm separately from Debian’s repositories—it’s outdated and broken. Always use NodeSource or nvm.
Verify the installation:
1
npm -v
Step 15: Install Yarn
Yarn is a package manager we’ll use to build the frontend assets:
1
2
3
4
5
6
7
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | \
sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | \
sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install -y yarn
Step 16: Clone and Set Up PowerDNS-Admin
Clone the PowerDNS-Admin repository:
1
2
git clone https://github.com/PowerDNS-Admin/PowerDNS-Admin.git /opt/web/powerdns-admin
cd /opt/web/powerdns-admin
Create a Python virtual environment:
1
python3 -m venv ./venv
Activate the virtual environment and install Python dependencies:
1
2
3
source ./venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
Step 17: Configure PowerDNS-Admin
Deactivate the virtual environment temporarily:
1
deactivate
Copy the development configuration to create a production config:
1
cp /opt/web/powerdns-admin/configs/development.py /opt/web/powerdns-admin/configs/production.py
Generate a secret key for Flask sessions:
1
python3 -c 'import secrets; print(secrets.token_hex())' 'ToddHowardLikes4126Turkeysammies'
Copy the output—you’ll need it in the next step.
Edit the production configuration:
1
nano /opt/web/powerdns-admin/configs/production.py
Find and update the database configuration section:
1
2
3
4
5
6
7
8
9
# Change from:
SQLA_DB_USER = 'pda'
SQLA_DB_PASSWORD = 'changeme'
SQLA_DB_NAME = 'pda'
# To:
SQLA_DB_USER = 'powerdnsmariaccessuser'
SQLA_DB_PASSWORD = 'MikeJohnsonLikes9091Hamburgers'
SQLA_DB_NAME = 'powerdnsadmin'
Scroll down to find the SQLite database URI section and update it:
1
2
3
4
5
# Comment out the SQLite line:
# SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')
# Add the MySQL connection string:
SQLALCHEMY_DATABASE_URI = 'mysql://powerdnsmariaccessuser:MikeJohnsonLikes9091Hamburgers@127.0.0.1/powerdnsadmin'
Also, add your generated secret key to the SECRET_KEY
variable in this file.
Save and close the file.
Step 18: Initialize the Application
Set up the Flask environment:
1
2
3
cd /opt/web/powerdns-admin
source ./venv/bin/activate
export FLASK_CONF=../configs/production.py
Run database migrations:
1
2
export FLASK_APP=powerdnsadmin/__init__.py
flask db upgrade
Generate frontend assets:
1
2
yarn install --pure-lockfile
flask assets build
Step 19: Test PowerDNS-Admin
You can now test the application:
1
./run.py
Visit http://your-server-ip:9191
in your web browser. You should see a registration page.
Important Notes:
- Disable any ad blockers or script blockers while accessing the interface
- On that page - you need to register your first user, that first user will automatically be granted Administrator rights.
- After registration, you’ll be redirected to the login page—this is normal. Yes, it worked. You got no afirmation of user creation, you just got re-directed back to the login page. Use your newly created credentials.
When testing is complete, press Ctrl+C
and deactivate the virtual environment:
1
deactivate
Part 5: Enabling the PowerDNS API
The PowerDNS API is crucial for API access for Proxmox SDN’s DNS automation with PowerDNS. This allows PowerDNS-Admin and Proxmox SDN to manage your DNS records programmatically, enabling seamless integration with your virtualization infrastructure.
Step 20: Generate an API Key
You can generate a secure API key at https://codepen.io/corenominal/pen/rxOmMJ or use any UUID generator.
For this guide, we’ll use: 135af146-c29c-4dd6-8608-14b3c0386ae9
Step 21: Configure the API
Edit the main PowerDNS configuration file:
1
sudo nano /etc/powerdns/pdns.conf
Add or uncomment these lines to enable API access for Proxmox SDN’s DNS automation with PowerDNS and PowerDNS-Admin:
1
2
3
4
5
6
7
8
9
#################################
# api Enable/disable the REST API (including HTTP listener)
#
api=yes
#################################
# api-key Static pre-shared authentication key for access to the REST API
#
api-key=135af146-c29c-4dd6-8608-14b3c0386ae9
Save the file and restart PowerDNS:
1
sudo systemctl restart pdns
Step 22: Clean Up Configuration Issues
Some PowerDNS configurations may contain invalid directives. Check your configuration directory:
1
cd /etc/powerdns/pdns.d/
If you have a bind.conf
file, edit it:
1
sudo nano bind.conf
Remove or comment out any lines except the first one (typically launch+=bind
). The bind-config
directive may not be valid in your version and should be removed.
Part 6: Creating a System Service
To be able to manage PowerDNS Admin just like other system services, we need to create a service file for it.
Step 23: Create the Service File
1
sudo nano /etc/systemd/system/pdnsadmin.service
Add the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Unit]
Description=PowerDNS-Admin
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/web/powerdns-admin
User=root
Group=root
# Environment variable for Flask config
Environment=FLASK_CONF=../configs/production.py
# Use the python interpreter inside your virtual environment
ExecStart=/opt/web/powerdns-admin/venv/bin/python /opt/web/powerdns-admin/run.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
Step 24: Create the Socket File
Also, create a socket file:
1
sudo nano /etc/systemd/system/pdnsadmin.socket
Add these lines:
1
2
3
4
5
6
7
8
[Unit]
Description=PowerDNS-Admin socket
[Socket]
ListenStream=/run/pdnsadmin/socket
[Install]
WantedBy=sockets.target
Step 25: Set Up Runtime Directory
Create the runtime directory and configure it to persist across reboots:
1
2
mkdir -p /run/pdnsadmin/
echo "d /run/pdnsadmin 0755 pdns pdns -" >> /etc/tmpfiles.d/pdnsadmin.conf
Step 26: Set Permissions
1
2
chown -R pdns: /run/pdnsadmin/
chown -R pdns: /opt/web/powerdns-admin
Step 27: Enable and Start the Service
Reload systemd to recognize the new service:
1
systemctl daemon-reload
Enable and start the PowerDNS-Admin service:
1
systemctl enable --now pdnsadmin.service pdnsadmin.socket
Check the service status:
1
systemctl status pdnsadmin.service pdnsadmin.socket
Part 7: Connecting PowerDNS-Admin to PowerDNS
Step 28: Configure the API Connection
- Log into the PowerDNS-Admin web interface at
http://your-server-ip:9191
- Navigate to the settings or configuration section
- Add your PowerDNS server with:
- API URL:
http://your-server-ip:8081
- API Key:
135af146-c29c-4dd6-8608-14b3c0386ae9
(the key from yourpdns.conf
)
- API URL:
Once connected, you’ll be able to create and manage DNS zones through the web interface!
Part 8: Integrating with Proxmox SDN
Since Proxmox SDN uses PowerDNS for its DNS features, your installation is now ready for Proxmox integration. Here’s how to leverage your PowerDNS setup with Proxmox VE:
Configuring Proxmox SDN DNS Integration
- In Proxmox VE, navigate to Datacenter → SDN → DNS
- Add DNS Server with these settings:
- Type: PowerDNS
- Server: Your PowerDNS server IP
- API URL:
http://your-powerdns-ip:8081
- API Key:
135af146-c29c-4dd6-8608-14b3c0386ae9
Benefits for Proxmox Multi-Client Environments
Your PowerDNS setup now enables:
- Automatic DNS record creation when VMs are deployed in Proxmox SDN zones
- Proxmox multi-client support through PowerDNS-Admin’s user management and role-based access control
- Centralized DNS management across multiple Proxmox clusters
- API-driven automation for infrastructure-as-code deployments
Benefits for Proxmox Multi-Domain Configurations
The database-backed PowerDNS installation provides:
- Multiple DNS zones for different departments or customers
- Domain delegation capabilities for Proxmox multi-domain setups
- Consistent DNS management across all your Proxmox environments
- Scalable architecture that grows with your infrastructure
And remember… if there’s any problems, it’s never the DNS.
🎚️ PowerDNS EZ-MODE script
But if you are having problems, just use the script below.
You need to make a few changes before running it:
PowerDNS and PowerDNS Admin with MariaDB Script Configuration Overview
Before running the script, update the variables below to match your environment:
Variable | Purpose | Example Value |
---|---|---|
DB_USER | Database username for PowerDNS & PowerDNS-Admin | powerdnsmariaccessuser |
DB_PASSWORD | Database password for the above user | TableSauceisnotRefrigerated1987 |
PDNS_DB_NAME | Database name used by PowerDNS | powerdns |
PDNSADMIN_DB_NAME | Database name used by PowerDNS-Admin | powerdnsadmin |
PDNS_API_KEY | Secret key for PowerDNS API | 135af146-c29c-4dd6-8608-14b3c0386ae9 |
PDNSADMIN_PATH | Installation path (no need to change) | /opt/web/powerdns-admin |
FLASK_SECRET_KEY | Secret for securing web sessions (ok if empty) | leave empty to auto-generate |
PowerDNS and PowerDNS Admin with MariaDB Script
Please be sure to make changes to the configuration variables below. Enjoy PowerDNS using MariaDB!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
#!/bin/bash
#############################################
# PowerDNS & PowerDNS-Admin Installation Script
# For Debian 12 (Bookworm)
#############################################
#############################################
# CONFIGURATION VARIABLES - EDIT THESE
#############################################
# Database Configuration
# Please change the DB_USER and DB_PASSWORD to something unique you can remember
DB_USER="powerdnsmariaccessuser"
DB_PASSWORD="MikeJohnsonLikes9091Hamburgers"
PDNS_DB_NAME="powerdns"
PDNSADMIN_DB_NAME="powerdnsadmin"
# PowerDNS API Configuration
# You can generate an API key at https://codepen.io/corenominal/pen/rxOmMJ
PDNS_API_KEY="135af146-c29c-4dd6-8608-14b3c0386ae9"
# PowerDNS-Admin Installation Path
PDNSADMIN_PATH="/opt/web/powerdns-admin"
# Flask Secret Key (auto-generated if left empty)
FLASK_SECRET_KEY=""
#############################################
# PRE-FLIGHT CHECKS
#############################################
# Ensure the script is run as root (via sudo or directly)
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root. Re-running with sudo..."
exec sudo "$0" "$@"
fi
# Exit on any error
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[✓]${NC} $1"
}
print_error() {
echo -e "${RED}[✗]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[!]${NC} $1"
}
# Tray tables in the upright position
print_status "Starting PowerDNS installation script..."
# Check if Debian 12
if ! grep -q "bookworm" /etc/os-release; then
print_warning "This script is designed for Debian 12 (Bookworm). Proceeding anyway..."
fi
#############################################
# SYSTEM PREPARATION
#############################################
print_status "Updating system packages..."
apt update && apt upgrade -y
print_status "Installing essential dependencies..."
apt install -y sudo curl git libpq-dev software-properties-common gnupg2
#############################################
# MARIADB INSTALLATION
#############################################
print_status "Installing MariaDB repository..."
curl -LsS -o mariadb_repo_setup https://downloads.mariadb.com/MariaDB/mariadb_repo_setup && echo "$(curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup.sha256)" > mariadb_repo_setup.sha256 && sha256sum -c mariadb_repo_setup.sha256 && sudo bash mariadb_repo_setup && rm mariadb_repo_setup mariadb_repo_setup.sha256
print_status "Installing MariaDB server and client..."
apt update && DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server
print_status "Starting and enabling MariaDB..."
systemctl enable --now mariadb
print_status "Securing MariaDB installation..."
# Automate mysql_secure_installation
mysql -u root <<EOF
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;
EOF
print_status "Creating PowerDNS databases and user..."
mysql -u root <<EOF
CREATE DATABASE IF NOT EXISTS ${PDNS_DB_NAME};
CREATE DATABASE IF NOT EXISTS ${PDNSADMIN_DB_NAME};
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';
GRANT ALL PRIVILEGES ON *.* TO '${DB_USER}'@'localhost';
FLUSH PRIVILEGES;
EOF
#############################################
# POWERDNS INSTALLATION
#############################################
print_status "Adding PowerDNS repository..."
printf "deb [signed-by=/etc/apt/keyrings/auth-50-pub.asc] http://repo.powerdns.com/debian bookworm-auth-50 main" > /etc/apt/sources.list.d/pdns.list
printf "Package: pdns-*\nPin: origin repo.powerdns.com\nPin-Priority: 600" > /etc/apt/preferences.d/auth-50
install -d /etc/apt/keyrings
curl https://repo.powerdns.com/FD380FBB-pub.asc | tee /etc/apt/keyrings/auth-50-pub.asc > /dev/null
print_status "Installing PowerDNS server..."
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y pdns-server
print_status "Installing PowerDNS MySQL backend..."
DEBIAN_FRONTEND=noninteractive apt-get install -y pdns-backend-mysql
#############################################
# POWERDNS CONFIGURATION
#############################################
print_status "Importing PowerDNS database schema..."
mariadb --user=${DB_USER} --password=${DB_PASSWORD} --database=${PDNS_DB_NAME} < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql
print_status "Configuring PowerDNS database connection..."
cat > /etc/powerdns/pdns.d/pdns.local.gmysql.conf <<EOF
# MySQL Configuration
# Launch gmysql backend
launch+=gmysql
# gmysql parameters
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=${PDNS_DB_NAME}
gmysql-user=${DB_USER}
gmysql-password=${DB_PASSWORD}
#gmysql-dnssec=yes
EOF
chown pdns: /etc/powerdns/pdns.d/pdns.local.gmysql.conf
chmod 640 /etc/powerdns/pdns.d/pdns.local.gmysql.conf
print_status "Enabling PowerDNS API..."
# Backup original config
cp /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf.backup
# Add API configuration
cat >> /etc/powerdns/pdns.conf <<EOF
#################################
# API Configuration
#################################
api=yes
api-key=${PDNS_API_KEY}
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1,::1
EOF
print_status "Cleaning up bind.conf if it exists..."
if [ -f /etc/powerdns/pdns.d/bind.conf ]; then
# Keep only the launch line
sed -i '/^launch/!d' /etc/powerdns/pdns.d/bind.conf
fi
print_status "Starting PowerDNS..."
systemctl restart pdns
systemctl enable pdns
# Verify PowerDNS is running
if systemctl is-active --quiet pdns; then
print_status "PowerDNS is running successfully"
else
print_error "PowerDNS failed to start"
systemctl status pdns
exit 1
fi
## Assigning Version Number
PDNS_VERSION=$(pdns_server --version | grep "PowerDNS Authoritative Server" | awk '{print $4}')
#############################################
# POWERDNS-ADMIN DEPENDENCIES
#############################################
print_status "Installing PowerDNS-Admin build dependencies..."
apt install -y apt-transport-https build-essential curl git \
libffi-dev libldap2-dev libmariadb-dev libpq-dev libsasl2-dev \
libssl-dev libxml2-dev libxmlsec1-dev libxslt1-dev pkg-config \
python3-dev python3-flask python3-venv virtualenv
print_status "Installing Node.js 20.x..."
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
print_status "Installing Yarn..."
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | tee /usr/share/keyrings/yarnkey.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | tee /etc/apt/sources.list.d/yarn.list
apt update && apt install -y yarn
#############################################
# POWERDNS-ADMIN INSTALLATION
#############################################
print_status "Cloning PowerDNS-Admin repository..."
if [ -d "$PDNSADMIN_PATH" ]; then
print_warning "PowerDNS-Admin directory already exists. Backing up..."
mv "$PDNSADMIN_PATH" "${PDNSADMIN_PATH}.backup.$(date +%Y%m%d_%H%M%S)"
fi
git clone https://github.com/PowerDNS-Admin/PowerDNS-Admin.git "$PDNSADMIN_PATH"
cd "$PDNSADMIN_PATH"
print_status "Creating Python virtual environment..."
python3 -m venv ./venv
print_status "Installing Python dependencies..."
source ./venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
deactivate
#############################################
# POWERDNS-ADMIN CONFIGURATION
#############################################
print_status "Creating PowerDNS-Admin production configuration..."
cp configs/development.py configs/production.py
# Generate Flask secret key if not provided
if [ -z "$FLASK_SECRET_KEY" ]; then
FLASK_SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex())')
print_status "Generated Flask secret key: $FLASK_SECRET_KEY"
fi
# Update production config
sed -i "s/SQLA_DB_USER = .*/SQLA_DB_USER = '${DB_USER}'/" configs/production.py
sed -i "s/SQLA_DB_PASSWORD = .*/SQLA_DB_PASSWORD = '${DB_PASSWORD}'/" configs/production.py
sed -i "s/SQLA_DB_NAME = .*/SQLA_DB_NAME = '${PDNSADMIN_DB_NAME}'/" configs/production.py
# Update SQLAlchemy URI
sed -i "s|^SQLALCHEMY_DATABASE_URI = 'sqlite.*|# SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')\nSQLALCHEMY_DATABASE_URI = 'mysql://${DB_USER}:${DB_PASSWORD}@127.0.0.1/${PDNSADMIN_DB_NAME}'|" configs/production.py
# Add secret key if not already present
if ! grep -q "^SECRET_KEY = " configs/production.py; then
echo "SECRET_KEY = '${FLASK_SECRET_KEY}'" >> configs/production.py
else
sed -i "s/SECRET_KEY = .*/SECRET_KEY = '${FLASK_SECRET_KEY}'/" configs/production.py
fi
print_status "Initializing PowerDNS-Admin database..."
source ./venv/bin/activate
export FLASK_CONF=../configs/production.py
export FLASK_APP=powerdnsadmin/__init__.py
flask db upgrade
print_status "Building frontend assets..."
yarn install --pure-lockfile
flask assets build
deactivate
#############################################
# SYSTEMD SERVICE CONFIGURATION
#############################################
print_status "Creating systemd service files..."
cat > /etc/systemd/system/pdnsadmin.service <<EOF
[Unit]
Description=PowerDNS-Admin
After=network.target
[Service]
Type=simple
WorkingDirectory=${PDNSADMIN_PATH}
User=pdns
Group=pdns
Environment=FLASK_CONF=../configs/production.py
ExecStart=${PDNSADMIN_PATH}/venv/bin/python ${PDNSADMIN_PATH}/run.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/pdnsadmin.socket <<EOF
[Unit]
Description=PowerDNS-Admin socket
[Socket]
ListenStream=/run/pdnsadmin/socket
[Install]
WantedBy=sockets.target
EOF
print_status "Setting up runtime directory..."
mkdir -p /run/pdnsadmin/
echo "d /run/pdnsadmin 0755 pdns pdns -" > /etc/tmpfiles.d/pdnsadmin.conf
print_status "Setting permissions..."
chown -R pdns: /run/pdnsadmin/
chown -R pdns: "$PDNSADMIN_PATH"
print_status "Enabling and starting PowerDNS-Admin service..."
systemctl daemon-reload
systemctl enable --now pdnsadmin.service pdnsadmin.socket
# Wait a few moments for the service to start
sleep 6
# Check if service is running
if systemctl is-active --quiet pdnsadmin.service; then
print_status "PowerDNS-Admin is running successfully"
else
print_error "PowerDNS-Admin failed to start"
systemctl status pdnsadmin.service
fi
# Wait a few more moments to be sure the service to started and doesnt spew text to the terminal
sleep 6
#############################################
# INSTALLATION COMPLETE
#############################################
echo ""
echo "=========================================="
print_status "Installation Complete!"
echo "=========================================="
echo ""
echo "Next Steps:"
echo " 1. Visit PowerDNS-Admin web interface"
echo " - http://$(hostname -I | awk '{print $1}'):9191"
echo " 2. Register your first user"
echo " 3. In PowerDNS-Admin setup, add your PowerDNS server:"
echo " - API URL: http://127.0.0.1:8081"
echo " - API Key: ${PDNS_API_KEY}"
echo " - Version: ${PDNS_VERSION}"
echo ""
echo "----------------------------------------------"
echo "PowerDNS Configuration:"
echo " - Database: ${PDNS_DB_NAME}"
echo " - API URL: http://$(hostname -I | awk '{print $1}'):8081"
echo " - API Key: ${PDNS_API_KEY}"
echo " - Version: ${PDNS_VERSION}"
echo ""
echo "PowerDNS-Admin Configuration:"
echo " - Web Interface: http://$(hostname -I | awk '{print $1}'):9191"
echo " - Database: ${PDNSADMIN_DB_NAME}"
echo " - Installation Path: ${PDNSADMIN_PATH}"
echo ""
echo "Database User:"
echo " - Username: ${DB_USER}"
echo " - Password: ${DB_PASSWORD}"
echo ""
echo "Service Status:"
echo " - PowerDNS: $(systemctl is-active pdns)"
echo " - PowerDNS-Admin: $(systemctl is-active pdnsadmin)"
echo ""
echo "=========================================="