Überarbeitung der Apache-Konfiguration für Ubuntu 20.04
Meine bisherige Konfiguration für den Webserver stammt noch ursprünglich aus dem Jahr 2006. Ich habe sie dann mit jedem neuen Server immer nur auf die dann aktuellere Linux-Version angepasst. Dabei entstand zwar immer ein funktionsfähiges System, aber viele Dinge sind nicht mehr einfach nachvollziehbar.
Vorbemerkung
Momentan habe ich meinen alten Hetzner-Server nicht im produktiven Einsatz, habe ihn auf Ubuntu 20.04 aktualisiert und bin dabei die einzelnen Komponenten systematisch zu konfigurieren. Ich werde dabei aber nicht alle Altlasten wirklich los werden, immerhin müssen die reichlich vorhandenen Systeme aktualisierbar bleiben ohne große Verschiebe-Prozesse.
Für die Aktualisierung des Mailservers habe ich einen eigenen Text erstellt Überarbeitung der Mail-Konfiguration für Ubuntu 20.04.
Diese Seite beschreibt die Einrichtung und Konfiguration von virtuellen Servern und beinhaltet:
- MySQL
- Apache
- letsencrypt
Datenbank-MySQL
Zur Installation von Server und Client dient der folgende Aufruf:
apt install mysql-client mysql-server mysql-common
Ich habe dann die Konfigurationsdatei /etc/mysql/mysql.conf.d/mysqld.cnf ergänzt
#ergänzt von U.D. innodb_flush_log_at_trx_commit = 2
und die Datenbank neu gestartet. Den Datenbankzugriff sollte man nicht über das Netz erlauben, also auch in der Firewall den entsprechenden Port nicht öffnen. Die Datenbank wird ja in der Regel nur über lokale Anwendungen genutzt und über PHPMyAdmin administriert.
MySQL-Passwort
In aktuellen Datenbank-Versionen hat der Benutzer root keinen Zugriff mittels Passwort und kann daher z.B. auch nicht per phpmyadmin arbeiten. Der folgende MySQL-Befehl zeigt die Einstellung
mysql> SELECT user,authentication_string,plugin,host FROM mysql.user;
+---------------------+-------------------------------------------+-----------------------+-----------+
| user | authentication_string | plugin | host |
+---------------------+-------------------------------------------+-----------------------+-----------+
| root | | auth_socket | localhost |
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
...
Ändern lässt sich diese Einstellung mittels:
use mysql;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
flush privileges;
Dann ergibt sich:
mysql> select user,authentication_string,plugin,host FROM mysql.user;
+---------------------+-------------------------------------------+-----------------------+-----------+
| user | authentication_string | plugin | host |
+---------------------+-------------------------------------------+-----------------------+-----------+
| root | *A9172BC315E0BF4D14D201C4CD16374ED187B2B3 | mysql_native_password | localhost |
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
Damit ist das Passwort gesetzt. Will man es später einmal ändern, so muss man berücksichtigen, dass sich das Passwort für MySQL nicht mehr mit den altbekannten Kommandos setzen lässt, weil das Passwort nicht mehr im Feld password, sondern im Feld authentication_string zu finden ist:
use mysql;
UPDATE user SET authentication_string= password('password') WHERE User = 'root';
flush privileges;
und
https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-20-04-de
Nachdem das Passwort gesetzt ist, kann sich der Benutzer root auch per phpmyadmin anmelden.
MySQL im Zusammenspiel mit phpmyadmin
Eine etwas einfachere Lösung das Passwort-Problem zu lösen gibt es, wenn mit phpmyadmin gearbeitet wird. In der Datei /etc/mysql/debian.cnf sind die Zugangsdaten für einen bei der Installation angelegten User zu finden:
# Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host = localhost
user = debian-sys-maint
password = BmhrjzFR0D0521NX
socket = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host = localhost
user = debian-sys-maint
password = BmhrjzFR01D021NX
socket = /var/run/mysqld/mysqld.sock
Mit dem hier befindlichen Benutzer und dem hier befindlichen zufällig generiertem Passwort kann man per phpmyadmin auf die Datenbank zugreifen. Hier kann man dann bequem einen Benutzer mit allen gewünschten Rechten anlegen.
Man muss also nicht dem Benutzer root den Zugriff ermöglichen. Aus Sicherheitsgründen ist es sowieso sinnvoller einen individuellen Benutzer anzulegen, da oft genug versucht wird sich über phpmyadmin einzuloggen. Ich habe mich auch angewöhnt in der Datei /etc/apache2/conf-available/phpmyadmin.conf die Alias-Zeile auszukommentieren:
#Alias /phpmyadmin /usr/share/phpmyadmin
So kann ich erreichen, dass das Tool nicht allen virtuellen Systemen zur Verfügung steht, sondern die Berechtigung aktiv konfiguriert werden muss.
letsencrypt
Für die verschlüsselte Übertragung von Webseiten werden Zertifikate von letsencrypt benötigt. Das notwendige Paket ist bei Ubuntu dabei:
apt install certbot
Für jede meiner virtuellen Domains habe ich dann eine letsencrypt.ini erstellt, mit folgendem Inhalt:
# Aufruf mit: /usr/bin/certbot certonly --config /var/www/vhosts/meine-maildomain.de/letsencrypt.ini
# Wir nutzen 4096 bit RSA key statt 2048
rsa-key-size = 4096
# allgemeine Angaben
email = uwe@meine-maildomain.de
authenticator = webroot
# Domains fuer die wir Zertifikate beantragen, die erste in
# der liste legt den Hauptnamen fest. Alle Domains müssen beim
# Aufruf erreichbar sein
domains = meine-maildomain.de, www.meine-maildomain.de
# Dies ist das Verzeichnis zur Domain, wo letsencrypt seinen Hash in
# /.well-known/acme-challenge schreiben will. Der Pfad muss auf / enden
# es muss in der vserver.conf stehen: Alias /.well-known /var/www/htdocs/.well-known
webroot-path = /var/www/htdocs/
Die Reihenfolge der Domains spielt insofern eine Rolle, als die erste Domain als Bezeichner für die Verzeichnisstruktur innerhalb von /etc/letsencrypt benutzt wird. Es bietet sich also an mit einer kürzeren Angabe zu beginnen.
Zum Erzeugen der Zertifikate dient dann der Aufruf:
/usr/bin/certbot certonly --config /var/www/vhosts/meine-maildomain.de/letsencrypt.ini
Die täglichen Aktualisierungsversuche für die Zertifikate übernimmt ein Con-Job, der automatisch angelegt wird (/etc/cron.d/certbot). Leider bekommt man dann keine Mails mehr, sondern muss in die Logdateien schauen, ob alles geklappt hat. Falls mir das auf Dauer nicht gefällt, so mache ich das wieder über den eigenen Cron-Job.
Was ich jetzt erst entdeckt habe ist das Prinzip der Hooks. Man kann bei letsencript an mehreren Stellen Scripten hinterlegen, die bei Aktualisierung eines Zertifikates aufgerufen werden. Damit kann man z.B. den Webserver oder den Mailserver neu starten.
Zertifikate erweitern
Das Erweitern von letsencrypt Zertifikaten ist relativ einfach. Ich ergänze eine die Domains-Zeile in der Konfigurationsdatei und rufe den Erzeugungsprozess neu auf. Letsencrypt erkennt die Situation und fragt, ob ich das Zertifikat erweitern oder erneuern möchte. Wählt man hier erweitern, so wird das passende Zertifikat neu erzeugt.
Zertifikat reduzieren
Manchmal soll eine Domain aus einem Zertifikat entfernt werden, weil man eventuell sie an anderer Stelle benötigt, oder sie nicht mehr verfügbar ist. Ich habe bisher keinen direkten Weg gefunden, wenn man vorgeht wie beim Erweitern und einfach die Liste verkürzt, dann legt Letsenctypt ein zusätzliches Zertifikat an, mit der Ergänzung -0001 am Namen. Man muss also das Zertifikat löschen und neu erstellen.
certbot delete --cert-name MeineDomain
Es geht auch interaktiv mit
certbot delete
es erscheint eine Liste der vorhandenen Zertifikate und man gibt die Nummer des Zertifikates an, das man löschen möchte.
Anschließend legt man das Zertifikat mit der verkleinerten Liste neu an.
Man muss aber damit rechnen, dass man von Letsencrypt Hinweis-Mails bekommt, wenn sich das eigentlich gelöschte Zertifikat dem Ablauf-Zeitpunkt nähert. So weit geht die Lösung nämlich nicht.
Dienste neu starten
In der Regel müssen z.B. die Mail-Dienste neue gestartet werden, wenn das benutzte Zertifikat erneuert wurde. Sonst wird weiterhin das alte Zertifikat benutzt. Letsencrypt kennt Hooks, über die Aktionen ausgelöst werden.
Hier die Datei /etc/letsencrypt/renewal-hooks/deploy/postfix-dovecot-reload.sh
#!/bin/sh
# Dieses script liegt ausführbar in: /etc/letsencrypt/renewal-hooks/deploy
for domain in $RENEWED_DOMAINS
do
if [ "$domain" = "mail.<meine Domain>.de" ]
then
systemctl reload postfix
systemctl reload dovecot
fi
done
Mehr Änderungen
Seit dem 1.12.2020 gibt der Cerbot auf den Servern mit Ubuntu 18.04 die folgende Meldung aus:
Your system is not supported by certbot-auto anymore. Certbot will no longer receive updates. Please visit https://certbot.eff.org/ to check for other alternatives.
Aktuell funktioniert die Aktualisierung der Zertifikate noch, aber der Client wird nicht mehr aktualisiert.
Auf https://certbot.eff.org finde ich für mein System dann die Anleitung ein Snap mit dem Certbot zu installieren. Da der snapd auf den Systemen bereits vorhanden ist geht die Installation relativ einfach in folgenden Schritten (als root):
snap install core snap refresh core snap install --classic certbot
Dann noch einen Link setzen:
ln -s /snap/bin/certbot /usr/bin/certbot
Danach kann man dann ausprobieren, ob der Certbot mit den vorhandenen Zertifikaten funktioniert:
certbot renew --dry-run
Denkbar ist dann ein Cronjob der Art:
/usr/bin/certbot renew
Meine Crontab habe ich dann angepasst, obwohl mir nicht ganz klar ist, ob die Aktualisierung nicht schon automatisch geschieht.
Mit
systemctl list-timers
kann man sich die Timer anschauen, die nicht über Cron laufen, sondern über den Systemd-Timer. Es gibt dort einen snap.certbot.renew.timer, der im Verzeichnis /etc/systemd/system/ zu finden ist, aber wohl nur für die Aktualisierung des Snaps zuständig ist.
Sonstige Timer sind übrigens meist im Verzeichnis /lib/systemd/system/ zu finden.
Ein neues Zertifikat erzeugt man dann mit
/usr/bin/certbot certonly --config /var/www/vhosts/<domain>/letsencrypt.ini
Apache
Der Apache Webserver ist ein enorm umfangreiches Stück Software. Ich hoffe, dass meine Konfiguration einigermaßen sinnvoll ist.
Installation
Die folgenden grundlegenden Pakete habe ich installiert
apt install apache2 apache2-bin apache2-data apache2-doc apache2-utils
Dann ein paar Pakete für PHP
apt install libapache2-mod-php php php-auth-sasl php-bz2 php-cli php-db php-gd php-geoip php-imap php-log php-mail php-curl php-imagick php-intl
apt install php-mbstring php-mdb2 php-mysql php-net-smtp php-phpseclib php-soap php-tcpdf php7.4-zip phpmyadmin
apt install php-apcu php7.4-opcache
Da sind eventuell noch Doppelungen drin, sowohl das Paket, als auch das Metapaket. Es ist aber das, was mir
dpkg --get-selections | grep php
lieferte.
Nicht vorhanden waren die Pakete php-gettext und php-recode, die Ursache muss ich noch recherchieren.
Nun noch ein paar Perl-Pakete:
apt install libapache2-mod-perl2 libapache2-reload-perl libapparmor-perl libarchive-zip-perl libauthen-sasl-perl libbsd-resource-perl libcairo-perl
apt install libcgi-fast-perl libfile-basedir-perl libfile-desktopentry-perl libfile-mimeinfo-perl libfont-afm-perl libgd-graph-perl libglib-perl libgtk2-perl
apt install libhtml-form-perl libhtml-format-perl libhtml-template-perl libhttp-daemon-perl libimage-magick-perl libmailtools-perl libnet-dbus-perl libtie-ixhash-perl
apt install libx11-protocol-perl libxml-xpathengine-perl libdbi-perl libdbd-mysql libclass-dbi-mysql-perl
Nach erfolgter Konfiguration (s.u.) darf man nicht vergessen die notwendigen Ports in der Firewall frei zu geben:
ufw allow "Apache Full"
Server-Module
Vorsichtshalber noch einmal ein paar Apache-Module aktivieren:
a2enmod perl a2enmod cgi a2enmod expires a2enmod headers a2enmod rewrite a2enmod ssl a2dismod status service apache2 restart
für Typo3
Da ich viel mit Typo3 arbeite habe ich etwas an den PHP-Einstellungen gedreht in der /etc/php/7.4/apache2/php.ini:
post_max_size=12M upload_max_filesize=12M max_execution_time=240 max_input_vars = 1500
Typo3 benötigt unbedingt imagemagick (oder alternativ graphicsmagick)
apt install imagemagick imagemagick-doc
apt install graphicsmagick ghostscript webalizer
Reihenfolge-Probleme bei der Apache-Konfiguration
Bei der Apache-Konfiguration muss man sehr auf die Reihenfolge der einzelnen Einstellungen achten. Dabei spielt der Aufbau der Hauptkonfigurationsdatei /etc/apache2/apache2.conf eine wichtige Rolle. Hier werden der Reihe nach alle Dateien aus folgenden Unterverzeichnissen eingebunden:
- mods-enabled
- conf-enabled
- sites-enabled
Die Dateien aus den einzelnen Verzeichnissen werden dann jeweils in alphabetischer Reihenfolge eingebunden, intern entsteht dabei eine einzige große Konfigurationsdatei. Innerhalb dieser virtuellen Datei spielen die Reihenfolgen eine Rolle.
Bei der Reihenfolge von Alias (auch SriptAlias) Anweisungen und Redirects, die in unterschiedlichen Kontexten auftreten, werden die Direktiven nach den üblichen Zusammenführungsregeln verarbeitet. Wenn jedoch mehrere Aliase oder Redirects im gleichen Kontext (z.B. im gleichen Abschnitt) auftreten, werden sie in einer bestimmten Reihenfolge verarbeitet.
Zunächst werden alle Umleitungen verarbeitet, bevor Aliase verarbeitet werden, und daher werden auf eine Anforderung, die mit einer Umleitung oder einer RedirectMatch übereinstimmt, niemals Aliase angewendet. Zweitens werden die Aliase und Redirects in der Reihenfolge verarbeitet, in der sie in den Konfigurationsdateien erscheinen, wobei die erste Übereinstimmung Vorrang hat.
Wenn also in der /etc/apache2/conf-available/postfixadmin.conf steht
Alias /postfixadmin /usr/share/postfixadmin/public
kann ich dies nicht im allgemeinen Teil der /etc/apache2/sites-available/000-default.conf überschreiben, weil die erst später inkludiert wird. Nur innerhalb einer Directory oder VirtualHost Struktur kann ich Veränderungen vornehmen, weil dies spezieller ist.
Aus dem gleichen Grund muss man, wenn zwei oder mehr dieser Direktiven auf denselben Unterpfad angewendet werden, den spezifischsten Pfad zuerst auflisten, damit alle Direktiven eine Wirkung haben. Zum Beispiel wird die folgende Konfiguration wie erwartet funktionieren:
ScriptAlias /cgi-bin/mailman/ /usr/lib/cgi-bin/mailman/
ScriptAlias /cgi-bin/ "/var/www/vhosts/default/cgi-bin/"
Aber wenn die beiden oben genannten Richtlinien in umgekehrter Reihenfolge angewendet würden, würde der /cgi-bin vor dem /cgi-bin/mailman-Alias stehen, so dass die letztere Richtlinie ignoriert würde.
Es ist sinnvoll beim Start von Apache auf die Meldungen im Syslog zu achten. Habe ich z.B. den Alias /postfixadmin bei den conf-enabled nicht auskommentiert, so erscheint bei meiner Konfiguration (s.u.) die Meldung
The Alias directive in /etc/apache2/sites-enabled/000-default.conf at line 19 will probably never match because it overlaps an earlier Alias.
/etc/apache2/sites-available/000-default.conf
Diese Datei besteht bei mir aus drei Teilen:
- Zuerst die allgemeinen Einstellungen, die dann für alle virtuellen Systeme gelten, sofern sie nicht überschrieben werden.
- Dann der virtuelle Default-Server für Port 80. Er würde aufgerufen, wenn jemand über die IP-Adresse, den Namen beim Provider (static.w.x.y.z.clients.your-server.de) oder eine nicht vorgesehene Domain kommt.
- Der entsprechende virtuelle Default-Server für Port 443.
Die virtuellen Standard-Server sind auch im Zusammenhang mit letsencrypt-Zertifikaten für den Mailserver ganz praktisch. Ich muss nicht für mail.meine-maildomain.de eine Webseite konfigurieren, wenn ich ein Zertifikat erstellen oder erweitern möchte. Letsencrypt landet im Zweifelsfall hier und kann den Zugriff verifizieren. Der Standard-Server auf Port 443 erleichtert dann die Kontrolle der erstellten Zertifikate für den Mailserver, wenn das hier angegebene Zertifikat auch im Mailsystem genutzt wird.
ServerName default
ServerAdmin Uwe@meine-maildomain.de
ServerTokens Major
ServerSignature off
TraceEnable off
ProxyRequests off
UseCanonicalName Off
DocumentRoot /var/www/vhosts/default/httpdocs
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
CustomLog /var/log/apache2/vhosts_access.log vhost_combined
Alias /webmail /var/www/htdocs/dummy
Alias /phpmyadmin /var/www/htdocs/dummy
Alias /postfixadmin /var/www/htdocs/dummy
Alias /webstat /var/www/htdocs/webalizer
Alias /roundcube /var/lib/roundcube
<IfDefine MAILMAN>
ScriptAlias /mailman/ /var/www/htdocs/dummy
Alias /mailmanicons/ /var/www/htdocs/dummy
Alias /pipermail/ /var/www/htdocs/dummy
</IfDefine>
<IfModule mod_userdir.c>
UserDir disabled
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
ExpiresByType text/html "access plus 1 week"
ExpiresByType image/gif "access plus 1 week"
ExpiresByType image/jpeg "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/javascript "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
ExpiresByType text/xml "access plus 1 week"
</IfModule>
<IfModule mod_setenvif.c>
# SEO
BrowserMatchNoCase (mindUp|meanpathbot|seoscanners|AiHitBot|BLEXBot|DotBot|linkdexbot|MJ12bot|SEOkicks-Robot) ist_ein_bot
# Sammeln Backlinks & Links
BrowserMatchNoCase (exabot|Baidu|Haosou|Semrush|MegaIndex|AhrefsBot|BacklinkCrawler|dlcbot|spbot) ist_ein_bot
# Performance Testing
BrowserMatchNoCase (200PleaseBot|LoadTimeBot) ist_ein_bot
# BilderSuche
BrowserMatchNoCase (psbot|Yandex) ist_ein_bot
# Harvester & Marketing
BrowserMatchNoCase (MegaIndex|Applebot|XoviBot|CareerBot|GrapeshotCrawler|iCjobs|magpie-crawler|proximic) ist_ein_bot
# Nutzlos, Schlecht bzw. unbekannt
BrowserMatchNoCase (PetalBot|360Spider|AfD-Verbotsverfahren|Barkrowler|PeoplePal|ltx71|CalendarAgent|JobboerseBot|GarlikCrawler|Mail.RU_B
# Per IP
SetEnvIfNoCase Remote_Addr (62\.138\.0\.25) ist_ein_bot
# kyivstar.net
SetEnvIfNoCase Remote_Addr ^(5\.248|46\.118|37\.115|178\.137) ist_ein_bot
# Einträge von 2020
BrowserMatchNoCase (MaviBot|oBot|MetaJobBot|seocompany|coccocbot-image|SeznamBot) ist_ein_bot
</IfModule>
<IfModule mod_ssl.c>
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
SSLCompression off
SSLCipherSuite ALL:!aNULL:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP:+eNULL
</IfModule>
<Directory "/var/www/vhosts">
AllowOverride All
Options +SymLinksIfOwnerMatch -Indexes
Require all granted
<IfModule mod_php7.c>
php_value date.timezone "Europe/Berlin"
php_value open_basedir /var/www/:/tmp/
php_value include_path /var/www/:/tmp/
</IfModule>
</Directory>
<VirtualHost *:80>
Alias /.well-known /var/www/htdocs/.well-known
<Directory /var/www/vhosts/default/httpdocs>
AllowOverride All
Options None
Require all granted
</Directory>
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost _default_:443 >
SSLEngine on
# Wenn das erste Zertifikat mit Letsencryp erstellt ist, dann die Zertifikate austauschen
# SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
# SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateFile /etc/letsencrypt/live/<dummy>/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/<dummy>/privkey.pem
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /var/www/vhosts/default/httpdocs>
SSLRequireSSL
AllowOverride All
Options None
Require all granted
</Directory>
</VirtualHost>
</IfModule>
Die SSL-Einstellungen der Seite kann man unter https://www.cdn77.com/tls-test (Hinweis: deren Cache lässt sich anscheinend nicht löschen) und ganz ausführlich unter https://www.ssllabs.com/ssltest/ testen lassen. Es geht übrigens auch ohne externen Dienstleister mittels
nmap --script ssl-enum-ciphers -p 443 example.com
Ursprünglich hatte ich hier auch einen Alias für .well-known mir drin, das führt aber zu Problemen bei z.B. Nextcloud, hier wird mit Unterverzeichnissen von .well-known gearbeitet und dann treten Probleme mit der Reihenfolge auf.
Vserver-Konfiguration
Für jeden weiteren VServer erfolgt die Konfiguration in /etc/apache2/vhosts/sites-available/<dummy>.conf nach folgendem System, wobei <dummy> durch z.B. den Domainnamen ersetzt wird. Das zugehörige Verzeichnis wird dann mit diesem Namen unterhalb von /var/www/vhosts/ angelegt.
<VirtualHost *:80>
ServerName www.<dummy>:80
ServerAlias <dummy>
DocumentRoot /var/www/vhosts/<dummy>/httpdocs
CustomLog /var/log/apache2/<dummy>_access.log combined
ErrorLog /var/log/apache2/<dummy>_error.log
CustomLog /var/log/apache2/vhosts_access.log vhost_combined
ScriptAlias /cgi-bin/ /var/www/vhosts/<dummy>/cgi-bin/
Alias /webstat /var/www/vhosts/<dummy>/webstat
Alias /.well-known /var/www/htdocs/.well-known
# Nur bei Bedarf aktivieren
# Alias /phpmyadmin /usr/share/phpmyadmin
# Alias /postfixadmin /usr/share/postfixadmin/public
<Directory /var/www/vhosts/<dummy>/httpdocs>
<IfModule mod_setenvif.c>
<RequireAll>
Require all granted
Require not env ist_ein_bot
</RequireAll>
</IfModule>
<IfModule mod_php7.c>
php_admin_flag engine on
php_admin_value include_path "/var/www/vhosts/<dummy>/httpdocs:.:/tmp:./:/usr/share/php/PEAR/:/srv/www/typo3src:/usr/bin"
php_admin_value open_basedir "/var/www/vhosts/<dummy>/httpdocs:/tmp:.:/usr/share/php/PEAR/:/srv/www/typo3src:/usr/bin"
</IfModule>
Options -Includes +ExecCGI
</Directory>
<Directory "/var/www/vhosts/<dummy>/cgi-bin">
AllowOverride None
Options +ExecCGI -Includes
Require all granted
</Directory>
</VirtualHost>
# soll SSL aktiviert werden das _no entfernen
<IfModule mod_ssl_no.c>
<VirtualHost *:443>
ServerName www.<dummy>:443
ServerAlias <dummy>
DocumentRoot /var/www/vhosts/<dummy>/httpdocs
CustomLog /var/log/apache2/<dummy>_access.log combined
ErrorLog /var/log/apache2/<dummy>_error.log
CustomLog /var/log/apache2/vhosts_access.log vhost_combined
ScriptAlias /cgi-bin/ /var/www/vhosts/<dummy>/cgi-bin/
Alias /webstat /var/www/vhosts/<dummy>/webstat
Alias /.well-known /var/www/htdocs/.well-known
# Nur bei Bedarf aktivieren
# Alias /phpmyadmin /usr/share/phpmyadmin
# Alias /postfixadmin /usr/share/postfixadmin/public
SSLEngine on
<Directory /var/www/vhosts/<dummy>/httpdocs>
<IfModule mod_setenvif.c>
<RequireAll>
Require all granted
Require not env ist_ein_bot
</RequireAll>
</IfModule>
<IfModule mod_php7.c>
php_admin_flag engine on
php_admin_value include_path "/var/www/vhosts/<dummy>/httpdocs:.:/tmp:./:/usr/share/php/PEAR/:/srv/www/typo3src:/usr/bin"
php_admin_value open_basedir "/var/www/vhosts/<dummy>/httpdocs:/tmp:.:/usr/share/php/PEAR/:/srv/www/typo3src:/usr/bin"
</IfModule>
Options -Includes +ExecCGI
</Directory>
<Directory "/var/www/vhosts/<dummy>/cgi-bin">
AllowOverride None
Options +ExecCGI -Includes
Require all granted
</Directory>
SSLCertificateFile /etc/letsencrypt/live/<dummy>/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/<dummy>/privkey.pem
</VirtualHost>
</IfModule>
Verwaltungs-Vserver
Für die Nutzung von
- postfixadmin
- phpmyadmin
- rspamd
- eigenen CGI Scripten
habe ich mir einen speziellen virtuellen Server erstellt, der keine eigenen Ordner bekommt, sondern auf dem Default-Server aufsetzt. /etc/apache2/vhosts/sites-available/verwaltung.conf
<VirtualHost *:80>
ServerName verwaltung.<dummy>:80
DocumentRoot /var/www/vhosts/default/httpdocs
CustomLog /var/log/apache2/verwaltung_access.log combined
ErrorLog /var/log/apache2/verwaltung_error.log
CustomLog /var/log/apache2/vhosts_access.log vhost_combined
ScriptAlias /cgi-bin/ /var/www/vhosts/default/cgi-bin/
Alias /webstat /var/www/vhosts/default/webstat
Alias /phpmyadmin /usr/share/phpmyadmin
Alias /postfixadmin /usr/share/postfixadmin/public
Alias /.well-known /var/www/htdocs/.well-known
<Directory /var/www/vhosts/default/httpdocs>
<IfModule mod_setenvif.c>
<RequireAll>
Require all granted
Require not env ist_ein_bot
</RequireAll>
</IfModule>
Options -Includes +ExecCGI
</Directory>
<Directory "/var/www/vhosts/default/cgi-bin">
AllowOverride None
Options +ExecCGI -Includes
Require all granted
</Directory>
RewriteEngine On
ProxyRequests Off
<Location /rspamd>
Order allow,deny
Allow from all
</Location>
RewriteRule ^/rspamd$ /rspamd/ [R,L]
RewriteRule ^/rspamd/(.*) http://localhost:11334/$1 [P,L]
</VirtualHost>
# soll SSL aktiviert werden das _no entfernen
<IfModule mod_ssl_no.c>
<VirtualHost *:443>
ServerName verwaltung.<dummy>:443
DocumentRoot /var/www/vhosts/default/httpdocs
CustomLog /var/log/apache2/verwaltung_access.log combined
ErrorLog /var/log/apache2/verwaltung_error.log
ScriptAlias /cgi-bin/ /var/www/vhosts/default/cgi-bin/
Alias /webstat /var/www/vhosts/default/webstat
Alias /phpmyadmin /usr/share/phpmyadmin
Alias /postfixadmin /usr/share/postfixadmin/public
Alias /.well-known /var/www/htdocs/.well-known
SSLEngine on
<Directory /var/www/vhosts/default/httpdocs>
<IfModule mod_setenvif.c>
<RequireAll>
Require all granted
Require not env ist_ein_bot
</RequireAll>
</IfModule>
Options -Includes +ExecCGI
</Directory>
<Directory "/var/www/vhosts/default/cgi-bin">
AllowOverride None
Options +ExecCGI -Includes
Require all granted
</Directory>
SSLCertificateFile /etc/letsencrypt/live/verwaltung.<dummy>/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/verwaltung.<dummy>/privkey.pem
RewriteEngine On
ProxyRequests Off
<Location /rspamd>
Order allow,deny
Allow from all
</Location>
RewriteRule ^/rspamd$ /rspamd/ [R,L]
RewriteRule ^/rspamd/(.*) http://localhost:11334/$1 [P,L]
</VirtualHost>
</IfModule>
Logdateien
Da ich die Logdateien für meine virtuellen Server mit Webalizer auswerten möchte, brauche ich eine Erweiterung für Logrotate:
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
if invoke-rc.d apache2 status > /dev/null 2>&1; then \
invoke-rc.d apache2 reload > /dev/null 2>&1; \
fi;
endscript
prerotate
/root/webalizer.sh
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi; \
endscript
}
Entweder hängt man diesen Teil an /etc/logrotate.d/apache2 an oder man erstellt eine neue Datei /etc/logrotate.d/apache-vhosts .