diff --git a/README.md b/README.md index 3c758196..74eca9fb 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,2 @@ # Admin Guide -You can find this repository here: [https://adminguide.pages.dev](https://adminguide.pages.dev). - -## Contribute -Feel free to open issues / pull requests. Please validate that your changes work as intented! -You can start the mkdocs development server by running `mkdocs serve`. - -Contribution Guidelines: -* Web Services are exposed to `[::1]:8000` -* Secret Environment Variables are in an env_file (and not in the `docker-compose.yml` itself, to prevent leaks) with the following format: - ```shell - # .servicename.env - KEY=value - ``` -* environment variables should be in form of a YAML array, not an object: - ```yaml - environment: - - "KEY=value" - ``` - instead of - ```yaml - # WRONG - please don't do this - environemnt: - KEY: value - # WRONG - ``` -* If possible the service should use either mariadb or postgresql. - If it makes sense, other databases (e.g. sqlite) are also quiet fine. -* YAML arrays should be quoted, regardless which data is stored: - ```yaml - volumes: - - "/srv/service_name/data:/data" - ports: - - "[::1]:8000:1234" - networks: - - "default" - - "database" - ``` -* All domain examples should end in `domain.de` \ No newline at end of file +You can find the rendered guide on [adminguide.pages.dev](https://adminguide.pages.dev). diff --git a/docs/10_overview.md b/docs/10_overview.md deleted file mode 100644 index a80fcae7..00000000 --- a/docs/10_overview.md +++ /dev/null @@ -1,63 +0,0 @@ -# Übersicht der Dienste - - -### Cloud Dienste -- [Nextcloud](./services/nextcloud.md) -- [Seafile](./services/seafile.md) - - -### CMS Dienste (Content-Management-System) -- [Bookstack](./services/bookstack.md) -- [WordPress](./services/wordpress.md) - - -### Dateiverwaltung/Datenvisualisierung -- [Calibre](./services/calibre.md) -- [Gitea](./services/gitea.md) -- [GitLab](./services/gitlab.md) -- [Grafana](./services/grafana.md) -- [Paperless](./services/paperless.md) -- [Syncthing](./services/syncthing.md) - - -### Datenbanken -- [influxdb](./services/influxdb.md) -- [MariaDB](./services/mariadb.md) -- [MongoDB](./services/mongodb.md) -- [pgAdmin4](./services/pgAdmin4.md) -- [PostgreSQL](./services/postgresql.md) - - -### Online IDE's -- [Jupyter Notebook](./services/jupyter.md) - - -### Messenger/Konferenz Dienste -- [Jitsi](./services/jitsi.md) -- [Matrix](./services/matrix.md) -- [Teamspeak](./services/teamspeak.md) - - -### Sicherheit und Authentifizierung: -- [Passbolt](./services/passbolt.md) -- [Vaultwarden](./services/vaultwarden.md) -- [Keycloak](./services/keycloak.md) -- [Psono](./services/psono.md) - -### Serververwaltung und Netzwerk -- [Docky-Onion](./services/docky-onion.md) -- [NetBox](./services/netbox.md) -- [nginx](./services/nginx.md) -- [OpenVPN](./services/openvpn.md) - - -### Spiele Server -- [Arma 3](./services/arma3.md) -- [Minecraft](./services/minecraft.md) - - -### Zusammenarbeit -- [Hedgedoc](./services/hedgedoc.md) -- [Privatebin](./services/privatebin.md) -- [ShareLaTeX](./services/sharelatex.md) -- [Guacamole](./services/guacamole.md) diff --git a/docs/30_backup.md b/docs/30_backup.md deleted file mode 100644 index c861056d..00000000 --- a/docs/30_backup.md +++ /dev/null @@ -1,20 +0,0 @@ -# Backup - -Während meiner Zeit als Administrator für Linux Systeme habe ich einige Skripte und Programme entwickelt -([PyBackup](https://github.com/felbinger/PyBackup), -[GBM](https://github.com/felbinger/GBM), -[DBM](https://github.com/felbinger/dbm)). Mittlerweile verwende ich für dateibasierte Sicherungen -hauptsächlich [borg backup](https://borgbackup.readthedocs.io/en/stable/). - -Im Backup des Servers sollten zumindest die Containerdefinitionen `/home/admin` -sowie Daten der Container (`/srv`) enthalten sein. Sofern nginx als Reverse -Proxy genutzt wird, ist auch eine Sicherung von `/etc/nginx/sites-availabe/` sinnvoll. - -Sofern Datenbanken auf dem Server sind, ist ggf. das Exportieren dieser -vor einem Backup ebenfalls sinnvoll, um einen konsistenten Stand zu haben. -```shell -sudo docker compose \ - -f /home/admin/service/docker-compose.yml \ - exec postgres pg_dumpall -U service_name \ - > /home/backups/service_name_$(date "+%Y-%m-%d").sql -``` \ No newline at end of file diff --git a/docs/A._Theorie/10_reverse-proxy.md b/docs/A._Theorie/10_reverse-proxy.md new file mode 100644 index 00000000..ad4c6e89 --- /dev/null +++ b/docs/A._Theorie/10_reverse-proxy.md @@ -0,0 +1,11 @@ +# 1. Wahl des Reverse Proxies +Im Rahmen dieses Guides werden [nginx](https://www.nginx.com/) auf dem Host sowie +[Traefik](https://traefik.io/) als Container vorgestellt. + +Nginx ist ein leistungsstarker und weit verbreiteter Webserver und Reverse Proxy, welcher sich +durch hohe Stabilität, Effizienz und Flexibilität in klassischen Serverumgebungen auszeichnet. + +Traefik hingegen ist speziell auf containerisierte Umgebungen ausgelegt und integriert sich +nahtlos mit Plattformen wie Docker oder Kubernetes. Es erkennt neue Services automatisch und +konfiguriert Routing-Regeln dynamisch, was es besonders für moderne, dynamische Deployments +attraktiv macht. diff --git a/docs/A._Theorie/20_tls.md b/docs/A._Theorie/20_tls.md new file mode 100644 index 00000000..718320ba --- /dev/null +++ b/docs/A._Theorie/20_tls.md @@ -0,0 +1,71 @@ +# 2. TLS +Für die verschlüsselte Kommunikation zwischen Nutzer und Webserver sind TLS-Zertifikate +erforderlich. + +In den Standard-Einstellungen von Betriebssystemen und Browsern ist bereits eine Auswahl +vertrauenswürdiger Zertifizierungsstellen (CAs) hinterlegt. Nur Zertifikate, die von einer +dieser anerkannten Stellen ausgestellt oder signiert wurden, werden vom Browser automatisch +als sicher bzw. vertrauenswürdig eingestuft. Diese sogenannte "Trusted Root Certificate Authority +List" wird von den jeweiligen Herstellern (z. B. Microsoft, Apple, Mozilla, Google) gepflegt und +regelmäßig aktualisiert. + +Es gibt grundsätzlich drei Möglichkeiten, TLS-Zertifikate zu beziehen bzw. auszustellen: + +1. **Kommerzielle Anbieter** + + Zertifikate können kostenpflichtig von anerkannten Zertifizierungsstellen wie DigiCert, + GlobalSign oder GoDaddy erworben werden. Sie werden häufig von Unternehmen genutzt, um + zusätzliche Garantieleistungen, erweiterte Validierungen (OV/EV) oder Supportleistungen + zu erhalten. + +2. **Kostenlose Zertifikate** + + Let’s Encrypt wurde 2015 von der gemeinnützigen Organisation Internet Security Research Group (ISRG) + gegründet. Ziel war es, das Web durch die Bereitstellung kostenloser, automatisierter und durch offene + Zertifikate sicherer zu gestalten und so verschlüsselte Verbindungen (HTTPS) zum Standard im Internet + zu etablieren. + + Neben Let’s Encrypt existieren weitere Anbieter, die ähnliche kostenlose Zertifizierungsdienste anbieten, + wie beispielsweise ZeroSSL und [Actalis](https://www.actalis.com/). Alle Anbieter unterstützen das + ACME-Protokoll (Automatic Certificate Management Environment), über das die Ausstellung und Verlängerung + von Zertifikaten automatisiert erfolgen kann. + + Diese kostenlosen Zertifikate sind von den gängigen Browsern als vertrauenswürdig anerkannt und eignen sich + hervorragend für öffentliche Websites, Webanwendungen und APIs. Im Vergleich zu kommerziellen Angeboten bieten + sie zwar keine zusätzlichen Garantieleistungen oder erweiterte Validierung (z. B. EV-Zertifikate), erfüllen + aber auf technischer Ebene die selben Sicherheitsstandards. + +3. **Eigene Zertifizierungsstelle (CA)** + + Neben öffentlichen und kommerziellen Anbietern besteht auch die Möglichkeit, eine eigene Zertifizierungsstelle + (Certificate Authority, CA) zu betreiben. Damit können eigene Zertifikate ausgestellt werden – beispielsweise + für interne Server, Entwicklungsumgebungen oder Testsysteme. + + Diese Variante ist kostenlos, erfordert jedoch mehr administrativen Aufwand. Damit Browser und Betriebssysteme + den ausgestellten Zertifikaten vertrauen, muss das Root-Zertifikat der eigenen CA manuell auf allen beteiligten + Geräten installiert werden. In kontrollierten Umgebungen (z. B. Firmennetzwerke oder geschlossene Systeme) kann + dies automatisiert über zentrale Verwaltungswerkzeuge erfolgen. + + Für den produktiven Einsatz im öffentlichen Internet ist diese Lösung jedoch nicht geeignet, da externe Nutzer + das Root-Zertifikat nicht installiert haben und der Browser die Verbindung daher als nicht vertrauenswürdig + einstufen würde. + +!!! warning + Von der Verwendung selbstsignierter Zertifikate und dem Ignorieren von Browserwarnungen ist dringend abzuraten. + + Wer sich daran gewöhnt, Sicherheitsmeldungen einfach „wegzuklicken“, entwickelt schnell ein riskantes Verhalten. + +Im Rahmen dieses Guides wird auf kostenlose TLS-Zertifikate des Anbieters Let’s Encrypt gesetzt. + +Für die Verwaltung dieser stehen verschiedene Tools und Clients zur Verfügung. Wird nginx als Reverse Proxy +eingesetzt, bietet sich die Verwendung von [acme.sh](https://github.com/acmesh-official/acme.sh), ein schlanker, +in Shell geschriebener ACME-Client, der sich einfach in bestehende Umgebungen integrieren lässt, an. +Traefik hingegen verwendet für diesen Zweck standardmäßig den in Go entwickelten ACME-Client [Lego](https://go-acme.github.io/lego/). + +Unabhängig von der gewählten Implementierung stehen bei Let’s Encrypt verschiedene [ACME-Challenge-Typen](https://letsencrypt.org/docs/challenge-types/) +zur Verfügung, über die die Domainvalidierung erfolgt. + +Während die Challenge-Typen HTTP-01 und TLS-ALPN-01 voraussetzen, dass der Reverse Proxy aus dem Internet +erreichbar ist, bietet die DNS-01-Challenge die Möglichkeit, die Domainvalidierung über einen TXT-Eintrag +im DNS durchzuführen. Dadurch muss der Webserver nicht öffentlich zugänglich sein, und die ausgestellten +Zertifikate können somit auch in internen Umgebungen verwendet werden. diff --git a/docs/A._Theorie/30_ipv6-per-serivce.md b/docs/A._Theorie/30_ipv6-per-serivce.md new file mode 100644 index 00000000..2785553d --- /dev/null +++ b/docs/A._Theorie/30_ipv6-per-serivce.md @@ -0,0 +1,63 @@ +# 3. Eine IPv6 Adresse pro Service + +!!! note + Die meisten Hosting-Provider weisen jedem Server ein /64-IPv6-Präfix zu, + was einem Adressraum von $2^{64}$ Adressen entspricht – eine Zahl, die in + der Praxis quasi unerschöpflich ist. + + Ausnahmen gibt es beispielsweise bei Strato: Dort wird nicht ein ganzes /64-IPv6-Präfix, + sondern lediglich eine einzelne IPv6-Adresse pro Server zugewiesen. Dadurch ist es nicht + möglich, jedem Dienst eine eigene IPv6-Adresse zu geben + ([siehe YouTube Short](https://www.youtube.com/shorts/oSvU4HXZ_Wc)). + +Wird jedem nginx Reverse Proxy eine eigene IPv6-Adresse zugewiesen, kann bereits auf OSI-Layer 3 +nachvollzogen werden, an welchen Webservice eine Anfrage gerichtet war. Würde hingegen für alle +Dienste nur eine gemeinsame Adresse verwendet, wäre eine eindeutige Zuordnung frühestens auf +Layer 5 (durch Auswertung des TLS SNI Headers) möglich; ohne ein spezielles Analysewerkzeug sogar +erst auf Layer 7, etwa über die Logdaten des Webservers. + +Der Webserver nginx bietet mit der Direktive `listen` die Möglichkeit, virtuelle Hosts an spezifische +IPv4- oder IPv6-Adressen zu binden. Diese Technik erlaubt eine frühzeitige Trennung und Zuordnung des +eingehenden Traffics zu den einzelnen Anwendungen. Soll ein Dienst abgeschaltet oder vorübergehend +blockiert werden, kann dessen zugewiesene Adresse zudem sehr einfach über die Firewall – oder sogar +direkt beim Provider – gesperrt werden, ohne dass Änderungen an der Servicekonfiguration selbst +erforderlich sind. + + +## Useful Scripts + +### IPv6 Adresse generieren +!!! note + Dieses Skript erzeugt jediglich eine neue IPv6-Adresse! Diese wird nicht automatisch dem + Netzwerkinterface hinzugefügt. Dies muss separat erfolgen! + +Das erstellen einer neuen IPv6 Adresse aus dem /64 Präfix des Servers kann mit folgendem simplen +Skript automatisiert werden: + +```bash +#!/bin/bash + +v=$(cat /dev/urandom | tr -dc a-f0-9 | fold -w16 | head -n1) +echo your:first:four:blocks:${v:0:4}:${v:4:4}:${v:8:4}:${v:12} +``` + +Die ersten vier Blöcke der IPv6-Adresse (`your:first:four:blocks`) müssen dabei durch das +jeweilige /64-Präfix des Servers ersetzt werden (Bsp.: `2001:0db8:85a3:0053`). + + +### Verwendete Ports auflisten +Wenn man jedem Dienst eine eigene IPv6-Adresse zuweist, kann jeder Dienst nach Außen den gleichen +Port verwenden (z. B. 443 für HTTPS). Auf dem Host müssen die Ports jedoch unterschiedlich sein. +Um sich die verwendet Ports aller Dienste anzeigen zu lassen, kann folgender Befehl verwendet werden: +`grep -oP "(?<=proxy_pass)[^;]*" /etc/nginx/sites-enabled/* | sed "s/ /\t/" | expand -t 30 | grep ${1:-.}` + + +Wenn man diesen Befehl in eine Funktion schreibt und diese in die `.bashrc` einfügt, kann man nach +der Verwendung eines genauen Ports suchen: +```bash +function searchport { + grep -oP "(?<=proxy_pass)[^;]*" /etc/nginx/sites-enabled/* | sed "s/ /\t/" | expand -t 30 | grep ${1:-.} +} +``` + +Verwendung: `searchport 8080` -> Listet alle Dienste auf, die den Port 8080 verwenden. \ No newline at end of file diff --git a/docs/A._Theorie/40_ipv4-to-ipv6-proxy.md b/docs/A._Theorie/40_ipv4-to-ipv6-proxy.md new file mode 100644 index 00000000..b43aaa4e --- /dev/null +++ b/docs/A._Theorie/40_ipv4-to-ipv6-proxy.md @@ -0,0 +1,91 @@ +# 4. IPv4 to IPv6 Proxy + +## Sonderfälle +### Virtualisierungsserver +Zwar richtet sich dieser Guide in erster Linie an Administratoren einfacher vServer, doch kann es +schnell vorkommen, dass aufgrund steigender Leistungsanforderungen auf einen dedizierten Server +gewechselt wird. + +Nehmen wir an, ein solcher Server verfügt über eine IPv4-Adresse und ein /64-IPv6-Präfix, auf dem +mehrere virtuelle Maschinen betrieben werden sollen. Das Hostsystem, das direkt auf der physischen +Hardware installiert ist, kann in diesem Szenario als Router fungieren. Über NAT und Port Address +Translation (PAT) lassen sich dabei gezielt einzelne Ports an die virtualisierten Systeme weiterleiten. + +Dank des zugewiesenen IPv6-Präfixes kann jedoch jeder virtuellen Maschine eine eigene öffentliche +IPv6-Adresse zugeordnet werden, wodurch sie direkt aus dem Internet erreichbar ist – ganz ohne NAT. + +In diesem Zusammenhang kann der Einsatz eines IPv4-zu-IPv6-Proxys sinnvoll sein. Ein solcher Proxy +nimmt Anfragen über IPv4 entgegen und leitet sie intern per IPv6 an den Zielserver weiter. Auf diese +Weise bleibt die Erreichbarkeit auch für IPv4-Clients gewährleistet, selbst wenn die eigentliche +Infrastruktur ausschließlich auf IPv6 basiert. + +### IPv6-only Server +Angenommen, es steht eine größere Anzahl von Servern zur Verfügung. Um Kosten und Verwaltungsaufwand +zu reduzieren, wird dabei bewusst auf individuelle IPv4-Adressen verzichtet und jedem System ausschließlich +ein IPv6-Netz zugewiesen. + +!!! warning + Dieses Setup impliziert, dass die Systeme selbst keine ausgehende IPv4-Verbindung aufbauen können. + Das kann die Administration erschweren – beispielsweise, wenn Repositories von GitHub, Docker Hub oder + anderen ausschließlich über IPv4 erreichbaren Diensten bezogen werden sollen. In solchen Fällen ist + entweder ein IPv6-fähiger Mirror oder ein NAT64-Gateway erforderlich, um den Zugriff zu ermöglichen. + + Die wenigsten Anbieter stellen derzeit NAT64 Gateways zur Verfügung, weshalb zum derzeitigen Zeitpunkt + von dieser Systemarchitektur abzuraten ist. + +Die Erreichbarkeit dieser Server aus dem IPv4-Internet kann in einem solchen Szenario über einen zentralen +IPv4-zu-IPv6-Proxy sichergestellt werden. Dieser Proxy fungiert als gemeinsame Eingangsstelle für alle +IPv4-Anfragen und leitet sie intern über IPv6 an die jeweiligen Zielsysteme weiter – effizient, kostensparend +und ohne die Notwendigkeit zusätzlicher IPv4-Ressourcen. + +## IPv4-to-IPv6 Proxy +Zur Vereinfachung der vorgestellten Sonderfälle kann folgende einfache nginx Konfiguration verwendet werden. +Diese implementiert einen IPv4-to-IPv6 Proxy, der zwar in dieser Version lediglich HTTP- und HTTPs-Verbindungen +unterstützt, jedoch mit geringfügigen Anpassungen auch für andere TLS-gesicherte Protokolle wie SMTPs, IMAPs +oder POP3s verwendet werden kann. + +```nginx +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + + sendfile on; + keepalive_timeout 65; + + server { + listen 80 default_server; + location / { + return 301 https://$host$request_uri; + } + } +} + +stream { + server { + listen 443; + + proxy_connect_timeout 1s; + proxy_timeout 3s; + + resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] ipv6=on ipv4=off; + + proxy_pass $ssl_preread_server_name:443; + ssl_preread on; + } +} +``` diff --git a/docs/22_internal_networks.md b/docs/A._Theorie/50_internal_networks.md similarity index 82% rename from docs/22_internal_networks.md rename to docs/A._Theorie/50_internal_networks.md index 9a6b9ad3..e44b5261 100644 --- a/docs/22_internal_networks.md +++ b/docs/A._Theorie/50_internal_networks.md @@ -1,13 +1,25 @@ -# Internal Networks +# 5. Internal Networks -Die im AdminGuide aufgeführten Services erhalten grundsätzlich alle ihre eigene Datenbank. Dies erfordert zum einen mehr +Die in diesem Guide aufgeführten Services erhalten grundsätzlich alle ihre eigene Datenbank. Dies erfordert zum einen mehr Ressourcen, als eine zentrale Datenbank, zum anderen erfordert es beim Exportieren der Datenbanken für ein Backup die Behandlung mehrerer Datenbankserver. Wenn man eine Datenbank für alle Dienste nutzen möchte so sollte dieser als eigener Service definiert werden und über ein docker-internes Netzwerk mit den anderen Diensten kommunizieren. -![Schematic with internal networks](img/internal_networks.png){: loading=lazy } +```mermaid +flowchart LR + Internet@{ shape: cloud, label: Internet } + Web@{ shape: diamond, label: "Reverse Proxy" } + A[HedgeDoc] + B[Nextcloud] + DB@{ shape: cyl, label: MariaDB } + + Internet <-- "[::]:443" --> Web + Web <-- "[::1]:8000" --> A + Web <-- "[::1]:8001" --> B + A & B <--> DB +``` Das interne Netzwerk kann mit dem folgenden Befehl erstellt werden: ```shell diff --git a/docs/A._Theorie/index.md b/docs/A._Theorie/index.md new file mode 100644 index 00000000..60671ed5 --- /dev/null +++ b/docs/A._Theorie/index.md @@ -0,0 +1,49 @@ +# TL;DR + +## Wahl des Reverse Proxies +Docker Images bringen oft keine Möglichkeit verschlüsselte Anfragen zu verarbeiten. +Des Weiteren könnten wir jeden Port nur einmal auf jeder IPv4 / IPv6 Adresse verwenden. + +Abhilfe schafft dabei ein Reverse Proxy, der die externen Anfragen verarbeitet und an den +richtigen Container leitet. Als Reverse Proxy kann [nginx](https://www.nginx.com/) direkt +auf dem Host oder [Traefik](https://traefik.io/) als eigenständiger Container verwendet werden. + +## TLS +Es werden kostenlose TLS Zertifikate von [Let's Encrypt](https://letsencrypt.org/) verwendet. + +Als Zertifikatsverwaltungsoftware dient + +- [acme.sh](https://github.com/acmesh-official/acme.sh), sofern nginx als Reverse Proxy verwendet wird, und +- [Lego](https://go-acme.github.io/lego/) wenn Wahl auf Traefik gefallen ist. + +Es wird die ACME-DNS-01 Challenge verwendet, da die Erreichbarkeit des Reverse Proxies +aus dem Internet nicht erforderlich ist und somit auch für interne Dienste (z. B. ein +Homelab) nutzbar ist. + +## Eine IPv6 Adresse pro Service +Die meisten Server erhalten vom Provider ein öffentliches /64er IPv6 Präfix. +Das ist in der Praxis eine unerschöpfliche Anzahl an Adressen, +daher erhält jeder Service eine eigene Adresse für eingehende Anfragen. + +Dies ermöglicht beispielsweise das blockieren eines Services über die +Firewall des Hosters, ohne dass der Server verändert werden muss +(z. B. von unterwegs). + +## IPv4 to IPv6 Proxy +Zu den möglichen Szenarien zählt beispielsweise der Betrieb eines dedizierten Servers, auf dem +virtualisiert wird und somit mehrere virtuelle Maschinen über eine IPv4-Adresse mit dem Internet +kommunizieren. Ebenso kann es vorkommen, dass mehrere Server genutzt werden, von denen einige aus +Kostengründen ausschließlich über eine IPv6-Adresse verfügen. + +Mit einem einfachen Proxy Server besteht die Möglichkeit Nutzer, welche sich über IPv4 mit dem +Dienst verbinden auf einen IPv6-only Server weiterzuleiten. Ein dedizierter Virtualisierungsserver +verfügt in der Regel über ein /64-IPv6-Präfix, sodass jeder virtuellen Maschine – auch in +Kombination mit dem vorherigen Konzept - eine eigene öffentliche IPv6-Adresse zugewiesen werden kann. + + +## Interne Netzwerke +Werden mehrere Dienste gehostet, ergeben sich oft gleiche Anforderungen (z. B. 3x MariaDB). + +Um Resourcen zu sparen kann eine zentrale Datenbank erstellt werden, die von allen Diensten +genutzt werden soll. Um diese nicht offen ins Internet zu hängen, wird diese über ein eigenes +Docker Netzwerk als interner Dienst angeboten. diff --git a/docs/B._Installation/10_base.md b/docs/B._Installation/10_base.md new file mode 100644 index 00000000..02500154 --- /dev/null +++ b/docs/B._Installation/10_base.md @@ -0,0 +1,46 @@ +# 1. Basisinstallation + +!!! note + Jeder, der diese Informationssammlung nutzt, sollte in der Lage sein, seinen + Linux Server grundlegend einzurichten und abzusichern. Daher verzichte ich hier + auf Standardanleitungen und stelle lediglich die spezifischen Konzepte vor. + +## Admin Gruppe +Ich gehe grundsätzlich davon aus, dass ich auf keinem System der alleinige Administrator +bin. Auf all meinen Systemen existiert daher eine eigene Admin-Gruppe, die Zugriff auf das +Verzeichnis `/home/admin` besitzt. Diese Gruppe dient als zentraler Ablageort für +Container-Definitionen, Umgebungsvariablen-Dateien und Skripte. + +!!! warning "`admin` vs. `adm`" + In vielen Linux-Distributionen – unter anderem auch in Debian – existiert + standardmäßig die Gruppe `adm`. Sie ist für Aufgaben der Systemüberwachung + vorgesehen und gewährt ihren Mitgliedern erweiterte Leserechte auf zahlreiche + Logdateien im Verzeichnis /var/log. + + Für den hier beschriebenen Anwendungsfall ist die Nutzung dieser Gruppe jedoch + ausdrücklich nicht vorgesehen, da sie administrative Berechtigungen über den + eigentlichen Bedarf hinaus gewährt und somit ein potenzielles Sicherheitsrisiko + darstellen kann. + +```shell +groupadd -g 1100 admin +mkdir -m 770 /home/admin +chown root:admin /home/admin +``` + +Die personalisierten Benutzerkonten der Systemadministratoren werden zusätzlich +zur Mitgliedschaft in der Gruppe `sudo` auch der Gruppe `admin` hinzugefügt. + +```shell +adduser nicof2000 +usermod -aG sudo,admin nicof2000 +``` + +## Docker +Die Installation von Docker ist in der offiziellen [Dokumentation](https://docs.docker.com/engine/install/debian/) +bereits sehr gut beschrieben. Zusätzlich richten wir einen Alias ein, um uns die wiederholte +Eingabe von `sudo docker compose` zu ersparen. +```shell +curl -fsSL https://get.docker.com | sudo bash +echo 'alias dc="sudo docker compose "' >> ~/.bashrc +``` diff --git a/docs/B._Installation/20_reverse-proxy.md b/docs/B._Installation/20_reverse-proxy.md new file mode 100644 index 00000000..eda98753 --- /dev/null +++ b/docs/B._Installation/20_reverse-proxy.md @@ -0,0 +1,374 @@ +# 2. Reverse Proxy + +## Installation + +=== "nginx" + Zunächst wird nginx auf dem System installiert + ```shell + sudo apt install -y nginx-full + ``` + + Für die Installation von acme.sh wird zunächst in den root-Kontext gewechselt. + Dies ist notwendig, weil acme.sh in das Nutzerverzeichnis installiert wird. + ```shell + sudo -s + ``` + ```shell + # acme.sh installieren und default ca auf Let's Encrypt setzen + curl https://get.acme.sh | sh -s email=acme@domain.de + ln -s /root/.acme.sh/acme.sh /usr/bin/acme.sh + acme.sh --install-cronjob + + acme.sh --server "https://acme-v02.api.letsencrypt.org/directory" --set-default-ca + ``` + + Anschließend kann die Datei `/etc/nginx/sites-available/default` durch folgenden Codeblock ersetzt werden. + ```nginx + server { + listen 0.0.0.0:80; + listen [::]:80; + http2 on; + + location / { + return 301 https://$host$request_uri; + } + } + ``` + Diese Server Direktive regelt, dass der Server lediglich TLS Verschlüsselte Anfragen verarbeitet. + + + Sofern geplant ist, jedem Virtual Host eine eigene IPv6 Adresse zu geben empfiehlt sich den nginx + systemd-Service um einige Sekunden zu verzögern, sodass sichergestellt werden kann, dass das System + die IPv6 Adressen der Netzwerkschnittstelle bereits hinzugefügt hat. + + ![Result of `systemctl status nginx`](../img/nginx/nginx-failed-ipv6-not-assignable.png){: loading=lazy } + + Dazu muss in der Datei `/lib/systemd/system/nginx.service` vor der ersten `ExecStartPre` Zeile folgendes hinzugefügt werden: + ```shell + # Make sure the additional ipv6 addresses (which have been added with post-up) + # are already on the interface (only required for enabled nginx service on system boot) + ExecStartPre=/bin/sleep 5 + ``` + +=== "Traefik" + Zunächst wird die Containerdefinition im Verzeichnis `/home/admin/traefik/docker-compose.yml` angelegt: + + ```yaml + services: + traefik: + image: traefik:v2.9 + restart: always + command: + - "--api.insecure=true" + - "--metrics.prometheus=true" + #- "--log.level=DEBUG" + - "--accesslog=true" + + - "--providers.docker=true" + - "--providers.docker.exposedbydefault=false" + - "--providers.docker.network=proxy" + + - "--providers.file.directory=/configs/" + + - "--entrypoints.web.address=:80" + - "--entrypoints.web.http.redirections.entrypoint.to=websecure" + - "--entrypoints.web.http.redirections.entrypoint.scheme=https" + + - "--entrypoints.websecure.address=:443" + #- "--entrypoints.websecure.http.middlewares=mw_hsts@file,mw_compress@file" + - "--entryPoints.websecure.http.tls=true" + - "--entryPoints.websecure.http.tls.certresolver=myresolver" + - "--entryPoints.websecure.http.tls.domains[0].main=domain.de" + - "--entryPoints.websecure.http.tls.domains[0].sans=*.domain.de" + + - "--certificatesresolvers.myresolver.acme.dnschallenge=true" + - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" + - "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53" + - "--certificatesresolvers.myresolver.acme.dnschallenge.delayBeforeCheck=10" + - "--certificatesresolvers.myresolver.acme.email=admin@domain.de" + - "--certificatesresolvers.myresolver.acme.storage=/acme/acme.json" + #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" + labels: + - "traefik.enable=true" + - "traefik.http.services.srv_traefik.loadbalancer.server.port=8080" + - "traefik.http.routers.r_traefik.rule=Host(`traefik.domain.de`)" + - "traefik.http.routers.r_traefik.entrypoints=websecure" + env_file: .traefik.env + ports: + - "80:80" + - "443:443" + volumes: + - "/srv/traefik/acme:/acme" + - "/srv/traefik/dynamic.yml:/configs/dynamic.yml" + - "/srv/traefik/middlewares.yml:/configs/middlewares.yml" + - "/etc/localtime:/etc/localtime:ro" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + networks: + - "proxy" + + static: + image: nginx:stable-alpine + restart: always + labels: + # BASIC CONFIGURATION + - "traefik.enable=true" + - "traefik.http.services.srv_static.loadbalancer.server.port=80" + + # ERROR PAGES + # you can use my error_pages: https://github.com/felbinger/AdminGuide/tree/master/error_pages + - "traefik.http.middlewares.error40x.errors.status=403-404" + - "traefik.http.middlewares.error40x.errors.service=srv_static" + - "traefik.http.middlewares.error40x.errors.query=/error/{status}.html" + - "traefik.http.middlewares.error30x.errors.status=300-308" + - "traefik.http.middlewares.error30x.errors.service=srv_static" + - "traefik.http.middlewares.error30x.errors.query=/error/30x.html" + + # DOMAIN ROOT CONTENT + - "traefik.http.routers.r_static_root.rule=HostRegexp(`domain.de`, `{subdomain:[a-z0-9]+}.domain.de`)" + - "traefik.http.routers.r_static_root.entrypoints=websecure" + - "traefik.http.routers.r_static_root.priority=10" + - "traefik.http.middlewares.mw_static_root.addprefix.prefix=/domain_root/" + - "traefik.http.routers.r_static_root.middlewares=mw_static_root@docker,error40x@docker,error30x@docker" + volumes: + - "/srv/static/webroot:/usr/share/nginx/html/" + networks: + - "proxy" + + networks: + proxy: + external: true + ``` + + Wird Traefik hinter einem IPv4-to-IPv6 Proxy eingesetzt sollte dieser lediglich auf IPv6 exposed werden. + + ```yaml + services: + traefik: + # ... + ports: + - "[::]:80:80" + - "[::]:443:443" + ``` + + Nun müssen noch einige Konfigurationen angelegt werden: + ```yaml + # /srv/traefik/middlewares.yml + http: + middlewares: + mw_compress: + compress: true + mw_hsts: + headers: + contentTypeNosniff: true + browserXssFilter: true + forceSTSHeader: true + sslRedirect: true + stsPreload: true + stsSeconds: 315360000 + stsIncludeSubdomains: true + customResponseHeaders: + X-Forwarded-Proto: https + X-Frame-Options: sameorigin + ``` + + ```yaml + # /srv/traefik/dynamic.yml + tls: + options: + default: + minVersion: VersionTLS13 + sniStrict: true + cipherSuites: + # TLS 1.3 + - TLS_AES_256_GCM_SHA384 + - TLS_CHACHA20_POLY1305_SHA256 + - TLS_AES_128_GCM_SHA256 + ``` + + Anschließend wird das `proxy` Docker Netzwerk angelegt und Traefik gestartet. + ```shell + docker network create proxy + docker compose up -d + ``` + +## Konfiguration für neue Dienste + +=== "nginx" + Für das einbinden eines webbasierten Dienstes in nginx sind eine Reihe von Schritten erforderlich. + + Zunächst muss die Containerdefinition des Dienstes um ein entsprechendes Port-Bindung erweitert werden. + Durch dieses wird der Port aus dem Container an das Hostsystem exposiert wird und lokal angesprochen werden kann. + Dabei darf natürlich nur die linke Seite (hier 8081) verändert werden. + + !!! tipp + Schon verwendete Ports lassen sich mit folgendem Befehl ermitteln: + ```sh + grep -oP "(?<=proxy_pass)[^;]*" /etc/nginx/sites-enabled/* | sed "s/ /\t/" | expand -t 30 + ``` + + Zur leichteren Verwendung empfielt sich das hinzufügen folgender Funktion in der Datei `~/.bashrc`: + ```bash + function searchport { + grep -oP "(?<=proxy_pass)[^;]*" /etc/nginx/sites-enabled/* | sed "s/ /\t/" | expand -t 30 | grep ${1:-.} + } + ``` + Neben der Möglichkeit alle Ports mit `searchport` aufzulisten, ergibt sich die Möglichkeit den ersetzen Parameter zu setzen (`searchport 8081`) um den zu einem Port gehörenden Domainnamen anzuzeigen. + + In der `docker-compose.yaml` des jeweiligen Dienstes muss demnach folgendes hinzugefügt werden: + ```yaml + ports: + - "[::1]:8081:80" + ``` + + Anschließend muss ein TLS Zertifikat für die gewünschte Domain auf der, der Dienst erreichbar sein soll + angefordert werden. + + ```shell + # Beispielkonfiguration für Cloudflare DNS API + CF_Token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX acme.sh --issue --keylength ec-384 --dns dns_cf -d service.domain.de + ``` + + Optional kann nun eine eigene IPv6 Adresse für diesen virtual Host konfiguriert werden: + + === "Debian" + ```shell + # /etc/network/interfaces + + # ... + + iface eth0 inet6 static + # ipv6 address of the host + address 2001:db8:1234:5678::1/64 + gateway 2001:db8::1 + + # service.domain.de + post-up ip -6 a add 2001:db8:1234:5678:5eca:dc9d:fd4e:6564/64 dev $IFACE + pre-down ip -6 a del 2001:db8:1234:5678:5eca:dc9d:fd4e:6564/64 dev $IFACE + ``` + + === "Ubuntu" + Da Ubuntu `netplan` zum Konfigurieren der Netzwerkeschnittstellen verwendet, muss die entsprechende Konfiguration im + Verzeichnis `/etc/netplan` angepasst werden. + Die Konfigurationsdatei sollte ungefähr wie folgt aussehen: + ```yaml + network: + version: 2 + renderer: networkd + ethernets: + enp1s0: + addresses: + - 10.10.10.2/24 + - 2001:db8::5/64 + dhcp4: no + routes: + - to: 0.0.0.0/0 + via: 10.10.10.1 + - to: ::/0 + via: 2001:db8::1 + nameservers: + addresses: [10.10.10.1, 1.1.1.1, 2001:470:20::2] + ``` + Wenn die Konfigurationsdatei gefunden wurde, fügt man in dem `addresses` Abschnitt die neue IPv6 Adresse wie + folgt hinzu: + ```yaml + addresses: + ... + - 2001:db8:4a:90a:d8d5:dbf4:fd80:8f80 + ``` + + Nun kann der V-Host unter dem Pfad `/etc/nginx/sites-available/service.domain.de` erstellt werden: + + !!! note + Standardmäßig wird der nginx auf beiden Adressfamilien exposiert. + + Ist lediglich IPv6 (z. B. für die Verwendung eines Proxy Servers) erwünscht, + müssen die `listen` Direktiven im Serverblock wie folgt angepasst werden: + + ```nginx + listen [::]:80; + ``` + + Ist weitergehend die Verwendung einer eigenen IPv6 Adresse pro Service erwünscht, + sollte diese anstelle von :: eingefügt werden: + + ```nginx + listen [2001:db8::dead]:80; + ``` + + ```nginx + # https://ssl-config.mozilla.org/#server=nginx&version=1.27.3&config=modern&openssl=3.4.0&ocsp=false&guideline=5.7 + server { + server_name service.domain.de; # <--- + listen 0.0.0.0:443 ssl; + listen [::]:443 ssl; + + ssl_certificate /root/.acme.sh/service.domain.de_ecc/fullchain.cer; + ssl_certificate_key /root/.acme.sh/service.domain.de_ecc/service.domain.de.key; + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; # about 40000 sessions + ssl_session_tickets off; + + # modern configuration + ssl_protocols TLSv1.3; + ssl_ecdh_curve X25519:prime256v1:secp384r1; + ssl_prefer_server_ciphers off; + + # HSTS (ngx_http_headers_module is required) (63072000 seconds) + add_header Strict-Transport-Security "max-age=63072000" always; + + # OCSP stapling + ssl_stapling on; + ssl_stapling_verify on; + + location / { + proxy_pass http://[::1]:8000/; # <--- + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + } + } + ``` + + Zum Abschluss kann die Konfiguration aktiviert, getestet und angewandt werden. + + ```shell + ln -s /etc/nginx/sites-available/service.domain.de \ + /etc/nginx/sites-enabled/ + + nginx -t && systemctl reload nginx + ``` + + +=== "Traefik" + Für das einbinden eines webbasierten Dienstes in Traefik sind lediglich zwei Schritte notwendig. + + Zunächst muss das `proxy`-Netzwerk dem Container hinzugefügt werden. Dabei ist zu beachten, dass + - sofern dieser mit anderen Containern in der gleichen Containerdefinition - interagieren muss, + ebenfalls das `default`-Netzwerk benötigt, welches der Standardwert für Container ohne explizite + Netzwerkkonfiguration ist: + ```yaml + networks: + - "proxy" + #- "default" + ``` + + Außerdem müssen die Docker Labels für das HTTP Routing gesetzt werden: + ```yaml + labels: + - "traefik.enable=true" + - "traefik.http.services.srv_service-name.loadbalancer.server.port=80" + - "traefik.http.routers.r_service-name.rule=Host(`service.domain.de`)" + - "traefik.http.routers.r_service-name.entrypoints=websecure" + ``` + + !!! warning + Hierbei sollte unbedingt darauf geachtet werden, dass weder service (Präfix `srv_`), + noch router-Bezeichnungen (Präfix `r_`) doppelt verwendet werden, da dies zu schwer + bemerkbaren Fehlern führen kann. + + Außerdem sollte auf die korrekte Konfiguration des Service Ports geachtet werden (hier 80). diff --git a/docs/B._Installation/30_backup.md b/docs/B._Installation/30_backup.md new file mode 100644 index 00000000..d683bd5a --- /dev/null +++ b/docs/B._Installation/30_backup.md @@ -0,0 +1,70 @@ +# 3. Backup + +Für das Backup des Server kann [BorgBackup2](https://borgbackup.readthedocs.io/en/master/index.html) verwendet werden. + +### Installation +```shell +sudo apt install borgbackup2 +``` + +### Backup Verzeichnis +In diesem Guide stellen wir die lokale Speicherung des Backups vor, da diese jeder mit einem Server verwenden kann. +Dennoch empfehlen wir das Sichern des Backups auf einem dedizierten Gerät (StorageBox, anderer Server, NAS, ...). + +#### Erstellung des Backup Verzeichnisses +Zu der lokalen Sicherung des Backups verwenden wir einen Ordner im `/home` Verzeichnis und geben ihm die selben Rechte +wie dem `/home/admin` Verzeichnis, damit alle Administrator des Servers auf dieses Backup zugreifen können. + +```shell +sudo mkdir -m 770 /home/backups +sudo chown root:admin /home/backups +``` + +#### Initialisierung des Verzeichnisses als Backupverzeichnis +```shell +borg2 -r /home/backups rcreate -e repokey-blake2-chacha20-poly1305 +``` + +### Sichern von kritischen Verzeichnissen +Wie oben schon beschrieben empfehlen wir hier das Sichern von den Verzeichnissen welche wir hier im Guide erstellen. +Man sichert aber lieber zu viel, als zu wenig! + +Der Aufbau des Sicherungsbefehl ist folgender: +```shell +borg2 -r /backup/verzeichnis create name_des_archives_in_borg /zu/sicherndes/verzeichnis +``` + +Um nicht jedes Verzeichnis einzeln auszuführen, haben wir uns dafür ein kleines Script geschrieben. Wir empfehlen dieses +Script in einem Screen auszuführen, da je nach Dateigröße das intiale Backup bis zu mehreren Stunden dauern kann. + +Hierbei sollte beachtet werden, dass das Script zwangsläufig unter dem root-Nutzer ausgeführt werden muss, sodass voller +Zugriff auf alle Pfade besteht. + +!!! note + Die folgenden Verzeichnisse sind jene, die im Rahmen dieses Guides aktiv verwendet werden. + + Selbstverständlich können auch zusätzliche Pfade in das Backup aufgenommen werden – denn: „Kein Backup, kein Mitleid!“ + +```shell +# backup.sh +declare -A map=( + ["admin"]="/home/admin" + ["srv"]="/srv" + ["nginx"]="/etc/nginx/sites-available" + ["network"]="/etc/network/" + ["certificates"]="/root/.acme" +) +for name in ${!map[@]}; do + paths="${map[${name}]}" + borg2 -r /home/backups create "${name}" "${paths}" +done +``` + + +Hinweis: Wenn man das Script als root User ausführt und das Script in folgender Reihenfolge ausführt, braucht man nicht +für jedes Verzeichnis den Key neu eingeben + +```shell +sudo -s +BORG_PASSPHRASE=s3cr3t-s3cur3-p4ssw0rd bash backup.sh +``` \ No newline at end of file diff --git a/docs/31_monitoring.md b/docs/B._Installation/40_monitoring.md similarity index 89% rename from docs/31_monitoring.md rename to docs/B._Installation/40_monitoring.md index ab6ee874..5c103301 100644 --- a/docs/31_monitoring.md +++ b/docs/B._Installation/40_monitoring.md @@ -1,4 +1,4 @@ -# Monitoring +# 4. Monitoring !!! info "" Work in progress - not finished yet! @@ -31,7 +31,7 @@ services: - "[::1]:8000:3000" prometheus: - image: quay.io/prometheus/prometheus + image: prom/prometheus restart: always volumes: - "/srv/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml" @@ -40,19 +40,19 @@ services: - "[::1]:9090:9090" alertmanager: - image: quay.io/prometheus/alertmanager + image: prom/alertmanager restart: always ports: - "[::1]:9093:9093" pushgateway: - image: quay.io/prometheus/pushgateway + image: prom/pushgateway restart: always ports: - "[::1]:9091:9091" node_exporter: - image: quay.io/prometheus/node-exporter + image: prom/node-exporter restart: always volumes: - "/proc:/host/proc:ro" @@ -66,7 +66,7 @@ services: - "--collector.filesystem.ignored-fs-types='^(sys|proc|auto|cgroup|devpts|ns|au|fuse\.lxc|mqueue)(fs|)$$'" blackbox_exporter: - image: quay.io/prometheus/blackbox-exporter + image: prom/blackbox-exporter restart: always command: "--config.file=/config/config.yaml" volumes: @@ -87,7 +87,7 @@ services: ``` ```yaml -# /srv/monitoring/prometheus/prometheus.yaml +# /srv/monitoring/prometheus/prometheus.yml global: scrape_interval: 30s evaluation_interval: 30s @@ -156,7 +156,7 @@ scrape_configs: ``` ```yaml -# /srv/monitoring/blackbox_exporter/config.yaml +# /srv/monitoring/blackbox_exporter/config.yml modules: http_2xx: prober: http @@ -167,3 +167,12 @@ modules: icmp: preferred_ip_protocol: "ip4" # defaults to "ip6" ``` + + +### Ordner kopieren und Ordnerberechtigungen anpassen +```bash +docker compose cp grafana:/var/lib/grafana /srv/monitoring/grafana/lib +docker compose cp grafana:/etc/grafana /srv/monitoring/grafana/etc + +sudo chown -R 472 /srv/monitoring/grafana +``` diff --git a/docs/C._Services/_overview.md b/docs/C._Services/_overview.md new file mode 100644 index 00000000..9cded6f3 --- /dev/null +++ b/docs/C._Services/_overview.md @@ -0,0 +1,3 @@ +# Übersicht der Dienste + + diff --git a/docs/C._Services/arma3.md b/docs/C._Services/arma3.md new file mode 100644 index 00000000..19f685e5 --- /dev/null +++ b/docs/C._Services/arma3.md @@ -0,0 +1,193 @@ +--- +tags: + - Gaming +hide: + - tags +--- +# Arma 3 Server + +Ein Arma 3 Gameserver ermöglicht es Arma 3 Spielern eine gemeinsame Mission zu spielen. +Das hier beschriebene Vorgehen erweitert die Grundfunktionalität von LGSM (Linux Game Server +Manager) um die benötigten Paketen für extdb2/extdb3. + +```yaml +services: + arma3: + image: ghcr.io/felbinger/arma3server + restart: always + env_file: .arma3.env + ports: + - "2302:2302/udp" # Arma 3 + voice over network + - "2303:2303/udp" # Steam Query + - "2304:2304/udp" # Steam Master + - "2305:2305/udp" # old Voice over Network + - "2306:2306/udp" # BattleEye + volumes: + - "/srv/arma3:/home/linuxgsm" + + mariadb: + image: mariadb + restart: always + environment: + - "MARIADB_RANDOM_ROOT_PASSWORD=true" + - "MARIADB_USER=arma3" + - "MARIADB_PASSWORD=S3cr3T" + - "MARIADB_DATABASE=exile" + volumes: + - "/srv/arma3-mariadb:/var/lib/mysql" +``` +```sh +# .arma3.env +# will also be stored on filesystem (/srv/aram3/lgsm/config-lgsm/arma3server/arma3server.cfg) during installation! +STEAM_USER=steam_username +STEAM_PASS=steam_password +``` + +Vor dem ersten Start müssen die Berechtigungen des Verzeichnisses `/srv/arma3` angepasst werden. +```shell +mkdir /srv/arma3 +chown 1000:1000 /srv/arma3 +``` + +Anschließend können die Container gestartet werden (`docker compose up -d arma3`), +wodurch die Installation angestoßen wird. + +### Wichtige Pfade +```shell +# things that need to be done to start the server (e. g. mods) +/srv/arma3/lgsm/config-lgsm/arma3server/arma3server.cfg + +# arma 3 server / network config +/srv/arma3/serverfiles/cfg/arma3server.server.cfg +/srv/arma3/serverfiles/cfg/arma3server.network.cfg + +# mpmission folder +/srv/arma3/serverfiles/mpmissions +``` + +## Exile Mod + +Für Exile müssen nun einige Mods im Verzeichnis `/srv/arma3/serverfiles/` hinzugefügt werden: +```shell +cd /srv/arma3/serverfiles/ + +# download and extract mods +wget https://bravofoxtrotcompany.com/exile/@Exile-1.0.4.zip +wget https://exilemod.com/ExileServer-1.0.4a.zip +unzip @Exile-1.0.4.zip +unzip ExileServer-1.0.4a.zip +rm *.zip + +# move the extracted files into the correct locations +cp -r /srv/arma3/serverfiles/Arma\ 3\ Server/* /srv/arma3/serverfiles/ + +# create tables on database using provided database schema +docker compose exec -T mariadb \ + mysql -uexile -pexile exile < /srv/arma3/serverfiles/MySQL/exile.sql + +# adjust extdb2 configuration +sed -i 's/^IP = 127.0.0.1/IP = mariadb/' /srv/arma3/serverfiles/@ExileServer/extdb-conf.ini +sed -i 's/^Username = changeme/Username = arma3/' /srv/arma3/serverfiles/@ExileServer/extdb-conf.ini +sed -i 's/^Password = /Password = S3cr3T/' /srv/arma3/serverfiles/@ExileServer/extdb-conf.ini + +# arma 3 server configs +mv /srv/arma3/serverfiles/@ExileServer/basic.cfg /srv/arma3/serverfiles/cfg/arma3server.network.cfg +mv /srv/arma3/serverfiles/@ExileServer/config.cfg /srv/arma3/serverfiles/cfg/arma3server.server.cfg + +# add mods to server startup configuration +cat <<_EOF > /srv/arma3/lgsm/config-lgsm/arma3server/arma3server.cfg +mods="@Exile" +servermods="@ExileServer" +_EOF + +# delete remaining extracted files from exile-server +rm -r /srv/arma3/serverfiles/{Arma\ 3\ Server,MySQL}/ + +# adjust permissions, so that LGSM can work with all files +chown -R 1000:1000 /srv/arma3 +``` + +Nach einem Neustart der Container (`docker compose down && docker compose up -d`) +sollten diese geladen werden, falls Probleme auftreten können diese dem Serverlog +entnommen werden (`docker compose exec arma3 arma3server console`). + + + +### Mod: AdminToolkit +1. [Git-Repository](https://github.com/ole1986/a3-admintoolkit) herunterladen +2. Mittels [PBO-Manager](https://github.com/SteezCram/Armaholic-Archive/tree/main/PBO_Manager) `/a3-admintoolkit-master/@AdminToolkitServer/addons/admintoolkit_servercfg.pbo` entpacken +3. Variablen in `config.cpp` anpassen (siehe `class AdminToolkit` in `class CfgSettings`): + - ServerCommandPassword + - AdminList + - ModeratorList +4. PBO mit modifizierter `config.cpp` packen und @AdminToolkitServer auf den Server hochladen. +5. mission anpassen + 1. Mission entpacken + 2. `/a3-admintoolkit-master/source/mission_file/atk` in root-Verzeichnis der Mission kopieren + 3. Vor `class CfgExileCustomCode` folgende `class CfgAdminToolkitCustomMod` einfügen: + ```cpp + class CfgAdminToolkitCustomMod { + /* Exclude some main menu items + * To only show the menus loaded from an extension, use: + * + * ExcludeMenu[] = {"Players", "Vehicles", "Weapons" , "Other"}; + */ + ExcludeMenu[] = {}; + + /* Load an additional sqf file as MOD */ + Extensions[] = { + /** + * Usage: {"", ""} + * add a new menu entry called My Extension into main menu */ + {"My Extension", "MyExtension"} + }; + + /* 4 Quick buttons allowing to add any action you want - See example below*/ + QuickButtons[] = { + /* send a message to everyone using the parameter text field */ + {"Restart Msg", "['messageperm', ['Server Restart in X minutes']] call AdminToolkit_doAction"}, + /* Quickly get a Helicopter */ + {"Heli", "['getvehicle', ['B_Heli_Light_01_armed_F']] call AdminToolkit_doAction"}, + /*4 button*/ + {"Empty", "['Command', ['Variable #1', 'Variable #2']] call AdminToolkit_doAction"} + }; + }; + ``` + + 4. `description.ext` bearbeiten, Nachfolgendes zur `class CfgRemoteExec.Functions` hinzufügen: + ```cpp + class AdminToolkit_network_receiveRequest { + allowedTargets = 2; + }; + ``` + 5. Mission packen und auf Server hochladen + +6. @AdminToolkitServer als Client(!) Mod zur Serverkonfiguration (`/srv/arma3/lgsm/config-lgsm/arma3server/arma3server.cfg`) hinzufügen + ``` + mods="@Exile;@AdminToolkitServer" + servermods="@ExileServer" + ``` + +8. `verifySignatures` in `serverfiles/cfg/arma3server.server.cfg` deaktivieren, da die Mod nicht signiert ist. + +9. Server Neustarten und testen + ```sh + docker compose -f /home/admin/arma3/docker-compose.yml down + docker compose -f /home/admin/arma3/docker-compose.yml up -d + ``` + + Client mit @AdminToolkit Mod starten und dem Spiel beitreten. + + Das AdminInterface sollte auf der Taste F2 liegen. + + \ No newline at end of file diff --git a/docs/services/bookstack.md b/docs/C._Services/bookstack.md similarity index 99% rename from docs/services/bookstack.md rename to docs/C._Services/bookstack.md index fe72cb08..57bd43db 100644 --- a/docs/services/bookstack.md +++ b/docs/C._Services/bookstack.md @@ -1,3 +1,9 @@ +--- +tags: + - CMS +hide: + - tags +--- # Bookstack Bookstack ist eine einfache Wiki- / KnowledgeBase Software. diff --git a/docs/services/calibre.md b/docs/C._Services/calibre.md similarity index 96% rename from docs/services/calibre.md rename to docs/C._Services/calibre.md index 3063339d..fcd24948 100644 --- a/docs/services/calibre.md +++ b/docs/C._Services/calibre.md @@ -1,3 +1,9 @@ +--- +tags: + - "Datenverwaltung / Datenvisualisierung" +hide: + - tags +--- # Calibre Calibre ist ein Programm zur Verarbeitung, Konvertierung und Verwaltung von E-Books. diff --git a/docs/C._Services/dayz.md b/docs/C._Services/dayz.md new file mode 100644 index 00000000..d57f8f9a --- /dev/null +++ b/docs/C._Services/dayz.md @@ -0,0 +1,9 @@ +# DayZ Server + +Habe ich vor kurzem auf einem Debian Server ohne Docker aufgesetzt und in Form eines +Blog Eintrags dokumentiert. + + + +In Kombination mit [der Anleitung für einen Arma 3 Server](./arma3.md) sollte man +damit das Docker deployment einfach durchführen können. diff --git a/docs/services/docky-onion.md b/docs/C._Services/docky-onion.md similarity index 95% rename from docs/services/docky-onion.md rename to docs/C._Services/docky-onion.md index 4a1f1ca9..7ac83ed8 100644 --- a/docs/services/docky-onion.md +++ b/docs/C._Services/docky-onion.md @@ -1,3 +1,9 @@ +--- +tags: + - "Serververwaltung und Netzwerk" +hide: + - tags +--- # docky-onion Um einen [tor hidden services](https://2019.www.torproject.org/docs/onion-services) mit docker zu verwenden, kann man diff --git a/docs/services/gitea.md b/docs/C._Services/gitea.md similarity index 97% rename from docs/services/gitea.md rename to docs/C._Services/gitea.md index 9afed509..b8fddebb 100644 --- a/docs/services/gitea.md +++ b/docs/C._Services/gitea.md @@ -1,3 +1,9 @@ +--- +tags: + - "Datenverwaltung / Datenvisualisierung" +hide: + - tags +--- # Gitea Gitea ist eine webbasierte Git-Plattform, die es Benutzern ermöglicht, Code-Repositories zu hosten, zu verwalten und zu diff --git a/docs/services/gitlab.md b/docs/C._Services/gitlab.md similarity index 98% rename from docs/services/gitlab.md rename to docs/C._Services/gitlab.md index 7ba2d291..ada8eefb 100644 --- a/docs/services/gitlab.md +++ b/docs/C._Services/gitlab.md @@ -1,3 +1,9 @@ +--- +tags: + - "Datenverwaltung / Datenvisualisierung" +hide: + - tags +--- # GitLab GitLab ist eine Software für Code-Management und Versionierung. Außerdem bietet es eine Vielzahl an Tools für die diff --git a/docs/services/grafana.md b/docs/C._Services/grafana.md similarity index 95% rename from docs/services/grafana.md rename to docs/C._Services/grafana.md index abd59231..5eb58d82 100644 --- a/docs/services/grafana.md +++ b/docs/C._Services/grafana.md @@ -1,3 +1,9 @@ +--- +tags: + - "Datenverwaltung / Datenvisualisierung" +hide: + - tags +--- # Grafana Grafana ist ein Dienst, welcher zur Datenvisualisierung und Überwachung verwendet wird. @@ -16,6 +22,10 @@ services: Da der Container die, in den Volumes liegenden Daten, nicht kopiert müssen wir das zuvor manuell erledigen: +!!! note + Standardmäßig läuft Grafana mit dem Nutzer `grafana` (UID 472). + Daher müssen die Verzeichnisse entsprechend diesem Nutzer gehören. + ```shell sudo mkdir -p /srv/grafana sudo docker compose up -d grafana diff --git a/docs/services/guacamole.md b/docs/C._Services/guacamole.md similarity index 98% rename from docs/services/guacamole.md rename to docs/C._Services/guacamole.md index 6f564927..b6b9e99f 100644 --- a/docs/services/guacamole.md +++ b/docs/C._Services/guacamole.md @@ -1,3 +1,9 @@ +--- +tags: + - Zusammenarbeit +hide: + - tags +--- # Guacamole Guacamole ist ein Webanwendungsdienst, welcher es ermöglicht, über einen Webbrowser auf entfernte Computer oder Server diff --git a/docs/services/hedgedoc.md b/docs/C._Services/hedgedoc.md similarity index 98% rename from docs/services/hedgedoc.md rename to docs/C._Services/hedgedoc.md index 86062ba4..d4f85a77 100644 --- a/docs/services/hedgedoc.md +++ b/docs/C._Services/hedgedoc.md @@ -1,3 +1,9 @@ +--- +tags: + - Zusammenarbeit +hide: + - tags +--- # HedgeDoc HedgeDoc ist eine Open-Source-Plattform für die kollaborative Bearbeitung von Dokumenten in Echtzeit, ähnlich wie Google diff --git a/docs/services/influxdb.md b/docs/C._Services/influxdb.md similarity index 95% rename from docs/services/influxdb.md rename to docs/C._Services/influxdb.md index e876e413..e45fb133 100644 --- a/docs/services/influxdb.md +++ b/docs/C._Services/influxdb.md @@ -1,3 +1,9 @@ +--- +tags: + - Database +hide: + - tags +--- # InfluxDB InfluxDB ist eine Open-Source-Zeitreihendatenbank, die speziell für die Speicherung, Abfrage und Visualisierung von diff --git a/docs/services/jitsi.md b/docs/C._Services/jitsi.md similarity index 98% rename from docs/services/jitsi.md rename to docs/C._Services/jitsi.md index 58ba7e3d..d8ffe2a3 100644 --- a/docs/services/jitsi.md +++ b/docs/C._Services/jitsi.md @@ -1,3 +1,9 @@ +--- +tags: + - Communication +hide: + - tags +--- # Jitsi Der [Self-Hosting Guide](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker) von Jitsi ist eigentlich selbsterklärend. diff --git a/docs/services/jupyter.md b/docs/C._Services/jupyter.md similarity index 96% rename from docs/services/jupyter.md rename to docs/C._Services/jupyter.md index ecb7f222..f3ce2e5f 100644 --- a/docs/services/jupyter.md +++ b/docs/C._Services/jupyter.md @@ -1,3 +1,9 @@ +--- +tags: + - IDE +hide: + - tags +--- # Jupyter Jupyter Notebook ist eine interaktive Entwicklungsumgebung, die es Benutzern ermöglicht, Code zu schreiben und diff --git a/docs/services/keycloak.md b/docs/C._Services/keycloak.md similarity index 99% rename from docs/services/keycloak.md rename to docs/C._Services/keycloak.md index c756394f..4ab52af4 100644 --- a/docs/services/keycloak.md +++ b/docs/C._Services/keycloak.md @@ -1,3 +1,9 @@ +--- +tags: + - IAM +hide: + - tags +--- # Keycloak Keycloak ist eine Software zur Verwaltung von Benutzer-Authentifizierung und Autorisierung, einschließlich diff --git a/docs/services/mariadb.md b/docs/C._Services/mariadb.md similarity index 86% rename from docs/services/mariadb.md rename to docs/C._Services/mariadb.md index e51e52aa..0d356463 100644 --- a/docs/services/mariadb.md +++ b/docs/C._Services/mariadb.md @@ -1,3 +1,9 @@ +--- +tags: + - Database +hide: + - tags +--- # MariaDB Einfache SQL basierte Datenbank. Nachfolger von MySQL. diff --git a/docs/services/matrix.md b/docs/C._Services/matrix.md similarity index 99% rename from docs/services/matrix.md rename to docs/C._Services/matrix.md index 263f7d83..12ceb605 100644 --- a/docs/services/matrix.md +++ b/docs/C._Services/matrix.md @@ -1,3 +1,9 @@ +--- +tags: + - Communication +hide: + - tags +--- # Matrix Ein Server für einen dezentralen Messenger Dienst. diff --git a/docs/services/minecraft.md b/docs/C._Services/minecraft.md similarity index 94% rename from docs/services/minecraft.md rename to docs/C._Services/minecraft.md index dca6f200..4b3b0433 100644 --- a/docs/services/minecraft.md +++ b/docs/C._Services/minecraft.md @@ -1,3 +1,9 @@ +--- +tags: + - Gaming +hide: + - tags +--- # Minecraft Server Ein Spigot Server, welcher auch den Zugriff auf Mods erlaubt. diff --git a/docs/services/mongodb.md b/docs/C._Services/mongodb.md similarity index 92% rename from docs/services/mongodb.md rename to docs/C._Services/mongodb.md index 81bbecd9..174abf1a 100644 --- a/docs/services/mongodb.md +++ b/docs/C._Services/mongodb.md @@ -1,3 +1,9 @@ +--- +tags: + - Database +hide: + - tags +--- # MongoDB MongoDB ist eine dokumentenorientierte NoSQL-Datenbank, die eine flexible und skalierbare Speicherlösung für diff --git a/docs/services/netbox.md b/docs/C._Services/netbox.md similarity index 98% rename from docs/services/netbox.md rename to docs/C._Services/netbox.md index 8fd36b8e..2394aa6d 100644 --- a/docs/services/netbox.md +++ b/docs/C._Services/netbox.md @@ -1,3 +1,9 @@ +--- +tags: + - "Serververwaltung und Netzwerk" +hide: + - tags +--- # NetBox NetBox ist eine Open-Source-Software zur Verwaltung von Netzwerkinfrastrukturen. Es bietet eine diff --git a/docs/services/nextcloud.md b/docs/C._Services/nextcloud.md similarity index 98% rename from docs/services/nextcloud.md rename to docs/C._Services/nextcloud.md index 65efbf8a..59aefd1d 100644 --- a/docs/services/nextcloud.md +++ b/docs/C._Services/nextcloud.md @@ -1,3 +1,9 @@ +--- +tags: + - Cloud +hide: + - tags +--- # Nextcloud Nextcloud ist eine vielseitige Cloud, welche mit zahlreichen Add-ons um Funktionen erweitert werden kann. diff --git a/docs/services/nginx.md b/docs/C._Services/nginx.md similarity index 96% rename from docs/services/nginx.md rename to docs/C._Services/nginx.md index a3dd97d8..c090122f 100644 --- a/docs/services/nginx.md +++ b/docs/C._Services/nginx.md @@ -1,3 +1,9 @@ +--- +tags: + - "Serververwaltung und Netzwerk" +hide: + - tags +--- # nginx Wird ein einfacher Webserver z. B. für eine statische Homepage benötigt, kann ein nginx Container verwendet werden. diff --git a/docs/services/openvpn.md b/docs/C._Services/openvpn.md similarity index 96% rename from docs/services/openvpn.md rename to docs/C._Services/openvpn.md index d7d46cd4..81b15a34 100644 --- a/docs/services/openvpn.md +++ b/docs/C._Services/openvpn.md @@ -1,3 +1,9 @@ +--- +tags: + - "Serververwaltung und Netzwerk" +hide: + - tags +--- # OpenVPN Einfacher und selbst gehosteter OpenSource VPN Dienst. diff --git a/docs/services/paperless.md b/docs/C._Services/paperless.md similarity index 100% rename from docs/services/paperless.md rename to docs/C._Services/paperless.md diff --git a/docs/services/passbolt.md b/docs/C._Services/passbolt.md similarity index 98% rename from docs/services/passbolt.md rename to docs/C._Services/passbolt.md index 3821a8e2..a7ab6d8a 100644 --- a/docs/services/passbolt.md +++ b/docs/C._Services/passbolt.md @@ -1,3 +1,9 @@ +--- +tags: + - "Password Manager" +hide: + - tags +--- # passbolt Passbolt ist ein self-hosted open source Passwortmanager, welcher sehr gut für Teams geeignet ist, durch die Funktion, diff --git a/docs/services/pgAdmin4.md b/docs/C._Services/pgAdmin4.md similarity index 98% rename from docs/services/pgAdmin4.md rename to docs/C._Services/pgAdmin4.md index 631d72f7..9daeff99 100644 --- a/docs/services/pgAdmin4.md +++ b/docs/C._Services/pgAdmin4.md @@ -1,3 +1,9 @@ +--- +tags: + - Database +hide: + - tags +--- # pgAdmin 4 Eine webbasierte Datenbank Visualisierungs- und Bearbeitungssoftware. diff --git a/docs/services/postgresql.md b/docs/C._Services/postgresql.md similarity index 88% rename from docs/services/postgresql.md rename to docs/C._Services/postgresql.md index 6755ca73..0f147e7e 100644 --- a/docs/services/postgresql.md +++ b/docs/C._Services/postgresql.md @@ -1,3 +1,9 @@ +--- +tags: + - Database +hide: + - tags +--- # PostgreSQL Eine SQL basierte relationale Datenbank. diff --git a/docs/services/privatebin.md b/docs/C._Services/privatebin.md similarity index 97% rename from docs/services/privatebin.md rename to docs/C._Services/privatebin.md index 890c2ac9..770a7048 100644 --- a/docs/services/privatebin.md +++ b/docs/C._Services/privatebin.md @@ -1,3 +1,9 @@ +--- +tags: + - Zusammenarbeit +hide: + - tags +--- # Privatebin PrivateBin ist eine Open-Source-Webanwendung, welche die sichere gemeinsame Nutzung von Text- und Dateiinhalten ermöglicht, diff --git a/docs/services/psono.md b/docs/C._Services/psono.md similarity index 99% rename from docs/services/psono.md rename to docs/C._Services/psono.md index c9c42548..72515b8f 100644 --- a/docs/services/psono.md +++ b/docs/C._Services/psono.md @@ -1,3 +1,9 @@ +--- +tags: + - "Password Manager" +hide: + - tags +--- # Psono Psono ist ein self-hosted open source passwort manager. Er auf einfache User Erfahrung optimiert und ist sehr simpel diff --git a/docs/services/seafile.md b/docs/C._Services/seafile.md similarity index 98% rename from docs/services/seafile.md rename to docs/C._Services/seafile.md index ae29fa38..64dbbc43 100644 --- a/docs/services/seafile.md +++ b/docs/C._Services/seafile.md @@ -1,3 +1,9 @@ +--- +tags: + - Cloud +hide: + - tags +--- # Seafile Seafile ist eine sichere, Open-Source-Plattform für die Synchronisation, Freigabe und Zusammenarbeit von Dateien, die diff --git a/docs/services/sharelatex.md b/docs/C._Services/sharelatex.md similarity index 99% rename from docs/services/sharelatex.md rename to docs/C._Services/sharelatex.md index 360bf5ba..12f3bc4e 100644 --- a/docs/services/sharelatex.md +++ b/docs/C._Services/sharelatex.md @@ -1,3 +1,9 @@ +--- +tags: + - Zusammenarbeit +hide: + - tags +--- # ShareLaTeX Eine selbst gehostete Version von [Overleaf](https://overleaf.com) diff --git a/docs/services/syncthing.md b/docs/C._Services/syncthing.md similarity index 96% rename from docs/services/syncthing.md rename to docs/C._Services/syncthing.md index 9789fbef..59beb27b 100644 --- a/docs/services/syncthing.md +++ b/docs/C._Services/syncthing.md @@ -1,3 +1,9 @@ +--- +tags: + - "Datenverwaltung / Datenvisualisierung" +hide: + - tags +--- # Syncthing Software zum Synchronisieren und Versionieren von Dateien. diff --git a/docs/services/teamspeak.md b/docs/C._Services/teamspeak.md similarity index 98% rename from docs/services/teamspeak.md rename to docs/C._Services/teamspeak.md index a8606b32..a3c1d6e0 100644 --- a/docs/services/teamspeak.md +++ b/docs/C._Services/teamspeak.md @@ -1,3 +1,9 @@ +--- +tags: + - Communication +hide: + - tags +--- # TeamSpeak TeamSpeak ist eine Voice-over-IP-Software, die es Benutzern ermöglicht, über das Internet miteinander zu kommunizieren. diff --git a/docs/services/vaultwarden.md b/docs/C._Services/vaultwarden.md similarity index 98% rename from docs/services/vaultwarden.md rename to docs/C._Services/vaultwarden.md index 9f468b08..8e20d28a 100644 --- a/docs/services/vaultwarden.md +++ b/docs/C._Services/vaultwarden.md @@ -1,3 +1,9 @@ +--- +tags: + - "Password Manager" +hide: + - tags +--- # Vaultwarden Vaultwarden ist eine Open-Source-Serveranwendung für das sichere Speichern und Verwalten von Passwörtern und anderen diff --git a/docs/services/wordpress.md b/docs/C._Services/wordpress.md similarity index 98% rename from docs/services/wordpress.md rename to docs/C._Services/wordpress.md index 5d5f8586..042e4ff3 100644 --- a/docs/services/wordpress.md +++ b/docs/C._Services/wordpress.md @@ -1,3 +1,9 @@ +--- +tags: + - CMS +hide: + - tags +--- # WordPress Ein CMS (Content-Management-System) zum einfachen Verwalten und erstellen von Websites. diff --git a/docs/contribution.md b/docs/contribution.md new file mode 100644 index 00000000..5c4de40a --- /dev/null +++ b/docs/contribution.md @@ -0,0 +1,37 @@ +# Contribution + +Feel free to open issues / pull requests. Please validate that your changes work as intented! +You can start the mkdocs development server by running `mkdocs serve`. + +## Contribution Guidelines +- Web Services are exposed to `[::1]:8000` +- Secret Environment Variables are in an env_file (and not in the `docker-compose.yml` itself, to prevent leaks) with the following format: + ```shell + # .servicename.env + KEY=value + ``` +- environment variables should be in form of a YAML array, not an object: + ```yaml + environment: + - "KEY=value" + ``` + instead of + ```yaml + # WRONG - please don't do this + environemnt: + KEY: value + # WRONG + ``` +- If possible the service should use either mariadb or postgresql. + If it makes sense, other databases (e.g. sqlite) are also quiet fine. +- YAML arrays should be quoted, regardless which data is stored: + ```yaml + volumes: + - "/srv/service_name/data:/data" + ports: + - "[::1]:8000:1234" + networks: + - "default" + - "database" + ``` +- All domain examples should end in `domain.de` diff --git a/docs/img/installation/cloudflare_origin-cert.png b/docs/img/installation/cloudflare_origin-cert.png deleted file mode 100644 index 40bf2011..00000000 Binary files a/docs/img/installation/cloudflare_origin-cert.png and /dev/null differ diff --git a/docs/img/installation/cloudflare_origin-cert2.png b/docs/img/installation/cloudflare_origin-cert2.png deleted file mode 100644 index c9c5a4cd..00000000 Binary files a/docs/img/installation/cloudflare_origin-cert2.png and /dev/null differ diff --git a/docs/img/installation/cloudflare_origin-pull.png b/docs/img/installation/cloudflare_origin-pull.png deleted file mode 100644 index 9239414b..00000000 Binary files a/docs/img/installation/cloudflare_origin-pull.png and /dev/null differ diff --git a/docs/img/installation/cloudflare_strict-tls.png b/docs/img/installation/cloudflare_strict-tls.png deleted file mode 100644 index 3e3ca4d3..00000000 Binary files a/docs/img/installation/cloudflare_strict-tls.png and /dev/null differ diff --git a/docs/img/internal_networks.drawio b/docs/img/internal_networks.drawio deleted file mode 100644 index 73c78d18..00000000 --- a/docs/img/internal_networks.drawio +++ /dev/null @@ -1 +0,0 @@ -7Vpbd6M2EP41fsweLobAoy/Jpm1229QPzfZNARm0xYgK+dZfXwkkQFx82YDj3Q0nx0GjQcD3jWZGI0bmbLX7SEASfsI+jEaG5u9G5nxksMNhv1ywzwW66eaCgCBfiErBAv0HhVAT0jXyYaooUowjihJV6OE4hh5VZIAQvFXVljhS75qAADYECw9ETelfyKdhLnUsrZQ/QBSE8s66JnpWQCoLQRoCH28rIvNuZM4IxjQ/W+1mMOLYSVzy6+47eosHIzCmp1yQBM+fLfj3k/llG3/Fz78/Pb78dmPno2xAtBYvLB6W7iUCBK9jH/JBtJE53YaIwkUCPN67ZZQzWUhXEWvp7HSJomiGI0xYO8YxU5r6IA2zy7N+HFPZPzLMZXYweUoJ/gdWejTNvpuwV5k2X1O8+QYSCncVkXjtjxCvICV7piKNUBqTsMGxaG5LQnVXyMIqmZI6IIwoKIYucWYnAuozYL89DjuM/Qm3X9byIpCmyFORVmnpRAn6in13YnSjfdDHhqvgpDdxslpgkjICI0DRRp04bdCJh/gDI/awxRMUaIu7OzXwU7wmHhQXVe28Po57eBwKSADpgXGkIl4uU6joZFwX2H07/YbVpJvxtBBNTGiIAxyD6K6U1ggvdR4xToRNfIWU7oUPBWuKVYuBO0SfK+df+FAfLNGa78TIWWMvGzF70+dqo3IVb5aXZS15HZ/n4kF0I+strFm4BSa5Rxy2w/abs34AS11MnZzWQ4rmiTPiPDtmrwX2FYWEW1HabeaF91HNs8ua6+q2VjPI/P69mqeEVHFPdkQFr4rh2v+usey4STPGJ0xBN5Jd2cnOAv4/DlC8k0OxR8tHy/sOxB39hLhTsTetFod4nAG2o2ltcWZ2a1qatFgl/vCjn/hT90i3Tb86bvGrg0UfORN65/eBz6059t6CYmh6HRRPNXdwio0axVaT4tuLUjx+NcVOG8Mja8p72Z81Z7/jsXkq1wxIqhKqEiXCQksCCSIUxKwZwSUfgZOCWII+EeIV8v0sQLbZjxo0lVS0j4ntqKy7ToN1sy2vHIz1tnS+j4m9gGSDGK4/nes2akmp7ton5cTDTey2pUMfFM+YEkAxJD+h83aOk2xflGS3k+SXko8+WH+EAUvEOykvxC9X7dcr1uUMUzLQW3I2p821WwOZhKwQDBbQ9TyiO3xWXSykkxy5a4rpxUxXF1xvFtON1yfrpxKvvxOvVL/emnm7AfwFq0SyFHRWlUgfXWmVyBDroeNVIuFnr6xK5LpVczqzqDRMlch4/RKzPSf5zLyLF+F1d1ry42ai9dq123BBFy0jGEOtNjZ8Rfkta41T9qAOMCzcSvd2U9cGVd/RxrSubGEpN2pP3JMSQHZuSNVdeydkRx3tZXafGgm/Y6tDnLr9NNaODNSx/9SbW25bO77zeDaP9YEM47I8mnqTtivfI7za7E+m7UezP5nTvHH2Z9YLUuPDm4R1fTVbHCb9M1vcyrt9Dr06uY497MP2dlT9EnvYcsr3nrl+AgSB+fR9baKbzfrIUIsT99fF0p/cU22iB9sntNpYD3/e6A2Gf4kpJLH4ZkfxTFGEkjTL/EOQcGG+wDzKSAdILVB24lZbmrd9fGa0wFb/bKk32IYuJMty4ne+Mfwqzusbwy3r+J5KiaxZfkKaO8/yO1zz7n8= \ No newline at end of file diff --git a/docs/img/internal_networks.png b/docs/img/internal_networks.png deleted file mode 100644 index a79a7e45..00000000 Binary files a/docs/img/internal_networks.png and /dev/null differ diff --git a/docs/img/schaubild_cloudflare-vs-transparent-proxy.drawio b/docs/img/schaubild_cloudflare-vs-transparent-proxy.drawio deleted file mode 100644 index 4eef4d5e..00000000 --- a/docs/img/schaubild_cloudflare-vs-transparent-proxy.drawio +++ /dev/null @@ -1 +0,0 @@ -7Vpbb5swFP41kbaHVtxCyGOSppdpnaK1054dcIhVB2fGue3X7wCGxJisbVbCRCtVFT7YB/v7/Nk+x+nYo8X2hqPl/J4FmHYsI9h27KuOZbm9HvxPDLvM4Jh2Zgg5CTKTuTc8kN9YGg1pXZEAx0pFwRgVZKkafRZF2BeKDXHONmq1GaPqV5coxJrhwUdUt/4kgZhnVq9r7O23mITz/MumId8sUF5ZGuI5CtjmwGSPO/aIMyayp8V2hGmCXY5L1u76yNuiYxxH4iUNvuEv7uPdzdyhP8b99f1Tj/ZvL6SXNaIrOeCBLxiXPRa7HAbo/DJ5XC1oVsEerjEXBID6iqaYTlhMBGERVJkyIdjioMKAkjB5IdgSrHOxoFAw4ZGtBCURHhXUGWCUHYK2eHt0pGaBH8w7zBZY8B1UkQ0cifhOLW72/NnSND+gzpU2JGdMWPjdgwoPEtdXYGy9A4wto2GQbQ3kEWWrYEZhRB3LpfD94RQwd8PkacLZdqcRAJ+BZQUKw5wKP/EB5c2cCPywRH5i3MBCp4L8BngWAB6ftKZVAahXF6COBuiYhDjCXEdTcBTF2VCrXv//YJvdptF2NbR1wKJgkGxoKVIojomv4sLZKgpwoEgcB9ruVsIItlPEQyyek5aO5QFW3QqochvHFAmyVrtRhZ/8woQR6GBBlacyVSYgZivuY9nmcPMruTFLfvolPxkImp+Uy2LMp9Pb0+i9m6xBYdALYMqAgqvzDdyl675KM5IrvZ+pTd8CFiQIEh9DjmPyG01Tf8mUWCajS8fbHXa6V3+TkjxNycbF0UKZPsfn8VHdGZdWTxXem8yRC9NVvOZw5x7YbBbjWnj1mpJtU3K0LVVHvf6ld5oiHec5TzVrsl+lyZbI0HtfMsyDxfejw9J2VhwXX6tC7SR05o3R1APQbGdsgwpNo3qKtFaGeqT7IcOTNkPNUd0y1MPn9myG2bQ8vwytvqrD/tl0qMfuLddh+Vhqem92Lj27FLttlqLTiBQ9VYg5xGdQop7X+Y4B0BiDUebFyumyT48c4Rl5SrMD1/A/Ckm0/axNgL1CzbMkzcrCyFO5hzkzo0LiZf28Wc7M1LMqOZozlvK/R8v9tWL5i4s4vWUaQAVvuU3ByV/nHCQSgArwlwhh4Dh27hl6mjmXFcusAL5ChT4WnD3hEaNJRv8qYlEivhmhtGR6uXKruK5ar/+NblOl27M1uqsS/GZtbOu5ltZIqVhAm9OSng350FJtWrKchsVk6WF3++4k7QpVnffiV4+HW7Nk2VUXlGddsiw9ZtVQaleUU8o22N3+Zc9VnZwa5VT5qjnQsfQotbgUSyZ+e6Ie68gNas1Rj9NU/sHSQ9iPw0Rthwnbre0wAcX979Oy2bH/kZ89/gM= \ No newline at end of file diff --git a/docs/img/schaubild_cloudflare-vs-transparent-proxy.png b/docs/img/schaubild_cloudflare-vs-transparent-proxy.png deleted file mode 100644 index c7489d1e..00000000 Binary files a/docs/img/schaubild_cloudflare-vs-transparent-proxy.png and /dev/null differ diff --git a/docs/img/services/element_cf_pages_1.jpg b/docs/img/services/element_cf_pages_1.jpg deleted file mode 100644 index 15bb6b4a..00000000 Binary files a/docs/img/services/element_cf_pages_1.jpg and /dev/null differ diff --git a/docs/img/services/status_cf_pages_1.png b/docs/img/services/status_cf_pages_1.png deleted file mode 100644 index 459f1b04..00000000 Binary files a/docs/img/services/status_cf_pages_1.png and /dev/null differ diff --git a/docs/img/services/status_example_1.png b/docs/img/services/status_example_1.png deleted file mode 100644 index dafa0f88..00000000 Binary files a/docs/img/services/status_example_1.png and /dev/null differ diff --git a/docs/index.md b/docs/index.md index 2792b3b6..a65a4717 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,10 +1,9 @@ # Startseite -Diese Informationssammlung beschreibt das von mir eingesetzten Verfahren zum -Aufsetzen eines Linux Servers mit Anwendungen in Docker Containern. Hauptsächlich -handelt es sich in meinem Fall um webbasierte Anwendungen. Diese werden mit einem -Reverse Proxy ([Traefik](https://traefik.io/) als Docker Container, oder -[nginx](https://www.nginx.com/) auf dem Host) erreichbar gemacht. +Diese Informationssammlung beschreibt ein mögliches Verfahren zum Aufsetzen eines +Linux Servers mit Anwendungen in Docker Containern. Die meisten hier vorgestellten +Anwendungen sind webbasiert und werden über einen Reverse Proxy aus dem Internet +erreichbar gemacht. ## Lokales HTTP Routing Nachdem die Anfragen den Reverse Proxy auf unserem eigenen Host erreicht haben, werden @@ -13,14 +12,15 @@ an den Container weitergeleitet, der den Dienst bereitstellt. ## Verzeichnisstruktur Jeder bereitgestellte Dienst erhält zwei Verzeichnisse: -1. Im Verzeichnis `/home/admin/` liegt die Containerdefinition (`docker-compose.yml`), + +1. Im Verzeichnis `/home/admin/` liegt die Container-Definition (`docker-compose.yml`), 2. die Daten des Dienstes werden im Verzeichnis `/srv/` gespeichert. ### Umgebungsvariablen Schützenswerte Umgebungsvariablen (Passwörter, API Tokens, ...) werden nicht in der Containerdefinition abgelegt, sondern in einer separaten `env`-Datei, um die Gefahr einer Offenlegung dieser (z. B. beim Teilen des Bildschirms) zu reduzieren. Diese werden entsprechend -des Container-Namen im docker-compose Kontext benannt. +des Container-Namen im docker compose Kontext benannt. Im folgenden Beispiel-Dienst (`service: example`, `service_name: example_srv`) würde die `env`-Datei unter dem Pfad `/home/admin/example/.example_srv.env` angelegt werden. diff --git a/docs/installation/05_base.md b/docs/installation/05_base.md deleted file mode 100644 index 8ee9a57b..00000000 --- a/docs/installation/05_base.md +++ /dev/null @@ -1,234 +0,0 @@ -# Basisinstallation - -Jeder, der diese Informationssammlung nutzt, sollte in der Lage sein, seinen -Linux Server grundlegend einzurichten und abzusichern. Daher verzichte ich hier -auf Standardanleitungen und stelle lediglich die spezifischen Konzepte vor. - -## Admin Gruppe - -Ich gehe grundsätzlich davon aus, dass ich auf keinem System der alleinige -Administrator bin, weshalb auf allen Systemen eine Admin-Gruppe existiert, -die Rechte auf das Verzeichnis `/home/admin` hat. - -```shell -groupadd -g 1100 admin -mkdir -m 775 /home/admin -chown root:admin /home/admin -``` - -Die personalisierten Accounts der Systemadministratoren erhalten neben der `sudo` -Gruppenmitgliedschaft auch die Gruppe `admin`: - -```shell -adduser nicof2000 -usermod -aG sudo,admin nicof2000 -``` - -## Docker - -Die Installation von Docker ist in der offiziellen [Dokumentation](https://docs.docker.com/engine/install/debian/) -bereits sehr gut beschrieben. Zusätzlich richten wir einen Alias ein, -um uns die wiederholte Eingabe von sudo docker compose zu ersparen. -```shell -curl -fsSL https://get.docker.com | sudo bash -echo 'alias dc="sudo docker compose "' >> ~/.bashrc -``` - -## Proxy und Reverse Proxy - -In den folgenden Kapiteln werden die sechs möglichen Kombinationen vorgestellt. - -Welche der Konfigurationen man verwendet, ist jedem selbst überlassen. - -### Meine Geschichte - -Vielleicht hilft euch meine Geschichte, welche beschreibt, warum ich diese verschiedenen Verfahren einsetze. Früher -hatte ich einen kleinen Cloudserver, welcher sowohl über eine IPv4 Adresse als auch ein /64er IPv6 Netz verfügte. Auf -diesem Server lief letzten Endes eine Vorgängerversion des hier beschriebenen Konzepts. - -Im weiteren Verlauf, administrierte ich einen dedizierten Server, der ebenfalls über eine IPv4 Adresse und ein /64er -IPv6 Netz verfügte. Da auf diesem jedoch mehrere virtuelle Maschinen betrieben werden sollten, musste ich mir eine -Möglichkeit überlegen, wie ich das HTTP Routing für Clients, die über IPv4 kamen gestaltete. - -Zunächst verwendete ich dafür einen zentralisierten Reverse Proxy, welcher alle HTTP Requests annahm und dann zu den -jeweils verantwortlichen virtuellen Maschinen weiterleitete. Dort wurde ein weiterer Reverse Proxy betrieben, welcher -sich um das HTTP Routing zu den einzelnen Docker Containern kümmerte. - -Dies hatte den großen Nachteil, dass zwangsläufig ein weiterer Reverse Proxy im Einsatz war, um die richtige virtuelle -Maschine zu adressieren. Für das Aufsetzen eines neuen Dienstes war plötzlich ein weiterer Schritt auf einer anderen -Maschine notwendig. - -Zu einem späteren Zeitpunkt erhielten weitere Administratoren für eigene virtuelle Maschinen Zugriff auf diesen -dedizierten Server. Da ich diesen den Zugriff auf den Reverse Proxy, welcher das Routing zu den virtuellen Maschinen -verwehren wollte, verwendete ich zunächst nur auf IPv6 exposierte Web-Server in Verbindung mit Cloudflare Proxy, um -die IPv4 Erreichbarkeit zu sichern und zusätzlich weitere Schutzmaßnahmen (z. B. Denial of Service Schutz) für diesen -dedizierten Server in Anspruch zu nehmen. - -Spätestens seit Zensus -2022, [bei dem das Statistische Bundesamt durch die Verwendung des Cloudflare Proxies in Verruf geriet](https://www.kuketz-blog.de/zensus-2022-statistisches-bundesamt-hostet-bei-cloudflare/), -ist klar, dass auch die Verwendung des Cloudflare Proxys aus Privatsphäre-Gründen bedenklich ist (die übermittelten -Daten stehen Cloudflare unverschlüsselt zur Verfügung, da der Cloudflare Proxy die TLS Verbindung terminiert). - -Vor allem durch unsicherheiten hinsichtlich -der [Abmahnwelle wegen Google Fonts](https://www.heise.de/news/DSGVO-Abmahnwelle-wegen-Google-Fonts-7206364.html) im -selben Jahr, konfigurierte ich mir einen eigenen (transparenten) Proxy, um zumindest für die IPv4 Erreichbarkeit eine -Alternative zu Cloudflare in der Hinterhand haben zu können. - -Die Idee hinter diesem Proxy ist extrem einfach: Im DNS stehen für IPv6 (DNS AAAA-Record) die Adressen des eigentlichen -Webservers, sodass die Nutzer sich direkt mit diesem Verbinden können. Falls die Nutzer über keine IPv6 Konfiguration -verfügen, nutzen Sie den im IPv4 (DNS A-Record) hinterlegten IPv4-to-IPv6 Proxy, der die Anfragen dann über IPv6 -weiterleitet, OHNE die TLS Verbindung zu terminieren. Dies hat den Vorteil das keine TLS Zertifikate benötigt werden. - -### IPv4-to-IPv6 Proxy - -Dieser einfache IPv4-to-IPv6 Proxy unterstützt in seiner ersten Version lediglich HTTP Verbindungen auf Port 80 und TLS -Verbindungen auf Port 443. Eine Anpassung dieser Konfiguration um einige anderen Protokolle (SMTPs, IMAPs, POP3s) welche -TLS verwenden zu unterstützten ist denkbar. - -Aus Gründen der Vollständigkeit hier einmal die nginx Konfiguration für den Proxy für Alpine Linux. Die Einrichtung ist -denkbar einfach: nginx installieren, die untenstehende Konfiguration kopieren und den Proxy starten: - -```nginx -user nginx; -worker_processes auto; - -error_log /var/log/nginx/error.log notice; -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - access_log /var/log/nginx/access.log main; - - sendfile on; - keepalive_timeout 65; - - server { - listen 80 default_server; - location / { - return 301 https://$host$request_uri; - } - } -} - -stream { - # https://gist.github.com/kekru/c09dbab5e78bf76402966b13fa72b9d2#non-terminating-tls-pass-through - server { - listen 443; - - proxy_connect_timeout 1s; - proxy_timeout 3s; - - resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] ipv6=on ipv4=off; - - proxy_pass $ssl_preread_server_name:443; - ssl_preread on; - } -} -``` - -### Vergleich der Möglichkeiten - -![Schaubild](../img/schaubild_cloudflare-vs-transparent-proxy.png){: loading=lazy } - -Aus meiner Sicht ergibt die Verwendung eines eigenen vorgeschaltenen Proxies nur Sinn, wenn mehr als ein -Server administriert wird und die Web-Server über IPv6 Adressen exposiert bereitstellt werden. - -Wird lediglich ein System betreut (wie z.B. der oben erwähnte Cloudserver), kann die zugewiesene IPv4 -Adresse natürlich ebenfalls auf den Ports 80 und 443 verwendet werden und dann auf den Reverse Proxy -zeigen. Dadurch entfällt die Abhängigkeit zu anderen Systemen. - -Sofern der Cloudserver über keine eigene IPv4 Adresse oder keine -eigenen IPv6 Adressen verfügt, sollte ein Proxy vorgeschaltet werden, -um den Nutzern, die keine IPv4/IPv6 Adresse verfügen den Zugriff zu -ermöglichen. - -Wird Cloudflare Proxy verwendet erkauft man sich neben der Erreichbarkeit -diverse Vorteile (DDoS Protection, -[Web Application Firewall](https://developers.cloudflare.com/waf/managed-rules/), -[Page Rules](https://www.cloudflare.com/features-page-rules/)). - -Jedoch sollte man einige Details beachten, bevor man sich auf Cloudflare festlegt. -Der Datenverkehr der Nutzer liegt bei Cloudflare unverschlüsselt vor, da diese die -TLS Pakete terminieren. In der kostenfreien Version von Cloudflare Proxy können -des Weiteren keine gestackten Subdomains (`sub.sub.domain.de`) eingerichtet werden, -da dafür kein TLS Zertifikat angefordert werden kann. - -### Reverse Proxy - -Sowohl nginx als auch Traefik, sind beide stark verbreitete Proxies. Sie werden von -großen Unternehmen wie Google, Cloudflare, Dropbox und Mozilla verwendet. Ich habe -mich nach reichlicher Überlegung dazu entschieden beide Varianten vorzustellen, da -sowohl Traefik, als auch nginx ihre Vorteile haben. - -!!! info "" - Hinsichtlich Traefik betrachten wir lediglich den dynamischen Modus, - bei dem das HTTP Routing über die Docker Labels konfiguriert wird. - -Die Ersteinrichtung von Traefik empfinde ich, vor allem auf den ACME Client bezogen, -als schwieriger als die von nginx. Mit nginx wird acme.sh (ein separates Skript) -zum Ausstellen der TLS Zertifkate verwendet, während dies bei Traefik integriert ist. - -Im weiteren Verlauf des Betriebs eines Systems mit Reverse Proxy bedeutet nginx einen -höheren Konfigurationsaufwand als Traefik, da die nginx Virtual Host Konfiguration anders -als bei Traefik nicht innerhalb der Containerdefinition erfolgt und die Zertifikate ggf. -manuell über acme.sh ausstellen werden müssen. - -Traefik bringt des Weiteren ein Dashboard mit, welches einen komfortablen Überblick über -die existierenden Services und Router gibt. Dieses Dashboard sollte natürlich, sofern extern -erreichbar, entsprechend geschützt sein, um das ungewollte Leaken von Informationen zu vermeiden. - -Einer der wichtigsten Aspekte für die Wahl des Reverse Proxies ist aber möglicherweise, dass -Traefik Zugriff auf den Docker Socket des Hosts benötigt, um die Container Labels auslesen zu können, -und die HTTP Routen dynamisch zu generieren. Im Falle einer Sicherheitslücke, bei der, der Traefik -Container übernommen werden kann, bedeutet dies, dass der gesamte Server komprimiert ist, da -beispielsweise ein neuer Container erstellt werden kann, bei dem das Host-Dateisystem komplett -eingehängt ist. - -=== "nginx" - Da nginx nicht als Docker Container bereitgestellt wird, sondern direkt auf dem Host - installiert wird, gilt hier eine andere Verzeichnisstruktur. - - Die "Virtual-Host" Konfigurationsdateien liegen im Verzeichnis `/etc/nginx/sites-available/` - unter der Domain, die Sie erreichbar machen. - - TLS Zertifikate beziehe ich mithilfe des Shellskriptes [`acme.sh`](https://github.com/acmesh-official/acme.sh), - welches ich unter dem root-Nutzer laufen lasse. Die resultierenden privaten Schlüssel - und Zertifkate werden im Verzeichnis `/root/.acme.sh/` gespeichert und direkt von - dort in der nginx Virtual-Host Konfiguration eingebunden. - -=== "Traefik" - Da Traefik als Docker Container bereitgestellt wird, gilt die oben genannte Verzeichnisstruktur: - - * Containerdefinition: `/home/admin/traefik/docker-compose.yml` - * Env-Vars (hier DNS API Token): `/home/admin/traefik/.traefik.env` - * Daten (z.B. TLS Zertifikate): `/srv/traefik` - - Traefik verwendet als ACME Client [Lego](https://go-acme.github.io/lego/). Die Konfiguration dieses - kann der [Traefik Dokumentation](https://doc.traefik.io/traefik/https/acme/) entnommen werden. - Die angeforderten Zertifikate und Privaten Schlüssel werden im `/srv/traefik` Volume des Traefik - Containers gespeichert. - -!!! note "" - In komplexeren Server-Infrastrukturen kann es sinnvoll sein, jedem Virtual Host eine - eigene dedizierte IPv6 Adresse zuzuweisen. Dies hat den großen Vorteil, das man z. B. - die Firewall Logs auf Layer 3 auswerten kann, statt den [TLS SNI Header]( - https://en.wikipedia.org/wiki/Server_Name_Indication) zu betrachten, um den beteiligten - Webserver in Erfahrung zu bringen. - Da ich in diesen Netzwerken bisher immer auf nginx gesetzt habe, - habe ich nie geprüft, ob Traefik dieses Feature (jedem HTTP Router - eine eigene IPv6 Adresse zuzuweisen) ebenfalls unterstützt. - -Prinzipiell ist die genutzte [ACME Challenge](https://letsencrypt.org/docs/challenge-types/) irrelevant, da ich -auch interne Dienste betreibe, die nicht aus dem Internet erreichbar sind, verwende ich prinzipiell die ACME-DNS-01 -Challenge. Sowohl [Traefik / Lego](https://doc.traefik.io/traefik/https/acme/#providers) als auch -[`acme.sh`](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) unterstützten eine Vielzahl an DNS API's diff --git a/docs/installation/10_nginx.md b/docs/installation/10_nginx.md deleted file mode 100644 index 25e9eeb0..00000000 --- a/docs/installation/10_nginx.md +++ /dev/null @@ -1,60 +0,0 @@ -# nginx ohne Proxy - -Wenn nginx ohne vorgeschalteten Proxy eingesetzt werden soll, benötigt man TLS Zertifikate, welche im -Browser validiert werden können. - -{% include-markdown "../../includes/installation/nginx_base.md" %} - -### nginx Virtual-Host konfigurieren und aktivieren -Anschließend wird die Virtual Host Konfiguration unter dem Pfad -`/etc/nginx/sites-available/domain` angelegt. Dabei müssen hauptsächlich die -mit Pfeil markierten Zeilen beachtet werden. -```nginx -# https://ssl-config.mozilla.org/#server=nginx&version=1.27.3&config=modern&openssl=3.4.0&ocsp=false&guideline=5.7 -server { - server_name service.domain.de; # <--- - listen 0.0.0.0:80 http2; - listen [::]:80 http2; # <--- - - location / { - return 301 https://$host$request_uri; - } -} - -server { - server_name service.domain.de; # <--- - listen 0.0.0.0:443 ssl http2; - listen [::]:443 ssl http2; # <--- - - ssl_certificate /root/.acme.sh/service.domain.de_ecc/fullchain.cer; - ssl_certificate_key /root/.acme.sh/service.domain.de_ecc/service.domain.de.key; - ssl_session_timeout 1d; - ssl_session_cache shared:MozSSL:10m; # about 40000 sessions - ssl_session_tickets off; - - # modern configuration - ssl_protocols TLSv1.3; - ssl_prefer_server_ciphers off; - - # HSTS (ngx_http_headers_module is required) (63072000 seconds) - add_header Strict-Transport-Security "max-age=63072000" always; - - # OCSP stapling - ssl_stapling on; - ssl_stapling_verify on; - - location / { - proxy_pass http://[::1]:8081/; # <--- - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } -} -``` - -{% include-markdown "../../includes/installation/nginx_enable_test_apply_vhost.md" %} diff --git a/docs/installation/11_nginx_cloudflare.md b/docs/installation/11_nginx_cloudflare.md deleted file mode 100644 index 52b0d000..00000000 --- a/docs/installation/11_nginx_cloudflare.md +++ /dev/null @@ -1,126 +0,0 @@ -# nginx mit Cloudflare Proxy - -Wird der Reverse Proxy nur hinter Cloudflare erreichbar gemacht, können [Origin Server Zertifikate]( -https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/) verwendet werden. Solche -werden zwar vom Browser als ungültig angesehen, dies ist jedoch, aufgrund des vorgeschalteten Cloudflare Proxies, -irrelevant. Da diese Zertifikate von Cloudflare selbst ausgestellt werden, können die TLS Einstellungen -der Domain dennoch auf "Full (Strict)" gesetzt werden: - -![Cloudflare Full (Strict) TLS Settings](../img/installation/cloudflare_strict-tls.png){: loading=lazy } - -Die Ausstellung der Zertifikate über das Cloudflare Dashboard kann den folgenden Screenshots entnommen werden: -![Cloudflare Origin Server Zertifikatserstellung](../img/installation/cloudflare_origin-cert.png){: loading=lazy } -![Cloudflare Origin Server Zertifikatserstellung](../img/installation/cloudflare_origin-cert2.png){: loading=lazy } - -Die entstehenden Privaten Schlüssel und Zertifikate werden im Verzeichnis `/etc/ssl/` auf dem Server gespeichert. - -Anschließend wird nginx auf dem Server installiert - -```shell -apt install nginx-full -``` - -## Authenticated Origin Pulls - -Um zu verhindern, das direkte Anfragen an den Webserver gestellt werden können (ohne -über Cloudflare Proxy zu gehen) kann der nginx so konfiguriert werden, dass ein mTLS -Zertifikat benötigt wird, welches von der "Cloudflare Origin Pull CA" signiert wurde. - -```shell -wget -O /etc/ssl/cloudflare_ca.crt \ - https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem -``` - -In jedem nginx Virtual-Host müssen dafür folgende Zeilen zum Server Block hinzugefügt werden: - -```nginx -server { - # ... - - # only allow cloudflare to connect to your nginx - ssl_client_certificate /etc/ssl/cloudflare_ca.crt; - ssl_verify_client on; - - # ... -} -``` - -Die [Einrichtung bei Cloudflare ist in deren Dokumentation](https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull/set-up) -beschreiben: -![Cloudflare Origin Pull](../img/installation/cloudflare_origin-pull.png){: loading=lazy } - -{% include-markdown "../../includes/installation/nginx-multiple-ipv6.md" %} - -### Konfiguration für neue Dienste - -Folgende Schritte sind notwendig, um ein neues HTTP Routing zu konfigurieren: - -1. Dienst aufsetzen. - -2. Port-Binding von Dienst auf IPv6 Localhost (`::1`) des Hosts. - -3. Optional: Sofern für die gewünschte Domain noch kein Zertifikat existiert, dieses Ausstellen. - -4. Optional: Eigene IPv6 Adresse für Virtual Host konfigurieren. - -5. nginx Virtual-Host konfigurieren und aktivieren. - -6. Konfiguration testen und nginx neu laden. - -#### Dienst aufsetzen - -Zum Aufsetzen des Dienstes muss lediglich die jeweilige Docker-Compose Datei kopiert, ggf. angepasst und ausgeführt -werden. - -{% include-markdown "../../includes/installation/local-port-binding.md" %} - -#### Optional: Sofern für die gewünschte Domain noch kein Zertifikat existiert, dieses Ausstellen. - -siehe oben! - -{% include-markdown "../../includes/installation/additional_ipv6.md" %} - -#### nginx Virtual-Host konfigurieren und aktivieren - -Anschließend wird die Virtual Host Konfiguration unter dem Pfad -`/etc/nginx/sites-available/domain` angelegt. Dabei müssen hauptsächlich die -mit Pfeil markierten Zeilen beachtet werden. - -```nginx -# https://ssl-config.mozilla.org/#server=nginx&version=1.27.3&config=modern&openssl=3.4.0&ocsp=false&guideline=5.7 -server { - server_name service.domain.de; # <--- - listen [::]:443 ssl http2; # <--- - - ssl_certificate /etc/ssl/domain.de.pem; - ssl_certificate_key /etc/ssl/domain.de.key; - ssl_session_timeout 1d; - ssl_session_cache shared:MozSSL:10m; # about 40000 sessions - ssl_session_tickets off; - - # modern configuration - ssl_protocols TLSv1.3; - ssl_prefer_server_ciphers off; - - # HSTS (ngx_http_headers_module is required) (63072000 seconds) - add_header Strict-Transport-Security "max-age=63072000" always; - - # only allow cloudflare to connect to your nginx - ssl_client_certificate /etc/ssl/cloudflare_ca.crt; - ssl_verify_client on; - - location / { - proxy_pass http://[::1]:8081/; # <--- - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } -} -``` - -{% include-markdown "../../includes/installation/nginx_enable_test_apply_vhost.md" %} diff --git a/docs/installation/12_nginx_proxy.md b/docs/installation/12_nginx_proxy.md deleted file mode 100644 index 7ec393a6..00000000 --- a/docs/installation/12_nginx_proxy.md +++ /dev/null @@ -1,58 +0,0 @@ -# nginx mit eigenem Proxy - -Wenn nginx mit einem eigenen transparenten Proxy für IPv4 Anfragen eingesetzt werden soll, -benötigt man TLS Zertifikate, die im Browser validiert werden können. - -{% include-markdown "../../includes/installation/nginx_base.md" %} - -### nginx Virtual-Host konfigurieren und aktivieren -Anschließend wird die Virtual Host Konfiguration unter dem Pfad -`/etc/nginx/sites-available/domain` angelegt. Dabei müssen hauptsächlich die -mit Pfeil markierten Zeilen beachtet werden. -```nginx -# https://ssl-config.mozilla.org/#server=nginx&version=1.27.3&config=modern&openssl=3.4.0&ocsp=false&guideline=5.7 -server { - server_name service.domain.de; # <--- - listen [::]:80 http2; # <--- - - location / { - return 301 https://$host$request_uri; - } -} - -server { - server_name service.domain.de; # <--- - listen [::]:443 ssl http2; # <--- - - ssl_certificate /root/.acme.sh/service.domain.de_ecc/fullchain.cer; - ssl_certificate_key /root/.acme.sh/service.domain.de_ecc/service.domain.de.key; - ssl_session_timeout 1d; - ssl_session_cache shared:MozSSL:10m; # about 40000 sessions - ssl_session_tickets off; - - # modern configuration - ssl_protocols TLSv1.3; - ssl_prefer_server_ciphers off; - - # HSTS (ngx_http_headers_module is required) (63072000 seconds) - add_header Strict-Transport-Security "max-age=63072000" always; - - # OCSP stapling - ssl_stapling on; - ssl_stapling_verify on; - - location / { - proxy_pass http://[::1]:8081/; # <--- - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $host; - proxy_cache_bypass $http_upgrade; - } -} -``` - -{% include-markdown "../../includes/installation/nginx_enable_test_apply_vhost.md" %} diff --git a/docs/installation/20_traefik.md b/docs/installation/20_traefik.md deleted file mode 100644 index 76f8a16e..00000000 --- a/docs/installation/20_traefik.md +++ /dev/null @@ -1,94 +0,0 @@ -# Traefik ohne Proxy - -Zunächst wird die Containerdefinition im Verzeichnis `/home/admin/traefik/docker-compose.yml` angelegt: -```yaml -services: - traefik: - image: traefik:v2.9 - restart: always - command: - - "--api.insecure=true" - - "--metrics.prometheus=true" - #- "--log.level=DEBUG" - - "--accesslog=true" - - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--providers.docker.network=proxy" - - - "--providers.file.directory=/configs/" - - - "--entrypoints.web.address=:80" - - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - - - "--entrypoints.websecure.address=:443" - #- "--entrypoints.websecure.http.middlewares=mw_hsts@file,mw_compress@file" - - "--entryPoints.websecure.http.tls=true" - - "--entryPoints.websecure.http.tls.certresolver=myresolver" - - "--entryPoints.websecure.http.tls.domains[0].main=domain.de" - - "--entryPoints.websecure.http.tls.domains[0].sans=*.domain.de" - - - "--certificatesresolvers.myresolver.acme.dnschallenge=true" - - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" - - "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53" - - "--certificatesresolvers.myresolver.acme.dnschallenge.delayBeforeCheck=10" - - "--certificatesresolvers.myresolver.acme.email=admin@domain.de" - - "--certificatesresolvers.myresolver.acme.storage=/acme/acme.json" - #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" - labels: - - "traefik.enable=true" - - "traefik.http.services.srv_traefik.loadbalancer.server.port=8080" - - "traefik.http.routers.r_traefik.rule=Host(`traefik.domain.de`)" - - "traefik.http.routers.r_traefik.entrypoints=websecure" - env_file: .traefik.env - ports: - - "80:80" - - "443:443" - volumes: - - "/srv/traefik/acme:/acme" - - "/srv/traefik/dynamic.yml:/configs/dynamic.yml" - - "/srv/traefik/middlewares.yml:/configs/middlewares.yml" - - "/etc/localtime:/etc/localtime:ro" - - "/var/run/docker.sock:/var/run/docker.sock:ro" - networks: - - "proxy" - - static: - image: nginx:stable-alpine - restart: always - labels: - # BASIC CONFIGURATION - - "traefik.enable=true" - - "traefik.http.services.srv_static.loadbalancer.server.port=80" - - # ERROR PAGES - # you can use my error_pages: https://github.com/felbinger/AdminGuide/tree/master/error_pages - - "traefik.http.middlewares.error40x.errors.status=403-404" - - "traefik.http.middlewares.error40x.errors.service=srv_static" - - "traefik.http.middlewares.error40x.errors.query=/error/{status}.html" - - "traefik.http.middlewares.error30x.errors.status=300-308" - - "traefik.http.middlewares.error30x.errors.service=srv_static" - - "traefik.http.middlewares.error30x.errors.query=/error/30x.html" - - # DOMAIN ROOT CONTENT - - "traefik.http.routers.r_static_root.rule=HostRegexp(`domain.de`, `{subdomain:[a-z0-9]+}.domain.de`)" - - "traefik.http.routers.r_static_root.entrypoints=websecure" - - "traefik.http.routers.r_static_root.priority=10" - - "traefik.http.middlewares.mw_static_root.addprefix.prefix=/domain_root/" - - "traefik.http.routers.r_static_root.middlewares=mw_static_root@docker,error40x@docker,error30x@docker" - volumes: - - "/srv/static/webroot:/usr/share/nginx/html/" - networks: - - "proxy" - -networks: - proxy: - external: true -``` - -{% include-markdown "../../includes/installation/traefik/config.md" %} - -{% include-markdown "../../includes/installation/traefik/docker-network.md" %} - -{% include-markdown "../../includes/installation/traefik/new.md" %} diff --git a/docs/installation/21_traefik_cloudflare.md b/docs/installation/21_traefik_cloudflare.md deleted file mode 100644 index 830cf6f3..00000000 --- a/docs/installation/21_traefik_cloudflare.md +++ /dev/null @@ -1,81 +0,0 @@ -# Traefik mit Cloudflare Proxy - -Zunächst wird die Containerdefinition im Verzeichnis `/home/admin/traefik/docker-compose.yml` angelegt: -```yaml -service: - traefik: - image: traefik:v2.9 - restart: always - command: - - "--api.insecure=true" - - "--metrics.prometheus=true" - #- "--log.level=DEBUG" - - "--accesslog=true" - - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--providers.docker.network=proxy" - - - "--providers.file.directory=/configs/" - - - "--entrypoints.websecure.address=:443" - #- "--entrypoints.websecure.http.middlewares=mw_hsts@file,mw_compress@file" - - "--entryPoints.websecure.http.tls=true" - - "--entryPoints.websecure.http.tls.certresolver=myresolver" - - "--entryPoints.websecure.http.tls.domains[0].main=domain.de" - - "--entryPoints.websecure.http.tls.domains[0].sans=*.domain.de" - labels: - - "traefik.enable=true" - - "traefik.http.services.srv_traefik.loadbalancer.server.port=8080" - - "traefik.http.routers.r_traefik.rule=Host(`traefik.domain.de`)" - - "traefik.http.routers.r_traefik.entrypoints=websecure" - env_file: .traefik.env - ports: - - "[::]:443:443" - volumes: - - "/srv/traefik/acme:/acme" - - "/srv/traefik/dynamic.yml:/configs/dynamic.yml" - - "/srv/traefik/middlewares.yml:/configs/middlewares.yml" - - "/etc/localtime:/etc/localtime:ro" - - "/var/run/docker.sock:/var/run/docker.sock:ro" - networks: - - "proxy" - - static: - image: nginx:stable-alpine - restart: always - labels: - # BASIC CONFIGURATION - - "traefik.enable=true" - - "traefik.http.services.srv_static.loadbalancer.server.port=80" - - # ERROR PAGES - # you can use my error_pages: https://github.com/felbinger/AdminGuide/tree/master/error_pages - - "traefik.http.middlewares.error40x.errors.status=403-404" - - "traefik.http.middlewares.error40x.errors.service=srv_static" - - "traefik.http.middlewares.error40x.errors.query=/error/{status}.html" - - "traefik.http.middlewares.error30x.errors.status=300-308" - - "traefik.http.middlewares.error30x.errors.service=srv_static" - - "traefik.http.middlewares.error30x.errors.query=/error/30x.html" - - # DOMAIN ROOT CONTENT - - "traefik.http.routers.r_static_root.rule=HostRegexp(`domain.de`, `{subdomain:[a-z0-9]+}.domain.de`)" - - "traefik.http.routers.r_static_root.entrypoints=websecure" - - "traefik.http.routers.r_static_root.priority=10" - - "traefik.http.middlewares.mw_static_root.addprefix.prefix=/domain_root/" - - "traefik.http.routers.r_static_root.middlewares=mw_static_root@docker,error40x@docker,error30x@docker" - volumes: - - "/srv/static/webroot:/usr/share/nginx/html/" - networks: - - "proxy" - -networks: - proxy: - external: true -``` - -{% include-markdown "../../includes/installation/traefik/config.md" %} - -{% include-markdown "../../includes/installation/traefik/docker-network.md" %} - -{% include-markdown "../../includes/installation/traefik/new.md" %} diff --git a/docs/installation/22_traefik_proxy.md b/docs/installation/22_traefik_proxy.md deleted file mode 100644 index 60d3a6b5..00000000 --- a/docs/installation/22_traefik_proxy.md +++ /dev/null @@ -1,94 +0,0 @@ -# Traefik mit eigenem Proxy - -Zunächst wird die Containerdefinition im Verzeichnis `/home/admin/traefik/docker-compose.yml` angelegt: -```yaml -service: - traefik: - image: traefik:v2.9 - restart: always - command: - - "--api.insecure=true" - - "--metrics.prometheus=true" - #- "--log.level=DEBUG" - - "--accesslog=true" - - - "--providers.docker=true" - - "--providers.docker.exposedbydefault=false" - - "--providers.docker.network=proxy" - - - "--providers.file.directory=/configs/" - - - "--entrypoints.web.address=:80" - - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - - - "--entrypoints.websecure.address=:443" - #- "--entrypoints.websecure.http.middlewares=mw_hsts@file,mw_compress@file" - - "--entryPoints.websecure.http.tls=true" - - "--entryPoints.websecure.http.tls.certresolver=myresolver" - - "--entryPoints.websecure.http.tls.domains[0].main=domain.de" - - "--entryPoints.websecure.http.tls.domains[0].sans=*.domain.de" - - - "--certificatesresolvers.myresolver.acme.dnschallenge=true" - - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" - - "--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53" - - "--certificatesresolvers.myresolver.acme.dnschallenge.delayBeforeCheck=10" - - "--certificatesresolvers.myresolver.acme.email=admin@domain.de" - - "--certificatesresolvers.myresolver.acme.storage=/acme/acme.json" - #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" - labels: - - "traefik.enable=true" - - "traefik.http.services.srv_traefik.loadbalancer.server.port=8080" - - "traefik.http.routers.r_traefik.rule=Host(`traefik.domain.de`)" - - "traefik.http.routers.r_traefik.entrypoints=websecure" - env_file: .traefik.env - ports: - - "[::]:80:80" - - "[::]:443:443" - volumes: - - "/srv/traefik/acme:/acme" - - "/srv/traefik/dynamic.yml:/configs/dynamic.yml" - - "/srv/traefik/middlewares.yml:/configs/middlewares.yml" - - "/etc/localtime:/etc/localtime:ro" - - "/var/run/docker.sock:/var/run/docker.sock:ro" - networks: - - "proxy" - - static: - image: nginx:stable-alpine - restart: always - labels: - # BASIC CONFIGURATION - - "traefik.enable=true" - - "traefik.http.services.srv_static.loadbalancer.server.port=80" - - # ERROR PAGES - # you can use my error_pages: https://github.com/felbinger/AdminGuide/tree/master/error_pages - - "traefik.http.middlewares.error40x.errors.status=403-404" - - "traefik.http.middlewares.error40x.errors.service=srv_static" - - "traefik.http.middlewares.error40x.errors.query=/error/{status}.html" - - "traefik.http.middlewares.error30x.errors.status=300-308" - - "traefik.http.middlewares.error30x.errors.service=srv_static" - - "traefik.http.middlewares.error30x.errors.query=/error/30x.html" - - # DOMAIN ROOT CONTENT - - "traefik.http.routers.r_static_root.rule=HostRegexp(`domain.de`, `{subdomain:[a-z0-9]+}.domain.de`)" - - "traefik.http.routers.r_static_root.entrypoints=websecure" - - "traefik.http.routers.r_static_root.priority=10" - - "traefik.http.middlewares.mw_static_root.addprefix.prefix=/domain_root/" - - "traefik.http.routers.r_static_root.middlewares=mw_static_root@docker,error40x@docker,error30x@docker" - volumes: - - "/srv/static/webroot:/usr/share/nginx/html/" - networks: - - "proxy" - -networks: - proxy: - external: true -``` - -{% include-markdown "../../includes/installation/traefik/config.md" %} - -{% include-markdown "../../includes/installation/traefik/docker-network.md" %} - -{% include-markdown "../../includes/installation/traefik/new.md" %} diff --git a/docs/services/arma3.md b/docs/services/arma3.md deleted file mode 100644 index 9516d6f0..00000000 --- a/docs/services/arma3.md +++ /dev/null @@ -1,100 +0,0 @@ -# Arma 3 Server - -Ein Arma 3 Gameserver ermöglicht es Arma 3 Spielern eine -gemeinsame Mission zu spielen. Das hier beschriebene Vorgehen -erweitert die Grundfunktionalität von LGSM (Linux Game Server -Manager) um die benötigten Paketen für extdb3. - -In diesem Beispiel wird ein Arma 3 Exile Mod Server aufgesetzt: - -```yaml -services: - arma3: - image: ghcr.io/felbinger/arma3server - restart: always - environment: - # will be stored on filesystem during installation: - # /srv/arma3/lgsm/config-lgsm/arma3server/arma3server.cfg - - "STEAM_USER=" - - "STEAM_PASS=" - ports: - - '2302:2302/udp' # Arma 3 + voice over network - - '2303:2303/udp' # Steam Query - - '2304:2304/udp' # Steam Master - - '2305:2305/udp' # old Voice over Network - - '2306:2306/udp' # BattleEye - volumes: - - '/srv/arma3:/home/linuxgsm' - - mariadb: - image: mariadb - restart: always - environment: - - "MARIADB_RANDOM_ROOT_PASSWORD=true" - - "MARIADB_USER=arma3" - - "MARIADB_PASSWORD=S3cr3T" - - "MARIADB_DATABASE=exile" - volumes: - - "/srv/arma3-mariadb:/var/lib/mysql" -``` - -Vor dem ersten Start müssen die Berechtigungen des Verzeichnisses `/srv/arma3` angepasst werden. -```shell -mkdir /srv/arma3 -chown 1000:1000 /srv/arma3 -``` - -Anschließend können die Container gestartet werden (`docker compose up -d arma3`), -wodurch die Installation angestoßen wird. - -Für Exile müssen nun einige Mods im Verzeichnis `/srv/arma3/serverfiles/` hinzugefügt werden: -```shell -cd /srv/arma3/serverfiles/ - -# download and extract mods -wget http://bravofoxtrotcompany.com/exile/@Exile-1.0.4.zip -wget http://exilemod.com/ExileServer-1.0.4a.zip -unzip @Exile-1.0.4.zip -unzip ExileServer-1.0.4a.zip -rm *.zip - -# move the extracted files into the correct locations -cp -r /srv/arma3/serverfiles/Arma\ 3\ Server/* /srv/arma3/serverfiles/ - -# create tables on database using provided database schema -docker compose exec -T mariadb \ - mysql -uexile -pexile exile < /srv/arma3/serverfiles/MySQL/exile.sql - -# adjust extdb2 configuration -sed -i 's/^IP = 127.0.0.1/IP = mariadb/' /srv/arma3/serverfiles/@ExileServer/extdb-conf.ini -sed -i 's/^Username = changeme/Username = arma3/' /srv/arma3/serverfiles/@ExileServer/extdb-conf.ini -sed -i 's/^Password = /Password = S3cr3T/' /srv/arma3/serverfiles/@ExileServer/extdb-conf.ini - -# arma 3 server configs -mv /srv/arma3/serverfiles/@ExileServer/basic.cfg /srv/arma3/serverfiles/cfg/arma3server.network.cfg -mv /srv/arma3/serverfiles/@ExileServer/config.cfg /srv/arma3/serverfiles/cfg/arma3server.server.cfg - -# add mods to server startup configuration -cat <<_EOF > /srv/arma3/lgsm/config-lgsm/arma3server/arma3server.cfg -mods="@Exile" -servermods="@ExileServer" -_EOF - -# delete remaining extracted files from exile-server -rm -r /srv/arma3/serverfiles/Arma\ 3\ Server/ -rm -r /srv/arma3/serverfiles/MySQL -``` - -Nach einem Neustart der Container (`docker compose down && docker compose up -d`) -sollten diese geladen werden, falls Probleme auftreten können diese dem Serverlog -entnommen werden (`docker compose exec arma3 arma3server console`). - -### Wichtige Pfade -```shell -# things that need to be done to start the server (e. g. mods) -/srv/arma3/lgsm/config-lgsm/arma3server/arma3server.cfg - -# arma 3 server / network config -/srv/arma3/serverfiles/cfg/arma3server.server.cfg -/srv/arma3/serverfiles/cfg/arma3server.network.cfg -``` diff --git a/includes/installation/additional_ipv6.md b/includes/installation/additional_ipv6.md deleted file mode 100644 index c47f1371..00000000 --- a/includes/installation/additional_ipv6.md +++ /dev/null @@ -1,50 +0,0 @@ -### Optional: Eigene IPv6 Adresse für Virtual Host konfigurieren -Sofern eine eigene IPv6 Adresse für diesen Dienst verwendet werden soll, -wird diese der entsprechenden Netzwerkschnittstelle hinzugefügt, sodass -diese in nginx verwendet werden kann. - -=== "Debian" - ```shell - # /etc/network/interfaces - - # ... - - iface eth0 inet6 static - # ipv6 address of the host - address 2001:db8:1234:5678::1/64 - gateway 2001:db8::1 - - # service.domain.de - post-up ip -6 a add 2001:db8:1234:5678:5eca:dc9d:fd4e:6564/64 dev $IFACE - pre-down ip -6 a del 2001:db8:1234:5678:5eca:dc9d:fd4e:6564/64 dev $IFACE - ``` - -=== "Ubuntu" - Da Ubuntu `netplan` zum Konfigurieren der Netzwerkeschnittstellen verwendet, muss die entsprechende Konfiguration im - Verzeichnis `/etc/netplan` angepasst werden. - Die Konfigurationsdatei sollte ungefähr wie folgt aussehen: - ```yaml - network: - version: 2 - renderer: networkd - ethernets: - enp1s0: - addresses: - - 10.10.10.2/24 - - 2001:db8::5/64 - dhcp4: no - routes: - - to: 0.0.0.0/0 - via: 10.10.10.1 - - to: ::/0 - via: 2001:db8::1 - nameservers: - addresses: [10.10.10.1, 1.1.1.1, 2001:470:20::2] - ``` - Wenn die Konfigurationsdatei gefunden wurde, fügt man in dem `addresses` Abschnitt die neue IPv6 Adresse wie - folgt hinzu: - ```yaml - addresses: - ... - - 2001:db8:4a:90a:d8d5:dbf4:fd80:8f80 - ``` diff --git a/includes/installation/local-port-binding.md b/includes/installation/local-port-binding.md deleted file mode 100644 index d5485e55..00000000 --- a/includes/installation/local-port-binding.md +++ /dev/null @@ -1,8 +0,0 @@ -### Port-Binding von Dienst auf IPv6 Localhost (`::1`) des Hosts -Die Containerdefinition muss einen entsprechenden Eintrag erhalten, sodass der Port -auf dem der Container den Dienst bereitstellt, auf dem Hostsystem lokal verfügbar ist. -Dabei darf natürlich nur die linke Seite (hier 8081) verändert werden. -```yaml - ports: - - "[::1]:8081:80" -``` \ No newline at end of file diff --git a/includes/installation/nginx-multiple-ipv6.md b/includes/installation/nginx-multiple-ipv6.md deleted file mode 100644 index 02089c7c..00000000 --- a/includes/installation/nginx-multiple-ipv6.md +++ /dev/null @@ -1,14 +0,0 @@ -### IPv6 Adresse pro Virtual-Host -Sofern geplant ist, jedem Virtual Host eine eigene IPv6 Adresse zu geben empfielt sich -den nginx systemd-Service um einige Sekunden zu verzögern, sodass sichergestellt werden -kann, dass das System die IPv6 Adressen der Netzwerkschnittstelle bereits hinzugefügt hat. -Dieses Verfahren wurde auch [hier](https://docs.ispsystem.com/ispmanager-business/troubleshooting-guide/if-nginx-does-not-start-after-rebooting-the-server) beschrieben. - -![Result of `systemctl status nginx`](../../docs/img/nginx/nginx-failed-ipv6-not-assignable.png){: loading=lazy } - -Dazu muss in der Datei `/lib/systemd/system/nginx.service` vor der ersten `ExecStartPre` Zeile folgendes hinzugefügt werden: -```shell -# make sure the additional ipv6 addresses (which have been added with post-up) -# are already on the interface (only required for enabled nginx service on system boot) -ExecStartPre=/bin/sleep 5 -``` \ No newline at end of file diff --git a/includes/installation/nginx_base.md b/includes/installation/nginx_base.md deleted file mode 100644 index b6dee4be..00000000 --- a/includes/installation/nginx_base.md +++ /dev/null @@ -1,50 +0,0 @@ - -Kostenlose TLS Zertifikate können über Anbieter wie ZeroSSL -oder Let's Encrypt bezogen werden. In unserem Fall beziehen wir diese von Let's Encrypt mithilfe von -[acme.sh](https://github.com/acmesh-official/acme.sh). - -```shell -# mit root-Rechten ausführen -apt install nginx-full - -# acme.sh installieren und default ca auf Let's Encrypt setzen -curl https://get.acme.sh | sh -s email=acme@domain.de -ln -s /root/.acme.sh/acme.sh /usr/bin/acme.sh -acme.sh --install-cronjob - -acme.sh --server "https://acme-v02.api.letsencrypt.org/directory" --set-default-ca -``` - -{% include-markdown "../../includes/installation/nginx-multiple-ipv6.md" %} - - -## Konfiguration für neue Dienste - -Folgende Schritte sind notwendig, um ein neues HTTP Routing zu konfigurieren: - -1. Dienst aufsetzen. -2. Port-Binding von Dienst auf IPv6 Localhost (`::1`) des Hosts. -3. TLS Zertifkat über acme.sh anfordern. -4. Optional: Eigene IPv6 Adresse für Virtual Host konfigurieren. -5. nginx Virtual-Host konfigurieren und aktivieren. -6. Konfiguration testen und nginx neu laden. - -### Dienst aufsetzen -... - -{% include-markdown "../../includes/installation/local-port-binding.md" %} - -### TLS Zertifkat über acme.sh anfordern - -Für acme.sh müssen die erforderlichen Umgebungsvariablen für die gewünschte -[ACME Challenge](https://letsencrypt.org/docs/challenge-types/) gesetzt -sein. Für die DNS API's der Anbieter empfielt sich ein Blick in -[diese Tabelle](https://github.com/acmesh-official/acme.sh/wiki/dnsapi). - -```shell -# Beispielkonfiguration für Cloudflare DNS API -export CF_Token= -acme.sh --issue --keylength ec-384 --dns dns_cf -d service.domain.de -``` - -{% include-markdown "../../includes/installation/additional_ipv6.md" %} diff --git a/includes/installation/nginx_enable_test_apply_vhost.md b/includes/installation/nginx_enable_test_apply_vhost.md deleted file mode 100644 index d6513df9..00000000 --- a/includes/installation/nginx_enable_test_apply_vhost.md +++ /dev/null @@ -1,11 +0,0 @@ -### Konfiguration aktivieren, testen und anwenden. -Nun muss noch der Link zu `/etc/nginx/sites-enabled/` angelegt werden, -bevor die Konfiguration von nginx getestet werden kann und anschließend -nginx neu geladen werden kann, sofern der Test keine Fehler ergeben hat: - -```shell -ln -s /etc/nginx/sites-available/service.domain.de \ - /etc/nginx/sites-enabled/ - -nginx -t && systemctl reload nginx -``` diff --git a/includes/installation/traefik/config.md b/includes/installation/traefik/config.md deleted file mode 100644 index 136bacf2..00000000 --- a/includes/installation/traefik/config.md +++ /dev/null @@ -1,38 +0,0 @@ -Nun müssen noch einige Konfigurationen angelegt werden: -```yaml -# /srv/traefik/middlewares.yml -http: - middlewares: - mw_compress: - compress: true - mw_hsts: - headers: - contentTypeNosniff: true - browserXssFilter: true - forceSTSHeader: true - sslRedirect: true - stsPreload: true - stsSeconds: 315360000 - stsIncludeSubdomains: true - customResponseHeaders: - X-Forwarded-Proto: https - X-Frame-Options: sameorigin -``` - -```yaml -# /srv/traefik/dynamic.yml -tls: - options: - default: - minVersion: VersionTLS12 - sniStrict: true - cipherSuites: - # TLS 1.3 - - TLS_AES_256_GCM_SHA384 - - TLS_CHACHA20_POLY1305_SHA256 - - TLS_AES_128_GCM_SHA256 - # TLS 1.2 - - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 -``` \ No newline at end of file diff --git a/includes/installation/traefik/docker-network.md b/includes/installation/traefik/docker-network.md deleted file mode 100644 index 85995eab..00000000 --- a/includes/installation/traefik/docker-network.md +++ /dev/null @@ -1,5 +0,0 @@ -Anschließend legen wir das `proxy` Docker Netzwerk an und starten Traefik. -```shell -docker network create proxy -docker compose up -d -``` \ No newline at end of file diff --git a/includes/installation/traefik/new.md b/includes/installation/traefik/new.md deleted file mode 100644 index 57420037..00000000 --- a/includes/installation/traefik/new.md +++ /dev/null @@ -1,28 +0,0 @@ -### Konfiguration für neue Dienste -Für das einbinden eines webbasierten Dienstes in Traefik sind lediglich zwei Schritte notwenig. - -Zunächst muss das `proxy`-Netzwerk dem Container hinzugefügt werden. Dabei ist zu beachten, dass -- sofern dieser mit anderen Containern in der gleichen Containerdefinition - interagieren muss, -ebenfalls das `default`-Netzwerk benötigt, welches der Standardwert für Container ohne explizite -Netzwerkkonfiguration ist: -```yaml - networks: - - "proxy" - #- "default" -``` - -Außerdem müssen die Docker Labels für das HTTP Routing gesetzt werden: -```yaml - labels: - - "traefik.enable=true" - - "traefik.http.services.srv_service-name.loadbalancer.server.port=80" - - "traefik.http.routers.r_service-name.rule=Host(`service.domain.de`)" - - "traefik.http.routers.r_service-name.entrypoints=websecure" -``` - -!!! warning "" - Hierbei sollte umbedingt darauf geachtet werden, dass weder service (Präfix `srv_`), - noch router-Bezeichnungen (Präfix `r_`) doppelt verwendet werden, da dies zu schwer - bemerkbaren Fehlern führen kann. - - Außerdem sollte auf die korrekte Konfiguration des Service Ports geachtet werden (hier 80). \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 642f08ab..a2d7d5f9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -44,7 +44,11 @@ markdown_extensions: - toc: permalink: true - pymdownx.highlight - - pymdownx.superfences + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format - admonition - pymdownx.tabbed: alternate_style: true @@ -57,7 +61,7 @@ plugins: #- git-revision-date-localized - search: lang: de - - include-markdown + - tags extra_javascript: - js/config.js diff --git a/requirements.txt b/requirements.txt index 6b1cc0d7..393190d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,3 @@ mkdocs-material mkdocs-git-revision-date-plugin mkdocs-git-revision-date-localized-plugin jinja2==3.1.6 -mkdocs-include-markdown-plugin \ No newline at end of file