LAMP-Server für InstaHub aufsetzen

24. April 2019 - Lesezeit: 14 Minuten

Dokumentation zum Aufsetzen eines LAMP-Servers auf Debian 9 mit dem Ziel InstaHub zu betreiben. Nicht unbedingt nachmachen, ich bin kein Profi.

Die Dokumentation dient hauptsächlich dazu, dass ich beim nächsten Mal nicht wieder einen Ferientag opfern muss, um einen LAMP Server aufzusetzen.

Genutzt wird ein Debian 9 mit der Minimal Ausführung. Das Image gibt es meist beim vHoster-Betreiber des Vertrauens zum Hosting mit dazu. Sonst entweder mit einem anderen Image sein Glück probieren oder hoffen, dass man ein virtuelles CD-Laufwerk hat (Download).

Genutzte Anleitungen (die nicht immer perfekt waren):

apt-get install sudo

Teilweise fehlen noch andere wichtige Befehle wie apt-get install unzip und apt-get install curl

Firewall installieren

apt install ufw
ufw allow OpenSSH
sudo ufw allow 9090
sudo ufw allow in "WWW Full"
ufw enable

Mit ufw app list kann man sich vordefinierte Filter auflisten lassen und mit ufw app info "SMTP" die damit verknüpften Ports ansehen. ufw deny SMTP sorgt dafür, dass Regeln wieder entfernt werden.

fail2ban installieren

apt install fail2ban
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Dann müssen wir noch auf unsere Firewall anpassen indem wir in der jail.local noch die Zeile auf banaction = ufw anpassen.

Und neustarten:

systemctl restart fail2ban.service

Cockpit installieren

apt-get install cockpit

Fehlt der Menüeintrag "Software Updates" kann dieser über apt-get install cockpit-packagekit nachgeladen werden.

DIe Seite ist dann über Port 9090 erreichbar. Login ist wie auf dem vServer selbst. Hierüber lassen sich etwa Sicherheitsupdates schnell installieren.

Apache installieren

sudo apt install apache2
a2enmod rewrite

Datenbank installieren

apt install mariadb-server
mysql_secure_installation
mariadb
MariaDB [(none)]> GRANT ALL ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> exit

Bei mysql_secure_installation kein Passwort für root vergeben und allen anderen Maßnahmen zustimmen. Und password ersetzen 😉.

PHP 7.3 installieren (Debian bringt aktuell nur 7.0 mit):

apt -y install lsb-release apt-transport-https ca-certificates
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
--2019-04-23 17:04:07--  https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php7.3.list
deb https://packages.sury.org/php/ stretch main
apt-get update
apt-get -y install php7.3
apt-get install php7.3-cli php7.3-fpm php7.3-json php7.3-pdo php7.3-mysql php7.3-zip php7.3-gd php7.3-mbstring php7.3-curl php7.3-xml php7.3-bcmath php7.3-json
apt-get install libapache2-mod-php7.3

Test ist mit php -v möglich. apt-get install libapache2-mod-php7.3 könnte unnötig sein, da schon davor unter der Haube ausgeführt.

phpMyAdmin installieren

apt install phpmyadmin php7.3-gettext
systemctl restart apache2
a2enmod ssl

Bis auf das installieren von phpmyadmin könnten alle Befehle hier unnötig gewesen sein.

Aktuell gibt es einen Fehler im Debian-Paket. Sollte in der Oberfläche ein recht langer Fehler erscheinen, dann diese Schritte durchführen.

In phpMyAdmin kannst du dich nur mit dem admin und nicht mit dem root Benutzer anmelden. Soll eigentlich die Sicherheit erhöhen, aber das haben wir gerade überbrückt. 😊

Jetzt lässt er sich an jedem Virtual Host mit /phpmyadmin/ aufrufen. Das wollen wir aber nicht, daher in /etc/apache2/conf-available/phpmyadmin.conf die Zeile

Alias /phpmyadmin /usr/share/phpmyadmin

mit # auskommentieren. Nun in die gewünschten Virtual Hosts (etwa default) gehen und dort die Zeile in den Virtual Host einfügen. Und neustarten nicht vergessen.

Ausführungszeit auf Datenbank beschränken

Nutzen wir gleich unseren admin-Benutzer und schränken die Ausführungszeit für alle ein. Das ist sehr wichtig, da CROSS JOINs sonst unsere Datenbank lahm legen können. PHP bricht zwar nach 30 Sekunden ab, aber die Datenbank läuft fröhlich weiter.

Folgende Befehle schränken ganz gut ein:

SET GLOBAL max_join_size=10000;
SET GLOBAL sql_select_limit=10000;
SET GLOBAL max_statement_time=20;

Let's Encrypt installieren

Fürst du die Befehle nach dem Login aus bist du im Verzeichnie /root

apt install curl
curl https://get.acme.sh | sh

Jetzt unbedingt das Terminal neu starten. Eigentlich sollte es eine Verknüpfung geben aber ich bin direkt mit cd .acme.sh/ in das Verzeichnis gegangen.

acme.sh --issue -d v22019048247987868.megasrv.de -w /var/www/html

Alternativ kann man sich auch ein Wildcard-Zertifikat ausstellen lassen. Das geht nur mit unterstützten DNS-Diensten automatisch.

acme.sh  --issue -d v22019048247987868.megasrv.de  -d  *.v22019048247987868.megasrv.de  --dns --force --yes-I-know-dns-manual-mode-enough-go-ahead-please 

Als nächstes die angezeigten DNS-Einstellungen vornehmen. Dann gemütlich warten, bis sich die neuen DNS-Einträge rumgesprochen haben und dann

acme.sh  --renew -d v22019048247987868.megasrv.de  -d  *.v22019048247987868.megasrv.de  --dns --force --yes-I-know-dns-manual-mode-enough-go-ahead-please 

Jetzt müssen wir das Zertifikat in /etc/apache2/sites-available/000-default.conf eintragen. Dabei sind die Zeilen schon im Text, aber mit # auskommentiert:

SSLCertificateFile /root/.acme.sh/v22019048247987868.megasrv.de/v22019048247987868.megasrv.de.cer
SSLCertificateKeyFile /root/.acme.sh/v22019048247987868.megasrv.de/v22019048247987868.megasrv.de.key

Die Dateien nicht zu kopieren, sondern aus dem Arbeitsverzeichnis zu verwenden wird vom Entwickler explizit nicht gutgeheißen, da sich die Ordnerstruktur ändern könnte.

Mit crontab -l kannst du prüfen, ob der Cronjob zum automatischen erneuern des Zertifikats gesetzt wurde. Das Zertifikat ist 90 Tage gültig und wird aller 60 Tage ersetzt.

Alternativ kann man auch die bestehenden Zeilen auskommentieren und ein selbst signiertes Zertifikat verwenden (besser als keins). Dafür muss noch das Zertifikat erstellt werden:

make-ssl-cert generate-default-snakeoil --force-overwrite

Virtual Hosts für die Webseiten anlegen

Im Ordner /etc/apache2/sites-available:

<VirtualHost *:80>
    ServerName instahub.yak9.de
    ServerAlias *.instahub.yak9.de
    ServerAdmin webmaster@instahub.org
    DocumentRoot /var/www/instahub.yak9.de/public

    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(?!/\.well-known/acme-challenge/)(.*)$ [NC]
    RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]

    ServerAdmin webmaster@localhost

    ErrorLog ${APACHE_LOG_DIR}/instahub.yak9.de.error.log
    CustomLog ${APACHE_LOG_DIR}/instahub.yak9.de.access.log combined
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Der obige Virtual Host lässt eigentlich nur Let's Encrypt passieren und verweist alle anderen auf die SSL-Verbindung.

<IfModule mod_ssl.c>
    <VirtualHost _default_:443>
        ServerName instahub.yak9.de
        ServerAlias *.instahub.yak9.de
        ServerAdmin webmaster@instahub.org
        DocumentRoot /var/www/instahub.yak9.de/public

        <Directory />
            Options FollowSymLinks
            AllowOverride None
        </Directory>
        <Directory /var/www/instahub.yak9.de/public>
                AllowOverride All
        </Directory>

        LogLevel warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SSLEngine on

        SSLCertificateFile /root/.acme.sh/instahub.yak9.de/instahub.yak9.de.cer
        SSLCertificateKeyFile /root/.acme.sh/instahub.yak9.de/instahub.yak9.de.key

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>
    </VirtualHost>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Und aktivieren:

a2ensite instahub.yak9.de.conf
a2ensite instahub.yak9.de-ssl.conf
systemctl reload apache2

InstaHub installieren

Hier laden wir den Branch beta herunter.

apt install git
cd /var/www
git clone -b beta git://github.com/wi-wissen/instahub.git instahub.yak9.de

SSL-Wildcard-Zertifikat erstellen:

cd /root
acme.sh --issue -d instahub.yak9.de -d *.instahub.yak9.de --dns --force --yes-I-know-dns-manual-mode-enough-go-ahead-please

Jetzt müssen die entsprechenden TXT-Einträge im DNS der Domain vorgenommen werden. Jenachdem wie schnell euer DNS-Server verbunden ist, muss man noch warten.

 acme.sh --renew -d instahub.yak9.de -d *.instahub.yak9.de --dns --force --yes-I-know-dns-manual-mode-enough-go-ahead-please

Und nicht vergessen, wie oben geschrieben die SSL-Zertifikate im Virtual Host verlinken und den Apache neu starten mit systemctl restart apache2.

Jetzt (oder während man auf den DNS-Server wartet), InstaHub einfach nach der Anleitung installieren: https://github.com/wi-wissen/instahub

Wenn man als root unterwegs ist muss man mit den Rechten besonders aufpassen, die müssen insbesondere bei storage rekursiv gesetzt werden.

kein Mailserver

Mailserver betreibe ich sehr ungern selber, da ich hier nicht ausversehen ein Spam-Bot werden möchte. Daher schalte ich meine Domain entweder für die Mails auf ein Shared-Hosting auf oder nutze folgende Dienste:

mailgun.com - Mit hinterlegter Kreditkarte und Einstellungen am DNS der Domain kann man kostenfrei bis zu 100.000 Mails im Monat versenden. Das reicht meist für den Anfang. 😉

mailtrap.io - Während der Entwicklung spielt der Dienst Mailserver, aber anstelle die Mails auszuliefern bewahrt er sie auf, sodass man sich in Ruhe ansehen kann, was gesendet wurden wäre. So benötigt man keine zig Dummy-Mailadressen.

TEMPMAIL - Für Tests auf dem Produktivsystem (ja, ich weiß, ganz schlechter Stil), mal schnell einen neuen Nutzer mit "eigenem" Mailkonto erstellen.

Abschließende Worte

Jetzt hast du vielleicht zwischendurch echt schlecht Luft bekommen oder dir mit der Hand gegen die Stirn geschlagen. Ja, ging mir auch so. Ich gebe gern zu, dass ich kein Serveradmin bin. Das ich manchmal Programmierparadigma über Bord werfe ist der gleiche schlechte Grund, wie auch bei dir auf Arbeit: Es muss jetzt mal fertig werden. Ich mache den ganzen S#### hier alleine.

Also falls du dich besser auskennst oder mithelfen möchtest. Ich würde mich freuen. 🙂

Über

Material und Anregungen für den Informatikunterricht.