Initial Commit
continuous-integration/drone Build is passing Details

This commit is contained in:
Markus Pesch 2021-10-13 19:25:16 +02:00
commit fed26c8bbd
Signed by: volker.raschek
GPG Key ID: 852BCC170D81A982
66 changed files with 9016 additions and 0 deletions

225
.drone.yml Normal file
View File

@ -0,0 +1,225 @@
---
kind: pipeline
type: kubernetes
name: latest
platform:
os: linux
arch: amd64
steps:
- name: build
commands:
- make latexmk/index.pdf
image: docker.io/volkerraschek/latex:latest-archlinux
resources:
limits:
cpu: 500
memory: 250M
- name: push-nextcloud
commands:
- curl --fail --user $WEBDAV_USER:$WEBDAV_PASSWORD --upload-file index.pdf --location https://nextcloud.cryptic.systems/remote.php/dav/files/markus.pesch/Dokumente/Studium/Fachschaftdaten/LX_-_Linux/linux_ws2122/Aufgabensammlung.pdf
depends_on:
- build
environment:
WEBDAV_USER:
from_secret: webdav_username
WEBDAV_PASSWORD:
from_secret: webdav_password
image: docker.io/volkerraschek/latex:latest-archlinux
resources:
limits:
cpu: 50
memory: 25M
when:
repo:
- fh-trier/linux_ws2122
event:
- push
- cron
- name: push-fhtrier
depends_on:
- build
image: docker.io/appleboy/drone-scp:1.6.2
settings:
host: ssh.hochschule-trier.de
user:
from_secret: ssh_user_fh-trier
key:
from_secret: ssh_key
port: 22
command_timeout: 2m
target:
- /dozenten/peschm/linux_ws2122
source:
- index.pdf
- csv/*
- sql/*
when:
branch:
- master
repo:
- fh-trier/linux_ws2122
event:
- push
- cron
- name: email-notification
depends_on:
- push-nextcloud
- push-fhtrier
environment:
PLUGIN_HOST:
from_secret: smtp_host
PLUGIN_USERNAME:
from_secret: smtp_username
PLUGIN_PASSWORD:
from_secret: smtp_password
PLUGIN_FROM:
from_secret: smtp_mail_address
image: docker.io/drillster/drone-email:latest
resources:
limits:
cpu: 50
memory: 25M
when:
status:
- changed
- failure
trigger:
event:
exclude:
- tag
---
kind: pipeline
type: kubernetes
name: release
platform:
os: linux
arch: amd64
steps:
- name: build
commands:
- make latexmk/index.pdf
environment:
VERSION: ${DRONE_TAG}
image: docker.io/volkerraschek/latex:latest-archlinux
resources:
limits:
cpu: 500
memory: 250M
- name: push-nextcloud
commands:
- curl --fail --user $WEBDAV_USER:$WEBDAV_PASSWORD --upload-file index.pdf --location https://nextcloud.cryptic.systems/remote.php/dav/files/markus.pesch/Dokumente/Studium/Fachschaftdaten/LX_-_Linux/linux_ws2122/Aufgabensammlung_${DRONE_TAG}.pdf
environment:
WEBDAV_USER:
from_secret: webdav_username
WEBDAV_PASSWORD:
from_secret: webdav_password
image: docker.io/volkerraschek/latex:latest-archlinux
resources:
limits:
cpu: 50
memory: 25M
- name: push-gitea
image: docker.io/plugins/gitea-release:latest
resources:
limits:
cpu: 50
memory: 25M
settings:
base_url: https://git.cryptic.systems
api_key:
from_secret: gitea_token
files:
- index.pdf
checksum:
- md5
- sha1
- sha256
- sha512
- adler32
- crc32
- name: email-notification
environment:
PLUGIN_HOST:
from_secret: smtp_host
PLUGIN_USERNAME:
from_secret: smtp_username
PLUGIN_PASSWORD:
from_secret: smtp_password
PLUGIN_FROM:
from_secret: smtp_mail_address
image: docker.io/drillster/drone-email:latest
resources:
limits:
cpu: 50
memory: 25M
when:
status:
- changed
- failure
trigger:
event:
- tag
repo:
- fh-trier/linux_ws2122
# ---
# kind: pipeline
# type: kubernetes
# name: sync
# platform:
# os: linux
# arch: amd64
# steps:
# - name: github
# image: docker.io/appleboy/drone-git-push:latest
# resources:
# limits:
# cpu: 50
# memory: 25M
# settings:
# branch: master
# remote: ssh://git@github.com/fh-trier/linux_ws2122.git
# force: true
# ssh_key:
# from_secret: ssh_key
# - name: email-notification
# environment:
# PLUGIN_HOST:
# from_secret: smtp_host
# PLUGIN_USERNAME:
# from_secret: smtp_username
# PLUGIN_PASSWORD:
# from_secret: smtp_password
# PLUGIN_FROM:
# from_secret: smtp_mail_address
# image: docker.io/drillster/drone-email:latest
# resources:
# limits:
# cpu: 50
# memory: 25M
# when:
# status:
# - changed
# - failure
# trigger:
# event:
# - push
# repo:
# - fh-trier/linux_ws2122

12
.editorconfig Normal file
View File

@ -0,0 +1,12 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false
[Makefile]
indent_style = tab

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
Makefile eol=lf

225
.gitignore vendored Normal file
View File

@ -0,0 +1,225 @@
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.fmt
*.fot
*.cb
*.cb2
## Intermediate documents:
*.dvi
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
# *.eps
*.pdf
## Generated if empty string is given at "Please type another file name for output:"
#.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex(busy)
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.pre
*.snm
*.vrb
# changes
*.soc
# cprotect
*.cpt
# elsarticle (documentclass of Elsevier journals)
*.spl
# endnotes
*.ent
# fixme
*.lox
# feynmf/feynmp
*.mf
*.mp
*.t[1-9]
*.t[1-9][0-9]
*.tfm
#(r)(e)ledmac/(r)(e)ledpar
*.end
*.?end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
*.glsdefs
# gnuplottex
*-gnuplottex-*
# gregoriotex
*.gaux
*.gtex
# hyperref
*.brf
# knitr
*-concordance.tex
# TODO Comment the next line if you want to keep your tikz graphics files
*.tikz
*-tikzDictionary
# listings
*.lol
# makeidx
*.idx
*.ilg
*.ind
*.ist
# minitoc
*.maf
*.mlf
*.mlt
*.mtc[0-9]*
*.slf[0-9]*
*.slt[0-9]*
*.stc[0-9]*
# minted
_minted*
*.pyg
# morewrites
*.mw
# nomencl
*.nlo
# pax
*.pax
# pdfpcnotes
*.pdfpc
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# scrwfile
*.wrt
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# pdfcomment
*.upa
*.upb
# pythontex
*.pytxcode
pythontex-files-*/
# thmtools
*.loe
# TikZ & PGF
*.dpth
*.md5
*.auxlock
# todonotes
*.tdo
# easy-todo
*.lod
# xindy
*.xdy
# xypic precompiled matrices
*.xyc
# endfloat
*.ttt
*.fff
# Latexian
TSWLatexianTemp*
## Editors:
# WinEdt
*.bak
*.sav
# Texpad
.texpadtmp
# Kile
*.backup
# KBibTeX
*~[0-9]*
# auto folder when using emacs and auctex
/auto/*
# expex forward references with \gathertags
*-tags.tex
# Tmp files
git-id.tmp
git-date.tmp
git-url.tmp

15
.latexmkrc Normal file
View File

@ -0,0 +1,15 @@
add_cus_dep('glo', 'gls', 0, 'run_makeglossaries');
add_cus_dep('acn', 'acr', 0, 'run_makeglossaries');
sub run_makeglossaries {
if ( $silent ) {
system "makeglossaries -q '$_[0]'";
}
else {
system "makeglossaries '$_[0]'";
};
}
push @generated_exts, 'glo', 'gls', 'glg';
push @generated_exts, 'acn', 'acr', 'alg';
$clean_ext .= ' %R.ist %R.xdy';

90
Makefile Normal file
View File

@ -0,0 +1,90 @@
# VERSION / RELEASE
# If no version is specified as a parameter of make, the last git hash
# value is taken.
VERSION?=$(shell git describe --abbrev=0)+hash.$(shell git rev-parse --short HEAD)
# CONTAINER_RUNTIME
# The CONTAINER_RUNTIME variable will be used to specified the path to a
# container runtime. This is needed to start and run a container images.
CONTAINER_RUNTIME?=$(shell which docker)
# BUILD_IMAGE
# Definition of the container build image, in which the BInary are compiled from
# source code
BUILD_IMAGE_REGISTRY:=docker.io
BUILD_IMAGE_NAMESPACE:=volkerraschek
BUILD_IMAGE_NAME:=container-latex
BUILD_IMAGE_VERSION:=latest-archlinux
BUILD_IMAGE_FULL=${BUILD_IMAGE_REGISTRY}/${BUILD_IMAGE_NAMESPACE}/${BUILD_IMAGE_NAME}:${BUILD_IMAGE_VERSION}
BUILD_IMAGE_SHORT=${BUILD_IMAGE_NAMESPACE}/${BUILD_IMAGE_NAME}:${BUILD_IMAGE_VERSION}
# Input tex-file and output pdf-file
FILE_NAME=index
IDX_TARGET:=${FILE_NAME:%=%.idx}
PDF_TARGET:=${FILE_NAME:%=%.pdf}
TEX_TARGET:=${FILE_NAME:%=%.tex}
# PDF_TARGET
# ==============================================================================
${PDF_TARGET}: latexmk/${PDF_TARGET}
PHONY:=latexmk/${PDF_TARGET}
latexmk/${PDF_TARGET}:
latexmk \
-shell-escape \
-synctex=1 \
-interaction=nonstopmode \
-file-line-error \
-pdf ${TEX_TARGET}
PHONY+=pdflatex/${PDF_TARGET}
pdflatex/${PDF_TARGET}:
makeglossaries ${FILE_NAME}
makeindex ${FILE_NAME}
pdflatex \
-shell-escape \
-synctex=1 \
-interaction=nonstopmode \
-enable-write18 ${TEX_TARGET}
# CLEAN
# ==============================================================================
PHONY+=clean
clean:
git clean -fX
# CONTAINER STEPS - PDF_TARGET
# ==============================================================================
container-run/${PDF_TARGET}:
$(MAKE) container-run COMMAND=${@:container-run/%=%}
container-run/latexmk/${PDF_TARGET}:
$(MAKE) container-run COMMAND=${@:container-run/%=%}
container-run/pdflatex/${PDF_TARGET}:
$(MAKE) container-run COMMAND=${@:container-run/%=%}
# CONTAINER STEPS - CLEAN
# ==============================================================================
container-run/clean:
$(MAKE) container-run COMMAND=${@:container-run/%=%}
# GENERAL CONTAINER COMMAND
# ==============================================================================
PHONY+=container-run
container-run:
${CONTAINER_RUNTIME} run \
--rm \
--user $(shell id --user):${shell id --group} \
--volume $(shell pwd):/workspace \
${BUILD_IMAGE_SHORT} \
make ${COMMAND} \
VERSION=${VERSION} \
# PHONY
# ==============================================================================
# Declare the contents of the PHONY variable as phony. We keep that information
# in a variable so we can use it in if_changed.
.PHONY: ${PHONY}

71
README.md Normal file
View File

@ -0,0 +1,71 @@
# Linux WS20/21
[![Build Status](https://drone.cryptic.systems/api/badges/fh-trier/linux_ws2021/status.svg)](https://drone.cryptic.systems/fh-trier/linux_ws2021)
This repository contains the latex source code of the linux module on the
University of Applied Science for WS20/21.
The document contains all tasks which the students should could solve before
they write their linux exam.
## Compiling the PDF document
There are two ways to compile the PDF document. Since the templates contain all
dependencies to the package `minted`, it is probably easier to use a container
image to compile the document.
To do this, install docker or podman as container runtime and Make as build
tool. If you have docker or podman and Make installed execute `make
container-run/latexmk/index.pdf` to compile the PDF document by using a
container image.
If you don't want to install a container runtime and the build tool make, you
have to install texlive manually - [installation instructions](https://www.tug.org/texlive/).
## make commands
### clean
Deletes all files that were not checked in using git.
```bash
make clean
```
### container-run/latexmk
Uses a docker container to compile the PDF document with `latexmk` By default
the docker container `volkerraschek/container-latex:latest-ubuntu18.04` is used.
However, it can also be modified. The Makefile contains the variables with the
prefix `BUILD_IMAGE` to change the full qualified image path for this purpose.
However, you may have to change the docker command call in `container-run` if
necessary.
```bash
make container-run/latexmk/index.pdf
```
### container-run/pdflatex
Similar to container-run/latexmk/index.pdf, but in the container pdflatex will
be execute instead of latexmk.
```bash
make container-run/pdflatex/index.pdf
```
### latexmk
Executes latexmk natively in the system environment.
```bash
make latexmk/index.pdf
```
### pdflatex
Executes pdflatex natively in the system environment.
```bash
make pdflatex
```

3
awk/01-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
awk -F ":" '{print $0;}' /etc/passwd

3
awk/02-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
awk -F ":" 'BEGIN {printf "user badname shell\n";} {printf "%s %s %s\n", $1, $5, $7;}' /etc/passwd

9
awk/03-aufgabe.awk Normal file
View File

@ -0,0 +1,9 @@
#!/bin/awk
BEGIN {
printf "user badname shell\n"
}
{
if ( $3>=1000 ) printf "%s %s %s\n", $1, $5, $7;
}

3
awk/03-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
awk -F ":" -f 03-aufgabe.awk /etc/passwd

9
awk/04-aufgabe.awk Normal file
View File

@ -0,0 +1,9 @@
#!/bin/awk
BEGIN {
printf " user badname shell\n"
}
{
if (FNR >= 5 && FNR <= 10) printf "%s %s %s %s\n", FNR, $1, badname, $7;
}

3
awk/04-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
awk -F ":" -f 04-aufgabe.awk /etc/passwd

14
awk/05-aufgabe.awk Normal file
View File

@ -0,0 +1,14 @@
#!/bin/awk
function logical_decission(i, user, badname, shell) {
if (i >= 5 && i <= 10) printf "%s %s %s %s\n", i, user, badname, shell;
}
BEGIN {
printf " user badname shell\n"
}
{
logical_decission(FNR, $1, $5, $7)
}

3
awk/05-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
awk -F ":" -f 05-aufgabe.awk /etc/passwd

29
awk/06-aufgabe.awk Normal file
View File

@ -0,0 +1,29 @@
#!/bin/awk
function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s }
function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s }
function trim(s) { ; return rtrim(ltrim(s)); }
function validBool(s) {
if (s == "ja" || s == "nein") {
return "1";
} else {
return "0";
}
}
{
if (FNR > 1) {
if ( validBool($4) == "0" ) { next; }
if ( validBool($9) == "0" ) { next; }
if ( validBool($10) == "0" ) { next; }
if ( validBool($15) == "0" ) { next; }
if ( validBool($16) == "0" ) { next; }
if ( validBool($17) == "0" ) { next; }
if ( validBool($19) == "0" ) { next; }
if ( validBool($21) == "0" ) { next; }
if ( validBool($22) == "0" ) { next; }
if ( validBool($23) == "0" ) { next; }
}
print trim($0)
}

3
awk/06-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
cat ../csv/credit_master.csv | sed 's/"//g' | awk -F "," -f 06-aufgabe.awk > ../csv/credit_master_cleaned.csv

76
awk/07-aufgabe.awk Normal file
View File

@ -0,0 +1,76 @@
#!/bin/awk
BEGIN{
print "-- PostgreSQL-Statements generated by awk"
print "";
print "CREATE TABLE IF NOT EXISTS credit_master ("
print " lfdnr INTEGER PRIMARY KEY,";
print " kreditbe NUMERIC(11,2) NOT NULL,";
print " rsv BOOLEAN NOT NULL,";
print " geschlec BOOLEAN NOT NULL,";
print " age NUMERIC(2) NOT NULL,";
print " telefon BOOLEAN NOT NULL,";
print " kinderza NUMERIC(2) NOT NULL,";
print " anschrif BOOLEAN NOT NULL,";
print " buerge BOOLEAN NOT NULL,";
print " arbeitsd NUMERIC(2) NOT NULL,";
print " einkomme NUMERIC(7,2) NOT NULL,";
print " verfeink NUMERIC(7,2) NOT NULL,";
print " miete NUMERIC(7,2) NOT NULL,";
print " pkw BOOLEAN NOT NULL,";
print " vertraeg BOOLEAN NOT NULL,";
print " kredit BOOLEAN NOT NULL,";
print " ausgaben NUMERIC(7,2) NOT NULL,";
print " kunde BOOLEAN NOT NULL,";
print " dauerkun INTEGER NOT NULL,";
print " sparguth BOOLEAN NOT NULL,";
print " wertpapi BOOLEAN NOT NULL,";
print " rueckzah BOOLEAN NOT NULL";
print ");";
print "";
print "INSERT INTO credit_master (";
print " lfdnr,";
print " kreditbe,";
print " rsv,";
print " geschlec,";
print " age,";
print " telefon,";
print " kinderza,";
print " anschrif,";
print " buerge,";
print " arbeitsd,";
print " einkomme,";
print " verfeink,";
print " miete,";
print " pkw,";
print " vertraeg,";
print " kredit,";
print " ausgaben,";
print " kunde,";
print " dauerkun,";
print " sparguth,";
print " wertpapi,";
print " rueckzah";
print ") VALUES";
}
FNR > 1 {
$4 == "ja" ? $4 = "'1'" : $4 = "'0'"; # RSV
$5 == "männlich" ? $5 = "'1'" : $5 = "'0'"; # geschlec
$7 == "ja" ? $7 = "'1'" : $7 = "'0'"; # telefon
$9 == "ja" ? $9 = "'1'" : $9 = "'0'"; # anschrif
$10 == "ja" ? $10 = "'1'" : $10 = "'0'"; # buerge
$15 == "ja" ? $15 = "'1'" : $15 = "'0'"; # pkw
$16 == "ja" ? $16 = "'1'" : $16 = "'0'"; # vertrag
$17 == "ja" ? $17 = "'1'" : $17 = "'0'"; # kredit
$19 == "ja" ? $19 = "'1'" : $19 = "'0'"; # kunde
$21 == "ja" ? $21 = "'1'" : $21 = "'0'"; # sparguth
$22 == "ja" ? $22 = "'1'" : $22 = "'0'"; # wertpapi
$23 == "ja" ? $23 = "'1'" : $23 = "'0'"; # rueckzah
printf "(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s),\n", $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23;
}

3
awk/07-aufgabe.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
cat ../csv/credit_master_cleaned.csv | awk -F "," -f 07-aufgabe.awk > ../sql/credit_master_cleaned.sql

201
chapters/01-ssh.tex Normal file
View File

@ -0,0 +1,201 @@
% <#>-----------------------------------------------------------------------<#>
\section{SSH}%
\label{sec:ssh}
Genau so wie eine Anmeldung am Linux-Rechner über ein Terminal (\textit{tty}),
ist auch die Anmeldung eines Benutzers über das Netzwerk möglich. Das gleichnamige Programm und Protokoll \acrfull{acr:telnet} wurde durch das gleichnamige Programm und Protokoll \acrfull{acr:ssh} in laufe der Zeit ersetzt.
Beim ersten Implementierung \acrshort{acr:ssh} von wird eine unverschlüsselte
Verbindung zwischen den beteiligten Rechnern aufgebaut und die Identifizierung
des Benutzers erfolgt nur durch dessen Namen und Passwort. Beim der zweiten
Implementierung von \acrshort{acr:ssh}, wird eine verschlüsselte Verbindung
aufgebaut, die sowohl das Abhören der Login-Daten, also auch der später
gesendeten Daten nahezu unmöglich macht. Es wird sowohl ein rechnerspezifischer
Schlüssel als auch ein benutzerspezifischer Schlüssel verwendet. Zu Testzwecken
ist natürlich auch eine Verbindung zu dem eigenen Rechner (localhost) möglich.
% #>------------------------------------------------------------------------<#
\subsection{Relevante Befehle für die weiteren Übungen}%
\label{sec:ssh.relevante_befehle_fuer_die_weiteren_uebungen}
\begin{itemize}[label={},itemsep=0pt]
\item \textit{ssh:} Stellt eine verschlüsselte Verbindung zwischen zwei
Rechnern her, über die neben der Shell auch andere Programme der
\acrshort{acr:gui} angesprochen werden können.
\item \textit{scp:} Ermöglicht das bidirektionale kopieren von Dateien und Verzeichnissen zwischen zwei Rechnern über eine \acrshort{acr:ssh}-Verbindung.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Relevante Konfigurationsdateien}%
\label{sec:ssh.relevante_konfigurationsdateien}
\begin{itemize}[label={}]
\item \textit{/etc/ssh/sshd\_config:} Konfigurationsdatei des
\acrshort{acr:ssh}-Servers.
\item \textit{/etc/ssh/ssh\_config:} Systemweite \acrshort{acr:ssh}-Client Konfiguration.
\item \textit{\textasciitilde/.ssh:} Enthält Benutzerspezifische \acrshort{acr:ssh}-Client Konfigurationen und Metainformationen.
\end{itemize}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2a:} Erkundigen Sie sich nach ihren
\acrshort{acr:ssh}-Zugangsdaten der Hochschule Trier.
\item \textbf{Aufgabe 2b:} Melden Sie sich mit ihren
\acrshort{acr:ssh}-Zugangsdaten per \acrshort{acr:ssh} an dem Rechner
\textit{ssh.hochschule-trier.de} an.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Authentifizierungsverfahren}%
\label{sec:ssh.authentifizierungsverfahren}
Bei \acrshort{acr:ssh} werden asymetrische Verschlüsselungsverfahren (Public-Key
Verfahren) eingesetzt. Wie Sie bei der ersten Verbindung bereits festgestellt
haben, werden die SSH-Server durch ein Schlüsselpaar identifiziert (\textit{Sie
mussten den öffentlichen Schlüssel des Servers bei der ersten Verbindung
akzeptieren}). In einer Umgebung mit erhöhtem Sicherheitsbedarf würde man den
angezeigten Fingerabdruck des Schlüssels mit einem vorher über einen anderen
Kanal übermittelten Fingerabdruck vergleichen, um eine sichere Verbindung zu
einem gefälschten Server zu vermeiden.
Die akzeptierten öffentlichen Schlüssel des Servers werden zur Abwehr von
Man-in-the-Middle Attacken in der Datei \textit{known\_hosts} gespeichert. Diese
befindet sich im Unterverzeichnis \textit{.ssh} des Heimatverzeichnis des
Benutzers.
Solange der private Schlüssel nicht abhanden kommt und auf dritten Server
repliziert und konfiguriert wird, ist bei der aktuellen Protokollversion 2 keine
umbemerkte Man-in-the-Middle Attacke möglich. Passt der auf dem Client
gespeicherte öffentliche Schlüssel nicht zu dem öffentlichen Schlüssel, den der
Server beim Verbindungsaufbau übermittelt, wird der weitere Verbindungsaufbau
mit einer entsprechenden Warnung abgebrochen.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 3a:} Nachdem Sie sich das erste mal per \textit{ssh} mit
dem \acrshort{acr:ssh}-Server der Hochschule Trier erfolgreich verbunden
haben. Überprüfen Sie die Dateiberechtigungen für den Ordner
\textit{\textasciitilde/.ssh} auf ihrer lokalen VM. Was fällt Ihnen in Vergleich zu anderen Verzeichnissen auf?
\end{itemize}
Bisher melden Sie sich an ihrem virtuellen Server oder den der Hochschule Trier
mit Benutzername und Passwort an. Die Daten werden zwar verschlüsselt übertragen
und können daher auch nicht abgehört werden, aber ein Angreifer kann beliebig
viele Passwörter per Brute-Force-Attacke an ihrem oder dem Server der Hochschule
Trier ausprobieren. Bei schwachen Passwörtern wird es daher nicht allzu lange
dauern, bis ein ernsthafter Angreifer erfolg hat. Bei einer frisch in Betrieb
genommenen virtuellen Maschine in einem Rechenzentrum dauert es meist nur wenige
Stunden, bis der erste derartige Angriff erfolgt! Daher sollte man so schnell
wie möglich auf ein besseres Verfahren umstellen.
Ähnlich wie die Authentifizierung der Rechner kann auch die Authentifizierung
der Benutzer per Public-Key Verfahren konfiguriert werden. Der Benutzer, der
sich unter einem entfernten Benutzer anmelden möchte, muss auf seinem lokalen
Rechner ein Schlüsselpaar generieren und den öffentlichen Schlüssel im
Heimatverzeichnis des entfernt liegenden Benutzer hinzufügen. Bei einem späteren
Login wir dann mit Hilfe des privaten Schlüssels des Client festgestellt,
dass der Anfragende tatsächlich der berechtigte Benutzer ist.
Die Schlüssel werden ebenfalls im Verzeichnis \textit{\textasciitilde/.ssh}
gespeichert. Ändert man bei der Erzeugung des Schlüsselpaares den dazugehörigen
Dateinamen, muss dieser bei jeder Verwendung angegeben werden! Alternativ kann
auch die Konfigurationsdatei \textit{\textasciitilde/.ssh/config} erstellt
werden, um dort den zugehörigen Schlüssel explizit anzugeben. Das Schlüsselpaar
kann optional mit einer Passphrase (Passwort) gesichert werden, falls man jedoch
automatische Logins z.B. für Backups wünscht, sollte man auf diese zusätzliche
Sicherung verzichten.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 3b:} Generieren Sie für ihren lokalen Benutzer eine
Schlüsselpaar mit dem \textit{ed25519} Algorithmus. Der Befehl \textit{ssh-keygen}
erzeugt Schlüsselpaare. Informieren Sie sich über \textit{ssh-keygen} per \textit{man ssh-keygen}.
\item \textbf{Aufgabe 3c:} Ermitteln Sie mit Hilfe der man-page via
\textit{man ssh-keygen} den Namen der Datei, in der der öffentliche Schlüssel
auf dem entfernten Rechner hinterlegt werden muss.
\item \textbf{Aufgabe 3d:} Mit dem Befehl \textit{scp} können Dateien über ein
\acrshort{acr:ssh}-Tunnel von einem Rechner zu einem anderen kopiert werden.
Die Syntax lautet: \textit{scp quelle ziel}. Beide Adressen enthalten einen
Pfad an dem die Ressourcen zu finden bzw. zu kopieren sind. Nur die entfernte
Adresse benötigt zusätzlich noch weitere Informationen wie Benutzername und
Rechnername bzw. IP des entfernten Systems. Die Adresse würde folgendem Schema
entsprechen \textit{user@rechner:pfad}. Kopieren Sie mit Hilfe von
\textit{scp} ihren öffentlichen Schlüssel in das Heimatverzeichnis ihres
entfernten Benutzers.
\item \textbf{Aufgabe 3e:} Der kopierte Schlüssel auf dem entfernten System
muss der Datei aus Aufgabe 3c hinzugefügt werden.
\item \textbf{Aufgabe 3f:} Nachdem der öffentliche Schlüssel erfolgreich
kopiert und konfiguriert wurde, öffnen Sie eine zweite
\acrshort{acr:ssh}-Verbindung ohne Eingabe des Passworts.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Absicherung des SSH-Servers}%
\label{sec:ssh.absicherung_des_ssh-servers}
Nachdem die Authentifizierung mit dem Public-Key-Verfahren erfolgreich getestet
wurde, kann im nächsten Schritt die unsichere Passwort-Authentifizierung auf dem
Server abgeschaltet werden. Dabei ist zu beachten, dass bei einem Neustart des
\acrshort{acr:ssh}-Servers bestehende Verbindungen gehalten werden. Vor dem
Logout sollte daher nach einer Konfigurationsänderung immer getestet werden, ob
der Login noch möglich ist. Falls man sich bei dieser Gelegenheit selbst vom
Server aussperrt, sind "Helping Hands" vom Provider meist nicht billig zu haben.
\begin{info-popup}
Dies ist für den Server \textit{ssh.hochschule-trier.de} nicht möglich, mangels
Berechtigungen. Führen Sie daher die Abschaltung an ihrem lokalen \acrshort{acr:ssh}-Server
durch.
\end{info-popup}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 4a:} Wie heißt der Eintrag in der Konfigurationsdatei
des Server, mit dem der Zugang für den Benutzer \textit{root} eingestellt
werden kann? Genaueres Betrachten der Konfigurationsdatei sollte schon zum
Ergebnis führen.
\item \textbf{Aufgabe 4b:} Stellen Sie diesen Eintrag so ein, dass für
\textit{root} nur noch der Zugang per Public-Key-Authentifizierung möglich
ist. Lesen Sie die Dokumentation für weitere Informationen.
\item \textbf{Aufgabe 4c:} Mit welchem Konfigurationswert kann das Verhalten
aus Aufgabe 4b auch für normale Benutzer erreicht werden? Informieren Sie sich
auch hier über die Dokumentation.
\item \textbf{Aufgabe 4d:} Stellen Sie das Verhalten so ein, dass für normale
Benutzer nur noch Zugang per Public-Key-Authentifizierung möglich ist.
\item \textbf{Aufgabe 4e:} Nach dem Speichern dieser Änderungen muss der
\acrshort{acr:ssh}-Dienst mit \textit{systemctl restart ssh} neu gestartet werden
\item \textbf{Aufgabe 4f:} Testen Sie die korrekte Funktionsfähigkeit dieser
Änderung mir einer zweiten \acrshort{acr:ssh}-Verbindung.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Client-Konfiguration}%
\label{sec:ssh.client-konfiguration}
Da Sie nun den Server erfolgreich auf Public-Key-Authentifizierung umgestellt
haben, kann im nächsten Schritt die \acrshort{acr:ssh}-Client Konfiguration
angepasst werden. Dazu ist die Datei \textit{\textasciitilde/.ssh/config}
notwendig. Der \acrshort{acr:ssh}-Client liest die Datei ein und setzt die
Konfiguration, welcher für den Verbindungsaufbau notwendig ist, rekursiv
abhängig von dem DNS-Namen, zusammen.
Möchte man Beispielsweise eine Verbindung zu \textit{verwaltung.example.local}
aufbauen. Werden zuerst alle Konfigurationsoptionen, welche für
\textit{verwaltung.example.local} definiert wurden, angewendet. Als nächstes
sucht der \acrshort{acr:ssh}-Client nach Konfigurationsoptionen, welche für
\textit{*.example.local} definiert wurden, anschließend für \textit{*.local} und
zum Schluss für \textit{*}. Konfigurationsoptionen, welche einmal definiert
wurden, können nicht mehr durch andere Optionen, welche in einem höhren
Scope definiert wurden, übersteuert werden.
\begin{itemize}[label={}]
\item \textbf{Aufgabe 5a:} Erstellen Sie die Datei
\textit{\textasciitilde/.ssh/config} und setzen Sie die entsprechenden
Berechtigungen.
\item \textbf{Aufgabe 5b:} Erstellen Sie einen Eintrag in der Konfiguration
für alle Verbindungen. Definieren Sie dort, welcher Schlüssel zur
Authentifizierung verwendet werden soll.
\item \textbf{Aufgabe 5c:} Erstellen Sie einen Eintrag in der Konfiguration
für alle Verbindungen, welche gegen die Domain \textit{*.hochschule-trier.de}
aufgebaut werden. Für die Domain \textit{*.hochschule-trier.de} soll der Port
22 verwendet werden. Die Authentifizierung per Passwort und der Verbindungsaufbau
über IPv6 soll nicht verwendet werden.
\item \textbf{Aufgabe 5d:} Erstellen Sie einen Eintrag in der Konfiguration
für die Verbindung \textit{ssh.hochschule-trier.de}. Geben Sie dort den
Benutzernamen an unter welchen Sie sich anmelden möchten.
\end{itemize}

208
chapters/02-dns.tex Normal file
View File

@ -0,0 +1,208 @@
% <#>-----------------------------------------------------------------------<#>
\section{DNS}%
\label{sec:dns}
% #>------------------------------------------------------------------------<#
\subsection{Aufbau des DNS}%
\label{sec:dns.aufbau}
Die Adressierung der Rechner in IP-basierten Netzen erfolgt über die IP-Adresse
des angesprochenen Rechners. Da der Mensch sich Nummernfolgen schlecht merken
kann, wurde schon früh eine Ersetzung der Nummern durch Namen auf der
Benutzerschnittstelle eingeführt. Die ursprüngliche Zuordnungsmethode wird auch
heute noch in kleinen Netzen angewendet: jeder Rechner im Netz verfügt über eine
Datei mit zuordnungen von Namen zu Nummern. Unter Unix-artigen Betriebssystemen
ist dies die Datei \textit{/etc/hosts}.
\begin{verbatim}
127.0.0.1 localdomain.localhost localhost
::1 localdomain.localhost localhost
\end{verbatim}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1a:} Überprüfen Sie ihre \textit{hosts} Datei, ob dort
abweichende Zuordungen zu der obrigen Ausgabe definiert sind
\item \textbf{Aufgabe 1b:} Welche Website wird ihnen im Browser dargestellt,
wenn Sie den folgenden Eintrag in die Datei \textit{hosts} aufnehmen und per
Browser die Seite \textit{hello-world.local} aufrufen? \texttt{198.145.29.83
hello-world.local}
\item \textbf{Aufgabe 1b:} In welchem Pfad findet man die entsprechende Datei
in Windows Systemen?
\end{itemize}
Dieses Verfahren der Namensauflösung führt in großen Netzwerken schnell zu
Problemen. Alle beteiligten Rechner benötigen in ihrer Version der Datei die
Zuordnungen aller Rechner, was die zentrale Verwaltung der Zuordnungen schnell
sehr aufwändig macht. Als Folge dieser Erkenntnis wurde das \acrfull{acr:dns}
entwickelt, das eine verteile Datenbank darstellt, bei der einzelne Server für
genau beschriebene Teilbereiche verantwortlich sind.
Den Namensraum im Internet ist hierarchisch gegliedert, ausgehend von der
höchsten Ebene, den sog. \acrfullpl{acr:tld}, können viele untergeordnete Ebenen
(Domains) eingefügt werden. Da die Internet-Entwicklung in den USA begann,
teilten die ersten \acrshortpl{acr:tld} den amerikanischen Netzbereich auf (z.B.
com, edu und org). Später kamen dann weitere \acrshortpl{acr:tld} für jedes Land
hinzu, die den genormten Länderkürzeln entprechen (ISO 3166), beispielsweise be,
de, nl usw. In der jüngsten Entwicklung wurden weitere allgemeine
\acrshortpl{acr:tld} hinzugefügt. Beispielsweise info, firm, museum, movie und
berlin.
Bei Domänennamen wird die Groß- und Kleinschreibung nicht beachtet, \textbf{edu}
und \textbf{EDU} bedeuten das gleiche. Einzelne Teil-Domainnamen dürfen maximal
63 Zeichen lang sein, der vollständige Domainname, \acrfull{acr:fqdn}, darf
nicht länger als 255 Zeichen sein. Für die Genehmigung eines neuen Domainnamens
ist die Verwaltung der nächst höheren Domain zuständig, für die Root-Zone und
damit die \acrshortpl{acr:tld} ist dies die \acrfull{acr:icann}.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2a:} Für welche Verwaltungsmaßnahmen ist die
\acrshort{acr:icann} verantwortlich? Nutzen Sie die Internetpräsenz der
\acrshort{acr:icann}, um die Frage zu beantworten.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Betrieb einer Domain}%
\label{sec:dns.betrieb_einer_domain}
Für jede offiziell registrierte Domain müssen mindestens zwei DNS-Server
eingerichtet werden, die in unterschiedlichen Subnetzen stehen müssen. Einer
dieser Server wird dann als Primary, der andere als Replica betrieben.
Änderungen müssen dann nur noch am Primary vorgenommen werden, der oder die
Replicas werden durch den Primary über die Änderungen informiert, worauf ein
Zonentransfer der Daten vom Replica veranlast wird.
Sucht ein Rechner die IP-Nummer zu einem Namen, wird er zuest den DNS-Server,
der voreingestellt ist, befragen. Dies ist meist der Server der eigenen Domain
bzw. des eigenen Providers. Für Heimnetzwerke stellt beispielsweise der Router
einen DNS-Server bereit. Hat dieser Server den gewünschten Datensatz in seiner
Datenbank, so kann er die Anfrage sofort beantworten (Authorative Answer). Ist
der Datensatz nicht vorhanden, kann je nach Konfiguration ein Server aus einer
höheren Ebene befragt werden, der dann den zuständigen Server kennt oder
seinerseits die Anfrage wieder nach oben weiterreicht. Der Server kann jedoch
auch als Antwort dem Client mitteilen, welchen Server er fragen soll, um seine
Anfrage zu beantworten. Jeder DNS-Server muss mindestens die DNS-Server seiner
direkt untergeordneten Domains kennen, um Anfragen hierfür weiterreichen zu
können und er muss die Adressen aller Root-Server kennen.
Für die Verwaltung des Namesraums wird dieser in Zonen aufgeteilt. Ein
DNS-Server kann für eine oder mehrere DNS-Zonen verantwortlich sein. Es gibt
üblicherweise Zonen für die Vorwärtsauflösung (Forward Lookup) und
Rückwärtsauflösung (Reverse Lookup). Vorwärtsauflösung bedeutet, dass für einen
gegebenen Rechnernamen eine IP-Adresse gesucht wird. Rückwärtsauflösung bedeutet
dementsprechend, dass für eine gegebene IP-Adresse ein Rechnername gesucht wird.
Für jede Zone werden die Informationen als sogenannte \acrfullpl{acr:rr}
gespeichert. Dies sind die gängigen \acrshortpl{acr:rr}:
\begin{itemize}[itemsep=0pt]
\item[\textbf{\acrshort{acr:soa}}] \acrfull{acr:soa} markiert den Start einer
DNS-Zone mit verschiedenen allgemeinen Informationen
\item[\textbf{A}] Enthält die IPv4-Adresse zu einem gegebenen Rechnernamen
\item[\textbf{AAAA}] Enthält die IPv6-Adresse zu einem gegebenen Rechnernamen
\item[\textbf{NS}] Enthält den Rechnernamen eines für die Domain
verantwortlichen DNS-Servers. Darf nicht auf einen \textit{CNAME} Eintrag
verweisen!
\item[\textbf{MX}] Enthält die Prioritätsangabe und den Rechnernamen eines
zuständigen Mailservers. Darf nicht auf einen \textit{CNAME} Eintrag
verweisen!
\item[\textbf{PTR}] Enthält den Rechnernamen zu einer gegebenen IP-Adresse
(IPv4 oder IPv6)
\item[\textbf{SSHFP}] Enthält den Fingerabdruck des privaten SSH-Schlüssels,
welcher auf dem jeweiligen Rechner beim Verbindungsaufbau abgefragt und
überprüft wird. Ein Vergleich der Fingerabdrücke aus dem DNS mit dem, welcher
der entfernte Server anbietet, deckt so einen möglichen Man-in-Middle Angriff
auf.
\end{itemize}
Clientseitig können die Programme \textbf{dig}, \textbf{resolvectl},
\textbf{nslookup} und \textbf{host} zur Abfrage verwendet werden. Diese Abfragen
werden normalerweise über das Transportprotokoll UDP abgewickelt und sind an den
Port 53 gerichtet.
Lesen Sie die Dokumentation eines der oben genannten Programme oder informieren
Sie sich im Internet, um folgende Fragen zu beantworten:
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2a:} Wann wird bei DNS das Transportprotokoll TCP eingesetzt?
\item \textbf{Aufgabe 2b:} Fragen Sie mit Hilfe eines der oben genannten
Programme den \acrshort{acr:rr} \textit{SSHFP} der Domain
\textit{pontos.cryptic.systems} ab. Welche Informationen werden zurück
gegeben?
\item \textbf{Aufgabe 2c:} Welche DNS-Server sind für die DNS-Zone
\textit{cryptic.systems} verantwortlich?
\item \textbf{Aufgabe 2c:} Welcher der DNS-Server ist für die Zone
\textit{cryptic.systems} der Primary und welcher der Replica DNS-Server?
\item \textbf{Aufgabe 2d:} Welche Mail-Server sind für die Zone
\textit{cryptic.systems} verantwortlich?
\item \textbf{Aufgabe 2e:} Welcher Mail-Server wird zur Zustellung von E-Mails
für die DNS-Zone \textit{cryptic.systems} privorisiert?
\item \textbf{Aufgabe 2f:} Welcher DNS-Name steht hinter der IP-Adresse
\textit{45.9.61.170}?
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Konfiguration des Clients}%
\label{sec:dns.konfiguration_des_clients}
Für die Namensauflösung auf der Seite des Clients ist der \textbf{Resolver}
verantwortlich, welcher von den Anwendungsprogrammen bei Bedarf automatisch
aufgerufen wird. Die Konfiguration erfolgt in Unix-Systemen über die Datei
\textit{/etc/resolv.conf}. Die wichtigsten Einträge in dieser Datei sind
\textit{domain} und \textit{nameserver}.
Immer seltener muss die Datei \textit{/etc/resolv.conf} manuell gepflegt werden.
Programme bzw. Dienste wie Beispielsweise der \textit{network-manager} oder
\textit{systemd-resolved} erstellen die Datei automatisch anhand der
Informationen, welche Sie per DHCP erhalten haben. Ändert man direkt den Inhalt
der Datei, kann dies dazu führen, dass das Programm oder der Dienst die
Einstellungen wieder überschreibt. Dem Programm bzw. dem Dienst muss daher
direkt mitgeteilt werden, welchen DNS-Server bzw. Domain der Rechner angehört,
um ein überschreiben zu vermeiden.
Mit dem Eintrag \textit{domain} wird festgelegt, welcher Domainname
standardmäßig an unvollständige Namen angehängt wird, bevor die Anfrage
abgesendet wird. Als unvollständig werden in der Regel Namen betrachtet, die
keinen Punkt enthalten. Es kann hier eine Liste mehrere Domainnamen angegeben
werden.
Mit dem Eintrag \textit{nameserver} wird angegeben, welcher DNS-Server für eine
Anfrage angesprochen wird. Zu Erhöhung der Redundanz ist es möglich, mehrere
Einträge dieser Art vorzunehmen. Ist der erste DNS-Server nicht erreichbar, wird
der nächste aus der Liste gefragt.
Die Datei \textit{/etc/nsswitch.conf} ist eine weitere Konfigurationsdatei aus
dem Bereich der Namensauflösung, in der eingestellt wird, in welcher Reihenfolge
interne und externe Quellen für die Namensauflösung verwendet werden. Wenn
folgende Zeile enthalten ist, wird zuerst in der lokalen Datei
\textit{/etc/hosts} gesucht. Wird dort kein passender Eintrag gefunden, wird das
DNS abfragt.
\begin{verbatim}
hosts: files dns
\end{verbatim}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 3a:} In Kapitel \ref{sec:network} haben Sie erfolgreich
\textit{systemd-networkd} konfiguriert. Passen Sie ihre Konfiguration so an,
dass primär der DNS-Server \textit{8.8.8.8} und sekundär der DNS-Server
\textit{8.8.4.4} für ihren Netzwerkadapter verwendet wird.
\item \textbf{Aufgabe 3b:} Überprüfen Sie die Konfiguration mit dem Aufruf von
\textit{resolvectl}. Beide DNS-Server sollten unter Ihrem Netzwerkadapter
gelistet und zusätzlich in der Datei \textit{/etc/resolv.conf} aufgeführt
sein.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Einstellen des Rechnernamens}%
\label{sec:dns.einstellen_des_rechnernamens}
Der Rechnername ist in der Datei \textit{/etc/hostname} gespeichert. Nach
Änderung der Datei ist es sinnvoll, den Rechner neu zu starten, um die Änderung
allen Diensten bekannt zu machen.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 4a:} Ändern Sie den Rechnernamen ab und starten Sie das System neu
\item \textbf{Aufgabe 4b:} Nutzen Sie eines der Programme zur Namensauflösung,
um die IP-Adresse ihres Rechners anhand des neuen Rechnernamens durch den im
lokalen Netzwerk befindlichen DNS-Server auflösen zu lassen. Überprüfen Sie,
ob die IP-Adresse mit der IP-Adresse ihrer Netzwerkkarte übereinstimmt.
\end{itemize}

274
chapters/03-network.tex Normal file
View File

@ -0,0 +1,274 @@
% <#>-----------------------------------------------------------------------<#>
\section{Netzwerk}%
\label{sec:network}
% #>------------------------------------------------------------------------<#
\subsection{Netzwerkkonfiguration}%
\label{sec:netzwerk.konfiguration}
Bei der Installation des Basis-Systems (Fedora Server Edition) wird das Paket
\textbf{network-manager} installiert. Dieses Paket ist für die einfache und
weitgehend automatische Netzwerk-Konfiguration auf Endbenutzer-Systemen
entwickelt worden. Daher ist es auf Serversystemen, bei denen eine statische
Adressvergabe oder es zu komplexen Netzwerkstrukturen kommen kann,
kontraproduktiv.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1a:} Stellen Sie mit dem Befehl \textit{yum list
installed} fest, ob das Paket mit dem Namensbestandteil
\textbf{network-manager} installiert ist.
\item \textbf{Aufgabe 1b:} Falls Sie hierbei fündig geworden sind, stoppen und
deaktivieren Sie den Dienst \textit{NetworkManager} per \textit{systemctl} und
\dots
\item \textbf{Aufgabe 1c:} überprüfen Sie mithilfe von \textit{systemctl}, ob
der Dienst \textit{NetworkManager} gestoppt und deaktiviert ist.
\end{itemize}
Nachdem Sie den Dienst \textit{NetworkManager} entfernt haben, stellen Sie
mithilfe von \textit{systemd} die Netzwerkkonfiguration ein und erstellen ggfl.
notwendige virtuelle Netzwerkkarten. \textit{systemd} unterteilt die
Netzwerkkonfiguration in drei unterschiedliche Dienste:
\begin{itemize}[label={},itemsep=0pt]
\item \textit{systemd-networkd:} Erstellt virtuelle Netzwerkkarten und richtet
diese als auch physische ein. Dadurch ist die Zuweisung einer dynamischen per
\acrshort{acr:dhcp} oder statischen IP-Adresse möglich.
\item \textit{systemd-resolved:} Kümmert sich um die Namensauflösung per
\acrshort{acr:dns}.
\item \textit{systemd-timesyncd:} Richtet die Uhrzeit mithilfe des
\acrfull{acr:ntp} auf dem System ein.
\end{itemize}
Die Dienste \textit{systemd-resolved} und \textit{systemd-timesyncd} rufen
notwendige Informationen von anderen Diensten auf dem System ab. Ein anpassen
des Standardverhaltens ist hier nicht notwendig.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1d:} Starten und aktivieren Sie die beiden Dienste
mithilfe des Befehls \textit{systemctl}.
\item \textbf{Aufgabe 1e:} Überprüfen Sie, ob die Dienste als \textit{active
(running)} markiert sind.
\item \textbf{Aufgabe 1f:} Zusätzlich überprüfen Sie, ob die Dienste auch als
\textit{enabled} markiert sind, sodass diese bei einem erneusten Systemstart
ausgeführt werden.
\end{itemize}
Die Netzwerkkonfiguration per \textit{systemd} wird über die unterschiedlichen
Dateiendungen \textit{.netdev} und \textit{.network} im Verzeichnis
\textit{/etc/systemd/network} geregelt.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1g:} Rufen Sie die Dokumentation von
\href{https://www.freedesktop.org/software/systemd/man/systemd.network.html}{systemd.network}
und
\href{https://www.freedesktop.org/software/systemd/man/systemd.netdev.html}{systemd.netdev}
auf und erklären Sie den Unterschied der beiden Konfigurationsdateien
\textit{.netdev} und \textit{.network}.
\end{itemize}
Mit dem Befehl \textit{ip link show} werden alle Netzwerkkarten, welches Ihr
System kennt ausgegeben.
\begin{bashcode}
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:b3:95:e4 brd ff:ff:ff:ff:ff:ff
\end{bashcode}
Das System, auf dem der Befehl ausgeführt wurde, kennt zwei Netzwerkadapter. Mit
dem Index 1 ist das \textit{loopback device} \textbf{lo} aufgeführt. Über das
\textit{loopback device} können Dienste, welche auf dem lokalen System
ausgeführt werden, per Netzwerk sich selbst oder andere Dienste adressieren bzw.
zugreifen. Dies ist durch die IP-Adresse \textit{127.0.0.1} oder den DNS-Namen
\textit{localhost} möglich.
Vorteil des \textit{loopback device} ist es, dass die Netzwerkpakete nicht den
Rechner verlassen. Dadurch wird unnötiger Netzwerkverkehr, welcher über das
physische Netzwerk geleitet wird, vermieden.
Mit dem Index 2 wird der Netzwerkadapter \textbf{enp1s0} geführt. Dieser besitzt
die MAC-Adresse \textit{52:54:00:b3:95:e4}. Der Netzwerkadapter ist als inaktiv
bzw. ausgeschaltet markiert. Dies kann durch die Information \textit{state DOWN}
entnommen werden. Dieser ist nicht konfiguriert und besitzt auch keine
IP-Adresse.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1h:} Ermitteln Sie ihren Netzwerkadapter, welcher nicht
konfiguriert wurde. Überprüfen Sie mit dem Befehl \textit{ip address show}, ob
ihr Netzwerkadapter eine IP-Adresse zugewiesen wurde.
\item \textbf{Aufgabe 1i:} Schauen Sie sich in der Dokumentation zu
\href{https://www.freedesktop.org/software/systemd/man/systemd.network.html}{systemd.network}
die Beispielkonfigurationen an und erstellen Sie für ihren Netzwerkadapter
eine passende Konfiguration.
Falls Sie die Konfiguration ihres lokalen Netzwerks nicht kennen, um ihrem
System eine statische IP-Adresse zu zuweisen, verwenden Sie
\acrshort{acr:dhcp}.
\item \textbf{Aufgabe 1j:} Starten und aktivieren Sie den Dienst
\textit{systemd-networkd} mithilfe von \textit{systemctl}.
\item \textbf{Aufgabe 1k:} Überprüfen Sie, ob der Dienst als \textit{active
(running)} markiert ist und \dots
\item \textbf{Aufgabe 1l:} ob dieser als \textit{enabled} markiert ist.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Routing}%
\label{sec:netzwerk.routing}
Das \acrfull{acr:ip} ist auf Schicht 3 des OSI-Modells angesiedelt. Es dient der
Strukturierung von großen Netzwerken, d.h der Aufteilung dieser Netze in
übersichtliche Teilnetze und der Verbindung dieser Teilnetze. \acrshort{acr:ip}
ist für die Vermittlung eines Weges, einer Route, zwischen zwei
Kommunikationspartnern zuständig. Diese Route muss auch über mehrere Teilnetze
hinweg gefunden werden. Die Verbindungspunkte zwischen Netzen werden als Router
oder Gateway bezeichnet.
Jeder Rechner, auch solche, die keine Routingfunktion haben, muss Informationen
zur Wegefindung im Netz speichern. Dies geschieht bei jedem
\acrshort{acr:ip}-fähigen Betriebssystem in einer Routingtabelle, die statisch
oder dynamisch verwaltet werden kann. In einem Maschennetz wie dem Internet ist
eine dynamische Verwaltung sinnvoll, da so die Wegewahl der aktuellen
Belastungssituation auf den verschiedenen Wegen angepasst werden kann. Auch bei
Ausfall einer Verbindung kann so automatisch eine Ersatzroute konfiguriert
werden. Bei einfachen Netzverbünden ohne Maschenstruktur wird statisches Routing
verwendet, was auch ohne Zusatzsoftware von den üblichen Betriebssystemen
geleistet werden kann.
% >---------------------------------------------------------------------------<
\subsubsection{Einfache Netze}%
\label{sec:netzwerk.routing.einfache-netze}
Selbst in \acrshort{acr:ip}-Netzen ohne Anbindung an andere Netze besitzt jeder
Rechner eine statische Routingtabelle in minimaler Größe. Die Tabelle enthält
mehrere Informationen, die wichtigsten sind in den ersten Spalten festgehalten.
Darunter wird das Zielnetzwerk, die verwendete Schnittstelle und das verwendete
Gateway aufgeführt. In diesem einfachsten Fall bleibt die Spalte für das Gateway
leer und es gibt nur einen Eintrag in jeder Tabelle. Diese minimale
Routingtabelle wird bei allen Betriebssystem mit der normalen
Netzwerkkonfiguration automatisch erstellt.
\begin{table}[H]
\footnotesize
\centering
\begin{tabularx}{17cm}{p{2.6cm}|p{2.6cm}|p{1.9cm}||p{2.6cm}|p{2.6cm}|p{1.9cm}}
\multicolumn{3}{c||}{\textbf{PC}} & \multicolumn{3}{c}{\textbf{Laptop}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway & Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.178.0/24 & enp1s0 & - & 192.168.178.0/24 & wlp5s1 & - \\
\end{tabularx}
\end{table}
\begin{table}[H]
\footnotesize
\centering
\begin{tabularx}{8.5cm}{p{2.6cm}|p{2.6cm}|p{1.9cm}}
\multicolumn{3}{c}{\textbf{Server A}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.178.0/24 & eth0 & - \\
\end{tabularx}
\end{table}
\begin{figure}[H]
\centering
\includegraphics[width=0.65\textwidth]{img/einfache-netze.png}
\end{figure}
% >---------------------------------------------------------------------------<
\subsubsection{Einfache Netze mit Internetanbindung}%
\label{sec:netzwerk.routing.einfache-netze-mit-internetanbindung}
Hat ein Netzwerk genau eine Anbindung an die anderen Netzwerke, erhält die
Routingtabelle auf jedem Rechner eine zusätzliche Zeile, in der angegeben wird,
auf welchem Weg die anderen Netzwerke erreicht werden können. Da alle Netzwerke
über den gleichen ersten Router erreicht werden, wird diese Zeile der
Routingtabelle als Standard- bzw. Default-Route bezeichnet. Dieses
Standard-Gateway muss bei allen Betriebssystemen gesondert konfiguriert werden.
\begin{table}[H]
\footnotesize
\centering
\begin{tabularx}{17cm}{p{2.6cm}|p{2.6cm}|p{1.9cm}||p{2.6cm}|p{2.6cm}|p{1.9cm}}
\multicolumn{3}{c||}{\textbf{PC}} & \multicolumn{3}{c}{\textbf{Laptop}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway & Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.178.0/24 & enp1s0 & - & 192.168.178.0/24 & wlp5s1 & - \\
0.0.0.0/0 & enp1s0 & 192.168.178.1 & 0.0.0.0/0 & wlp5s1 & 192.168.178.1 \\
\end{tabularx}
\end{table}
\begin{table}[H]
\footnotesize
\centering
\begin{tabularx}{8.5cm}{p{2.6cm}|p{2.6cm}|p{1.9cm}}
\multicolumn{3}{c}{\textbf{Server A}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.178.0/24 & eth0 & - \\
189.10.55.47/32 & ppoe1 & - \\
0.0.0.0/0 & ppoe1 & 189.10.55.47 \\
\end{tabularx}
\end{table}
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/einfache-netze-mit-internetanbindung.png}
\end{figure}
% >---------------------------------------------------------------------------<
\subsubsection{Zwei Netze mit Internetanbindung}%
\label{sec:netzwerk.routing.zwei-netze-mit-internetanbindung}
\begin{table}[H]
\footnotesize
\centering
\begin{tabularx}{17cm}{p{2.6cm}|p{2.6cm}|p{1.9cm}||p{2.6cm}|p{2.6cm}|p{1.9cm}}
\multicolumn{3}{c||}{\textbf{PC}} & \multicolumn{3}{c}{\textbf{Laptop}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway & Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.178.0/24 & enp1s0 & - & 192.168.178.0/24 & wlp5s1 & - \\
0.0.0.0/0 & enp1s0 & 192.168.178.1 & 0.0.0.0/0 & wlp5s1 & 192.168.178.1 \\
\multicolumn{6}{c}{} \\
\multicolumn{3}{c||}{\textbf{Server A}} & \multicolumn{3}{c}{\textbf{Server B}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway & Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.178.0/24 & eth0 & - & 192.168.178.0/24 & eth0 & 192.168.179.1 \\
192.168.179.0/24 & eth0 & 192.168.178.4 & 192.168.179.0/24 & eth1 & - \\
189.10.55.47/32 & ppoe1 & - & 0.0.0.0/0 & eth0 & 192.168.178.1 \\
0.0.0.0/0 & ppoe1 & 189.10.55.47 \\
\multicolumn{6}{c}{} \\
\multicolumn{3}{c||}{\textbf{Tablet}} & \multicolumn{3}{c}{\textbf{Smartphone}} \\
\hline
Zielnetz & Netzwerkadapter & Gateway & Zielnetz & Netzwerkadapter & Gateway \\
\hline\hline
192.168.179.0/24 & wlp7s3 & - & 192.168.179.0/24 & wlp3s8 & - \\
0.0.0.0/0 & wlp7s3 & 192.168.179.1 & 0.0.0.0/0 & wlp3s8 & 192.168.179.1 \\
\end{tabularx}
\end{table}
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/zwei-netze-mit-internetanbindung.png}
\end{figure}
\newpage
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2b:} Ermitteln Sie mithilfe des Befehls \textit{ip} Ihr
Gateway.
\item \textbf{Aufgabe 2c:} Erstellen Sie anhand des folgenden
Netzwerkdiagramms die Routingtabellen für alle abgebildeten Netzwerkgeräte.
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/aufgabe-netze-mit-internetanbindung.png}
\end{figure}

View File

@ -0,0 +1,673 @@
% <#>-----------------------------------------------------------------------<#>
\section{Benutzer, Gruppen und Dateiberechtigungen}%
\label{sec:benutzer-gruppen-und-berechtigungen}
Die Verwaltung von Benutzer, Gruppen und Dateiberechtigungen unter Unix-artigen
Systemen sind identisch. Das hat den Vorteil, dass es für Anwender einfacher ist
Benutzer, Gruppen und Dateiberechtigungen auf Linux Distributionen wie Debian,
Ubuntu, Linux Mint oder RHEL, CentOS, Fedora als auch BSD Distributionen wie
MacOS, FreeBSD oder OpenBSD zu übertragen.
Optional können durch sogenannte \acrfull{acr:acl} Berechtigungen
erweitert werden, um die Rechtevergabe für Benutzer und Gruppen noch feiner
einteilen zu können.
In der Praxis gibt es jedoch sehr selten Szenarien, bei denen dies notwendig ist.
Aus diesem Grund liefern manche Distributionen die notwendigen Programme zum
verfeinern der Rechtevergabe nicht standardmäßig aus.
% #>------------------------------------------------------------------------<#
\subsection{Benutzer und Gruppen}%
\label{sec:benutzer-gruppen-und-berechtigungen.benutzer-und-gruppen}
Linux ist als Mehrbenutzer-Betriebssystem entwickelt worden. Dies bedeutet, dass
mehrere Benutzer gleichzeit auf dem System Prozesse ausführen können. Dabei
werden die Berechtigungen auf Dateien und Verzeichnisse klar durch den Besitzer,
als auch durch die Gruppe, welche als mehrere Benutzern bestehen kann, geregelt.
% #>------------------------------------------------------------------------<#
\subsubsection{Benutzer}%
\label{sec:benutzer-gruppen-und-berechtigungen.benutzer-und-gruppen.benutzer}
Man unterscheidet bei Benutzern zwischen funktionalen und realen Benutzern.
Funktionale Benutzer werden vorwiegend für Dienste verwendet, um zu vermeiden,
dass der Dienst ungewollt auf Dateien und Verzeichnisse Zugriff erhält. Aus
diesem Grund wird auch vermieden, dass funktionale Benutzer eine Shell öffnen
können. Dazu später mehr.
Reale Benutzer sind natürliche Personen, die sich entweder direkt per
Desktopmanager, einer Shell oder über ein Protokoll (\acrshort{acr:rdp},
\acrshort{acr:ssh}, \acrshort{acr:vnc}) Zugang verschaffen.
Alle Benutzer werden in der Datei \textit{/etc/passwd} gelistet. Sie wird als
Tabellenform geführt, getrennt durch einen Doppelpunkt \textbf{:}. Zur
einfacheren Darstellung kann folgender Befehl verwendet werden.
\begin{bashcode}
cat /etc/passwd | column --table --separator :
\end{bashcode}
Die Spalten, exemplarisch für den Benutzer root, haben folgende Bedeutung:
\begin{itemize}[itemsep=0pt]
\item[\textbf{1. Spalte}] Name des Benutzers
\item[\textbf{2. Spalte}] Ehemals Spalte für das Kennwort. Das \textit{x}
kennzeichnet, dass für den Benutzer in der Datei \textit{/etc/shadow} ein
Kennwort existiert. Dazu später mehr.
\item[\textbf{3. Spalte}] Die ID des Benutzers. Wird oft auch als \textit{UID}
angegeben.
\item[\textbf{4. Spalte}] Die ID der Hauptgruppe. Wird oft auch als \textit{GID}
angegeben.
\item[\textbf{5. Spalte}] Erweiterter Name des Benutzers. Damit
nachvollziehbar ist, welchem Dienst oder welcher realen Person der Benutzer
zuzuordnen ist.
\item[\textbf{6. Spalte}] Das Heimatverzeichnis des Benutzers. Im Regelfall
wird dieses Verzeichnis betreten, sofern der Benutzer sich über eine
Login-Shell anmeldet. Die Tilde verweist auf das hier definierte
Heimatverzeichnis.
\item[\textbf{7. Spalte}] Enthält den absoluten Pfad zur Login-Shell. Dies ist
im Regelfall die \acrfull{acr:bash}. Um zu vermeiden, dass sich als Benutzer
eines Dienstes angemeldet werden kann, kann hier auch auf
\textit{/usr/bin/nologin} verwiesen werden.
\end{itemize}
Die 2. Spalte wurde ausgelagert nach \textit{/etc/shadow}, um die Sicherheit auf
dem System zu erhöhen. In der Datei \textit{/etc/shadow} werden weitere
Informationen gespeichert. Beispielsweise die Information, mit welchem
Hash-Algorithmus die Kennwörter gehasht wurden bzw. wie der Salt-Wert lautet.
Erzeugen Sie sich erneut mit dem genannten Befehl aus Kapitel
\ref{sec:benutzer-gruppen-und-berechtigungen.benutzer-und-gruppen.benutzer} eine
Ausgabe in tabellarischer Form für die Datei \textit{/etc/shadow}. Die Spalten
haben folgende Bedeutung:
\begin{itemize}[itemsep=0pt]
\item[\textbf{1. Spalte}] Name des Benutzers.
\item[\textbf{2. Spalte}] Das Kennwort, gespeichert als Hash mit Informationen
zum Hash.-Algorithmus. Der Wert \textit{!!} bedeutet, dass kein Kennwort
definiert wurde.
\item[\textbf{3. Spalte}] Enthält die Tage seit Beginn der Unix-Zeitrechnung,
wann das Kennwort zuletzt geändert wurde.
\item[\textbf{4. Spalte}] Tage bevor das Kennwort geändert werden muss.
\item[\textbf{5. Spalte}] Tage ab wann eine Warnung ausgegeben werden soll,
dass das Kennwort abläuft.
\item[\textbf{6. Spalte}] Tage bevor das Kennwort abläuft, nachdem keine
Anmeldung erfolgt ist.
\item[\textbf{7. Spalte}] Enthält die Tage seit Beginn der Unix-Zeitrechnung,
seit dem das Kennwort abgelaufen ist.
\item[\textbf{8. Spalte}] Reservierte Spalte. Wird aktuell nicht verwendet.
\end{itemize}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1a:} Ermitteln Sie den Hash-Algorithmus, welcher
verwendet wurde um Ihr Kennwort zu hashen.
\item \textbf{Aufgabe 1b:} Wann beginnt die Unix-Zeitrechnung?
\item \textbf{Aufgabe 1c:} Wann wurde zuletzt das Kennwort des Benutzers root geändert?
\item \textbf{Aufgabe 1d:} Ermitteln Sie die \textbf{User-ID} ihres aktuellen
Benutzers mithilfe eines Befehls, welcher in den GNU Core Utilities enthalten
und dem Bereich \glqq{}Shell Utilities\grqq{} zugeordnet ist.
\item \textbf{Aufgabe 1e:} Nutzen Sie den Befehl \textit{wc}, um alle
eingerichteten Benutzer auf ihrem System zu zählen. Lesen Sie die Manpage für
weitere Informationen zu diesem Befehl.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsubsection{Gruppen}%
\label{sec:benutzer-gruppen-und-berechtigungen.benutzer-und-gruppen.gruppen}
Ähnlich wie bei Benutzern gibt es auch Dateien in denen die Gruppen bzw.
Gruppenkennwörter festgehalten sind. Dies sind die Dateien \textit{/etc/group}
und \textit{/etc/gshadow}. Die beiden Dateien sind ähnlich wie
\textit{/etc/passwd} und \textit{/etc/shadow} aufgebaut. Sie enthalten jedoch
weniger Spalten.
Die Datei \textit{/etc/group} enthält eine Spalte für den Namen der Gruppe, ob
ein Eintrag in \textit{/etc/gshadow} vorhanden ist, die Gruppen-ID, als auch alle
Benutzer, welche der Gruppe angehören. Die Benutzer werden durch ein Komma.
Die Datei \textit{/etc/gshadow} enthält noch weniger Informationen. Die ersten
drei Spalten sind identisch zu den Spalten aus der Datei \textit{/etc/shadow}.
Die letzte Spalte enthält Benutzer, welcher das Kennwort ändern dürfen.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2a:} Ermitteln Sie die \textbf{Gruppen-ID} ihres
aktuellen Benutzers mithilfe eines Befehls, welcher in den GNU Core Utilities
enthalten und dem Bereich \glqq{}Shell Utilities\grqq{} zugeordnet ist.
\item \textbf{Aufgabe 2b:} Nutzen Sie den Befehl \textit{wc}, um die Gruppen
zu zählen. Lesen Sie die Manpage für weitere Informationen zu diesem Befehl.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsubsection{Benutzer root}%
\label{sec:benutzer-gruppen-und-berechtigungen.root}
Der Benutzer root besitzt auf allen Unix-artigen Systemen die User-ID und
Gruppen-ID 0. Er besitzt vollen Zugriff auf das gesamte System und damit auf
alle Dateien und Einstellungen aller Benutzer. Er kann beispielsweise ohne
Einschränkungen auf alle angeschlossenen Geräte unter \textit{/dev} zugreifen.
Der Benutzer root ist ein funktionaler Benutzer, mit dem sich reale Benutzer
anmelden können, um Befehle, welche einen höheren Berechtigungsgrad benötigen,
auszuführen. Durch die Verwendung des Benutzers root ist nachträglich nicht mehr
nachvollziehbar, welcher reale Benutzer welchen Befehl ausgeführt hat. Aus
diesem Grund und anderen Gründen wurde das Programm \textit{sudo} entwickelt.
% #>------------------------------------------------------------------------<#
\subsubsection{sudo}%
\label{sec:benutzer-gruppen-und-berechtigungen.sudo}
Das Programm \textit{sudo} führt den nachgestellten Befehl mit root
Berechtigungen aus. Mithilfe von sudo lässt sich die Verwendung von root
Berechtigungen auf einzelne Benutzer einschränken. Für die Verwendung von
\textit{sudo} muss ein Benutzer der Gruppe \textit{wheel} unter RHEL basierenden
Distributionen angehören oder der Gruppe \textit{sudo} für Debian basierende
Distributionen.
Mithilfe des Befehls \textit{visudo} lässt sich die Konfiguration von
\textit{sudo} bearbeiten. Dort kann unter anderem auch eingestellt werden, dass
der Aufruf eines Befehls mit \textit{sudo} keiner erneuten Kennworteingabe des
Benutzers benötigt.
Mit dem folgenden Beispiel kann ein realer Benutzer mit \textit{sudo} den Ordner
\textit{/mnt/sda1} erstellen, für welchen root Berechtigungen notwendig sind, da
root der Eigentümer des Verzeichnisses \textit{/mnt} ist.
\begin{bashcode}
sudo mkdir --parent /mnt/sda1
\end{bashcode}
Möchte man mehrere Befehle mit root Berechtigungen ausführen lohnt sich die
Anmeldung als root Benutzer von einem normalen Benutzer aus. Dies kann entweder
mit \textit{sudo -i} oder alternativ mit \textit{su} erreicht werden.
% #>------------------------------------------------------------------------<#
\subsubsection{Passwort ändern}%
\label{sec:benutzer-gruppen-und-berechtigungen.benutzer-und-gruppen.s}
Um das Passwort zu ändern reicht die Ausführung des Befehls \textit{passwd}.
Damit ist es möglich das Kennwort des gerade verwendeten Benutzers zu ändern.
Möchte man das Kennwort anderer Benutzer ändern, muss man root Berechtigungen
besitzen, sei es als Benutzer root oder per \textit{sudo}, und gibt hinter den
Befehl den Namen des Benutzers an, wessen Kennwort man ändern möchte.
Das Programm \textit{passwd} ändert dem entsprechend die Zeile in
\textit{/etc/shadow} für den Benutzer, für welchen das Passwort geändert werden
soll.
Nachteil von \textit{passwd} ist, dass es interaktiv bedient werden muss -
sprich, mit \textit{passwd} ist es nicht möglich Kennwörter von Benutzern per
Skript zu ändern. Aus diesem Grund wurde das Programm \textit{chpasswd}
entwickelt.
Allerdings möchte man nicht nur das Kennwort eines Benutzers ändern können,
sondern auch wann das Kennwort ablaufen soll oder ab wann das System eine
Warnung ausgeben soll. Mit Hilfe des Programms \textit{chage} ist dies möglich.
% #>------------------------------------------------------------------------<#
\subsubsection{Gruppe hinzufügen, bearbeiten und löschen}%
\label{sec:benutzer-gruppen-und-berechtigungen.gruppen.add-mod-rm}
Das Bearbeiten der Gruppen direkt in der Datei \textit{/etc/group} sollte
vermieden werden und stattdessen auf die Programme zurück gegriffen werden,
welche die Distribution bereit stellt.
Zum Erstellen, Bearbeiten und Löschen werden folgende Programme zur Verfügung
gestellt.
\begin{itemize}[label={},itemsep=0pt]
\item \textit{groupadd:} Erstellt eine neue Gruppe
\item \textit{groupmod:} Modifiziert eine bestehende Gruppe
\item \textit{groupdel:} Löscht eine Gruppe
\end{itemize}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 3a:} Estellen Sie die Gruppe \textit{hr} für
\textit{human resources} mit der \textit{GID} 2000.
\item \textbf{Aufgabe 3b:} Vergewissern Sie sich, dass in der Datei
\textit{/etc/group} die neue Gruppe mit entsprechender \textit{GID} angelegt wurde.
\item \textbf{Aufgabe 3c:} Benennen Sie die Gruppe \textit{hr} nach
\textit{dev} für \textit{development} um und überprüfen Sie, ob sich der Name
der Gruppe in der Datei \textit{/etc/group} geändert hat
\item \textbf{Aufgabe 3d:} Ändern Sie die \textit{GID} auf 3000 und überprüfen
Sie, ob diese sich in der Datei \textit{/etc/group} geändert hat.
\item \textbf{Aufgabe 3e:} Löschen Sie die Gruppe \textit{dev}
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsubsection{Benutzer hinzufügen, bearbeiten und löschen}%
\label{sec:benutzer-gruppen-und-berechtigungen.benutzer.add-mod-rm}
Ähnlich wie Gruppen können auch Benutzer hinzugefügt, modifiziert und gelöscht
werden. Auf folgende Befehle kann zurück gegriffen werden.
\begin{itemize}[label={},itemsep=0pt]
\item \textit{useradd:} Erstellt einen neuen Benutzer
\item \textit{usermod:} Modifiziert einen bestehenden Benutzer
\item \textit{userdel:} Löscht den Benutzer
\end{itemize}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 4a:} Erstellen Sie den Benutzer \textit{manfred} mit dem
Namen \textit{Manfred Mertens}. Der Benutzer nutzt die \acrlong{acr:bash}.
Sein Heimatverzeichnis soll unter \textit{/home} erstellt werden. Das Kennwort
lautet \textit{manni}. Seine Primärgruppe lautet \textit{manfred}. Als
\textit{UID} verwenden Sie \textit{2000}.
\item \textbf{Aufgabe 4b:} Setzen Sie das Ablaufdatum des Kennworts für den
Benutzer \textit{manni} auf den \textit{31. Juni 2021} und überprüfen Sie die
passende Spalte aus der Datei \textit{/etc/shadow}.
\item \textbf{Aufgabe 4c:} Fügen Sie den Benutzer der Gruppe \textit{wheel} hinzu.
\item \textbf{Aufgabe 4d:} Entfernen Sie den Benutzer \textit{manfred} aus der
Gruppe \textit{wheel} ohne ihn dabei aus anderen Gruppen zu entfernen.
\item \textbf{Aufgabe 4e:} Setzen Sie das Kennwort des Benutzers auf
\textit{manni-der-busfahrer}.
\item \textbf{Aufgabe 4f:} Entfernen Sie den Benutzer \textit{manfred} und
löschen Sie ggfls. seine Primärgruppe, sofern niemand mehr Mitglied ist.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Dateiberechtigungen}%
\label{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen}
% #>------------------------------------------------------------------------<#
\subsubsection{DOS Ideologie}%
\label{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.dos-ideologie}
Unter Windows sind Grundsätzlich alle Dateien, welche auf den Suffix
\textit{.exe} enden Ausführbar. Unix-artige Systeme interpretieren Dateiendungen
anders. Sie sind ausschließlich dafür da, damit Desktopmanager wie gnome,
cinnamon, kde, xfce oder andere erkennen, um welche Datei es sich hier handel
und mit welchen Programmen aus einer Liste diese geöffnet werden können.
Dies bedeutet, dass auch die PDF-Datei \texttt{Aufgabensammlung.pdf} ausführbar
sein kann, obwohl diese nur lesbar sein sollte, damit Programme wie evince oder
masterpdfeditor von ihr lesen können.
% #>------------------------------------------------------------------------<#
\subsubsection{Einfache Dateiberechtigungen}%
\label{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.einfach}
Unter Unix-artigen Systemen, welche die GNU Core Utilities verwenden, ist das
Programm \textit{ls} vorinstalliert. Das Programm dient zu Auflistung von
Dateien und Verzeichnissen.
Die Ausgabe ist eine Zusammenstellung von mehreren Einträgen unterschiedlicher
Auflistungen, um Dateiberechtigungen exemplarisch zu erklären.
\begin{verbatim}
drwxr-xr-x. 2 markus users 40 29. Sep 21:48 hello-world
-rw-r--r--. 1 christian users 0 29. Sep 21:48 hello-world2
srw-rw----. 1 root docker 0 5. Okt 19:34 docker.sock
lrwxrwxrwx. 1 markus markus 38 14. Apr 11:32 .g -> .gnupg
brw-rw----. 1 root disk 8 5. Okt 19:34 sda
crw--w----. 1 root tty 4 5. Okt 19:34 tty0
-rwx------. 1 demo users 0 5. Okt 20:01 mybin
\end{verbatim}
Die Attributzeichenkette besteht auch 10 Zeichen und gibt Auskunft über den Typ
als auch die Berechtigungen auf die Ressource.
Das erste Attribut gibt den Typ der Ressource wieder. Folgende Attribute
beschreiben die Ressource.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{-:} Ist eine normale Datei
\item \textbf{d:} \textbf{d}irectory
\item \textbf{s:} unix \textbf{s}ocket - Beispielsweise TCP socket eines Web Servers
\item \textbf{l:} symbolic \textbf{l}ink - Link auf eine andere Datei oder
anderes Verzeichnis
\item \textbf{b:} \textbf{b}lock device - Festplatten
\item \textbf{c:} \textbf{c}haracter device - Terminal
\end{itemize}
Die verbleibenden neun Attribute werden in drei Gruppen gesplittet. Jede Gruppe
beschreibt die Berechtigungen für den Besitzer (engl. user, kurz u), die Gruppe
(engl. group, kurz g) und alle anderen Benutzer, welche weder als Besitzer noch
Mitglied in der genannten Gruppe sind. Diese Benutzer werden auch als Andere
(engl. other, kurz o) beschrieben.
Dabei haben die Attribute folgende Bedeutung:
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{r:} \textbf{r}ead - Von Ressource lesen oder Verzeichnisinhalt
auflisten
\item \textbf{w:} \textbf{w}rite - Ressource beschreiben oder
Verzeichnisinhalt ändern (hinzufügen, umbenennen, löschen)
\item \textbf{x:} e\textbf{x}ecute - Programm ausführen oder in das
Verzeichnis hineinwechseln
\end{itemize}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 5a}: Sind block devices in der obrigen Ausgabe gelistet,
wenn ja welche?
\item \textbf{Aufgabe 5b:} Nenne alle Dateien aus der obrigen Ausgabe.
\item \textbf{Aufgabe 5c:} Kann der Benutzer \textit{root} in das Verzeichnis
\textit{hello-word} hineinwechseln, wenn ja warum?
\item \textbf{Aufgabe 5d:} Welche Gruppe und was für Berechtigungen wurden der
Aufzählung \textit{hello-world2} zugewiesen?
\item \textbf{Aufgabe 5e:} Kann der Benutzer \textit{christian} das Programm
\textit{mybin} ausführen?
\item \textbf{Aufgabe 5f:} Kann der Benutzer \textit{demo} die Datei
\textit{helloworld2} lesen?
\item \textbf{Aufgabe 5g:} Wer kann mit welchen Berechtigungen mit dem
Unix-Socket \textit{docker.sock} kommunizieren?
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsubsection{Änderung der Dateiberechtigungen}%
\label{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.mod}
Die Berechtigungen auf Ressourcen als auch der Besitzer bzw. die Gruppe kann
geändert werden. Dazu sind in GNU Core Utilities folgende Programme enthalten.
\begin{itemize}[label={},itemsep=0pt]
\item \textit{chown:} Ändert den Besitzer einer Ressource
\item \textit{chgrp:} Ändert die Gruppe einer Ressource
\item \textit{chmod:} Ändert die Berechtigung auf eine Ressource für alle
anderen Benutzer, welche weder als Besitzer noch Mitglieder der Gruppe sind
\end{itemize}
Das Ändern des Besitzers per \textit{chown} kann durch \textit{chown user
ressource} geändert werden. Gleiches gilt für das Ändern der Gruppe:
\textit{chgrp group ressource}. Möchte man den Besitzer als auch die Gruppe in
einem ändern kann dies durch \textit{chown} umgesetzt werden. Dabei muss der
Besitzer als auch die Gruppe getrennt durch einen Doppelpunkt angegeben werden:
\textit{chown user:group ressource}. Alternativ zu den Namen kann auch die
\textit{UID} bzw. für die Gruppe die \textit{GID} verwendet werden.
Die Dateiberechtigungen lassen sich per \textit{chmod} anpassen. Das Programm
\textit{chmod} unterstützt die Symbolische- als auch die Oktal-Notation, um
Berechtigungen für Ressourcen zu beschreiben.
Für die Oktal-Natation müssen die Oktal-Werte für jede Gruppe (Besitzer, Gruppe,
Andere) addiert werden, um die symbolische Notation nachbilden zu können. Bei
der Symbolischen-Notation können die Gruppen über die Buchstaben u für engl. user, g
für engl. group und o für engl. other referenziert werden.
\begin{table}[H]
\centering
\begin{tabularx}{\textwidth}{X|X|X}
\textbf{Berechtigung} & \textbf{Oktal-Wert} & \textbf{Symbolisches-Attribut} \\
\hline\hline
read & 4 & r \\
write & 2 & w \\
execute & 1 & x \\
\end{tabularx}
\end{table}
Hier zwei Beispiele, um die Berechtigungen aus der Aufzählung aus Kapitel
\ref{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.einfach}
anzupassen. Dabei führen die ersten beiden und letzen beiden Befehle, unabhängig
von der Notation, zu dem gleichen Ergebnis.
\begin{bashcode}
$ chmod 750 helloworld2
$ chmod u=+rwx,g=+rx-w,o=-rwx helloworld2
$ chmod 775 helloworld mybin
$ chmod u=+rwx,g=+rwx,o=+rx-w mybin
$ ls -la
drwxr-x--- 2 markus users 40 29. Sep 21:48 hello-world
-rwxrwxr-x 1 demo users 0 5. Okt 20:01 mybin
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 6a:} Wie lautet der Befehl die Berechtigung zum lesen
des Verzeichnis \textit{helloworld2} für die Gruppe zu entfernen? Bitte gebe
die Symbolische- und Oktal-Notation an.
\item \textbf{Aufgabe 6b:} Wie lautet der Befehl der Datei mybin die
Berechtigung zum Ausführen für alle Gruppen (Besitzer, Gruppe und Andere) zu
entfernen? Symbolische- und Oktal-Notation erforderlich.
\item \textbf{Aufgabe 6c:} Wie lautet der Befehl anderen Benutzern, welche
nicht Besitzer oder Mitglied der Gruppe docker sind von dem Unix-Socket
\textit{docker.sock} zu lesen. Symbolische- und Oktal-Notation erforderlich.
\item \textbf{Aufgabe 6d:} Wie lautet der Befehl den Besitzer auf
\textit{root} und die Gruppe auf \textit{markus} für die Datei
\textit{helloworld} zu setzen? Einzeiler bitte.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsubsection{Erweiterte Dateiberechtigungen}%
\label{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.erweitert}
Neben den einfachen Dateiberechtigungen unterstützen alle Unix-artige Systeme
die erweiterten Dateiberechtigungen. Diese werden \textit{setuid},
\textit{setgid} und \textit{sticky bit} genannt.
Sie lassen sich ebenfalls über die Symbolische- als auch die Oktal-Notation
setzen.
\begin{table}[H]
\centering
\begin{tabularx}{\textwidth}{X|X|X}
\textbf{Berechtigung} & \textbf{Oktal-Wert} & \textbf{Symbolisches-Attribut} \\
\hline\hline
setuid & 4 & s \\
setgid & 2 & s \\
sticky bit & 1 & t \\
\end{tabularx}
\end{table}
Die \textit{setuid} auf Dateien wird ignoriert, außer sie ist ausführbar. Ist
die Datei ausführbar wird diese mit den Berechtigungen des Besitzers ausgeführt.
Ein gutes Beispiel ist das Programm \textit{/bin/passwd}. Ohne die Option
\textit{setuid} wäre ein normaler Benutzer nicht in der Lage sein Kennwort zu
ändern, da das Programm die Dateien \textit{/etc/passwd} und
\textit{/etc/shadow} bearbeitet, welche dem Besitzer \textit{root} als auch der
Gruppe \textit{root} gehören.
Ist das \textit{setuid} auf eine Datei oder ein Verzeichnis gesetzt, wird das
Attribut \textit{x} durch ein \textit{s} unter den Berechtigungen des Besitzers
in der Attributzeichenkette ersetzt.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 7a:} Überprüfe, ob für das Programm \textit{/bin/passwd}
\textit{setuid} gesetzt ist.
\end{itemize}
Das setzen von \textit{setuid}, \textit{setgid} und \textit{sticky bit} wird per
\textit{chmod} erreicht. Es kann die Symbolische- als auch die Oktal-Notation
verwendet werden. Exemplarisch wird nachfolgend \textit{setuid} über die
Symbolische- als auch Oktal-Notation für die Datei hello-world.py gesetzt.
\begin{bashcode}
$ chmod 4755 hello-world-py
$ chmod u=+rws,g=+rx-w,o=+rx-w hello-world-py
\end{bashcode}
Die erweiterte Berechtigung \textit{setgid} verhält sich analog zu
\textit{setuid}, was Dateien betrifft. Es hat jedoch noch die Besonderheit, dass
wenn \textit{setgid} auf ein Verzeichnis gesetzt ist alle erstellten Dateien und
Verzeichnisse unterhalb des Verzeichnisses die Gruppe erben. Allerdings
\textbf{nicht} die Berechtigungen. Dies kann per \acrlongpl{acr:acl} realisiert
werden.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 7b:} Erstellen Sie das Verzeichnis \textit{/tmp/setgid}
und setzen Sie die Gruppe auf \textit{users}. Überprüfen Sie, ob
\textit{setgid} erfolgreich gesetzt wurde.
\item \textbf{Aufgabe 7c:} Erstellen Sie eine neue Datei als auch ein neues
Verzeichnis in \textit{/tmp/setgid}. Überprüfen Sie, ob die Gruppe
\textit{users} für die von ihnen erstellte Datei als auch Verzeichnis gesetzt
wurde.
\end{itemize}
Das \textit{sticky bit} wird auf Dateien ignoriert. Wird es allerdings auf ein
Verzeichnis gesetzt verhindert es, dass Benutzer Dateien und Verzeichnisse
löschen können für welche sie nicht als Besitzer hinterlegt sind.
% #>------------------------------------------------------------------------<#
\subsubsection{Access-Control-List}%
\label{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.acl}
Mit \acrfull{acr:acl} können Berechtigungen granularer vergeben werden. Sie
erweitern somit die Rechteverwaltung unter Linux und werden insbesondere dafür
verwendet, Berechtigungen für neu angelegte Dateien und Verzeichnisse innerhalb
eines Verzeichnisses zu vererben.
Unter Fedora muss das Paket \textit{acl} installiert sein, um die
Rechteverwaltung granularer einstellen zu können.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 8a:} Installieren Sie mit \textit{yum} das Paket
\textit{acl}, sofern dies nicht installiert ist.
\end{itemize}
Das Paket \textit{acl} enthält mehrere Programme, um \acrshortpl{acr:acl} auf
dem System verwalten zu können. Dies sind die wichtigsten:
\begin{itemize}[label={},itemsep=0pt]
\item \textit{setfacl:} Dient zum definieren von \acrshortpl{acr:acl} auf ein
Verzeichnis oder eine Datei
\item \textit{getfacl:} Liest definierte \acrshortpl{acr:acl} von einem
Verzeichnis oder einer Datei aus
\end{itemize}
Die Programme \textit{setfacl} und \textit{getfacl} folgen einer ähnlichen
Befehlsstruktur wie \textit{chmod}, \textit{chown} und \textit{chgrp}.
Hier ein Beispiel, um dem Benutzer \textit{christian} die Berechtigung
\textit{rwx} auf das Programm \textit{mybin} per \acrshort{acr:acl} einzuräumen.
\begin{bashcode}
$ setfacl -m "u:christian:rwx" mybin
\end{bashcode}
Ähnlich verhält sich das Programm, wenn man einer Gruppe oder Benutzern, welche
weder Besitzer noch Mitglieder einer Gruppe sind, Berechtigungen einräumen
möchte.
\begin{bashcode}
$ setfacl -m "g:christian:r-x" mybin
$ setfacl -m "o:r-x" mybin
\end{bashcode}
Führt man den Befehl \textit{ls -la} erneut aus, macht das \textit{+}-Zeichen
hinter der Attributzeichenkette auf die definierte \acrshort{acr:acl}
aufmerksam.
\begin{verbatim}
drwxr-xr-x. 2 markus users 40 29. Sep 21:48 hello-world
-rw-r--r--. 1 christian users 0 29. Sep 21:48 hello-world2
srw-rw----. 1 root docker 0 5. Okt 19:34 docker.sock
lrwxrwxrwx. 1 markus markus 38 14. Apr 11:32 .g -> .gnupg/
brw-rw----. 1 root disk 8 5. Okt 19:34 sda
crw--w----. 1 root tty 4 5. Okt 19:34 tty0
-rwx------+ 1 demo users 0 5. Okt 20:01 mybin
\end{verbatim}
Die definierte \acrshort{acr:acl} kann per \textit{getfacl} ausgelesen werden.
\begin{bashcode}
$ getfacl mybin
# file: mybin
# owner: demo
# group: users
user::rwx
user:christian:rwx
group::---
group:christian:r-x
mask::rwx
other::r-x
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 8b:} Erstellen Sie folgende Verzeichnisstruktur:
\textit{/tmp/acl-test/share}
\item \textbf{Aufgabe 8c:} Stellen Sie sicher, dass ausschließlich der
Benutzer \textit{root} und die Gruppe \textit{root} über die klassichen
Dateiberechtigungen Zugriff auf das Verzeichnis \textit{/tmp/acl-test} erhalten.
\item \textbf{Aufgabe 8d:} Erstellen Sie einen neuen Benutzer mit dem Namen
\textit{fuacl} und räumen Sie diesem per \acrshort{acr:acl} Berechtigungen
ein, Dateien und Verzeichnisse aus dem Verzeichnis \textit{/tmp/acl-test} zu
lesen, ändern und deren Inhalt aufzulisten. Überprüfen Sie die Einstellung!
\item \textbf{Aufgabe 8e:} Entziehen Sie dem Benutzer \textit{fuacl} die
Berechtigung Dateien und Verzeichnisse aus dem Verzeichnis
\textit{/tmp/acl-test/shared} zu lesen und aufzulisten. Überprüfen Sie die
Einstellung!
\item \textbf{Aufgabe 8f:} Stellen Sie sicher, dass neu erstellte Dokumente in
\textit{/tmp/acl-test} immer der Gruppe \textit{root} gehören und die
Berechtigung \textit{rwx} für Verzeichnisse und \textit{rw-} für Dateien
gesetzt werden. \textit{Tipp: setfact --default}. Überprüfen Sie die
Berechtigung durch erstellen eines neuen Dokuments.
\item \textbf{Aufgabe 8g:} Entfernen Sie ausschließlich jene
\acrshort{acr:acl}, welche vererbt wird.
\item \textbf{Aufgabe 8h:} Entfernen Sie rekursive alle \acrshortpl{acr:acl}.
\end{itemize}
% #>------------------------------------------------------------------------<#
\subsection{Praxisaufgabe: Verzeichnisstruktur mit Dateiberechtigungen erstellen}%
\label{sec:benutzer-gruppen-und-berechtigungen.praxis-task}
Sie befinden sich in folgender Situation:
Das Unternehmen indem Sie arbeiten wechselt aus Kostengründen von Windows
Sharepoint zu Samba. Ihr Vorgesetzter hat Sie daher gebeten Vorbereitungen für
den Umstieg zu treffen. Darunter auch die notwendige Verzeichnisstruktur für die
Abteilungen als auch die Benutzer und Gruppen zu erstellen, sowie Berechtigungen
den Vorgaben entsprechend anzupassen.
Folgende Beziehungen führt das Unternehmen zwischen Mitarbeiter und Abteilungen.
\begin{table}[H]
\centering
\begin{tabularx}{\textwidth}{X|X}
\textbf{Mitarbeiter} & \textbf{Abteilungen} \\
\hline\hline
Hugo McKinnock & Entwicklung \\
Hans Rakinzky & Entwicklung, System Administration \\
Marie Haseloff & Personalabteilung, Buchhaltung \\
Sophie Becker & Personalabteilung \\
Axel Tuller & System Administration \\
Tobias Moretti & Entwicklung, Qualitätssicherung \\
Lisa Meerkamp & Sekretärin \\
Manfred Krupp & Vorstand \\
\end{tabularx}
\end{table}
Die Verzeichnisstruktur ist unter \textit{/srv/documents} zu erstellen. Dabei
besitzt jede Abteilung ihr eigenes Verzeichnis. Innerhalb ihres Verzeichnisses
erhalten fast alle Abteilungen das Verzeichnis \textit{public} und
\textit{private}. Die Abteilung Entwicklung und Qualitätssicherung haben kein
Verzeichnis \textit{private}, da ihre Dokumente allen Benutzern im Unternehmen
zugänglich sein sollen. Dagegen besitzen die Abteilungen Sekreteriat als auch
Vorstand kein Verzeichnis \textit{public}, sondern ausschließlich
\textit{private}.
In den Verzeichnissen \textit{private} können ausschließlich Mitglieder der
Abteilung lesen und schreiben. Neu erstellte Dokumente gehören der Abteilung und
dem Benutzer \textit{root}. Ähnlich ist dies für das Verzeichnis
\textit{public}. Alle Benutzer können die Dateien oder Verzeichnisse öffnen.
Allerdings können nur Mitglieder der Abteilung neue Dokumente erstellen und
bearbeiten.
Bitte geben Sie die nötigen Befehle an, mit denen Sie die nachfolgenden Aufgaben
lösen.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 9a:} Erstellen Sie die Gruppen, beginnend mit der
\textit{GID} 2000.
\item \textbf{Aufgabe 9b:} Erstellen Sie die Benutzer, beginnend mit der
\textit{UID} 2000. Die Primärgruppe ist \textit{users}.
\item \textbf{Aufgabe 9c:} Verknüpfen Sie die Benutzer mit den Gruppen.
\item \textbf{Aufgabe 9d:} Erstellen Sie die beschriebene Verzeichnisstruktur.
\item \textbf{Aufgabe 9e:} Setzen Sie die beschriebenen Berechtigungen um.
\item \textbf{Aufgabe 9f:} Melden Sie sich unter dem Benutzer von Marie
Haseloff per \textit{sudo} an und überprüfen Sie folgende Berechtigungen:
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 9f$_1$:} Erstellen, bearbeiten und löschen von Dateien
und Verzeichnissen in der für Ihr, über die Abteilung, zugewiesenen
Verzeichnisse.
\item \textbf{Aufgabe 9f$_2$:} Neu erstellte Dokumente und Verzeichnisse
gehören der jeweiligen Abteilung. Verzeichnisse haben die
Gruppenberechtigung \textit{rwx}. Dateien haben die Gruppenberechtigung
\textit{rw-}.
\item \textbf{Aufgabe 9f$_3$:} Von Dateien und Verzeichnissen der Abteilung
Vorstand darf weder gelesen noch geschrieben als auch deren Inhalt gelistet
werden.
\item \textbf{Aufgabe 9f$_4$:} Dateien aus dem Verzeichnis \textit{public}
der Abteilung System Administration sind lesbar, aus dem Verzeichnis
\textit{private} nicht.
\end{itemize}
\end{itemize}

View File

@ -0,0 +1,221 @@
% <#>-----------------------------------------------------------------------<#>
\section{Verzeichnisstrukturen}%
\label{sec:verzeichnisstrukturen}
Das Konzept der Verzeichnisstruktur von Unix-artigen Betriebssystemen ist
annähernd identisch. Es gibt jedoch Besonderheiten zwischen den einzelnen
Abspaltungen von Unix hinsichtlich Linux und BSD, als auch der jeweiligen
Distributionen und Abspaltungen: Debian, RHEL, OpenBSD etc. Da jedoch die
Vielfalt zu groß für dieses Kapitel wäre, werden diese hier nicht näher
behandelt.
% >---------------------------------------------------------------------------<
\subsection{/ (root directory, Wurzelverzeichnis)}%
\label{sec:verzeichnisstrukturen.root}
% NOTE: Missing reference to chapter where devices will be mounted
Das Wurzelverzeichnis \textit{/} ist die oberste Verzeichnisebene. Es enthält
alle weiteren Unterverzeichnisse und Dateien unabhängig, ob diese sich auf einem
physikalisch anderen Gerät befinden. Dazu später mehr.
% >---------------------------------------------------------------------------<
\subsection{/bin/}%
\label{sec:verzeichnisstrukturen.bin}
Systemrelevante Programme, beispielsweise jene, welche Bestandteil der GNU Core
Utility Collection sind werden in dem Verzeichnis \textit{/bin/} gespeichert.
Dies sind zum Beispiel \textit{chmod}, \textit{chown}, \textit{chgrp},
\textit{id}, \textit{cp}, \textit{mv} oder \textit{rm}. Im Regelfall sind alle
Programme, welche notwendig sind das System erfolgreich zu booten im Verzeichnis
\textit{/bin/} hinterlegt.
% >---------------------------------------------------------------------------<
\subsection{/boot/}%
\label{sec:verzeichnisstrukturen.boot}
In dem Verzeichnis \textit{/boot/} befindet sich der Linux Kernel. Der Linux
Kernel wird als Datei gespeichert. Im Dateinamen aller unterschiedlichen
Kernelversionen befindet sich in der Regel die folgende Zeichenkette, wenn je
nach Distribution diese nicht überschrieben wurde: \textit{vmlinux}.
% NOTE: Missing reference to chapter where linux system will be booted
Neben dem Kernel befindet sich in dem Verzeichnis passend zu den installierten
Kernelversionen noch die Datei \textit{initramdisk}. Sie wird in den
\acrshort{acr:ram} während des Bootvorgangs geladen und startet den Kernel. Mehr
zum Bootvorgang unter Linux in einem späteren Kapitel.
% >---------------------------------------------------------------------------<
\subsection{/boot/EFI/}%
\label{sec:verzeichnisstrukturen.efi}
Das Verzeichnis \textit{/boot/EFI} ist ausschließlich bei Systemen vorhanden,
welches statt der \acrshort{acr:bios} Bootmethode \acrshort{acr:uefi} verwendet.
Das Verzeichnis beinhalter die unterschiedlichen Bootloader. Beispielweise den
von Windows, GRUB oder systemd-boot.
Ratsam ist es daher das Verzeichnis \textit{/boot/EFI} als seperate Partition zu
behandeln, sodass wenn mehrere Systeme installiert sind ein und die selbe EFI
Partition verwendet werden kann. Dies hat den Vorteil, dass ausschließlich eine
Partition in der Firmware des Motherboards angeben werden muss, damit die
Firmware die entsprechenden Bootloader von den jeweiligen Systemen findet.
% >---------------------------------------------------------------------------<
\subsection{/dev/}%
\label{sec:verzeichnisstrukturen.dev}
Physische als auch virtuelle Peripheriegeräte, beispielsweise die physisch
verbaute oder dem Gastsystem zugewiesene virtuelle Festplattte, werden neben
anderen Geräten im Verzeichnis \textit{/dev/} als Datei abgebildet. Siehe
Kapitel
\ref{sec:benutzer-gruppen-und-berechtigungen.dateiberechtigungen.einfach}, um
aus der Attributszeichenkette erkennen zu können, bei welcher Datei es sich um
ein Blockdevice handelt.
Auf diese speziellen Dateien kann anschließend mit anderen Programmen
zugegriffen werden. Beispielsweise das Einbinden eines Blockgerätes (Festplatte)
an einen beliebigen Einbindungspunkt - siehe \textit{mount} Befehl.
% >---------------------------------------------------------------------------<
\subsection{/etc/}%
\label{sec:verzeichnisstrukturen.etc}
In dem Verzeichnis \textit{/etc/} sind Konfigurationsdateien von Programmen
enthalten. Im Regelfall werden diese durch die Entwickler bereitgestellt.
Beispielsweise durch Installation des entsprechenden \acrshortpl{acr:rpm}.
Sind keine Konfigurationsdateien für ein Programm im Verzeichnis \textit{/etc/}
vorhanden. Können diese auch unter \textit{/usr/} gespeichert sein. Ein
manuelles platzieren der Konfigurationsdateien unter \textit{/etc/} würde das
Standardverhalten des Programms übersteuern.
% >---------------------------------------------------------------------------<
\subsection{/home/}%
\label{sec:verzeichnisstrukturen.home}
Es ist das Standardverzeichnis für normale bzw. reale Benutzer. Dieses
Verzeichnis wird manchmal auch mit anderen Linux-Distributionen geteilt, sofern
das gleiche Heimatverzeichnis von mehreren Benutzern unterschiedliche
Distributionen verwendet werden soll.
% >---------------------------------------------------------------------------<
\subsection{/lib/}%
\label{sec:verzeichnisstrukturen.lib}
Bibliotheken, welche gemeinsam durch mehrere Programme, welche sich in den
Verzeichnissen \textit{/bin/} und \textit{/sbin} befinden, geteilt werden,
werden im Verzeichnis \textit{/lib} gespeichert.
% >---------------------------------------------------------------------------<
\subsection{/media/}%
\label{sec:verzeichnisstrukturen.media}
In dem Verzeichnis \textit{/media/} werden entfernbare Dateisysteme eingebunden.
Beispielsweise der USB-Stick, eine USB-Festplatte oder eine CD bzw. DVD, welche
sich im Laufwerk befindet.
Desktopmanager wie Gnome, Cinnamon, Xfce oder KDE übernehmen hier die Funktion,
das Gerät automatisch unter \textit{/media/} einzubinden.
% >---------------------------------------------------------------------------<
\subsection{/mnt/}%
\label{sec:verzeichnisstrukturen.mnt}
Andere Systempartitionen, beispielsweise die C: oder D: Partition von
Windowssystemen auf einem Dualboot System, werden unter \textit{/mnt/}
eingebunden. Im Regelfall auch nur temporär, beispielsweise wenn der
Systemadministrator versucht unter Linux auf die Windowspartitionen zu
zugreifen.
% >---------------------------------------------------------------------------<
\subsection{/opt/}%
\label{sec:verzeichnisstrukturen.opt}
Das Verzeichnis \textit{/opt} ist das Standardverzeichnis für proprietäre
Programme und steht für \textit{optional package tree}. In diesem Verzeichnis
legen daher im Regelfall proprietäre Programme Binär-, Konfigurations-, und
Bibliotheksdateien ab.
Beispielsweise, wenn man einen TeamSpeak 3 Server oder Druckertreiber von
Brother installieren möchte, werden diese unter \textit{/opt} installiert.
% >---------------------------------------------------------------------------<
\subsection{/root/}%
\label{sec:verzeichnisstrukturen.root}
Der Benutzer \textit{root} besitzt sein eigenes Heimatverzeichnis direkt
unterhalb des Wurzelverzeichnisses. Es ist das Verzeichnis \textit{/root/}. Es
wird gesondert geführt und ausschließlich der Benutzer \textit{root} besitzt
Berechtigungen von dem Verzeichnis zu lesen und zu schreiben als auch es
betreten zu können.
% >---------------------------------------------------------------------------<
\subsection{/run/}%
\label{sec:verzeichnisstrukturen.run}
Programme, welche ausgeführt werden und Informationen auslagern speichern diese
im Verzeichnis \textit{/run/}. Dies können beispielsweise Unix-Sockets oder auch
temporäre Einstellungsparameter sein, welche nur zur Laufzeit des Programms
vorhanden sind.
Die Dateien werden nicht im Verzeichnis \textit{/tmp/} gespeichert, da Dateien
und Verzeichnisse unter \textit{/tmp/} automatisch entfernt werden können.
Beispielsweise, wenn das System bemerkt der Speicherplatz geht zur Neige.
Der Dienst \textit{systemd-resolved} speichert als gutes Beispiel unter
\textit{/run/systemd/resolve/resolv.conf} die \textit{resolv.conf} Datei ab,
welche von \textit{/etc/resolv.conf} per symbolischen link referenziert wird.
% >---------------------------------------------------------------------------<
\subsection{/sbin/}%
\label{sec:verzeichnisstrukturen.sbin}
Das Verzeichnis \textit{/sbin} ist identisch zu dem Verzeichnis \textit{/bin}.
Es enthält jedoch ausschließlich Programme welche für den Benutzer \textit{root}
vorgesehen sind.
% >---------------------------------------------------------------------------<
\subsection{/srv/}%
\label{sec:verzeichnisstrukturen.srv}
Stellt das System beispielsweise Mail-, Web- oder andere Dienste bereit, werden
die persistenten Daten unter \textit{/srv/} gespeichert. Dieses Verzeichnis ist
nicht automatisch Bestandteil jeder Distribution. Es kann daher sein, das gerade
bei Distributionen, welche einen minimalistischen Ansatz fahren nicht vorhanden
ist.
% >---------------------------------------------------------------------------<
\subsection{/tmp/}%
\label{sec:verzeichnisstrukturen.tmp}
Das \textit{/tmp/} Verzeichnis ist der generelle Speicherort für temporäre
Dateien. Ältere Systeme verwenden eine eigene Partition für das Verzeichnis
\textit{/tmp/}, um die Größe zu limitieren. Neuere Systeme, welche systemd
verwenden, richten das Verzeichnis \textit{/tmp/} als
\nameref{sec:dateisysteme.tmpfs}
Dateisystem ein und limitieren dieses auf eine prozentuale Größe.
% >---------------------------------------------------------------------------<
\subsection{/usr/}%
\label{sec:verzeichnisstrukturen.usr}
Anwendungen und Dateien die von realen Benutzern verwendet werden, werden im
Gegensatz zu Anwendungen und Dateien welche vom System verwendet werden, unter
\textit{/usr/} gespeichert. Aus diesem Grund sind unterhalb von \textit{/usr/}
auch Verzeichnisse wie \textit{/usr/bin}, \textit{/usr/sbin} oder
\textit{/usr/lib} enthalten. Alle Unterverzeichnisse von \textit{/usr/} sind für
Benutzer nur lesbar und betretbar. Dateien sind in der Regel ebenfalls nur
lesbar eventuell noch ausführbar.
% >---------------------------------------------------------------------------<
\subsection{/var/}%
\label{sec:verzeichnisstrukturen.var}
Der Grundgedanke des Verzeichnisses \textit{/var/} ist, dass es das Gegenstück
zu \textit{/usr/} abbilden soll. Hier können Benutzer beliebig Dateien oder
Verzeichnisse erstellen. Allerdings sind können diese Eingeschränkt sein.
Ein gutes Beispiel sind Logdateien. Würden Logdateien eines Programms, welche
aus dem Verzeichnis \textit{/usr/bin} oder \textit{/usr/sbin} ausgeführt werden,
in das Verzeichnis \textit{/usr/} speichern, würde dies gegen das Konzept des
Verzeichnisses \textit{/usr/} sprechen. Aus diesem Grund werden Logdateien in
das Verzeichnis \textit{/var/log} gespeichert.

404
chapters/06-filesystems.tex Normal file
View File

@ -0,0 +1,404 @@
% <#>---------------------------------------------------------------------------<#>
\section{Dateisysteme}%
\label{sec:dateisysteme}
Je nach Kernel werden unterschiedliche Dateisysteme unterstützt. Bekannt von
Windows ist Ihnen bestimmt das \acrfull{acr:ntfs}. Linux unterstützt im
Gegensatz zum Windows NT Kernel nicht nur ein oder zwei Dateisysteme sondern
eine große Vielzahl, beispielsweise \acrshort{acr:ext3}, \acrshort{acr:ext4},
\acrshort{acr:btrfs}, \acrshort{acr:eCryptfs}, \acrshort{acr:reiser} oder XFS.
Jedes Dateisystem hat Stärken und Schwächen. Aus diesem Grund werden nicht alle
Dateisysteme detailiert betrachtet, sondern ausschließlich \acrshort{acr:btrfs},
welches für Fedora 33 als Standard Dateisystem angekündigt
ist\footcite{fedora33-btrfs-default} als auch kleinere Dateisysteme, welche
nicht direkt eine physische oder virtuelle Festplatte vorraussetzen.
% #>-------------------------------------------------------------------------<#
\subsection{BtrFS}%
\label{sec:dateisysteme.btrfs}
Das \acrshort{acr:btrfs} Dateisystem ist ein \acrlong{acr:cow} Dateisystem.
\acrshort{acr:cow} bedeutet, dass für Dateien, welche kopiert werden, nicht der
selbe Speicherplatz anfällt. Sie werden stattdessen nur referenziert. Dies hat
den Vorteil, das Speicherplatz eingespart werden kann. Im Umfeld von
systemorierntierten Programmiersprachen wie C, Rust oder Go, kann dies mit dem
Konzept von Pointern verglichen werden. Wobei statt Speicheradressen die
Dateisystemblöcke referenziert werden, welche die Datei im Dateisystem abbilden.
\acrshort{acr:btrfs} bietet mehrere Funktionen an, welche in dem Umfang kein
anderes Dateisystem anbietet. Hier einige Informationen über \acrshort{acr:btrfs}:
\begin{itemize}[itemsep=0pt]
\item Dynamisch wachsende Inodes
\item Verwaltung von Subvolumes
\item Erstellung von Snapshots pro Subvolume
\item Datenkompression auf Dateisystemebene
\item Dateisystemcheck und Defragmentierung während des Betriebs
\item Prüfsummenbasiert
\item Integrierte \acrshort{acr:raid} option, wobei nur \acrshort{acr:raid} 0
und 1 als stabil zu betrachten sind
\end{itemize}
% >---------------------------------------------------------------------------<
\subsubsection{Was ist genau BtrFS}%
\label{sec:dateisysteme.btrfs.erklaerung}
Eine \acrshort{acr:btrfs}-Partition stellt eine Volume dar, welches in mehrere
Subvolume unterteilt werden kann. Subvolumes stehen in ihrer Eigenschaft
zwischen Partitionen und Verzeichnissen. Partitionen haben eine feste Größe,
Subvolumes nicht, außer sie werden durch Quotas limitiert. Daher verhalten sich
Subvolumes ähnlich wie Verzeichnisse.
Im Verzeichnisbaum des Systems werden Subvolumes automatisch als Ordner
eingehängt. In Ubuntu-Derivaten und OpenSUSE hat es sich eingebürgert
Top-Level-Subvolumen mit einem vorangestellten \textit{@} zu benennen. Dies ist
eine reine Konvention unter den Nutzern dieser Linux-Derivate und formell nicht
nötig. Subvolumen bedürfen keiner speziellen Nomenklatur. Es ist sogar
hinderlich, da jedes Subvolumen welches anders heißt als wie vom System erwartet
explizit eingehängt werden muss.\footcite{was-ist-btrfs}
\acrshort{acr:btrfs} erlaubt zudem das Erstellen von Snapshots. Snapshots
representieren eine Momentaufnahme eines Subvolumes. Snapshots müssen auf der
selben \acrshort{acr:btrfs} Partition gespeichert werden wie das Subvolume.
Enthält ein Subvolume einen Snapshot, enthält der Snapshot nicht rekursiv alle
Snapshots, welche zum Zeitpunkt der Erstellung vorhanden waren. Da Snapshots
Momentaufnahmen sind, können diese sehr leicht zurück gespielt werden. Hier ist
allerdings zu beachten, dass ein Snapshot kein Backup im eigentlichen Sinne ist.
Backups werden auf physisch getrennte Geräte gespeichert, was bei Snapshots
nicht der Fall ist.
Dateien und Verzeichnisse, welche durch einen Snapshot kopiert werden, belegen
nicht zusätzlichen Speicherplatz. Sie werden nur von ein oder mehreren Quellen
referenziert. Folgende Abbildung beschreibt den Prozess und die Referenzierung:
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/btrfs-cow.png}
\caption{Referenzierung von Speicherblöcken}%
\label{fig:dateisysteme.btrfs.referenzierung-von-speicherbloecken}
\end{figure}
Erst wenn alle Referenzen gelöscht sind können die Dateisystemblöcke
überschrieben werden.
% >---------------------------------------------------------------------------<
\subsubsection{Step-By-Step}%
\label{sec:dateisysteme.btrfs.step-by-step}
Mit dem Befehl \textit{mkfs.btrfs} kann eine \acrshort{acr:btrfs} Dateisystem
auf einer leeren Partition erstellt werden. Mit dem Befehl \textit{parted} oder
\textit{fdisk} lassen sich Partitionen einer Festplatte bearbeiten,
beispielsweise um neue zu erstellen, zu löschen oder deren Größe anzupassen.
Bei der Erstellung eines \acrshort{acr:btrfs} Dateisystems wird zwischen Daten
und Metadaten unterschieden. Bei Daten handelt es um die Daten welche auf der
Festplatte gespeichert werden. Metadaten enthalten dagegen Informationen, welche
Datei durch welches Subvolume oder Snapshot referenziert wird. Für beide
Informationsträgertypen kann zwischen mehreren Profilen unterschieden werden. Es
können Beispielsweise die Daten auf einem \acrshort{acr:raid}-0 und die
Metadaten auf einem \acrshort{acr:raid}-1 gespeichert werden. Je nach
Einsatzszenario kann ein vordefiniertes Profil bei der Erstellung verwendet
werden. Das verwendete Profil lässt sich nachträglich nicht mehr ändern.
Neben den Profilen lassen sich auch weitere Informationen für die
\acrshort{acr:btrfs} Partition definieren. Beispielsweise das Label oder die
UUID.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1a:} Binden Sie über ihren HyperVisor (HyperV,
\acrshort{acr:kvm} oder Virtual Box) zwei neue virtuelle Festplatten an ihre
VM. Beide virtuelle Festplatten sollen eine Größe von 5GB besitzen. Starten
Sie, nachdem Sie die virtuellen Festplatten der VM zugewiesen haben, die
Virtuelle Maschine und überprüfen Sie mit \textit{lsblk} (list block devices),
ob beide virtuelle Festplatten durch ihre VM erkannt wurden.
\item \textbf{Aufgabe 1b:} Welche unterschiedlichen Profile werden von dem
\acrshort{acr:btrfs} Dateisystem unterstützt?
\item \textbf{Aufgabe 1c:} Erstellen Sie eine neue Partition mit dem
Partitionsschema \textit{msdos}. Nutzen Sie zur Partitionierung entweder
\textit{parted} oder \textit{fdisk}.
\item \textbf{Aufgabe 1d:} Richten Sie ein neues \acrshort{acr:btrfs}
Dateisystem ein. Verwenden Sie dazu die beiden virtuellen Festplatten. Die
Daten als auch Metadaten sollen als \acrshort{acr:raid}-1 vor einem
Festplattenausfall geschützt werden. Verwenden Sie als Label
\textit{btrfs-raid-1}.
\end{itemize}
Physische als auch virtuelle Geräte können an unterschiedlichen Stellen im
Verzeichnisbaum eingebunden werden. Zum Einbinden eines Gerätes in den
Verzeichnisbaum wird der Befehl \textit{mount} verwendet. Die allgemeine Syntax
lautet:
\begin{bashcode}
$ mount [-t <typ>, -o <option>] <dev> <mountpoint>
# Beispiel, um die Partition vdb1 der virtuellen Festplatte /dev/vdb nach /mnt/vbd1 zu "mounten".
$ mount /dev/vdb1 /mnt/vdb1
\end{bashcode}
Weitere Informationen zum Einbinden von Geräten finden Sie in der Dokumentation:
\textit{man mount}.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2a:} Erstellen Sie das Verzeichnis \textit{/mnt/btrfs}.
\item \textbf{Aufgabe 2b:} Ermitteln Sie, was die Optionen \textit{rw},
\textit{noatime}, \textit{compress}, \textit{ssd}, \textit{space\_cache} und
\textit{subvol} bedeutet, welche beim Einbinden eines \acrshort{acr:btrfs}
Dateisystems verwendet werden können.
\item \textbf{Aufgabe 2c:} Binden Sie das \acrshort{acr:btrfs}
\acrshort{acr:raid} Dateisystem unter \textit{/mnt/btrfs} ein. Entscheiden Sie
selbst, welche Optionen für Sie relevant sind.
\end{itemize}
Nach einem Neustart des Systems ist das \acrshort{acr:btrfs} Dateisystem nicht
mehr eingebunden. Sie müssen das Einbinden des Dateisystems per \textit{mount}
wiederholen oder einen Eintrag in die Datei \textit{/etc/fstab} vornehmen. Dazu
ermitteln Sie am besten per \textit{blkid} die UUID ihrer btrfs-raid Partition
und verweden diese in der \textit{fstab}, um die Partition automatisch nach
einem Neustart einzubinden. Weitere Informationen finden Sie unter folgendem
\href{https://wiki.archlinux.de/title/Fstab}{Link}.
Wie bereits in Kapitel \ref{sec:dateisysteme.btrfs.erklaerung} beschrieben
untersützt das \acrshort{acr:btrfs} Dateisystem Subvolumes. Auf dem kürzlich
erstellten \acrshort{acr:btrfs} \acrshort{acr:raid} Dateisystem sollen zukünftig
Bilder, Musiktitel, Podcasts und Videos gespeichert werden.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 3a:} Erstellen Sie für die Bilder, Musiktitel, Podcasts
und Videos ein Subvolume auf dem neuen \acrshort{acr:btrfs}
\acrshort{acr:raid} Dateisystem.
\item \textbf{Aufgabe 3b}: Überprüfen Sie, ob die Subvolumes erkannt wurden.
\item \textbf{Aufgabe 3c:} Löschen Sie das Subvolume Podcasts.
\item \textbf{Aufgabe 3d:} Erstellen Sie unterhalb der verbleibenden
Subvolumes das Verzeichnis \textit{.snapshots}.
\end{itemize}
Nachdem Sie nun die drei Subvolumes mit dem Unterverzeichnis \textit{.snapshots}
erstellt haben kommen wir an den Punkt Snapshots zu erstellen. Snapshots sind
Grundsätzlich nichts anderes als Subvolumes. Sie referenzieren auf die gleichen
Dateien, welches sich zum Zeitpunkt des Snapshots im Subvolume befanden. Die
Dateien innerhalb eines Snapshots lassen sich bearbeiten und modifizieren ohne
dabei die Dateien innerhalb des Subvolumes zu beeinträchtigen. Dies ist jedoch
nicht immer gewünscht, da dadurch ein Snapshot nicht mehr der Momentaufnahme
entspricht. Aus diesem Grund kann das nachträgliche Editieren von Dateien
innerhalb eines Snapshots unterbunden werden.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 4a:} Erstellen Sie einen \textit{read-only} Snapshot von
jedem Subvolume, um ein nachträgliches Editieren von Dateien in den Snapshots
zu unterbinden. Speichern Sie den Snapshot in das Verzeichnis
\textit{.snapshots} des jeweiligen Subvolumes mit dem Namensschema
\textit{$<nameSubvolume>.<jahr><monat><tag>T<stunde><minute>$} ab.
\item \textbf{Aufgabe 4b:} Überprüfen Sie, ob die Snapshots als Subvolumes
erkannt wurden.
\item \textbf{Aufgabe 4c:} Löschen Sie das Subvolume von dem Sie einen
Snapshot erstellt haben.
\item \textbf{Aufgabe 4d:} Stellen Sie mithilfe des Snapshots das Subvolume
wieder her.
\end{itemize}
Nun, ein Snapshot ist kein Backup. Ein Backup ist die Sicherung eines Zustands
auf einem anderen physischen Gerät, beispielsweise einer zweiten angeschlossenen
Festplatte oder einem entfernten System. Um ein Backup zu erstellen enthält das
Programm \textit{btrfs} den Unterbefehl \textit{send}. Damit kann ein Snapshot
in eine Datei exportiert werden. Neben dem Unterkommando \textit{send} enthält
es unter anderem auch das Unterkommando \textit{receive}, um Snapshots aus einer
Datei zu importieren.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 5a:} Exportieren Sie einen kürzlich erstellten Snapshot
per \textit{btrfs send} in eine Datei.
\item \textbf{Aufgabe 5b:} Löschen Sie den Snapshot.
\item \textbf{Aufgabe 5c:} Stellen Sie den gesicherten Snapshot aus der Datei
wieder her.
\item \textbf{Aufgabe 5d:} Kopieren Sie per \textit{scp} von dem SSH-Server
der Hochschule die Datei
\textit{/dozenten/peschm/linux\_ws2021/videos.20201027T223646.snapshot} in
ihre VM. Spielen Sie den Snapshot unter dem Subvolume \textit{videos} wieder
ein. Schauen Sie sich das darin enthaltene Video an ;) Eventuell muss das
Video auf ein anderes System kopiert werden, da ihre VM keinen Mediaplayer
besitzt.
\end{itemize}
Die Snapshots können nun durch ein Skript erstellt und gelöscht werden, als auch
das letzte Backup auf ein entferntes System oder eine zweite Festplatte
exportiert werden. Doch warum sollte man sich die Arbeit machen solch ein Skript
zu erstellen, wenn andere bereits ein Program daraus gemacht haben.
Mit dem Programm \textit{btrbk} können Snapshots und Backups je nach Szenario
verwaltet werden. Der Quellcode des Programms ist auf
\href{https://github.com/digint/btrbk}{github.com} verfügbar, dort sind neben
den Konfigurationsoptionen auch mögliche Szenarien, welche das Programm abdeckt,
beschrieben.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 6a:} Installieren Sie das Programm \textit{btrbk} mit
\textit{yum}.
\item \textbf{Aufgabe 6b:} Informieren Sie sich über die \textit{README.md}
Datei, welche möglichen Szenarien durch \textit{btrbk} abgedeckt werden.
\item \textbf{Aufgabe 6c:} Konfigurieren Sie \textit{btrbk}, dass von den
Subvolumes Bilder, Musiktitel und Videos stündlich ein Snapshot in das
jeweilige \textit{.snapshots} Verzeichnis erstellt wird. Eine
Beispielkonfiguration liegt unter \textit{/etc/btrbk}. Weitere Informationen
finden Sie in der ausführlich dokumentierten
\href{https://digint.ch/btrbk/doc/archive/}{Dokumentation}.
\item \textbf{Aufgabe 6d:} Passen Sie die Konfiguration so an, dass die
Snapshots der folgenden Ausbewahrungsrichtlinie entspricht. Die letzen 24
stündliche, 14 tägliche, 4 wöchentliche, 12 monatliche und jährliche Snapshots
sollen behalten werden, um dem Großvater-Vater-Kind Prinzip zu entsprechen.
\item \textbf{Aufgabe 6e:} Passen Sie ggfl. das Namensschema der Snapshots an,
sodass es dem Namensschema von Aufgabe 4a entspricht.
\item \textbf{Aufgabe 6f:} Starten Sie \textit{btrbk} per \textit{btrbk run -c
/etc/btrbk/btrbk.conf run} und überprüfen Sie in der Ausgabe als auch im
Dateisystem, ob die Snapshots erstellt wurden.
\end{itemize}
% #>-------------------------------------------------------------------------<#
\subsection{overlayfs}%
\label{sec:dateisysteme.overlayfs}
Overlayfs ermöglicht die Überlagerung eines Verzeichnisbaums mit einem anderen
Verzeichnisbaum. Alle Änderungen gehen in die höhere beschreibbare Ebene.
Dadurch können mehrere Verzeichnisbäume basieren auf unterschiedlichen und
wiederverwendbaren Ebenen abgebildet werden. Diese Art von Mechanismus wird
vorwiegend für Container Applikationen verwendet. Es gibt jedoch auch eine
Vielzahl anderer Verwendungsmöglichkeiten.
Um overlayfs anhand eines Beispiels einfacher zu erklären betrachten wir den
Entwicklungsprozess einer Applikation mit allen notwendigen Dateien. Notwendig
für die Ausführung der Applikation ist die Binärdatei (das eigentliche
Programm), die Konfigurationsdateien, das Logverzeichnis und die systemd unit
Dateien, welche beschreiben wie das Programm unter einem systemd basierenden
System gestartet werden soll. Optional können noch Plugins bereitgestellt
werden.
Alle Dateien bzw. Plugins werden im Entwicklungsprozess in einem eigenen
Verzeichnisbaum gespeichert. Jeder Verzeichnisbaum wird durch eine Ebene
repräsentiert. Dies entspricht einem modularem Aufbau, da die Verzeichnisbäume
individuell wiederverwendet oder ausgetauscht werden können.
Die folgende Abbildung beschreibt den modularen Aufbau der Applikation mit allen
notwendigen Ebenen. Jede Ebene (layer) wird lesend über die vorherige Ebene
überlagert. Links befindet sich die Applikation ohne Plugins, rechts mit
Plugins, welche zusätzlich als seperate Ebene abgebildet sind und nicht
verändert werden können. Die horizontale Linie markiert den Punkt, ab wann
unterschiedliche Ebenen verwendet werden. Die oberste Ebene (workspace) ist
beschreibbar, um Konfigurationsdateien anzupassen oder damit das Programm
Logeinträge in die Logdateien schreiben kann.
\begin{figure}[H]
\centering
\includegraphics[width=0.55\textwidth]{img/overlayfs.png}
\caption{Aufbau eines OverlayFS mit mehreren wiederverwendeten Ebenen}%
\label{fig:dateisysteme.overlayfs.aufbau-mit-mehreren-ebenen}
\end{figure}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 7a:} Erstellen Sie folgendes Arbeitsverzeichnis und
wechseln die dort hinein: \textit{/root/workspace/overlayfs}.
\item \textbf{Aufgabe 7b:} Erstellen Sie folgende Dateien und Verzeichnisse
unterhalb ihres Arbeitsverzeichnisses:
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 7b$_1$:} Die \glqq{}Binärdatei\grqq{}:\\
\textit{./lower\_0/usr/bin/mybin}.
\item \textbf{Aufgabe 7b$_2$:} Die globale Konfigurationsdatei:\\
\textit{./lower\_1/etc/mybin/config.json}.
\item \textbf{Aufgabe 7b$_3$:} Die Logdatei:\\
\textit{./lower\_2/var/log/mybin/info.log}
\item \textbf{Aufgabe 7b$_4$:} Die systemd unit Dateien:\\
\textit{./lower\_3/usr/lib/systemd/system/mybin.service}
\item \textbf{Aufgabe 7b$_5$:} Die Konfigurationsdatei für das sqlite Plugin:\\
\textit{./lower\_4/etc/mybin/conf.d/sqlite.config}
\item \textbf{Aufgabe 7b$_6$:} Die Konfigurationsdatei für das postgresql
Plugin:\\
\textit{./lower\_5/etc/mybin/conf.d/postgresql.config}
\end{itemize}
\end{itemize}
Um mehrere Verzeichnisbäume überlagernd einzubinden ist folgende allgemeine
Syntax notwendig:
\begin{bashcode}
$ mount -t overlay -o lowerdir=<path_lowerdir1>:<path_lowerdir2>:... ,upperdir=<path>,workdir=<path> overlayfs <path>
\end{bashcode}
Das Flag \textit{-t} gibt den Typ an. Mit dem Flag \textit{-o} werden Optionen
definiert. Der Option lowerdir kann eine Liste von Pfaden übergeben werden,
gerennt durch einen Doppelpunkt, um zu defineren welche Verzeichnisbäume
überlagert werden sollen. Dabei ist die Reihenfolge zu beachten. Upperdir
entspricht dem workspace der Abbildung, sprich das spätere beschreibbare
Verzeichnis. Als workdir muss der Pfad zu einem leeren Verzeichnis angegeben
werden, indem der Prozess für den Überlagerungsvorgang Dateien zwischenspeichern
kann. Das zweite Argument entspricht dem Pfad im Dateisystem, andem der
überlagerte Verzeichnisbaum eingebunden werden soll.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 7c:} Binden Sie mithilfe des \textit{mount} Befehls das
OverlayFS Dateisystem bestehend aus allen notwendigen Ebenen unter
\textit{./application} und \textit{./application\_plugins} ein, um einmal den
notwendigen Verzeichnisbaum für die Applikation mit und ohne Plugin ab zu
bilden. Vergewissern Sie sich, dass alle notwendigen Verzeichnisse vorhanden
sind. Verwenden Sie die unterschiedlichen Verzeichnisbäume bzw. Ebenen wieder.
\item \textbf{Aufgabe 7d:} Erstellen Sie unter \textit{./application} das
Verzeichnis \textit{hello-world}. Überprüfen Sie, ob das Verzeichnis in einer
der Ebenen, welche als lesende Verzeichnisbäume eingebunden wurden, erstellt
wurde.
\item \textbf{Aufgabe 7e:} Löschen Sie unter \textit{./application\_plugins}
die plugin Konfigurationsdateien. Überprüfen Sie anschließend ob in der
entsprechenden Ebene ebenfalls die Konfigurationsdatei gelöscht wurde. Diese
dürfte nach dem Konzept nicht gelöscht worden sein.
\end{itemize}
Dateisysteme von Container Applikationen sind genau nach diesem Konzept
aufgebaut. Die Stärke liegt jedoch nicht nur in dem modularen Dateisystemaufbau
oder der Isolierung von Ressourcen - sprich CPU, \acrshort{acr:ram}, Storage,
ect., sondern auch darin, dass die Ebenen sich leicht von einem System auf ein
anderes übertragen lassen. Man spricht bei diesem Abschnitt in der Entwicklung
einer Applikation von Deployment. Dabei gilt, dass die beste Software die
schlechteste sein kann, wenn der Anwender nicht in der Lage ist, sie ohne große
Umstände installieren oder ausführen zu können.
Container Runtimes wie containerd, crio oder runc bemächtigen sich der Funktion
Subvolumes des darunter liegenden BtrFS Dateisystems zu importieren bzw.
exportieren, da dadurch Verzeichnisbäume einfach von einem System auf ein
anderes kopiert werden können. Ebenen bzw. Layer werden dann als eigenständiges
Subvolume betrachtet.
Finden Container Runtimes auf dem System kein BtrFS Dateisystem vor, werden die
Verzeichnisbäume unterhalb eines Verzeichnisses im Dateisystem gespeichert.
Ähnlich wie es bei der Übung veranschaulicht wurde. Dies hat jedoch den
Nachteil, dass identische Dateien, welche in mehreren Ebenen bzw. Layern
wiederverwendet werden zusätzlichen Speicherplatz auf der Festplatte
verbrauchen.
% #>-------------------------------------------------------------------------<#
\subsection{tmpfs}%
\label{sec:dateisysteme.tmpfs}
\textit{tmpfs} ist ein Dateisystem im \acrshort{acr:ram}. Es wird gerne
verwendet, wenn große IO Operationen stattfinden oder das Dateisystem nur
während der Laufzeit des Systems benötigt wird.
Da dieses Dateisystem sich im \acrshort{acr:ram} befindet, sind sehr schnelle
Zugriffszeiten keine Seltenheit mehr. Bei einfachen Rechnern mit DDR4 kann man
schon mit 10GiB/Sekunde rechnen. Typischer Anwendungsfall ist, wenn ein Programm
durch einen Kompiler kompiliert wird und der Vorgang hohe I/O Operationen auf der
Festplatte verursacht. Hinsichtlich der verbauten Festplatte wird gerade dadurch
die Lebenszeit erheblich erhöht.
Mit dem folgenden Befehl wird ein neues Dateisystem mit einer Größe von 512MB im
\acrshort{acr:ram} erstellt. Dieses wird anschließend nach \textit{/mnt/tmpfs}
eingebunden. Mit dem Befehl \textit{findmnt} können die Optionen des
\textit{tmpfs} Dateisystems überprüft werden.
\begin{bashcode}
$ mkdir --parent /mnt/tmpfs
$ mount -t tmpfs -o rw,relatime,size=512M tmpfs /mnt/tmpfs
$ findmnt /mnt/tmpfs
TARGET SOURCE FSTYPE OPTIONS
/mnt/tmpfs tmpfs tmpfs rw,relatime,seclabel,size=524288k
\end{bashcode}
Dateien und Verzeichnisse, welche sich in einem tmpfs Dateisystem befinden sind
nach einem Neustart des Systems verloren. Sie sind nicht wiederherstellbar.

204
chapters/07-backups.tex Normal file
View File

@ -0,0 +1,204 @@
% <#>---------------------------------------------------------------------------<#>
\section{Backup}%
\label{sec:backup}
Sicherlich hat jeder schon einmal schmerzlichst erfahren müssen, wie ärgerlich
es ist, wenn Daten verloren gegangen sind und diese nicht durch ein Backup
gesichert wurden. Der Schmerz sitzt tief, wenn die Urlaubsbilder, Kinderfotos
oder andere wichtige Dokumente verloren sind. Man ärgert sich häufig über sich
selber, da man wusste, dass dieser Moment früher oder später mal eintreten würde
und man es bis dahin nicht geschafft hat ein Backup zu erstellen.
In Kapitel \nameref{sec:dateisysteme.btrfs} wurden Snapshots von Subvolumes
erzeugt. Dies Snapshots können nicht direkt als ein Backup betrachtet werden,
obwohl sie eine Momentaufnahme eines Subvolumes wiederspiegeln. Der Grund ist,
dass unter einem Backup die Sicherung eines Zustands auf einem anderen
Speichergerät verstanden wird. Dies kann beispielsweise auf eine andere
Festplatte oder ein Magnetband per Bandlesegerät realisiert werden.
Früher wurden Bandlesegeräte sehr häufig eingesetzt, um große Datenmengen zu
sichern. Diese Methode wird zunehmend ersetzt durch andere Technologien wie
Beispielsweise das exportieren und importieren von Snapshots. Dies muss nicht
zwingend ein BtrFS Dateisystem sein, es kann auch ein ZFS oder QCOW2 Dateisystem
sein. Aus der Zeit, in der Bandlaufgeräte vorwiegend Verwendung fanden, sind
unterschiedliche Backup Methoden entstanden.
Je nach Datenbestand wurden unterschiedliche Methoden angewand oder kombiniert,
um die Vorteile je nach Situation auszunutzen. Nachfolgend werden die einzelnen
Methoden näher erläutert.
% #>-----------------------------------------------------------------------------<#
\subsection{Inkrementelles Backup}%
\label{sec:backup.inkrementell}
Ein inkrementelles Backup setzt ein bestehendes Backup der Daten vorraus. Dies
kann ein Vollbackup, differentielles oder inkrementelles Backup sein. Es werden
ausschließlich die Daten gesichert, welche sich zum Zeitpunkt des letzten
Backups geändert haben. Zum Wiederherstellen des Datenbestandes werden somit
alle Backups benötigt, da die Änderungen sequenziell eingespielt werden müssen.
Dies führt beim dem Einsatz von Magnetbändern gerade dazu, dass Administratoren
panisch auf die Suche nach den Magnetbändern gehen, wenn Daten vergangener Jahre
wiedergerstellt werden müssen. Grund für die Aufregung ist, dass wenn ein Backup
oder Magnetband fehlt die Wiederherstellung der gesicherten Daten nicht möglich
ist.
Die folgende Abbildung beschreibt den Speicherverbrauch pro Wochentag und hebt
hervor, welche Änderungen in welchem inkrementellen Backup gesichert sind.
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/inkrementell-backup.png}
\caption{Inkrementelle Backups}%
\label{fig:backup.inkrementell}
\end{figure}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Vorteile:}
\begin{enumerate}[itemsep=0pt]
\item Sehr einfaches Verfahren
\item Niedriger Speicherbedarf. Die Backups sind wesentlich kleiner als
differentielle oder Vollbackups. Es werden daher auch Magnetbänder mit
geringerer Kapazität benötigt. Kosten können so gesenkt werden.
\item Das Erstellen der Sicherung ist im Vergleich zu den anderen Methoden
schneller erstellt, da nur die letzten Änderungen gesichert werden müssen.
\end{enumerate}
\item \textbf{Nachteile:}
\begin{enumerate}[itemsep=0pt]
\item Das Vollbackup und \textbf{alle} inkrementellen Backups sind
notwendig, um einen Zeitpunkt wiederherzustellen.
\end{enumerate}
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{Differenzielles Backup}%
\label{sec:backup.differentiell}
Das differentielle Backup ist dem inkrementellen Backup sehr ähnlich. Es werden
jedoch nicht die Änderungen zu jedem letzten beliebigen Backup gesichert,
sondern ausschließlich zum letzten Vollbackup. Demnach ist zur Wiederherstellung
der Daten das letzte Vollbackup und das gewünschte differentielle Backup
notwendig. Die folgende Abbildung spiegelt wie Abbildung
\ref{fig:backup.inkrementell} den Speicherverbrauch pro Wochentag ab und hebt
hervor, welche Änderungen in welchem differenziellen Backups gesichert sind.
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/differentielles-backup.png}
\caption{Differenzielle Backups}%
\label{fig:backup.differentiell}
\end{figure}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Vorteile:}
\begin{enumerate}[itemsep=0pt]
\item Weniger Speicherbedarf als bei einem Vollbackup, aber mehr als bei
einem inkrementellen Backup
\item Zur Wiederherstellung wird nur das letzte Vollbackup und das
differentielle Backup zum gewünschten Zeitpunkt benötigt.
\end{enumerate}
\item \textbf{Nachteile:}
\begin{enumerate}[itemsep=0pt]
\item Dateien, die einmal verändert werden, müssen bei jedem differentiellen
Backup neu gesichert werden. Dadurch entsteht ein höheres Datenaufkommen.
\end{enumerate}
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{Vollbackup}%
\label{sec:backup.vollbackup}
Bei einem Vollbackup wird der komplette Datenbestand gesichert. Um verlorene
Daten wiederherzustellen wird nur das entsprechende Vollbackup benötigt. Die
folgende Abbildung beschreibt das Wachstum der Vollbackups pro Tag.
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{img/vollbackups.png}
\caption{Vollbackups}%
\label{fig:backup.vollbackup}
\end{figure}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Vorteile:}
\begin{enumerate}[itemsep=0pt]
\item Sehr einfache Wiederherstellung
\item Nur das jeweilige Backup bzw. Band notwendig
\end{enumerate}
\item \textbf{Nachteile:}
\begin{enumerate}[itemsep=0pt]
\item Sehr hoher Speicherverbrauch
\item Um auf mehrere Versionen zurückgreifen zu können wird das jeweilige
Backup benötigt.
\end{enumerate}
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{Großvater-Vater-Sohn Prinzip}%
\label{sec:backup.gvs-prinzip}
Das Großvater-Vater-Sohn Prinzip, auch Generationen Prinzip genannt, ist ein
Rotationsverfahren für Magnetbänder, um mit möglichst wenigen Magnetbändern den
Zugriff auf ältere Sicherungszustände zu gewährleisten.
Als Sohn-Sicherung werden die täglichen Sicherungen von Montag bis Donnerstag
beschrieben. Dies sind in der Regel inkrementelle Sicherungen. Die Sicherung,
welche Freitags erstellt wird, ist die erste Vater-Sicherung. Für die erste
Woche sind daher fünf Magnetbänder notwendig.
Wird nun bei der Vater-Sicherung ein differentielles Backup erstellt, sind die
Änderungen, welche in der Woche angefallen sind inkludiert. Dies bedeutet, dass
die Sicherungsbänder von Montag bis Donnerstag in der zweiten Woche
wiederverwendet und überschrieben werden können.
Daraus folgt, dass ein sechstes Band für die 2. Vater-Sicherung in der 2. Woche
notwendig ist. Dies geht so für die 3. und 4. Woche des Monats weiter. Es
resultiert daher für einen Monat, dass vier Sicherungsbänder für die
Sohn-Sicherungen und vier Sicherungsbänder für die Vater-Sicherungen notwendig
sind. Also insgesamt acht Bänder.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1a:} Gehen Sie davon aus, dass zu Beginn des Monats ein
Vollbackup des vergangenen Monats existiert. Geben Sie tabellarisch oder
grafisch für den aktuellen Monat an, an welchen Tagen, welches Band und
Backup-Methode verwendet wird, um dem Vater-Sohn Prinzip zu entsprechen.
\end{itemize}
Am letzten Tag im Monat wird die Sohn- oder Vater-Sicherung durch die
Großvater-Sicherung ersetzt. Die Großvater-Sicherung ist im Regelfall ein
Vollbackup. Anschließend wird wieder mit der Sohn- und Vater-Sicherung für den
nächsten Monat fortgefahren. Da die Großvater-Sicherung alle Änderungen des
letzten Monats beinhaltet, kann die Sohn-Sicherung als auch die Vater-Sicherung
im nächsten Monat überschrieben werden. Daraus resultiert, dass zusätzlich 12
Bänder für jeden Monat benötigt werden. Insgesamt also 20 Bänder pro Jahr.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1b:} Geben Sie für drei Monate tabellarisch oder
grafisch die Tage an, welches Band und Backup-Methode verwendet wird, um dem
Großvater-Vater Prinzip zu entsprechen.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{Praxisaufgabe: Die nette Kollegin}%
\label{sec:backup.praxisfall}
In dem Unternehmen, indem Sie tätig sind wird nicht Ende des Monats, sondern an
dem ersten Freitag im Monat, die Großvater-Sicherung erstellt. Die letzte
Großvater-Sicherung wurde vergangenen Freitag, den 6. November 2020, erstellt.
Eine Kollegin aus der Finanzabteilung hat Sie schriftlich informiert, dass der
letzte Praktikant ein Verzeichnis gelöscht hat, welches Sie nun benötigt. Das
Beschäftigungsverhältnis des Praktikanten fing vor drei Monaten, zwei Wochen und
einem Tagen, ausgehend von der letzen Großvater-Sicherung, an. Gehen Sie davon
aus, dass die Dateien zu diesem Zeitpunkt vorhanden waren.
Welche Bänder sind notwendig, um die Dateien und Verzeichnisse für die Kollegin
aus der Finanzabteilung wiederherzustellen?
Ihr Chef traut ihnen nun das Wiederherstellen von Daten zu. Prompt erhalten Sie
einen Anruf, dass die Daten welche sie wiederhergestellt haben nicht in der
Version vorliegt, welche die nette Kollegin erwartet hat. Sie hat sie angewiesen
die Daten vom 28. Oktober 2020 wiederherzustellen.
Welche Bänder sind notwendig, um die Daten und Verzeichnisse vom 28. Oktober
2020 wiederherzustellen?.

View File

@ -0,0 +1,649 @@
% <#>---------------------------------------------------------------------------<#>
\section{Text Processing}%
\label{sec:text-processing}
Unter Text Processing versteht man das Einlesen, Filtern, Modifizieren und
Umleiten von Dateien oder Streams. Dieses Kapitel behandelt daher die gängigen
Programme, welche ein Linux Systemadministrator oder Entwickler als sein
Handwerkszeug betrachten würde.
Bevor jedoch die Programme erklärt werden, sind die Grundlagen von Umleitungen
und Befehlsverkettungen notwendig.
% <#>---------------------------------------------------------------------------<#>
\subsection{Umleitungen und Befehlsverkettungen}
\label{sec:text-processing.redirections}
Nachfolgend wird der Begriff Befehlsverkettung oder auch Kommandoverkettung
anhand von Syntax Beispielen näher erläutert.
\begin{itemize}[label={},itemsep=0pt]
\item \bashinline{cmd1 | cmd2} \\
Die \textit{Pipe} verbindet die Standard-Ausgabe (\textit{stdout}) eines
Programms mit der Eingabe (\textit{stdin}) eines anderen Programms.
\item \bashinline{cmd1 ; cmd2} \\
Führt erst das Programm \textit{cmd1} aus und anschließend das Programm
\textit{cmd2} - ganz egal, ob Programm \textit{cmd1} einen Fehler geworfen hat
oder nicht.
\item \bashinline{cmd1 && cmd2} \\
Jedes Programm übergibt zuletzt an das Betriebssystem einen sogenannten
Returncode (auch Errorlevel oder Exitlevel genannt). Bei einem Returncode 0
ist alles in Ordnung, bei einem Wert ungleich 0 trat ein Fehler auf. In diesem
Fall der Kombination wird \textit{cmd2} nur ausgeführt, wenn der Returncode
von \textit{cmd1} gleich 0 war.
\item \bashinline{cmd1 || cmd2} \\
Dies ist genau das Gegenteil. Das Programm \textit{cmd2} wird nur ausgeführt,
wenn der Returncode von \textit{cmd1} ungleich 0 war.
\item \bashinline{cmd1 & cmd2} \\
Das \&-Zeichen am Ende einer Befehlszeile veranlasst, dass das Programm in den
Hintergrund verlagert wird und ihnen die Prompt wieder zur Verfügung gestellt
wird. Dadurch ist es möglich über eine Session mehrere Befehle auszuführen.
Nichts anderes passiert hier. Das Programm \textit{cmd1} wird in den
Hintergrund verlagert. Das Programm \textit{cmd2} wird nach der Verlagerung
ausgeführt.
\end{itemize}
Neben den Befehlsverkettungen gibt es auch noch Umleitungen der Ein- und
Ausgabekanäle (\textit{stdin}, \textit{stdout}, \textit{stderr}).
\begin{itemize}[label={},itemsep=0pt]
\item \bashinline{cmd > /tmp/output.log} oder auch \bashinline{cmd 1> /tmp/output.log} \\
Die Standard-Ausgabe \textit{stdout} wird in die Datei \textit{/tmp/output.log}
geschrieben.
\item \bashinline{cmd >> /tmp/output.log} \\
Die Standard-Ausgabe \textit{stdout} wird an die Datei \textit{/tmp/output.log}
angehängt.
\item \bashinline{cmd 2> /tmp/output.log} \\
Die Standard-Fehlerausgabe \textit{stderr} wird an die Datei \textit{/tmp/error.log}
geschrieben.
\item \bashinline{cmd &> /tmp/complete.log} \\
Die Standard-Ausgabe \textit{stdout} und die -Fehlerausgabe \textit{stderr}
werden in die Datei \textit{/tmp/complete.log} geschrieben. geschrieben.
\item \bashinline{cmd < /tmp/input} \\
Die Standard-Eingabe \textit{stdin} erfolgt nicht durch die Tastatur, sondern
aus der Datei \textit{/tmp/input}.
\item \bashinline{cmd << EOT} \\
Die Standard-Eingabe wird nur bis zu der frei wählbaren Zeichenfolge EOT
gelesen und anschließend beendet. Man nennt diese Konstruktion HERE-Dokument.
Dazu später mehr.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{cat}
\label{sec:text-processing.cat}
Das Programm \textit{cat} konkateniert mehrere Dateien und schreibt diese auf
die Standard-Ausgabe \textit{stdout}. Nachfolgend einige Beispiele.
Die Ausgabe der Datei \textit{/etc/passwd}. Die Zeilen wurden gekürzt.
\begin{bashcode}
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
\end{bashcode}
Die Datei \textit{/etc/passwd} und \textit{/etc/group} werden zusammengeführt
und nach \textit{/tmp/user-and-groups} umgeleitet.
\begin{bashcode}
$ cat /etc/passwd /etc/group > /tmp/user-and-groups
\end{bashcode}
In dem folgenden Beispiel wird ein HERE-Dokument genutzt, um die Eingabe in eine
Datei umzuleiten.
\begin{bashcode}
$ cat > /tmp/my-here-document <<EOF
Hello,
this is my first here document.
EOF
\end{bashcode}
% #>-----------------------------------------------------------------------------<#
\subsection{wc}
\label{sec:text-processing.wc}
Mit Programm \textit{wc} lassen sich die Wörter, Zeilen oder Buchstaben von
einer Standard-Eingabe oder Dateien zählen. Das folgende Beispiel addiert die
Zeilen der Datei \textit{/etc/passwd} und \textit{/etc/group}.
\begin{bashcode}
$ wc --lines /etc/passwd /etc/group
42 /etc/passwd
62 /etc/group
104 total
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 1a:} Zählen Sie die Buchstaben und Wörter der Datei
\textit{/etc/services}. Definieren Sie die Quelle einmal per Pfad zur Datei und
ein anderes mal per Befehlsverkettung - \textit{Pipe}.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{date}
\label{sec:text-processing.date}
Mit dem Programm \textit{date} können Daten, basierend auf dem aktuellen oder
einem vordefinierten Datum, berechnet werden. Zusätzlich kann das Format anhand
eines Formatstrings bestimmt werden. Die einzelnen Formatattribute sind in der
Dokumentation von \textit{date} beschrieben. Schauen Sie sich für weitere
Informationen die Dokumentation an: \textit{man date}.
Nachfolgend einige Beispiele ein Datum basierend auf den Anforderungen zu
berechnen.
\begin{bashcode}
$ # Gibt das aktuelle Datum und die Uhrzeit aus
$ date '+%Y-%m-%d %H:%M:%S'
2020-11-14 16:35:07
$ # Gibt das Datum des letzten Montags aus
$ date --date 'last monday' '+%Y-%m-%d'
2020-11-09
$ # Berechnet das Datum des letzten Montags vor zwei Wochen
$ date --date 'last monday + 14 day ago' '+%Y-%m-%d'
2020-10-26
$ # Gibt das Datum des kommenden Montags aus
$ date --date 'next monday' '+%Y-%m-%d'
2020-11-16
$ # Berechnet das Datum des nächsten Montags in zwei Wochen
$ date --date 'next monday + 14 day' '+%Y-%m-%d'
2020-11-30
$ # Berechnet das Datum des letzten Montags in zwei Wochen
$ date --date 'last monday + 14 day' '+%Y-%m-%d'
2020-11-23
$ # Gibt das Datum und die Uhrzeit für die Zeitzone
$ # America/New_York aus
$ TZ=America/New_York date '+%Y-%m-%d %H:%M:%S %z'
2020-11-14 10:41:39 -0500
$ # Gibt das Datum, die Uhrzeit, Kalenderwoche und den Tag aus
$ date '+%A, %Y-%m-%d %H:%M:%S, KW %V'
Samstag, 2020-11-14 16:42:44, KW 46
$ # Addiert zwei Tage auf den 3. Oktober 2020
$ date --date '03 OCT 2020 + 2 day' '+%Y-%m-%d'
2020-10-05
$ # Addiert zwei Tage auf den 3. Oktober vor 5 Jahren.
$ date --date "03 OCT $(date --date '5 year ago' '+%Y') + 2 day" '+%Y-%m-%d'
2015-10-05
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 2a:} Berechnen Sie das Datum des kommenden Sonntags.
Verwenden Sie folgendes Format: \textit{2020-05-31}. Erkundigen Sie sich in
der Dokumentation über weitere Formatattribute.
\item \textbf{Aufgabe 2b:} Berechnen Sie das Datum des letzten Dienstags vor
einem Monat. Verwenden Sie folgendes Format: \textit{Dienstag, 2020-05-31, KW
22}
\item \textbf{Aufgabe 2c:} Berechnen Sie das Datum des Mittwochs der 44 KW vor
12 Jahren für die Zeitzone Africa/Mogadishu. \textit{KW 22, Dienstag, 15
November 2008}.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{sed}
\label{sec:text-processing.sed}
Das Programm \textit{sed} ist ein stream Editor, welcher zum Filtern,
Modifizieren und Löschen von Textstreams geeignet ist.
Das Programm bietet einen sehr großen Umfang an zusätzlichen Optionen an. Nicht
alle Optionen werden behandelt. Der Fokus liegt ausschließlich auf den gängigen
Optionen, welche öfters in der Praxis verwendet werden. Weitere Informationen zu
allen möglichen Optionen können über die Dokumentation abgerufen werden:
\textit{man sed}.
In dem folgenden Beispiel wird der Inhalt der Datei \textit{/etc/passwd} durch
\textit{sed} modifiziert und auf der Standard-Ausgabe ausgegeben. Die
Zeichenkette \textit{root} wird durch \textit{nobody} ersetzt. Vergleichen Sie
die ersten Zeilen der Ausgabe mit der ursprünglichen Datei.
Für komplexere Kriterien können Reguläre Ausdrücke verwendet werden. Falls Ihnen
Reguläre Ausdrücke fremd sind, informieren Sie sich bitte im Internet über
Reguläre Ausdrücke.
\begin{bashcode}
$ sed 's/root/nobody/g' /etc/passwd
nobody:x:0:0:nobody:/nobody:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
\end{bashcode}
Möchte man Reguläre Ausdrücke verwenden kann das Flag bzw. die Option
\textit{-e, --expression} verwendet werden. Allerdings hat diese Option den
Nachteil, dass Zeichen für Reguläre Ausdrücke maskiert werden müssen. Anders ist
dies bei dem Flag \textit{-E, -r, --regexp-extended}. Die Syntax der Regulären
Ausdrücke ist identisch zu der Syntax von \textit{grep} mit dem Flag
\textit{--perl-regexp} und sollte daher bevorzugt verwendet werden.
In dem folgenden Beispiel wird die Ausgabe umgeleitet in eine Datei.
\begin{bashcode}
$ sed 's/root/nobody/g' /etc/passwd > /tmp/passwd_modified
\end{bashcode}
Möchte man die selbe Datei anhand von Kriterien Filtern und Modifizieren bietet
sich die Option bzw. das Flag \textit{-i, --in-place} an. Die Änderungen werden
direkt in die Quelldatei übernommen.
In dem folgenden Beispiel wird die Zeile 5 bis 10 und die Zeile 12 aus der Datei
\textit{/tmp/passwd\_modified} entfernt.
\begin{bashcode}
$ sed --in-place '5,10d;12d' /tmp/passwd_modified
\end{bashcode}
Sicherlich fragen Sie sich nun was die Zeichen \textit{s/}, \textit{d} oder
\textit{/g} zu Beginn oder zum Ende der Bedingung bedeuten. Mit \textit{s/} wird
\textit{sed} mitgeteilt, dass eine Zeichenkette durch eine andere ersetzt werden
soll. Die Zeichen \textit{/g} bedeuten, dass der Ausdruck auf alle Treffer
angewendet werden soll. Eine andere Bedeutung für das \textit{g} ist
\glqq{}global\grqq{}. Nun, wofür \textit{d} steht können Sie sich nun schon
denken - \textit{delete}.
In dem folgenden Beispiel werden alle Zeilen aus der Datei \textit{/etc/passwd}
und \textit{/etc/group} entfernt, die mit der Zeichenkette \textit{root} beginnen.
\begin{bashcode}
$ sed --regexp-extended '/^root/d' /etc/passwd /etc/group
\end{bashcode}
Ein invert ist ebenfalls möglich. In dem folgenden Beispiel werden alle Zeilen
außer die fünfte Zeile entfernt.
\begin{bashcode}
$ sed '5!d' /etc/passwd
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
\end{bashcode}
Mithilfe von Gruppen, welche Reguläre Ausdrücke bereitstellen, können komplexe
Zeichenketten gruppiert und neu angeordnet werden. In dem folgenden Beispiel
wird die letzte Spalte der Datei \textit{/etc/passwd} an die erste Stelle
verschoben.
\begin{bashcode}
$ sed --regexp-extended 's/^(.*):(.*):(.*):(.*):(.*):(.*):(.*)$/\7:\1:\2:\3:\4:\5:\6/g' /etc/passwd
/bin/bash:root:x:0:0:root:/root
/sbin/nologin:bin:x:1:1:bin:/bin
/sbin/nologin:daemon:x:2:2:daemon:/sbin
...
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 3a:} Löschen Sie alle Zeilen, welche als Shell
\textit{/sbin/nologin} verwenden. Geben Sie die Ausgabe auf der
Standard-Ausgabe aus.
\item \textbf{Aufgabe 3b:} Löschen Sie alle Zeilen aus der Datei
\textit{/etc/passwd} und \textit{/etc/group}, welche mit \textit{root} oder
\textit{system} beginnen. Zählen Sie anschließend die Zeilen. Nutzen Sie dazu
die Umleitung von einem Programm zu einem anderen per \textit{Pipe}.
\item \textbf{Aufgabe 3c:} Bereinigen Sie die Datei \textit{/etc/services}.
Löschen Sie Kommentarzeilen und Zeilen welche leer sind. Manche Zeilen
enthalten am Ende Kommentare, entfernen Sie diese.
\item \textbf{Aufgabe 3d:} Suchen Sie in der Datei \textit{/etc/services} nach
Zeilen, welche mit dem Port 5 beginnen und vertauschen Sie den Port mit dem
Protokoll.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{grep}
\label{sec:text-processing.grep}
Das Programm \textit{grep} wird primär dazu verwendet Dateien oder Streams nach
Schlagwörtern zu filtern. Ähnlich wie bei \textit{sed} können auch hier nicht
alle Optionen oder Flags ausführlich in Detail behandelt werden. Aus diesem
Grund liegt der Fokus erneut auf den gängigen Optionen bzw. Flags aus der Praxis.
Das nachfolgende Beispiel filtert die Datei \textit{/etc/passwd} und
\textit{/etc/group} nach der Zeichenkette \textit{root} und hebt diese farblich
hervor.
\begin{bashcode}
$ grep --color root /etc/passwd /etc/group
/etc/passwd:root:x:0:0:root:/root:/bin/bash
/etc/passwd:operator:x:11:0:operator:/root:/sbin/nologin
/etc/group:root:x:0:
\end{bashcode}
In dem folgenden Beispiel wird ein Regulärer Ausdruck verwendet, um nach der
Zeichenkette \textit{root} oder \textit{sophie}, beginnend für jede Zeile, in
der Datei \textit{/etc/passwd} zu suchen.
\begin{bashcode}
$ grep --color --perl-regexp '^(root|sophie)' /etc/passwd
root:x:0:0:root:/root:/bin/bash
sophie:x:2003:100:Sophie Becker:/home/sophie:/bin/bash
\end{bashcode}
Manchmal möchte man allerdings nur die gefundenen Schlagwörter der Zeile
weiterverarbeiten. Dazu stellt das Programm \textit{grep} die Option
\textit{--only-matching} bereit. Nachfolgend wird der gleiche Befehl erneut
ausgeführt mit der Option.
\begin{bashcode}
$ grep --color --only-matching --perl-regexp '^(root|sophie)' /etc/passwd
root
sophie
\end{bashcode}
Sicherlicht kennen einige die folgende Situation. Unterhalb eines Verzeichnisses
liegen sehr viele Dokumente. Eines von diesen enthält einen Begriff, welcher
dort erklärt oder beschrieben wird. In dem nachfolgenden Beispiel werden alle
Dateien rekursiv geöffnet und nach den Schlagwörtern durchsucht. In der Ausgabe
ist der Dateiname und die Zeile als auch das Schlagwort enthalten, welches den
Treffer ausgelöst hat.
\begin{bashcode}
$ grep --color --recursive --perl-regexp '(btrfs|subvolume|snapshot)' ~/workspace/linux_ws2021
~/workspace/linux_ws2021/referenzen/bibliothek.bib: @online{fedora33-btrfs-default,
~/workspace/linux_ws2021/referenzen/bibliothek.bib: url = {https://fedoramagazine.org/btrfs-coming-to-fedora-33/},
~/workspace/linux_ws2021/referenzen/bibliothek.bib: @online{was-ist-btrfs,
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 4a:} Suchen Sie alle Zeilen aus der Datei
\textit{/etc/passwd} und \textit{/etc/group} herraus, welche nicht die
Zeichenketten \textit{root} und ihren aktuellen Benutzernamen enthalten.
Nutzen Sie zur Ermittlung ihres Benutzernamens die Umgebungsvariable
\textit{USER}.
\item \textbf{Aufgabe 4b:} Filtern Sie aus der Datei \textit{/etc/passwd} alle
Zeilen, welche mit \textit{system} beginnen. Leiten Sie die Ausgabe weiter an
\textit{sed}, um die Zeichenkette \textit{/sbin/nologin} durch
\textit{/bin/bash} zu ersetzen.
Kleiner Tipp: Statt \textit{/} können auch andere Zeichen, wie
\textit{\#} oder \textit{@}, als Trennung zwischen dem Such- und
Ersetzungspattern verwendet werden. Dies kann hilfreich sein, um ein escapen
von Verzeichnispfaden zu vermeiden.
\item \textbf{Aufgabe 4c:} Zählen Sie alle Zeilen der Datei
\textit{/etc/services}, welche das Protokoll tcp verweden.
\item \textbf{Aufgabe 4d:} Ermitteln Sie, ob in der Datei
\textit{/etc/services} noch andere Protokolle statt tcp und udp verwendet
werden. Gegen Sie die unbekannten Protokolle auf der Standard-Ausgabe aus.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{uniq}
\label{sec:text-processing.uniq}
Manchmal möchte man Treffer zählen. Beispielsweise wird eine Datei durchsucht
nach einem Schlagwort und man stellt sich die Frage, wie oft das Schlagwort in
der Datei verwendet wurde. Um diese Frage zu beantworten ist unter anderem
\textit{uniq} sehr helfreich, denn es kann Mehrfachvorkommen von Zeichenketten
vermeiden und ggfls. zählen.
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 5a:} Zählen Sie wie oft in der Datei
\textit{/etc/passwd} die Zeichkette \textit{root} verwendet wurde. Eventuell
ist es hilfreich \textit{grep} hinzuzuziehen.
\item \textbf{Aufgabe 5b:} Suchen Sie in der Datei \textit{/etc/services} nach
Diensten die nur einen Port bzw Protokoll benötigen. Nutzen Sie auch hier die
bereits kennengelernten Programme.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{column}
\label{sec:text-processing.column}
Manchmal erhält man Dateien, welche für das menschliche Auge unübersichtlich
formatiert sind. Das Programm \textit{column} kann hier insoweit Abhilfe
schaffen, dass die Eingabe in mehrere Spalten formatiert wird.
In dem folgenden Beispiel wird die Datei \textit{/etc/passwd} eingelesen, die
Spalten anhand des Trenners \textit{:} getrennt und als Tabelle auf der
Standard-Ausgabe ausgegeben.
\begin{bashcode}
$ column --separator ":" --table /etc/passwd
\end{bashcode}
Es können auch zusätzlich Kopfzeilen hinzugefügt werden. Im nächsten Beispiel
ist dies genau der Fall. Die Kopfzeile wird definiert und mit ausgegeben.
\begin{bashcode}
$ column --separator ":" \
--table \
--table-column "user,password,id,gid,comment,homedir,shell" /etc/passwd
\end{bashcode}
Wahrscheinlich wird das Programm \textit{column} häufiger verwendet, um Dateien
in json umzuwandeln. In dem folgenden Beispiel wird die Datei in json
umgewandelt.
\begin{bashcode}
$ column --separator ":" \
--table \
--table-name "passwd" \
--table-column "user,password,id,gid,comment,homedir,shell" \
--json /etc/passwd
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 6a:} Filtern Sie alle Zeilen aus der Datei
\textit{/etc/services}, welches das UDP-Protokoll verwenden und mit dem
Buchstaben \textit{n} beginnen. Teilen Sie die zweite Spalte auf in Port und
Protokoll. Die Ausgabe muss in ein json umgewandelt werden. Der Tabellenname
ist \textit{services} und die Spalten sollen \textit{service}, \textit{port}
und \textit{protocol} heißen. Speichern Sie die Ausgabe in die Datei
\textit{/tmp/services.json} ab.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{head und tail}
\label{sec:text-processing.head-und-tail}
Mit den bisherigen Programmen können wir schon einiges erreichen, doch fehlt es
an der Möglichkeiten die Ausgabe zu beschränken. Mit den Programmen
\textit{head} und \textit{tail} kann genau das erreicht werden. Beide Programme
schreiben auf die Standard-Ausgabe \textit{stdout}, wenn keine Umleitung
definiert ist.
Mit dem Programm \textit{head} können n Zeilen, beginnend ab der ersten Zeile,
ausgegeben werden. Das Programm \textit{tail} dagegen zählt ab der letzten
Zeile.
In dem nachfolgenden Beispiel werden die ersten drei Zeilen der Datei
\textit{/etc/passwd} ausgegeben.
\begin{bashcode}
$ head --lines=3 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
\end{bashcode}
Das nächste Beispiel gibt die letzten drei Zeilen aus.
\begin{bashcode}
$ tail --lines=3 /etc/passwd
tobias:x:2005:100:Tobias Moretti:/home/tobias:/bin/bash
lisa:x:2006:100:Lisa Meerkamp:/home/lisa:/bin/bash
manfred:x:2007:100:Manfred Krupp:/home/manfred:/bin/bash
\end{bashcode}
Zusätzlich besitzt \textit{tail} die Möglichkeit alle Zeilen, beginnend ab der
n-ten Zeile, auszugeben. In dem folgenden Beispiel wird die Datei
\textit{/etc/passwd} ab der 35en Zeile ausgegeben. Die Ausgabe ist zusätzlich
noch einmal gekürzt.
\begin{bashcode}
$ tail --lines=+35 /etc/passwd
hugo:x:2000:100:Hugo McKinnock:/home/hugo:/bin/bash
hans:x:2001:100:Hans Rakinzsky:/home/hans:/bin/bash
marie:x:2002:100:Marie Haseloff:/home/marie:/bin/bash
sophie:x:2003:100:Sophie Becker:/home/sophie:/bin/bash
\end{bashcode}
Manche Programme, insbesondere Dienste, schreibe Log-Dateien, welche gerade für
Administratoren oder Entwickler interessant sein können. Um ausschließlich die
neusten Zeilen aus einer Logdatei zu erhalten bietet das Programm \textit{tail}
die Option \textit{-f, --follow} an. Dadurch wird veranlasst, dass stets neu
hinzukommende Zeilen direkt ausgegeben werden, ohne das das Programm erneut
gestartet werden muss.
% #>-----------------------------------------------------------------------------<#
\subsection{cut}
\label{sec:text-processing.cut}
Das Programm \textit{cut} ist genau das richtige Programm, um Spalten, getrennt
durch einen Trenner, auszuwählen. In dem nachfolgenden Beispiel wird
ausschließlich die erste Zeile der Datei \textit{/etc/passwd} ausgegeben.
\begin{bashcode}
$ cut --delimiter=":" --fields=1 /etc/passwd
root
bin
daemon
...
\end{bashcode}
Es ist auch möglich mehrere Spalten zu selektieren. In dem folgenden Beispiel
wird ausschließlich die zweite bis vierte und siebte Spalte selektiert.
\begin{bashcode}
$ cut --delimiter=":" --fields=2-4,7 /etc/passwd
x:0:0:/bin/bash
x:1:1:/sbin/nologin
x:2:2:/sbin/nologin
...
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 7a:} Nutzen Sie die bereits bekannten Programme, um die
Datei \textit{/etc/services} zu bereinigen. Lassen Sie sich anschließend nur
die Spalte mit den Ports und Protokollen anzeigen. Leiten Sie die Ausgabe in
die Datei \textit{/tmp/port-protocol} um.
\item \textbf{Aufgabe 7b:} Verwenden Sie die Programme \textit{echo},
\textit{cut}, \textit{cat}, \textit{tail} und \textit{head}, um die folgenden
Felder aus der Datei \text{/etc/passwd} zu selektieren. Spalte/Zeile: (1/1),
(3/7), (5/3), (7/4).
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{sort}
\label{sec:text-processing.sort}
Um nach Spalten zu sortieren wird durch die GNU Core Utility Collection das
Programm \textit{sort} bereit gestellt. Dieses Programm kann nach mehreren
möglichen Optionen sortieren. Nach einfachem Text, nach Speichergrößen, Zahlen,
Monaten (JAN$<$DEC) oder Versionen. Weitere Optionen sind in der Dokumentation
beschrieben.
Das nächste Beispiel behandelt die Sortierung der Ausgabe des Programms
\textit{df}. Das Programm \textit{df} gibt Informationen über den gesamten,
freien und verbrauchten Speicherplatz der eingehängten Partitionen aus. Die
Ausgabe wird nach der dritten Spalte aufsteigend sortiert. Dazu wird die Option
bzw. das Flag \textit{-k, --key} übergeben. Durch dieses Flag kann die Spalte
zur Sortierung übergeben werden. Mittels tail wird zudem die Kopfzeile
abgeschnitten.
\begin{bashcode}
$ df | tail --lines +2 | sort --key 3 --numeric-sort
tmpfs 401876 0 401876 0% /run/user/0
tmpfs 2009384 4 2009380 1% /tmp
tmpfs 2009384 1068 2008316 1% /run
/dev/vda1 613184 8740 604444 2% /boot/efi
...
\end{bashcode}
Die Speichergrößen können auch abgerundet werden durch die gängigen
Speicherabkürzungen K (Kilobyte), M (Megabyte), G (Gigabyte), T (Terabyte) ect.
In dem folgenden Beispiel wird dazu die Option \textit{--human-readable} dem
Programm \textit{df} übergeben. Anschließend muss sort mitgeteilt werden, dass
die Spalte nun Speichergrößen mit ihren Abkürzungen enthält. Andernfalls
sortiert \textit{sort} falsch.
\begin{bashcode}
$ df --human-readable | tail --lines +2 | sort --key 3 --human-numeric-sort
tmpfs 393M 0 393M 0% /run/user/0
tmpfs 2,0G 4,0K 2,0G 1% /tmp
tmpfs 2,0G 1,1M 2,0G 1% /run
/dev/vda1 599M 8,6M 591M 2% /boot/efi
...
\end{bashcode}
In den beiden Beispielen wurde stets nach einer Spalte sortiert. Es ist jedoch
auch möglich eine Sortierreihenfolge zu definieren. Dies wird erreicht indem das
Flag \textit{-k, --key} mehrfach definiert wird. In dem folgenden Beispiel wird
erst nach dem Mountpoint sortiert und anschließend nach dem gesamten
Speicherplatz.
\begin{bashcode}
$ df --human-readable | tail --lines +2 | sort --key 6 --key 3h
/dev/vda4 17G 4,0G 13G 25% /
/dev/vda2 1014M 228M 787M 23% /boot
/dev/vda1 599M 8,6M 591M 2% /boot/efi
...
\end{bashcode}
Sicherlich fragen Sie sich nun, was der Buchstabe \textit{h} bei Angabe der
zweiten Spalte bedeutet. Es ist möglich \textit{sort} mitzuteilen welche Spalte
welches Format besitzt. Der Buchstabe \textit{h} bedeutet nichts weiteres als
\textit{human-numeric-sort}. Informieren Sie sich in der Dokumentation über die
anderen Buchstaben, um einer Spalte ein Schema zuzuweisen.
In dem folgenden Beispiel wird nach dem dritten Zeichen, der ersten Spalte
von der Ausgabe \textit{df}, absteigend sortiert.
\begin{bashcode}
$ df | tail --lines +2 | sort --reverse --key 1.3
devtmpfs 1989716 0 1989716 0% /dev
tmpfs 401876 0 401876 0% /run/user/0
tmpfs 2009384 4 2009380 1% /tmp
...
\end{bashcode}
\begin{itemize}[label={},itemsep=0pt]
\item \textbf{Aufgabe 8a:} Bereinigen Sie die Datei \textit{/etc/services} und
leiten die Ausgabe an \textit{sort} weiter. Sortieren Sie aufsteigend nach dem
Port, absteigend nach dem Protokoll und anschließend aufsteigend nach dem
Namen.
\item \textbf{Aufgabe 8b:} Sortieren Sie die Datei \textit{/etc/passwd} nach
der \textit{UID} und \textit{GID} absteigend. Anschließend nach dem
Benutzernamen.
\end{itemize}
% #>-----------------------------------------------------------------------------<#
\subsection{join}
\label{sec:text-processing.join}
Sicherlich kennen Sie das \textit{JOIN} Statement von SQL. Ähnlich zu dem
SQL-Statement verhält sich das Programm \textit{join}, jedoch mit einigen
Restriktionen.
\begin{itemize}[itemsep=0pt]
\item Die Spalten müssen nach dem Fremdschlüssel sortiert sein.
\item Beide Dateien müssen den gleichen Trenner verwenden.
\item Kann ein Fremdschlüssel nicht aufgelöst werden, wird eine Fehlermeldung
für die jeweilige Zeile ausgegeben.
\end{itemize}
Im folgenden Beispiel werden die Zeilen aus den Dateien \textit{/etc/passwd} und
\textit{/etc/group} über die Spalte \textit{GID} miteinander verbunden und
weitergeleitet. Dazu werden beide Dateien vorab sortiert. Können Fremdschlüssel
nicht aufgelöst werden wird die Fehlermeldung dazu nach \textit{/dev/null}
umgeleitet. Die Ausgabe wird anschließend noch einmal nach dem Benutzernamen
sortiert.
Informieren Sie sich in der Dokumentation über die Bedeutung der Optionen bzw.
Flags.
\begin{bashcode}
$ join -t ":" -1 3 -2 4 <(sort --field-separator=":" --key 3n /etc/group) <(sort --field-separator=":" --key 4n /etc/passwd) 2> /dev/null | sort --field-separator=":" --key 5
0:root:x::halt:x:7:halt:/sbin:/sbin/halt
0:root:x::operator:x:11:operator:/root:/sbin/nologin
0:root:x::root:x:0:root:/root:/bin/bash
...
\end{bashcode}

134
chapters/99-awk.tex Normal file
View File

@ -0,0 +1,134 @@
% ##########################################################################
% ############################ Übungsblatt AWK #############################
% ##########################################################################
\section{AWK}
\label{sec:awk}
% ############################### Aufgabe 01 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe01}
Geben Sie alle Zeilen der Datei \texttt{/bin/passwd} mithilfe von awk aus.
\subsubsection*{Lösung}
\label{sec:awk.aufgabe01.loesung}
% \inputbash{./awk/01-aufgabe.sh}
% ############################### Aufgabe 02 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe02}
Gebem Sie von allen Benutzern den username, badname und die login shell aus.
Greifen Sie dazu erneut auf die Datei \texttt{/etc/passwd} zu. Die Ausgabe soll
ähnlich wie die Tabelle \ref{tbl:awk.aufgabe02.beispielausgabe} aussehen.
\begin{table}[H]
\begin{tabularx}{\textwidth}{X|X|X}
\textbf{user} & \textbf{badname} & \textbf{shell} \\
\hline\hline
root & & \texttt{/bin/bash} \\
postfix & & \texttt{/bin/nologin} \\
markus & Markus Pesch & \texttt{/bin/bash} \\
$[$\dots$]$ & $[$\dots$]$ & $[$\dots$]$ \\
\end{tabularx}
\caption{AWK - Beispielsausgabe}
\label{tbl:awk.aufgabe02.beispielausgabe}
\end{table}
\subsubsection*{Lösung}
\label{sec:awk.aufgabe02.loesung}
% \inputbash{./awk/02-aufgabe.sh}
% ############################### Aufgabe 03 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe03}
Modifizieren Sie Aufgabe \ref{sec:awk.aufgabe02}, sodass nur Benutzer mit einer
UID größer gleich 1000 ausgegeben werden.
\subsubsection*{Lösung}
\label{sec:awk.aufgabe03.loesung}
% \inputawk{./awk/03-aufgabe.awk}
% \inputbash{./awk/03-aufgabe.sh}
% ############################### Aufgabe 04 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe04}
Gebe Sie alle Zeilen der Datei \texttt{/etc/passwd} zwischen fünf und zehn aus.
Ergänzen Sie die Tabelle um eine Spalte. Die neue Spalte enthält die
Zeilennummer.
\subsubsection*{Lösung}
\label{sec:awk.aufgabe04.loesung}
% \inputawk{./awk/04-aufgabe.awk}
% \inputbash{./awk/04-aufgabe.sh}
% ############################### Aufgabe 05 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe05}
Modifiziere Sie die Aufgabe \ref{sec:awk.aufgabe04}, sodass die logischen
Entscheidungen in eine Funktion ausgelagert werden.
\subsubsection*{Lösung}
\label{sec:awk.aufgabe05.loesung}
% \inputawk{./awk/05-aufgabe.awk}
% \inputbash{./awk/05-aufgabe.sh}
% ############################### Aufgabe 06 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe06}
Lesen Sie die Datei \texttt{credit\_master.csv} ein. Die Datei enthält
unerwünschte Leerzeichen. Korrigieren Sie diese Datensätze indem Sie die
unerwünschten Leerzeichen entfernen. Als boolsche Variablen sind ausschließlich
ja und nein akzeptabel. Entfernen Sie auch hier die Datensätze, deren boolsche
Variablen nicht übereinstimmen.
Die validen Datensätze sollen in die Datei
\texttt{csv/credit\_master\_cleaned.csv} gespeichert werden.
\subsubsection*{Lösung}
\label{sec:awk.aufgabe06.loesung}
% \inputawk{./awk/06-aufgabe.awk}
% \inputbash{./awk/06-aufgabe.sh}
% ############################### Aufgabe 06 ###############################
\subsection{Aufgabe}
\label{sec:awk.aufgabe07}
Lesen Sie die Datei \texttt{credit\_master\_cleaned.csv} ein. Erstellen Sie für
jede Zeile ein passendes SQL-Statement, um die Zeile in die Tabelle
\texttt{credit\_master} zu überführen. Geben Sie zu Beginn das SQL-Statement zum
erstellen der notwendigen Tabelle aus. Speichern Sie ihre SQL-Statements in der
Datei \texttt{credit\_master\_cleaned.sql} ab.
Ob Sie nun die SQL-Statements in der Oracle, Maria, MySQL, Postgres oder SQLite
Notation erstellen ist ihnen überlassen, jedoch verwenden Sie den passenden
boolschen Datentyp je nach Datenbank, um die boolschen Variablen zu überführen.
Verwenden Sie sofern möglich ihre eigene \texttt{credit\_master\_cleaned.csv} Datei.
\subsubsection*{Lösung}
\label{sec:awk.aufgabe07.loesung}
% \inputawk{./awk/07-aufgabe.awk}
% \inputbash{./awk/07-aufgabe.sh}

30
chapters/99-questions.tex Normal file
View File

@ -0,0 +1,30 @@
\section{Assessment Test}
\label{sec:assessment-test}
\subsection{Aufgabe}
\label{sec:assessment-test.aufgabe01}
Welche der folgenden namen sind shell Programme? (Wähle Sie alle, welche
zutreffen)
\begin{itemize}[itemsep=0pt]
\item Bash
\item Korn Shell
\item Born Shell
\item Dash
\item Z Shell
\end{itemize}
\subsection{Aufgabe}
\label{sec:assessment-test.aufgabe02}
Sie sind Administrator eines Linux Servers. Sie benötigen jene Logs seit dem 30
Mai, welche die IPv4 Adresse 192.168.10.42 enthalten. Das Datum wird in
englischer Notation gespeicher. Die Logs sind in \texttt{/var/log/messages}
gespeichert. Welche der folgenden \texttt{grep} Befehle ist der beste Befehl?
\begin{itemize}[itemsep=0pt]
\item \bashinline{grep "May 30?192.168.10.42" /var/log/messages}
\item \bashinline{grep "May 30.*192.168.10.42" /var/log/messages}
\item \bashinline{grep -i "May 30.*192.168.10.42" /var/log/messages}
\item \bashinline{grep -i "May 30?192.168.10.42" /var/log/messages}
\item \bashinline{grep -v "May 30.*192.168.10.42" /var/log/messages}
\end{itemize}

1399
csv/credit_master.csv Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-09-27T15:26:21.800Z" agent="5.0 (X11)" etag="5r5OPbZKd_OzWzaFqK4M" version="13.7.5" type="device"><diagram id="njiB7J01PMf0DHfhUy9N" name="Page-1">7Vxdc5s4FP01fowHJD4fEydtd6bbyWwetvuIg2yzwYgFObb761cykg0SXy5g09SdNjUXIWTdc8890oVM4Gy9+5x48epP7KNwAjR/N4GPEwB0A4AJ+6v5+8xiAyszLJPA541OhpfgB+JGjVs3gY/SQkOCcUiCuGh8xVGEXknB5iUJ3habLXBYvGvsLZFieHn1QtX6d+CTVWZ1gH2yf0HBciXurFtudmbticb8m6Qrz8fbnAk+TeAswZhkn9a7GQrZ5Il5ya77VHH2OLAERaTNBeDxfm4tgRtq377P74MvG+hv7kQ3KdmLb4x8OgH8ECdkhZc48sKnk/UhwZvIR6xbjR6d2nzFOKZGnRr/RYTsuTe9DcHUtCLrkJ+lI07239n1U1cc/pM/97jjnWdH+/zRM0qCNSIo4caUeAm5Z66mhghHSNg+BWF4vNCXWlBL7vwCR2SGQ5wcpgBqmmXNZqzVLiDZOE1+dBwm/XwaJTvY5w7kMaq+EvOON8krqnEQ5Jj3kiUiNe1EvDDv5e7AofAZYTqcZE8bJCj0SPBehLfHo2R5bMcvpbPm7XMNYhxEJM31/MwMtAEPeEvj4c3DHeoSKKX2hl3bnn7IRiCOcl/lZDoA/QzQ8zl998INn4bnmRIGVZB4RwkJKD/ch8EyoufmmBC8zp346s1R+IzTgASYNSAsKB5CyfpKkcDg8eDxfo6GXJzgDQmDCM2O3HbAKoVtbmCzw58D5hP8hnJnLMfRHyA9s0w8P0Cnr8NDQJgfg4T2ng0rYtF87EwwHmCWlRezqVnvlozppxEiW5y8pdM1jgLC+q1GOZsatKuFJT9rWkU8AI3jepsjX25a5XjXMquBnAPT+VjR7asQpOCdTqyTo1lzFDT78zRoDsJuCh0BV4KfwJroIhsov6qG11y92I8t9ZPxudLPuXRLg7xIn7IGqB+W1HwYttUdhW7jOMaIDsUKKQwe5kkhvqz/NkwSHXLyXXqIkHvaQIfx7gAhcZ5+WrL/bXtqOFPDmOquWxqrB0IuxpdCujKrrwPfz0IZ0SF480N/DMLcI7Rz82FiPvJx8kDWYSnIa4lF4cajluV3LcjFMs68o+FtOqDgWd5Tx3C4g8Ve7+Qu8GKRIjKRSbYH1JgKaF5QQudK8fAtH0v5OM3mqVrU9pCmZd7RXVNJ03ZJmpbptL80bSh4EfTiB++d+AWRlSb6omM7dJed6esOujbVpvq0L0KsGuzlZUwfmuG0BBMCqKMYOqqfn5ZCzYzfVtaIVVvj8q6t/uHxqU2BYRgSd2u95ASjYoXXJJHOlTbQPU/aQHlcddrmdPXwmUzMTz6VbQPyulIi8rbkbJvisvnrJZVBp3nFqWsluQwOlstAfS4rsjwDTat04dB0oeSKb4j82KLkzfOp0E0Ra8ebZzmJfsdPwMhllOx29YlmwLGuvfQtN0pgmlPxT8unT2WAbcYthSMFEFFAzoGcjwhuygVRLkHQyePHvGO9brUhIjNEC9IPvI+SSyg1XYU3NErgbQwGb0uB9x+MhyJGvwxv9Odzgt8Dv0Tt/2pM9RrijV9GuZXkXM/plalgQLEPmwnSLQGQvOXRG4AAvIaWHd1mmuJx9qeTGjVaitGR1Bpss6hwmxSiUb9ZNszul7ou/erFLJZv4u8nKTXM5q8XarO1FtxmXZLbVO2HolhPtZ72BrisA1ViZ6A9UkanKV8xn7OAPqNwBCp23HOetC4pc4Aa+dswNvv2pBj/B3KlJdcAHdWVZZuLfbgSLVeLxT8b8tez/2T668V8vnu80xVP9rXzVyyEDLO7mKuPOJfdYVSB2HYt1R6w21VA0EvsHYTNlmYKReuVI7Sk7KKAtnpRJQHUVQFatqQCgwHUuYoi7qlI3aZmLEnNRn1bOk3uWfq29+KyoReX4gph9VQU1qFTuI/VuHPapTk0G1S3Xtu+s+qu8/StejhU9bATfcoANVom+D6qh+X8qW7RI7Lqqx6n22CqW0ytaapY++WqcAB2pPuBy3C9ZApgqqmimmhqynC6IZ4HPpbheNedn1QqxpCpS0/A9VWGk+jb4veponugOXXtL1KGK49xNSfkK/unooFYWI1UzvbAv9L6ynTUhzcuKl9BPwusymVK67JTaS9qiQzw5oLXuxbJrv/9RFkNNJTVuo70ioW4Q4roVojrJnrMIpEaQBU9ABpq2A22rQFUirtsHcW2O2uAi+mWPsUFaCkuMqnQ+zoU2g3Soad1qOHK0qFhYSnVc6ye3wWpdcbtZZBBXgbpRJmGDYqUWbJOHOplkHKw3N4cGi1YxLbVeMCiPsJ+A8tIwALcsTGLdR0t1qCeetVq7SVUszICgygjS3pYzjTabaooHZlShcgc6P2vqgFXjUtu3yTJTHgNSaa+MDay5XJxOwAWtgPAB9oOgLftgKG2A+QMZJVkoAtvB6gbpCODZTHsDN7cZWHnTHXb+UCRZ9wib6jIM5yxbcRBdf8bRTFM9UIFUiomAlPdvhtHhWKQB26KesqCqs8uWrIQL0YXXWak1R4Dv5fHoG2MzGPq85goqgsx+qPNs5UfxF+G9FiPaV+5KAjV7RPqL6fEXTkBoP42qw/rMNMam8PU97qow2CDw34jj8kvGwzoMXp4+sVy2br89Ov54NP/</diagram></mxfile>

1
draw/btrfs-cow.drawio Normal file
View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-10-27T17:45:48.007Z" agent="5.0 (X11)" etag="WwKqZD7jocYK9EHfiNyY" version="13.8.5" type="device"><diagram id="Gn1ND9kZ1Rsn8MRQMOzS" name="Page-1">7Zzfc6o4FMf/Gh+9QxJ++dhq2324O7MzfdjefdmJEIVbJC7EqvvXbyJBwGDLHWnJRtvOlBwIhu85n0BOiCM0Xe2eMryOfqchSUbQCncjNBtBCGwIR+LPCveFxYNuYVhmcSgPqgzP8b9EGi1p3cQhyRsHMkoTFq+bxoCmKQlYw4azjG6bhy1o0vzUNV4SxfAc4ES1/hmHLCqsPvQq+28kXkblJwN3UuxZ4fJgeSV5hEO6rZnQwwhNM0pZsbXaTUkixCt1Keo9ntl7bFhGUtalArmzrL/Yy1M+fXleh9sdfPu+GwO/OM0bTjbyimVr2b6UIKObNCTiLNYI3W+jmJHnNQ7E3i13OrdFbJXwEuCbizhJpjSh2aEuCh3ihza35yyjr6S2x4dz5Lp8j2wAyRjZnb00cBSMRxqhK8KyPT9EVnBtqbEMMl8Wt5XH7PKQqO4tVxqxjJLl8dSVkHxDavkruk4UXe97FXbhiN82Yd3Dj6hBU1azFz/9CO6BpuDAUxV3WwT/NL1LyGp63xmkt+vopjdQ9J4apLfn6aY3VPSeGaS3j3TTGyl6P5ik90Q3vW1F70eD9J5o1387it5PBukNLO0eUNoetN2ESR0awrv/bGi5Y5wfhkT8YcYCznpX7eRbS/E/T/E6j4RJHMPbFvEWiybi7HWT841v5RGiAC1ojYE1ht7fwOdPTWPLKpvB9xYtKc6rRAP3Bmu6vOnalKbkJA6kCSfxMuXFgHuPcPu98G3Mx1h3cscqDkPxMa0x1ozCXh6mnGZsWC3DBdASHOizggOoT6/9wugHJAjaYJz7ju30pCtym8yhSYuuXzsMQ56iIwn5+F4WZXw2paUZi+iSpjj5TulaCvqTMLaX2Qm8YbQpN9nF7EVU/+bI0g95MrE929UL+7KQ8gusVRLFH+X5RKGqdiiV9UKcR4e2FgTijN2JNIfAK8F5Hgel+TFOyvYVIogrf9+1XCi6yQLyjqKgTMLgbEnYewdO2oMlIwlm8VuzJf0TpY5PTBp/2yfPy8fuaqjbG3KNA60jWw0e+wQNdgStlkwcAjR1YGpS4gV5uoHmGwfa0Hc01BW0M6HyRaCpGQmTMm72RDfQJjfQegbN7goaHBQ0NRU1Mwg0x9EMtHJEeAOtN9CcrqChQUFTc5Am5dhdoBtoQFH3BtploLldQbMHBc1VQDNpcsXVbYxmq9nbG2iXgeZ1Bc0ZFDRPAc2kWTVPt6wjfD/rWDH1UFn74w7UqTsy+BF3depqEJ7hrk+GOiJUvBI4GEIKQb0CFGLiL1pnwtzAJ/NFP6D4TU6Gfx0RDTnGAh3JaN6RrA/I+PqbUNeEPBg0T6jm4y+c+OqBB6Dd6y9qcu+6g//joL40Jyer/kHjw9suMjLgySAZOScuLxoma1VeV04EYPNEyssaBd7KiQ7hc7yeC3rYIQfX/5Mg+7CH7ZogBoPmrdT88IUTMT30sKccDd7DoiHHwKbw0DWPCwZNL6lp3NllPGg16IW6LQVA6EbWxWR1TdyCQfNJat7WpAkSpNuiD2TfyLqYrK6Z2mJSYiiy1EStSTMiSLflPci5kXUxWX5XsrwhyVLXuZg0BWJrl8lSe7Ke1hVt5m802azIuYVFV7ZqCJz2qS2rhqDV4vpPWzVkq4mInNFMfKGFnl4QgSL7buD0xOPJVIvdsuboi72iDodNeiFetycLWx0jmbTQR7uZE1u935j0Grp2eVRbfZ46dvLWPKHBa349vf2xJy+9Yw/e26vf83O97vFc3dxT9p419wQZwUx457hw/mr845z6B6n+aXsvBf66e3ix+mazYo61+n449PAf</diagram></mxfile>

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-08T13:47:52.153Z" agent="5.0 (X11)" etag="Lje8PvzWndpk4Yfm-F20" version="13.9.2" type="device"><diagram id="s1RfbO-vQOXVO2XHRdqD" name="Page-1">7VzbcqM4EP0aP84WSFzsx0kyk62tStVsJTuz+0hAttnByIXxxN6vXxEkLmrbKDYCglOVB6sRcuv0Uaul7niCb1e7+8RbLx9oQKIJMoLdBN9NEDIthCbZnxHsc4mLnFywSMKAdyoFj+F/hAsNLt2GAdnUOqaURmm4rgt9GsfET2syL0noS73bnEb1b117CwIEj74XQemPMEiXuXSK3FL+OwkXS/HNpjPLn6w80ZnPZLP0AvpSEeEvE3ybUJrmn1a7WxJl4Alc8ve+HnlaKJaQOFV54ZP575P58Mc3Hy/jP/ffn+43wV+f+Ci/vGjLJ8yVTfcCgYRu44BkgxgTfPOyDFPyuPb87OkLszmTLdNVxFom+zgPo+iWRjR5fRcHNpkGFpNv0oT+JJUnU/SMHYc9gdMQOpEkJbuKiE/rntAVSZM96yKeGhxizjHk8PZLaTGLi5ZVYwmhx0myKIYucWQfOJRvgBU1w0ri4HPGT9byI2+zCf06kkdxIUGNsRCVyqztA7MWsoREXhr+qvP8EBL8G77RkGlSgD6tY27JWG7oNvEJf6lKy9PjmEgaJ/WSBUnBOK9mKSZ9vqXw+C1lSZYyzrSUK5tcHkizqSxgqvsbYCzmMtK6eequJ6YxkfwUF3lRuIgzGzMzEia/yRxQyHaCz/zBKgyC7GsO+sC6l2zBqeEj66LBp8nLpzWXZgP0vybheOGX9xTL7Bl/R+9OPZ/Pke8f2qkD59mx29qpnTqqeNozqi5A9YHGI2a1MzBWz8bA6gIewWrF+FNb+CmsWoH1iX0YLa1lA/ROa1PhAPAOeC0FfFgxBplqgxVG6z8YguPltRxx987rUUQhWDoRYUMNVlM+8LSHK4xDnpbbZLzMlk3QP7OnwAKjPt9YQzvfmDAUHHUobg0tFEdXFjTaQwsaiylcSXRjDy26EcHM1ezCztB2YaRwHT/8fJS8t5qK9wH6LgQQvL1tFddu4nZ5y8Qz1bhdF6yjuL6SN0LsqsGKdcGKNXuBjmCVb0/6vhXEo3AC8p6FhW9rgNW1dcEKz+4A1qYUcgl71iK7MP07M8FvTOm8+U/l0d2Om+e1sReNmE0mfwvZol28ljXK915b4sWjNsnzwidmzhHN074n+nGABpION6XMqm1LC041H25KC9xWzIczJnj7Srd11mGjrrBlG6f1ck/2Zx9yDdqto4D3J5eugtYJ3UhUESgMlKmWvOOqMlUuJgAD6WKqc5qpQC+nC6YqBG0dMfUsR3+xvx4Iu4txLmb3rCd2uw3slvVyO2C3CH0+2N0vu7HZErtx0zLRxe7paXYDvaZdsBvmHwNvvwEMH80NnSuj3PcNnfW20w5H9R1Vy0rBM5aRVF23s4ZxdBfLwng8o44x5pJZ+R6r97Xytkjz3a8VcHV15loB47S0xR1RV+uOJZCucABd2TosTnm9la7DxCq+MhuYdt82eNs/2rx7X1jk/C70hWAczXGDDf/L5pSdDp4fyxNj9bhYHhDbvrYTWeOBMEG+2JidyQT5dgwsTt1UUMgXKVPB7IYKw/IJbTHBki4Tihv+rpgAj93faRQ9e/7P7XrEe6i0ABXz4vr2UHj2vgvnc5JNMWTvExb7GjdjN4p1ZC30ZpUWMl9HcRmKI5Mqb9C5/0NsytciXYc3LSR/rsZY8lLDiufytozlKPw6xYexjmSbsFz1pttY6MNYZyd1QGSo2VhuCytrkDVLAyGK1VblhiXX8mjK/gGFG2qMgF5d1Bi5LbgY3TVGYyOg3VHpEFC4oXQI6NVF6ZDbwq8FDbK4YnSs7agkCCjcUBIE9OqiJMht4Ur3g7UdsNbpqNQHKNxQ6gP0uqzUhzXLXz3Mu5e/HYm//A8=</diagram></mxfile>

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-09-27T14:33:01.384Z" agent="5.0 (X11)" etag="LKVXtaolmzFDfvVzfO-V" version="13.7.5" type="device"><diagram id="njiB7J01PMf0DHfhUy9N" name="Page-1">7VpNc+I4EP01HKFs+QN8DJDMbFV2itocduYosLA1MZZXlgPMr18JS1i2bAMJZDJVSYWU1Wq32+rXr1sKA2e22X2hMIv/JiFKBsAKdwNnPgDAdgEYiF8r3JeSMfBLQURxKJUqwRP+haTQktIChyivKTJCEoazunBF0hStWE0GKSXbutqaJPWnZjBChuBpBRNT+i8OWVxKJ2Bcyb8iHMXqybYflDMbqJTlm+QxDMlWEzn3A2dGCWHl1WY3Q4lYPLUu5X0PHbNHxyhK2Tk3gPnd0o9AkFjfvi/v8NfCCYuhMpOzvXpjFPIFkENCWUwiksLkvpJOKSnSEAmzFh9VOo+EZFxoc+FPxNheRhMWjHBRzDaJnOUe0/13cf8oUMMf+tx8J42Xo70+WiCKN4ghKoU5g5TdiVBzQUpSpGQPOEmON4YNDS7R5tckZTOSEHpYAseyfH82E1o7zEo/PTk6usmvKy/FYK8Nmj6asVLrTgq6Qj0BciTmIY0Q69FT+SKipz1BQuELItwduucKFCWQ4Zc6vKHMkuioJ2/lqwb3mkJGcMpyzfJCCLiCTHjfkukt092xG6Bs6LvjXn1+UXqgRtqrVKID0C8AvVzTF5gUchkWMyMNuiDxgijDnB/uEhylfG5JGCMbbeIRLlGyIDlmmAgFJpJimjSkK44EAY8plHaOAi1PSMESnKLZkdsOWOWw1RybHX4OmKfkGWkz/mRiTx0+E1EYYlS9jkwBJZ5jyq2XbqUim4/GFOMBIYlhJpZms4sE049SxLaEPuejDUkxE3a7US6WBu16YSlnPb+OB2BJXG818pWiWONd3+sGsgamy7Fij38LQSreeRPraDTrfQiafT0NejdhN4OOQNCAn8KaMlE6Ku/q4bXArtsZN+yUfG7YuZRueZLX6bPZA/S71VC/DdvaE4NusywjiLviJxwG0yXlV5G4sifByOZg9UbupDXtDtxaTxWDP5sEvcFhWGYlyvEvuDzYE2iUi8uNe9OBN2/FZy8nGLR2bEPlU2qdXhvdDcXLTkAtKNLSG5E8dOpWh00TZL3OERs0+fEKAfeMeD8hytfKiOhnKW2U0rxcp+5+9AoVtkkZduAZFXbcUmGbTHi9CusaeFHMEOIXRQ2IxZYS88doMy3KdgBGtj8Z2WP+MWmmy8771/lrFNVqj6I6hDd2C8f24NW9wuvrvNrGnNzvnNsQSNRbI+C6boMRraswrdux5TnVM1xa653gslrvNP3qK/bV3bevD2p99AKxxWwVGxn4uQc7t3CU63eVAuFMTm/BbKulQjg3qxDgnAqhRAI0NRj5/xVETQzzAxXfcQV7ku2qSWXlG2K/tog+w5C3izkSelJdqyn8RR+Aq5WR8pn91eWGDm9g/qy5CngDrT5Wb/k7x+9GTnIUMQPpEs16WkiRlkniYbIS8sWTY2nY7mvcVXomaM2ug/FjN6OaINvEuOO2YNy9GcZ9A+N/CTJKBQcLvPG/C0pecNjSSP9pdLVKSBG28W4nQ/cTe2c9uGEf7ZxmyaAFQM2DgKsBCDi/o4H9cEdMRsTFz5taUvfMjvSDnMCPvXqbe6pNdPuPkG5zJmRu+R5hJnL5swN8JaUm5fpdhdrG1hnc5r8nt5kNIEozO29pbvQ2DXQ1Lzc6PhT0WLZrB9NXiITXjMTYPKxpqzI3a8WBmbnbJPNORcKsTX9aJHyv+Z+B94sEiuL1+kfB/lmE9164WS+Xu/nQNgLRssU4HLSDs3ck2vn7+LLtQO1M67ydwfnx3saYoacMHsr0lvOe0bl0RLMl5t1bgkZ8A5Pz2jYE4PL48mH1rY+yolbfnXHu/wc=</diagram></mxfile>

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-09-27T14:28:17.128Z" agent="5.0 (X11)" etag="pKZ9F801HblY14u58-0M" version="13.7.5" type="device"><diagram id="njiB7J01PMf0DHfhUy9N" name="Page-1">7VlNc6M4EP01HOMC8WH7aONk55CdSlUOO3uUjQyaCMQKEdv59SuBBAJsEqfwzG5VXHEVemo1Teu1Xgdbbpge/2AwT/6kESIWsKOj5W4sABwPAEv+2dGpRuYgqIGY4UgZtcAzfkMKtBVa4ggVHUNOKeE474I7mmVoxzsYZIweumZ7Srp3zWGMBsDzDpIh+heOeFKjCzBv8W8Ix4m+sxMs65kUamP1JEUCI3owIPfeckNGKa+v0mOIiEyezku97uHCbBMYQxn/yAKwWW2DGCyJ/f3HdoW/lW5U3mk3BT/pJ0aRSIAaUsYTGtMMkvsWXTNaZhGSbm0xam0eKc0F6AjwJ+L8pHYTlpwKKOEpUbMiYnb6IdfPlnr4tzm3OSrn9ehkjp4QwyniiCmw4JDxldxqAWQ0Qxp7wIQ0C6OehUCM+T3NeEgJZVUKXNsOgjCUVkfM6zh9NWrCFNdtlHJwMgb9GOsky8xe3Dy9EbRkOzSyY64qAshixEfsnJZjojgRFeGwk1jIEIEcv3YDgapK4sZOLRVZgyfDIKc444Xh+UkCwkAVvO8ptqtyd50eKXv2njNqLy7qCPTIeJQWqoh+BelVCl8hKVUansJBGVyixCtiHIvzYUVwnIm5LeWcpsbEI9wi8kQLzDGVBlwWxZr00J3YeEmPNVR+GsCoE1pygjMUNmdbxVVBWyOwsPpUnGf0BRkzwWLhrF0xEzMYYdQ+jioBDW8wE97rsDJZzY0zfeIBiSQwl6lJj7E86WcZ4gfKXopZSjPMpV/FcpkHdBzn+ZCWmj92lw9Ajw/G4augxDh3A/8ykQ0yXc8Vf8CVZ8TEIw748sWLHi+KOk+XD9cJ6OLMu3Rxlv6ALvMzdNEUmpwujjfgiwUCIm67jvCruIzlJeKJrWFxG2PmjLGzBDMnWMycufjq+S3rr+j7+fWqPoUQt4KrRfZzgtt0GE1L8en+YkLt1mL3rnj7o6y3Z8DzvA7x73SXeZ28D/TYvaDfjYv6GdWqtliu7RNct3effvPaswf9uMBIn9Cu1uHQ/b5A3OpX9wS9hM6PKRAHzHfJV0PxaeGo8zeJQGiejPUTjn1GIdybKQT4iEJoSJKmQ6Pgn5LqibuiOopXwsBZ5Md2Unv5jvjbAbEXGDFUFEjaKXNDU8SDPgDPkJH6nuPqcsOAU1i8GKEC35/prz0qfx+Ju1eTglh8wHTFZrMsFGRUkryZUkKRPDVWjp0zVZ3iKKpkVpcnQXs+DcebbkY3Qc6Q4825bnLcuxXHgfs7+g/jrYL/33yrID/TdhTeBxuK3/M2QAjGVSrvzq9Q+akUfNixP8JcauyXgH9SwEmdv0kOt8B7X8CXwfBsm9/sbBvqN8pypzijTabKgkvaY2zuYOMvioiQc/wGt5UryQBViMKvv7b8jfQljsdabSvXE+yE19+J+fB/7eWv7KTAsHIPJPff24mhNv3fdsJf9nZicbOdEMP2F4r6xG1/53Hv/wU=</diagram></mxfile>

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-08T13:50:31.826Z" agent="5.0 (X11)" etag="UwTo-BhQn7eYwiBEDnTg" version="13.9.2" type="device"><diagram id="s1RfbO-vQOXVO2XHRdqD" name="Page-1">7Vzfk6I4EP5rfNwrIID6uDOzO3dXN1V7Nb/u7g0hKjcIFuKo99dfkKCQVoluQjQ6uw+kCbHz9ZdOpxPooPvJ8jH1puOnJMBRxzKCZQc9dCzLtC2rk/83glUh6VpuIRilYUArbQXP4X+YCg0qnYcBntUqZkkSZeG0LvSTOMZ+VpN5aZos6tWGSVT/1ak3wkDw7HsRlL6HQTYupD2ru5X/isPRuPxl0+0XdyZeWZn2ZDb2gmRREaFvHXSfJklWXE2W9zjKwStxKZ77vufuRrEUxxnPA1/Mf1/Mp99/+Ggc/7l6e3mcBa9faCufXjSnHabKZqsSgTSZxwHOGzE66G4xDjP8PPX8/O6C2JzIxtkkIiWTXA7DKLpPoiRdP4sCB/cCm8hnWZp84MqdnjVArkvuwG6UOuE0w8uKiHbrEScTnKUrUqW8a1CIKccsl5YXW4vZVDSuGqsUepQko03TWxzJBYXyCFitZlhxHHzN+UlKfuTNZqFfR3IvLjioMRaiUum1s6PXpSzFkZeFn3We70KC/sKPJCSabEDv1TG3WSxnyTz1MX2oSsvD7ZgW007mpSOcgXbWZtl0+nRLIf0tZTOWMk60VJc1OduQZFPZwFSPd8BYxGVkdfPUXU+cxJjxU1TkReEozm1MzIiJ/C53QCGZCb7SG5MwCPKf2ekD615SgFNDe8ZFg09jh48wl+ZKnik83Bv6u2YK1+/hwVDQTOHWUUU9xaj25KI6dPJ/O1Fd/+VPJHFWkRd/YtDewHYuaPd14DBAlTPakYaqKTmIVEzi3mlwS4stTY7g8gJYzMLKOb/JgxWGFxqxGNmnwd2TBrcW8QSA1VDsiy2O9cz5L+htZkFv8k5x8hb0jg50tdnwt8+ZKJEGa1dnp+uwkZpyuLUIgAGsXcVOF0mOyBSzmI3UOOFG0uCWPce1w+IT1xXSnAPSOgB22UjNcbjgth1ZcGsRUQBYLT5Y5TkHjoiiKaG/hT0v4WWY/ZWb4JeuQ4t/V249LKl51oVVWYhJZ4qnLKcsbx7LC9vn1qXywb02KZLrB3pOO34mmw4mk7+2WYvz7jqYjJ90OHcdiIW9VaXaNK8wO0JhxzisV/dgfXJRaCB2t4ojX3wku4UT9VwI2BdEQHYnBjQkioCswg0EBHq1QkCOFcSNgIV9HFEEbGKyIAIChZsIeJiwcghYBhM3AjYSEJmCCIiamCyIgEDhBgICvVohIMdi/0bAOk9+loA2G2tJIiBQuIGAQK9WCCjgyNK1EFBUDOi0FAMChRsICPRqhYAciaIbAYtmRMWATksxIFC4iYBKYkCO1NmNgOsarqgY0G0pBgQKNxAQ6NUKAeHhhcBbzQAJtTmM2mVRLq2kasvNPi7NS1G9oEPbTGSJWCR5x22/oR3ZZ7ZhwjKnjqHzyW12e1r5WDkuZ3fxYwWcAjpxrIB2BE1xe9SVOmOVSFc4YF3ZONzky1WNQweek0ZXZgPTUW2D45InF+8LNycnf9IXgnYkxw2OgBzDdlFXXdFt13CiN+DLs7dnwgR2O6d/IhPYfUYwOGVTQcBqf0MFsx0qnJdPEMUEm1mbb45AtMUEuOx+S6Jo4Pkf86nGcygzAFUfd3Xg2vu3+CPFkxyuKMIk9DXudLeJvWcoKDOKgJNBe3E5Fz/GvL5gnfomO3vUBrUd3Qg4RXM1xmKHGuJclosylsvxeuvNWHvOBCH2uLpsY1k3Y518rgcEhuKM5X7O/jD+eXhHb4vB6zzF6Sse7Pj40Pc0BOY6p5gBBAg7eLI3ZmA/U9TmJspO/OFYeUpijfF3zwx/mIt6IRfa4s8mA5XjD3NM76S/+uLPfr9JNf4wsfMynqf6GoD9WoByA8B8itYTMPtZAeX4w0SK1hMw+/kB5fjDnInWEzD74rxy/GEaROsJmH3lWzn+5e9fzQzMvq6s3gICkktCj7IyOQ4ucC/tjeKW3iZR/EYxKW4/Ll1U336iG337Hw==</diagram></mxfile>

1
draw/overlayfs.drawio Normal file
View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-01T10:54:19.725Z" agent="5.0 (X11)" etag="vngRYxWJjwUmDCPF0SRJ" version="13.8.8" type="device"><diagram id="gjxS07TwHvcXm2kWn2jG" name="Page-1">7Zpdb9sgFIZ/TaT1YpMNtoMv87VMaiZtqtZuVxMxxHZLTEbIV3/9cIzjOKZNJsXO1FTtBRzgYN6Hg8lJWrA3XQ8FnkVfOaGsBSyybsF+CwDbAaCV/ltkk1nawMsMoYiJ7lQY7uJnqo2Wti5iQueljpJzJuNZ2RjwJKGBLNmwEHxV7jbhrDzrDIe0YrgLMKtaH2Iio8yKQLuwf6FxGOUz256ftUxx3lmvZB5hwld7JjhowZ7gXGal6bpHWSperks27vMLrbsHEzSRpwyw+o/DWyB7bu/3aOX8uR093d5/tDWeJWYLvWL9tHKTSyD4IiE09WK1YHcVxZLezXCQtq4UdGWL5JSpmq2Kk5ixHmdcbMfCMQ4Qgco+l4I/0b0WAB3HVU671XXopS2pkHS9Z9LrGlI+pVJsVBfdCi2tsd5kdlvXVwUy29G2aA8XdDQtrLdJuPNdKKkKWsx/ENZ/C7o6qKyrc6Ksu3Fnl9U2yOoxNW2XxEtVDNMiwxsqVK8Pgt/kzWORt+YWNf/eGIMbiJIJgsTkwXrJyRkRE0zRJDAh9gJEx5MzIfYPQsf2q4yBgbFXF2LTiVQbYt91HpPllSFuXxoxbBAx8JOJDy9G2KWIOCbCCIyh59VDGHqGg7pRwk6DhC3HSQi6MsQOuDRi9z2Iz0oY2gdB7F76mPbeg7hexM7FL1vtCuIVF0/zrWwp09XNWWWeoIAGxgvPGLmOa9VzVl78bYjeosqHm/ny18r8gfZ0xrMZiwMsY55UJFbrlGUdy3olPKEH4moTZnGYqGqg1FOHH+ymqqlpWEc3TGNC0mmM4Mpo67gb+CdueFAbCbuiNiUhvdNVLmTEQ55gNiisB7oUfUaczzSgRyrlRicJ8ULyMj66juXPdPgnV9d+7bX019rztrI5Jv+cL0RAX1mj3u0Si5DK4/3S9b8KU1Cm9umynHc8P5nqZ6+riJHKqxedeFrVFyOmC/Rh0CSkkyaxC1krJPKsNDCd9+1O+veagke35Z4+rkGe3Hby7tUzfOOxepIdHtAu49mlGnMXWTjqUYXyFUceOuIoi9eKoy3C3bJPohourB/jwX0yWjwn4+HD6Ht/2mk0QYlQEPrRf39lrgSpYSOeHLfAb/CWYSQMGiQMySQE+MoIw0sTbjI9eQ0xXElPWg1+IDMSbjI9eQ0xfEjY+E3hmQiravGlefbaLn56AAd/AQ==</diagram></mxfile>

1
draw/vollbackups.drawio Normal file
View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-11-08T13:49:10.728Z" agent="5.0 (X11)" etag="wgJMpjDe5lUiW8eBPVa6" version="13.9.2" type="device"><diagram id="s1RfbO-vQOXVO2XHRdqD" name="Page-1">5Vpbc6IwFP41PnZGCKA+tm7rzu447faynX1kSSppI3FCrLq/fkMJCImuqYUF6YwPcBIO5PtOTs7FHhjP1xPmL8IphYj07D5c98CXnm1bjm33kl8fblLJwPZSwYxhKCdtBXf4D5LCvpQuMURxaSKnlHC8KAsDGkUo4CWZzxhdlac9UVJ+68KfIU1wF/hElz5iyMNUOrQHW/lXhGdh9mbLG6Ujcz+bLFcShz6kq4IIXPbAmFHK06v5eoxIAl6GS/rc1Z7R/MMYirjJA2fW8701/XYTgDD6sfl5P4nhw5nU8uqTpVyw/Fi+yRBgdBlBlCjp98DFKsQc3S38IBldCc6FLORzIu4scfmECRlTQtnbswC6aAgdIY85oy+oMDK0fwPPEyP6MrJvQoyjdUEklzVBdI4424gp2WhfQixtzPbk/WrLmCNFYZGsTOhLI5nlqrc4igsJ5TtgtQ/DiiJ4ntinuAuIH8c4KCO5FxcESxaro1JYtbtj1ZmMIeJz/Fq2811IyDfcUCy+JAd9WMbcUbGM6ZIFSD5UNMt/67FsRQ/32QxxTc8bLfmij2cKdJ8pR2GqfyRTA5VyVVHNVDkaVZMLjSzhMniZnrLriWiEFD8lRT7BsyjhWNCIhPwicUBYnATncmCOIUxes9MHlr1kBU4N7NkXB3yaun0qc2nWQIP/iuHu4q8eKo7VNAFDjYApjTpMgNc2AkYaAffiorME5Ei2hYBMcYGAR7Hg7hKgHriNE6CnC/fhknWXAaDGTo0zYBCvtj9hc5Sz1XINYXXrwtXxNFyhv4m7a9kDt2WW7ejxpYZ+IROTqJ5QGjYoAw5UJE3TsNEBPXVnYXoYmphOv8u5mBIIgcb3ih6Jdnqv2McWl0YH9OzZKwI4f1OYtkgmxO/+3C3FqcJK92GGdMEG7E+2D/MaSVP70NXjYfDJODAO3Wrj4H0V3JP3hXlZ5IO+UNNTXdxwTaavzvjleoxu6S/yMH9+uv1uUmj/L4mLZuk7uDeuSeWmfqjTpIJ9jPnvhFUvip8grJpjNyx2W8O6YHU7AavaWxsa+uoqnPVOWA1yvPbDqhaFLMN2sxZ9VgarnpKdIKyO4lstQ99q1+ZbDbKs9sPqqgGbaSOxNt+aZc8njqvqXE2LAqPacG3Ln3k+hKuneFfDM0srg1UHq63B2vbG98f8cION790E6KlD2xvflR6EzROgJxltb3xXemQ2T4CejrS98V3p2do8AXp7sPWN70pP4RoZELfbP0Gn1abtX8nB5V8=</diagram></mxfile>

View File

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-09-27T15:06:43.732Z" agent="5.0 (X11)" etag="aVSUEErxaXeUi47Vbqjs" version="13.7.5" type="device"><diagram id="njiB7J01PMf0DHfhUy9N" name="Page-1">7VzLcuMoFP0aL+MS6L1MnKR7qnq6UpPFdC9lC9uayEIj4djurx+wwEaAZCWW8ph2KklZF4QQ93DugUsysier7Zciypd/4hilI2jF25F9O4IQOBCO2LcV7yqLD73KsCiSmFc6Gh6TX4gbLW5dJzEqaxUJxilJ8rpxhrMMzUjNFhUF3tSrzXFaf2oeLZBmeJxFqW79O4nJsrIG0D/av6JksRRPBl5YlawiUZm/SbmMYryRTPbdyJ4UGJPq02o7QSkbPDEu1X33DaWHjhUoI11ugLfXU28Bw9T6/mN6nXxd2/H6SjRTkp14YxTTAeCXuCBLvMBZlN4drTcFXmcxYs1a9OpY5xvGOTUCavwHEbLj3ozWBFPTkqxSXkp7XOx+sPvHobj8KZfdbnnj1dVOvnpARbJCBBXcWJKoINfM1dSQ4QwJ232SpocbY6UGtUjlc5yRCU5xsR8C27I8bzJhtbYJqfrp8qtDN+nnYy/ZxU66UPuo+0qMO14XM9TiIJtjPioWiLTUE/OFeU96AofCF4Rpd4odrVCgNCLJcx3eEZ8li0M9fisdtWgnVchxkpFSavmBGWgFPuE9i09vPt1toIBSqe/4rfXph6oH4kp6laNpD/QXgJ6P6XOUrvkwPEy0adAEiWdUkITyw3WaLDJaNsWE4JVU8C2aovQBlwlJMKtA2KS4SRXrjCKBweMm4u0cDNI8wWuSJhmaHLhtj1UKW6ljk/3XHvMFfkJSiRcE4MamJYsiihN0fB0+BYT5Nilo61W3MjabD40JxoPMsoxyNjSr7YIx/ThDZIOLp3K8wllCWLvNKGdDg7atsOSlrlfHA7Q4rjcS+XLTUuJdz20GsgSml2MF+O9CkIJ3zmIdiWbdD0Gzr6dBdxB20+gIhgr8BNZEE1VH+V0tvBaCeju+0k7F51o7L6VbOsnr9KlqgPZuKdWHYVsQaHSb5zlGtCteSmFwMy3opwX7BIJwDChY3bETGKfdnlvrU0XjT5WgV0kcV7MSlcmvaLpvj6GRDy5t3L0ZubdGfLZygkZrBxnKn1JTeia6u2IvG8CaU3hLZyL5yq63eqU2gefzEpGRyo89ONzV/P2ICjpWmkcvoVQJpWU1Ts16tIcIq1IGCF0twvqGCKsyYX8R1tHwIpghTp4FNSCytISZPkYqMVQGIRwDLxgDn/7oNNPUztvH+T6C6nGNIhTCmWrhIA9erRVeH+fFMubkeqerIOCot8bQcRyFEa1emNZpWPKc0gwvjfV2+LJYb6v9agv2x7uHjw9ifOQAsUnIbKnNwMsarGvgqMavlwBhB6eXYMAyRAh7sAgBu0QIYWKgqcHI+3eNRcFVuafia1oBBPn2WCha+Y7Irw0qnqKYysUSsXq8uhRT6IveQ0cKI9Uz26PLgB1eReWT1FVIBbT4sVrDX5d+K3OSoohoSOdolqcFN0kziT2MR0I6ePyaNwzahLuYnimak34wflAzQgQBHeO2Y8C4MxjGPQ3jfzAyyhgHM7zR3w8Ffk5ig5D+bHQ1S/E6NvFuI0O3E3tjPBhQR9unWTI0AEjdCOgNQNB+DwH74baYNI+zr7MkqdNRkX6QHXjfrcvcUzLRad9CGmZPSF/yfYtyNpcvCvCVlJpW49cLtflWB27z3pLbdAGIshyUBnEjyzTYJF4G2j5k9FjJtX3TPXjCVT3h65s1pigzmBSH+szdpLl7yhN6bPpsnvBcNTPwdp5Ai+V8/nNN/nqI79x4NZ9Ot7dXQHOEYYmx32iHnVck0v67/7LlQG1Pq9vKoLu/N8uEoMc82ofpDeU9Tbk0eNPg8+YlgeLfUOc804IADuXf98k7/p4HMxTJZqQKWf+ZJ+Q7Hbio53k8y22Xe35r/aZdwYanua6Sd2/Y63yFbjSPsTkt+Emy8V2S412gKC9ZjMMU6pBtWbL0nkV3QH13Rds16S37rWD5xFIHQOus+rZ7YikFWuufvZRq8/Ul2zpUtvU8VaFA1Al0WTFUttXMoHryxZxtBd1V40Hoh5dsa/do0HO2tZfAAbqKnbAV9YNmW1X9MlS2VXkOaNdVttov0ElX9ZptbXXpJds6VLb1rABhB2qA0PcVBsu2mgGjb5tdEgnHRMLbrzxPs7bfkbXfZ4nqu3VZLBaNTVSq1j9FvY66DOhGvU2987oFlN742bij6rfvqIYfY2/7LOZzraA+8G+4t232hH5wlXrCLoN2T3yIve2zPOG5H80T+mGIV6uV+gkBVaoctMz/V62s8DTZQ6uPOdtBrZh2yfvIDLaGvgtSekDK/s8WSD9I8a3TSDHq2uGgou+UyYfKzYlLpwO5f9KEF/AU4dNxLg+W8YL6SvUNj3lC9Zhn+GGPecLf6JjnebuvyjFPx3CQpa9jnvTy+Lf81eLg+B8R7Lv/AA==</diagram></mxfile>

246
examples/examples.tex Normal file
View File

@ -0,0 +1,246 @@
\section{Übung}
\label{sec:uebung_01}
% ##########################################################################
% ############################### Aufgabe 01 ###############################
% ##########################################################################
\subsection{Aufgabe}
\label{sec:uebung_01.aufgabe_01}
Starten Sie das Skript.
\subsubsection*{Lösung}
\label{sec:uebung_01.aufgabe_01.loesung}
% ##########################################################################
% ################################# Minted #################################
% ##########################################################################
\section{Minted}
% ############################### Begin-Block ##############################
\subsection{Begin-Block}
\subsubsection{AWK-Code}
\begin{awkcode}
if NR > 3 {
print "0";
}
\end{awkcode}
\subsubsection{JSON}
\begin{jsoncode}
{
"name": "Molecule Man",
"age": 29,
"secretIdentity": "Dan Jukes",
"powers": [
"Radiation resistance",
"Turning tiny",
"Radiation blast"
]
}
\end{jsoncode}
\subsubsection{R-Code}
\begin{rcode}
print(match(5, c(2,7,5,3))) # 5 is in 3rd place
print(seq(from=1,to=3,by=.5) %in% 1:3)
\end{rcode}
\subsubsection{SQL-Code}
\begin{sqlcode}
SELECT *
FROM tab;
\end{sqlcode}
\subsubsection{XML}
\begin{xmlcode}
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
\end{xmlcode}
% ################################ Input-File ###############################
\subsection{Inputfile}
\subsubsection{AWK-Code}
\inputsql{examples/test.awk}
\subsubsection{JSON}
\inputsql{examples/test.json}
\subsubsection{R-Code}
\inputsql{examples/test.r}
\subsubsection{SQL-Code}
\inputsql{examples/test.sql}
\subsubsection{XML}
\inputsql{examples/test.xml}
% ################################## Inline #################################
\subsection{Inline}
\subsubsection{SQL-Code}
\sqlinline{SELECT * FROM tab;}
% ##########################################################################
% ################################ Info-Boxen ##############################
% ##########################################################################
\section{Info-Boxen}
% ################################### WARN #################################
\begin{warn-popup}
Warn-Popup
\end{warn-popup}
% ################################### INFO #################################
\begin{info-popup}
Info-Popup
\end{info-popup}
% ################################# Example ################################
\begin{example-popup}
Example-Popup
\end{example-popup}
% ##########################################################################
% ################################# Akronyme ###############################
% ##########################################################################
\section{Akronyme}
\acrfull{acr:sql}\\
\acrlong{acr:sql}\\
\acrshort{acr:sql}\\
% ##########################################################################
% ################################ Text-Boxen ##############################
% ##########################################################################
\section{Text-Boxen}
\begin{textblock*}{\textwidth}(4cm,0cm)
Ich bin eine Textbox
\end{textblock*}
% ##########################################################################
% ############################### Aufzählungen #############################
% ##########################################################################
\section{Aufzählungen}
\begin{itemize}[itemsep=0pt]
\item Item
\item Item
\item Item
\end{itemize}
\begin{enumerate}[itemsep=0pt]
\item Item
\item Item
\item Item
\end{enumerate}
\begin{itemize}[itemsep=0pt]
\item[A)] Item
\item[B)] Item
\item[C)] Item
\end{itemize}
\begin{description}[itemsep=0pt]
\item[Itempoint 1] \mbox{} \\
\lipsum[1]
\bigskip
\item[Itempoint 2] \mbox{} \\
\lipsum[1]
\bigskip
\item[Itempoint 3] \mbox{} \\
\lipsum[1]
\end{description}
% ##########################################################################
% ################################# Tabellen ###############################
% ##########################################################################
\section{Tabellen}
% ################################# tabularx ###############################
\begin{table}[H]
\begin{tabularx}{\textwidth}{X|X|X|X}
\textbf{FIRSTNAME} & \textbf{LASTNAME} & \textbf{BIRTHDAY} & \textbf{HIREDATE} \\
\hline\hline
Maximilian & Arbeitsscheu & 1998-06-21 & 2007-04-18 \\
Henry & Großkreutz & 1990-09-01 & 2009-02-10 \\
Leni & Mayer & 1996-10-15 & 2009-02-10 \\
$[$\dots$]$ & $[$\dots$]$ & $[$\dots$]$ & $[$\dots$]$ \\
\end{tabularx}
\caption{tabularx - beispiel\_01}
\label{tbl:beispiel_01}
\end{table}
% ########################## tabularx - multicolumn ########################
\begin{table}[H]
\begin{tabularx}{\textwidth}{X|X|X|X}
\textbf{FIRSTNAME} & \textbf{LASTNAME} & \textbf{BIRTHDAY} & \textbf{HIREDATE} \\
\hline\hline
\multicolumn{2}{c|}{\textbf{Multi-column}} & 1998-06-21 & 2007-04-18 \\
Henry & Großkreutz & \multicolumn{2}{c}{\textbf{Multi-column}} \\
\multicolumn{3}{c|}{\textbf{Multi-column}} & 2009-02-10 \\
$[$\dots$]$ & $[$\dots$]$ & $[$\dots$]$ & $[$\dots$]$ \\
\end{tabularx}
\caption{tabularx - beispiel\_02}
\label{tbl:beispiel_02}
\end{table}
% ############################ tabularx - multirow #########################
\begin{table}[H]
\ttfamily
\begin{tabularx}{\textwidth}{X|X|X|X}
\textbf{FIRSTNAME} & \textbf{LASTNAME} & \textbf{BIRTHDAY} & \textbf{HIREDATE} \\
\hline\hline
\multirow{2}{*}{\textbf{Multi-row}} & Arbeitsscheu & 1998-06-21 & 2007-04-18 \\
& Großkreutz & 1990-09-01 & 2009-02-10 \\
Leni & Mayer & 1996-10-15 & \multirow{2}{*}{\textbf{Multi-row}} \\
$[$\dots$]$ & $[$\dots$]$ & $[$\dots$]$ & \\
\hline
\end{tabularx}
\caption{tabularx - beispiel\_03}
\label{tbl:beispiel_03}
\end{table}
% ################################## tabular ###############################
\begin{table}[H]
\ttfamily
\begin{tabular}{l|l|l|l}
\cellcolor{light-grey} \textbf{FIRSTNAME} & \textbf{LASTNAME} & \textbf{BIRTHDAY} & \cellcolor{grey} \textbf{HIREDATE} \\
\hline\hline
Maximilian & Arbeitsscheu & \cellcolor{orange}1998-06-21 & 2007-04-18 \\
Henry & \cellcolor{red} Großkreutz & 1990-09-01 & 2009-02-10 \\
\cellcolor{green} Leni & Mayer & 1996-10-15 & \cellcolor{blue} 2009-02-10 \\
$[$\dots$]$ & \cellcolor{yellow} $[$\dots$]$ & \cellcolor{brown} $[$\dots$]$ & $[$\dots$]$ \\
\end{tabular}
\caption{tabular - beispiel\_04}
\label{tbl:beispiel_04}
\end{table}
% ################################## tabular 2 ###############################
\begin{table}[H]
\begin{tabular}{llll}
\toprule[2pt]
\cellcolor{light-grey} \textbf{FIRSTNAME} & \textbf{LASTNAME} & \textbf{BIRTHDAY} & \cellcolor{grey} \textbf{HIREDATE} \\ \midrule[1.5pt]
Maximilian & Arbeitsscheu & \cellcolor{orange}1998-06-21 & 2007-04-18 \\ \midrule
Henry & \cellcolor{red} Großkreutz & 1990-09-01 & 2009-02-10 \\ \midrule
\cellcolor{green} Leni & Mayer & 1996-10-15 & \cellcolor{blue} 2009-02-10 \\ \midrule
$[$\dots$]$ & \cellcolor{yellow} $[$\dots$]$ & \cellcolor{brown} $[$\dots$]$ & $[$\dots$]$ \\
\bottomrule
\end{tabular}
\caption{tabular - beispiel\_05}
\label{tbl:beispiel_05}
\end{table}

11
examples/test.awk Normal file
View File

@ -0,0 +1,11 @@
BEGIN {
print "HELLO;WORLD;";
}
{
print $0;
}
END {
print "END";
}

22
examples/test.json Normal file
View File

@ -0,0 +1,22 @@
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}

0
examples/test.r Normal file
View File

3
examples/test.sql Normal file
View File

@ -0,0 +1,3 @@
CREATE OR REPLACE VIEW "EMPLOYEES" AS
SELECT *
FROM dwh.employees;

20
examples/test.xml Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE glossary PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
<glossary>
<title>example glossary</title>
<GlossDiv>
<title>S</title>
<GlossList>
<GlossEntry ID="SGML" SortAs="SGML">
<GlossTerm>Standard Generalized Markup Language</GlossTerm>
<Acronym>SGML</Acronym>
<Abbrev>ISO 8879:1986</Abbrev>
<GlossDef>
<para>A meta-markup language, used to create markup languages such as DocBook.</para>
<GlossSeeAlso OtherTerm="GML">
<GlossSeeAlso OtherTerm="XML">
</GlossDef>
<GlossSee OtherTerm="markup">
</GlossEntry>
</GlossList>
</GlossDiv>
</glossary>

15
git-info.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
if [ $1 == "date" ]; then
git log -1 --pretty=format:"%ad" --date=short
elif [ $1 == "commit" ]; then
GV=$(git rev-parse --short HEAD)-git
echo ${VERSION:-$GV}
elif [ $1 == "url" ]; then
URL=$(git config --get remote.origin.url | sed -e 's#^git@#https://#' -e 's#systems:#systems/#' -e 's#_#\\_#g' -e 's#.git$##' )
if [ -z "$URL" ]; then
echo "https://git.cryptic.systems"
else
echo $URL
fi
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
img/btfs_subvol_snaps.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
img/btrfs-cow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
img/einfache-netze.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
img/inkrementell-backup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
img/overlayfs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
img/vollbackups.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

442
index.tex Normal file
View File

@ -0,0 +1,442 @@
% Dokumentanklasse: a4paper, 14pt
% Beschreibung: Dokumentenformat
% Option: extraarticle - ?
\documentclass[12pt]{article}
% Packet: xcolor
% Beschreibung: Define own color schemas
% Option:
% Restriktion: Muss vor Paket hyperref geladen werden. Ansonsten werden die Farben der Links nicht genutzt.
\usepackage{xcolor}
% Definiere Farben
\definecolor{blue}{HTML}{5E7FB8}
\definecolor{brown}{HTML}{BA9D5E}
\definecolor{green}{HTML}{79B960}
\definecolor{grey}{HTML}{7C7C7C}
\definecolor{light-grey}{HTML}{D5D5D5}
\definecolor{orange}{HTML}{FF7F00}
\definecolor{red}{HTML}{B80A0A}
\definecolor{violet}{HTML}{B688CB}
\definecolor{white}{HTML}{FFFFFF}
\definecolor{yellow}{HTML}{E2E66C}
% Paket: setspace
% Beschreibung: Setz über die optionen den Zeilenabstand
% Optionen: Möglicher Zeilenabstand
% singlespacing = 1,0
% onehalfspacing = 1,5
% doublespacing = 2,0
% Restriktion: Muss vor Paket hyperref geladen werden. Ansonsten funktioniert das Paket nicht.
\usepackage[onehalfspacing]{setspace}
% ###########################################################################################################################
% Paket: appendix
% Beschreibung: Das Paket dient dazu, ausschließlich das Thema einer Überschrift in das Inhaltsverzeichnis zu überführen
% Option: appendix - Überführt die Überschriften des Anhangs richtig ins das Inhaltsverzeichnis
\usepackage[titletoc]{appendix}
% Paket: ansmath
% Beschreibung: Zum darstellen von mathematischen Formeln
\usepackage{amsmath}
% Paket: bebel
% Beschreibung: Stellt das Literatur-, Abbilungs-, Tabellenverzeichnis auf eine beliebige Sprache
% Option: ngerman
\usepackage[ngerman]{babel}
% Paket: biblatex
% Beschreibung: Ermöglicht es, ein Literaturverzeichnis zu führen
% Option:
\usepackage[
style=authoryear-icomp, % Zitierstil (https://de.overleaf.com/learn/latex/Biblatex_bibliography_styles)
isbn=false, % ISBN nicht anzeigen, gleiches geht mit nahezu allen anderen Feldern
pagetracker=true, % ebd. bei wiederholten Angaben (false=ausgeschaltet, page=Seite, spread=Doppelseite, true=automatisch)
maxbibnames=50, % maximale Namen, die im Literaturverzeichnis angezeigt werden
maxcitenames=3, % maximale Namen, die im Text angezeigt werden, ab 4 wird u.a. nach den ersten Autor angezeigt
autocite=inline, % regelt Aussehen für \autocite (inline=\parancite)
block=space, % kleiner horizontaler Platz zwischen den Feldern
backref=true, % Seiten anzeigen, auf denen die Referenz vorkommt
backend=biber,
backrefstyle=three+, % fasst Seiten zusammen, z.B. S. 2f, 6ff, 7-10
date=short, % Datumsformatbackend=biber
]{biblatex}
\setlength{\bibitemsep}{1em} % Abstand zwischen den Literaturangaben
\setlength{\bibhang}{2em} % Einzug nach jeweils erster Zeile
\addbibresource{referenzen//bibliothek.bib}
% Paket: caption
% Beschreibung: Bietet eine große Auswahl an Gestaltungsmöglichkeiten bezüglich der Beschriftung von Bildern und Tabellen.
\usepackage{caption}
% Paket: colortbl
% Beschreibung: Ermöglicht Tabellen, Spalten oder Zellen farbig zu gestalten.
% Befehle: \columncolor
% Dokumentation: http://texdoc.net/texmf-dist/doc/latex/colortbl/colortbl.pdf
\usepackage{colortbl}
% Paket: booktabs
% Beschreibung: Das Hauptaugenmerk von booktabs liegt dabei auf der Gestaltung der horizontalen Linien innerhalb einer Tabelle.
% Was unter anderem daran liegt, dass der Autor des Paketes Simon Fear mehrere Regeln bzw. Empfehlungen für die
% Erstellung/Gestaltung einer Tabelle gibt. Aufgrund der ersten zwei Regeln:
% 1) Verwende nie und nimmer vertikale Linien.
% 2) Verwende keine doppelten Linien.
% Dokumentation: https://www.namsu.de/Extra/pakete/Booktabs.html
\usepackage{booktabs}
% Paket: courier
% Beschreibung: Lädt das Paket courier für Schriftarten mit fester Breite.
% Befehle: \ttfamily Aktiviert Courier füt Tabellen bzw. generelle begin-Blöcke
\usepackage{courier}
% Packet: csquotes
% Beschreibung: Muss nach babel, polyglossia, biblatex und inputec geladen werden
% Options:
% autostyle=true - Diese Anweisung passt das Zitatdesign so an, dass es zur momentan im Dokument verwendeten Sprache passt
% autostyle=once - Ändert das Zitatdesign einmalig, sodass es zur Grundsprache des Dokumentes passt.
% autostyle=try - Verhalten sich, sollte multilinguale Unterstützung vorhanden sein, wie true und once, doch werden sie,
% für den Fall, dass dies nicht möglich wäre, keine Warnungen erzeugen. (D. h. falls weder babel noch
% polyglossia geladen wurden). Die Kurzformautostyleist äquivalent zu autostyle=true
% Dokumentation: http://mirrors.ibiblio.org/CTAN/info/translations/csquotes/de/csquotes-DE.pdf
\usepackage[autostyle=true]{csquotes}
% Paket: enumitem
% Beschreibung: Zeilenabstände bei Aufzählungen definieren
% Option:
\usepackage{enumitem}
% Paket: eurosym
% Beschreibung: Bildet das Euro-Zeichen in unterschiedlichen Varianten ab
% Option:
\usepackage{eurosym}
% Paket: fancyhdr
% Beschreibung: Ermöglich ein generelles Seitenlayout ein zu stellen mit Kopf und Fußzeile.
\usepackage{fancyhdr}
% Paket: float
% Beschreibung: Zum Ausrichten von Tabellen und Spalten bzw. deren Zentrierung
% Option:
% Restriktion: Muss von Paket hyperref geladen werden. Ansonsten funktioniert das Paket nicht.
\usepackage{float}
\usepackage{forest}
% Packet: framemethod
% Beschreibung:
% Option:
\usepackage[framemethod=tikz]{mdframed}
\mdtheorem[
linecolor=red,
frametitlefont=\sffamily\bfseries\color{white},
frametitlebackgroundcolor=red,
]{warn-popup}{Warnung}[subsection]
\mdtheorem[
linecolor=orange,
frametitlefont=\sffamily\bfseries\color{white},
frametitlebackgroundcolor=orange,
]{info-popup}{Information}[subsection]
\mdtheorem[
linecolor=green,
frametitlefont=\sffamily\bfseries\color{white},
frametitlebackgroundcolor=green,
]{example-popup}{Beispiel}
% Paket: footmisc
% Beschreibung: Das footmisc Paket liefert viele Möglichkeiten, wie Fußnoten in Dokumenten dargestellt werden können.
% Option:
% Dokumentation: http://mirror.utexas.edu/ctan/info/translations/footmisc/de/footmiscDE.pdf
\usepackage[bottom]{footmisc}
% Paket: geometry
% Beschreibung: A4 Seitenabstände
% Option:
\usepackage{geometry}
\geometry{
% a4paper, % Papierformat (wird auch über die Dokumentenklasse definiert)
top=2.5cm, % Abstand Kopfseite (Zwischen Kopfseite und Inhalt)
bottom=2cm, % Abstand Fußseite (Zwischen Fußseite und Inhalt)
left=2.5cm, % Abstand Linkeseite (Zwischen Linkerseite und Inhalt)
right=2.5cm, % Abstand Rechteseite (Zwischen Recherseite und Inhalt)
% width= % textwidth (+marginsep +marinparwidth)
% textwidth=15cm, % Textbreite
% marginparsep=1cm, % Randnotiztrennng
% marginparwidth=10cm,% Randnotizbreite
% height= % textheight (+headheight +headsep + footskip)
% textheight= % Texthöhe
headheight=1cm, % Kopfhöhe
headsep=0.5cm, % Kopftrennung (Größe zwischen Kopfzeile und Inhalt)
footskip=1cm, % Fußzeilenhöhe
}
% Paket: graphicx
% Beschreibung: Einbinden von Bildern
% Option:
\usepackage{graphicx}
% Packet: Hyperref
% Beschreibung: Importiert hyperref um Querverweise mittels \hyperref zu erzeugen.
% Dokumentation: https://www.namsu.de/Extra/pakete/Hyperref.html
\usepackage{hyperref}
\hypersetup{
colorlinks=false, % hyperlinks are coloured
citecolor=green, % color for cite links, only visible if colorlinks=true
linkcolor=red, % color for page links, only visible if colorlinks=true
urlcolor=orange, % color for url links, only visible if colorlinks=true
citebordercolor=green, % color for citeborder, only visible if colorlinks=true
urlbordercolor=orange, % color for url links, only visible if colorlinks=true
linkbordercolor=red, % color for page links, only visible if colorlinks=true
pdfborderstyle={/S/U/W 1}, % border style will be underline of width 1pt
pdftitle={PDF-Title},
pdfauthor={Markus Pesch},
pdfsubject={PDF-Subject},
pdfkeywords={},
pdfcreator={pdflatex},
pdfproducer={LaTeX with hyperref}
}
% Paket: glossaries
% Beschreibung: Das Paket glossaries muss nach dem Paket hyperref geladen werden
% Dokumentation: http://ftp.gwdg.de/pub/ctan/macros/latex/contrib/glossaries/glossaries-user.pdf
% Option/en:
% acronyms - This is equivalent to acronym=true and may be used in the document class option list.
% section - This is a key=value option. Its value should be the name of a sectional unit (e.g. chapter).
% This will make the glossaries appear in the named sectional unit, otherwise each glossary will
% appear in a chapter, if chapters exist, otherwise in a section. Unnumbered sectional units will
% be used by default.
% toc - Add the glossaries to the table of contents.
\usepackage[toc,acronyms]{glossaries}
\makeglossaries
\include{referenzen/glossar}
% Paket: utf8
% Beschreibung: Stellt Umlaute richtig dar
% Option: inputenc - Erlaubt die Darstellung der gleichen Zeichen (Character) wie sie in stdin überliefert werden
\usepackage[utf8]{inputenc}
% Paket: lipsum
% Beschreibung:
% Option:
\usepackage{lipsum}
% Paket: makeindex
% Beschreibung: Ermöglicht das Indexieren von Wörter und den Befehl \printindex um den Index auszugeben
\usepackage{makeidx}
\makeindex
% Packet: Minted
% Beschreibung: Dient zum highlining von Quellcode wie beispielsweise Java, Bash oder Python.
% Option/en:
% autogobble: Leerzeichen zwischen linken Rand und Sourcecode einrücken bzw. weg schneiden.
% breaklines: Automatische Zeilenumbrüche
% cache: de- oder aktiviert den cache um Sourcecode zwischen zu speichern und so das PDF schneller zu erzeugen
% cachedir: Definiert den Pfad zum cache, an dem minted seine Daten zwischen speichern kann
% fontfamily: Die Schriftart die benutzt werden soll. tt, courier und helvetica sind vordefiniert.
% fontsize: Die Schriftgröße die benutzt werden soll. Beispielsweise fontsize=\footnotesize
% linenos: Zeilennummern
% keywordcase: Änderung der Buchstaben. Takes lower, upper, or capitalize.
% showspaces: Blendet Leerzeichen ein
\usepackage[cache=true]{minted}
% usemintedstyle
% Gebe 'pygmentize -L styles' im Terminal ein um alle verfügbaren styles anzuzeigen.
\usemintedstyle{tango}
% newminted
% Definiere neue aliase um einmalig ein highlighting pro Sprache zu deklarieren
% \newminted{<makroname>}{optionen} ist verfügbar unter "\<makroname>{code}"
\newminted{awk}{autogobble=true, breaklines=true, linenos=true}
\newminted{bash}{autogobble=true, breaklines=true, linenos=true}
\newminted{json}{autogobble=true, breaklines=true, linenos=true}
\newminted{julia}{autogobble=true, breaklines=true, linenos=true}
\newminted{r}{autogobble=true, breaklines=true, linenos=true}
\newminted{sql}{autogobble=true, breaklines=true, linenos=true, keywordcase=upper}
\newminted{xml}{autogobble=true, breaklines=true, linenos=true}
% newmintedfile
% Definiere neue Makros um automatisch Sourcecode aus Dateien zu highlighten.
% \makroname{Dateipfad}
\newmintedfile[inputawk]{awk}{autogobble=true, breaklines=true, linenos=true}
\newmintedfile[inputbash]{bash}{autogobble=true, breaklines=true, linenos=true}
\newmintedfile[inputjson]{json}{autogobble=true, breaklines=true, linenos=true}
\newmintedfile[inputjulia]{julia}{autogobble=true, breaklines=true, linenos=true}
\newmintedfile[inputr]{r}{autogobble=true, breaklines=true, linenos=true}
\newmintedfile[inputsql]{sql}{autogobble=true, breaklines=true, linenos=true, keywordcase=upper}
\newmintedfile{inputxml}{autogobble=true, breaklines=true, linenos=true}
% newmintinline
% Definiere neues Makro um Sourcecoude einzeiler zu highlighten
% \begin{awkcode} \end{awkcode}
\newmintinline{awk}{autogobble=true, breaklines=true, linenos=true}
\newmintinline{bash}{autogobble=true, breaklines=true, linenos=true}
\newmintinline{json}{autogobble=true, breaklines=true, linenos=true}
\newmintinline{julia}{autogobble=true, breaklines=true, linenos=true}
\newmintinline{r}{autogobble=true, breaklines=true, linenos=true}
\newmintinline{sql}{autogobble=true, breaklines=true, linenos=true, keywordcase=upper}
\newmintinline{xml}{autogobble=true, breaklines=true, linenos=true}
% Paket: multirow
% Beschreibung: Zum kombinieren mehrerer Zellen einer Tabelle
% Option:
\usepackage{multirow}
% Paket: natbib
% Beschreibung: Für Zitate
% Option: round - ?
%\usepackage[round]{natbib}
% Paket: pdflscape
% Beschreibung: Ermöglicht Seiten horizontal darzustellen
% Option: \begin{landscape} \end{landscape}
\usepackage{pdflscape}
% Paket: showframe
% Beschreibung: Blendet alle Frames (Textkörper, Fußzeile Kopzeile, Seitenrand) ein
% Option:
% \usepackage{showframe}
% Paket: subcaption
% Beschreibung: Bietet eine große Auswahl an Gestaltungsmöglichkeiten bezüglich der Beschriftung von Bildern und Tabellen
% die neben oder unter untereinander dargestellt werden sollen.
\usepackage{subcaption}
% format=NAME - Einstellung des grundsätzlichen Formats von Gleitobjektbeschriftungen
% indention=EINZUG - Einstellung des Einzugs der Beschriftung ab der zweiten Zeile
% labelformat=NAME - Einstellung der Zusammensetzung des Bezeichners (z. B. Label und Nummer) der Beschriftung
% labelsep=NAME - Einstellung des Trenners nach dem Bezeichner
% justification=NAME - Einstellung er Ausrichtung des Textes Beschriftung
% singlelinecheck=BOOL - Sonderbehandlung für einzeilige Beschriftungen ein- oder ausschalten
% font=NAME - Einstellung der Schrift der gesamten Beschriftung
% labelfont=NAME - Einstellung der Schrift des Bezeichners
% textfont=NAME - Einstellung der Schrift des Textes der Beschriftung
% margin=BREITE - Einstellung der Breite des Randes der Beschriftung
% width=BREITE - Einstellung der Breite der Beschriftung
% parskip=ABSTAND - Einstellung des Absatzabstandes der Beschriftung
% hangindent=EINZUG - Einstellung des Einzugs abgesehen von ersten Absatzzeilen
% style=NAME - Auswahl einer vordefinierten Gesamteinstellung
% aboveskip=ABSTAND - Einstellung des Abstandes vor einer Beschriftung
% belowskip=ABSTAND - Einstellung des Abstandes nach einer Beschriftung
% position=WAHL - Einstellung ob die Beschriftung als Über- oder Unterschrift formatiert werden soll
% tableposition=WAHL - Einstellung ob nur bei Tabellen die Beschriftung als Über- oder Unterschrift formatiert werden soll
\captionsetup[figure]{position=bottom}
\captionsetup[table]{position=bottom}
% Packet: tabularx
% Beschreibung: Werden Tabellen mit diesem Paket erstellt, ist es möglich Zeilenumbrüche in einer Zelle zu erzeugen
\usepackage{tabularx}
% Paket: textpos
% Beschreibung: Zum erstellen von Textboxen
% \begin{textblock*}{\textwidth}(0cm,0.5cm)
\usepackage{textpos}
% Paket: tikz
% Beschreibung: TikZ and PGF are TeX packages for creating graphics programmatically.
% Dokumentation:
\usepackage{tikz}
\usetikzlibrary{intersections}
% Packet: varwidth
% Beschreibung: The package defines a varwidth environment (based on minipage) which is an analogue
% of minipage, but whose resulting width is the natural width of its contents.
% Dokumentation: http://ctan.math.washington.edu/tex-archive/macros/latex/contrib/varwidth/varwidth-doc.pdf
% https://www.namsu.de/Extra/befehle/Minipage.html
% Option:
\usepackage{varwidth}
% Paket: verbatim
% Beschreibung: Bildet einen Quelltext exakt ab.
% Options:
\usepackage{verbatim}
% Paket: warapfig
% Beschreibung: Ermöglich das floaten von Texten neben Bildern
% Options:
% \begin{wrapfigure}{R}{0.30\textwidth}
% \includegraphics[width=0.30\textwidth]{img/middleware.png}
% \caption{Middleware}
% \end{wrapfigure}
\usepackage{wrapfig}
% Start des Dokuments
\begin{document}
% Set Globally Table-Margin
\def\arraystretch{1.2}
% Fetch Commit ID and Date
\immediate\write18{./git-info.sh commit > git-id.tmp}
\immediate\write18{./git-info.sh date > git-date.tmp}
\immediate\write18{./git-info.sh url > git-url.tmp}
% Importiere weitere .tex Dokumente
\include{./titel/titel}
\pagebreak
% Pagestyle
% Setze das Seitenlayout auf fancyhdr um Fuß- und Kopfzeilen zu setzen
\pagestyle{fancy}
% Löscht alle Kopf- und Fußzeilen des pagestyles fancyhdr
\fancyhf{}
% Fuß- und Kopfzeile des Paketes fancyhdr
% [L] - Linkeseite [O] - Ungerade Seitenzahlen [LE,LO] - Linkeseite, Gerade- und Ungerade Seitenanzahlen
% [C] - Mitte [E] - Gerade Seitenanzahlen [CE] - Seitenmitte, nur gerade Seitenanzahlen
% [R] - Rechteseite [RO] - Rechteseite, nur ungerade Seitenanzahlen
% \fancyhead Kopfzeile
% \fancyfoot Fußzeile
\fancyhead[L]{\rightmark}
\fancyhead[R]{\includegraphics[width=4cm]{img/logo.png}}
\fancyfoot[L]{Betriebssysteme / Linux WS21/22 - Aufgabensammlung}
\fancyfoot[C]{}
% Pixelstärke der Kopf- und Fußzeilenlinie
\renewcommand{\headrulewidth}{1pt}
\renewcommand{\footrulewidth}{1pt}
% Agenda
\tableofcontents
\pagebreak
% Setze die Seitenbeginn zurück
\setcounter{page}{1}
\fancyfoot[R]{Seite \thepage}
% Importiere weitere .tex Dokumente
% \include{./examples/examples}
\include{./chapters/01-ssh}
% \include{./chapters/01-network}
% \include{./chapters/02-dns}
% \include{./chapters/03-ssh}
% \include{./chapters/04-file-permissions}
% \include{./chapters/05-directory-structure}
% \include{./chapters/06-filesystems}
% \include{./chapters/07-backups}
% \include{./chapters/08-textprocessing}
% \include{./chapters/99-questions}
% \include{./chapters/99-awk}
% Aufzählung aller Bilder
% \listoffigures
% \newpage
% Aufzählung aller Tabellen
% \listoftables
% \newpage
% Glossary
\printglossaries
\newpage
% Literatur
\printbibliography[heading=bibintoc]
\end{document}

87
referenzen/bibliothek.bib Normal file
View File

@ -0,0 +1,87 @@
@book{ID,
author = {author},
title = {title},
date = {date},
OPTeditor = {editor},
OPTeditora = {editora},
OPTeditorb = {editorb},
OPTeditorc = {editorc},
OPTtranslator = {translator},
OPTannotator = {annotator},
OPTcommentator = {commentator},
OPTintroduction = {introduction},
OPTforeword = {foreword},
OPTafterword = {afterword},
OPTsubtitle = {subtitle},
OPTtitleaddon = {titleaddon},
OPTmaintitle = {maintitle},
OPTmainsubtitle = {mainsubtitle},
OPTmaintitleaddon = {maintitleaddon},
OPTlanguage = {language},
OPToriglanguage = {origlanguage},
OPTvolume = {volume},
OPTpart = {part},
OPTedition = {edition},
OPTvolumes = {volumes},
OPTseries = {series},
OPTnumber = {number},
OPTnote = {note},
OPTpublisher = {publisher},
OPTlocation = {location},
OPTisbn = {isbn},
OPTchapter = {chapter},
OPTpages = {pages},
OPTpagetotal = {pagetotal},
OPTaddendum = {addendum},
OPTpubstate = {pubstate},
OPTdoi = {doi},
OPTeprint = {eprint},
OPTeprintclass = {eprintclass},
OPTeprinttype = {eprinttype},
OPTurl = {url},
OPTurldate = {urldate},
}
@online{ID,
ALTauthor = {author},
ALTeditor = {editor},
title = {title},
date = {date},
url = {url},
OPTsubtitle = {subtitle},
OPTtitleaddon = {titleaddon},
OPTlanguage = {language},
OPTversion = {version},
OPTnote = {note},
OPTorganization = {organization},
OPTdate = {date},
OPTmonth = {month},
OPTyear = {year},
OPTaddendum = {addendum},
OPTpubstate = {pubstate},
OPTurldate = {urldate},
}
@online{fedora33-btrfs-default,
author = {Murphy, Chris and White, Langdon},
title = {Btrfs Coming to Fedora 33},
date = {2020-08-24},
url = {https://fedoramagazine.org/btrfs-coming-to-fedora-33/},
OPTurldate = {2020-10-21},
}
@online{was-ist-btrfs,
author = {Community, Arch Linux},
title = {Arch auf BtrFS},
date = {2020-08-01},
url = {https://wiki.archlinux.de/title/Arch_auf_BtrFS},
OPTurldate = {2020-10-27},
}
@PHDTHESIS{roy-thomas-fielding,
author = {Fielding, Roy Thomas},
title = {Architectural Styles and the Design of Network-based Software Architectures},
school = {University of California, Irvine},
year = {2000},
}

40
referenzen/glossar.tex Normal file
View File

@ -0,0 +1,40 @@
% Akronyme
\newacronym[longplural=Virtuelle Maschinen]{acr:vm}{VM}{Virtuelle Maschine}
\newacronym{acr:acl}{ACL}{Access-Control-List}
\newacronym{acr:bash}{bash}{Bourn Again Shell}
\newacronym{acr:bios}{BIOS}{Basis Input Output System}
\newacronym{acr:btrfs}{BtrFS}{B-tree File System}
\newacronym{acr:cow}{COW}{Copy-On-Write}
\newacronym{acr:ddl}{DDL}{Data-Definition-Language}
\newacronym{acr:dhcp}{DHCP}{Dynamic Host Configuration Protocol}
\newacronym{acr:dns}{DNS}{Domain Name System}
\newacronym{acr:eCryptfs}{eCryptfs}{Enterprise Cryptographic Filesystem}
\newacronym{acr:ext2}{ext2}{Second Extended Filesystem}
\newacronym{acr:ext3}{ext3}{Third Extended Filesystem}
\newacronym{acr:ext4}{ext4}{Fourth Extended Filesystem}
\newacronym{acr:fqdn}{FQDN}{Full Qualified Domain Name}
\newacronym{acr:gui}{GUI}{Graphical-User-Interface}
\newacronym{acr:icann}{ICANN}{Internet Corporation for Assigned Names and Numbers}
\newacronym{acr:ip}{IP}{Internet Protocol}
\newacronym{acr:kvm}{KVM}{Kernel-based Virtual Machine}
\newacronym{acr:ntfs}{NTFS}{New Technology File System}
\newacronym{acr:ntp}{NTP}{Network-Time-Protocol}
\newacronym{acr:raid}{RAID}{Redundant Array of Independent Disks}
\newacronym{acr:ram}{RAM}{Random-Access-Memory}
\newacronym{acr:rdp}{RDP}{Remote-Desktop-Protocol}
\newacronym{acr:reiser}{Reiser}{Reiser File System}
\newacronym{acr:rpm}{RPM}{RPM Package Manager}
\newacronym{acr:rr}{RR}{Recource Record}
\newacronym{acr:soa}{SOA}{Start-of-Authority}
\newacronym{acr:sql}{SQL}{Structured-Query-Language}
\newacronym{acr:ssh}{SSH}{Secure-Shell}
\newacronym{acr:uefi}{UEFI}{Unified Extensible Firmware Interface}
\newacronym{acr:telnet}{Telnet}{Teletype Network}
\newacronym{acr:tld}{TLD}{Top-Level-Domain}
\newacronym{acr:vnc}{VNC}{Virtual-Network-Computing}
% Glossar
\newglossaryentry{gls:minted}{
name={Minted},
description={Minted is a package that allows formatting and highlighting source code in \latex.}
}

70
solutions/07-backups.md Normal file
View File

@ -0,0 +1,70 @@
## Aufgabe 1a
Datum Wochentag Backup-Methode Band
2020-11-02 Mon Ink Sohn-1
2020-11-03 Tue Ink Sohn-2
2020-11-04 Wed Ink Sohn-3
2020-11-05 Thur Ink Sohn-4
2020-11-06 Fri Diff Vater-1
2020-11-09 Mon Ink Sohn-1
2020-11-10 Tue Ink Sohn-2
2020-11-11 Wed Ink Sohn-3
2020-11-12 Thur Ink Sohn-4
2020-11-13 Fri Diff Vater-2
2020-11-16 Mon Ink Sohn-1
2020-11-17 Tue Ink Sohn-2
2020-11-18 Wed Ink Sohn-3
2020-11-19 Thur Ink Sohn-4
2020-11-20 Fri Diff Vater-3
2020-11-23 Mon Ink Sohn-1
2020-11-24 Tue Ink Sohn-2
2020-11-25 Wed Ink Sohn-3
2020-11-26 Thur Ink Sohn-4
2020-11-27 Fri Diff Vater-4
## Aufgabe 1b
Datum Wochentag Backup-Methode Band
2020-11-07 Fri Diff Vater-1
2020-11-14 Fri Diff Vater-2
2020-11-21 Fri Diff Vater-3
2020-11-28 Fri Diff Vater-4
2020-11-30 Mon Voll Großvater-1
2020-12-04 Fri Diff Vater-1
2020-12-11 Fri Diff Vater-2
2020-12-18 Fri Diff Vater-3
2020-12-25 Fri Diff Vater-4
2020-12-31 Thur Voll Großvater-2
2021-01-01 Fri Diff Vater-1
2021-01-08 Fri Diff Vater-2
2021-01-15 Fri Diff Vater-3
2021-01-22 Fri Diff Vater-4
2021-01-29 Fri Voll Großvater-3
## Praxisaufgabe
### Teilaufgabe A
Drei Monate, zwei Wochen und einen Tag zurück vom 6. November 2020.
```bash
$ date --date '2020-11-06 - 3 month - 2 week - 1 day' '+%A, %d %B %Y'
Montag, 22 Juli 2020
```
Benötigte Backups
Großvater-Backup 07. August 2020
### Teilaufgabe B
28.10.2020
Benötigte Backups
Großvater-Backup 02. Oktober 2020
Vater-Backup 09. 16. und 23. Oktober 2020
Sohn-Backup 26. 27. und 28. Oktober 2020

38
solutions/overlayfs.sh Normal file
View File

@ -0,0 +1,38 @@
#!/bin/bash
# 7a
mkdir --parent /root/workspace/overlayfs
cd /root/workspace/overlayfs
# 7b1
mkdir --parent ./lower_0/usr/bin
touch ./lower_0/usr/bin/mybin
# 7b2
mkdir --parent ./lower_1/etc/mybin
touch ./lower_1/etc/mybin/config.json
# 7b3
mkdir --parent ./lower_2/var/log/mybin
touch ./lower_2/var/log/mybin/info.log
# 7b4
mkdir --parent ./lower_3/usr/lib/systemd/system
touch ./lower_3/usr/lib/systemd/system/mybin.service
# 7b5
mkdir --parent ./lower_4/etc/mybin/conf.d/
touch ./lower_4/etc/mybin/conf.d/sqlite.config
# 7b6
mkdir --parent ./lower_5/etc/mybin/conf.d/
touch ./lower_4/etc/mybin/conf.d/postgresql.config
# 7c
mkdir --parent ./upper_application ./upper_application_plugins
mkdir --parent ./workdir_application ./workdir_application_plugins
mkdir --parent ./application ./application_plugins
mount -t overlay -o lowerdir=$(pwd)/lower_0:$(pwd)/lower_1:/$(pwd)/lower_2:/$(pwd)/lower_3,upperdir=$(pwd)/upper_application,workdir=$(pwd)/workdir_application overlayfs $(pwd)/application
mount -t overlay -o lowerdir=$(pwd)/lower_0:$(pwd)/lower_1:/$(pwd)/lower_2:/$(pwd)/lower_3:/$(pwd)/lower_4:/$(pwd)/lower_5,upperdir=$(pwd)/upper_application_plugins,workdir=$(pwd)/workdir_application_plugins overlayfs $(pwd)/application_plugins

0
sql/.gitkeep Normal file
View File

File diff suppressed because it is too large Load Diff

31
titel/titel.tex Normal file
View File

@ -0,0 +1,31 @@
\begin{titlepage}
\begin{center}
\begin{large}
Aufgabensammlung WS21/22
\end{large}
\begin{huge}
\begin{singlespace}
\textbf{Betriebssysteme / Linux}
\end{singlespace}
\end{huge}
\vspace{0.5cm}
\begin{figure}[h]
\centering
\includegraphics[width=0.85\textwidth]{img//logo.png}
\label{img:fh-trier-logo}
\end{figure}
\vspace{2cm}
\begin{large}
\textit{Markus Pesch} \\
\href{mailto:peschm@hochschule-trier.de}{\textit{peschm@hochschule-trier.de}}
\end{large}
\vspace{2cm}
Version \input{git-id.tmp} vom \input{git-date.tmp}
\end{center}
\end{titlepage}