diff --git a/docs/wiki/Configure-Active-Directory-Authentication-using-Group-Security.md b/docs/wiki/Configure-Active-Directory-Authentication-using-Group-Security.md new file mode 100644 index 0000000..417bdc3 --- /dev/null +++ b/docs/wiki/Configure-Active-Directory-Authentication-using-Group-Security.md @@ -0,0 +1,34 @@ +Active Directory Setup - Tested with Windows Server 2012 + +1) Login as an admin to PowerDNS Admin + +2) Go to Settings --> Authentication + +3) Under Authentication, select LDAP + +4) Click the Radio Button for Active Directory + +5) Fill in the required info - + +* LDAP URI - ldap://ip.of.your.domain.controller:389 +* LDAP Base DN - dc=youdomain,dc=com +* Active Directory domain - yourdomain.com +* Basic filter - (objectCategory=person) + * the brackets here are **very important** +* Username field - sAMAccountName +* GROUP SECURITY - Status - On +* Admin group - CN=Your_AD_Admin_Group,OU=Your_AD_OU,DC=yourdomain,DC=com +* Operator group - CN=Your_AD_Operator_Group,OU=Your_AD_OU,DC=yourdomain,DC=com +* User group - CN=Your_AD_User_Group,OU=Your_AD_OU,DC=yourdomain,DC=com + +6) Click Save + +7) Logout and re-login as an LDAP user from each of the above groups. + +If you're having problems getting the correct information for your groups, the following tool can be useful - + +https://docs.microsoft.com/en-us/sysinternals/downloads/adexplorer + +In our testing, groups with spaces in the name did not work, we had to create groups with underscores to get everything operational. + +YMMV diff --git a/docs/wiki/DynDNS2.md b/docs/wiki/DynDNS2.md new file mode 100644 index 0000000..2fbd9ae --- /dev/null +++ b/docs/wiki/DynDNS2.md @@ -0,0 +1,15 @@ +Usage: +IPv4: http://user:pass@yournameserver.yoursite.tld/nic/update?hostname=record.domain.tld&myip=127.0.0.1 +IPv6: http://user:pass@yournameserver.yoursite.tld/nic/update?hostname=record.domain.tld&myip=::1 +Multiple IPs: http://user:pass@yournameserver.yoursite.tld/nic/update?hostname=record.domain.tld&myip=127.0.0.1,127.0.0.2,::1,::2 + +- user needs to be a LOCAL user, not LDAP etc +- user must have already logged-in +- user needs to be added to Domain Access Control list of domain.tld - admin status (manage all) does not suffice +- record has to exist already - unless on-demand creation is allowed +- ipv4 address in myip field will change A record +- ipv6 address in myip field will change AAAA record +- use commas to separate multiple IP addresses in the myip field, mixing v4 & v6 is allowed + +DynDNS also works without authentication header (user:pass@) when already authenticated via session cookie from /login, even with external auth like LDAP. +However Domain Access Control restriction still applies. \ No newline at end of file diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md new file mode 100644 index 0000000..7902a97 --- /dev/null +++ b/docs/wiki/Home.md @@ -0,0 +1,22 @@ +Welcome to the PowerDNS-Admin wiki! + +## Preparation guides +- [Prepare MySQL or MariaDB Database for PowerDNS-Admin](Prepare-MySQL-or-MariaDB-Database-for-PowerDNS-Admin) +- [Using PowerDNS-Admin with PostgreSQL](Using-PowerDNS-Admin-with-PostgreSQL) + +## Installation guides +- [Running PowerDNS Admin on Ubuntu or Debian](Running-PowerDNS-Admin-on-Ubuntu-or-Debian) +- [Running PowerDNS-Admin in Centos 7](Running-PowerDNS-Admin-on-Centos-7) +- [Running PowerDNS-Admin in Fedora 30](Running-PowerDNS-Admin-on-Fedora-30) +- [Running PowerDNS-Admin on FreeBSD 12.1-RELEASE](Running-on-FreeBSD) + +## Web Server configuration +- [Supervisord](Supervisord-example) +- [Systemd](Systemd-example) +- [Systemd + Gunicorn + Nginx](Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx) +- [Systemd + Gunicorn + Apache](Running-PowerDNS-Admin-with-Systemd,-Gunicorn-and-Apache) +- [uWSGI](uWSGI-example) +- [WSGI-Apache](WSGI-Apache-example) + +## Feature usage +- [DynDNS2](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/DynDNS2) \ No newline at end of file diff --git a/docs/wiki/Install-PowerDNS-Admin-in-Fedora-23.md b/docs/wiki/Install-PowerDNS-Admin-in-Fedora-23.md new file mode 100644 index 0000000..7f876ff --- /dev/null +++ b/docs/wiki/Install-PowerDNS-Admin-in-Fedora-23.md @@ -0,0 +1 @@ +Please refer to CentOS guide: https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/Running-PowerDNS-Admin-on-Centos-7 \ No newline at end of file diff --git a/docs/wiki/Prepare-MySQL-or-MariaDB-Database-for-PowerDNS-Admin.md b/docs/wiki/Prepare-MySQL-or-MariaDB-Database-for-PowerDNS-Admin.md new file mode 100644 index 0000000..774d3e3 --- /dev/null +++ b/docs/wiki/Prepare-MySQL-or-MariaDB-Database-for-PowerDNS-Admin.md @@ -0,0 +1,22 @@ +This guide will show you how to prepare a MySQL or MariaDB database for PowerDNS-Admin. + +### Step-by-step instructions +1. ivan@ubuntu:~$ `mysql -u root -p` (then enter your MySQL/MariaDB root users password) +2. mysql> `CREATE DATABASE powerdnsadmin CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;` +3. mysql> `GRANT ALL PRIVILEGES ON powerdnsadmin.* TO 'pdnsadminuser'@'%' IDENTIFIED BY 'p4ssw0rd';` +4. mysql> `FLUSH PRIVILEGES;` +5. mysql> `quit` + +**NOTE:** + +If you plan to manage large zones, you may encounter some issues while applying changes. +This is due to PowerDNS-Admin trying to insert the entire modified zone into the column history.detail. + +Using MySQL/MariaDB, this column is created by default as TEXT and thus limited to 65,535 characters. + +_Solution_: + +Convert the column to MEDIUMTEXT: + +* `USE powerdnsadmin;` +* `ALTER TABLE history MODIFY detail MEDIUMTEXT;` \ No newline at end of file diff --git a/docs/wiki/Running-PowerDNS-Admin-as-a-service-(Systemd).md b/docs/wiki/Running-PowerDNS-Admin-as-a-service-(Systemd).md new file mode 100644 index 0000000..df01179 --- /dev/null +++ b/docs/wiki/Running-PowerDNS-Admin-as-a-service-(Systemd).md @@ -0,0 +1,72 @@ +*** +**WARNING** +This just uses the development server for testing purposes. For production environments you should probably go with a more robust solution, like [gunicorn](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx) or a WSGI server. +*** + +### Following example shows a systemd unit file that can run PowerDNS-Admin + +You shouldn't run PowerDNS-Admin as _root_, so let's start of with the user/group creation that will later run PowerDNS-Admin: + +Create a new group for PowerDNS-Admin: + +> sudo groupadd powerdnsadmin + +Create a user for PowerDNS-Admin: + +> sudo useradd --system -g powerdnsadmin powerdnsadmin + +_`--system` creates a user without login-shell and password, suitable for running system services._ + +Create new systemd service file: + +> sudo vim /etc/systemd/system/powerdns-admin.service + +General example: +``` +[Unit] +Description=PowerDNS-Admin +After=network.target + +[Service] +Type=simple +User=powerdnsadmin +Group=powerdnsadmin +ExecStart=/opt/web/powerdns-admin/flask/bin/python ./run.py +WorkingDirectory=/opt/web/powerdns-admin +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +Debian example: +``` +[Unit] +Description=PowerDNS-Admin +After=network.target + +[Service] +Type=simple +User=powerdnsadmin +Group=powerdnsadmin +Environment=PATH=/opt/web/powerdns-admin/flask/bin +ExecStart=/opt/web/powerdns-admin/flask/bin/python /opt/web/powerdns-admin/run.py +WorkingDirectory=/opt/web/powerdns-admin +Restart=always + +[Install] +WantedBy=multi-user.target +``` +Before starting the service, we need to make sure that the new user can work on the files in the PowerDNS-Admin folder: +> chown -R powerdnsadmin:powerdnsadmin /opt/web/powerdns-admin + +After saving the file, we need to reload the systemd daemon: +> sudo systemctl daemon-reload + +We can now try to start the service: +> sudo systemctl start powerdns-admin + +If you would like to start PowerDNS-Admin automagically at startup enable the service: +> systemctl enable powerdns-admin + +Should the service not be up by now, consult your syslog. Generally this will be a file permission issue, or python not finding it's modules. See the Debian unit example to see how you can use systemd in a python `virtualenv` \ No newline at end of file diff --git a/docs/wiki/Running-PowerDNS-Admin-on-Centos-7.md b/docs/wiki/Running-PowerDNS-Admin-on-Centos-7.md new file mode 100644 index 0000000..e61485a --- /dev/null +++ b/docs/wiki/Running-PowerDNS-Admin-on-Centos-7.md @@ -0,0 +1,100 @@ +``` +NOTE: If you are logged in as User and not root, add "sudo", or get root by sudo -i. +``` +
+ +**Remove old Python 3.4**
+If you had it installed because of older instructions
+``` +yum remove python34* +yum autoremove +``` +
+ +## Install required packages +**Install needed repositories:** +
+``` +yum install epel-release +yum install https://repo.ius.io/ius-release-el7.rpm https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm +``` + +**Install Python 3.6 and tools** +``` +yum install python3 python3-devel python3-pip +pip3.6 install -U pip +pip install -U virtualenv +``` + +**Install required packages for building python libraries from requirements.txt file** +``` +--> NOTE: I am using MySQL Community server as the database backend. + So `mysql-community-devel` is required. For MariaDB, + and PostgreSQL the required package will be different. +``` + +If you use MariaDB ( from [MariaDB repositories](https://mariadb.com/resources/blog/installing-mariadb-10-on-centos-7-rhel-7/) ) + +``` +yum install gcc MariaDB-devel MariaDB-shared openldap-devel xmlsec1-devel xmlsec1-openssl libtool-ltdl-devel +``` + +If you use default Centos mariadb (5.5) +``` +yum install gcc mariadb-devel openldap-devel xmlsec1-devel xmlsec1-openssl libtool-ltdl-devel +``` + + +**Install yarn to build asset files + Nodejs 14** +``` +curl -sL https://rpm.nodesource.com/setup_14.x | bash - +curl -sL https://dl.yarnpkg.com/rpm/yarn.repo -o /etc/yum.repos.d/yarn.repo +yum install yarn +``` +
+ +## Checkout source code and create virtualenv +NOTE: Please adjust `/opt/web/powerdns-admin` to your local web application directory + +``` +git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /opt/web/powerdns-admin +cd /opt/web/powerdns-admin +virtualenv -p python3 flask +``` + +Activate your python3 environment and install libraries: +``` +. ./flask/bin/activate +pip install python-dotenv +pip install -r requirements.txt +``` +
+ +## Running PowerDNS-Admin +NOTE: The default config file is located at `./powerdnsadmin/default_config.py`. If you want to load another one, please set the `FLASK_CONF` environment variable. E.g. +```bash +export FLASK_CONF=../configs/development.py +``` + +**Then create the database schema by running:** +``` +export FLASK_APP=powerdnsadmin/__init__.py +flask db upgrade +``` + +**Also, we should generate asset files:** +``` +yarn install --pure-lockfile +flask assets build +``` + +**Now you can run PowerDNS-Admin by command:** +``` +./run.py +``` + +Open your web browser and access to `http://localhost:9191` to visit PowerDNS-Admin web interface. Register an user. The first user will be in Administrator role. + +At the first time you login into the PDA UI, you will be redirected to setting page to configure the PDNS API information. + +_**Note:**_ For production environment, i would recommend you to run PowerDNS-Admin with gunicorn or uwsgi instead of flask's built-in web server, take a look at WIKI page to see how to configure them. \ No newline at end of file diff --git a/docs/wiki/Running-PowerDNS-Admin-on-Fedora-30.md b/docs/wiki/Running-PowerDNS-Admin-on-Fedora-30.md new file mode 100644 index 0000000..e3b23ea --- /dev/null +++ b/docs/wiki/Running-PowerDNS-Admin-on-Fedora-30.md @@ -0,0 +1,83 @@ +``` +NOTE: If you are logged in as User and not root, add "sudo", or get root by sudo -i. + Normally under centos you are anyway mostly root. +``` +
+ +## Install required packages + +**Install Python and requirements** +```bash +dnf install python37 python3-devel python3-pip +``` +**Install Backend and Environment prerequisites** +```bash +dnf install mariadb-devel mariadb-common openldap-devel xmlsec1-devel xmlsec1-openssl libtool-ltdl-devel +``` +**Install Development tools** +```bash +dnf install gcc gc make +``` +**Install PIP** +```bash +pip3.7 install -U pip +``` +**Install Virtual Environment** +```bash +pip install -U virtualenv +``` + +**Install Yarn for building NodeJS asset files:** +```bash +dnf install npm +npm install yarn -g +``` + +## Clone the PowerDNS-Admin repository to the installation path: +```bash +cd /opt/web/ +git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git powerdns-admin +``` + +**Prepare the Virtual Environment:** +```bash +cd /opt/web/powerdns-admin +virtualenv -p python3 flask +``` +**Activate the Python Environment and install libraries** +```bash +. ./flask/bin/activate +pip install python-dotenv +pip install -r requirements.txt +``` + +## Running PowerDNS-Admin + +NOTE: The default config file is located at `./powerdnsadmin/default_config.py`. If you want to load another one, please set the `FLASK_CONF` environment variable. E.g. +```bash +export FLASK_CONF=../configs/development.py +``` + +**Then create the database schema by running:** +``` +(flask) [khanh@localhost powerdns-admin] export FLASK_APP=powerdnsadmin/__init__.py +(flask) [khanh@localhost powerdns-admin] flask db upgrade +``` + +**Also, we should generate asset files:** +``` +(flask) [khanh@localhost powerdns-admin] yarn install --pure-lockfile +(flask) [khanh@localhost powerdns-admin] flask assets build +``` + +**Now you can run PowerDNS-Admin by command:** +``` +(flask) [khanh@localhost powerdns-admin] ./run.py +``` + +Open your web browser and access to `http://localhost:9191` to visit PowerDNS-Admin web interface. Register an user. The first user will be in Administrator role. + +At the first time you login into the PDA UI, you will be redirected to setting page to configure the PDNS API information. + +_**Note:**_ For production environment, i recommend to run PowerDNS-Admin with WSGI over Apache instead of flask's built-in web server... + Take a look at [WSGI Apache Example](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/WSGI-Apache-example#fedora) WIKI page to see how to configure it. \ No newline at end of file diff --git a/docs/wiki/Running-PowerDNS-Admin-on-Ubuntu-or-Debian.md b/docs/wiki/Running-PowerDNS-Admin-on-Ubuntu-or-Debian.md new file mode 100644 index 0000000..1cdda78 --- /dev/null +++ b/docs/wiki/Running-PowerDNS-Admin-on-Ubuntu-or-Debian.md @@ -0,0 +1,94 @@ +## Install required packages + +**Install Python 3 development package** + +```bash +sudo apt install python3-dev +``` + +**Install required packages for building python libraries from requirements.txt file** + +```bash +sudo apt install -y git libmysqlclient-dev libsasl2-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev pkg-config apt-transport-https virtualenv build-essential curl +``` + +_**Note:**_ I am using MySQL Community server as the database backend. So `libmysqlclient-dev` is required. For MariaDB, and PostgreSQL the required package will be difference. + +** Install Maria or MySQL (ONLY if not ALREADY installed)** +```bash +sudo apt install mariadb-server mariadb-client +``` +Create database and user using mysql command and entering +```bash +>create database pda; +>grant all privileges on pda.* TO 'pda'@'localhost' identified by 'YOUR_PASSWORD_HERE'; +>flush privileges; +``` +**Install NodeJs** + +```bash +curl -sL https://deb.nodesource.com/setup_14.x | bash - +apt install -y nodejs +``` + +**Install yarn to build asset files** + +```bash +sudo curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list +sudo apt update -y +sudo apt install -y yarn +``` + +## Checkout source code and create virtualenv +_**Note:**_ Please adjust `/opt/web/powerdns-admin` to your local web application directory + +```bash +git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /opt/web/powerdns-admin +cd /opt/web/powerdns-admin +python3 -mvenv ./venv +``` + +Activate your python3 environment and install libraries: + +```bash +source ./venv/bin/activate +pip install --upgrade pip +pip install -r requirements.txt +``` + + + +## Running PowerDNS-Admin + +Create PowerDNS-Admin config file and make the changes necessary for your use case. Make sure to change `SECRET_KEY` to a long random string that you generated yourself ([see Flask docs](https://flask.palletsprojects.com/en/1.1.x/config/#SECRET_KEY)), do not use the pre-defined one. E.g.: + +```bash +cp /opt/web/powerdns-admin/configs/development.py /opt/web/powerdns-admin/configs/production.py +vim /opt/web/powerdns-admin/configs/production.py +export FLASK_CONF=../configs/production.py +``` + +Do the DB migration + +```bash +export FLASK_APP=powerdnsadmin/__init__.py +flask db upgrade +``` + +Then generate asset files + +```bash +yarn install --pure-lockfile +flask assets build +``` + +Now you can run PowerDNS-Admin by command + +```bash +./run.py +``` + +Open your web browser and go to `http://localhost:9191` to visit PowerDNS-Admin web interface. Register a user. The first user will be in the Administrator role. + +This is good for testing, but for production usage, you should use gunicorn or uwsgi. See [Running PowerDNS Admin with Systemd, Gunicorn and Nginx](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx) for instructions. \ No newline at end of file diff --git a/docs/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx.md b/docs/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx.md new file mode 100644 index 0000000..57725bc --- /dev/null +++ b/docs/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx.md @@ -0,0 +1,181 @@ +Following is an example showing how to run PowerDNS-Admin with systemd, gunicorn and nginx: + +## Configure PowerDNS-Admin + +Create PowerDNS-Admin config file and make the changes necessary for your use case. Make sure to change `SECRET_KEY` to a long random string that you generated yourself ([see Flask docs](https://flask.palletsprojects.com/en/1.1.x/config/#SECRET_KEY)), do not use the pre-defined one. +``` +$ cp /opt/web/powerdns-admin/configs/development.py /opt/web/powerdns-admin/configs/production.py +$ vim /opt/web/powerdns-admin/configs/production.py +``` + +## Configure systemd service + +`$ sudo vim /etc/systemd/system/powerdns-admin.service` + +``` +[Unit] +Description=PowerDNS-Admin +Requires=powerdns-admin.socket +After=network.target + +[Service] +PIDFile=/run/powerdns-admin/pid +User=pdns +Group=pdns +WorkingDirectory=/opt/web/powerdns-admin +ExecStartPre=+mkdir -p /run/powerdns-admin/ +ExecStartPre=+chown pdns:pdns -R /run/powerdns-admin/ +ExecStart=/usr/local/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 +``` + +`$ sudo systemctl edit powerdns-admin.service` + +``` +[Service] +Environment="FLASK_CONF=../configs/production.py" +``` + +`$ sudo vim /etc/systemd/system/powerdns-admin.socket` + +``` +[Unit] +Description=PowerDNS-Admin socket + +[Socket] +ListenStream=/run/powerdns-admin/socket + +[Install] +WantedBy=sockets.target +``` + +`$ sudo vim /etc/tmpfiles.d/powerdns-admin.conf` + +``` +d /run/powerdns-admin 0755 pdns pdns - +``` + +Then `sudo systemctl daemon-reload; sudo systemctl start powerdns-admin.socket; sudo systemctl enable powerdns-admin.socket` to start the Powerdns-Admin service and make it run on boot. + +## Sample nginx configuration +``` +server { + listen *:80; + server_name powerdns-admin.local www.powerdns-admin.local; + + index index.html index.htm index.php; + root /opt/web/powerdns-admin; + access_log /var/log/nginx/powerdns-admin.local.access.log combined; + error_log /var/log/nginx/powerdns-admin.local.error.log; + + 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 365d; + } + + location ~* ^.+.(css|js)$ { + expires 7d; + } + } + + location / { + proxy_pass http://unix:/run/powerdns-admin/socket; + proxy_read_timeout 120; + proxy_connect_timeout 120; + proxy_redirect off; + } + +} +``` + +
+Sample Nginx-Configuration for SSL + +* Im binding this config to every dns-name with default_server... +* but you can remove it and set your server_name. + +``` +server { + listen 80 default_server; + server_name ""; + return 301 https://$http_host$request_uri; +} + +server { + listen 443 ssl http2 default_server; + server_name _; + index index.html index.htm; + error_log /var/log/nginx/error_powerdnsadmin.log error; + access_log off; + + ssl_certificate path_to_your_fullchain_or_cert; + ssl_certificate_key path_to_your_key; + ssl_dhparam path_to_your_dhparam.pem; + ssl_prefer_server_ciphers on; + ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; + ssl_session_cache shared:SSL:10m; + + 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 $http_host; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_headers_hash_bucket_size 64; + + location ~ ^/static/ { + include mime.types; + root /opt/web/powerdns-admin/powerdnsadmin; + location ~* \.(jpg|jpeg|png|gif)$ { expires 365d; } + location ~* ^.+.(css|js)$ { expires 7d; } + } + + location ~ ^/upload/ { + include mime.types; + root /opt/web/powerdns-admin; + location ~* \.(jpg|jpeg|png|gif)$ { expires 365d; } + location ~* ^.+.(css|js)$ { expires 7d; } + } + + location / { + proxy_pass http://unix:/run/powerdns-admin/socket; + proxy_read_timeout 120; + proxy_connect_timeout 120; + proxy_redirect http:// $scheme://; + } +} +``` +
+ +## Note +* `/opt/web/powerdns-admin` is the path to your powerdns-admin web directory +* Make sure you have installed gunicorn in flask virtualenv already. +* `powerdns-admin.local` just an example of your web domain name. \ No newline at end of file diff --git a/docs/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn-and-Apache.md b/docs/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn-and-Apache.md new file mode 100644 index 0000000..a2d4fa2 --- /dev/null +++ b/docs/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn-and-Apache.md @@ -0,0 +1,97 @@ +Following is an example showing how to run PowerDNS-Admin with systemd, gunicorn and Apache: + +The systemd and gunicorn setup are the same as for with nginx. This set of configurations assumes you have installed your PowerDNS-Admin under /opt/powerdns-admin and are running with a package-installed gunicorn. + +## Configure systemd service + +`$ sudo vim /etc/systemd/system/powerdns-admin.service` + +``` +[Unit] +Description=PowerDNS web administration service +Requires=powerdns-admin.socket +Wants=network.target +After=network.target mysqld.service postgresql.service slapd.service mariadb.service + +[Service] +PIDFile=/run/powerdns-admin/pid +User=pdnsa +Group=pdnsa +WorkingDirectory=/opt/powerdns-admin +ExecStart=/usr/bin/gunicorn-3.6 --workers 4 --log-level info --pid /run/powerdns-admin/pid --bind unix:/run/powerdns-admin/socket "powerdnsadmin:create_app(config='config.py')" +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s TERM $MAINPID +PrivateTmp=true +Restart=on-failure +RestartSec=10 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target +``` + +`$ sudo vim /etc/systemd/system/powerdns-admin.socket` + +``` +[Unit] +Description=PowerDNS-Admin socket + +[Socket] +ListenStream=/run/powerdns-admin/socket + +[Install] +WantedBy=sockets.target +``` + +`$ sudo vim /etc/tmpfiles.d/powerdns-admin.conf` + +``` +d /run/powerdns-admin 0755 pdnsa pdnsa - +``` + +Then `sudo systemctl daemon-reload; sudo systemctl start powerdns-admin.socket; sudo systemctl enable powerdns-admin.socket` to start the Powerdns-Admin service and make it run on boot. + +## Sample Apache configuration + +This includes SSL redirect. + +``` + + ServerName dnsadmin.company.com + DocumentRoot "/opt/powerdns-admin" + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + Require all granted + + Redirect permanent / https://dnsadmin.company.com/ + + + ServerName dnsadmin.company.com + DocumentRoot "/opt/powerdns-admin/powerdnsadmin" + ## Alias declarations for resources outside the DocumentRoot + Alias /static/ "/opt/powerdns-admin/powerdnsadmin/static/" + Alias /favicon.ico "/opt/powerdns-admin/powerdnsadmin/static/favicon.ico" + + AllowOverride None + Require all granted + + ## Proxy rules + ProxyRequests Off + ProxyPreserveHost On + ProxyPass /static/ ! + ProxyPass /favicon.ico ! + ProxyPass / unix:/var/run/powerdns-admin/socket|http://%{HTTP_HOST}/ + ProxyPassReverse / unix:/var/run/powerdns-admin/socket|http://%{HTTP_HOST}/ + ## SSL directives + SSLEngine on + SSLCertificateFile "/etc/pki/tls/certs/dnsadmin.company.com.crt" + SSLCertificateKeyFile "/etc/pki/tls/private/dnsadmin.company.com.key" + +``` + +## Notes +* The above assumes your installation is under /opt/powerdns-admin +* The hostname is assumed as dnsadmin.company.com +* gunicorn is installed in /usr/bin via a package (as in the case with CentOS/Redhat 7) and you have Python 3.6 installed. If you prefer to use flask then see the systemd configuration for nginx. +* On Ubuntu / Debian systems, you may need to enable the "proxy_http" module with `a2enmod proxy_http` diff --git a/docs/wiki/Running-on-FreeBSD.md b/docs/wiki/Running-on-FreeBSD.md new file mode 100644 index 0000000..76a8f5b --- /dev/null +++ b/docs/wiki/Running-on-FreeBSD.md @@ -0,0 +1,102 @@ +On [FreeBSD](https://www.freebsd.org/), most software is installed using `pkg`. You can always build from source with the Ports system. This method uses as many binary ports as possible, and builds some python packages from source. It installs all the required runtimes in the global system (e.g., python, node, yarn) and then builds a virtual python environment in `/opt/python`. Likewise, it installs powerdns-admin in `/opt/powerdns-admin`. + +### Build an area to host files + +```bash +mkdir -p /opt/python +``` + +### Install prerequisite runtimes: python, node, yarn + +```bash +sudo pkg install git python3 curl node12 yarn-node12 +sudo pkg install libxml2 libxslt pkgconf py37-xmlsec py37-cffi py37-ldap +``` + +## Check Out Source Code +_**Note:**_ Please adjust `/opt/powerdns-admin` to your local web application directory + +```bash +git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /opt/powerdns-admin +cd /opt/powerdns-admin +``` + +## Make Virtual Python Environment + +Make a virtual environment for python. Activate your python3 environment and install libraries. It's easier to install some python libraries as system packages, so we add the `--system-site-packages` option to pull those in. + +> Note: I couldn't get `python-ldap` to install correctly, and I don't need it. I commented out the `python-ldap` line in `requirements.txt` and it all built and installed correctly. If you don't intend to use LDAP authentication, you'll be fine. If you need LDAP authentication, it probably won't work. + +```bash +python3 -m venv /web/python --system-site-packages +source /web/python/bin/activate +/web/python/bin/python3 -m pip install --upgrade pip wheel +# this command comments out python-ldap +perl -pi -e 's,^python-ldap,\# python-ldap,' requirements.txt +pip3 install -r requirements.txt +``` + +## Configuring PowerDNS-Admin + +NOTE: The default config file is located at `./powerdnsadmin/default_config.py`. If you want to load another one, please set the `FLASK_CONF` environment variable. E.g. +```bash +cp configs/development.py /opt/powerdns-admin/production.py +export FLASK_CONF=/opt/powerdns-admin/production.py +``` + +### Update the Flask config + +Edit your flask python configuration. Insert values for the database server, user name, password, etc. + +```bash +vim $FLASK_CONF +``` + +Edit the values below to something sensible +```python +### BASIC APP CONFIG +SALT = '[something]' +SECRET_KEY = '[something]' +BIND_ADDRESS = '0.0.0.0' +PORT = 9191 +OFFLINE_MODE = False + +### DATABASE CONFIG +SQLA_DB_USER = 'pda' +SQLA_DB_PASSWORD = 'changeme' +SQLA_DB_HOST = '127.0.0.1' +SQLA_DB_NAME = 'pda' +SQLALCHEMY_TRACK_MODIFICATIONS = True +``` + +Be sure to uncomment one of the lines like `SQLALCHEMY_DATABASE_URI`. + +### Initialise the database + +```bash +export FLASK_APP=powerdnsadmin/__init__.py +flask db upgrade +``` + +### Build web assets + +```bash +yarn install --pure-lockfile +flask assets build +``` + +## Running PowerDNS-Admin + +Now you can run PowerDNS-Admin by command + +```bash +./run.py +``` + +Open your web browser and go to `http://localhost:9191` to visit PowerDNS-Admin web interface. Register a user. The first user will be in the Administrator role. + +### Running at startup + +This is good for testing, but for production usage, you should use gunicorn or uwsgi. See [Running PowerDNS Admin with Systemd, Gunicorn and Nginx](https://github.com/ngoduykhanh/PowerDNS-Admin/wiki/Running-PowerDNS-Admin-with-Systemd,-Gunicorn--and--Nginx) for instructions. + +The right approach long-term is to create a startup script in `/usr/local/etc/rc.d` and enable it through `/etc/rc.conf`. \ No newline at end of file diff --git a/docs/wiki/Supervisord-example.md b/docs/wiki/Supervisord-example.md new file mode 100644 index 0000000..11cebc8 --- /dev/null +++ b/docs/wiki/Supervisord-example.md @@ -0,0 +1,18 @@ +Following is an example showing how to run PowerDNS-Admin with supervisord + +Create supervisord program config file +``` +$ sudo vim /etc/supervisor.d/powerdnsadmin.conf +``` + +``` +[program:powerdnsadmin] +command=/opt/web/powerdns-admin/flask/bin/python ./run.py +stdout_logfile=/var/log/supervisor/program_powerdnsadmin.log +stderr_logfile=/var/log/supervisor/program_powerdnsadmin.error +autostart=true +autorestart=true +directory=/opt/web/powerdns-admin +``` + +Then `sudo supervisorctl start powerdnsadmin` to start the Powerdns-Admin service. \ No newline at end of file diff --git a/docs/wiki/Systemd-example.md b/docs/wiki/Systemd-example.md new file mode 100644 index 0000000..d7f738b --- /dev/null +++ b/docs/wiki/Systemd-example.md @@ -0,0 +1,50 @@ +## Configure systemd service + +This example uses package-installed gunicorn (instead of flask-installed) and PowerDNS-Admin installed under /opt/powerdns-admin + +`$ sudo vim /etc/systemd/system/powerdns-admin.service` + +``` +[Unit] +Description=PowerDNS web administration service +Requires=powerdns-admin.socket +Wants=network.target +After=network.target mysqld.service postgresql.service slapd.service mariadb.service + +[Service] +PIDFile=/run/powerdns-admin/pid +User=pdnsa +Group=pdnsa +WorkingDirectory=/opt/powerdns-admin +ExecStart=/usr/bin/gunicorn-3.6 --workers 4 --log-level info --pid /run/powerdns-admin/pid --bind unix:/run/powerdns-admin/socket "powerdnsadmin:create_app(config='config.py')" +ExecReload=/bin/kill -s HUP $MAINPID +ExecStop=/bin/kill -s TERM $MAINPID +PrivateTmp=true +Restart=on-failure +RestartSec=10 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target +``` + +`$ sudo vim /etc/systemd/system/powerdns-admin.socket` + +``` +[Unit] +Description=PowerDNS-Admin socket + +[Socket] +ListenStream=/run/powerdns-admin/socket + +[Install] +WantedBy=sockets.target +``` + +`$ sudo vim /etc/tmpfiles.d/powerdns-admin.conf` + +``` +d /run/powerdns-admin 0755 pdns pdns - +``` + +Then `sudo systemctl daemon-reload; sudo systemctl start powerdns-admin.socket; sudo systemctl enable powerdns-admin.socket` to start the Powerdns-Admin service and make it run on boot. diff --git a/docs/wiki/Using-PowerDNS-Admin-with-PostgreSQL.md b/docs/wiki/Using-PowerDNS-Admin-with-PostgreSQL.md new file mode 100644 index 0000000..04155e9 --- /dev/null +++ b/docs/wiki/Using-PowerDNS-Admin-with-PostgreSQL.md @@ -0,0 +1,38 @@ +If you would like to use PostgreSQL instead of MySQL or MariaDB, you have to install difference dependencies. Check the following instructions. + +### Install dependencies +``` +$ sudo yum install postgresql-libs +$ pip install psycopg2 +``` + +### Create database +``` +$ sudo su - postgres +$ createuser powerdnsadmin +$ createdb powerdnsadmindb +$ psql +postgres=# alter user powerdnsadmin with encrypted password 'powerdnsadmin'; +postgres=# grant all privileges on database powerdnsadmindb to powerdnsadmin; +``` + +In your `config.py` file, make sure you have +``` +SQLALCHEMY_DATABASE_URI = 'postgresql://powerdnsadmin:powerdnsadmin@127.0.0.1/powerdnsadmindb' +``` + +Note: +- Please change the information above (db, user, password) to fit your setup. +- You might need to adjust your PostgreSQL's `pg_hba.conf` config file to allow password authentication for networks. + +### Use Docker +``` +docker run --name pdnsadmin-test -e BIND_ADDRESS=0.0.0.0 +-e SECRET_KEY='a-very-secret-key' +-e PORT='9191' +-e SQLA_DB_USER='powerdns_admin_user' +-e SQLA_DB_PASSWORD='exceptionallysecure' +-e SQLA_DB_HOST='192.168.0.100' +-e SQLA_DB_NAME='powerdns_admin_test' +-v /data/node_modules:/var/www/powerdns-admin/node_modules -d -p 9191:9191 ixpict/powerdns-admin-pgsql:latest +``` \ No newline at end of file diff --git a/docs/wiki/WSGI-Apache-example.md b/docs/wiki/WSGI-Apache-example.md new file mode 100644 index 0000000..d31e4f7 --- /dev/null +++ b/docs/wiki/WSGI-Apache-example.md @@ -0,0 +1,100 @@ +How to run PowerDNS-Admin via WSGI and Apache2.4 using mod_wsgi. + +**Note**: You must install mod_wsgi by using pip3 instead of system default mod_wsgi!!! + +### Ubuntu/Debian +```shell +# apt install apache2-dev +# virtualenv -p python3 flask +# source ./flask/bin/activate +(flask) # pip3 install mod-wsgi +(flask) # mod_wsgi-express install-module > /etc/apache2/mods-available/wsgi.load +(flask) # a2enmod wsgi +(flask) # systemctl restart apache2 +``` +### CentOS +```shell +# yum install httpd-devel +# virtualenv -p python3 flask +# source ./flask/bin/activate +(flask) # pip3 install mod-wsgi +(flask) # mod_wsgi-express install-module > /etc/httpd/conf.modules.d/02-wsgi.conf +(flask) # systemctl restart httpd +``` +### Fedora +```bash +# Install Apache's Development interfaces and package requirements +dnf install httpd-devel gcc gc make +virtualenv -p python3 flask +source ./flask/bin/activate +# Install WSGI for HTTPD +pip install mod_wsgi-httpd +# Install WSGI +pip install mod-wsgi +# Enable the module in Apache: +mod_wsgi-express install-module > /etc/httpd/conf.modules.d/02-wsgi.conf +systemctl restart httpd +``` + +Apache vhost configuration; +```apache + + ServerName superawesomedns.foo.bar + ServerAlias [fe80::1] + ServerAdmin webmaster@foo.bar + + SSLEngine On + SSLCertificateFile /some/path/ssl/certs/cert.pem + SSLCertificateKeyFile /some/path/ssl/private/cert.key + + ErrorLog /var/log/apache2/error-superawesomedns.foo.bar.log + CustomLog /var/log/apache2/access-superawesomedns.foo.bar.log combined + + DocumentRoot /srv/vhosts/superawesomedns.foo.bar/ + + WSGIDaemonProcess pdnsadmin user=pdnsadmin group=pdnsadmin threads=5 + WSGIScriptAlias / /srv/vhosts/superawesomedns.foo.bar/powerdnsadmin.wsgi + + # pass BasicAuth on to the WSGI process + WSGIPassAuthorization On + + + WSGIProcessGroup pdnsadmin + WSGIApplicationGroup %{GLOBAL} + + AllowOverride None + Options +ExecCGI +FollowSymLinks + SSLRequireSSL + AllowOverride None + Require all granted + + +``` +**In Fedora, you might want to change the following line:** +```apache +WSGIDaemonProcess pdnsadmin socket-user=apache user=pdnsadmin group=pdnsadmin threads=5 +``` +**And you should add the following line to `/etc/httpd/conf/httpd.conf`:** +```apache +WSGISocketPrefix /var/run/wsgi +``` + +Content of `/srv/vhosts/superawesomedns.foo.bar/powerdnsadmin.wsgi`; +```python +#!/usr/bin/env python3 +import sys +sys.path.insert(0, '/srv/vhosts/superawesomedns.foo.bar') + +from app import app as application +``` +Starting from 0.2 version, the `powerdnsadmin.wsgi` file is slighty different : +```python +#!/usr/bin/env python3 +import sys +sys.path.insert(0, '/srv/vhosts/superawesomedns.foo.bar') + +from powerdnsadmin import create_app +application = create_app() +``` + +(this implies that the pdnsadmin user/group exists, and that you have mod_wsgi loaded) \ No newline at end of file diff --git a/docs/wiki/images/readme_screenshots/fullscreen-dashboard.png b/docs/wiki/images/readme_screenshots/fullscreen-dashboard.png new file mode 100644 index 0000000..828fc48 Binary files /dev/null and b/docs/wiki/images/readme_screenshots/fullscreen-dashboard.png differ diff --git a/docs/wiki/images/readme_screenshots/fullscreen-domaincreate.png b/docs/wiki/images/readme_screenshots/fullscreen-domaincreate.png new file mode 100644 index 0000000..ceb2d00 Binary files /dev/null and b/docs/wiki/images/readme_screenshots/fullscreen-domaincreate.png differ diff --git a/docs/wiki/images/readme_screenshots/fullscreen-domainmanage.png b/docs/wiki/images/readme_screenshots/fullscreen-domainmanage.png new file mode 100644 index 0000000..998bf9e Binary files /dev/null and b/docs/wiki/images/readme_screenshots/fullscreen-domainmanage.png differ diff --git a/docs/wiki/images/readme_screenshots/fullscreen-login.png b/docs/wiki/images/readme_screenshots/fullscreen-login.png new file mode 100644 index 0000000..4d95472 Binary files /dev/null and b/docs/wiki/images/readme_screenshots/fullscreen-login.png differ diff --git a/docs/wiki/images/webui/create.jpg b/docs/wiki/images/webui/create.jpg new file mode 100644 index 0000000..3707735 Binary files /dev/null and b/docs/wiki/images/webui/create.jpg differ diff --git a/docs/wiki/images/webui/index.jpg b/docs/wiki/images/webui/index.jpg new file mode 100644 index 0000000..33f0ded Binary files /dev/null and b/docs/wiki/images/webui/index.jpg differ diff --git a/docs/wiki/images/webui/login.jpg b/docs/wiki/images/webui/login.jpg new file mode 100644 index 0000000..08bb3c1 Binary files /dev/null and b/docs/wiki/images/webui/login.jpg differ diff --git a/docs/wiki/uWSGI-example.md b/docs/wiki/uWSGI-example.md new file mode 100644 index 0000000..d50455d --- /dev/null +++ b/docs/wiki/uWSGI-example.md @@ -0,0 +1,49 @@ +This guide will show you how to run PowerDNS-Admin via uWSGI and nginx. This guide was written using Debian 8 with the following software versions: +- nginx 1.6.2 +- uwsgi 2.0.7-debian +- python 2.7.9 + +`sudo apt-get install uwsgi uwsgi-plugin-python nginx` + +### Step-by-step instructions +1. Create a uWSGI .ini in `/etc/uwsgi/apps-enabled` with the following contents, making sure to replace the chdir, pythonpath and virtualenv directories with where you've installed PowerDNS-Admin: + ```ini + [uwsgi] + plugins = python27 + + uid=www-data + gid=www-data + + chdir = /opt/pdns-admin/PowerDNS-Admin/ + pythonpath = /opt/pdns-admin/PowerDNS-Admin/ + virtualenv = /opt/pdns-admin/PowerDNS-Admin/flask + + mount = /pdns=powerdnsadmin:create_app() + manage-script-name = true + + vacuum = true + harakiri = 20 + buffer-size = 32768 + post-buffering = 8192 + socket = /run/uwsgi/app/%n/%n.socket + chown-socket = www-data + pidfile = /run/uwsgi/app/%n/%n.pid + + daemonize = /var/log/uwsgi/app/%n.log + enable-threads + ``` +2. Add the following configuration to your nginx config: + ```nginx + location / { try_files $uri @pdns_admin; } + + location @pdns_admin { + include uwsgi_params; + uwsgi_pass unix:/run/uwsgi/app/pdns-admin/pdns-admin.socket; + } + + location /pdns/static/ { + alias /opt/pdns-admin/PowerDNS-Admin/app/static/; + } + ``` +3. Restart nginx and uwsgi. +4. You're done and PowerDNS-Admin will now be available via nginx. \ No newline at end of file