From 30ddadd954addb51792f83d7745a61294a7e0beb Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Tue, 22 Dec 2020 08:49:18 +0100 Subject: [PATCH] Add test mgr setup --- README.md | 7 ++ application.Dockerfile | 7 +- docker-compose.yml | 19 +++ docker/apache-foreground | 10 -- docker/apache-mgr-foreground | 17 +++ docker/apache-mgr-virtualhost.conf | 21 ++++ docker/initdb.sh | 19 ++- docker/mgr-application.ini | 57 +++++++++ docker/run-dovecot | 4 + docker/run-postfix | 2 +- mail.Dockerfile | 23 ++++ mariadb.Dockerfile | 1 + mgr.Dockerfile | 44 +++++++ setup_test_ca.sh | 178 +++++++++++++++++++++-------- 14 files changed, 345 insertions(+), 64 deletions(-) create mode 100755 docker/apache-mgr-foreground create mode 100644 docker/apache-mgr-virtualhost.conf create mode 100644 docker/mgr-application.ini create mode 100755 docker/run-dovecot create mode 100644 mail.Dockerfile create mode 100644 mgr.Dockerfile diff --git a/README.md b/README.md index 10a7a11..026d2f2 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ Variable | Usage `MYSQL_ROOT_PASSWORD` | Database root password `MYSQL_APP_USER` | Database application user `MYSQL_APP_PASSWORD` | Database application password +`CLIENT_CERT_EMAIL` | email address for client certificate generated by `setup_test_ca.sh` +`CLIENT_CERT_USERNAME` | user name for client certificate generated by `setup_test_ca.sh` +`CLIENT_CERT_PASSWORD` | PKCS#12 keystore password for client certificate generated by `setup_test_ca.sh` ```shell echo -e "MYSQL_ROOT_PASSWORD=$(openssl rand -base64 18)\nMYSQL_APP_USER=cacert_dev\nMYSQL_APP_PASSWORD=$(openssl rand -base64 18)" > .env @@ -43,3 +46,7 @@ docker-compose up ``` After these steps you should be able to reach the CAcert application at https://test.cacert.localhost:8443/. +The test manager application is reachable at https://mgr.cacert.localhost:9443/. + +A client certificate is created by `setup_test_ca.sh` and is placed in `testca/certs/clientcert.p12` +which can be imported in a browser to support client certificate authentication. diff --git a/application.Dockerfile b/application.Dockerfile index f870bb7..89583f3 100644 --- a/application.Dockerfile +++ b/application.Dockerfile @@ -40,7 +40,12 @@ RUN apt-get update \ STOPSIGNAL SIGWINCH COPY docker/apache-foreground /usr/local/bin/ -COPY testca/ /usr/local/etc/testca/ +COPY testca/root/ca.crt.pem /usr/local/share/ca-certificates/testca_root.crt +COPY testca/class3/ca.crt.pem /usr/local/share/ca-certificates/testca_class3.crt +COPY testca/certs/test.cacert.localhost.crt.pem testca/certs/secure.test.cacert.localhost.crt.pem /etc/ssl/certs/ +COPY testca/certs/test.cacert.localhost.key.pem testca/certs/secure.test.cacert.localhost.key.pem /etc/ssl/private/ +COPY testca/certs/cachain.crt.pem /etc/ssl/certs/combined.crt + COPY docker/apache-virtualhost.conf /etc/apache2/sites-available/ COPY docker/cacert.conf /etc/apache2/conf-available/ COPY docker/php5-cacert.ini /etc/php5/mods-available/cacert.ini diff --git a/docker-compose.yml b/docker-compose.yml index 5b0cf8b..6151567 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,6 +19,12 @@ services: dockerfile: smtp.Dockerfile volumes: - maildir:/home/catchall/Maildir + mail: + build: + context: . + dockerfile: mail.Dockerfile + volumes: + - maildir:/home/catchall/Maildir application: build: context: . @@ -46,6 +52,19 @@ services: - smtp volumes: - ./cacert-software:/www + mgr: + build: + context: . + dockerfile: mgr.Dockerfile + env_file: + - ./.env + ports: + - "9443:443" + depends_on: + - db + - mail + volumes: + - ./cacert-mgr:/var/www volumes: db: { } diff --git a/docker/apache-foreground b/docker/apache-foreground index e0c24d9..f83ae5a 100755 --- a/docker/apache-foreground +++ b/docker/apache-foreground @@ -4,16 +4,6 @@ set -eux # Apache gets grumpy about PID files pre-existing rm -f /run/apache2/apache2.pid -cp /usr/local/etc/testca/certs/test.cacert.localhost.crt.pem /etc/ssl/certs/ -cp /usr/local/etc/testca/certs/test.cacert.localhost.key.pem /etc/ssl/private/ -( - openssl x509 -in /usr/local/etc/testca/class3/ca.crt.pem - openssl x509 -in /usr/local/etc/testca/root/ca.crt.pem -) >/etc/ssl/certs/combined.crt - -cp /usr/local/etc/testca/certs/secure.test.cacert.localhost.crt.pem /etc/ssl/certs/ -cp /usr/local/etc/testca/certs/secure.test.cacert.localhost.key.pem /etc/ssl/private/ - cp /usr/local/etc/application/feed.rss /www/pages/index/feed.rss make -C /www/locale diff --git a/docker/apache-mgr-foreground b/docker/apache-mgr-foreground new file mode 100755 index 0000000..e7dc445 --- /dev/null +++ b/docker/apache-mgr-foreground @@ -0,0 +1,17 @@ +#!/bin/sh +set -eux + +# Apache gets grumpy about PID files pre-existing +rm -f /run/apache2/apache2.pid + +sed "s/@MYSQL_MGR_USER@/${MYSQL_MGR_USER}/g; s/@MYSQL_MGR_PASSWORD@/${MYSQL_MGR_PASSWORD}/g" \ + /usr/local/etc/mgr-application.ini > /var/www/manager/application/configs/application.ini + +mysql -u "${MYSQL_MGR_USER}" -h db "-p${MYSQL_MGR_PASSWORD}" mgr <<-EOF +REPLACE INTO system_user (id, system_role_id, login, user_client_crt_s_dn_i_dn) +VALUES (2, 2,'${CLIENT_CERT_EMAIL}','/CN=${CLIENT_CERT_USERNAME}///C=AU/O=CAcert Inc./CN=Class 3 Test CA'); +EOF + +apache2ctl start "$@" + +exec tail -F --follow=name --retry /var/log/apache2/error.log diff --git a/docker/apache-mgr-virtualhost.conf b/docker/apache-mgr-virtualhost.conf new file mode 100644 index 0000000..707958b --- /dev/null +++ b/docker/apache-mgr-virtualhost.conf @@ -0,0 +1,21 @@ + + ServerName mgr.cacert.localhost + ServerAlias www.mgr.cacert.localhost + DocumentRoot /var/www/manager/public + + SSLEngine on + SSLStrictSNIVHostCheck on + SSLProtocol all -SSLv2 -SSLv3 -TLSv1 + SSLHonorCipherOrder on + SSLCipherSuite kEECDH:kEDH:AESGCM:ALL:!3DES!RC4:!LOW:!EXP:!MD5:!aNULL:!eNULL + SSLCertificateFile /etc/ssl/certs/mgr.cacert.localhost.crt.pem + SSLCertificateKeyFile /etc/ssl/private/mgr.cacert.localhost.key.pem + SSLCertificateChainFile /etc/ssl/certs/combined.crt + + SSLCACertificateFile /etc/ssl/certs/combined.crt + SSLVerifyClient require + SSLVerifyDepth 2 + SSLOptions +StdEnvVars + + Header always set Strict-Transport-Security "max-age=31536000" + diff --git a/docker/initdb.sh b/docker/initdb.sh index 4a1cc21..83b34dd 100755 --- a/docker/initdb.sh +++ b/docker/initdb.sh @@ -4,15 +4,15 @@ set -eux mysql -h localhost -u root "-p$MYSQL_ROOT_PASSWORD" <<-EOF CREATE database cacert CHARSET latin1 COLLATE latin1_swedish_ci; -CREATE USER $MYSQL_APP_USER@'%' IDENTIFIED BY '$MYSQL_APP_PASSWORD'; -GRANT CREATE TEMPORARY TABLES ON cacert.* TO $MYSQL_APP_USER@'%'; -GRANT SELECT, INSERT, UPDATE, DELETE ON cacert.* TO $MYSQL_APP_USER@'%'; +CREATE database mgr CHARSET utf8 COLLATE utf8_unicode_ci; EOF for script in /db_migrations/*.sh; do sh "$script" -h localhost -u root "-p$MYSQL_ROOT_PASSWORD" cacert done +mysql -h localhost -u root "-p$MYSQL_ROOT_PASSWORD" mgr ca.cnf <certs/cachain.crt.pem +fi + +if [ ! -f certs/cats.cacert.localhost.crt.pem ]; then + openssl req -new -keyout certs/cats.cacert.localhost.key.pem -nodes \ + -out certs/cats.cacert.localhost.csr.pem -subj "/CN=cats.cacert.localhost" \ + -addext "subjectAltName=DNS:cats.cacert.localhost,DNS:www.cats.cacert.localhost" + openssl ca -config ca.cnf \ + -name class3_ca \ + -in certs/cats.cacert.localhost.csr.pem \ + -out certs/cats.cacert.localhost.crt.pem \ + -rand_serial \ + -extensions server_ext \ + -batch +fi +if [ ! -f certs/cats-client.cacert.localhost.crt.pem ]; then + openssl req -new -keyout certs/cats-client.cacert.localhost.key.pem -nodes \ + -out certs/cats-client.cacert.localhost.csr.pem -subj "/CN=cats.cacert.localhost" \ + -addext "subjectAltName=DNS:cats.cacert.localhost" + openssl ca -config ca.cnf \ + -name class3_ca \ + -in certs/cats-client.cacert.localhost.csr.pem \ + -out certs/cats-client.cacert.localhost.crt.pem \ + -rand_serial \ + -extensions client_ext \ + -batch +fi +if [ ! -f certs/mgr.cacert.localhost.crt.pem ]; then + openssl req -new -keyout certs/mgr.cacert.localhost.key.pem -nodes \ + -out certs/mgr.cacert.localhost.csr.pem -subj "/CN=mgr.cacert.localhost" \ + -addext "subjectAltName=DNS:mgr.cacert.localhost,DNS:www.mgr.cacert.localhost" + openssl ca -config ca.cnf \ + -name class3_ca \ + -in certs/mgr.cacert.localhost.csr.pem \ + -out certs/mgr.cacert.localhost.crt.pem \ + -rand_serial \ + -extensions server_ext \ + -batch +fi +if [ ! -f certs/secure.test.cacert.localhost.crt.pem ]; then + openssl req -new -keyout certs/secure.test.cacert.localhost.key.pem -nodes \ + -out certs/secure.test.cacert.localhost.csr.pem -subj "/CN=secure.test.cacert.localhost" \ + -addext "subjectAltName=DNS:secure.test.cacert.localhost" + openssl ca -config ca.cnf \ + -name class3_ca \ + -in certs/secure.test.cacert.localhost.csr.pem \ + -out certs/secure.test.cacert.localhost.crt.pem \ + -rand_serial \ + -extensions server_ext \ + -batch +fi +if [ ! -f certs/test.cacert.localhost.crt.pem ]; then + openssl req -new -keyout certs/test.cacert.localhost.key.pem -nodes \ + -out certs/test.cacert.localhost.csr.pem -subj "/CN=test.cacert.localhost" \ + -addext "subjectAltName=DNS:test.cacert.localhost,DNS:www.test.cacert.localhost" + openssl ca -config ca.cnf \ + -name class3_ca \ + -in certs/test.cacert.localhost.csr.pem \ + -out certs/test.cacert.localhost.crt.pem \ + -rand_serial \ + -extensions server_ext \ + -batch +fi + +if [ ! -f certs/testclient.p12 ]; then + openssl req -new -keyout certs/testclient.key.pem -nodes \ + -out certs/testclient.csr.pem -subj "/CN=${CLIENT_CERT_USERNAME}" \ + -addext "subjectAltName=email:${CLIENT_CERT_EMAIL}" + openssl ca -config ca.cnf \ + -name class3_ca \ + -in certs/testclient.csr.pem \ + -out certs/testclient.crt.pem \ + -rand_serial \ + -extensions client_ext \ + -batch + openssl pkcs12 -export -out certs/testclient.p12 \ + -passout "pass:${CLIENT_CERT_PASSWORD}" \ + -chain -CAfile certs/cachain.crt.pem \ + -inkey certs/testclient.key.pem \ + -in certs/testclient.crt.pem \ + -name "${CLIENT_CERT_USERNAME}" +fi