* 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