Install package dependencies.I had to install libmariadb-dev-compat
to get the build to work. (I believe the author uses MySQL Community server, but I'm a MariaDB type of guy)
apt install -y apt-transport-https build-essential curl git libffi-dev libldap2-dev libmariadb-dev-compat libpq-dev libsasl2-dev libssl-dev libxml2-dev libxmlsec1-dev libxslt1-dev mariadb-server mariadb-client nodejs npm pkg-config python3-dev python3-pip python3-venv
Yarn (via NPM)
npm install --global yarn
Create a pdns unix user account
useradd -ms /bin/bash pdns
Create a database
CREATE DATABASE pda;
Create a new user will all privileges on the new database
GRANT ALL PRIVILEGES ON pda.* TO 'pda'@'localhost' IDENTIFIED BY '*************';
Flush privileges and exit
FLUSH PRIVILEGES;
exit
Clone PDNS-Admin and create a venv
inside the project directory
git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /opt/web/powerdns-admin && \
cd /opt/web/powerdns-admin && \
python3 -m venv ./venv
Activate the Python environment and install required libraries
source /opt/web/powerdns-admin/venv/bin/activate && \
pip install --upgrade pip && \
pip install -r requirements.txt
Copy the development config to a production file
cp -n /opt/web/powerdns-admin/configs/development.py /opt/web/powerdns-admin/configs/production.py
Modify the production.py
file and change SECRET_KEY
to something you generate - don't use the key that shipped with the file. You can use this time to configure your database parameters too.
Set the ENV
variables FLASK_CONF
and FLASK_APP
then run the DB migration
export FLASK_CONF=/opt/web/powerdns-admin/configs/production.py && \
export FLASK_APP=/opt/web/powerdns-admin/powerdnsadmin/__init__.py && \
flask db upgrade
Generate asset files with Yarn
yarn install --pure-lockfile && \
flask assets build
Change the ownership of the PDNS-Admin files
chown -R pdns:pdns /opt/web/powerdns-admin
Test PowerDNS-Admin
./run.py
Register a new user - the first user will be in the admin role.
PowerDNS-Admin uses the PowerDNS API - we need to enable the API
Open the PowerDNS conf file /etc/powerdns/pdns.conf
and modify the following parameters
api=yes
api-key=**********************************
webserver=yes
Restart PowerDNS
systemctl restart pdns.service
NGINX will serve static files. Everything else will be handled by the Python WSGI server.
Create a new site config
bash -c "cat > /etc/nginx/sites-available/pdns-admin.conf" <<'EOL'
server {
listen *:80;
server_name pdns-admin.example.com;
index index.html index.htm index.php;
root /opt/web/powerdns-admin;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
proxy_buffer_size 8k;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_headers_hash_bucket_size 64;
location ~ ^/static/ {
include /etc/nginx/mime.types;
root /opt/web/powerdns-admin/powerdnsadmin;
location ~* \.(jpg|jpeg|png|gif)$ {
expires 90d;
}
location ~* ^.+.(css|js)$ {
expires 1d;
}
}
location / {
proxy_pass http://unix:/run/powerdns-admin/socket;
proxy_read_timeout 120;
proxy_connect_timeout 120;
proxy_redirect off;
}
}
EOL
Disable the default site and enable the new one
rm /etc/nginx/sites-enabled/default && \
ln -s /etc/nginx/sites-available/pdns-admin.conf /etc/nginx/sites-enabled/pdns-admin.conf
Restart Nginx
systemctl restart nginx.service
Create a new systemd
service file
bash -c "cat > /etc/systemd/system/powerdns-admin.service" <<'EOL'
[Unit]
Description=PowerDNS-Admin
Requires=powerdns-admin.socket
After=network.target
[Service]
PIDFile=/run/powerdns-admin/pid
User=pdns
Group=pdns
Environment="FLASK_CONF=/opt/web/powerdns-admin/configs/production.py"
Environment="FLASK_APP=/opt/web/powerdns-admin/powerdnsadmin/__init__.py"
WorkingDirectory=/opt/web/powerdns-admin
ExecStartPre=+mkdir -p /run/powerdns-admin/
ExecStartPre=+chown pdns:pdns -R /run/powerdns-admin/
ExecStart=/opt/web/powerdns-admin/venv/bin/gunicorn --pid /run/powerdns-admin/pid --bind unix:/run/powerdns-admin/socket 'powerdnsadmin:create_app()'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOL
Create a new socket config file
bash -c "cat > /etc/systemd/system/powerdns-admin.socket" <<'EOL'
[Unit]
Description=PowerDNS-Admin socket
[Socket]
ListenStream=/run/powerdns-admin/socket
[Install]
WantedBy=sockets.target
EOL
Add this config override too
bash -c "cat > /etc/tmpfiles.d/powerdns-admin.conf" <<'EOL'
d /run/powerdns-admin 0755 pdns pdns -
EOL
Reload systemd, start and enable the new service
systemctl daemon-reload && \
systemctl enable --now powerdns-admin.service && \
systemctl status powerdns-admin.service