====== Notizen der Admin Grundlagen Schulung (Suse) vom Dezember 2022 ====== ===== Hilfe ===== * --help * Man pages * tldr.sh ==== Pager ==== * Suchen mit /                                  === Notizen ===      debootstrap --arch=amd64 stretch /srv/container/debian/ systemd-nspawn -D /srv/container/debian Passwort im Container für den Benutzer "root" setzen:  host$ systemd-nspawn -D /srv/container/debian container$ passwd container$ exit Container booten: systemd-nspawn -bD /srv/container/debian Flatpak:  1) Installation: zypper install flatpak  2) Repository hinzufügen:  flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo  3) Software suchen: flatpak search Beispiel: flatpak search logseq  4) Software installieren: flatpak install flatpak install com.logseq.Logseq  5) Software starten (als normaler Benutzer): flatpak run Update aller Suse Pakete: zypper update Docker: 1) Docker Engine installieren: zypper install docker 2) Docker Engine starten: systemctl enable --now docker 3) Docker testen: docker run hello-world Docker Aufgabe: Wir installieren einen Webserver im Docker. Wir testen die Software 'caddy' 1) Suche im Docker Hub nach einem Image mit dem Caddy Webserver:  docker search caddy 2) Lade das Image 'abiosoft/caddy' in das lokale Docker Image Repository:  docker pull abiosoft/caddy 3) Starte einen neuen Container mit dem Caddy-Webserver - Verbinde  Port 80 auf dem Laptop mit Port 2015 im Container: docker run -d --name=caddy-webserver -p 80:2015 abiosoft/caddy 4) Prüfe, das der Container läuft docker ps 5) Teste mit dem Firefox Browser auf dem Laptop, lade die Webseite  von http://localhost:80 6) Ein paar Befehle zum Testen von Docker Funktionen docker logs caddy-webserver docker top caddy-webserver docker stats caddy-webserver docker exec -it caddy-webserver /bin/sh Docker Aufgabe: Daten ausserhalb des Docker Containers  1) Verzeichnis für eigene Webseite erstellen mkdir -p /srv/webseite  2) Schreibe mit einem Text-Editor eine einfacht Webseite unter /srv/webseite/index.html  3) Stoppe den laufenden Caddy-Container docker stop caddy-webserver  4) Lösche den caddy-webserver Container docker rm caddy-webserver  5) Starte einen neuen Caddy-Container - in diesem Container wird das Verzeichnis /srv/webseite vom Linux (Suse) Host in der Verzeichnis /srv im Container verbunden docker run -d --name=caddy-webserver -p 80:2015 -v /srv/webseite:/srv abiosoft/caddy  6) Besuche die Webseite mit der URL http://localhost/ mit dem Firefox Browser - es sollte die eigene Webseite angezeigt werden  7) Ändere mit einem Text-Editor vom Suse-Linux (ausserhalb des Containers) die Datei /srv/webseite/index.html, lade dann die Seite im Browser neu -  die Änderungen sollten sichtbar werden Übung: Eigenes Image mit Dockerfile erstellen  1) Stoppe und lösche den Caddy-Container  2) Erstelle ein Arbeitsverzeichnis für die Docker-Dateien mkdir ~/Docker-work cd ~/Docker-work  3) Erstelle eine Datei mit dem Namen "Dockerfile" mit dem folgenden Inhalt      # Debian mit NGINX Webserver FROM debian:latest     MAINTAINER: Linuxhotel Trainer   # Pakete aktualisieren RUN apt -y update && apt -y upgrade # NGINX Webserver installieren RUN apt -y install nginx     # Hostnamen für den Container festlegen RUN echo "webserver.example.com" > /etc/hostname # NGINX Start-Befehl für den Container CMD ["nginx", "-g", "daemon off;"] 4) Neues Docker Image mit den Anweisungen aus dem Dockerfile bauen docker build -t debian-nginx --no-cache . 5) Docker Images auflisten docker images 6) Docker Container aus dem Image starten (Auf Port 80, mit dem eigenen Web-Dateien Verzeichnis) docker run -d --name=nginx01 -p 80:80 -v /srv/webseite:/var/www/html debian-nginx 1 Das "ip" Kommando =================== * der Befehl `ip' ersetzt viele der Low-Level Netzwerk-Konfigurationsbefehle traditioneller Unix/Linux Systeme: arp, route, ifconfig, netstat ... 1.1 Link-Layer ~~~~~~~~~~~~~~ * Statistiken anzeigen ,---- | # ip -s link show | # ip -s -s link show `---- * Konfiguration ,---- | # ip link set down | # ip link set up | # ip link set address | # ip link set name | # ip link show `---- 1.2 IPv4 Konfiguration ~~~~~~~~~~~~~~~~~~~~~~ ,---- | # ip address add a.b.c.d/pre broadcast x.x.x.x dev | # ip address add a.b.c.d/pre broadcast + dev | # ip address delete a.b.c.d/pre dev | # ip -4 address flush label `---- * primary und secondary adressen ,---- | # ip address add a.b.c.d/pre broadcast + dev | # ip address add a.b.c.e/pre broadcast + dev | # ip address add a.b.c.f/pre broadcast + dev | # ip a s | # ip address add a.b.d.d/pre broadcast + dev | # ip address add a.b.d.e/pre broadcast + dev | # ip address add a.b.d.e/pre broadcast + dev | # ip a s `---- * ARP ,---- | # ip n s | # ip neighbour delete 192.168.1.2 dev | # ip neighbour add 192.0.2.10 dev lladdr nud permanent | # ip n s | # ip -s n s | # ip -s -s n flush `---- * IPv6 Konfiguration ,---- | # ip -6 addr show dev | # ip -6 addr add / dev | # ip -6 addr del / dev | # ip -6 route show [dev ] | # ip -6 route add / via [dev ] | # ip -6 route del / via [dev ] | # ip -6 route add / dev metric 1 | # ip -6 route del / dev | # ip -6 neigh show [dev ] | # ip -6 neigh add lladdr dev | # ip -6 neigh del lladdr dev `---- * Routing ,---- | # ip route show | # ip route add /
 via 
  | # ip route add /
 dev  via 
  | # ip route delete /
  | # ip route flush cache
  `----


1.3 Netzwerk Namespaces
~~~~~~~~~~~~~~~~~~~~~~~

  * 
  * 
  * 

  * Benutzung:
    - Isolierung von Prozessen vom Netzwerk
    - Virtuelle Netzwerke zwischen Containern (LXC/Docker)
    - Admin-Netze "unsichtbar" machen

  * Achtung: *root* kann innerhalb eines Namespaces auf die Namespace
    "1" (Default-Namespace) zugreifen.

  ,----
  | # ip netns add netns1
  | # ip netns list
  | netns1
  | # ip netns exec netns1 ip link list
  | 1: lo:  mtu 65536 qdisc noop state DOWN mode DEFAULT
  |     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  | # ip netns delete netns1
  | # ip netns exec netns1 ping 127.0.0.1
  | connect: Network is unreachable
  | # ip netns exec netns1 ip link set dev lo up
  | # ip netns exec netns1 ping 127.0.0.1
  | PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
  | 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.051 ms
  | # ip link add veth0 type veth peer name veth1
  | # ip link
  | # ip link set veth1 netns netns1  # auch physische NICs koennen in Namespaces verschoben werden
  | # ip link
  | # ip netns exec ip link
  | # ip netns exec netns1 ip link
  | # ip a
  | # ip netns exec netns1 ifconfig veth1 10.1.1.1/24 up
  | # ip netns exec netns1 ip a
  | # ping 10.1.1.1
  | # ip netns exec netns1 ping 10.1.1.2
  | # ip netns exec netns1 route
  | # ip netns exec netns1 iptables -L
  | # ip netns delete netns1
  `----


1.4 Multicast Routing
~~~~~~~~~~~~~~~~~~~~~

  ,----
  | # ip mroute show
  | # ip mroute show from a.b.c.d/pre
  | # ip mroute show to a.b.c.d/pre
  `----


1.5 GRE Tunnel
~~~~~~~~~~~~~~

  * GRE (Generic Route Encapulation) ist ein Standardverfahren um
    IP-Pakete über IP-Netze zu tunneln
  * Damit können Netze über Gateway-Rechner, welche gegenseitig
    erreichbar sind, verbunden werden (auch mit privaten
    IP-Adressen). Ein VPN (aber ohne Verschlüsselung)
  * 
  ,----
  | NetA
  | network 10.110.1.0
  | netmask 255.255.255.0
  | router  10.110.1.1
  | 
  | NetB
  | network 10.110.2.0
  | netmask 255.255.255.0
  | router  10.110.2.1
  `----
  * Firewalld stoppen
  ,----
  | systemctl stop firewalld
  `----
  * Auf dem Router/Rechner NetA (IP 192.168.1.yyy)
  ,----
  | # ip tunnel show
  | # ip tunnel add netb mode gre \
  |    remote 192.168.1.xxx local 192.168.1.yyy ttl 64
  | # ip link set netb up
  | # ip addr add 10.110.1.1/24 dev netb
  | # ip route add 10.110.2.0/24 dev netb
  `----
  * Auf dem Router/Rechner NetB (IP 192.168.1.xxx)
  ,----
  | ip tunnel show
  | ip tunnel add neta mode gre \
  |   remote 192.168.1.yyy local 192.168.1.xxx ttl 64
  | ip link set neta up
  | ip addr add 10.110.2.1/24 dev neta
  | ip route add 10.110.1.0/24 dev neta
  `----
  * Tunnel entfernen
  ,----
  | # ip tunnel del 
  `----
  * Firewalld wieder starten
  ,----
  | systemctl start firewalld
  `----


1.6 IPSec VPN
~~~~~~~~~~~~~

  * IPSec Verbindungsparameter werden vom Linux-Kernel verwaltet. IPSec
    Programme wie StrongSWAN oder LibreSWAN benutzen IKE und andere
    Protokolle um die IPSec Parameter mit der Gegenstelle auszuhandeln
    und in den Linux-Kernel einzutragen. Die IPSec Parameter können
    jedoch auch direkt über den `ip' Befehl verwaltet werden.
  * das folgende Beispiel erzeugt einen IPSec Tunnel mit statischen
    Authentisierungs- und Verschlüsselungs Schlüsseln. Eine solche
    Konfiguration kann für /Ad-Hoc/ VPN Verbindungen benutzt werden,
    sollte aber nicht für Produktions-VPN-Installationen eingesetzt
    werden.


1.6.1 Beispiel: Ad-Hoc IPSec VPN
--------------------------------

  * in diesem Beispiel richten wir das IPSec VPN zwischen dem Laptop und
    der VM ein. Der IPSec Tunnel kann zwischen zwei Rechnern erstellt
    werden, welche über das IP-Protokoll kommunizieren können.
  * Node1: Laptop
  * Node2: VM
  * IPSec Konfiguration des Linux-Kernels anzeigen
  ,----
  | ip xfrm state
  | ip xfrm policy
  `----
  * ggf. alte IPSec Konfiguration löschen
  ,----
  | ip xfrm state flush
  | ip xfrm policy flush
  `----
  * Shell-Variable mit dem Authentisierungs-Schlüssel erstellen (auf
    beiden Endpunkten)
  ,----
  | export AUTHKEY=$(echo "passwort1" | openssl dgst -sha256 | cut -d ' ' -f 2)
  | echo $AUTHKEY
  `----
  * Shell-Variable mit dem Verschlüsselungs-Schlüssel erstellen (auf
    beiden Endpunkten)
  ,----
  | export ENCKEY=$(echo "passwort2" | openssl dgst -sha256 | cut -d ' ' -f 2)
  | echo $ENCKEY
  `----
  * IPSec Authentisierungs- und Verschlüsselungs-Paremeter zwischen
    beiden Endpunkten festlegen. Diese Befehle werden auf beiden
    Endpunkten ausgeführt:
  ,----
  | ip xfrm state add src  dst  \
  |    proto esp spi 0x00000001 reqid 0x1 mode tunnel \
  |    auth sha256 0x$AUTHKEY \
  |    enc aes 0x$ENCKEY
  | ip xfrm state add src  dst  \
  |    proto esp spi 0x00000001 reqid 0x1 mode tunnel \
  |    auth sha256 0x$AUTHKEY \
  |    enc aes 0x$ENCKEY
  `----
  * IPSec Tunnel mit den Tunnel-Adressen definieren
  * Node1:
  ,----
  | ip xfrm policy add src  dst  \
  |    dir out tmpl src  dst  proto esp reqid 0x1 mode tunnel
  | ip xfrm policy add src  dst  \
  |    dir in  tmpl src  dst  proto esp reqid 0x1 mode tunnel
  `----
  * Node2:
  ,----
  | ip xfrm policy add src  dst  \
  |    dir out tmpl src  dst  proto esp reqid 0x1 mode tunnel
  | ip xfrm policy add src  dst  \
  |    dir in  tmpl src  dst  proto esp reqid 0x1 mode tunnel
  `----
  * Tunnel-IP lokal auf das Loopback-Interface binden und
    Routing-Eintrag für die Tunnel-IP erstellen
  * Node1:
  ,----
  | ip addr add  dev lo
  | ip route add  dev virbr0 src 
  `----
  * Node2:
  ,----
  | ip addr add  dev lo
  | ip route add  dev eth0 src 
  `----
  * IPSec Status anzeigen
  ,----
  | ip xfrm state
  | ip xfrm policy
  `----
  * Testen (von Node1)
  ,----
  | ping 
  `----
  * IPSec Pakete im `tcpdump' anschauen
  ,----
  | tcpdump -i virbr0
  `----


1.7 Netzwerkänderungen überwachen
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  ,----
  | # ip monitor all
  | # ip -t -s monitor link
  | # ip monitor address a.b.c.d/pre
  | # ip monitor route a.b.c.d/pre
  | # rtmon file /var/log/rtmon.log
  | # ip monitor file /var/log/rtmon.log
  `----

SSH mit Schlüssel

 1) Erstelle ein SSH-Schlüsselpaar auf dem Client (eigenes
    Notebook). Bestaetige den Pfad der Schlüssel-Dateien und vergebe eine
    Passphrase (langes Passwort). Der private Schlüssel wird mit diesem
    Passwort verschlüsselt
    ssh-keygen -t ed25519
 2) Port 22 (SSH) in der Firewall auf dem Laptop freischalten
    firewall-cmd --add-service=ssh --permanent
    firewall-cmd --reload
 3) Sicherstellen das der SSH-Dienst gestartet ist
    systemctl status sshd
 4) Den eigenen öffentlichen SSH-Schlüssel auf den entfernten Rechner (Laptop
    des Partner-Teilnehmers) kopieren (XX=Nummer des Partner-Teilnehmers)
    ssh-copy-id nutzerXX@192.168.1.2XX
 5) SSH-Verbindung testen. Statt des Passwortes sollte nun die Passphrase des
    privaten Schlüssels gefragt werden
    ssh nutzerXX@192.168.1.2XX
 6) Wenn die Anmeldung des Partner-Teilnehmers per SSH-Schlüssel am eigenen
    Laptop funktioniert, dann in der SSH-Dienst Konfiguration die
    Passwort-Anmeldung deaktivieren. In der Datei /etc/ssh/sshd_config
    Alt -> PasswordAuthentication yes / UsePAM yes
    Neu -> PasswordAuthentication no  / UsePAM no
 7) SSH-Dienst neu starten
    systemctl restart sshd
 8) Den Partner-Teilnehmer bitten, die Anmeldung per Schlüssel zu testen. Wenn
    die Anmeldung per Schlüssel funktioniert, die Gegenprobe durchführen
    (Anmeldung per Passwort). Für die Gegenprobe versuchen sich am Rechner per
    SSH mit einem unbekannten Benutzer anzumelden (es sollte nicht nach einem
    Passwort Gefragt werden):  ssh unbekannt@192.168.1.2XX


SSH mit SSH-Agent

 0) Lokalen SSH-Agent laden (gilt nur in der aktuellen Shell, notwenig wenn
    man nicht als an der grafischen Oberfläche angemeldeter Benutzer in der
    Shell arbeitet)
    eval $(ssh-agent)
 1) Privater Schlüssel in den SSH-Agent laden
    ssh-add
 2) Schlüssel im Agent auflisten
    ssh-add -l
 3) Wenn nun eine SSH Verbindung mit Schlüssel aufgebaut wird, so wird nicht
    mehr nach der Passphrase gefragt. Bitte einmal ausprobieren
    ssh nutzerXX@192.168.1.2XX
 4) SSH-Agent mit einem Passwort sperren (z.B. wenn man den Laptop einige Zeit
    unbeaufsichtigt lässt)
    ssh-add -x
 5) SSH-Agent wieder entsperren (grosses 'X')
    ssh-add -X
 6) Alle Schlüssel aus dem SSH-Agent löschen
    ssh-add -D

BTRFS Dateisystem

1 BTRFS Dateisystem erstellen
=============================

  * Ein 1 Gb grosses BTRFS-Dateisystem erstellen
  ,----
  | mkfs.btrfs -b 1G /dev/sda4
  `----


2 btrfs Mount-Optionen
======================

  * thread_pool= - Anzahl der "worker-threads" für dieses
    Dateisystem. Insgesamt sollte die Anzahl der "worker-threads" aller
    BTRFS-Dateisysteme in System die Anzahl der CPU-Kerne nicht
    übertreffen
  * discard - DISCARD/TRIM Befehl für Flash-Speichermedien (SSD)
    anschalten
  * noacl - Keine Posix-ACLs auf dem Dateisystem erlauben
  * space_cache - Die Datenstruktur der freien Bloecke im Dateisystem
    auch auf die Platte schreiben. Dies beschleunigt das Caching für
    Block-Gruppen nach dem Einhängen des Dateisystems.
  * nospace_cache - Space-Cgache ausschalten
  * clear_cache - Space-Cache auf der Platte leeren. Der Space-Cache
    muss neu erstellt werden. Diese Mount-Option solle nur einmalig
    benutzt werden, nachdem des Probleme bei der Berechnung des freien
    Speichers in einem BTRS-Dateisystem gegeben hat
  * compress - Komprimiert Daten 'on-the-fly'


3 btrfs Dateisysteme vergroessern/verkleinern
=============================================

  * btrfs Dateisysteme koennen im laufenden Betrieb vergrössert oder
    verkleinert werden
  * der neue Grössenwert kann absolut gesetzt werden, z.b. "20g"
  * die Grössenveraenderung kann relativ angegeben werden, "-2g" um das
    Dateisystem um 2GB zu schrunmpfen, "+2g" um das Dateisystem um 2GB
    zu vergrössern. Bei einem Wert von "max" vergrössert sich das
    Dateisystem auf die maximale Grösse des freien Platzes auf dem
    Block-Gerät.
  ,----
  | # btrfs filesystem resize  /mount-point
  `----


4 RAID mit stripe / mirror
==========================

  * BTRFS implementiert Software-RAID Varianten:
    - RAID 0 = Stripe
    - RAID 1 = Mirror
    - RAID 01 = Mirror of Stripes
    - RAID 10 = Stripe of Mirrors
  * die Unterstützung fuer RAID 5 (Block-Level Striping mit verteilter
    Paritätsinformation) oder RAID 6 (Block-Level Striping mit doppelter
    verteilter Paritätsinformation) sind in BTRFS implementiert, aber
    noch fehlerbehaftet und sollten *nicht* in Produktionssystemen
    eingesetzt werden! (siehe
    )
  * Daten-Striping ueber 2 Platten (RAID 0), Metadaten gespiegelt
  ,----
  | mkfs.btrfs /dev/device1 /dev/device2
  `----
  * Metadaten und Daten als RAID 0 (stripe, nicht empfohlen)
  ,----
  | # mkfs.btrfs -m raid0 /dev/device1 /dev/device2
  `----
  * Spiegel mit 2 Platten (RAID 1)
  ,----
  | mkfs.btrfs -m raid1 -d raid1 /dev/device1 /dev/device2
  `----
  * RAID 0 - Dateisystem über 4 Platten (metadata mirrored, data
    striped).
  ,----
  | # mkfs.btrfs /dev/device1 /dev/device2 /dev/device3 /dev/device4
  `----
  * RAID 10 (ein RAID 0 über mehrere RAID 1)
  ,----
  | # mkfs.btrfs -m raid10 -d raid10 /dev/device1 /dev/device2 /dev/device3 /dev/device4
  `----
  * ein Block-Gerät zu einem bestehenden BTRFS-Dateisystem hinzufügen
  ,----
  | # btrfs device add /dev/device2 /mount-point
  | # btrfs filesystem balance /mount-point
  `----
  * Ein einfaches BTRFS-Dateisystem zu einem BTRFS-Spiegel erweitern
    (RAID 1)
  ,----
  | # mount /dev/sdb1 /mnt
  | # btrfs device add /dev/sdc1 /mnt
  | # btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
  `----
  * Block-Gerät aus einem BTRFS-RAID entfernen
  ,----
  | # btrfs device delete /dev/sdc /mnt
  `----
  * Ausgefallende Platte aus einem RAID entfernen
  ,----
  | # mount -o degraded /dev/sdb /mnt
  | # btrfs device delete missing /mnt
  `----
  * Ausgefallendes Gerät um laufenden Betrieb durch eine neue Platte
    ersetzen
  ,----
  | # btrfs replace start /dev/old /dev/new /mnt
  | # btrfs replace status
  `----

5 btrfs scrub
=============

  * BTRFS "scrub" liest alle Daten im Dateisystem, vergleicht die
    Checksummen und repariert defekte Dateibereiche (bei RAID 1, RAID 10
    etc)
  ,----
  | # btrfs scrub start /path
  | # btrfs scrub start -B /path  # im Vordergrund ausfuehren
  | # btrfs scrub status /path
  `----


6 btrfs Dateisystem defragmentieren
===================================

  * BTRFS kann Daten defragmentieren. Dabei werden die Daten auf neue
    Positionen im Dateisystem geschrieben
  ,----
  | # btrfs filesystem defragment -r -v /mnt
  `----
  * Defragmentierung bei gleichzeitiger Komprimierung der Daten
  ,----
  | # btrfs filesystem defragment -c -r -v /mnt
  `----


7 btrfs Datenkompression
========================

  * BTRFS kann Daten "on-the-fly" komprimieren (beim Speichern) und
    dekomprimieren (beim Laden). Unterstützte Kompressions-Algorithmen
    sind zlib (Standard) und lzo (Lempel-Ziv-Oberhumer
    ).
  ,----
  | # mount -o remount,compress=lzo /mnt/
  `----
  * Defragmentierung mit gleichzeitiger Komprimierung der Daten
  ,----
  | # btrfs filesystem defragment -r -v -clzo /mnt
  `----
  * Abfrage des erweiterten Attributs "C" (Compression)
  ,----
  | # lsattr /mnt/file
  `----


8 Filesystem-Informationen
==========================

  * mit dem Befehl `btrfs filesystem' können Informationen über das
    Dateisystem angezeigt werden. Informationen über die Belegung von
    Speicher auf Copy-on-Write Dateisystemen wie `btrfs' (oder auch ZFS)
    sind nie ganz exakt sondern Näherungswerte.
  ,----
  | # btrfs filesystem show
  | # btrfs filesystem df
  | # btrfs filesystem usage
  `----
  * Der Befehl `btrfs filesystem sync' sorgt aehnlich wie der `sync'
    Befehl dafuehr das daten aus den Hauptspeicher-Puffern in das
    Dateisystem geschrieben werden. Auch wird Speicher von geloeschten
    Subvolumes wieder freigegeben. `filesystem sync' sollte vor
    `filesystem df' oder `filesystem usage' ausgerufen werden, wenn
    genauere Werte ueber die Belegung des btrfs-Dateisystems benoetigt
    werden.
  ,----
  | btrfs filesystem sync /pfad
  `----


9 Dateisystem Label setzen
==========================

  * Das Label des Dateisystems kann mit dem Sub-Befehl `btrfs filesystem
    label' gesetzt werden
  ,----
  | # btrfs filesystem label /path