1
0
Fork 0

Implement docker-compose setup for CAcert software

This commit is contained in:
Jan Dittberner 2020-12-20 14:52:15 +01:00 committed by Jan Dittberner
commit 279dbcffbf
17 changed files with 642 additions and 0 deletions

1
.dockerignore Normal file
View file

@ -0,0 +1 @@
.env

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
.idea/
cacert-cats/
cacert-mgr/
cacert-software/
.env
testca/

8
.mrconfig Normal file
View file

@ -0,0 +1,8 @@
[cacert-cats]
checkout = git clone https://github.com/CAcertOrg/cats cacert-cats
[cacert-mgr]
checkout = git clone git+ssh://git.cacert.org/srv/git/cacert-mgr.git cacert-mgr
[cacert-software]
checkout = git clone git+ssh://git.cacert.org/srv/git/cacert-devel.git cacert-software

56
application.Dockerfile Normal file
View file

@ -0,0 +1,56 @@
FROM debian:jessie
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
libapache2-mod-php5 \
locales-all \
mariadb-client \
nullmailer \
php-apc \
php-mail \
php-mail-mime \
php-mail-mimedecode \
php-net-smtp \
php-net-socket \
php5-apcu \
php5-curl \
php5-gd \
php5-imagick \
php5-imap \
php5-json \
php5-mcrypt \
php5-mysql \
php5-pspell \
php5-recode \
psmisc \
wamerican \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
STOPSIGNAL SIGWINCH
COPY docker/apache-foreground /usr/local/bin/
COPY testca/ /usr/local/etc/testca/
COPY docker/mysql.php /usr/local/etc/application/mysql.php
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
COPY docker/feed.rss /usr/local/etc/application/feed.rss
VOLUME /www
RUN a2ensite apache-virtualhost ; \
a2dissite 000-default ; \
a2enconf cacert ; \
a2enmod headers ; \
a2enmod rewrite ; \
a2enmod ssl ; \
ln -s /etc/php5/mods-available/cacert.ini /etc/php5/apache2/conf.d/20-cacert.ini
EXPOSE 80
EXPOSE 443
CMD ["/usr/local/bin/apache-foreground"]

39
docker-compose.yml Normal file
View file

@ -0,0 +1,39 @@
---
version: "3.8"
services:
db:
build:
context: .
dockerfile: mariadb.Dockerfile
env_file:
- ./.env
volumes:
- db:/var/lib/mysql
ports:
- "13306:3306"
healthcheck:
test: out=$$(mysqladmin ping -h localhost -P 3306 -u root -p$$MYSQL_ROOT_PASSWORD 2>&1); echo $$out | grep 'mysqld is alive' || { echo $$out ; exit 1 ; }
smtp:
build:
context: .
dockerfile: smtp.Dockerfile
volumes:
- maildir:/home/catchall/Maildir
application:
build:
context: .
dockerfile: application.Dockerfile
env_file:
- ./.env
ports:
- "8080:80"
- "8443:443"
depends_on:
- db
- smtp
volumes:
- ./cacert-software:/www
volumes:
db: { }
maildir: { }

27
docker/apache-foreground Executable file
View file

@ -0,0 +1,27 @@
#!/bin/sh
set -eux
# Apache gets grumpy about PID files pre-existing
rm -f /run/apache2/apache2.pid
cp /usr/local/etc/testca/certs/test.cacert.org.crt.pem /etc/ssl/certs/test.cacert.org.crt
cp /usr/local/etc/testca/certs/test.cacert.org.key.pem /etc/ssl/private/test.cacert.org.pem
(
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.org.crt.pem /etc/ssl/certs/secure.crt
cp /usr/local/etc/testca/certs/secure.test.cacert.org.key.pem /etc/ssl/private/secure_test_cacert_org.pem
sed -i "s/@MYSQL_USERNAME@/$MYSQL_APP_USER/g; s/@MYSQL_PASSWORD@/$MYSQL_APP_PASSWORD/g" \
/usr/local/etc/application/mysql.php
if [ ! -f /www/includes/mysql.php ]; then
rm -f /www/includes/mysql.php
cp /usr/local/etc/application/mysql.php /www/includes/mysql.php
fi
cp /usr/local/etc/application/feed.rss /www/pages/index/feed.rss
apache2ctl start "$@"
exec tail -F --follow=name --retry /var/log/apache2/error.log /var/log/apache2/phperror.log

View file

@ -0,0 +1,74 @@
<VirtualHost *:80>
ServerName test.cacert.org
ServerAlias www.test.cacert.org
DocumentRoot /www/www
ScriptAlias /cgi-bin/ /www/cgi-bin/
Redirect permanent /revoke.crl http://crl.cacert.org/revoke.crl
Redirect permanent /class3-revoke.crl http://crl.cacert.org/class3-revoke.crl
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
<Directory /www/www/policy>
AddDefaultCharset utf-8
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName test.cacert.org
ServerAlias www.test.cacert.org
DocumentRoot /www/www
SSLEngine on
SSLStrictSNIVHostCheck on
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite kEECDH:kEDH:AESGCM:ALL:!3DES!RC4:!LOW:!EXP:!MD5:!aNULL:!eNULL
SSLCertificateFile /etc/ssl/certs/test.cacert.org.crt
SSLCertificateKeyFile /etc/ssl/private/test.cacert.org.pem
SSLCACertificateFile /etc/ssl/certs/combined.crt
Header always set Strict-Transport-Security "max-age=31536000"
ScriptAlias /cgi-bin/ /www/cgi-bin/
Redirect permanent /revoke.crl http://crl.cacert.org/revoke.crl
Redirect permanent /class3-revoke.crl http://crl.cacert.org/class3-revoke.crl
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
<Directory /www/www/policy>
AddDefaultCharset utf-8
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName secure.test.cacert.org
ServerAlias secure.test.cacert.org
DocumentRoot /www/www
SSLEngine on
SSLStrictSNIVHostCheck on
SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite kEECDH:kEDH:AESGCM:ALL:!3DES!RC4:!LOW:!EXP:!MD5:!aNULL:!eNULL
SSLCertificateFile /etc/ssl/certs/secure.crt
SSLCertificateKeyFile /etc/ssl/private/secure_test_cacert_org.pem
SSLVerifyClient require
SSLVerifyDepth 2
SSLCACertificateFile /etc/ssl/certs/combined.crt
#SSLCARevocationFile /etc/ssl/crls/cacert-combined.crl
#SSLOCSPEnable on
#SSLOCSPDefaultResponder http://ocsp.cacert.org/
SSLOptions +StdEnvVars
Header always set Strict-Transport-Security "max-age=31536000"
Redirect permanent /revoke.crl http://crl.cacert.org/revoke.crl
Redirect permanent /class3-revoke.crl http://crl.cacert.org/class3-revoke.crl
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
<Directory /www/www/policy>
AddDefaultCharset utf-8
</Directory>
</VirtualHost>

55
docker/cacert.conf Normal file
View file

@ -0,0 +1,55 @@
# customized settings for CAcert webserver
MaxRequestsPerChild 100
ServerAdmin support@cacert.org
ServerName cacert.org
Header always set X-Frame-Options "DENY"
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Content-Type-Options "nosniff"
DocumentRoot /www/www
<Directory />
Options -Indexes +Includes +FollowSymLinks
AllowOverride None
</Directory>
<Directory /www/www>
Options -Indexes +Includes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<Directory /www/www/docs>
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride None
</Directory>
<Directory /www/stamp>
Options -Indexes +Includes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
UseCanonicalName off
HostnameLookups on
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" mod_gzip: %{mod_gzip_compression_ratio}npct. %T %v" full
CustomLog /var/log/apache2/access.log full
ServerSignature off
AddDefaultCharset on
<IfModule mod_ssl.c>
# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:${APACHE_RUN_DIR}/ocsp(1280000)
SSLStaplingFakeTryLater off
SSLStaplingStandardCacheTimeout 86400
</IfModule>

18
docker/feed.rss Normal file
View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?><!-- generator="WordPress/2.5.1" -->
<rss version="0.92">
<channel>
<title>CAcert NEWS Blog</title>
<link>http://blog.cacert.org</link>
<description>CAcert NEWS and up coming events.</description>
<lastBuildDate>Fri, 20 Aug 2010 11:54:30 +0000</lastBuildDate>
<docs>http://backend.userland.com/rss092</docs>
<language>en</language>
<item>
<title>Looking for confirmation email on creating account?</title>
<description>Please go to https://ca-mgr1.it-sls.de/login login with your just created account and password. Under MAIL you'll find your individual confirmation email.
</description>
<link>https://ca-mgr1.it-sls.de/testsystemdoc.html</link>
</item>
</channel>
</rss>

14
docker/initdb.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/sh
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@'%';
EOF
for script in /db_migrations/*.sh; do
sh "$script" -h localhost -u root "-p$MYSQL_ROOT_PASSWORD" cacert
done

114
docker/mysql.php Normal file
View file

@ -0,0 +1,114 @@
<? /*
LibreSSL - CAcert web application
Copyright (C) 2004-2008 CAcert Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
$_SESSION['mconn'] = mysql_connect("db", "@MYSQL_USERNAME@", "@MYSQL_PASSWORD@");
if ($_SESSION['mconn'] != FALSE)
{
mysql_select_db("cacert");
$_SESSION['mconn'] = TRUE;
}
$_SESSION['_config']['normalhostname'] = "test.cacert.org:8443";
$_SESSION['_config']['securehostname'] = "secure.test.cacert.org:8443";
$_SESSION['_config']['tverify'] = "tverify.cacert.org";
function sendmail($to, $subject, $message, $from, $replyto = "", $toname = "", $fromname = "", $errorsto = "returns@cacert.org", $use_utf8 = true)
{
$lines = explode("\n", $message);
$message = "";
foreach($lines as $line)
{
$line = trim($line);
if($line == ".")
$message .= " .\n";
else
$message .= $line."\n";
}
if($fromname == "")
$fromname = $from;
$bits = explode(",", $from);
$from = addslashes($bits['0']);
$fromname = addslashes($fromname);
$smtp = fsockopen("smtp", 25);
if(!$smtp)
{
echo("Could not connect to mailserver at localhost:25\n");
return;
}
$InputBuffer = fgets($smtp, 1024);
fputs($smtp, "EHLO test.cacert.org\r\n");
$InputBuffer = fgets($smtp, 1024);
fputs($smtp, "MAIL FROM:<returns@cacert.org>\r\n");
$InputBuffer = fgets($smtp, 1024);
$bits = explode(",", $to);
foreach($bits as $user)
fputs($smtp, "RCPT TO:<".trim($user).">\r\n");
$InputBuffer = fgets($smtp, 1024);
fputs($smtp, "DATA\r\n");
$InputBuffer = fgets($smtp, 1024);
fputs($smtp, "X-Mailer: CAcert.org Website\r\n");
if (array_key_exists("REMOTE_ADDR", $_SERVER))
fputs($smtp, "X-OriginatingIP: ".$_SERVER["REMOTE_ADDR"]."\r\n");
fputs($smtp, "Sender: $errorsto\r\n");
fputs($smtp, "Errors-To: $errorsto\r\n");
if($replyto != "")
fputs($smtp, "Reply-To: $replyto\r\n");
else
fputs($smtp, "Reply-To: $from\r\n");
fputs($smtp, "From: $from\r\n");
fputs($smtp, "To: $to\r\n");
if(preg_match("/[^a-zA-Z0-9 .-\[\]!_@]/",$subject))
{
fputs($smtp, "Subject: =?utf-8?B?".base64_encode(recode("html..utf-8", $subject))."?=\r\n");
}
else
{
fputs($smtp, "Subject: $subject\r\n");
}
fputs($smtp, "Mime-Version: 1.0\r\n");
if($use_utf8)
{
fputs($smtp, "Content-Type: text/plain; charset=\"utf-8\"\r\n");
}
else
{
fputs($smtp, "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n");
}
fputs($smtp, "Content-Transfer-Encoding: quoted-printable\r\n");
fputs($smtp, "Content-Disposition: inline\r\n");
// fputs($smtp, "Content-Transfer-Encoding: BASE64\r\n");
fputs($smtp, "\r\n");
// fputs($smtp, chunk_split(base64_encode(recode("html..utf-8", $message)))."\r\n.\r\n");
$encoded_lines = explode( "\n", str_replace("\r", "", $message) );
array_walk( $encoded_lines,
function (&$a) {
$a = quoted_printable_encode(recode("html..utf-8", $a));
});
$encoded_message = implode("\n", $encoded_lines);
$encoded_message = str_replace("\r.", "\r=2E", $encoded_message);
$encoded_message = str_replace("\n.", "\n=2E", $encoded_message);
fputs($smtp, $encoded_message);
fputs($smtp, "\r\n.\r\n");
fputs($smtp, "QUIT\n");
$InputBuffer = fgets($smtp, 1024);
fclose($smtp);
}

20
docker/php5-cacert.ini Normal file
View file

@ -0,0 +1,20 @@
;
; Additional settings for CAcert webdb application
;
safe_mode_allowed_env_vars = LC_ALL,LANG,LANGUAGE,PHP_
disable_functions = passthru
expose_php = Off
memory_limit = 18M
display_errors = Off
log_errors = On
error_log = /var/log/apache2/phperrors.log
sendmail_path = "/usr/sbin/sendmail -t -i -freturns@cacert.org"
session.use_only_cookies = On
session.cookie_secure = On
error_reporting = E_ALL
short_open_tag = On
; Starting with PHP 5.6, PHP's default character set is set to UTF-8.
; This is not what the current CAcert application code expects, so we
; overrrule it with the earlier default.
default_charset = "iso-8859-1"

7
docker/run-postfix Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh
set -eu
mkdir -p /home/catchall/Maildir/tmp /home/catchall/Maildir/new /home/catchall/Maildir/cur
chown -Rc catchall.catchall /home/catchall/Maildir
postfix start-fg

15
imap.Dockerfile Normal file
View file

@ -0,0 +1,15 @@
FROM debian:buster
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
dovecot-imapd \
psmisc \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 25
COPY docker/start-postfix.sh /usr/local

4
mariadb.Dockerfile Normal file
View file

@ -0,0 +1,4 @@
FROM mariadb:focal
COPY docker/initdb.sh /docker-entrypoint-initdb.d/initdb.sh
COPY cacert-software/scripts/db_migrations/*.sh /db_migrations/

155
setup_test_ca.sh Executable file
View file

@ -0,0 +1,155 @@
#!/bin/sh
set -eux
if [ -d testca/ ]; then
echo "testca/ exists, remove it if you want to start from scratch"
exit 1
fi
ORGANIZATION="CAcert Inc."
COUNTRY_CODE="AU"
mkdir -p testca/
cd testca
mkdir -p root/newcerts class3/newcerts root/private class3/private certs
touch root/index.txt class3/index.txt
cat >ca.cnf <<EOF
[ca]
default_ca = class3_ca
[root_ca]
dir = ./root
certs = \$dir/certs
crl_dir = \$dir/crl
database = \$dir/index.txt
serial = \$dir/serial
new_certs_dir = \$dir/newcerts
crl = \$dir/crl.pem
certificate = \$dir/ca.crt.pem
private_key = \$dir/private/ca.key.pem
RANDFILE = \$dir/private/.rand
policy = policy_any
unique_subject = no
email_in_dn = no
copy_extensions = none
default_md = sha256
default_days = 1825
default_crl_days = 30
extensions = intermediary_extensions
[class3_ca]
dir = ./class3
certs = \$dir/certs
crl_dir = \$dir/crl
database = \$dir/index.txt
serial = \$dir/serial
new_certs_dir = \$dir/newcerts
crl = \$dir/crl.pem
certificate = \$dir/ca.crt.pem
private_key = \$dir/private/ca.key.pem
RANDFILE = \$dir/private/.rand
policy = policy_any
unique_subject = no
email_in_dn = no
copy_extensions = copy
default_md = sha256
default_days = 365
default_crl_days = 30
extensions = class3_extensions
[policy_any]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[req]
default_bits = 3072
prompt = no
utf8 = yes
distinguished_name = req_distinguished_name
[req_distinguished_name]
countryName = AU
organizationName = CAcert Inc.
organizationalUnitName = Software Testing
[root_extensions]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[class3_extensions]
basicConstraints = critical,CA:true,pathlen:0
keyUsage = critical,keyCertSign,cRLSign
extendedKeyUsage = serverAuth,clientAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
authorityInfoAccess = 1.3.6.1.5.5.7.48.2;URI:http://test.cacert.org/ca/root/ca.crt,OCSP;URI:http://ocsp.test.cacert.org/
crlDistributionPoints = URI:http://crl.test.cacert.org/class3.crl
certificatePolicies = @policy_class3_ca
[server_ext]
basicConstraints = critical,CA:false
keyUsage = digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
authorityInfoAccess = 1.3.6.1.5.5.7.48.2;URI:http://test.cacert.org/ca/class3/ca.crt,OCSP;URI:http://ocsp.test.cacert.org/
crlDistributionPoints = URI:http://crl.test.cacert.org/class3.crl
certificatePolicies = @policy_class3_ca
[policy_class3_ca]
policyIdentifier = 1.3.6.1.5.5.7.2.1
CPS = http://test.cacert.org/ca/class3/cps.html
EOF
openssl req -new -x509 -config ca.cnf \
-keyout root/private/ca.key.pem \
-nodes \
-subj "/CN=Test Root/C=${COUNTRY_CODE}/O=${ORGANIZATION}" \
-days 3650 \
-extensions root_extensions \
-out root/ca.crt.pem
openssl req -new -config ca.cnf \
-keyout class3/private/ca.key.pem \
-nodes \
-subj "/CN=Class 3 Test CA/C=${COUNTRY_CODE}/O=${ORGANIZATION}" \
-out class3/ca.csr.pem
openssl ca -config ca.cnf \
-name root_ca \
-in class3/ca.csr.pem -out class3/ca.crt.pem \
-rand_serial \
-extensions class3_extensions \
-batch
openssl req -new -keyout certs/test.cacert.org.key.pem -nodes \
-out certs/test.cacert.org.csr.pem -subj "/CN=test.cacert.org" \
-addext "subjectAltName=DNS:test.cacert.org,DNS:www.test.cacert.org"
openssl req -new -keyout certs/secure.test.cacert.org.key.pem -nodes \
-out certs/secure.test.cacert.org.csr.pem -subj "/CN=secure.test.cacert.org" \
-addext "subjectAltName=DNS:secure.test.cacert.org"
openssl ca -config ca.cnf \
-name class3_ca \
-in certs/test.cacert.org.csr.pem \
-out certs/test.cacert.org.crt.pem \
-rand_serial \
-extensions server_ext \
-batch
openssl ca -config ca.cnf \
-name class3_ca \
-in certs/secure.test.cacert.org.csr.pem \
-out certs/secure.test.cacert.org.crt.pem \
-rand_serial \
-extensions server_ext \
-batch

29
smtp.Dockerfile Normal file
View file

@ -0,0 +1,29 @@
FROM debian:buster
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
dumb-init \
mutt \
postfix \
postfix-pcre \
psmisc \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 25
RUN adduser --uid 1000 --gecos "catchall mailbox" --disabled-password catchall ; \
postconf home_mailbox=Maildir/ ; \
postconf maillog_file=/dev/stdout ; \
postconf mailbox_command= ; \
postconf virtual_alias_maps=pcre:/etc/postfix/virtual ; \
echo '/.*/ catchall' > /etc/postfix/virtual
VOLUME /home/catchall/Maildir
COPY docker/run-postfix /usr/local/bin/run-postfix
CMD ["dumb-init", "/usr/local/bin/run-postfix"]