operasoftware / dns-ui

Opera's LDAP-authenticated PowerDNS user interface
Apache License 2.0
283 stars 57 forks source link

dns-ui with docker (with local user authentication) #54

Open christianbur opened 6 years ago

christianbur commented 6 years ago

Hello,

Thanks for the nice pdns GUI :-) I'm going to build pdns and your gui with docker, i almost succeeded. However, I fail at the user authentication in dns-ui. I do not need LDAP authentication for my small project so I would like to use a local user authentication. In the demo I saw that I can create local users (Users -> Create User ->"You can create users in the local directory here".) Currently I am getting the PHP error "Not logged in.", because the varialbe PHP_AUTH_USER is not set. In the GUI I am getting the error "Oops! Something went wrong!"

What settings (Apache, PHP, dns-ui, dns-ui-db) must be made in a new installation to use local authentication?

thomas-pike commented 6 years ago

DNS UI doesn't handle any authentication[1] (yet), so you need to handle it in Apache. For example using AuthUserFile with a user file that you generate yourself with htpasswd. Example config:

AuthType Basic
AuthName "DNS UI"
AuthBasicProvider file
AuthUserFile /etc/apache2/htpasswd
Require valid-user

Generate the htpasswd file with eg. htpasswd -c /etc/apache2/htpasswd username

[1] This may seem like a glaring omission in the tool, but we developed the DNS UI because we needed one that integrated with LDAP auth and allowed us to delegate multiple admins for each zone - something that no existing tool provided - so we saw no need to develop any other authentication methods.

thomas-pike commented 6 years ago

Also since you would have no users in the database yet, you'd need to manually create one (via SQL commands) that matches a username in the htpasswd file.

christianbur commented 6 years ago

many thanks, my docker environment with pdns and your gui is running :-)

christianbur commented 6 years ago

docker-compose.yml

version: '3.3'
services:

    pdns-gui:
      image: cb/pdns-gui
      build: ./conf/gui/Dockerfiles
      ports:
        - 127.0.0.1:5380:80
      environment:
        - LOCAL_ADMIN1_USER=admin
        - LOCAL_ADMIN1_PASSWORD=xxxxxpassxxxxx
        - LOCAL_ADMIN2_USER=admin2
        - LOCAL_ADMIN2_PASSWORD=xxxxxpassxxxxx
      volumes:
       - ./conf/gui/config.ini:/data/dns-ui/config/config.ini:ro
      restart: always
      depends_on:
#        - pdns-server
        - pdns-gui-db
      networks:
        network-pdns:

    pdns-gui-db:
      image: postgres
      volumes:
        - ./data/pdns-gui-db/:/var/lib/postgresql/data/
      environment:
        - POSTGRES_PASSWORD=xxxxxpdns-gui-db-passxxxxxx
        - POSTGRES_USER=user_dnsui
        - POSTGRES_DB=db_dnsui
      restart: always
      networks:
        network-pdns:
          aliases:
           - pdns-gui-db

networks:
  network-pdns:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.26.1.0/24

Dockerfile

FROM php:5.6-apache
MAINTAINER Christian Burmeister

RUN apt-get update && \
    apt-get -y install git libpq-dev zlib1g-dev libicu-dev g++ ldap-utils libldap2-dev \
    && docker-php-ext-configure intl \
    && docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/  \
    && docker-php-ext-install pdo pdo_pgsql json intl ldap \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get purge

RUN mkdir /data && cd /data && git clone https://github.com/operasoftware/dns-ui.git

COPY ./000-default.conf /etc/apache2/sites-available/000-default.conf
COPY ./docker-entrypoint.sh /

ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"]

000-default.conf

<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual host. For the default virtual host (this file) this
    # value is not decisive as it is used as a last resort host regardless.
    # However, you must set it for any further virtual host explicitly.
    #ServerName www.example.com

    ServerAdmin webmaster@localhost
    DocumentRoot /data/dns-ui/public_html/
        DirectoryIndex init.php
        FallbackResource /init.php
        AllowEncodedSlashes NoDecode

        <Directory "/data/dns-ui/public_html">
          AuthType Basic
          AuthName "DNS UI"
          AuthBasicProvider file
          AuthUserFile /data/.htpasswd
          Require valid-user 
        </Directory>

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

docker-entrypoint.sh

#!/bin/bash
set -e

echo "create /data/.htpasswd"
htpasswd -b -c /data/.htpasswd $LOCAL_ADMIN1_USER $LOCAL_ADMIN1_PASSWORD
htpasswd -b  /data/.htpasswd $LOCAL_ADMIN2_USER $LOCAL_ADMIN2_PASSWORD

# Run

if [[ ! -z "$1" ]]; then
    exec ${*}
else
    exec apache2-foreground
fi

./conf/gui/config.ini:

[web]
...
baseurl = http://localhost:5380
...
[database]
dsn = "pgsql:host=pdns-gui-db dbname=db_dnsui"
username = user_dnsui
password = xxxxxpdns-gui-db-passxxxxxx

...

Insert admin user for dns-ui

after the first call of http://localhost:5380 (this initializes the database) create a admin user. [I should integrate that into the docker-entrypoint.sh (possibly with php)]

docker exec -it powerdns_pdns-gui-db_1 psql -U user_dnsui -d db_dnsui -c "INSERT INTO \"user\" (uid, name, email, active, admin, auth_realm) VALUES ('admin', 'User Admin', 'admin@example.com', 1, 1, 'local')"

docker exec -it powerdns_pdns-gui-db_1 psql -U user_dnsui -d db_dnsui -c "INSERT INTO \"user\" (uid, name, email, active, admin, auth_realm) VALUES ('admin2', 'User Admin2', 'admin2@example.com', 1, 1, 'local')"

show the created user docker exec -it powerdns_pdns-gui-db_1 psql -U user_dnsui -d db_dnsui -c "SELECT * FROM \"user\""

why two admin user?

If a zone is to be deleted, this must be confirmed with a second admin.

INFO (BUG): dns-ui offers no possibility to log out, therefore a second browser has to be used for the zone delete.

thomas-pike commented 6 years ago

Great news! Thanks for this