Dokumentation zum Aufsetzen eines LAMP-Servers auf Debian 11 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 11 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).
Als erstes ändern wir das root-Passwort.
passwd root
Dateien lassen sich entweder mit einem graphischen Werkzeug oder direkt in der Konsole mit nano
etwa nano /etc/fail2ban/jail.local
bearbeitet werden.
Teilweise fehlen noch andere wichtige Befehle wie apt-get install unzip
und apt-get install curl
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.
apt install fail2ban
systemctl enable 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 Zeilen so anpassen:
banaction = ufw
banaction_allports = ufw
Und neustarten:
systemctl restart fail2ban.service
Cockpit ist ein Dashboard, womit man auch von unterwegs den Server administrieren und die Auslastung prüfen kann.
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.
sudo apt install apache2
a2enmod rewrite # add rewrite
a2enmod ssl #enable ssl
a2ensite default-ssl # enable default page also in ssl
systemctl restart apache2
apt install mariadb-server
mysql_secure_installation
mariadb
MariaDB [(none)]> GRANT ALL ON *.* TO 'admin_xskBTs'@'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. Eigenen Benutzer ausdenken und password
ersetzen 😉.
PHP 8.3 installieren (Debian bringt aktuell nur 7.4 mit):
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
apt install wget
apt install apt-transport-https software-properties-common
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -
apt update
apt install php8.3
apt install php8.3-common php8.3-gd php8.3-ldap php8.3-odbc php8.3-xsl php8.3-apcu php8.3-curl php8.3-gmp php8.3-opcache php8.3-mbstring php8.3-pgsql php8.3-imagick php8.3-memcached php8.3-bz2 php8.3-ds php8.3-imap php8.3-cgi php8.3-mysql php8.3-cli php8.3-fpm php8.3-xml php8.3-gettext php8.3-bcmath
Test ist mit php -v
möglich. Die Version kann auch später noch über update-alternatives --config php
geändert werden.
apt install phpmyadmin
Unbedingt bei der Installation beachten, dass die Frage an der Integration in apache2 zwar hervorgehoben aber nicht ausgewählt ist. Das unbedingt noch setzen.
In phpMyAdmin kannst du dich nur mit dem admin_xskBTs
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/phpmyadmin/apache.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:
systemctl restart apache2
Nutzen wir gleich unseren admin
-Benutzer und schränken die Ausführungszeit für alle ein. Das ist sehr wichtig, da CROSS JOIN
s 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;
Da diese aber in jeder Datenbank gesetzt werden müssten, beschränken wir uns auf eine Änderung der /etc/mysql/mariadb.cnf
und fügen dort ein:
max_join_size = 10000
max_statement_time = 20
Die mögliche Speicherbelegung der Datenbank im Arbeitsspeicher ist in fast allen Fällen zu klein. Der Default ist 128MB, während meist 70% des verfügbaren Arbeitsspeichers empfohlen wird. Hier in Byte der Speicherplatz für 3GB verfügbare Speicher:
innodb_buffer_pool_size = 3221225472
sudo apt install -y ca-certificates curl gnupg
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
Fürst du die Befehle nach dem Login aus bist du im Verzeichnie /root
curl https://get.acme.sh | sh
Jetzt unbedingt das Terminal neu starten und danach Let's Encrypt als CA auswählen:
acme.sh --set-default-ca --server letsencrypt
Anschließend stellen wir ein Zertifikat für die interne Server-URL aus:
acme.sh --issue --apache -d v220220282479179029.bestsrv.de
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/v220220282479179029.bestsrv.de/v220220282479179029.bestsrv.de.cer
SSLCertificateKeyFile /root/.acme.sh/v220220282479179029.bestsrv.de/v220220282479179029.bestsrv.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
Im Ordner /etc/apache2/sites-available/
die Datei instahub.yak9.de.conf
anlegen:
<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>
Der obige Virtual Host lässt eigentlich nur Let's Encrypt passieren und verweist alle anderen auf die SSL-Verbindung.
Anschließend den eigentlichen Host für instahub.yak9.de-ssl.conf
anlegen:
<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>
Und aktivieren:
a2ensite instahub.yak9.de.conf
a2ensite instahub.yak9.de-ssl.conf
systemctl reload apache2
Zuerst installieren wir das Kommandozeilenwerkzeug Composer:
apt install wget php-cli php-zip unzip
wget -O composer-setup.php https://getcomposer.org/installer
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
Nun 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
Und das SSL-Wildcard-Zertifikat erstellen:
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. Je nachdem 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 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. Etwa so:
usermod -a -G www-data root
chown -R www-data:www-data "/var/www/instahub.yak9.de/"
cd "/var/www/instahub.yak9.de/"
chgrp -R www-data storage bootstrap/cache
chmod -R ug+rwx storage bootstrap/cache
Noch den Storage-Ordner mit Hardlink versehen:
php artisan storage:link
Ab 2024 noch den Java-Skript übersetzen:
npm install
npm run build
Wer das versehentlich als root
gemacht hat muss unbedingt sudo chown -R www-data:www-data .
ausführen, damit der Apache sich austoben kann
Mailserver betreibe ich sehr ungern selber, da ich hier nicht aus Versehen ein Spam-Bot werden möchte. Daher schalte ich meine Domain entweder für die Mails auf ein Shared-Hosting oder Mailpaket auf bzw. nutze folgende Dienste:
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.
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.
Also falls du dich besser auskennst oder mithelfen möchtest. Ich würde mich freuen. 🙂