From d10b0c7778db2560212d28ed4e9f5f5b6f076472 Mon Sep 17 00:00:00 2001 From: Joerg Deckert Date: Sat, 16 Nov 2024 10:03:25 +0100 Subject: [PATCH] first release --- LICENSE | 2 +- Makefile | 27 ++++++++ apache/default_vhost.include | 73 ++++++++++++++++++++++ appliance/02firstboot.start | 109 +++++++++++++++++++++++++++++++++ appliance/PostgreSQL-Backup.sh | 35 +++++++++++ appliance/backup.service | 8 +++ appliance/backup.timer | 12 ++++ appliance/cert-renew.service | 8 +++ appliance/cert-renew.sh | 52 ++++++++++++++++ appliance/cert-renew.timer | 12 ++++ make.conf | 6 ++ package.accept_keywords | 3 + package.use | 7 +++ va-kivitendo.cfg | 2 + world | 5 ++ 15 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 apache/default_vhost.include create mode 100755 appliance/02firstboot.start create mode 100755 appliance/PostgreSQL-Backup.sh create mode 100644 appliance/backup.service create mode 100644 appliance/backup.timer create mode 100644 appliance/cert-renew.service create mode 100755 appliance/cert-renew.sh create mode 100644 appliance/cert-renew.timer create mode 100644 make.conf create mode 100644 package.accept_keywords create mode 100644 package.use create mode 100644 va-kivitendo.cfg create mode 100644 world diff --git a/LICENSE b/LICENSE index d635d6b..e489b3f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 VA +Copyright (c) 2024 Unitas Network GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cb1c90c --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +02firstboot = $(CHROOT)/usr/local/bin/02firstboot.start +cert-renew.sh = $(CHROOT)/etc/ssl/cert-renew.sh + +systemd-units: appliance/PostgreSQL-Backup.sh appliance/backup.service appliance/backup.timer appliance/cert-renew.service appliance/cert-renew.timer + mkdir -p $(CHROOT)/usr/local/bin + cp appliance/PostgreSQL-Backup.sh $(CHROOT)/usr/local/bin/ + cp appliance/backup.service appliance/backup.timer appliance/cert-renew.service appliance/cert-renew.timer $(CHROOT)/etc/systemd/system/ + +$(02firstboot): appliance/02firstboot.start + mkdir -p $(CHROOT)/usr/local/bin + cp $< $@ + touch $(CHROOT)/02firstboot + +$(cert-renew.sh): appliance/cert-renew.sh + mkdir -p $(CHROOT)/etc/ssl + cp $< $@ + +preinstall: + +postinstall: systemd-units $(02firstboot) $(cert-renew.sh) +## # Wegen Abhängigkeiten wird Perl mit USE=ithreads gebaut. +## # Deswegen müssen auch alle Module neu erstellt werden. +## RUN perl-cleaner --reallyall + # configure postgresql + sed -i 's#^PG_INITDB_OPTS=.*#PG_INITDB_OPTS="--encoding=UTF8 --locale=de_DE.UTF-8"#' $(CHROOT)/etc/conf.d/postgresql-* + rm -rf $(CHROOT)/var/lib/postgresql/* + RUN emerge --config dev-db/postgresql diff --git a/apache/default_vhost.include b/apache/default_vhost.include new file mode 100644 index 0000000..9efd6e9 --- /dev/null +++ b/apache/default_vhost.include @@ -0,0 +1,73 @@ +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +ServerAdmin root@localhost + +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +# If you change this to something that isn't under /var/www then suexec +# will no longer work. +DocumentRoot "/var/www/localhost/htdocs" + +# This should be changed to whatever you set DocumentRoot to. + + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + Options Indexes FollowSymLinks + + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + AllowOverride All + + # Controls who can get stuff from this server. + Require all granted + + +# Kivitendo CGI +AliasMatch ^/kivitendo-erp/[^/]+\.pl /var/www/localhost/kivitendo-erp/dispatcher.pl +Alias /kivitendo-erp/ /var/www/localhost/kivitendo-erp/ + + + AddHandler cgi-script .pl + Options ExecCGI Includes FollowSymlinks + # das folg. war in der Kivitendo-Doku nicht drin + # ohne gibts aber Forbidden... + Require all granted + + + + Require all granted + + + +### Kivitento FCGI +##AddHandler cgi-script .pl .fpl .fcgi +##AliasMatch ^/[^/]+\.pl /var/www/localhost/kivitendo-erp/dispatcher.fcgi +##Alias / /var/www/localhost/kivitendo-erp/ +## +## +## AllowOverride All +## Options ExecCGI Includes FollowSymlinks +## Require all granted +## +## +## +## Require all denied +## +## +## +## Require all denied +## + +# vim: ts=4 filetype=apache diff --git a/appliance/02firstboot.start b/appliance/02firstboot.start new file mode 100755 index 0000000..78dc3be --- /dev/null +++ b/appliance/02firstboot.start @@ -0,0 +1,109 @@ +#!/bin/bash + +# variables +LABEL="DATA" +DATABASE_PASS=$(head -c 300 /dev/urandom | tr -cd 'a-zA-Z0-9' | head -c 16) +ADMIN_PASS=$(head -c 300 /dev/urandom | tr -cd 'a-zA-Z0-9' | head -c 8) +TLD="example.com" +HOST="kivitendo" +ORGNAME="Kivitendo example" + +# start +set -e + +PGVER=$(eselect postgresql show) + +[ -e /01firstboot ] && exit 0 +[ -e /02firstboot ] || exit 0 + +# Kivitendo configuration +if [ ! -L /var/www/localhost/kivitendo-erp/config/kivitendo.conf ]; then + if [ ! -f "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" ]; then + echo 'Create Kivitendo config...' + mkdir -p "/$LABEL/var/www/localhost/kivitendo-erp/config" + echo "[authentication]" > "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "admin_password = $ADMIN_PASS" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "cookie_name = kivitendo_session_01" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "session_timeout = 600" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "[authentication/database]" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "host = localhost" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "port = 5432" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "db = kivitendo_auth" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "user = kivitendo" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "password = $DATABASE_PASS" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "[system]" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "language = de" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "stylesheet = kivitendo" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "default_manager = german" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "[paths]" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "document_path = /var/www/localhost/kivitendo-erp/documents" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "[task_server]" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + echo "run_as = apache" >> "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" + ln -s "/$LABEL/var/www/localhost/kivitendo-erp/config/kivitendo.conf" /var/www/localhost/kivitendo-erp/config/kivitendo.conf + echo "/var/www/localhost/kivitendo-erp/config/kivitendo.conf" >> /DATA/.APPLIANCE/populate-data/LINK + fi +fi + +# Database +systemctl stop postgresql-$PGVER +if [ ! -d "/$LABEL/var/lib/postgresql" ]; then + echo 'Create kivitendo db user and auth database...' + mkdir -p "/$LABEL/var/lib" + rm -rf "/$LABEL/var/lib/postgresql.orig" + cp -a "/var/lib/postgresql" "/$LABEL/var/lib/postgresql.orig" + mv "/var/lib/postgresql" "/$LABEL/var/lib/postgresql" + ln -s "/$LABEL/var/lib/postgresql" "/var/lib/postgresql" + systemctl start postgresql-$PGVER + psql -U postgres -d template1 -c "CREATE EXTENSION IF NOT EXISTS plpgsql;" + psql -U postgres -d postgres -c "CREATE ROLE kivitendo WITH LOGIN;" + psql -U postgres -d postgres -c "ALTER USER kivitendo WITH PASSWORD '$DATABASE_PASS';" + # laut Kivitendo-Doku benötigt der Datenbankbenutzer "postgres" ein Paßwort + # Dieses wird im Folgenden auf das Kivitendo-Admin-Paßwort gesetzt + # Zumindest hier unter Gentoo wird das aber trotzdem nicht abgefragt. + # Evtl. gibt es dann Probleme mit Trigram Prozeduren. + psql -U postgres -d postgres -c "ALTER USER postgres WITH PASSWORD '$ADMIN_PASS';" + # Das Folgende steht auch nicht in der Doku, ohne kann aber über die Admin-GUI + # keine Mandanten-Datenbank angelegt werden + psql -U postgres -d postgres -c "ALTER USER kivitendo CREATEDB;" +else + echo 'start PostgreSQL DB...' + if [ ! -L /var/lib/postgresql ]; then + rm -rf "/$LABEL/var/lib/postgresql.orig" + mv "/var/lib/postgresql" "/$LABEL/var/lib/postgresql.orig" + ln -s "/$LABEL/var/lib/postgresql" "/var/lib/postgresql" + fi + systemctl start postgresql-$PGVER +fi + +# Certificate +if [ ! -f "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-cert.pem" ]; then + echo 'Create certificates...' + mkdir -p "/$LABEL/CERTS/KEYS/" + mkdir -p "/$LABEL/CERTS/$HOST.$TLD" + echo "FQDN = $HOST.$TLD" > "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" + echo "ORGNAME = $ORGNAME" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" + echo "ALTNAMES = DNS:$HOST.$TLD , DNS:$TLD" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" + echo -e "\n[ req ]\ndefault_bits = 4096\ndefault_md = sha256\nprompt = no\nencrypt_key = no\ndistinguished_name = dn\nreq_extensions = req_ext\ndefault_keyfile = ../KEYS/\$FQDN-key.pem\n" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" + echo -e "\n[ dn ]\nC = DE\nO = \$ORGNAME\nCN = \$FQDN\n" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" + echo -e "\n[ req_ext ]\nsubjectAltName = \$ALTNAMES" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" + openssl req -x509 -new -config "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" -out "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-cert.pem" -keyout "/$LABEL/CERTS/KEYS/$HOST.$TLD-key.pem" + cp "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-cert.pem" "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-fullchain.pem" + touch "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-chain.pem" +fi + +rm -rf /etc/ssl/apache2 +mkdir -p /etc/ssl +ln -sf "/$LABEL/etc/ssl/apache2" "/etc/ssl/apache2" + +/etc/ssl/cert-renew.sh + +systemctl enable postgresql-$PGVER +systemctl enable apache2 + +systemctl restart apache2 + +rm /02firstboot diff --git a/appliance/PostgreSQL-Backup.sh b/appliance/PostgreSQL-Backup.sh new file mode 100755 index 0000000..3a50d12 --- /dev/null +++ b/appliance/PostgreSQL-Backup.sh @@ -0,0 +1,35 @@ +#!/bin/bash +PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" + +DIR="/DATA/Backup/PostgreSQL" +USER="postgres" +##PASS="gentoo" + +if [ -z $1 ]; then + echo "database name missing! use --all for all db's" + exit 1; +elif [ $1 = '--all' ]; then + echo "full backup" +## for i in `psql -U $USER -l -t | cut -d'|' -f1 | sed -e 's/ //g' -e '/^$/d'`; do +for i in $(psql -U $USER -l -t | cut -d'|' -f1 | sed -e 's/ //g' -e '/^$/d'); do + if [ "$i" != "postgres" ] && [ "$i" != "template0" ] && [ "$i" != "template1" ] && [ "$i" != "template_postgis" ]; then + if test -f ${DIR}/${i}.sql; then + echo "Move ${DIR}/${i}.sql to ${DIR}/${i}.sql.1" + mv ${DIR}/${i}.sql ${DIR}/${i}.sql.1 + fi + echo "dump ${i} to ${DIR}/${i}.sql" + pg_dump -U $USER $i > ${DIR}/${i}.sql + chmod 600 ${DIR}/${i}.sql + fi + done; +elif [ -n $1 ]; then + echo "Starting backup of $1" + if test -f $DIR/$1.sql; then + echo "Move $DIR/$1.sql to $DIR/$1.sql.1" + mv ${DIR}/${1}.sql ${DIR}/${1}.sql.1 + fi + pg_dump -U $USER $1 > ${DIR}/${1}.sql + chmod 600 ${DIR}/${1}.sql +fi +echo "Done" +exit 0; diff --git a/appliance/backup.service b/appliance/backup.service new file mode 100644 index 0000000..619cd03 --- /dev/null +++ b/appliance/backup.service @@ -0,0 +1,8 @@ +[Unit] +Description=execute backup tasks +RefuseManualStart=no +RefuseManualStop=yes + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/PostgreSQL-Backup.sh --all diff --git a/appliance/backup.timer b/appliance/backup.timer new file mode 100644 index 0000000..ec59929 --- /dev/null +++ b/appliance/backup.timer @@ -0,0 +1,12 @@ +[Unit] +Description=execute backup tasks +RefuseManualStart=no +RefuseManualStop=no + +[Timer] +Persistent=false +OnCalendar=Sun *-*-* 02:19:00 +Unit=backup.service + +[Install] +WantedBy=default.target diff --git a/appliance/cert-renew.service b/appliance/cert-renew.service new file mode 100644 index 0000000..59ec86d --- /dev/null +++ b/appliance/cert-renew.service @@ -0,0 +1,8 @@ +[Unit] +Description=renew certificates from git store +RefuseManualStart=no +RefuseManualStop=yes + +[Service] +Type=oneshot +ExecStart=/etc/ssl/cert-renew.sh diff --git a/appliance/cert-renew.sh b/appliance/cert-renew.sh new file mode 100755 index 0000000..3e7bab8 --- /dev/null +++ b/appliance/cert-renew.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +HOST="kivitendo" +TLD="example.com" +FQDN="$HOST.$TLD" +LABEL="DATA" + +CERT_DIR=/$LABEL/CERTS +CERT_APACHE=/$LABEL/etc/ssl/apache2 +GETREPO="" +GETUSER="" +GETPASS="" + +function getCurrentVersion() { +# Get hash from latest revision + git log --format=format:%H -1 +} + +cd $CERT_DIR + +if [ -z "$GETREPO" ]; then + GIT_REVISION=0 + GIT_NEW_REVISION=1 + cd $FQDN +elif [ ! -d "$FQDN" ]; then + GIT_REVISION=0 + git clone "https://$GETUSER:$GETPASS@$GETREPO" + cd $FQDN + GIT_NEW_REVISION=$(getCurrentVersion) +else + cd $FQDN + GIT_REVISION=$(getCurrentVersion) + git commit -m "CRON: auto commit" + git fetch + git merge origin/master -m "Auto Merge" + GIT_NEW_REVISION=$(getCurrentVersion) +fi + +echo "old: $GIT_REVISION" +echo "new: $GIT_NEW_REVISION" + +if [ $GIT_REVISION != $GIT_NEW_REVISION ] +then + echo "Update Apache certificate..." + mkdir -p $CERT_APACHE + cp $CERT_DIR/$FQDN/$FQDN-fullchain.pem $CERT_APACHE/server.crt + cp $CERT_DIR/KEYS/$FQDN-key.pem $CERT_APACHE/server.key + echo "Restarting Apache..." + systemctl is-active --quiet apache2 && systemctl restart apache2 +fi + +exit 0 diff --git a/appliance/cert-renew.timer b/appliance/cert-renew.timer new file mode 100644 index 0000000..fa2ee54 --- /dev/null +++ b/appliance/cert-renew.timer @@ -0,0 +1,12 @@ +[Unit] +Description=renew certificates from git store +RefuseManualStart=no +RefuseManualStop=no + +[Timer] +Persistent=false +OnCalendar=Sun *-*-* 04:03:00 +Unit=cert-renew.service + +[Install] +WantedBy=default.target diff --git a/make.conf b/make.conf new file mode 100644 index 0000000..9264221 --- /dev/null +++ b/make.conf @@ -0,0 +1,6 @@ + +# Kivitendo +PERL_FEATURES="ithreads" + +# TeX Live +L10N="de el en" diff --git a/package.accept_keywords b/package.accept_keywords new file mode 100644 index 0000000..a6590d0 --- /dev/null +++ b/package.accept_keywords @@ -0,0 +1,3 @@ +# Kivitendo +dev-perl/Class-Std +dev-perl/Set-Crontab diff --git a/package.use b/package.use new file mode 100644 index 0000000..c14e070 --- /dev/null +++ b/package.use @@ -0,0 +1,7 @@ +# Kivitendo +dev-lang/perl ithreads +media-gfx/qrencode png + +# TeX Live +media-libs/harfbuzz icu +app-text/texlive extra graphics humanities png pstricks truetype xml diff --git a/va-kivitendo.cfg b/va-kivitendo.cfg new file mode 100644 index 0000000..188fee8 --- /dev/null +++ b/va-kivitendo.cfg @@ -0,0 +1,2 @@ +REPO_NAMES += unitas-kivitendo +REPO_URI_unitas-kivitendo = https://git.unitas-network.de/Gentoo/unitas-kivitendo.git diff --git a/world b/world new file mode 100644 index 0000000..69d407f --- /dev/null +++ b/world @@ -0,0 +1,5 @@ +app-crypt/certbot-apache +dev-db/postgresql +net-fs/autofs +net-fs/nfs-utils +www-apps/kivitendo-erp