Neue Sortierung und Welcome + Datenschutz
This commit is contained in:
90
articles/2024/der-eigene-dns-server-im-homelab.md
Normal file
90
articles/2024/der-eigene-dns-server-im-homelab.md
Normal file
@@ -0,0 +1,90 @@
|
||||
<!--{"title": "Der eigene DNS-Server im Homelab", "date": "2024-04-22", "slug": "der-eigene-dns-server-im-homelab", "cover": "/static/img/der-eigene-dns-server-im-homelab.png"}-->
|
||||
**Wer ein eigenes Homelab betrieben möchte, kommt oft an einen Punkt, an der die Verwendung von IP-Adressen zur Abgrenzung von Diensten nicht mehr ausreichend ist. Insbesondere, um im Homelab Dienste bereitzustellen, welche mit TLS-Verbindungen arbeiten, ist eine Namensauflösung gefragt.
|
||||
Ich zeige euch heute eine einfache Möglichkeit, euren eigenen DNS-Server im Homelab bereitzustellen.**
|
||||
|
||||
## Was ist ein DNS-Server
|
||||
|
||||
Ein DSN-Server, oder Domain Name System Server, ist ein grundlegendes Element der Internetinfrastruktur, das eine entscheidende Rolle bei der Auflösung von Domainnamen in IP-Adressen spielt. Kurz gesagt, ein DNS-Server fungiert als eine Art "Telefonbuch" des Internets, das Domainnamen wie z. B. "example.com" in die entsprechenden IP-Adressen wie "192.0.2.1" übersetzt.
|
||||
|
||||
Der DNS-Server erfüllt folgende Hauptaufgaben:
|
||||
|
||||
* **Auflösung von Domainnamen:** Wenn ein Benutzer im Internet eine Website aufruft, sendet sein Browser eine Anfrage an den DNS-Server, um die IP-Adresse der Website zu finden, die mit dem eingegebenen Domainnamen verknüpft ist.
|
||||
* **Verteilung von Anfragen:** DNS-Server sind hierarchisch organisiert und können in verschiedene Kategorien wie Root-Server, Toplevel-Domain-Server und Authoritative-Server unterteilt sein. Sie arbeiten zusammen, um DNS-Anfragen effizient zu verarbeiten und die entsprechenden IP-Adressen zurückzugeben.
|
||||
* **Caching:** DNS-Server können die Ergebnisse von vorherigen Anfragen zwischenspeichern, um die Antwortzeit zu verkürzen und die Netzwerkbelastung zu reduzieren. Dieser Prozess wird als Caching bezeichnet.
|
||||
|
||||
Insgesamt spielt der DNS-Server eine entscheidende Rolle bei der Navigation im Internet, indem er Domainnamen in die entsprechenden IP-Adressen auflöst und somit eine nahtlose Kommunikation zwischen den verschiedenen Computern und Servern im Netzwerk ermöglicht.
|
||||
|
||||
## Verwendung von DNS-Namen im Homelab
|
||||
|
||||
In einem Homelab, das für private oder Testzwecke betrieben wird, können Sie im Allgemeinen beliebige Domainnamen verwenden, solange sie nicht bereits von einem öffentlichen Domainnamen registriert wurden. Ein Homelab bietet Ihnen die Freiheit, eine Domänennamenstruktur zu verwenden, die Ihren Bedürfnissen und Vorlieben entspricht. Hier sind einige allgemeine Richtlinien und Beispiele für Domainnamen, die in einem Homelab verwendet werden können:
|
||||
|
||||
* .local: Dies ist eine der häufigsten TLDs für interne Netzwerke und wird von vielen Organisationen verwendet.
|
||||
* .lan: Eine weitere beliebte Wahl für interne Netzwerke, die als Alternative zu ".local" verwendet werden kann.
|
||||
* .home: Obwohl ".home" in einigen Fällen öffentlich registriert ist, wird es oft für private Netzwerke verwendet, solange es keine Konflikte gibt.
|
||||
* .internal: Diese TLD wird oft für interne Netzwerke verwendet, um sie von öffentlichen Domains zu unterscheiden.
|
||||
* .intra: Diese TLD wird oft für interne Netzwerke verwendet, um sie von öffentlichen Domains zu unterscheiden.
|
||||
* .corp: Ähnlich wie ".internal" wird ".corp" oft für private Netzwerke verwendet.
|
||||
* Subdomains eines öffentlichen Domainnamens: Wenn Sie bereits über eine registrierte Domain verfügen, können Sie Subdomains für Ihr Homelab verwenden, z. B. "homelab.meinefirma.com".
|
||||
|
||||
Es ist wichtig sicherzustellen, dass die von Ihnen verwendeten Domainnamen eindeutig sind und nicht mit echten Domains im Internet kollidieren, um Konflikte und Probleme mit der Namensauflösung zu vermeiden.
|
||||
|
||||
## Einrichtung eines DNS-Servers im Homelab unter Docker
|
||||
|
||||
Ich gehe davon aus, das Sie bereit Docker in Ihrem Netzwerk konfiguriert haben. Ebenso sollten Sie einen Reverse-Proxy wie Traefik konfiguriert haben.
|
||||
|
||||
Sehen Sie sich gerne mein Tutorial an:
|
||||
[Traefik richtig im Homelab oder Unternehmen mit eigenen Zertifikaten einrichten](/post/traefik-richtig-im-homelab-oder-unternehmen-mit-eigenen-zertifikaten-einrichten)
|
||||
|
||||
Dies ist insbesondere dann erforderlich, wenn Sie die verschlüsselten Protokolle (z.B.: DNS-over-HTTPS) nutzen wollen.
|
||||
Ich nutze die offizielle docker-compose.yml um die Nutzung im vorbereiteten Umfeld zu zeigen:
|
||||
|
||||
```
|
||||
version: "3"
|
||||
services:
|
||||
dns-server:
|
||||
container_name: dns-server
|
||||
hostname: dns-server
|
||||
image: technitium/dns-server:latest
|
||||
# For DHCP deployments, use "host" network mode and remove all the port mappings, including the ports array by commenting them
|
||||
# network_mode: "host"
|
||||
ports:
|
||||
- "5380:5380/tcp" #DNS web console (HTTP)
|
||||
# - "53443:53443/tcp" #DNS web console (HTTPS)
|
||||
- "53:53/udp" #DNS service
|
||||
- "53:53/tcp" #DNS service
|
||||
# - "853:853/udp" #DNS-over-QUIC service
|
||||
# - "853:853/tcp" #DNS-over-TLS service
|
||||
# - "443:443/udp" #DNS-over-HTTPS service (HTTP/3)
|
||||
# - "443:443/tcp" #DNS-over-HTTPS service (HTTP/1.1, HTTP/2)
|
||||
# - "80:80/tcp" #DNS-over-HTTP service (use with reverse proxy or certbot certificate renewal)
|
||||
# - "8053:8053/tcp" #DNS-over-HTTP service (use with reverse proxy)
|
||||
# - "67:67/udp" #DHCP service
|
||||
environment:
|
||||
- DNS_SERVER_DOMAIN=dns-server #The primary domain name used by this DNS Server to identify itself.
|
||||
# - DNS_SERVER_ADMIN_PASSWORD=password #DNS web console admin user password.
|
||||
# - DNS_SERVER_ADMIN_PASSWORD_FILE=password.txt #The path to a file that contains a plain text password for the DNS web console admin user.
|
||||
# - DNS_SERVER_PREFER_IPV6=false #DNS Server will use IPv6 for querying whenever possible with this option enabled.
|
||||
# - DNS_SERVER_WEB_SERVICE_HTTP_PORT=5380 #The TCP port number for the DNS web console over HTTP protocol.
|
||||
# - DNS_SERVER_WEB_SERVICE_HTTPS_PORT=53443 #The TCP port number for the DNS web console over HTTPS protocol.
|
||||
# - DNS_SERVER_WEB_SERVICE_ENABLE_HTTPS=false #Enables HTTPS for the DNS web console.
|
||||
# - DNS_SERVER_WEB_SERVICE_USE_SELF_SIGNED_CERT=false #Enables self signed TLS certificate for the DNS web console.
|
||||
# - DNS_SERVER_OPTIONAL_PROTOCOL_DNS_OVER_HTTP=false #Enables DNS server optional protocol DNS-over-HTTP on TCP port 8053 to be used with a TLS terminating reverse proxy like nginx.
|
||||
# - DNS_SERVER_RECURSION=AllowOnlyForPrivateNetworks #Recursion options: Allow, Deny, AllowOnlyForPrivateNetworks, UseSpecifiedNetworks.
|
||||
# - DNS_SERVER_RECURSION_DENIED_NETWORKS=1.1.1.0/24 #Comma separated list of IP addresses or network addresses to deny recursion. Valid only for `UseSpecifiedNetworks` recursion option.
|
||||
# - DNS_SERVER_RECURSION_ALLOWED_NETWORKS=127.0.0.1, 192.168.1.0/24 #Comma separated list of IP addresses or network addresses to allow recursion. Valid only for `UseSpecifiedNetworks` recursion option.
|
||||
# - DNS_SERVER_ENABLE_BLOCKING=false #Sets the DNS server to block domain names using Blocked Zone and Block List Zone.
|
||||
# - DNS_SERVER_ALLOW_TXT_BLOCKING_REPORT=false #Specifies if the DNS Server should respond with TXT records containing a blocked domain report for TXT type requests.
|
||||
# - DNS_SERVER_BLOCK_LIST_URLS= #A comma separated list of block list URLs.
|
||||
# - DNS_SERVER_FORWARDERS=1.1.1.1, 8.8.8.8 #Comma separated list of forwarder addresses.
|
||||
# - DNS_SERVER_FORWARDER_PROTOCOL=Tcp #Forwarder protocol options: Udp, Tcp, Tls, Https, HttpsJson.
|
||||
# - DNS_SERVER_LOG_USING_LOCAL_TIME=true #Enable this option to use local time instead of UTC for logging.
|
||||
volumes:
|
||||
- config:/etc/dns
|
||||
restart: unless-stopped
|
||||
sysctls:
|
||||
- net.ipv4.ip_local_port_range=1024 65000
|
||||
|
||||
volumes:
|
||||
config:
|
||||
```
|
||||
|
202
articles/2024/ein-eigenes-docker-Image-erstellen-so-gehts.md
Normal file
202
articles/2024/ein-eigenes-docker-Image-erstellen-so-gehts.md
Normal file
@@ -0,0 +1,202 @@
|
||||
<!--{"title": "Ein eigenes Docker-Image erstellen - so geht's", "date": "2024-04-21", "slug": "ein-eigenes-docker-Image-erstellen-so-gehts", "cover": "/static/img/ein-eigenes-docker-Image-erstellen-so-gehts.png"}-->
|
||||
**Ein eigenes Docker-Image erstellen, oder ein vorhandenes Image den eigenen Bedürfnissen anpassen?
|
||||
Natürlich geht das! Ich zeige euch, wie ihr dies einfach umsetzen könnt.**
|
||||
|
||||
## Vorwort
|
||||
|
||||
Die Verwendung von Images ist in der Welt von Docker und anderen Container-Diensten absoluter Standard.
|
||||
|
||||
Viele Nutzer verwenden diese fertig zusammengestellten Images. Oft ist damit auch alles gut, bis man etwas ändern möchte.
|
||||
|
||||
Ich diesem praktischen Beispiel möchte ich euch dies mit dem Beispiel einer beliebten Webanwendung zeigen. Wir verwenden hier die Forum-Software von Woltlab.
|
||||
|
||||
Wenn Sie die Software als freies Framework nutzen wollen, genügt in der Regel eine Standard-Konfiguration von einem Webserver-Container, z.B. nginx und der FPM-Version von PHP. Beides kann als Standard-Image von Docker-Hub bezogen werden.
|
||||
|
||||
Möchte man nun aber Funktionen von Plugins, wie das Abfragen von E-Mail-Konten über das IMAP-Protokoll verwenden, so kann dies normalerweise nicht erfolgen, da die PHP-Erweiterung IMAP nicht vorhanden ist. Jetzt kommt das große Problem. Wie kann die Erweiterung möglichst dauerhaft konfiguriert werden? Denn jede Änderung an den Container-Einstellungen wird beim Neustart, spätestens jedoch beim Update des Images überschreiben.
|
||||
|
||||
Die Antwort: Ein eigenes Image erstellen.
|
||||
|
||||
Ich möchte euch hier zeigen, wie ihr ein All-in-One Image erzeugen könnt.
|
||||
|
||||
## Vorbereitung
|
||||
|
||||
Zunächst sollten wir uns aber alle Quellen ansehen, die wir zur Erstellung des Docker-Images brauchen, oder berücksichtigen müssen.
|
||||
|
||||
### Alpine-Linux
|
||||
|
||||
Ich erstelle das Image auf Basis von alpine-Linux. Alpine ist eine sehr kleine Linux Distribution und sehr weit verbreitet.
|
||||
|
||||
Da ich auf dieser Basis sowohl PHP, als auch nginx erzeugen möchte, benötige ich die konkreten Pakete, die im Image erzeugt und installiert werden müssen.
|
||||
|
||||
Dafür schaue ich mir die Paket-Details auf dem Paket-Server von alpine-Linux an: [https://pkgs.alpinelinux.org/packages](https://pkgs.alpinelinux.org/packages)
|
||||
|
||||
### PHP unter Alpine-Linux
|
||||
|
||||
Speziell sehe ich nach PHP, da hier die Version eine besondere Rolle bei der Kompatibilität mit den Anwendungen spielt:
|
||||
|
||||
[Alpine Linux packages](https://pkgs.alpinelinux.org/package/edge/community/armhf/php83)
|
||||
|
||||
Wenn Sie eine andere PHP-Version installieren möchten, können Sie im oberen der zwei Links im Feld "Package name" einfach ``php*`` eingeben und die Architektur auf x86_64 einstellen und suchen.
|
||||
|
||||
Ich kompiliere jedoch die zur Zeit der Veröffentlichung aktuellste und mit Woltlab kompatible Version PHP 8.3 (8.3.6).
|
||||
|
||||
Beachten Sie, dass Sie neben dem Haupt-Paket von PHP auch alle benötigten Erweiterungen installieren müssen.
|
||||
|
||||
### nginx unter Alpine-Linux
|
||||
|
||||
Beim Paket von nginx ist die Installation eindeutiger. Hier gibt es nur das Paket "nginx".
|
||||
|
||||
### Redis unter Alpine-Linux
|
||||
|
||||
Ebenso sieht es beim Paket für den Redis-Dienst aus. Auch hier gibt es nur das Paket "redis".
|
||||
|
||||
### Basis-Pakete unter Alpine-Linux
|
||||
|
||||
Zudem müssen bestimmte Basis-Pakete installiert werden, um die Voraussetzungen zum Start der Dienste zu gewährleisten, oder um für spätere Wartungsarbeiten direkt die wichtigsten Tools an der Hand zu haben.
|
||||
|
||||
Hier sind besonders zu nennen:
|
||||
|
||||
* bash
|
||||
* autoconf
|
||||
* automake
|
||||
* make
|
||||
* gcc
|
||||
* g++
|
||||
|
||||
## Aufbau der Datei "Dockerfile"
|
||||
|
||||
Ein Dockerfile ist eine Textdatei, die eine Reihe von Anweisungen enthält, um ein Docker-Image zu erstellen. Hier ist eine typische Struktur eines Dockerfiles:
|
||||
|
||||
### Basisimage wählen
|
||||
|
||||
Der erste Schritt in einem Dockerfile ist die Auswahl eines Basisimages, auf dem das neue Image aufbauen wird. Dies geschieht mit dem FROM-Befehl, gefolgt von dem Namen des Basisimages und optional der Versionsnummer.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
FROM ubuntu:20.04
|
||||
```
|
||||
|
||||
### Pakete und Abhängigkeiten installieren
|
||||
|
||||
Anschließend können Anwendungen oder Bibliotheken installiert werden, die für die Ausführung der gewünschten Software benötigt werden. Dies geschieht normalerweise mit Paketverwaltungstools wie apt für Ubuntu-basierte Images oder yum für CentOS-basierte Images.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
RUN apt-get update && apt-get install -y <paketname>
|
||||
```
|
||||
|
||||
### Arbeitsverzeichnis festlegen
|
||||
|
||||
Mit dem WORKDIR-Befehl kann das Arbeitsverzeichnis innerhalb des Containers festgelegt werden, in dem Befehle ausgeführt werden.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
WORKDIR /app
|
||||
```
|
||||
|
||||
### Dateien hinzufügen/kopieren
|
||||
|
||||
Dateien und Verzeichnisse können mit dem ADD- oder COPY-Befehl in das Image kopiert werden. COPY ist dabei meist vorzuziehen, da es weniger Funktionalität als ADD bietet, aber auch weniger überraschendes Verhalten hat.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
COPY ./app /app
|
||||
```
|
||||
|
||||
### Umgebungsvariablen setzen
|
||||
|
||||
Mit dem ENV-Befehl können Umgebungsvariablen innerhalb des Containers gesetzt werden, die von der ausgeführten Anwendung genutzt werden können.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
ENV DB_HOST=localhost
|
||||
```
|
||||
|
||||
### Ports freigeben
|
||||
|
||||
Wenn die Anwendung einen Netzwerkport verwendet, muss dieser mit dem EXPOSE-Befehl im Dockerfile bekannt gegeben werden. Dies beeinflusst jedoch nicht, wie der Container tatsächlich gestartet wird.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
EXPOSE 8080
|
||||
```
|
||||
|
||||
### Befehl zum Ausführen der Anwendung
|
||||
|
||||
Schließlich wird ein Befehl definiert, der beim Start des Containers ausgeführt werden soll. Dies wird durch den CMD- oder ENTRYPOINT-Befehl erreicht.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
CMD ["python", "app.py"]
|
||||
```
|
||||
|
||||
## Konkretes Beispiel für mein Dockerfile mit PHP, nginx und Redis auf Alpine-Linux
|
||||
|
||||
Nachdem wir jetzt wissen, was wir für das Erstellen eines Images benötigen können wir uns dem eigentlichen Herzstück für die Erstellung eines eigenen Images widmen, dem Dockerfile.
|
||||
|
||||
```
|
||||
FROM alpine:latest
|
||||
RUN apk update && apk upgrade
|
||||
RUN apk add bash
|
||||
RUN apk add autoconf automake make gcc g++
|
||||
RUN apk add nginx
|
||||
RUN apk add php83 php83-fpm php83-opcache php83-tokenizer
|
||||
RUN apk add php83-gd php83-zlib php83-curl php83-bz2 php83-bcmath php83-exif php83-fileinfo php83-iconv php83-imap php83-intl php83-ldap php83-mbstring php83-mysqli php83-odbc php83-pdo php83-pdo_mysql php83-pdo_odbc php83-pdo_pgsql php83-pdo_sqlite php83-pear php83-pecl-imagick php83-pecl-memcache php83-pecl-memcached php83-pecl-mongodb php83-pecl-redis php83-pecl-smbclient php83-pecl-ssh2 php83-pecl-xdebug php83-pecl-yaml php83-pgsql php83-phar php83-phpdbg php83-session php83-simplexml php83-snmp php83-soap php83-sockets php83-sodium php83-sqlite3 php83-sysvmsg php83-tidy php83-xml php83-xmlreader php83-xmlwriter php83-xsl php83-zip
|
||||
RUN apk add redis
|
||||
#COPY server/etc/nginx /etc/nginx
|
||||
#COPY server/etc/php /etc/php83
|
||||
#COPY server/etc/redis/redis.conf /etc/redis.conf
|
||||
#COPY src /usr/share/nginx/html
|
||||
RUN mkdir /var/run/php
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
EXPOSE 6379
|
||||
EXPOSE 9000
|
||||
STOPSIGNAL SIGTERM
|
||||
CMD ["/bin/bash", "-c", "php-fpm83 && chmod 755 /usr/share/nginx/html/* && nginx -g 'daemon off;' && redis-server /etc/redis.conf"]
|
||||
```
|
||||
|
||||
In meinem Dockerfile wird nun alles zum Image hinzugefügt, was für den Betrieb notwendig ist.
|
||||
|
||||
Als Basis-Image dient die letzte Version von alpine (alpine:latest). Danach werden alle offenen Updates des Betriebssystems abgerufen und installiert (RUN apk update && apk upgrade). Im Anschluss werden die Basis-Pakete installiert (RUN apk add bash | RUN apk add autoconf automake make gcc g++). Danach werden der Webserver nginx, PHP mit seinen Erweiterungen und der Caching-Dienst Redis installiert.
|
||||
|
||||
Die Auskommentierten COPY-Befehle würden die Konfigurationen relativ zum Verzeichnis des Dockerfile direkt in das Image schreiben.
|
||||
|
||||
Der nächste Befehl (RUN mkdir /var/run/php) erstellt ein Verzeichnis, welches für PHP benötigt wird.
|
||||
|
||||
Mit den EXPOSE-Befehlen geben wir dem Image an. Schnittstellen an den Container freizugeben, die von außerhalb erreichbar gemacht werden sollen. Dazu gehören die Ports des nginx (80, 443), der PHP-FPM-Port (9000) und der Redis-Port (6379).
|
||||
|
||||
Zuletzt geben wir noch das Start und Stoppverhalten vor.
|
||||
|
||||
Damit ist das Dockerfile einmal erläutert. Wie man das Image jetzt erzeugt, folgt jetzt.
|
||||
|
||||
## Erzeugen des Images
|
||||
|
||||
Das Erzeugen des Images ist denkbar einfach. Dennoch gibt es ein paar Dinge zu beachten, damit Ihre Image-Verwaltung nicht in einem Debakel endet.
|
||||
|
||||
* Erzeugen Sie Images möglichst immer mit einem eindeutigen Tag (alpine_np83r:1.0)
|
||||
* Wenn Sie eine eigene, interne Containerregistrierung haben, können Sie auch direkt den vollständigen Tag verwenden. z.B.: (registry.homelab.lan/alpine_np83r:1.0)
|
||||
* Erstellen Sie zudem den Tag "latest" zu ihrem letzten, funktionierenden Image.
|
||||
|
||||
Erstellen können Sie das oben definierte Image mit dem Befehl ```sudo docker build -t alpine_np83r:1.0 .```.
|
||||
|
||||
Beachten Sie, das Sie mit der Konsole zuvor in das Verzeichnis navigieren müssen, indem sich die oben erstellte Datei (Dockerfile) befindet.
|
||||
|
||||
Danach können Sie das Image innerhalb dieser Maschine verwenden.
|
||||
|
||||
Möchten Sie das Image auf anderen Maschinen verwenden, so müssen Sie dieses Image auf eine Container-Registrierung hochladen.
|
||||
|
||||
Haben Sie beim Erstellen des Images den vollständigen Tag-Namen mit Ihrer Registry eingegeben, können Sie das image mit folgendem Befehl in Ihre Registrierung "pushen": ```sudo docker push registry.homelab.lan/alpine_np83r:1.0```.
|
||||
|
||||
## Fazit
|
||||
|
||||
Ich hoffe ich konnte Ihnen die Sorgen rund um das Thema "Eigene Docker Images erstellen" etwas nehmen. Ich habe für mich festgestellt, das es nur etwas Übung braucht, um mit der Thematik "warm" zu werden. Insgesamt ist mein Fazit, das es sich definitiv auszahlt, eigene Images zu erstellen und auch in einer eigenen Registrierung vorzuhalten.
|
||||
|
||||
In diesem Sinne, bis zum nächsten Thema!
|
30
articles/2024/einbinden-nfs-ubuntu-24-04.md
Normal file
30
articles/2024/einbinden-nfs-ubuntu-24-04.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--{"title": "Einbinden von NFS-Freigaben in Ubuntu (24.04 LTS)", "date": "2024-04-24", "slug": "einbinden-nfs-ubuntu-24-04", "cover": "/static/img/einbinden-nfs-ubuntu-24-04.png"}-->
|
||||
**Das Einbinden von Dateisystemen außerhalb von Linux kann Vorteile haben. Eine einfache Lösung ist das Einbinden von NFS-Freigaben.
|
||||
Hierbei ist es unwichtig, ob Sie die NFS-Freigabe von einem Windows, oder einem Linux-System nutzen.**
|
||||
|
||||
## Vorbereitungen
|
||||
|
||||
Um NFS-Freigaben in Ubuntu einbinden zu können, müssen bestimmte Voraussetzungen erfüllt werden. Eine davon ist der NFS-Client.
|
||||
Wir nutzen den Paket-Manager APT, um nfs-common zu installieren. Setzen Sie den folgenden Befehl in einer Konsole ab:
|
||||
|
||||
```
|
||||
sudo apt install -y nfs-common
|
||||
```
|
||||
|
||||
## Herstellen einer Verbindung und Einbindung einer NFS-Freigabe
|
||||
|
||||
Um eine NFS-Freigabe einzubinden, müssen Sie ein Kommando in die Konsole eingeben:
|
||||
|
||||
```
|
||||
sudo mount -t nfs -o vers=3 <ip/or/hostname>:/freigabename /einhängepunkt
|
||||
Z.B.: sudo mount -t nfs -o vers=3 192.168.0.10:/wwwdata /docker/webserver/wwwdata
|
||||
```
|
||||
|
||||
Soll die Einbindung beim Systemstart eingebunden werden, so müssen Sie noch folgende eingaben tätigen:
|
||||
|
||||
```
|
||||
sudo nano /etc/fstab
|
||||
192.168.0.10:/wwwdata /docker/webserver/wwwdata nfs defaults 0 0
|
||||
```
|
||||
|
||||
Es können so auch mehrere NFS-Verbindungen hergestellt werden.
|
100
articles/2024/in-ubuntu-den-port-53-dns-selber-nutzen.md
Normal file
100
articles/2024/in-ubuntu-den-port-53-dns-selber-nutzen.md
Normal file
@@ -0,0 +1,100 @@
|
||||
<!--{"title": "In Ubuntu den Port 53 - DNS - selber nutzen", "date": "2024-04-15", "slug": "in-ubuntu-den-port-53-dns-selber-nutzen", "cover": "/static/img/in-ubuntu-den-port-53-dns-selber-nutzen.png"}-->
|
||||
**Ubuntu verwendet standardmäßig den DNS-Over-UDP-Port (53) selber.
|
||||
Dies kann sehr hinderlich sein, wenn man seinen eigenen DNS-Server betreiben, oder ihn an einen Container weitergeben möchte.
|
||||
Ich zeige euch, wie ihr den Port auf Ubuntu freigeben und selber nutzen könnt.**
|
||||
|
||||
## Vorwort
|
||||
|
||||
Ich empfehle zunächst nur erfahrenen Benutzern dazu eine solche Änderung vorzunehmen.
|
||||
|
||||
## Analyse
|
||||
|
||||
Zunächst analysieren wir, von welchem Dienst der Port 53 genutzt wird. Das kann mit diesem Kommando ausgelesen werden:
|
||||
|
||||
```
|
||||
sudo lsof -i :53
|
||||
```
|
||||
|
||||
Die Ausgabe sieht in etwa so aus:
|
||||
|
||||
```
|
||||
root@ubnt:/home/root# lsof -i :53
|
||||
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
|
||||
systemd-r 634 systemd-resolve 13u IPv4 19902 0t0 UDP localhost:domain
|
||||
systemd-r 634 systemd-resolve 14u IPv4 19903 0t0 TCP localhost:domain (LISTEN)
|
||||
root@ubnt-core-a:/home/root#
|
||||
```
|
||||
|
||||
Sollte hier keine Ausgabe erfolgen, so ist vermutlich der Port 53 nicht in Verwendung!
|
||||
|
||||
Wir können anhand der Ausgabe erkennen, dass der Port 53 vom Systemdienst ```systemd-resolved``` verwendet wird.
|
||||
|
||||
Anpassung der Konfiguration zum Freigeben
|
||||
|
||||
Nach dem wir wissen, das der Systemdienst den DNS-Port belegt, können wir die Konfiguration anpassen, um den Port für unsere Zwecke frei zu bekommen.
|
||||
|
||||
Dazu bearbeiten wir die Datei ```/etc/systemd/resolved.conf``` idealerweise mit der Software nano: ```sudo nano /etc/systemd/resolved.conf```
|
||||
|
||||
Die Datei sieht wie folgt aus:
|
||||
|
||||
```
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free
|
||||
# Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Entries in this file show the compile time defaults. Local configuration
|
||||
# should be created by either modifying this file, or by creating "drop-ins" in
|
||||
# the resolved.conf.d/ subdirectory. The latter is generally recommended.
|
||||
# Defaults can be restored by simply deleting this file and all drop-ins.
|
||||
#
|
||||
# Use 'systemd-analyze cat-config systemd/resolved.conf' to display the full config.
|
||||
#
|
||||
# See resolved.conf(5) for details.
|
||||
[Resolve]
|
||||
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
|
||||
# Cloudflare: 1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
|
||||
# Google: 8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
|
||||
# Quad9: 9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
|
||||
#DNS=
|
||||
#FallbackDNS=
|
||||
#Domains=
|
||||
#DNSSEC=no
|
||||
#DNSOverTLS=no
|
||||
#MulticastDNS=no
|
||||
#LLMNR=no
|
||||
#Cache=no-negative
|
||||
#CacheFromLocalhost=no
|
||||
#DNSStubListener=yes
|
||||
#DNSStubListenerExtra=
|
||||
#ReadEtcHosts=yes
|
||||
#ResolveUnicastSingleLabel=no
|
||||
```
|
||||
|
||||
Wir entfernen die Raute (#) vor der Zeile (DNS=) und geben einen Sinnvollen DNS-Server ein z.B. ```1.1.1.1``` oder ```8.8.8.8``` oder im Heimnetzwerk die Adresse ihres Routers.
|
||||
|
||||
Wir entfernen die Raute (#) vor der Zeile (DNSStubListener=) und geben als Wert ```no``` an.
|
||||
|
||||
Wir speichern die Datei so ab. ```Strg + x``` -> ```Y``` -> ```Enter```.
|
||||
|
||||
Damit ist das Gröbste geschafft. Nun folgt noch ein weiterer Schritt, bevor Sie das System neu starten müssen.
|
||||
|
||||
Lassen Sie uns einen Symbol-Link erstellen, der von ```/run/systemd/resolve/resolv.conf``` auf ```/etc/resolv.conf``` verweist.
|
||||
|
||||
Führen Sie dazu dieses Kommando aus:
|
||||
|
||||
```
|
||||
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||
```
|
||||
|
||||
Die Parameter für diesen Befehl sind:
|
||||
|
||||
* -s: Erstellt einen Symbol-Link und keinen Hard-Link
|
||||
* -f: Entfernt das Ziel, wenn es existiert (```/etc/resolv.conf```)
|
||||
Abschluss
|
||||
|
||||
Nun fehlt Ihnen nur noch ein Neustart des Systems. Danach ist der DNS-Port (53) frei zur Verwendung durch Drittsoftware.
|
||||
|
||||
Ich hoffe euch hat dieser Artikel weitergeholfen und ich freue mich euch im nächsten Artikel wieder zu lesen
|
89
articles/2024/mysql-auf-linux-installieren.md
Normal file
89
articles/2024/mysql-auf-linux-installieren.md
Normal file
@@ -0,0 +1,89 @@
|
||||
<!--{"title": "MySQL auf Linux installieren", "date": "2024-04-08", "slug": "mysql-auf-linux-installieren", "cover": "/static/img/mysql-auf-linux-installieren.png"}-->
|
||||
**Sie möchten einen schnellen und performanten MySQL-Server betreiben und haben bislang MySQL nur Windows genutzt? Versuchen Sie es doch mal mit Linux.
|
||||
Linux ist kein Hexenwerk und die Performance wird Sie überraschen. Wir zeigen Ihnen hier alle relevanten Schritte für eine erfolgreiche Umsetzung und einen stabilen Betrieb.**
|
||||
|
||||
Hier zeige ich euch, wie ihr einen MySQL-Server auf Linux (Ubuntu 22.04) installiert.
|
||||
|
||||
Sie benötigen eine physische oder virtuelle Maschine mit Linux. Wir verwenden in diesem Beitrag die aktuelle Core-Server Version von Ubuntu mit Long-Term-Support (LTS).
|
||||
|
||||
Beachten Sie, das Server-Maschinen grundsätzlich mit einer statischen IP-Adresse eingerichtet sein sollten. Alternativ können Sie auch eine DHCP-Reservierung verwenden. Wir empfehlen jedoch die Nutzung einer statischen IP-Konfiguration.
|
||||
|
||||
Melden Sie sich an Ihrer Linux-Konsole an und führen folgendes Kommando aus, um den Software-Dienst zu aktualisieren: ```sudo apt update```.
|
||||
|
||||
Installieren Sie das MySQL-Server-Paket mit folgendem Kommando: ```sudo apt install mysql-server```.
|
||||
|
||||
Starten Sie den neu installierten MySQL-Dienst mit diesem Kommando: ```sudo systemctl start mysql.service```.
|
||||
|
||||
Rufen Sie die MySQL-Konsole auf: ```sudo mysql```.
|
||||
|
||||
Geben Sie nacheinander die folgenden vier Kommandos ein. In Zeile 1 ersetzen Sie "passwort" durch Ihr neues Root- (Administrator-) Passwort. In Zeile 2 ersetzen Sie "starkespasswort" durch Ihr neues Administrator-Passwort. Verwenden Sie hier ein maximal starkes Passwort, da diesem Benutzer erlaubt wird, sie von externen Hosts (%) anzumelden. Ersetzen Sie zudem in Zeile 2 "deinuser" durch den von Ihnen gewünschten Benutzernamen.
|
||||
|
||||
```
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'passwort';
|
||||
CREATE USER 'deinuser'@'%' IDENTIFIED WITH mysql_native_password BY 'starkespasswort';
|
||||
GRANT ALL PRIVILEGES on *.* TO 'deinuser'@'%' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
Verlassen Sie die MySQL-Konsole mit diesem Befehl: ```exit```.
|
||||
|
||||
Führen Sie jetzt die erweiterte Konfiguration durch:
|
||||
|
||||
Setzen Sie folgendes Kommando ab: ```sudo mysql_secure_installation```.
|
||||
|
||||
```
|
||||
Securing the MySQL server deployment.
|
||||
Enter password for user root:
|
||||
VALIDATE PASSWORD COMPONENT can be used to test passwords
|
||||
and improve security. It checks the strength of password
|
||||
and allows the users to set only those passwords which are
|
||||
secure enough. Would you like to setup VALIDATE PASSWORD component?
|
||||
Press y|Y for Yes, any other key for No:
|
||||
Using existing password for root.
|
||||
Change the password for root ? ((Press y|Y for Yes, any other key for No) : n
|
||||
... skipping.
|
||||
By default, a MySQL installation has an anonymous user,
|
||||
allowing anyone to log into MySQL without having to have
|
||||
a user account created for them. This is intended only for
|
||||
testing, and to make the installation go a bit smoother.
|
||||
You should remove them before moving into a production
|
||||
environment.
|
||||
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
|
||||
Success.
|
||||
|
||||
Normally, root should only be allowed to connect from
|
||||
'localhost'. This ensures that someone cannot guess at
|
||||
the root password from the network.
|
||||
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : n
|
||||
... skipping.
|
||||
By default, MySQL comes with a database named 'test' that
|
||||
anyone can access. This is also intended only for testing,
|
||||
and should be removed before moving into a production
|
||||
environment.
|
||||
|
||||
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
|
||||
- Dropping test database...
|
||||
Success.
|
||||
- Removing privileges on test database...
|
||||
Success.
|
||||
Reloading the privilege tables will ensure that all changes
|
||||
made so far will take effect immediately.
|
||||
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
|
||||
Success.
|
||||
All done!
|
||||
```
|
||||
|
||||
Bearbeiten Sie die Konfiguration mit folgendem Befehl: ```sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf```. Ändern Sie die Konfiguration auf die unten genannten Werte.
|
||||
|
||||
```
|
||||
bind-address = 0.0.0.0
|
||||
mysqlx-bind-address = 0.0.0.0
|
||||
```
|
||||
|
||||
Starten Sie den Dienst mit folgendem Kommando neu: ```sudo systemctl restart mysql.service```.
|
||||
|
||||
Nun ist Ihr MySQL-Server auf Linux startbereit.
|
||||
|
||||
Möglicherweise interessiert Sie auch unser Artikel zu PHPMyAdmin in Docker?
|
||||
|
||||
[PHPMyAdmin mit Serverauswahl im Homelab mittels Docker bereitstellen](/post/phpmyadmin-mit-serverauswahl-im-homelab-mittels-docker-bereitstellen)
|
@@ -0,0 +1,41 @@
|
||||
<!--{"title": "PHPMyAdmin mit Serverauswahl im Homelab mittels Docker bereitstellen", "date": "2024-04-09", "slug": "phpmyadmin-mit-serverauswahl-im-homelab-mittels-docker-bereitstellen", "cover": "/static/img/phpmyadmin-mit-serverauswahl-im-homelab-mittels-docker-bereitstellen.png"}-->
|
||||
**PHPMyAdmin ist eines der erfolgreichsten Datenbank-Management-Systeme für PHP.
|
||||
Die einfache Verwaltung, der geringe Installationsaufwand und die kostenfreie Nutzung machten es bereits vor vielen Jahren zu der beleibtesten Verwaltungsoberfläche für MySQL und MariaDB. Wir zeigen euch eine Möglichkeit PHPMyAdmin in eurem Homelab oder internen Firmennetzwerk für beliebige Server unter Docker einzurichten.**
|
||||
|
||||
Die beliebte Verwaltungsoberfläche können Sie ohne große Aufwendungen einfach in Ihrem bestehenden Docker-Server als weiteren Container hinzufügen.
|
||||
|
||||
Wenn Sie unsere anderen Docker-Anleitungen bereits umgesetzt haben, kommt Ihnen der Aufbau bekannt vor und Sie müssen kaum etwas an der Compose-Datei anpassen. Andererseits finden Sie den Artikel hier:
|
||||
|
||||
[Traefik richtig im Homelab oder Unternehmen mit eigenen Zertifikaten einrichten](/post/traefik-richtig-im-homelab-oder-unternehmen-mit-eigenen-zertifikaten-einrichten)
|
||||
|
||||
In unserem Beispiel machen wir PHPMyAdmin mit einer sicheren SSL-Verbindung im Netzwerk verfügbar. Zudem aktivieren wir die freie Eingabe einer Server-Adresse.
|
||||
|
||||
Dies kann im Homelab mit stetig wechselnden Servern Sinnvoller sein, als stetig die Serverliste in PHPMyAdmin anpassen zu müssen. Für eine öffentlich zugängliche Variante empfehlen wir die Umsetzung nach offizieller Anleitung für eine vorgegebene Server-Liste oder einen fest hinterlegten Server umzusetzen!
|
||||
|
||||
Für unser Projekt finden Sie im Folgenden die Compose-Datei, in der Sie möglicherweise noch kleinere Anpassungen machen müssen.
|
||||
|
||||
Beachten Sie, wie üblich, den Host-Namen in der Datei anzupassen und zuvor einen gültigen DNS-Eintrag zu vergeben.
|
||||
|
||||
````
|
||||
version: "3.3"
|
||||
services:
|
||||
phpmyadmin:
|
||||
container_name: phpmyadmin
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.phpmyadmin.rule=Host(`phpmyadmin.deinedomain.tld`)
|
||||
- traefik.http.services.phpmyadmin.loadbalancer.server.port=80
|
||||
- traefik.http.routers.phpmyadmin.entrypoints=websecure
|
||||
- traefik.http.routers.phpmyadmin.tls=true
|
||||
- traefik.protocol=http
|
||||
environment:
|
||||
- PMA_ARBITRARY=1
|
||||
image: phpmyadmin
|
||||
networks:
|
||||
- traefik_traefik-net
|
||||
networks:
|
||||
traefik_traefik-net:
|
||||
external: true
|
||||
```
|
||||
|
||||
Ich hoffe, das Ihnen die Anleitung geholfen hat und Sie ein weiteres Tool erfolgreich in Ihr Homelab integrieren und fortan nutzen können!
|
@@ -0,0 +1,61 @@
|
||||
<!--{"title": "Windows Fehler 0x80072F8F - Installation optionaler Features schlägt fehl", "date": "2024-04-10", "slug": "windows-fehler-0x80072f8f-installation-optionaler-features-schlaegt-fehl", "cover": "/static/img/windows-fehler-0x80072f8f-installation-optionaler-features-schlaegt-fehl.png"}-->
|
||||
**Der Fehlercode 0x80072F8F tritt häufig auf, kann jedoch oft von Administratoren und Benutzern nicht gelöst werden.
|
||||
Die Ursachen für diesen Fehler können vielseitig sein. In einer Vielzahl der Probleme hilft jedoch eine simple Lösung.
|
||||
Ich zeige Ihnen, wie Sie mit dem Fehlercode umgehen und Ihr System wieder reparieren können.**
|
||||
|
||||
## Vorwort und Fehlerbeschreibung
|
||||
|
||||
Die Auswirkungen, die dieser Fehler aufzeigen kann sind umfänglich.
|
||||
|
||||
Die Möglichkeiten, die sich bei der Fehleranalyse und Behebung bieten, können überfordernd über einen hineinbrechen. Erst Recht, wenn man aufgrund der Vielzahl an Symptomen nicht weiß, wo man eigentlich anfangen soll. Zu vielen Fehlersymptomen kommen unzählige Behebungsmöglichkeiten. Problematisch sind aus meiner Sicht die vielen Anleitungen, die zwar die Symptome abschalten, jedoch nicht die Ursache bekämpfen.
|
||||
|
||||
In meinem Fall war es den Computern im Netzwerk nicht mehr möglich, optionale Features über die Einstellungen / Apps zu installieren. Es erscheint nach einer kurzen Wartezeit immer der Fehlercode 0x80072F8F. Eine detaillierte Fehlerbeschreibung gibt es nicht. Das Windows Ereignisprotokoll ist ebenso nicht besonders aussagekräftig.
|
||||
|
||||
Ein erster Aufschluss gab mir tatsächlich das Protokoll der Netzwerk-Firewall. Hier war bei den durch mich getesteten Clients stetig der Fehler "Connection Reset" zu erkennen. Nach dem Ausschlussverfahren habe ich die üblichen Verdächtigen (Firewall, Proxy, Netzwerkkonfiguration, ...) ausgeschlossen.
|
||||
|
||||
Die auszurufende URL war [https://sls.update.microsoft.com](https://sls.update.microsoft.com). Zwei Tests führten mich zunächst auf eine falsch Fährte. Zuerst versuchte ich die Seite mittels Google Chrome zu öffnen. Dort erhielt ich bereits eine Zertifikatswarnung. Ein erster Anhaltspunkt.
|
||||
|
||||
Mein zweiter Test, der Webseiten-Check der Firma Qualys SSL Labs: [https://www.ssllabs.com/ssltest/analyz…e.microsoft.com](https://www.ssllabs.com/ssltest/analyz…e.microsoft.com). Hier der nächste Hammer für mich: This server's certificate is not trusted, see below for details.
|
||||
|
||||
Was ist hier passiert? Hat Microsoft ein falsches Zertifikat im Einsatz? Ist das die Lösung?
|
||||
|
||||
Die Antwort ist einfach: Nein. Das Zertifikat wird nicht Global verteilt. Lediglich in Windows-Systemen über Windows-Update. Zumindest eigentlich.
|
||||
|
||||
In allen Fällen, die mir bislang untergekommen sind, ist eben dies im Zusammenhang mit dem Fehler 0x80072F8F nicht passiert. Der Zertifikatsstamm wurde auf den Rechnern, respektive der ganzen Domäne nicht aktualisiert. Die Gründe sind mir immer noch unbekannt. Denn eine manuelle Aktualisierung funktioniert problemlos. Dies werden wir in einem späteren Punkt noch erfolgreich belegen.
|
||||
|
||||
Zu diesem Fehler-Symptom gesellen sich noch diverse weitere, die im Zusammenspiel in Firmennetzwerken auch wechselseitige Auswirkungen auf andere Gruppenrichtlinien, Vertrauensstellungen anderer Domänen und diversen Einträgen im Fehlerprotokoll haben können. In der Ereignisanzeige deutet sich dieses Problem oft in der Quelle CAPI2 an. Sind hier viele Einträge vom Typ "Fehler" so ist davon auszugehen, das die authrootstl.cab im SYSVOL-Verzeichnis ebenfalls defekt ist. Ebenso kann es vorkommen, dass die Installation von optionalen Features nicht klappt, sowie die Ausführung von Online-Updates nicht funktioniert.
|
||||
|
||||
Normale Clients die nicht in Firmennetzwerken eingesetzt werden, können Probleme mit dem Ausführen von Windows-Updates, dem Einsatz des Media-Creation-Tools und anderer Software von Microsoft bekommen. Unter Anderem kann hier auch der Windows-Store betroffen sein.
|
||||
|
||||
Es gibt zwei Möglichkeiten das Problem zu beheben.
|
||||
|
||||
## Lösung 1: Einzelner Clients / Server
|
||||
|
||||
Führen Sie das unten stehende Script in einer Powershell mit Administrator-Berechtigungen aus. Es wird ein Verzeichnis angelegt, eine Datei von Windows-Update heruntergeladen und schließlich entpackt und installiert.
|
||||
|
||||
```
|
||||
md c:\cert
|
||||
cd c:\cert
|
||||
certutil.exe -generateSSTFromWU C:\cert\roots.sst
|
||||
certutil -syncWithWU c:\cert\
|
||||
$sstStore = ( Get-ChildItem -Path C:\cert\roots.sst )
|
||||
$sstStore | Import-Certificate -CertStoreLocation Cert:\LocalMachine\Root
|
||||
```
|
||||
|
||||
Wenn Sie das Script erfolgreich ausgeführt haben und das Problem sofort behoben ist, empfehle ich Ihnen dennoch einen Neustart des Systems.
|
||||
|
||||
## Lösung 2: Fehler auf allen Endgeräten einer Domäne
|
||||
|
||||
Im Unternehmensumfeld kann dies auch zu einem globalen Problem werden. In meinem Fall, waren alle Clients und alle modernen Server-Versionen von dem Problem betroffen. Hier hat eine einfache Lösung den Erfolg gebracht, da so alle Clients automatisch repariert werden. Verbinden Sie sich mit dem Administrator-Konto Ihrer Domäne auf einen Domänen-Controller und öffnen eine Powershell mit Administrator-Berechtigungen. Geben Sie folgenden Befehl ein:
|
||||
|
||||
```
|
||||
Certutil -syncWithWU -f \\ihredomain.tld\SYSVOL\ihredomain.tld\rootcert\
|
||||
```
|
||||
|
||||
Danach sollten sich innerhalb weniger Minuten alle Clients in Ihrer Domäne heilen.
|
||||
|
||||
Bislang konnte dieses Kommando jede korrumpierte Domänenstruktur wieder reparieren und den Betrieb aller PCs wieder sicherstellen.
|
||||
|
||||
Bislang war es mir unmöglich zu reproduzieren, wie der Fehler verursacht wird. Wenn Sie Ergänzungen dazu haben, nutzen Sie gerne die Kommentar-Funktion unter diesem Artikel oder nutzen Sie die "Vorschläge" Funktion meines Systems.
|
||||
|
||||
Ich bedanke mich, das Sie diesen Eintrag gelesen haben und hoffe das Sie ebenso erfolgreich Ihr Problem lösen konnten!
|
Reference in New Issue
Block a user