* Suchen mit /
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 <suchbegriff> Beispiel: flatpak search logseq 4) Software installieren: flatpak install <Applikation-ID> flatpak install com.logseq.Logseq 5) Software starten (als normaler Benutzer): flatpak run <Applikation-ID> 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 <info@linuxhotel.de> # 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 <dev> | # ip -s -s link show <dev> `---- * Konfiguration ,---- | # ip link set <dev> down | # ip link set <dev> up | # ip link set <dev> address <mac-addr> | # ip link set <dev> name <neuer-name> | # ip link show <neuer-name> `---- 1.2 IPv4 Konfiguration ~~~~~~~~~~~~~~~~~~~~~~ ,---- | # ip address add a.b.c.d/pre broadcast x.x.x.x dev <dev> | # ip address add a.b.c.d/pre broadcast + dev <dev> | # ip address delete a.b.c.d/pre dev <dev> | # ip -4 address flush label <dev> `---- * primary und secondary adressen ,---- | # ip address add a.b.c.d/pre broadcast + dev <dev> | # ip address add a.b.c.e/pre broadcast + dev <dev> | # ip address add a.b.c.f/pre broadcast + dev <dev> | # ip a s | # ip address add a.b.d.d/pre broadcast + dev <dev> | # ip address add a.b.d.e/pre broadcast + dev <dev> | # ip address add a.b.d.e/pre broadcast + dev <dev> | # ip a s `---- * ARP ,---- | # ip n s | # ip neighbour delete 192.168.1.2 dev <dev> | # ip neighbour add 192.0.2.10 dev <dev> lladdr <mac-addr> nud permanent | # ip n s | # ip -s n s | # ip -s -s n flush <ip> `---- * IPv6 Konfiguration ,---- | # ip -6 addr show dev <interface> | # ip -6 addr add <ipv6address>/<prefixlength> dev <interface> | # ip -6 addr del <ipv6address>/<prefixlength> dev <interface> | # ip -6 route show [dev <device>] | # ip -6 route add <ipv6network>/<prefixlength> via <ipv6address> [dev <device>] | # ip -6 route del <ipv6network>/<prefixlength> via <ipv6address> [dev <device>] | # ip -6 route add <ipv6network>/<prefixlength> dev <device> metric 1 | # ip -6 route del <ipv6network>/<prefixlength> dev <device> | # ip -6 neigh show [dev <device>] | # ip -6 neigh add <IPv6 address> lladdr <link-layer address> dev <device> | # ip -6 neigh del <IPv6 address> lladdr <link-layer address> dev <device> `---- * Routing ,---- | # ip route show | # ip route add <netz>/<pre> via <gateway> | # ip route add <netz>/<pre> dev <dev> via <gateway> | # ip route delete <netz>/<pre> | # ip route flush cache `---- 1.3 Netzwerk Namespaces ~~~~~~~~~~~~~~~~~~~~~~~ * <http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/> * <http://man7.org/linux/man-pages/man8/ip-netns.8.html> * <https://lwn.net/Articles/580893/> * 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: <LOOPBACK> 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) * <http://www.deepspace6.net/docs/iproute2tunnel-en.html> ,---- | 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 <device> `---- * 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 <ip-node1> dst <ip-node2> \ | proto esp spi 0x00000001 reqid 0x1 mode tunnel \ | auth sha256 0x$AUTHKEY \ | enc aes 0x$ENCKEY | ip xfrm state add src <ip-node2> dst <ip-node1> \ | 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 <tunnel-ip-node1> dst <tunnel-ip-node2> \ | dir out tmpl src <ip-node1> dst <ip-node2> proto esp reqid 0x1 mode tunnel | ip xfrm policy add src <tunnel-ip-node2> dst <tunnel-ip-node1> \ | dir in tmpl src <ip-node2> dst <ip-node1> proto esp reqid 0x1 mode tunnel `---- * Node2: ,---- | ip xfrm policy add src <tunnel-ip-node2> dst <tunnel-ip-node1> \ | dir out tmpl src <ip-node2> dst <ip-node1> proto esp reqid 0x1 mode tunnel | ip xfrm policy add src <tunnel-ip-node1> dst <tunnel-ip-node2> \ | dir in tmpl src <ip-node1> dst <ip-node2> 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 <tunnel-ip-node1> dev lo | ip route add <tunnel-ip-node2> dev virbr0 src <tunnel-ip-node1> `---- * Node2: ,---- | ip addr add <tunnel-ip-node2> dev lo | ip route add <tunnel-ip-node1> dev eth0 src <tunnel-ip-node2> `---- * IPSec Status anzeigen ,---- | ip xfrm state | ip xfrm policy `---- * Testen (von Node1) ,---- | ping <tunnel-ip-node2> `---- * 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=<nummer> - 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 <amount> /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 <https://btrfs.wiki.kernel.org/index.php/RAID56>) * 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 <https://de.wikipedia.org/wiki/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 <label> `---- 10 Subvolumes/Snapshots ======================= * Sub-Volumes sind eigenständige Dateisysteme, welche innerhalb eines bestehenden BTRFS-Dateisystems existieren. Während bei traditionellen Dateisystemen (ext4, XFS ...) die Dateisysteme nur in eigenen Block-Geräten oder Dateien erstellt werden können, sind BTRFS-Dateisysteme "schachtelbar". Alle geschachtelten Dateisysteme teilen sich den freien Speicherplatz des Mediums. ,---- | # btrfs subvolume create <name> | # btrfs subvolume show /path/to/subvolume | # btrfs subvolume list /path `---- * Ein Snapshot ist eine Sonderform eines Sub-Volumes. Ein Snapshot ist ein (schreibbares) 1-zu-1 Abbild eines bestehenden BTRFS-Dateisystems. Ein Snapshots verbraucht nur Speicher fuer die Differenzen zwischen dem Original und dem Snapshot-Dateisystem. * Einsatzszenarien fuer Dateisystem-Snapshots - Klonen von virtuellen Maschinen (Image-Dateien) - Klonen von Container-Verzeichnissen - inkrementelle Backups mit online Zugriff auf alle gesicherten "Generationen" des Backup (wie Apple Timemachine) - als Quelle fuer BTRFS "send/receive" (s.u.) - temporäre Arbeitsverzeichnisse (Software-Entwicklung etc) ,---- | # btrfs subvolume snapshot /old /new `---- * Ein "read-only" Snapshot erstellen ,---- | # btrfs subvolume snapshot -r /old /new `---- * ein BTRFS-Subvolume separat anhaengen ,---- | # mount -o subvol=name /dev/sdX /mountpoint | # mount -o subvolid=num /dev/sdX /mountpoint `----/dev/sda3 * Snapshot loeschen. Das Subvolume wird als geloescht markiert, das Speicher wird allerdings nicht sofort freigegeben sondern von BTRFS im Hintergrund verzoegert "eingesammelt" (Aktualisierung des Space-Cache). ,---- | btrfs subvolume delete /pfad `---- * auf das "Commit" warten, bis BTRFS den Speicher des Subvolumes wieder freigegeben hat ,---- | btrfs subvolume delete -c /pfad `---- * Manuell den als geloescht markierten Speicher wieder freigeben ,---- | btrfs subvolume sync `---- 11 BTRFS send/receive ===================== * Einen "read-only" snapshot erzeugen, in eine Datei "senden" (serialisieren) und dann loeschen ,---- | # btrfs subvolume snapshot -r /mnt/kernel/4.x/ /mnt/kernel/4.2r | # btrfs send /mnt/kernel/4.2r | gzip > /root/btrfs.send.gz | # btrfs subvolume delete /mnt/kernel/4.2r `---- * Snapshot aus einer Datei empfangen und zuruecksichern. Das Ziel darf noch nicht existieren, es wird ein neues Subvolume (read-only) angelegt ,---- | # zcat /root/btrfs.send.gz | btrfs receive -v /mnt | At subvol 4.2r | receiving subvol 4.2r uuid=daebdf0d-c46c-1848-b122-a865be93ac75, stransid=17 `---- Firewalld * Sicherheits "Zonen" * Konfiguration in `/usr/lib/firewalld/' und `/etc/firewalld/' ,---- | # systemctl status firewalld `---- * Panik-Modus ,---- | # firewall-cmd --panic-on | # firewall-cmd --panic-off `---- * FirewallD Informationen ,---- | # firewall-cmd --state | # firewall-cmd --reload | # firewall-cmd --get-default-zone | # firewall-cmd --set-default-zone <zone> | # firewall-cmd --get-active-zones | # firewall-cmd --get-zones | # firewall-cmd --list-all-zones | # firewall-cmd --get-services | # firewall-cmd --get-zone-of-interface=enp0s25 `---- * Service-Definitionen ,---- | ls /usr/lib/firewalld/services/ `---- * Sicherheits-Zonen anpassen ,---- | # firewall-cmd --zone=<zone> --list-all | # firewall-cmd --zone=<zone> --add-service=<service> | # firewall-cmd --zone=<zone> --add-service=<service> --permanent | # firewall-cmd --zone=<zone> --remove-service=<service> | # firewall-cmd --zone=<zone> --list-ports | # firewall-cmd --zone=<zone> --add-port=<portnum>[-portnum]/proto | # firewall-cmd --zone=<zone> --remove-port=<portnum>[-portnum]/proto | # firewall-cmd --zone=<zone> --add-port=<portnum>[-portnum]/proto --timeout=<timeval> | # firewall-cmd --zone=<zone> --add-port=<portnum>[-portnum]/proto --permanent | # firewall-cmd --zone=<zone> --add-masquerade | # firewall-cmd --zone=<zone> --remove-masquerade | # firewall-cmd --zone=<zone> --add-forward-port=port=22:proto=tcp:toport=422 | # /usr/sbin/sshd -D -p 422 | # firewall-cmd --zone=<zone> --add-forward-port=port=22:proto=tcp:toaddr=192.0.2.55 | # firewall-cmd --zone=<zone> --add-forward-port=port=22:proto=tcp:toport=422:toaddr=192.0.2.55 `---- * Rich-Rules ,---- | # firewall-cmd --zone=<zone> --list-rich-rules | # firewall-cmd --zone=<zone> --add-rich-rule='rule' [--timeout] | # firewall-cmd --zone=<zone> --remove-rich-rule='rule' [--timeout] `---- * Direkter-Modus (iptables) ,---- | firewall-cmd --direct --remove-rule ipv4 filter IN_public_allow \ | 0 -m tcp -p tcp --dport 666 -j ACCEPT `---- * Netzwerk-Schnittstellen ,---- | # firewall-cmd --zone=<zone> --list-interfaces | # firewall-cmd --zone=<zone> --add-interface=interface | # firewall-cmd --zone=<zone> --change-interface=interface | # firewall-cmd --zone=<zone> --remove-interface=interface `---- * Quellen ,---- | # firewall-cmd --zone=<zone> --list-sources | # firewall-cmd --zone=<zone> --add-source=source[/mask] | # firewall-cmd --zone=<zone> --change-source=source[/mask] | # firewall-cmd --zone=<zone> --remove-source=source[/mask] `---- * Lockdown und Whitelists ,---- | # firewall-cmd --lockdown-on | # firewall-cmd --lockdown-off | # firewall-cmd --add-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/command' | # firewall-cmd --add-lockdown-whitelist-uid=uid | # firewall-cmd --add-lockdown-whitelist-user=user `---- Übung Backup-Restore: Anleitung im Wiki unter "Backup / Bare-Metal Restore Suse Linux" https://wiki.lab.linuxhotel.de/doku.php/admin_grundlagen:systemsicherung#backup_bare-metal_restore_suse_linux Eigene Daten (Notizen, Konfigurationen etc) auf dem Laptop vorher sichern (z.B. in das Etherpad kopieren oder per "scp" auf einen anderen Laptop sichern) ! In 2er Teams zusammen an der Übung arbeiten. Jeden Schritt gemeinsam besprechen und gegenseitig prüfen. Bei Fehlern beim Backup kann später der Laptop nicht wiederhergestellt werden und muss neu installiert werden. Erst ein Backup eines Laptops auf den Laptop des anderen Team-Mitglieds durchführen. Danach diesen Laptop unbrauchbar machen und wiederherstellen. Nach erfolgreicher Wiederherstellung die Rollen tauschen und den anderen Laptop Sichern, unbrauchbar machen und wiederherstellen. Subvolumes welche gesichert werden: / /home /opt /srv /var /root /usr/local /tmp /boot/grub2/x86_64-efi /boot/grub2/i386-pc Beispiel Datei /etc/fstab nach Wiederherstellung /dev/nvme0n1p3 / btrfs defaults 0 0 /dev/nvme0n1p3 /.snapshots btrfs subid=279 0 0 /dev/nvme0n1p3 /var btrfs subvol=var 0 0 /dev/nvme0n1p3 /usr/local btrfs subvol=usr-local 0 0 /dev/nvme0n1p3 /tmp btrfs subvol=tmp 0 0 /dev/nvme0n1p3 /srv btrfs subvol=srv 0 0 /dev/nvme0n1p3 /root btrfs subvol=root 0 0 /dev/nvme0n1p3 /opt btrfs subvol=opt 0 0 /dev/nvme0n1p3 /home btrfs subvol=home 0 0 /dev/nvme0n1p3 /boot/grub2/x86_64-efi btrfs subvol=x86_64-efi 0 0 /dev/nvme0n1p3 /boot/grub2/i386-pc btrfs subvol=i386-pc 0 0 /dev/nvme0n1p1 /boot/efi vfat rw 0 2 /dev/nvme0n1p2 none swap sw 0 0 BTRFS 1) Erstelle ein RAID 10 (Stipe of Mirror) ueber die Partitionen 4-7 (4 Geräte) mkfs.btrfs -f -m raid10 -d raid10 /dev/nvme0n1p4 /dev/nvme0n1p5 /dev/nvme0n1p6 /dev/nvme0n1p7 2) Erstelle einen Eintrag in der Datei /etc/fstab welche dieses BTRFS Dateisystem nach /srv/data einhängt. Dabei sollen die Daten per 'zstd' Algorithmus transparent komprimiert werden /dev/nvme0n1p4 /srv/data btrfs compress=zstd 0 0 3) Teste den Eintrag in der Filesystem-Tabelle (kann das Dateisystem angehangen werden?) mount -a 4) Führe ein Reboot des Laptops durch. Prüfe nach dem Reboot, das /srv/data eingehangen ist 5) Das Dateisystem sollte eine Kapazität von ~4GB (unkomprimiert) besitzen. Teste die Komprimierung, eine neue Datei von 6 GB bestehend aus vielen NULL Bytes erstellt wird (sollte ideal komprimiert werden) dd if=/dev/zero of=/srv/data/grosse-datei-mit-nullen.dat bs=1M count=6000 6) Vergleiche die Ausgaben dieser Befehle df -Th du -sh /srv/data btrfs filesystem show /srv/data btrfs filesystem usage /srv/data btrfs filesystem df /srv/data BTRFS Quota 1) Erstelle ein Subvolume /srv/data/subvol btrfs subvol create /srv/data/subvol 2) Schalte Quota-Support für dieses BTRFS Dateisystem an btrfs quota enable /srv/data 3) Setze ein Limit von 100 MB auf das neue Subvolume btrfs qgroup limit 100M /srv/data/subvol 4) Test des Quota (Schreibe eine neue 150 MB Datei) dd if=/dev/urandom of=/srv/data/subvol/test.dat bs=1M count=150 5) Der Test sollte mit eine "Quota exceeded" Fehlermeldung abbrechen Logical Volume Management 1) Finde die Dokumentation zu LVM im Linuxhotel Wiki https://wiki.lab.linuhotel.de/ 2) Hänge das BTRFS Dateisystem aus /srv/data aus 3) Benutze den Befehl 'wipefs' (siehe Wiki) um die BTRFS Dateisysteme von Partition 4-7 zu löschen 4) Erstelle ein neues PV (Physical Volume) auf Partition 4 5) Erstelle eine neue Volume Group auf dem PV 6) Erstelle ein Logical Volume (LV) von 1GB in der Volume Group 7) Formatiere das Logical Volume mit dem XFS Dateisystem (mkfs.xfs /dev/...) 8) Binde dieses LV unter /srv/data ein (mount) 9) Vergrössere das LV im laufenden Betrieb um 500 MB 10) Lege ein 2tes PV auf der Partition 5 an 11) Füge diese 2te PV der Volume Group hinzu 12) Wandle das Logical Volume in ein RAID1 (Mirror) um 13) Binde das LV in die Datei /etc/fstab ein (ersetze die alte BTRFS Konfiguration-Zeile) 14) Teste die Filesystem-Tabelle mit "mount -a" 15) Teste ein Reboot des Laptops. Das Dateisystem auf dem LV sollte automatisch unter /srv/data eingehangen sein (mit "mount" oder "df -TH" testen) Übung: CUPS Netzwerk-Druckdienst 1) Der CUPS Netzwerkdruckdienst läuft unter Suse nur auf der Loopback-Schnittstelle Wir wollen die CUPS Konfiguration ändern, so das der Dienst auch über das Netzwerk erreichbar ist 2) In der Datei /etc/cups/cupsd.conf den Befehl "Listen 127.0.0.1:631" so ändern, das der Dienst auch auf alle Netzwerkschnittstellen horcht Listen 0.0.0.0:631 3) In der Datei /etc/cups/cupsd.conf für die Lokation (Location) "/" das Netz 192.168.1.0/24 erlauben <Location /> Order allow,deny Allow from 192.168.1.* </Location> 4) Datei sichern und den CUPS-Dienst neu starten systemctl restart cups systemctl status cups 5) Prüfen, das der Cups-Prozess nun auf allen IPv4 Adressen Daten entgegennimmt (Port 631) lsof -Poni :631 6) Einen anderen Teilnehmer bitten, mit dem Firefox auf die eigene IP-Adresse auf Port 631 zu verbinden http://192.168.1.2XX:631 Dies sollte noch nicht möglich sein, da die Firewall die Verbindung unterbindet 7) Port 631 in der Firewall freischalten firewall-cmd --add-port=631/tcp firewall-cmd --add-port=631/tcp --permanent 8) Nochmals von einem anderen Rechner aus testen. Nun sollte die CUPS Admin Webseite erscheinen Übung: NGINX Webserver 1) Installiere den NGINX Webserver aus den Suse Paketquellen 2) Passe die NGINX Konfiguration an, so das der Webserver auf der IP-Adresse des Laptops (Port 80) horcht 3) Erstelle eine einfache HTML Webseite für den Webserver 4) Erlaube den Webserver (per Port oder per Service) in der Firewall 5) Starte den NGINX Webserver Dienst, stelle sicher das der Dienst erfolgreich gestartet wurde 6) Lasse die Webseite von einem anderen Teilnehmer per http://192.168.1.2XX/ testen Übung zu RSyslog: 1) Erzeuge eine neue Syslog-Regel-Datei unter /etc/rsyslog.d mit der Dateiendung ".frule". Diese Regel soll alle Log-Meldungen der Facility (Anwendung) "local3" und der Wichtigkeit (Severity) "info" in die Datei /var/log/mylogfile.log schreiben Lösung: local3.info -/var/log/mylogfile.log 2) Den RSyslog-Dienst neu starten systemctl restart rsyslog 3) Lese die "man-page" Dokumentation zum Befehl "logger". Sende eine oder mehrere Log-Meldungen mit dem Befehl "logger" mit der Facility "local3" und der Severity "info". Prüfe das diese Log-Informationen in der Log-Datei /var/log/mylogfile.log erscheinen 4) Schaue die Konfigurationsdatei /etc/rsyslog.d/remote.conf im Text-Editor an. Erstelle eine Regel in dieser Datei, welche die Log-Meldungen der Facility "local3" (jede Severity) via UDP an den Laptop des Trainers (192.168.1.246) zum Syslogport (514) sendet Lösung: local3.* @192.168.1.246 5) Starte den Dienst RSyslog neu 6) Sende eine Log-Meldung für die Facility "local3" mit dem Befehl "logger" 7) Schaue das diese Log-Meldung am Bildschirm des Trainers angezeigt wird 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