diff --git a/powerdns-admin/defaults/main.yml b/powerdns-admin/defaults/main.yml new file mode 100644 index 00000000..4e49c219 --- /dev/null +++ b/powerdns-admin/defaults/main.yml @@ -0,0 +1,27 @@ +--- +pdns_admin_install: True +pdns_admin_dir: 'pdns_admin-{{ pdns_admin_version }}.linux-amd64' +pdns_admin_git_repo_url: 'https://github.com/ngoduykhanh/PowerDNS-Admin.git' +pdns_admin_user: pdnsadmin +pdns_admin_home: /opt/pdnsadmin +pdns_admin_cmd: '{{ pdns_admin_dist_dir }}/{{ pdns_admin_dir }}/pdns_admin' +pdns_admin_http_port: 9393 +pdns_admin_opts: '' +pdns_admin_loglevel: 'WARN' +pdns_admin_logdir: '/var/log/pdnsadmin' +pdns_admin_logfile: '{{ pdns_admin_logdir }}/pdnsadmin.log' + +pdns_admin_prereqs: + - git + - python3 + - python3-pip + - python3-virtualenv + - python3-dev + - libmysqlclient-dev + - libxmlsec1-dev + - pkg-config + - libpq-dev + - libsasl2-dev + - libldap2-dev + - libssl-dev + - python3-psycopg2 \ No newline at end of file diff --git a/powerdns-admin/handlers/main.yml b/powerdns-admin/handlers/main.yml new file mode 100644 index 00000000..b2850d61 --- /dev/null +++ b/powerdns-admin/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: Restart pdns_admin + service: name=powerdns-admin state=restarted + diff --git a/powerdns-admin/meta/main.yml b/powerdns-admin/meta/main.yml new file mode 100644 index 00000000..f1749521 --- /dev/null +++ b/powerdns-admin/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: '../../library/roles/nginx' diff --git a/powerdns-admin/tasks/main.yml b/powerdns-admin/tasks/main.yml new file mode 100644 index 00000000..dc684a85 --- /dev/null +++ b/powerdns-admin/tasks/main.yml @@ -0,0 +1,74 @@ +--- +- block: + - name: Create the user under pdns_admin will run + user: name={{ pdns_admin_user }} home={{ pdns_admin_home }} createhome=no shell=/usr/sbin/nologin system=yes + + - name: Create the pdns_admin server base directory + file: dest={{ item }} state=directory owner=root group=root + with_items: + - '{{ pdns_admin_home }}' + + - name: Create the pdns_admin server log directory + file: dest={{ item }} state=directory owner={{ pdns_admin_user }} group={{ pdns_admin_user }} + with_items: + - '{{ pdns_admin_logdir }}' + + - name: Install the pdns_admin prerequisite deb packages + apt: pkg={{ item }} state=present update_cache=yes cache_valid_time=1800 + with_items: '{{ pdns_admin_prereqs }}' + + - name: Clone pdns_admin + git: repo={{ pdns_admin_git_repo_url }} dest={{ pdns_admin_home }} + + - name: Make the upload directory writeable by the pdnsadmin user + file: dest={{ pdns_admin_home }}/upload recurse=yes owner={{ pdns_admin_user }} group={{ pdns_admin_user }} + + - name: Install the pdns_admin configuration + template: src=config.py dest={{ pdns_admin_home }}/config.py + notify: Restart pdns_admin + + - name: Create a python3 virtualenv + shell: cd {{ pdns_admin_home }} ; virtualenv -p python3 flask + args: + creates: '{{ pdns_admin_home }}/flask' + notify: Restart pdns_admin + + - name: Install the virtualenv requirements + pip: requirements={{ pdns_admin_home }}/requirements.txt virtualenv={{ pdns_admin_home }}/flask virtualenv_site_packages=True + notify: Restart pdns_admin + + - name: Install psycopg2 as an additional requirement + pip: name=psycopg2-binary virtualenv={{ pdns_admin_home }}/flask + notify: Restart pdns_admin + + - name: Initialise the database + shell: cd {{ pdns_admin_home }}; . {{ pdns_admin_home }}/flask/bin/activate ; ./create_db.py ; touch {{ pdns_admin_logdir }}/.db_initialised + args: + creates: '{{ pdns_admin_logdir }}/.db_initialised' + + - name: Install the pdns_admin server systemd unit + template: src=powerdns-admin.service dest=/etc/systemd/system/powerdns-admin.service mode=0644 owner=root group=root + when: ansible_service_mgr == 'systemd' + notify: systemd reload + + - name: Ensure that pdns_admin is started and enabled + service: name=powerdns-admin state=started enabled=yes + + tags: pdns_admin + when: pdns_admin_install + +- block: + - name: Ensure that pdns_admin is stopped and disabled + service: name=powerdns-admin state=stopped enabled=no + + - name: Remove the pdns_admin init script + file: dest=/etc/systemd/system/powerdns-admin.service state=absent + + - name: Remove all the pdns_admin files + file: dest={{ item }} state=absent + with_items: + - '{{ pdns_admin_home }}' + - '{{ pdns_admin_logdir }}' + + tags: pdns_admin + when: not pdns_admin_install diff --git a/powerdns-admin/templates/config.py b/powerdns-admin/templates/config.py new file mode 100644 index 00000000..301ff1fb --- /dev/null +++ b/powerdns-admin/templates/config.py @@ -0,0 +1,116 @@ +import os +basedir = os.path.abspath(os.path.dirname(__file__)) + +# BASIC APP CONFIG +WTF_CSRF_ENABLED = True +SECRET_KEY = '{{ pdns_admin_secret_key }}' +BIND_ADDRESS = '127.0.0.1' +PORT = {{ pdns_admin_http_port }} +LOGIN_TITLE = "PowerDNS Admin" + +# TIMEOUT - for large zones +TIMEOUT = 60 + +# LOG CONFIG +LOG_LEVEL = '{{ pdns_admin_loglevel }}' +LOG_FILE = '{{ pdns_admin_logfile }}' + +# Upload +UPLOAD_DIR = os.path.join(basedir, 'upload') + +SQLALCHEMY_DATABASE_URI = 'postgresql://{{ pdns_admin_db_user }}:{{ pdns_admin_db_pwd }}@{{ pdns_admin_db_host }}/{{ pdns_admin_db_name }}' +SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository') +SQLALCHEMY_TRACK_MODIFICATIONS = True + +# LDAP CONFIG +LDAP_ENABLED = False +LDAP_TYPE = 'ldap' +LDAP_URI = 'ldaps://your-ldap-server:636' +# with LDAP_BIND_TYPE you can specify 'direct' or 'search' to use user credentials +# for binding or a predefined LDAP_USERNAME and LDAP_PASSWORD, binding with non-DN only works with AD +LDAP_BIND_TYPE= 'direct' # direct or search +LDAP_USERNAME = 'cn=dnsuser,ou=users,ou=services,dc=duykhanh,dc=me' +LDAP_PASSWORD = 'dnsuser' +LDAP_SEARCH_BASE = 'ou=System Admins,ou=People,dc=duykhanh,dc=me' +LDAP_GROUP_SECURITY = False +LDAP_ADMIN_GROUP = 'CN=PowerDNS-Admin Admin,OU=Custom,DC=ivan,DC=local' +LDAP_USER_GROUP = 'CN=PowerDNS-Admin User,OU=Custom,DC=ivan,DC=local' +# Additional options only if LDAP_TYPE=ldap +LDAP_USERNAMEFIELD = 'uid' +LDAP_FILTER = '(objectClass=inetorgperson)' +# enable LDAP_GROUP_SECURITY to allow Admin and User roles based on LDAP groups +#LDAP_GROUP_SECURITY = True # True or False +#LDAP_ADMIN_GROUP = 'CN=DnsAdmins,CN=Users,DC=example,DC=me' +#LDAP_USER_GROUP = 'CN=Domain Admins,CN=Users,DC=example,DC=me' + +## AD CONFIG +#LDAP_TYPE = 'ad' +#LDAP_URI = 'ldaps://your-ad-server:636' +#LDAP_USERNAME = 'cn=dnsuser,ou=Users,dc=domain,dc=local' +#LDAP_PASSWORD = 'dnsuser' +#LDAP_SEARCH_BASE = 'dc=domain,dc=local' +## You may prefer 'userPrincipalName' instead +#LDAP_USERNAMEFIELD = 'sAMAccountName' +## AD Group that you would like to have accesss to web app +#LDAP_FILTER = 'memberof=cn=DNS_users,ou=Groups,dc=domain,dc=local' + +# Github Oauth +GITHUB_OAUTH_ENABLE = False +GITHUB_OAUTH_KEY = '' +GITHUB_OAUTH_SECRET = '' +GITHUB_OAUTH_SCOPE = 'email' +GITHUB_OAUTH_URL = 'http://127.0.0.1:9191/api/v3/' +GITHUB_OAUTH_TOKEN = 'http://127.0.0.1:9191/oauth/token' +GITHUB_OAUTH_AUTHORIZE = 'http://127.0.0.1:9191/oauth/authorize' + + +# Google OAuth +GOOGLE_OAUTH_ENABLE = False +GOOGLE_OAUTH_CLIENT_ID = ' ' +GOOGLE_OAUTH_CLIENT_SECRET = ' ' +GOOGLE_REDIRECT_URI = '/user/authorized' +GOOGLE_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token' +GOOGLE_TOKEN_PARAMS = { + 'scope': 'email profile' +} +GOOGLE_AUTHORIZE_URL='https://accounts.google.com/o/oauth2/auth' +GOOGLE_BASE_URL='https://www.googleapis.com/oauth2/v1/' + +# SAML Authnetication +SAML_ENABLED = False +SAML_DEBUG = True +SAML_PATH = os.path.join(os.path.dirname(__file__), 'saml') +##Example for ADFS Metadata-URL +SAML_METADATA_URL = 'https:///FederationMetadata/2007-06/FederationMetadata.xml' +#Cache Lifetime in Seconds +SAML_METADATA_CACHE_LIFETIME = 1 +SAML_SP_ENTITY_ID = 'http://' +SAML_SP_CONTACT_NAME = '' +SAML_SP_CONTACT_MAIL = '' +#Cofigures if SAML tokens should be encrypted. +#If enabled a new app certificate will be generated on restart +SAML_SIGN_REQUEST = False +#Use SAML standard logout mechanism retreived from idp metadata +#If configured false don't care about SAML session on logout. +#Logout from PowerDNS-Admin only and keep SAML session authenticated. +SAML_LOGOUT = False +#Configure to redirect to a different url then PowerDNS-Admin login after SAML logout +#for example redirect to google.com after successful saml logout +#SAML_LOGOUT_URL = 'https://google.com' + +#Default Auth +BASIC_ENABLED = True +SIGNUP_ENABLED = True + +# POWERDNS CONFIG +PDNS_STATS_URL = 'http://{{ pdns_master_host }}:8081/' +PDNS_API_KEY = '{{ pdns_auth_api_key }}' +PDNS_VERSION = '4.2.1' + +# RECORDS ALLOWED TO EDIT +RECORDS_ALLOW_EDIT = ['SOA', 'A', 'AAAA', 'CAA', 'CNAME', 'MX', 'PTR', 'SPF', 'SRV', 'TXT', 'LOC', 'NS', 'PTR'] +FORWARD_RECORDS_ALLOW_EDIT = ['A', 'AAAA', 'CAA', 'CNAME', 'MX', 'PTR', 'SPF', 'SRV', 'TXT', 'LOC' 'NS'] +REVERSE_RECORDS_ALLOW_EDIT = ['SOA', 'TXT', 'LOC', 'NS', 'PTR'] + +# EXPERIMENTAL FEATURES +PRETTY_IPV6_PTR = False diff --git a/powerdns-admin/templates/powerdns-admin.service b/powerdns-admin/templates/powerdns-admin.service new file mode 100644 index 00000000..d85c4479 --- /dev/null +++ b/powerdns-admin/templates/powerdns-admin.service @@ -0,0 +1,14 @@ +[Unit] +Description=PowerDNS-Admin +After=network.target + +[Service] +Type=simple +User={{ pdns_admin_user }} +Group={{ pdns_admin_user }} +ExecStart={{ pdns_admin_home }}/flask/bin/python ./run.py +WorkingDirectory={{ pdns_admin_home }} +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/powerdns-admin/vars/main.yml b/powerdns-admin/vars/main.yml new file mode 100644 index 00000000..945e4fb8 --- /dev/null +++ b/powerdns-admin/vars/main.yml @@ -0,0 +1,22 @@ +--- +http_port: 80 +https_port: 443 +nginx_letsencrypt_managed: True +nginx_use_common_virthost: True +nginx_virthosts: + - virthost_name: '{{ ansible_fqdn }}' + listen: '{{ http_port }}' + server_name: '{{ ansible_fqdn }}' + server_aliases: '' + index: index.html + ssl_enabled: True + ssl_only: True + ssl_letsencrypt_certs: '{{ nginx_letsencrypt_managed }}' + root: '{{ nginx_webroot }}' + server_tokens: 'off' + proxy_standard_setup: True + locations: + - location: / + target: http://localhost:{{ pdns_admin_http_port }} + +