Browse Source

feat(docker): split databases into separate containers for api, nsmaster, nslord

Peter Thomassen 8 years ago
parent
commit
32d94f55bd
37 changed files with 370 additions and 153 deletions
  1. 29 20
      README.md
  2. 1 1
      api/entrypoint.sh
  3. 0 29
      db/initdb.d/00-init.sql.var
  4. 0 6
      db/initdb.d/99-2-poweradmin-mysql-update-to-2.1.5.sql.disabled
  5. 0 4
      db/initdb.d/99-3-poweradmin-mysql-update-to-2.1.6.sql
  6. 0 28
      db/initdb.d/99-4-poweradmin-mysql-update-to-2.1.7.sql.disabled
  7. 10 0
      dbapi/Dockerfile
  8. 0 0
      dbapi/initdb.d/00-init.sh
  9. 0 0
      dbapi/initdb.d/00-init.sql
  10. 9 0
      dbapi/initdb.d/00-init.sql.var
  11. 2 0
      dblord/51-server.cnf
  12. 13 0
      dblord/Dockerfile
  13. 6 0
      dblord/initdb.d/00-init.sh
  14. 0 0
      dblord/initdb.d/00-init.sql
  15. 13 0
      dblord/initdb.d/00-init.sql.var
  16. 1 1
      dblord/initdb.d/10-pdns-lord.sql
  17. 1 1
      dblord/initdb.d/11-pdns-lord-REFERENCES.sql
  18. 2 0
      dblord/initdb.d/20-poweradmin-mysql-db-structure.sql
  19. 12 11
      dblord/initdb.d/20-poweradmin-mysql-db-structure.sql.var
  20. 1 1
      dbmaster/51-server.cnf
  21. 1 1
      dbmaster/Dockerfile
  22. 6 0
      dbmaster/initdb.d/00-init.sh
  23. 2 0
      dbmaster/initdb.d/00-init.sql
  24. 16 0
      dbmaster/initdb.d/00-init.sql.var
  25. 1 1
      dbmaster/initdb.d/10-pdns-master.sql
  26. 1 1
      dbmaster/initdb.d/11-pdns-master-REFERENCES.sql
  27. 1 1
      dbmaster/initdb.d/11-pdns-master-supermasters.sql
  28. 3 4
      devadmin/Dockerfile
  29. 175 0
      devadmin/conf/phpmyadmin/config.inc.php
  30. 8 8
      devadmin/conf/poweradmin/config.inc.php
  31. 2 1
      docker-compose.dev.yml
  32. 40 20
      docker-compose.yml
  33. 4 4
      nslord/conf/pdns.conf.var
  34. 4 4
      nslord/cronhook/my.cnf.var
  35. 1 1
      nslord/entrypoint.sh
  36. 4 4
      nsmaster/conf/pdns.conf.var
  37. 1 1
      nsmaster/entrypoint.sh

+ 29 - 20
README.md

@@ -7,39 +7,48 @@ This is a docker-compose application providing the basic stack for deSEC name se
   - There is a cron hook installed to secure new zones with DNSSEC and to set NSEC3 parameters. For new zones under `dedyn.io`, `DS` records are set in the parent zone. Expected to be superseded by native DNSSEC support in the PowerDNS API.
 - `nsmaster`: Stealth authoritative DNS server (PowerDNS). Receives fully signed AXFR zone transfers from `nslord`. No access to keys.
 - `api`: RESTful API to create deSEC users and domains. Currently used for dynDNS purposes only.
-- `db`: MariaDB database service for `nslord`, `nsmaster`, and `api`. Exposes `nsmaster` database (`pdnsmaster`) at 3306 for TLS-secured replication.
-  - Note that, at the moment, storage is not a Docker volume, but local to the container. Thus, destroying the container destroys the database.
+- `dbapi`, `dblord`, `dbmaster`: MariaDB database services for `api`, `nslord`, and `nsmaster`, respectively. The `dbmaster` database is exposed at 3306 for TLS-secured replication.
 - `devadmin`: Web server with phpmyadmin and poweradmin for dev purposes.
 
-**Note:** All passwords / keys are currently set to dummy values. You are supposed to replace them with sensible non-default values. We will make this easier in the future.
-
 
 Requirements
 -----
 
 Although most configuration is contained in this repository, some external dependencies need to be met before the application can be run. Dependencies are:
 
-1.  `./api-settings.py`: `api` configuration, in the style of `api/desecapi/settings_local.py.dist`
+1.  We run this software with the `--userland-proxy=false` flag of the `dockerd` daemon, and recommend you do the same.
 
-2.  `./nslord/cronhook/my.cnf`: Configuration for the MariaDB/MySQL client, used by the `nslord` cron hook, to get the list of insecure zones from the `pdnslord` database.
+2.  `./api-settings.py`: `api` configuration
 
 3.  Set up TLS-secured replication of the `pdnsmaster` database to feed your PowerDNS slaves.
 
     To generate the necessary keys and certificates, follow the instructions at https://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html. In the `openssl req -newkey` steps, consider switching to a bigger key size, and add `-subj '/CN=slave.hostname.example'`. (It turned out that StartSSL and Let's Encrypt certificates do not work out of the box.)
 
-4.  Set passwords etc. using environment variables or an `.env` file. You need:
-    - `DESECSTACK_API_SECRETKEY`: Django secret
-    - `DESECSTACK_DB_PASSWORD_root`: mysql root password
-    - `DESECSTACK_DB_PASSWORD_desec`: mysql password for desecapi
-    - `DESECSTACK_DB_PASSWORD_pdnslord`: mysql password for pdnslord
-    - `DESECSTACK_DB_PASSWORD_pdnsmaster`: mysql password for pdnslord
-    - `DESECSTACK_DB_PASSWORD_poweradmin`: poweradmin password
-    - `DESECSTACK_DB_PASSWORD_ns1replication`: slave 1 replication password
-    - `DESECSTACK_DB_SUBJECT_ns1replication`: slave 1 replication SSL certificate subject name
-    - `DESECSTACK_DB_PASSWORD_ns2replication`: slave 2 replication password
-    - `DESECSTACK_DB_SUBJECT_ns2replication`: slave 2 replication SSL certificate subject name
-    - `DESECSTACK_DEVADMIN_PASSWORDmd5`: poweradmin password MD5 hash (if you're planning to use the dev environment)
-    - `DESECSTACK_NSLORD_APIKEY`: pdns API key
+4.  Set sensitive information and network topology using environment variables or an `.env` file. You need (you can use the `env` file as a template):
+    - network
+      - `DESECSTACK_IPV6_SUBNET`: IPv6 net, ideally /80 (see below)
+      - `DESECSTACK_IPV6_ADDRESS`: IPv6 address of frontend container, ideally 0642:ac10:0080 in within the above subnet (see below)
+    - certificates
+      - `DESECSTACK_CERT_FOLDER`: `./path/to/certificates`
+    - API-related
+      - `DESECSTACK_API_SECRETKEY`: Djange secret
+      - `DESECSTACK_DBAPI_PASSWORD_root`: mysql root password for API database
+      - `DESECSTACK_DBAPI_PASSWORD_desec`: mysql password for desecapi
+    - nslord-related
+      - `DESECSTACK_DBLORD_PASSWORD_root`: mysql root password for nslord database
+      - `DESECSTACK_DBLORD_PASSWORD_pdns`: mysql password for pdns on nslord
+      - `DESECSTACK_DBLORD_PASSWORD_poweradmin`: mysql password for poweradmin (can write to nslord database! use for development only.)
+      - `DESECSTACK_NSLORD_APIKEY`: pdns API key on nslord
+    - nsmaster-related
+      - `DESECSTACK_DBMASTER_PASSWORD_root`: mysql root password for nsmaster database
+      - `DESECSTACK_DBMASTER_PASSWORD_pdns`: mysql password for pdns on nsmaster
+      - `DESECSTACK_DBMASTER_PASSWORD_ns1replication`: slave 1 replication password
+      - `DESECSTACK_DBMASTER_SUBJECT_ns1replication`: slave 1 replication SSL certificate subject name
+      - `DESECSTACK_DBMASTER_PASSWORD_ns2replication`: slave 2 replication password
+      - `DESECSTACK_DBMASTER_SUBJECT_ns2replication`: slave 1 replication SSL certificate subject name
+    - devadmin-related
+      - `DESECSTACK_DEVADMIN_PASSWORD_poweradmin`: poweradmin password (if you're planning to use the dev environment)
+      - `DESECSTACK_DEVADMIN_SESSIONKEY_poweradmin`: poweradmin session key
 
 Running the standard stack will also fire up an instance of the `www` proxy service (see `desec-www` repository), assuming that the `desec-static` project is located under the `static` directory/symlink. TLS certificates are assumed to be located in `certs`.
 
@@ -58,7 +67,7 @@ Production:
 
 Storage
 ---
-All important data is stored in the database managed by the `db` container. It uses a Docker volume which, by default, resides in `/var/lib/docker/volumes/desecstack_mysql`.
+All important data is stored in the databases managed by the `db*` containers. They use Docker volumes which, by default, reside in `/var/lib/docker/volumes/desecstack_{dbapi,dblord,dbmaster}_mysql`.
 This is the location you will want to back up. (Be sure to follow standard MySQL backup practices, i.e. make sure things are consistent.)
 
 

+ 1 - 1
api/entrypoint.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-host=db; port=3306; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
+host=dbapi; port=3306; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
 host=nslord; port=8081; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
 
 python manage.py migrate

+ 0 - 29
db/initdb.d/00-init.sql.var

@@ -1,29 +0,0 @@
--- Narrow down root logins
-USE mysql;
-UPDATE user SET Host = 'localhost' WHERE User = 'root';
-FLUSH PRIVILEGES;
-
--- deSEC user and domain database
-CREATE DATABASE desec;
-CREATE USER 'desec'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DB_PASSWORD_desec}';
-GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, CREATE, ALTER, DROP ON desec.* TO 'desec'@'172.16.1.%';
-
--- nslord database, including devadmin access
-CREATE DATABASE pdnslord;
-CREATE USER 'pdnslord'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DB_PASSWORD_pdnslord}';
-GRANT SELECT, INSERT, UPDATE, DELETE ON pdnslord.* TO 'pdnslord'@'172.16.1.%';
-
-CREATE USER 'poweradmin'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DB_PASSWORD_poweradmin}';
-GRANT SELECT, INSERT, UPDATE, DELETE ON pdnslord.* TO 'poweradmin'@'172.16.1.%';
-
--- nsmaster database
-CREATE DATABASE pdnsmaster;
-CREATE USER 'pdnsmaster'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DB_PASSWORD_pdnsmaster}';
-GRANT SELECT, INSERT, UPDATE, DELETE ON pdnsmaster.* TO 'pdnsmaster'@'172.16.1.%';
-
--- replication
-CREATE USER ns1@'%' IDENTIFIED BY "${DESECSTACK_DB_PASSWORD_ns1replication}";
-GRANT REPLICATION SLAVE ON *.* TO ns1@'%' REQUIRE SUBJECT '/CN=${DESECSTACK_DB_SUBJECT_ns1replication}';
-
-CREATE USER ns2@'%' IDENTIFIED BY "${DESECSTACK_DB_PASSWORD_ns2replication}";
-GRANT REPLICATION SLAVE ON *.* TO ns2@'%' REQUIRE SUBJECT '/CN=${DESECSTACK_DB_SUBJECT_ns2replication}';

+ 0 - 6
db/initdb.d/99-2-poweradmin-mysql-update-to-2.1.5.sql.disabled

@@ -1,6 +0,0 @@
-USE pdnslord;
-
-ALTER TABLE zones ADD zone_templ_id INT( 11 ) NOT NULL;
-ALTER TABLE zones ENGINE = InnoDB;
-ALTER TABLE zone_templ ENGINE = InnoDB;
-ALTER TABLE zone_templ_records ENGINE = InnoDB;

+ 0 - 4
db/initdb.d/99-3-poweradmin-mysql-update-to-2.1.6.sql

@@ -1,4 +0,0 @@
-USE pdnslord;
-
-ALTER TABLE users MODIFY username VARCHAR(64) NOT NULL DEFAULT '0';
-ALTER TABLE users MODIFY password VARCHAR(128) NOT NULL DEFAULT '0';

+ 0 - 28
db/initdb.d/99-4-poweradmin-mysql-update-to-2.1.7.sql.disabled

@@ -1,28 +0,0 @@
-USE pdnslord;
-
-ALTER TABLE users ADD use_ldap BOOLEAN NOT NULL;
-
-ALTER TABLE users ENGINE=InnoDB;
-ALTER TABLE perm_items ENGINE=InnoDB;
-ALTER TABLE perm_templ ENGINE=InnoDB;
-ALTER TABLE perm_templ_items ENGINE=InnoDB;
-ALTER TABLE zones ENGINE=InnoDB;
-ALTER TABLE zone_templ ENGINE=InnoDB;
-ALTER TABLE zone_templ_records ENGINE=InnoDB;
-ALTER TABLE domainmetadata ENGINE=InnoDB;
-ALTER TABLE cryptokeys ENGINE=InnoDB;
-ALTER TABLE tsigkeys ENGINE=InnoDB;
-ALTER TABLE domains ENGINE=InnoDB;
-ALTER TABLE records ENGINE=InnoDB;
-ALTER TABLE supermasters ENGINE=InnoDB;
-
-CREATE TABLE records_zone_templ (
-    domain_id INTEGER NOT NULL,
-    record_id INTEGER NOT NULL,
-    zone_templ_id INTEGER NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-
-CREATE TABLE migrations (
-    version VARCHAR(255) NOT NULL,
-    apply_time INTEGER NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;

+ 10 - 0
dbapi/Dockerfile

@@ -0,0 +1,10 @@
+FROM mariadb:10.1
+
+# install tools used in init script
+RUN set -ex && apt-get update && apt-get -y install gettext-base && apt-get clean && rm -rf /var/lib/apt/lists/*
+
+COPY initdb.d/* /docker-entrypoint-initdb.d/
+RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/
+
+# mountable storage
+VOLUME /var/lib/mysql

+ 0 - 0
db/initdb.d/00-init.sh → dbapi/initdb.d/00-init.sh


+ 0 - 0
db/initdb.d/00-init.sql → dbapi/initdb.d/00-init.sql


+ 9 - 0
dbapi/initdb.d/00-init.sql.var

@@ -0,0 +1,9 @@
+-- Narrow down root logins
+USE mysql;
+UPDATE user SET Host = 'localhost' WHERE User = 'root';
+FLUSH PRIVILEGES;
+
+-- deSEC user and domain database
+CREATE DATABASE desec;
+CREATE USER 'desec'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBAPI_PASSWORD_desec}';
+GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, INDEX, CREATE, ALTER, DROP ON desec.* TO 'desec'@'172.16.1.%';

+ 2 - 0
dblord/51-server.cnf

@@ -0,0 +1,2 @@
+[mysqld]
+wait_timeout = 28800

+ 13 - 0
dblord/Dockerfile

@@ -0,0 +1,13 @@
+FROM mariadb:10.1
+
+# install tools used in init script
+RUN set -ex && apt-get update && apt-get -y install gettext-base && apt-get clean && rm -rf /var/lib/apt/lists/*
+
+COPY initdb.d/* /docker-entrypoint-initdb.d/
+RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/
+
+# Additional configuration
+COPY ./51-server.cnf /etc/mysql/conf.d/51-server.cnf
+
+# mountable storage
+VOLUME /var/lib/mysql

+ 6 - 0
dblord/initdb.d/00-init.sh

@@ -0,0 +1,6 @@
+# https://stackoverflow.com/questions/59895/can-a-bash-script-tell-which-directory-it-is-stored-in
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+for file in $DIR/*.sql.var; do
+	envsubst < $file > $DIR/`basename $file .var`
+done

+ 0 - 0
db/initdb.d/99-1-poweradmin-mysql-db-structure.sql → dblord/initdb.d/00-init.sql


+ 13 - 0
dblord/initdb.d/00-init.sql.var

@@ -0,0 +1,13 @@
+-- Narrow down root logins
+USE mysql;
+UPDATE user SET Host = 'localhost' WHERE User = 'root';
+FLUSH PRIVILEGES;
+
+-- nslord database
+CREATE DATABASE pdns;
+CREATE USER 'pdns'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBLORD_PASSWORD_pdns}';
+GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'pdns'@'172.16.1.%';
+
+-- poweradmin database (for devadmin)
+CREATE USER 'poweradmin'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBLORD_PASSWORD_poweradmin}';
+GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'poweradmin'@'172.16.1.%';

+ 1 - 1
db/initdb.d/10-pdns-lord.sql → dblord/initdb.d/10-pdns-lord.sql

@@ -1,4 +1,4 @@
-USE pdnslord;
+USE pdns;
 
 CREATE TABLE domains (
   id                    INT AUTO_INCREMENT,

+ 1 - 1
db/initdb.d/11-pdns-lord-REFERENCES.sql → dblord/initdb.d/11-pdns-lord-REFERENCES.sql

@@ -1,4 +1,4 @@
-USE pdnslord;
+USE pdns;
 
 -- As recommended by https://doc.powerdns.com/md/authoritative/backend-generic-mysql/
 ALTER TABLE `records` ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE;

+ 2 - 0
dblord/initdb.d/20-poweradmin-mysql-db-structure.sql

@@ -0,0 +1,2 @@
+-- This file is required to exist and will be overriden by 00-init.sh.
+-- If it is created only by 00-init.sh, the entrypoint script will miss it.

+ 12 - 11
db/initdb.d/99-1-poweradmin-mysql-db-structure.sql.var → dblord/initdb.d/20-poweradmin-mysql-db-structure.sql.var

@@ -1,4 +1,5 @@
-USE pdnslord;
+USE pdns;
+
 -- PowerAdmin
 -- MySQL Database Structure
 --
@@ -14,12 +15,12 @@ CREATE TABLE users (
   active      TINYINT      NOT NULL,
   use_ldap    TINYINT      NOT NULL,
   PRIMARY KEY (id)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 START TRANSACTION;
     INSERT INTO users ( id, username, `password`, fullname, email
                       , description, perm_templ, active, use_ldap )
-    VALUES ( 1, 'admin', '${DESECSTACK_DEVADMIN_PASSWORDmd5}', 'Administrator'
+    VALUES ( 1, 'admin', MD5('${DESECSTACK_DEVADMIN_PASSWORD_poweradmin}'), 'Administrator'
            , 'admin@example.net', 'Administrator with full rights.', 1, 1, 0 );
 COMMIT;
 
@@ -28,7 +29,7 @@ CREATE TABLE perm_items (
   name VARCHAR(64) NOT NULL,
   descr TEXT       NOT NULL,
   PRIMARY KEY (id)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 START TRANSACTION;
     INSERT INTO perm_items ( id, name, descr ) VALUES ( 41, 'zone_master_add', 'User is allowed to add new master zones.' );
@@ -59,7 +60,7 @@ CREATE TABLE perm_templ (
   name  VARCHAR(128) NOT NULL,
   descr TEXT         NOT NULL,
   PRIMARY KEY  (id)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 START TRANSACTION;
     INSERT INTO perm_templ ( id, name, descr )
@@ -72,7 +73,7 @@ CREATE TABLE perm_templ_items (
   templ_id INTEGER NOT NULL,
   perm_id INTEGER  NOT NULL,
   PRIMARY KEY (id)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 START TRANSACTION;
     INSERT INTO perm_templ_items ( id, templ_id, perm_id )
@@ -87,7 +88,7 @@ CREATE TABLE zones (
   zone_templ_id INTEGER NOT NULL,
   PRIMARY KEY (id),
   KEY owner (owner)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 CREATE TABLE zone_templ (
   id    INTEGER      NOT NULL AUTO_INCREMENT,
@@ -95,7 +96,7 @@ CREATE TABLE zone_templ (
   descr TEXT         NOT NULL,
   owner INTEGER      NOT NULL,
   PRIMARY KEY (id)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 CREATE TABLE zone_templ_records (
   id            INTEGER      NOT NULL AUTO_INCREMENT,
@@ -106,15 +107,15 @@ CREATE TABLE zone_templ_records (
   ttl           INTEGER      NOT NULL,
   prio          INTEGER      NOT NULL,
   PRIMARY KEY (id)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 CREATE TABLE records_zone_templ (
     domain_id INTEGER NOT NULL,
     record_id INTEGER NOT NULL,
     zone_templ_id INTEGER NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;
 
 CREATE TABLE migrations (
     version VARCHAR(255) NOT NULL,
     apply_time INTEGER NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+) ENGINE=InnoDB;

+ 1 - 1
db/51-server.cnf → dbmaster/51-server.cnf

@@ -7,7 +7,7 @@ server-id               = 1
 log_bin                 = /var/log/mysql/mysql-bin.log
 binlog_format=ROW
 log-basename=nsmaster
-binlog-do-db=pdnsmaster
+binlog-do-db=pdns
 expire_logs_days        = 10
 
 wait_timeout = 28800

+ 1 - 1
db/Dockerfile → dbmaster/Dockerfile

@@ -6,7 +6,7 @@ RUN set -ex && apt-get update && apt-get -y install gettext-base && apt-get clea
 COPY initdb.d/* /docker-entrypoint-initdb.d/
 RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/
 
-# Replication master configuration
+# Additional configuration
 COPY ./51-server.cnf /etc/mysql/conf.d/51-server.cnf
 
 # mountable ssl certificate and key directory

+ 6 - 0
dbmaster/initdb.d/00-init.sh

@@ -0,0 +1,6 @@
+# https://stackoverflow.com/questions/59895/can-a-bash-script-tell-which-directory-it-is-stored-in
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+for file in $DIR/*.sql.var; do
+	envsubst < $file > $DIR/`basename $file .var`
+done

+ 2 - 0
dbmaster/initdb.d/00-init.sql

@@ -0,0 +1,2 @@
+-- This file is required to exist and will be overriden by 00-init.sh.
+-- If it is created only by 00-init.sh, the entrypoint script will miss it.

+ 16 - 0
dbmaster/initdb.d/00-init.sql.var

@@ -0,0 +1,16 @@
+-- Narrow down root logins
+USE mysql;
+UPDATE user SET Host = 'localhost' WHERE User = 'root';
+FLUSH PRIVILEGES;
+
+-- nsmaster database
+CREATE DATABASE pdns;
+CREATE USER 'pdns'@'172.16.1.%' IDENTIFIED BY '${DESECSTACK_DBMASTER_PASSWORD_pdns}';
+GRANT SELECT, INSERT, UPDATE, DELETE ON pdns.* TO 'pdns'@'172.16.1.%';
+
+-- replication
+CREATE USER ns1@'%' IDENTIFIED BY "${DESECSTACK_DBMASTER_PASSWORD_ns1replication}";
+GRANT REPLICATION SLAVE ON *.* TO ns1@'%' REQUIRE SUBJECT '/CN=${DESECSTACK_DBMASTER_SUBJECT_ns1replication}';
+
+CREATE USER ns2@'%' IDENTIFIED BY "${DESECSTACK_DBMASTER_PASSWORD_ns2replication}";
+GRANT REPLICATION SLAVE ON *.* TO ns2@'%' REQUIRE SUBJECT '/CN=${DESECSTACK_DBMASTER_SUBJECT_ns2replication}';

+ 1 - 1
db/initdb.d/10-pdns-master.sql → dbmaster/initdb.d/10-pdns-master.sql

@@ -1,4 +1,4 @@
-USE pdnsmaster;
+USE pdns;
 
 CREATE TABLE domains (
   id                    INT AUTO_INCREMENT,

+ 1 - 1
db/initdb.d/11-pdns-master-REFERENCES.sql → dbmaster/initdb.d/11-pdns-master-REFERENCES.sql

@@ -1,4 +1,4 @@
-USE pdnsmaster;
+USE pdns;
 
 -- As recommended by https://doc.powerdns.com/md/authoritative/backend-generic-mysql/
 ALTER TABLE `records` ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE;

+ 1 - 1
db/initdb.d/11-pdns-master-supermasters.sql → dbmaster/initdb.d/11-pdns-master-supermasters.sql

@@ -1,3 +1,3 @@
-USE pdnsmaster;
+USE pdns;
 
 INSERT INTO supermasters SET ip="172.16.1.11", nameserver="ns1.desec.io";

+ 3 - 4
devadmin/Dockerfile

@@ -4,9 +4,7 @@ RUN apk add --no-cache \
 	php5-gettext \
 	phpmyadmin
 
-RUN chmod -v 644 /etc/phpmyadmin/config.inc.php && sed -i 's/localhost/db/g' /etc/phpmyadmin/config.inc.php
-
-# Can't use /var/www/htmt/ because parent image defines it as a volume, but we're going to modify it at build time
+# Can't use /var/www/html/ because parent image defines it as a volume, but we're going to modify it at build time
 ENV WEBROOT /var/www/htdocs
 
 RUN mkdir /var/www/htdocs \
@@ -17,7 +15,8 @@ RUN mkdir /var/www/htdocs \
 	&& ln -s /usr/share/webapps/phpmyadmin phpmyadmin \
 	&& ln -s poweradmin-2.1.7 poweradmin
 
-COPY config.inc.php /var/www/htdocs/poweradmin-2.1.7/inc/
+COPY conf/phpmyadmin/config.inc.php /etc/phpmyadmin/
+COPY conf/poweradmin/config.inc.php /var/www/htdocs/poweradmin-2.1.7/inc/
 
 # Don't be smart
 ENV TEMPLATE_NGINX_HTML=0

+ 175 - 0
devadmin/conf/phpmyadmin/config.inc.php

@@ -0,0 +1,175 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * phpMyAdmin sample configuration, you can use it as base for
+ * manual configuration. For easier setup you can use setup/
+ *
+ * All directives are explained in documentation in the doc/ folder
+ * or at <https://docs.phpmyadmin.net/>.
+ *
+ * @package PhpMyAdmin
+ */
+
+/**
+ * This is needed for cookie based authentication to encrypt password in
+ * cookie
+ */
+$cfg['blowfish_secret'] = ''; /* YOU MUST FILL IN THIS FOR COOKIE AUTH! */
+
+/**
+ * Servers configuration
+ */
+$i = 0;
+
+/**
+ * First server
+ */
+$i++;
+/* Authentication type */
+$cfg['Servers'][$i]['auth_type'] = 'cookie';
+/* Server parameters */
+$cfg['Servers'][$i]['host'] = 'dbapi';
+$cfg['Servers'][$i]['connect_type'] = 'tcp';
+$cfg['Servers'][$i]['compress'] = false;
+$cfg['Servers'][$i]['AllowNoPassword'] = false;
+
+$i++;
+/* Authentication type */
+$cfg['Servers'][$i]['auth_type'] = 'cookie';
+/* Server parameters */
+$cfg['Servers'][$i]['host'] = 'dblord';
+$cfg['Servers'][$i]['connect_type'] = 'tcp';
+$cfg['Servers'][$i]['compress'] = false;
+$cfg['Servers'][$i]['AllowNoPassword'] = false;
+
+$i++;
+/* Authentication type */
+$cfg['Servers'][$i]['auth_type'] = 'cookie';
+/* Server parameters */
+$cfg['Servers'][$i]['host'] = 'dbmaster';
+$cfg['Servers'][$i]['connect_type'] = 'tcp';
+$cfg['Servers'][$i]['compress'] = false;
+$cfg['Servers'][$i]['AllowNoPassword'] = false;
+
+/**
+ * phpMyAdmin configuration storage settings.
+ */
+
+/* User used to manipulate with storage */
+// $cfg['Servers'][$i]['controlhost'] = '';
+// $cfg['Servers'][$i]['controlport'] = '';
+// $cfg['Servers'][$i]['controluser'] = 'pma';
+// $cfg['Servers'][$i]['controlpass'] = 'pmapass';
+
+/* Storage database and tables */
+// $cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';
+// $cfg['Servers'][$i]['bookmarktable'] = 'pma__bookmark';
+// $cfg['Servers'][$i]['relation'] = 'pma__relation';
+// $cfg['Servers'][$i]['table_info'] = 'pma__table_info';
+// $cfg['Servers'][$i]['table_coords'] = 'pma__table_coords';
+// $cfg['Servers'][$i]['pdf_pages'] = 'pma__pdf_pages';
+// $cfg['Servers'][$i]['column_info'] = 'pma__column_info';
+// $cfg['Servers'][$i]['history'] = 'pma__history';
+// $cfg['Servers'][$i]['table_uiprefs'] = 'pma__table_uiprefs';
+// $cfg['Servers'][$i]['tracking'] = 'pma__tracking';
+// $cfg['Servers'][$i]['userconfig'] = 'pma__userconfig';
+// $cfg['Servers'][$i]['recent'] = 'pma__recent';
+// $cfg['Servers'][$i]['favorite'] = 'pma__favorite';
+// $cfg['Servers'][$i]['users'] = 'pma__users';
+// $cfg['Servers'][$i]['usergroups'] = 'pma__usergroups';
+// $cfg['Servers'][$i]['navigationhiding'] = 'pma__navigationhiding';
+// $cfg['Servers'][$i]['savedsearches'] = 'pma__savedsearches';
+// $cfg['Servers'][$i]['central_columns'] = 'pma__central_columns';
+// $cfg['Servers'][$i]['designer_settings'] = 'pma__designer_settings';
+// $cfg['Servers'][$i]['export_templates'] = 'pma__export_templates';
+/* Contrib / Swekey authentication */
+// $cfg['Servers'][$i]['auth_swekey_config'] = '/etc/swekey-pma.conf';
+
+/**
+ * End of servers configuration
+ */
+
+/**
+ * Directories for saving/loading files from server
+ */
+$cfg['UploadDir'] = '';
+$cfg['SaveDir'] = '';
+
+/**
+ * Whether to display icons or text or both icons and text in table row
+ * action segment. Value can be either of 'icons', 'text' or 'both'.
+ * default = 'both'
+ */
+//$cfg['RowActionType'] = 'icons';
+
+/**
+ * Defines whether a user should be displayed a "show all (records)"
+ * button in browse mode or not.
+ * default = false
+ */
+//$cfg['ShowAll'] = true;
+
+/**
+ * Number of rows displayed when browsing a result set. If the result
+ * set contains more rows, "Previous" and "Next".
+ * Possible values: 25, 50, 100, 250, 500
+ * default = 25
+ */
+//$cfg['MaxRows'] = 50;
+
+/**
+ * Disallow editing of binary fields
+ * valid values are:
+ *   false    allow editing
+ *   'blob'   allow editing except for BLOB fields
+ *   'noblob' disallow editing except for BLOB fields
+ *   'all'    disallow editing
+ * default = 'blob'
+ */
+//$cfg['ProtectBinary'] = false;
+
+/**
+ * Default language to use, if not browser-defined or user-defined
+ * (you find all languages in the locale folder)
+ * uncomment the desired line:
+ * default = 'en'
+ */
+//$cfg['DefaultLang'] = 'en';
+//$cfg['DefaultLang'] = 'de';
+
+/**
+ * How many columns should be used for table display of a database?
+ * (a value larger than 1 results in some information being hidden)
+ * default = 1
+ */
+//$cfg['PropertiesNumColumns'] = 2;
+
+/**
+ * Set to true if you want DB-based query history.If false, this utilizes
+ * JS-routines to display query history (lost by window close)
+ *
+ * This requires configuration storage enabled, see above.
+ * default = false
+ */
+//$cfg['QueryHistoryDB'] = true;
+
+/**
+ * When using DB-based query history, how many entries should be kept?
+ * default = 25
+ */
+//$cfg['QueryHistoryMax'] = 100;
+
+/**
+ * Whether or not to query the user before sending the error report to
+ * the phpMyAdmin team when a JavaScript error occurs
+ *
+ * Available options
+ * ('ask' | 'always' | 'never')
+ * default = 'ask'
+ */
+//$cfg['SendErrorReports'] = 'always';
+
+/**
+ * You can find more configuration options in the documentation
+ * in the doc/ folder or at <https://docs.phpmyadmin.net/>.
+ */

+ 8 - 8
devadmin/config.inc.php → devadmin/conf/poweradmin/config.inc.php

@@ -15,11 +15,11 @@
 // Better description of available configuration settings you can find here:
 // <https://github.com/poweradmin/poweradmin/wiki/Configuration-File>
 // Database settings
-$db_host = 'db';
+$db_host = 'dblord';
 $db_port = '';
 $db_user = 'poweradmin';
-$db_pass = getenv('DESECSTACK_DB_PASSWORD_poweradmin');
-$db_name = 'pdnslord';
+$db_pass = getenv('DESECSTACK_DBLORD_PASSWORD_poweradmin');
+$db_name = 'pdns';
 $db_type = 'mysql';
 //$db_file		= '';		# used only for SQLite, provide full path to database file
 //$db_debug		= false;	# show all SQL queries
@@ -27,7 +27,7 @@ $db_layer		= 'PDO';	# or MDB2
 //$db_ssl_ca            = '';
 // Security settings
 // This should be changed upon install
-$session_key = 'p0w3r4dm1n';
+$session_key = getenv('DESECSTACK_DEVADMIN_SESSIONKEY_poweradmin');
 $password_encryption = 'md5'; // or md5salt
 
 // Interface settings
@@ -40,10 +40,10 @@ $iface_title = 'Poweradmin';
 $iface_add_reverse_record = true;
 
 // Predefined DNS settings
-$dns_hostmaster = '';
-$dns_ns1 = '';
-$dns_ns2 = '';
-$dns_ttl = 86400;
+$dns_hostmaster = 'hostmaster.desec.io.';
+$dns_ns1 = 'ns1.desec.io';
+$dns_ns2 = 'ns1.desec.io';
+$dns_ttl = 3600;
 $dns_fancy = false;
 $dns_strict_tld_check = false;
 $dns_top_level_tld_check = false;     // Don't allow to create top level TLDs

+ 2 - 1
docker-compose.dev.yml

@@ -16,7 +16,8 @@ services:
   devadmin:
     build: devadmin
     environment:
-    - DESECSTACK_DB_PASSWORD_poweradmin
+    - DESECSTACK_DBLORD_PASSWORD_poweradmin
+    - DESECSTACK_DEVADMIN_SESSIONKEY_poweradmin
     ports:
      - "127.0.0.1:81:80"
     networks:

+ 40 - 20
docker-compose.yml

@@ -24,35 +24,53 @@ services:
     networks:
     - front # TODO change to back2 when https://github.com/docker/docker/issues/27101 is fixed
 
-  db:
-    build: db
+  dbapi:
+    build: dbapi
+    volumes:
+    - dbapi_mysql:/var/lib/mysql
+    environment:
+    - MYSQL_ROOT_PASSWORD=${DESECSTACK_DBAPI_PASSWORD_root}
+    - DESECSTACK_DBAPI_PASSWORD_desec
+    networks:
+    - back1
+
+  dblord:
+    build: dblord
+    volumes:
+    - dblord_mysql:/var/lib/mysql
+    environment:
+    - MYSQL_ROOT_PASSWORD=${DESECSTACK_DBLORD_PASSWORD_root}
+    - DESECSTACK_DBLORD_PASSWORD_pdns
+    - DESECSTACK_DBLORD_PASSWORD_poweradmin
+    - DESECSTACK_DEVADMIN_PASSWORD_poweradmin
+    networks:
+    - back1
+
+  dbmaster:
+    build: dbmaster
     ports:
     - "3306:3306"
     volumes:
     - ${DESECSTACK_CERT_FOLDER}:/etc/ssl/private:ro
-    - mysql:/var/lib/mysql
+    - dbmaster_mysql:/var/lib/mysql
     environment:
-    - MYSQL_ROOT_PASSWORD=${DESECSTACK_DB_PASSWORD_root}
-    - DESECSTACK_DB_PASSWORD_desec
-    - DESECSTACK_DB_PASSWORD_pdnslord
-    - DESECSTACK_DB_PASSWORD_pdnsmaster
-    - DESECSTACK_DB_PASSWORD_poweradmin
-    - DESECSTACK_DB_PASSWORD_ns1replication
-    - DESECSTACK_DB_SUBJECT_ns1replication
-    - DESECSTACK_DB_PASSWORD_ns2replication
-    - DESECSTACK_DB_SUBJECT_ns2replication
-    - DESECSTACK_DEVADMIN_PASSWORDmd5
+    - MYSQL_ROOT_PASSWORD=${DESECSTACK_DBMASTER_PASSWORD_root}
+    - DESECSTACK_DBMASTER_PASSWORD_pdns
+    - DESECSTACK_DBMASTER_PASSWORD_ns1replication
+    - DESECSTACK_DBMASTER_SUBJECT_ns1replication
+    - DESECSTACK_DBMASTER_PASSWORD_ns2replication
+    - DESECSTACK_DBMASTER_SUBJECT_ns2replication
     networks:
     - back1
 
   api:
     build: api
     depends_on:
-    - db
+    - dbapi
     - nslord
     environment:
     - DESECSTACK_API_SECRETKEY
-    - DESECSTACK_DB_PASSWORD_desec
+    - DESECSTACK_DBAPI_PASSWORD_desec
     - DESECSTACK_NSLORD_APIKEY
     volumes:
     - ./api-settings.py:/usr/src/app/desecapi/settings_local.py:ro
@@ -63,10 +81,10 @@ services:
   nslord:
     build: nslord
     environment:
-    - DESECSTACK_DB_PASSWORD_pdnslord
+    - DESECSTACK_DBLORD_PASSWORD_pdns
     - DESECSTACK_NSLORD_APIKEY
     depends_on:
-    - db
+    - dblord
     networks:
       back1:
         ipv4_address: 172.16.1.11
@@ -74,15 +92,17 @@ services:
   nsmaster:
     build: nsmaster
     environment:
-    - DESECSTACK_DB_PASSWORD_pdnsmaster
+    - DESECSTACK_DBMASTER_PASSWORD_pdns
     depends_on:
-    - db
+    - dbmaster
     networks:
       back1:
         ipv4_address: 172.16.1.12
 
 volumes:
-  mysql:
+  dbapi_mysql:
+  dblord_mysql:
+  dbmaster_mysql:
 
 networks:
   back1: # TODO can we declare this internal? compose 1.9.0 will allow it: https://github.com/docker/compose/pull/3488 May break apt inside nslord etc.

+ 4 - 4
nslord/conf/pdns.conf.var

@@ -17,9 +17,9 @@ webserver-address=0.0.0.0
 webserver-allow-from=172.16.1.0/24
 
 launch=gmysql
-gmysql-host=db
+gmysql-host=dblord
 gmysql-port=
-gmysql-dbname=pdnslord
-gmysql-user=pdnslord
-gmysql-password=${DESECSTACK_DB_PASSWORD_pdnslord}
+gmysql-dbname=pdns
+gmysql-user=pdns
+gmysql-password=${DESECSTACK_DBLORD_PASSWORD_pdns}
 gmysql-dnssec=yes

+ 4 - 4
nslord/cronhook/my.cnf.var

@@ -1,5 +1,5 @@
 [client]
-host=db
-database=pdnslord
-user=pdnslord
-password=${DESECSTACK_DB_PASSWORD_pdnslord}
+host=dblord
+database=pdns
+user=pdns
+password=${DESECSTACK_DBLORD_PASSWORD_pdns}

+ 1 - 1
nslord/entrypoint.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-host=db; port=3306; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
+host=dblord; port=3306; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
 
 # Post-create cron hook
 envsubst < /root/cronhook/my.cnf.var > /root/cronhook/my.cnf

+ 4 - 4
nsmaster/conf/pdns.conf.var

@@ -7,9 +7,9 @@ slave=yes
 version-string=powerdns
 
 launch=gmysql
-gmysql-host=db
+gmysql-host=dbmaster
 gmysql-port=
-gmysql-dbname=pdnsmaster
-gmysql-user=pdnsmaster
-gmysql-password=${DESECSTACK_DB_PASSWORD_pdnsmaster}
+gmysql-dbname=pdns
+gmysql-user=pdns
+gmysql-password=${DESECSTACK_DBMASTER_PASSWORD_pdns}
 gmysql-dnssec=yes

+ 1 - 1
nsmaster/entrypoint.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-host=db; port=3306; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
+host=dbmaster; port=3306; n=120; i=0; while ! (echo > /dev/tcp/$host/$port) 2> /dev/null; do [[ $i -eq $n ]] && >&2 echo "$host:$port not up after $n seconds, exiting" && exit 1; echo "waiting for $host:$port to come up"; sleep 1; i=$((i+1)); done
 
 # Manage credentials
 envsubst < /etc/powerdns/pdns.conf.var > /etc/powerdns/pdns.conf