From 9113e476668d0e33e7f4024ed01b33322f440bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Deckert?= Date: Fri, 2 Jun 2023 18:53:05 +0200 Subject: [PATCH] first release --- LICENSE | 2 +- Makefile | 49 ++++++++++++++++++++++ appliance/02firstboot.start | 81 ++++++++++++++++++++++++++++++++++++ appliance/MySQL-Backup.sh | 32 ++++++++++++++ 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 | 1 + mariadb/my.cnf.root | 11 +++++ package.accept_keywords | 2 + package.use | 8 ++++ php/php.ini-opcache.diff | 44 ++++++++++++++++++++ world | 15 +++++++ 15 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100755 appliance/02firstboot.start create mode 100755 appliance/MySQL-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 mariadb/my.cnf.root create mode 100644 package.accept_keywords create mode 100644 package.use create mode 100644 php/php.ini-opcache.diff create mode 100644 world diff --git a/LICENSE b/LICENSE index 2071b23..0d13c41 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) +Copyright (c) 2023 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..91c706e --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +02firstboot = $(CHROOT)/usr/local/bin/02firstboot.start +cert-renew.sh = $(CHROOT)/etc/ssl/cert-renew.sh +PHPCONFIG = $(CHROOT)/var/tmp/phpconfig + +systemd-units: appliance/MySQL-Backup.sh appliance/backup.service appliance/backup.timer appliance/cert-renew.service appliance/cert-renew.timer + cp appliance/MySQL-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)/etc/local.d + cp $< $@ + touch $(CHROOT)/02firstboot + +$(cert-renew.sh): appliance/cert-renew.sh + mkdir -p $(CHROOT)/etc/ssl + cp $< $@ + +$(PHPCONFIG): + # Apache-/PHP-Konfiguration + patch $(CHROOT)/etc/php/apache2-*/php.ini < php/php.ini-opcache.diff + find $(CHROOT)/etc/php/apache2-*/ -iname php.ini -print | xargs \sed -i \ + -e 's:.*date.timezone =.*:date.timezone = Europe/Berlin:' \ + -e 's:.*max_execution_time =.*:max_execution_time = 3600:' \ + -e 's:.*max_input_time =.*:max_input_time = 3600:' \ + -e 's:.*memory_limit =.*:memory_limit = 512M:' \ + -e 's:.*post_max_size =.*:post_max_size = 8G:' \ + -e 's:.*upload_max_filesize =*.:upload_max_filesize = 8G:' \ + -e 's:.*always_populate_raw_post_data =.*:always_populate_raw_post_data = -1:' + touch $(PHPCONFIG) + +$(CHROOT)/var/lib/mysql: mariadb/my.cnf.root + # MariaDB-Konfiguration ($$, weil make ein $ entfernt) + sed -i "s/^character-set-server.*$$/character-set-server = utf8mb4/" $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + sed -iE 's/^\(log-bin\)/#\1/' $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo "collation-server = utf8mb4_general_ci" >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo "transaction_isolation = READ-COMMITTED" >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo "binlog_format = ROW" >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo "expire_logs_days = 3" >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo "innodb_file_per_table = 1" >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + echo "innodb_large_prefix = on" >> $(CHROOT)/etc/mysql/mariadb.d/50-distro-server.cnf + cp mariadb/my.cnf.root $(CHROOT)/root/.my.cnf + chmod 0600 $(CHROOT)/root/.my.cnf + rm -rf $(CHROOT)/var/lib/mysql/* + RUN bash -c 'yes gentoo | emerge --config dev-db/mariadb' + +preinstall: + +postinstall: systemd-units $(PHPCONFIG) $(02firstboot) $(cert-renew.sh) $(CHROOT)/var/lib/mysql diff --git a/appliance/02firstboot.start b/appliance/02firstboot.start new file mode 100755 index 0000000..77c462f --- /dev/null +++ b/appliance/02firstboot.start @@ -0,0 +1,81 @@ +#!/bin/bash + +# variables +LABEL="DATA" +TLD="example.com" +HOST="lamp" +ORGNAME="lamp example" + +# start +set -e + +[ -e /01firstboot ] && exit 0 +[ -e /02firstboot ] || exit 0 + +# Database +systemctl stop mariadb +if [ ! -d "/$LABEL/var/lib/mysql/mysql" ]; then + echo 'Initialize MariaDB...' + mkdir -p "/$LABEL/var/lib" + rm -rf "/$LABEL/var/lib/mysql" + if [ ! -L /var/lib/mysql ]; then + rm -rf "/$LABEL/var/lib/mysql.orig" + cp -a "/var/lib/mysql" "/$LABEL/var/lib/mysql.orig" + mv "/var/lib/mysql" "/$LABEL/var/lib/mysql" + ln -s "/$LABEL/var/lib/mysql" "/var/lib/mysql" + elif [ -d "/$LABEL/var/lib/mysql.orig" ]; then + cp -a "/$LABEL/var/lib/mysql.orig" "/$LABEL/var/lib/mysql" + rm -rf "/var/lib/mysql" + ln -s "/$LABEL/var/lib/mysql" "/var/lib/mysql" + else + echo '### ERROR initialize database !!! ###' + exit 1 + fi +else + echo 'Use existing MariaDB...' + if [ ! -L /var/lib/mysql ]; then + rm -rf "/$LABEL/var/lib/mysql.orig" + mv "/var/lib/mysql" "/$LABEL/var/lib/mysql.orig" + else + rm -f "/var/lib/mysql" + fi + ln -s "/$LABEL/var/lib/mysql" "/var/lib/mysql" +fi + +if [ -x "/$LABEL/etc/ssl/cert-renew.sh" ]; then + # angepaßtes Zertifikat vorhanden (kein example) + if [ ! -L /etc/ssl/cert-renew.sh ]; then + rm -f "/$LABEL/etc/ssl/cert-renew.sh.orig" + mv "/etc/ssl/cert-renew.sh" "/$LABEL/etc/ssl/cert-renew.sh.orig" + else + rm -f "/etc/ssl/cert-renew.sh" + fi + ln -s "/$LABEL/etc/ssl/cert-renew.sh" "/etc/ssl/cert-renew.sh" +else + echo 'Create example certificate...' + 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 + +echo +echo "Success!" +echo "Do not forget to upgrade the MySQL database:" +echo " # mysql_upgrade" +echo + +rm /02firstboot diff --git a/appliance/MySQL-Backup.sh b/appliance/MySQL-Backup.sh new file mode 100755 index 0000000..19ccfc9 --- /dev/null +++ b/appliance/MySQL-Backup.sh @@ -0,0 +1,32 @@ +#!/bin/bash +PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" + +DIR="/DATA/Backup/MySQL" + +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 `mysqlshow --defaults-file=/root/.my.cnf | awk '{print $2}' | grep -v Databases`; do + if [ "$i" != "information_schema" ] && [ "$i" != "performance_schema" ]; 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}.sgl" + mysqldump --defaults-file=/root/.my.cnf --single-transaction --events --opt -QF -r${DIR}/${i}.sql $i + 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 + mysqldump --defaults-file=/root/.my.cnf --single-transaction --opt -QF -r${DIR}/${1}.sql $1 + 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..13ca921 --- /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/MySQL-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..ccedc40 --- /dev/null +++ b/appliance/cert-renew.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +HOST="lamp" +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..1650675 --- /dev/null +++ b/make.conf @@ -0,0 +1 @@ +PHP_TARGETS="php8-1" diff --git a/mariadb/my.cnf.root b/mariadb/my.cnf.root new file mode 100644 index 0000000..b5ac578 --- /dev/null +++ b/mariadb/my.cnf.root @@ -0,0 +1,11 @@ +[mysqladmin] +user = root +password = gentoo + +[mysql] +user = root +password = gentoo + +[client] +user = root +password = gentoo diff --git a/package.accept_keywords b/package.accept_keywords new file mode 100644 index 0000000..8e34d53 --- /dev/null +++ b/package.accept_keywords @@ -0,0 +1,2 @@ +# GeoIP +dev-php/maxmind-db-reader diff --git a/package.use b/package.use new file mode 100644 index 0000000..d3e4bc6 --- /dev/null +++ b/package.use @@ -0,0 +1,8 @@ +# GeoIP +dev-php/maxmind-db-reader extension + +# LAMP +app-eselect/eselect-php apache2 fpm +dev-lang/php apache2 bcmath curl exif gd gmp imap intl ldap ldap-sasl mysql mysqli pdo sockets sodium sqlite sysvipc truetype unicode xmlreader xmlrpc xmlwriter zip +media-gfx/imagemagick -openmp +www-servers/apache apache2_modules_proxy apache2_modules_proxy_ajp apache2_modules_proxy_connect apache2_modules_proxy_http apache2_modules_proxy_wstunnel diff --git a/php/php.ini-opcache.diff b/php/php.ini-opcache.diff new file mode 100644 index 0000000..fdca369 --- /dev/null +++ b/php/php.ini-opcache.diff @@ -0,0 +1,44 @@ +--- php.ini.orig 2020-06-10 17:18:21.946478636 +0200 ++++ php.ini 2020-06-10 17:49:47.009780070 +0200 +@@ -1766,20 +1766,20 @@ + + [opcache] + ; Determines if Zend OPCache is enabled +-;opcache.enable=1 ++opcache.enable=1 + + ; Determines if Zend OPCache is enabled for the CLI version of PHP + ;opcache.enable_cli=0 + + ; The OPcache shared memory storage size. +-;opcache.memory_consumption=128 ++opcache.memory_consumption=128 + + ; The amount of memory for interned strings in Mbytes. +-;opcache.interned_strings_buffer=8 ++opcache.interned_strings_buffer=12 + + ; The maximum number of keys (scripts) in the OPcache hash table. + ; Only numbers between 200 and 1000000 are allowed. +-;opcache.max_accelerated_files=10000 ++opcache.max_accelerated_files=10000 + + ; The maximum percentage of "wasted" memory until a restart is scheduled. + ;opcache.max_wasted_percentage=5 +@@ -1797,14 +1797,14 @@ + ; How often (in seconds) to check file timestamps for changes to the shared + ; memory storage allocation. ("1" means validate once per second, but only + ; once per request. "0" means always validate) +-;opcache.revalidate_freq=2 ++opcache.revalidate_freq=1 + + ; Enables or disables file search in include_path optimization + ;opcache.revalidate_path=0 + + ; If disabled, all PHPDoc comments are dropped from the code to reduce the + ; size of the optimized code. +-;opcache.save_comments=1 ++opcache.save_comments=1 + + ; Allow file existence override (file_exists, etc.) performance feature. + ;opcache.enable_file_override=0 diff --git a/world b/world new file mode 100644 index 0000000..b1e9a71 --- /dev/null +++ b/world @@ -0,0 +1,15 @@ +app-arch/unzip +app-crypt/certbot-apache +dev-db/mariadb +dev-db/phpmyadmin +dev-db/redis +dev-libs/libmaxminddb +dev-php/composer +dev-php/maxmind-db-reader +dev-php/pecl-apcu +dev-php/pecl-imagick +dev-python/passlib +dev-python/redis-py +net-misc/geoipupdate +www-apache/mod_wsgi +www-servers/apache