Install PowerDNS on Redhat/Ubuntu based Distros Auto Install Script

Installing Power DNS

What is PowerDNS?

PowerDNS is an open-source authoritative DNS Server, written in C++ and licensed under GPL/GNU and is a great alternative to BINDPowerDNS (PDNS) has better performance and can be installed with many support backends like with SQL platforms such as MySQLMariaDB, and PostgreSQL. You can even configure it with Bind as a backend with zone files.

I started out writing this as an How to and included the script, but I think it got confusing switching between the two ways of installing PowerDNS, so I removed all the how to stuff and just included the script on it own. And then showed how to setup PowerAdmin  

This script should work with version 8, RedHat based distros and Ubuntu 18, 20,22.04. I have only tested it on Centos Stream, Rocky 8.4 and 8.5, Alma Linux 8 and a few versions of Ubuntu. It should also work on version 9 of RedHat stuff, I know that RedHat/Centos 7 will be supported with maintenance releases till 2024, but figured most folks will opt for the longevity of version 8

This script will install PowerDNS with the MariaDB backend and PowerAdmin with very little user interaction in about 5 minutes, and then you will spend about 10 mins configuring PowerAdmin, so to start the install. The script will start with MariaDB first and then secure it second 

You can download this install script here or at the bottom of the page

Requirements

This is where I tell you the obvious stuff like you need to be logged in as the root user or sudo su -  to root, but I'm sure you already knew that! The script will check for that and exit if your not, also the script assumes that this will be a fresh install. 

Installing MariaDB

As I said before you need to install the MariaDB first. In the script you will need to put your password here 

########################
#### User Variables ####
########################
MYSQL_PASS='Password@123'  # <-- Your MySql root Password here
MY_PDNS_USR=pdns           # <-- The username for your PowerDNS DB
MY_PDNS_DB=powerdns        # <-- The name for your PowerDNS DB
MY_PDNS_PW=somepassword    # <-- The password you wantt for you PowerDNS DB
MY_PDNS_HOST=localhost     # <-- The default here is localhost, but can be set to a remote host if you have configured that
DEL_MY_CNF=Y               # <-- Place a Capital Y for yes or N for no here to delete /root/.my.cnf when db_instal function is done
WEB_HOST_NAME=test1.linuxcomputer.cloud    # <-- The FQDN of your server goes here
EMAIL=admin@$WEB_HOST_NAME  # <-- this is the email you want to use for Let's Encrypt registations
HTTP=nginx                 # <-- TODO Apache Config for Beta TESTING please only choose nginx 

The script will check for and install mariadb if not present :

#########################
#### Install MariaDB ####
#########################
function install_mysql() {
    {
        if [ ! "$(command -v mysql)" ]; then
            if [ "${OS}" = ubuntu ]; then
                ${PAKMGR} update
                ${PAKMGR} install mariadb-client mariadb-server
            else
                ${PAKMGR} install mariadb mariadb-server
            fi
        fi
        systemctl enable --now mariadb
    }
}

Then it will secure the mariadb :

######################
#### Secure MySQL ####
######################
function secure_mysql() {
    {
        if [ ! "$(command -v expect)" ]; then
            ${PAKMGR} install expect
        fi

        expect -f - <<-EOF
            set timeout 10
            spawn mysql_secure_installation
            expect "Enter current password for root (enter for none):"
            send -- "\r"
            expect "Set root password?"
            send -- "y\r"
            expect "New password:"
            send -- "${MYSQL_PASS}\r"
            expect "Re-enter new password:"
            send -- "${MYSQL_PASS}\r"
            expect "Remove anonymous users?"
            send -- "y\r"
            expect "Disallow root login remotely?"
            send -- "y\r"
            expect "Remove test database and access to it?"
            send -- "y\r"
            expect "Reload privilege tables now?"
            send -- "y\r"
            expect eof
EOF
    }
}

This if function just creates a .my.cnf file in the root dir to allow for the command line creation of the user, privileges, database and tables it is deleted after use unless you selected N for DEL_MY_CNF in User Variables section of the script,

###################################
#### Install PowerDNS DataBase ####
###################################
function pdns_db_install() {
    {
        define () {
            IFS=$'\n' read -r -d '' "$1"
        }

        if [ ! -f /root/.my.cnf ]; then
            {
                echo '[mysql]'
                echo 'user=root'
                echo "password=$MYSQL_PASS"
            } >/root/.my.cnf
        fi

The next step is to create a database and user for PowerDNS,

	mysql -e "CREATE DATABASE $MY_PDNS_DB /*\!40100 DEFAULT CHARACTER SET utf8 */;"
        mysql -e "CREATE USER $MY_PDNS_USR@localhost IDENTIFIED BY '$MY_PDNS_PW';"
        mysql -e "GRANT ALL PRIVILEGES ON $MY_PDNS_DB.* TO '$MY_PDNS_USR'@'localhost';"
        mysql -e "FLUSH PRIVILEGES;"

After that the tables are created :

touch /tmp/pdns.sql
        OUTFILE="/tmp/pdns.sql"
        define PDNS_SQL << 'EOF'
        CREATE TABLE domains (
        id                    INT AUTO_INCREMENT,
        name                  VARCHAR(255) NOT NULL,
        master                VARCHAR(128) DEFAULT NULL,
        last_check            INT DEFAULT NULL,
        type                  VARCHAR(6) NOT NULL,
        notified_serial       INT UNSIGNED DEFAULT NULL,
        account               VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL,
        PRIMARY KEY (id)
        ) Engine=InnoDB CHARACTER SET 'latin1';

        CREATE UNIQUE INDEX name_index ON domains(name);


        CREATE TABLE records (
        id                    BIGINT AUTO_INCREMENT,
        domain_id             INT DEFAULT NULL,
        name                  VARCHAR(255) DEFAULT NULL,
        type                  VARCHAR(10) DEFAULT NULL,
        content               VARCHAR(64000) DEFAULT NULL,
        ttl                   INT DEFAULT NULL,
        prio                  INT DEFAULT NULL,
        disabled              TINYINT(1) DEFAULT 0,
        ordername             VARCHAR(255) BINARY DEFAULT NULL,
        auth                  TINYINT(1) DEFAULT 1,
        PRIMARY KEY (id)
        ) Engine=InnoDB CHARACTER SET 'latin1';

        CREATE INDEX nametype_index ON records(name,type);
        CREATE INDEX domain_id ON records(domain_id);
        CREATE INDEX ordername ON records (ordername);


        CREATE TABLE supermasters (
        ip                    VARCHAR(64) NOT NULL,
        nameserver            VARCHAR(255) NOT NULL,
        account               VARCHAR(40) CHARACTER SET 'utf8' NOT NULL,
        PRIMARY KEY (ip, nameserver)
        ) Engine=InnoDB CHARACTER SET 'latin1';


        CREATE TABLE comments (
        id                    INT AUTO_INCREMENT,
        domain_id             INT NOT NULL,
        name                  VARCHAR(255) NOT NULL,
        type                  VARCHAR(10) NOT NULL,
        modified_at           INT NOT NULL,
        account               VARCHAR(40) CHARACTER SET 'utf8' DEFAULT NULL,
        comment               TEXT CHARACTER SET 'utf8' NOT NULL,
        PRIMARY KEY (id)
        ) Engine=InnoDB CHARACTER SET 'latin1';

        CREATE INDEX comments_name_type_idx ON comments (name, type);
        CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);


        CREATE TABLE domainmetadata (
        id                    INT AUTO_INCREMENT,
        domain_id             INT NOT NULL,
        kind                  VARCHAR(32),
        content               TEXT,
        PRIMARY KEY (id)
        ) Engine=InnoDB CHARACTER SET 'latin1';

        CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);


        CREATE TABLE cryptokeys (
        id                    INT AUTO_INCREMENT,
        domain_id             INT NOT NULL,
        flags                 INT NOT NULL,
        active                BOOL,
        published             BOOL DEFAULT 1,
        content               TEXT,
        PRIMARY KEY(id)
        ) Engine=InnoDB CHARACTER SET 'latin1';

        CREATE INDEX domainidindex ON cryptokeys(domain_id);


        CREATE TABLE tsigkeys (
        id                    INT AUTO_INCREMENT,
        name                  VARCHAR(255),
        algorithm             VARCHAR(50),
        secret                VARCHAR(255),
        PRIMARY KEY (id)
        ) Engine=InnoDB CHARACTER SET 'latin1';

        CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);
EOF
        {
            printf "%s\n" "$PDNS_SQL" | cut -c 2-
        } > "$OUTFILE"
        if [ ${DEL_MY_CNF} != N ]; then
            rm -rf /root/.my.cnf
        fi
        mysql -D powerdns < /tmp/pdns.sql
        rm /tmp/pdns.sql
    }
}

ok mariadb is installed and secured now for PowerDNS....

Installing PowerDNS

In this part of the script, a few repos are installed before it installs the PowerDNS app, on RedHat based OS it will add the EPEL and REMI repository first, on Ubuntu based OS it checks for and disables systemd-resolved if it's running and modifies the resolv.conf file. After that it runs the installation command to install pdns, the mysql connector and bind utilities.

That is accomplished here :

####################################
#### Install/Configure PowerDNS ####
####################################
function pdns_app_install() {
    {
        if [ "${OS}" = ubuntu ]; then
            if systemctl is-enabled systemd-resolved; then
                systemctl disable --now systemd-resolved
                systemctl mask systemd-resolved
                sed -i 's/nameserver /#nameserver /g' /etc/resolv.conf
                echo -e 'nameserver 8.8.8.8 \nnameserver 8.8.4.4' >> /etc/resolv.conf
            fi
            DEBIAN_FRONTEND=noninteractive ${PAKMGR} install pdns-backend-mysql fpdns bind9utils
        else
            ${PAKMGR} install epel-release
            ${PAKMGR} install http://rpms.remirepo.net/enterprise/remi-release-8.rpm
            ${PAKMGR} install pdns-backend-mysql pdns bind-utils
            expect -f - <<-EOF
                set timeout 2
                spawn dnf module enable php:remi-7.4
                expect "Is this ok:"
                send -- "y\r"
                expect eof
EOF
        fi

If everything went well then it will edit the /etc/pdns/pdns.conf configuration file of PowerDNS, I wanted to have the entire file in there as there's alway something missing when you don't, I show some of my settings in here which are not part of the default, that you will use, they are only there as an example. I will try to note the changes I have for a default install :

Domain Transfers

...

#################################
# allow-axfr-ips        Allow zonetransfers only to these subnets
#
# allow-axfr-ips=127.0.0.0/8,::1
allow-axfr-ips=192.168.1.53, 192.168.2.31, 192.168.3.80, 2a02:c207:2057:3344::1, 2605:a140:2066:3931::1, 2a02:c206:2061:9005::1

...

So here I have given an example of multiple servers I have, I run several dns servers in a master/slave mode which allows me to have all my domains on all the servers and allows me to promote one or more servers from slave to master, if there is gonna be a lot of down time in one or the other. This is only an example 

This is not include in the default config and you will have to edit the file yourself to add it

Config DIR

...
    
#################################
# config-dir    Location of configuration directory (pdns.conf)
#
 config-dir=/etc/pdns
    
...

This is not required it's the default so you can comment it out if you want, 

Deamon

...

#################################
# daemon        Operate as a daemon
#
daemon=yes
     
...

Needs to run in this mode, the default in the conf file is set to no, this causes pdns to run in the foreground instead of the background outta of way

Disable Transfers

...      

#################################
# disable-axfr Disable zonetransfers but do allow TCP queries
disable-axfr=no

...

This is another of my settings, due to multiple dns servers, it is not included in the default configuration, you will have to change this yourself 

PDNS Guardian

...
    
#################################
# guardian      Run within a guardian process
#
guardian=yes
    
...

The default for this is off, but I like to use it guardian is a wrapper that will control pdns, the wrapper keeps an eye on performance, manages the starts, restarts and stops that pdns has to do, when guardian is not used everything talks directly to the pdns server

It's not required and can safely be set to no or comment it out if you want

Launch Section

...
    
#################################
# launch        Which backends to launch and order to query them in
#
#launch=bind
launch=gmysql
gmysql-dnssec
gmysql-host=localhost
gmysql-user=pdns
gmysql-password=somepassword
gmysql-dbname=powerdns
    
...

Ok this will take a minute to explain, so let me break it up by line

  • launch=gmysql - This is the backend you are connecting to that stores your domains and various other settings
  • gmysql-dnssec - I have my domains in a DNSEC mode for secured data, if a DNSSEC configuration is found for a domain, the PowerDNS daemon will provide key records, signatures and (hashed) denials of existence automatically, It's not required, and will not affect your everyday usage, so you can comment it out if you want.
  • gmysql-host=$MY_PDNS_HOST - This is usually localhost, but if you have a remote host you can put it here instead which is sadly out of the scope of this script, but will be set to whatever you set in user variables. 
  • gmysql-user=$MY_PDNS_USR - This is you database username and will be set to what ever you selected in the user variables
  • gmysql-password=$MY_PDNS_PW - This is the database users password, which will also be set to whatever you selected in the user variables
  • gmysql-dbname=$MY_PDNS_DB - This is the database name and will be set to whatever you selected in the user variables

Master Setting

...
        
 #################################
# master        Act as a primary
#
master=yes

...

This is set to yes as the default, you can change it to no or comment it out if you want, all my dns servers act as primary and secondary for my domains. 

GID/UID

...
    
#################################
# setgid        If set, change group id to this gid for more security
#
setgid=pdns

#################################
# setuid        If set, change user id to this uid for more security
#
setuid=pdns
    
...

This is the default for this dns server, only change this if you know what you are doing.

Version String

...

###############################
# version-string        PowerDNS version in packets - full, anonymous, powerdns or custom
#
# version-string=full
version-string=ScoobyDooHost 0.1 Alpha

...

Put whatever you want here, the default is to announce itself as PowerDNS and version number, I got in the habit of making it something else back in the bind days for security, you can safely comment it out or change it to anything you like.

SuperSlave

...

#################################
# superslave    Act as a autosecondary
#
# superslave=no
superslave=yes

...

This is another one of my settings and is commented out in this conf file.

The script will now enable and start the pdns server

 if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
            setsebool -P pdns_can_network_connect_db 1
            setsebool -P nis_enabled 1
        fi

        sed -i 's/ //g' /etc/pdns/pdns.conf
        systemctl enable --nom pdns
    }
}

None of the other settings need to messed with for the installed app to work at this point so on to the web server and frontend

PowerAdmin

To manage PowerDNS you need an interface. PowerAdmin as it is a simple Web Interface that manages PowerDNS with a web browser. I like PowerAdmin as the web-based interface of management PowerDNS

I use Nginx just as much as I use Apache... (I will add an Apache config to the script file later when I get some time to do it so you will be able to choose), the original config was for Nginx it was in my head at the time of the script and this post writing so that's the reason I used it, I have since added the Apache configuration to the script and it's still in the beta stages so use with caution as results may vary. Just change HTTP=nginx under User Variables to HTTP=apache

WebServer Install

###########################################
#### Install/Configure Apache or Nginx ####
###########################################
function webserver_install() {
    {
        if [ ! -d /var/www/html/$WEB_HOST_NAME ]; then
            mkdir -p /var/www/html/$WEB_HOST_NAME
        fi

        if [ $HTTP = apache ]; then
            if [ "${OS}" = ubuntu ]; then
                ${PAKMGR} install build-essential apache2 php php-dev php-fpm php-gd php-intl php-mysql php-odbc php-pear php-xml php-xmlrpc php-mbstring gettext libmcrypt-dev
                pecl channel-update pecl.php.net
                pecl update-channels
                expect -f - <<-EOF
                    set timeout 10
                    spawn pecl install mcrypt
                    expect "libmcrypt prefix?"
                    send -- "\r"
                    expect eof
EOF
                sed -i 's/;extension=shmop/extension=mcrypt.so/g' /etc/php/*/cli/php.ini
                sed -i 's/;extension=shmop/extension=mcrypt.so/g' /etc/php/*/apache2/php.ini
                if ! php -m | grep mcrypt; then
                    echo ''
                    echo 'mcrypt did not install correctly on this Ubuntu machine...!'
                    exit 1
                fi
                systemctl restart apache2
            else
                ${PAKMGR} install httpd php74 php74-php-devel php74-php-fpm php74-php-gd php74-php-intl php74-php-mysqlnd php74-php-odbc php74-php-pear php74-php-xml php74-php-xmlrpc php74-php-mbstring php74-php-pecl-mcrypt gettext
            fi

            if [ "${OS}" = ubuntu ]; then
                path=/etc/apache2/sites-available/$WEB_HOST_NAME.conf
            else
                path=/etc/httpd/conf.d/$WEB_HOST_NAME.conf
            fi
            
            {
                echo ''
                echo "    ServerAdmin admin@n$WEB_HOST_NAME"
                echo "    ServerName $WEB_HOST_NAME"
                echo "    DocumentRoot /var/www/html/$WEB_HOST_NAME"
                echo '    #DirectoryIndex index.php'
                echo "    #ErrorLog /var/log/httpd/$WEB_HOST_NAME-error.log"
                echo "    #CustomLog /var/log/httpd/$WEB_HOST_NAME-access.log combined"
                echo ''
                echo '    '
                echo '        '
                if [ "${OS}" = ubuntu ]; then
                    echo '            SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"'
                else
                    echo '            SetHandler "proxy:unix:/var/opt/remi/php74/run/php-fpm/www.sock|fcgi://localhost"'
                fi
                echo '        '
                echo '    '
                echo ''
                }  > $path

            
            if [ "${OS}" = ubuntu ]; then
                if ! apachectl configtest; then
                    echo ''
                    echo -e '\e[01;37m -----------------------------------------------------------------------------------------------------'
                    echo -e "\e[01;31m   An Error was detected with apache2, Please manually look at the configuration to comfirm it's good" >&2
                    echo -e '\e[01;37m -----------------------------------------------------------------------------------------------------'
                    exit 1
                fi
            else
                if ! httpd -t; then
                    echo ''
                    echo -e '\e[01;37m ----------------------------------------------------------------------------------------------------'
                    echo -e "\e[01;31m   An Error was detected with httpd, Please manually look at the configuration to comfirm it's good" >&2
                    echo -e '\e[01;37m ----------------------------------------------------------------------------------------------------'
                    exit 1
                fi
            fi
            
            if [ "${OS}" = ubuntu ]; then
                systemctl enable --now php-fpm
                a2dissite 000-default
                a2ensite $WEB_HOST_NAME
                systemctl enable apache2
                systemctl reload apache2
            else
                chcon -R -t httpd_sys_content_t /var/www/html/$WEB_HOST_NAME
                systemctl enable --now php74-php-fpm
                systemctl enable --now httpd
            fi
        elif [ $HTTP = nginx ]; then
            if [ "${OS}" = ubuntu ]; then
                ${PAKMGR} install build-essential php php-cli php-dev php-fpm php-gd php-intl php-json php-mysql php-pear php-xml php-xmlrpc php-mbstring gettext libmcrypt-dev
                pecl channel-update pecl.php.net
                pecl update-channels
                expect -f - <<-EOF
                    set timeout 10
                    spawn pecl install mcrypt
                    expect "libmcrypt prefix?"
                    send -- "\r"
                    expect eof
EOF
                sed -i 's/;extension=shmop/extension=mcrypt.so/g' /etc/php/*/cli/php.ini
                sed -i 's/;extension=shmop/extension=mcrypt.so/g' /etc/php/*/apache2/php.ini
                systemctl disable --now apache2
                systemctl mask apache2
                if ! php -m | grep mcrypt; then
                    echo ''
                    echo 'mcrypt did not install correctly on this Ubuntu machine...!'
                    exit 1
                    systemctl disable --now httpd
                    systemctl mask httpd
                fi
            else
                ${PAKMGR} install php php-fpm php-cli php-mysqlnd php-pecl-mcrypt php-json php-intl
                chown apache:apache /var/lib/php/sessions
                systemctl disable --now httpd
                systemctl mask httpd
            fi
        fi

            ${PAKMGR} install nginx

            if [[ ${OS} = centos || ${OS} = redhat || ${OS} = oracle || ${OS} = rocky || ${OS} = alma ]]; then
                if ! grep "listen = /run/php-fpm/www.sock" /etc/php-fpm.d/www.conf; then
                    sed -i '/listen = */c\listen = \/run\/php-fpm\/www.sock' /etc/php-fpm.d/www.conf
                fi
            fi

            if [ "${OS}" = ubuntu ]; then
                path=/etc/nginx/sites-available/$WEB_HOST_NAME.conf
            else
                path=/etc/httpd/conf.d/$WEB_HOST_NAME.conf
            fi
            # shellcheck disable=SC2016
            {
                echo 'server {'
                echo "     server_name $WEB_HOST_NAME;"
                echo '     listen 80;'
                echo ''
                echo "     root /var/www/html/$WEB_HOST_NAME;"
                echo "     #access_log /var/log/nginx/$WEB_HOST_NAME-access_log;"
                echo "     #error_log /var/log/nginx/$WEB_HOST_NAME-error_log;"
                echo ''
                echo '     index index.php;'
                echo ''
                echo '     location / {'
                echo '        try_files $uri $uri/ /index.php?query_string;'
                echo '      }'
                echo ''
                echo '     location ~ \.php$ {'
                echo '         fastcgi_index index.php;'
                echo '         fastcgi_split_path_info ^(.+\.php)(.*)$;'
                echo '         fastcgi_keep_conn on;'
                echo '         include /etc/nginx/fastcgi_params;'
                if [ "${OS}" = ubuntu ]; then
                    echo '         fastcgi_pass unix:/run/php/php-fpm.sock;'
                else
                    echo '         fastcgi_pass unix:/run/php-fpm/www.sock;'
                fi
                echo '         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;'
                echo '     }'
                echo ''
                echo '     location ~/\.ht {'
                echo '        deny all;'
                echo '     }'
                echo ''
                echo '}'
            } > $path

            if ! nginx -t; then
                echo ''
                echo -e '\e[01;37m --------------------------------------------------------------------------------------------------'
                echo -e "\e[01;31m  An Error was detected with nginx, Please manually look at the configuration to comfirm it's good" >&2
                echo -e '\e[01;37m --------------------------------------------------------------------------------------------------'
                exit 1
            fi
            
            if [ "${OS}" = ubuntu ]; then
                rm /etc/nginx/sites-enabled/default
                ln -s /etc/nginx/sites-available/$WEB_HOST_NAME.conf /etc/nginx/sites-enabled/$WEB_HOST_NAME
                systemctl enable --now php-fpm
                systemctl enable nginx
                systemctl start nginx
            else
                systemctl enable --now php-fpm
                systemctl enable nginx
                chcon -R -t httpd_sys_content_t /var/www/html/$WEB_HOST_NAME
                systemctl start nginx
        fi
    }
}

PowerAdmin Install

############################
#### Install PowerAdmin ####
############################
function pdns_admin_install() {
    {
        if [ ! -d /var/www/html/$WEB_HOST_NAME ]; then
            mkdir -p /var/www/html/$WEB_HOST_NAME
        fi

Making the directory if it does not exist that PowerAdmin calls home 

${PAKMGR} install git
        cd /var/www/html/$WEB_HOST_NAME || exit
        git clone https://github.com/poweradmin/poweradmin.git
        mv poweradmin/* .
        rm -rf poweradmin/
        find /var/www/html/$WEB_HOST_NAME/ -type d -exec chmod 755 {} \;
        find /var/www/html/$WEB_HOST_NAME/ -type f -exec chmod 644 {} \;
        if [ "${OS}" = ubuntu ]; then
            chown www-data:www-data /var/www/html/$WEB_HOST_NAME/
        else   
            chown apache:apache /var/www/html/$WEB_HOST_NAME/
            chown apache:apache /var/lib/php/session
        fi
    }
}

I like to use the git version of PowerAdmin, it works 99.9% of the time with little fuss as opposed to the version that is on their site 

Installing Certbot

I added this when I added the TEST Apache configuation, this will install, configure and request a Let's Encrypt Cert for your PowerAdmin site

##########################################
#### Install Certbot and request Cert ####
##########################################
install_certbot() {
    {
        if [ $HTTP = apache ]; then
            ${PAKMGR} install python3-certbot-apache
            systemctl enable --now httpd
        elif [ $HTTP = nginx ]; then
            ${PAKMGR} install python3-certbot-nginx
            systemctl enable --now nginx
        fi

        #################################################################################################
        ####         Be sure that your domain has the proper dns entry or this will not work.        ####
        ####                                                                                         ####
        ####      If your domain is not properly configured and you know it, or you just wanna       ####
        ####      test that you can get a cert uncomment this line                                   ####
        ####                                                                                         ####
        #### certbot certonly --redirect --agree-tos --nginx -d $WEB_HOST_NAME -m "$EMAIL" --dry-run ####                                          ####
        ####                              and comment out this line                                  ####
        ####     certbot --non-interactive --redirect --agree-tos -d $WEB_HOST_NAME -m "$EMAIL"      ####
        #################################################################################################

        if [ $HTTP = apache ]; then
            certbot certonly --redirect --agree-tos --apache -d $WEB_HOST_NAME -m "$EMAIL" --dry-run -v
            #certbot --non-interactive --redirect --agree-tos --apache -d $WEB_HOST_NAME -m "$EMAIL"
            systemctl restart httpd
        elif [ $HTTP = nginx ]; then
            certbot certonly --redirect --agree-tos --nginx -d $WEB_HOST_NAME -m "$EMAIL" --dry-run -v
            #certbot --non-interactive --redirect --agree-tos --nginx -d $WEB_HOST_NAME -m "$EMAIL"
            systemctl restart nginx
        fi

        if [ "${OS}" = ubuntu ]; then
            if ! grep "certbot" /var/spool/cron/crontab/root; then
                echo "0 */12  * * *   root    certbot -q renew" >>/etc/crontab
            fi
        else
            if ! grep "certbot" /var/spool/cron/root; then
                echo "0 */12 * * * root certbot -q renew" >>/var/spool/cron/root
            fi
        fi   
    }
}

Please note the colored text above... You have 3 total choices here 

  1. Uncomment the test cert line and comment out the live cert line <-- This is the Default
  2. Comment out the test cert line and uncomment the live cert line
  3. Comment out install_certbot from the list at the bottom of the script and not worry about installing, getting or testing for cert for now

The entire install is setup in functions so that you can comment out what will or won't be installed. All function are listed at the bottom of the script after Code End

check_RootUser        <-- Checking for Root User
install_mysql         <-- Install of MySQL
secure_mysql          <-- Securing MySQL
pdns_db_install       <-- Install of PowerDNS DataBase
pdns_app_install      <-- Install of the PowerDNS App
webserver_install     <-- Install of Apache or Nginx 
pdns_admin_install    <-- Install of PowerAdmin
install_certbot       <-- Install/Request of Certbot and Certificate Request
install_complete      <-- Final Message with Link

Commenting out what you think you need or don't need will affect the stability of the install, do so at your own risk 

So onto the final part of the install, this you will have to do on your own, it's easy to do and you should be able to follow along with the following guide to help you

You Should now b able to access PowerAdmin you can browse to your subdomain with a URL of  https://your.domain.com/install or by the IP https://123.231.225.1 an example like this

Note: If you opt'd not to install the certificate with certbot remove the s from https://  other then that everything else from here on is the same as far as setup

https://test1.linuxcomputer.cloud/install/
PowerAdmin - Installation Step 1

Step 1 - In the first step, you will see the configuration choices above, choose the language you want for PowerAdmin. I selected I prefer to proceed in english then I clicked Go to step 2

PowerAdmin - Installation Step 2

Step 2 - You are agreeing that the PowerDNS DataBase has never been used, because it will over write portions of the DataBase on installation. So you can click Go to step 3 if you are sure, to install PowerAdmin.

PowerAdmin - Installation Step 3

Step 3 - Database configuration, you will use the info you used to setup the DB... Hint it's all in the User Variables area of the script, I will use my test info for this setup, if you input the wrong info it will tell you.

  • Username - pdns <-- This user has the rights to the powerdns DB
  • Password - somepassword <-- The password for the username DB
  • Database type - MySQL <-- Should default here in case it's not
  • DB Port - 3306 <-- Again it should defualt there, but in case it not you can set it
  • Database - powerdns <-- The DB the PowerDNS connects to
  • DB Char -           <-- I have never had to change from the default
  • DB Collation -     <-- Again I have never had to change from the default
  • Poweradmin administrator password - anotherpassword <-- This is the admin users password, as admin you can do pretty much anything in PowerAdmin

By default the username to login to PowerAdmin is admin,  that what you will use once you are done with step 3,  After you have entered your info, you can click Go to step 4 for the next step.

PowerAdmin - Installation Step 4

Step 4 - It asks for Hostmaster, Primary nameserver  and Secondary nameserver as wellas a Username and Password for database connection/access for PowerAdmin, You can reuse your username and password you used before if you want, I like to use a different one, but thats just me, you can do whatever you want. Here is an example of what I might put

  • Username - ImaUser <-- This user is for everyday tasks, you can add or remove permissions by logging in with the admin user
  • Password - YetAnotherPassword  <-- The everyday users password 
  • Hostmaster - test1.linuxserver.cloud  <--- This usually would be the primary Hostmaster or the PowerDNS Master server if you like, but should match the primary nameserver
  • Primary nameserver - test1.linuxserver.cloud <-- Primary Master Server
  • Secondary nameserver - test2.linuxserver.cloud  <-- This is usually your slave server, it can also be the primaries IP Address so you have a little flexibility in you configuration of it, the more you play the more you know 

Once you are done with this page you can then click on Go to step 5

PowerAdmin - Installation Step 5

Step 5 - This page ask you to create the limited access acct from the previous step  to the database. You can skip this step if you want or do it one of these 2 ways

  1. From the bash command line you can run -- example -->mysql -e "GRANT SELECT, INSERT, UPDATE, DELETE ON powerdns.* TO 'ImaUser'@'localhost' IDENTIFIED BY 'YetAnotherPassword';" -p You will need to put your info in and not use mine Enter the MySQL root user password when prompted (NOTE: If you opt'd not to remove the .my.cnf that the script created, remove the -p from the end of the command line as it is not required!)
  2. Login to mysql as root mysql -p and run the command you see on the setup screen -- example --> GRANT SELECT, INSERT, UPDATE, DELETE ON powerdns.* TO 'ImaUser'@'localhost' IDENTIFIED BY 'YetAnotherPassword';  once you have created this user you can quit mysql as you are done (NOTE: If you opt'd not to remove the .my.cnf that the script created, remove the -p from the end of the mysql command as it is not required!)

Once you have done this move on to the next stop by clicking Go to step 6

Step 6 - Here it asks you to create the config.inc.php configuration file, which in my case it is   /var/www/html/test1.linuxcomputer.cloud/inc/config.inc.php All you need to do here is copy/paste the configuration on the screen to your config.inc.php 

So vim /var/www/html/name-of.your.server/inc/config.inc.php

Edit config.inc.php

Paste the configuration on the step 6 page above,  once you are finished with that you can click on Go to step 7

PowerAdmin - Installation Step 7

In the last step, you will be asked to delete the folder install,

In my case it would be :

rm -rf /var/www/html/test1.linuxcomputer.cloud/install/

After you deleted that folder you can try to access your PowerAdmin with URL http://your.domain.com or https://your.domain.comand (if you got a cert then https:// if not then http://) either way it should look like this.

Installing PowerAdmin - Main login Page

Closing Words

PowerDNS is one of the best DNS Server applications and is an alternative to BIND (named) DNS Server. To control or manage PowerDNS you can use PowerAdmin as a web-based interface DNS configuration.

Version History

Version 1.0 - Initial Release
Version 1.1 - Fixed bug in Database Creation
Version 1.2 - Upgraded install to use PHP 7.4
Version 1.3 - Added Ubuntu Support
Version 1.4 Added Apache Configurations
Version 1.5 - added some error checking and color output
Version 2.0 - Cleaned up script and re-wrote sections to be more logical
Version 2.1 - BugFixes
Version 2.2 - Fixed change in php-fpm on Ubuntu servers

You can download this install script here

Comments