SQL erweitert, neu: ansible, Linux umd passwd und shadows erweitert

This commit is contained in:
Sven Riwoldt
2026-08-19 13:50:00 +02:00
parent 2a8733f8f8
commit d696ff35e7
3 changed files with 1226 additions and 11 deletions
+487 -1
View File
@@ -346,7 +346,7 @@ Diese Variante ist oft einfacher und ebenso effizient.
**MIB wird nicht geladen** **MIB wird nicht geladen**
- MIB liegt nicht in einem durchsuchten Verzeichnis. Prüfen mit `net-snmp-config --default-mibdirs`; übliche Pfade sind `~/.snmp/mibs`, `/usr/share/snmp/mibs`. - MIB liegt nicht in einem durchsuchten Verzeichnis. Prüfen mit `net-snmp-config --default-mibdirs`; übliche Pfade sind `~/.snmp/mibs`, <mark>`/usr/share/snmp/mibs</mark>`.
- MIB nicht per `-m` oder Konfiguration aktiviert. Test: `snmpwalk -m ALL ...` oder in `~/.snmp/snmp.conf` bzw. `/etc/snmp/snmp.conf`: `mibs +MEIN-MIB`. - MIB nicht per `-m` oder Konfiguration aktiviert. Test: `snmpwalk -m ALL ...` oder in `~/.snmp/snmp.conf` bzw. `/etc/snmp/snmp.conf`: `mibs +MEIN-MIB`.
- net-snmp lädt standardmäßig nur ein Minimalset. `mibs :` deaktiviert alles. - net-snmp lädt standardmäßig nur ein Minimalset. `mibs :` deaktiviert alles.
@@ -530,3 +530,489 @@ openssl req -new -days 1095 -key dlsea3tim01.server.key -out dlsea3tim01.server.
##### Zertifikatsrequest ansehen ##### Zertifikatsrequest ansehen
openssl req -text -in dlsea3tim01.server.csr|less openssl req -text -in dlsea3tim01.server.csr|less
Bei Apache/mod_ssl ist der Unterschied:
- **`SSLCertificateFile`** → enthält das **öffentliche Zertifikat** des Servers. Darin stecken u. a. der öffentliche Schlüssel, Domainname und die Signatur der CA. Dieses Zertifikat wird beim TLS-Handshake an den Client geschickt.
- **`SSLCertificateKeyFile`** → enthält den dazugehörigen **privaten Schlüssel**. Er bleibt ausschließlich auf dem Server und darf **niemals veröffentlicht** werden.
# SCP
```bash
scp [Optionen] [Quelle] [Ziel]
```
### Optionen
Dies sind optionale Flags, die das Verhalten des SCP-Befehls verändern. Sie können verschiedene Optionen verwenden, um den Übertragungsprozess individuell zu gestalten. Hier sind einige gängige Optionen:
**-r:** Kopiert Verzeichnisse und deren Inhalte rekursiv.
**-p:** Behält die Berechtigungen, Zeitstempel und Modi der Originaldatei bei.
–**P**: Gibt die Portnummer für die SSH-Verbindung an.
–**i**: Gibt die private Schlüsseldatei für die SSH-Authentifizierung an.
**-C:** Verwenden Sie die Komprimierung, um die Datenübertragung zu beschleunigen.
**-l:** Begrenzen Sie die für die Übertragung verwendete Bandbreite (in Kbit/s).
**-v:** Ausführlicher Modus – zeigt Debugging-Meldungen während der Übertragung an.
**-o:** Übergibt eine Option an den SSH-Client. Sie kann verwendet werden, um die strenge Prüfung des Hostschlüssels zu deaktivieren.
# Linux: `/etc/passwd` und `/etc/shadow`
Unter Linux werden Benutzerinformationen hauptsächlich in den Dateien `/etc/passwd` und `/etc/shadow` gespeichert.
- `/etc/passwd` enthält allgemeine Informationen über Benutzerkonten.
- `/etc/shadow` enthält sensible Informationen zur Passwort- und Accountverwaltung.
---
## 1. `/etc/passwd`
Die Datei `/etc/passwd` enthält pro Benutzer eine Zeile.
### Beispiel
```text
max:x:1001:1001:Max Mustermann:/home/max:/bin/bash
```
Die einzelnen Felder werden durch einen Doppelpunkt (`:`) getrennt.
```text
max:x:1001:1001:Max Mustermann:/home/max:/bin/bash
 │  │   │    │         │           │          │
 │  │   │    │         │           │          └─ Login-Shell
 │  │   │    │         │           └─ Home-Verzeichnis
 │  │   │    │         └─ Kommentar / GECOS
 │  │   │    └─ primäre GID
 │  │   └─ UID
 │  └─ Passwort-Platzhalter
 └─ Benutzername
```
### Aufbau
| Feld | Beispiel | Bedeutung |
|---|---|---|
| 1 | `max` | Benutzername |
| 2 | `x` | Passwort-Platzhalter |
| 3 | `1001` | UID – User ID |
| 4 | `1001` | GID – primäre Group ID |
| 5 | `Max Mustermann` | Kommentar / GECOS |
| 6 | `/home/max` | Home-Verzeichnis |
| 7 | `/bin/bash` | Login-Shell |
### Feld 1 – Benutzername
```text
max
```
Der eindeutige Name, unter dem der Benutzer im System bekannt ist.
---
### Feld 2 – Passwort-Platzhalter
```text
x
```
Das `x` bedeutet, dass sich die eigentlichen Passwortinformationen in `/etc/shadow` befinden.
Historisch konnten Passwort-Hashes direkt in `/etc/passwd` gespeichert werden. Das wäre heute problematisch, da `/etc/passwd` normalerweise für alle Benutzer lesbar sein muss.
---
### Feld 3 – UID
```text
1001
```
Die **UID (User ID)** ist die numerische Kennung des Benutzers.
Linux arbeitet intern an vielen Stellen mit der UID und nicht mit dem Benutzernamen.
Beispielsweise besitzt `root` normalerweise die UID:
```text
0
```
---
### Feld 4 – GID
```text
1001
```
Die **GID (Group ID)** gibt die primäre Gruppe des Benutzers an.
Weitere Gruppenzugehörigkeiten werden normalerweise über `/etc/group` bzw. entsprechende Benutzerverwaltungsdienste bestimmt.
---
### Feld 5 – GECOS / Kommentar
```text
Max Mustermann
```
Dieses Feld kann zusätzliche Informationen über den Benutzer enthalten, beispielsweise:
- vollständiger Name
- Raumnummer
- Telefonnummer
- sonstige Informationen
---
### Feld 6 – Home-Verzeichnis
```text
/home/max
```
Das Home-Verzeichnis des Benutzers.
Nach einem normalen Login befindet sich der Benutzer üblicherweise in diesem Verzeichnis.
---
### Feld 7 – Login-Shell
```text
/bin/bash
```
Die Shell, die nach einem Login gestartet werden soll.
Beispiele:
```text
/bin/bash
/bin/sh
/bin/zsh
```
Bei Systemkonten findet man häufig auch:
```text
/usr/sbin/nologin
```
oder:
```text
/bin/false
```
Damit soll normalerweise ein interaktiver Login verhindert werden.
---
# 2. `/etc/shadow`
Die Datei `/etc/shadow` enthält die sensiblen Passwort- und Ablaufinformationen eines Benutzers.
Sie ist deshalb im Gegensatz zu `/etc/passwd` normalerweise nur für `root` bzw. entsprechend privilegierte Prozesse lesbar.
### Beispiel
```text
max:$6$...:20680:0:99999:7:::
```
Eine Zeile besteht aus **9 Feldern**:
```text
max:$6$...:20680:0:99999:7:::
 │      │      │   │    │   │ │ │ │
 │      │      │   │    │   │ │ │ └─ reserviert
 │      │      │   │    │   │ │ └─ Account-Ablauf
 │      │      │   │    │   │ └─ Inaktivität
 │      │      │   │    │   └─ Warnzeit
 │      │      │   │    └─ maximales Passwortalter
 │      │      │   └─ minimales Passwortalter
 │      │      └─ letzte Passwortänderung
 │      └─ Passwort-Hash / Passwortstatus
 └─ Benutzername
```
## Aufbau
| Feld | Bedeutung |
|---|---|
| 1 | Benutzername |
| 2 | Passwort-Hash / Passwortstatus |
| 3 | Letzte Passwortänderung |
| 4 | Minimales Passwortalter |
| 5 | Maximales Passwortalter |
| 6 | Warnzeit vor Passwortablauf |
| 7 | Inaktivitätszeit |
| 8 | Ablaufdatum des Accounts |
| 9 | Reserviert |
---
## 3. Benutzername
Das erste Feld muss zum entsprechenden Benutzerkonto passen.
Beispiel:
```text
max
```
Damit können die Informationen aus `/etc/passwd` und `/etc/shadow` demselben Benutzer zugeordnet werden.
---
## 4. Passwort-Hash / Passwortstatus
Das zweite Feld ist besonders wichtig.
Ein Eintrag könnte beispielsweise folgendermaßen aussehen:
```text
$6$salt$hash
```
Dabei steht `$6$` bei klassischen `crypt`-Passwörtern für **SHA-512**.
Auf modernen Linux-Systemen können auch andere Verfahren eingesetzt werden, beispielsweise **yescrypt**, das häufig an einem Präfix wie `$y$` erkennbar ist.
Das Passwort selbst wird nicht gespeichert. Stattdessen wird ein daraus berechneter Hash gespeichert.
---
## 5. Besondere Werte im Passwortfeld
Das zweite Feld kann auch Werte enthalten, die keinen gültigen Passwort-Hash darstellen.
### Übersicht
| Eintrag | Typische Bedeutung |
|---|---|
| `$6$...` | Passwort-Hash, z. B. SHA-512 |
| `$y$...` | Passwort-Hash, z. B. yescrypt |
| `!$6$...` | Passwort gesperrt, ursprünglicher Hash noch vorhanden |
| `!!` | Kein verwendbares Passwort gesetzt / Passwort-Login gesperrt |
| `*` | Passwort-Authentifizierung nicht möglich |
| leer | Potenziell kein Passwort erforderlich – sicherheitskritisch |
---
# 6. Was bedeutet `!!`?
Beispiel:
```text
max:!!:20680:0:99999:7:::
```
Hier steht im zweiten Feld:
```text
!!
```
`!!` ist **kein gültiger Passwort-Hash**.
Es bedeutet typischerweise:
> Für diesen Benutzer ist kein verwendbares lokales Passwort gesetzt. Eine Authentifizierung über dieses Passwortfeld ist daher nicht möglich.
Das sieht man beispielsweise bei neu angelegten oder bewusst für Passwort-Logins gesperrten Accounts.
Wichtig ist dabei:
**Ein gesperrtes Passwort ist nicht automatisch dasselbe wie ein vollständig gesperrter Benutzeraccount.**
Abhängig von der Systemkonfiguration könnten andere Authentifizierungsverfahren weiterhin funktionieren, beispielsweise:
- SSH Public Keys
- Kerberos
- LDAP / zentrale Authentifizierung
- SSO
- andere PAM-basierte Verfahren
Vereinfacht:
```text
max:!!:20680:0:99999:7:::
    ^^
    │
    └── kein gültiger Passwort-Hash
        → lokale Passwortauthentifizierung nicht möglich
```
---
# 7. Passwortalter und Ablauf
Die restlichen Felder von `/etc/shadow` steuern unter anderem die Gültigkeitsdauer eines Passworts.
Beispiel:
```text
max:$6$...:20680:0:99999:7:::
```
Hier bedeuten die Werte:
```text
20680 : 0 : 99999 : 7
  │      │     │     │
  │      │     │     └─ Warnung vor Ablauf
  │      │     └─ maximales Passwortalter
  │      └─ minimales Passwortalter
  └─ letzte Passwortänderung
```
Die Datumswerte werden grundsätzlich als Anzahl der **Tage seit dem 01.01.1970** angegeben.
---
# 8. Warum gibt es zwei Dateien?
Der Grund für die Trennung ist hauptsächlich die Sicherheit.
`/etc/passwd` muss von vielen Programmen gelesen werden können.
Beispielsweise müssen Programme herausfinden können:
```text
UID 1001 → Benutzer max
```
Daher ist `/etc/passwd` normalerweise für alle Benutzer lesbar.
Passwort-Hashes sollen dagegen geschützt werden.
Deshalb wurden sie in die stärker geschützte Datei `/etc/shadow` ausgelagert.
---
# 9. Zusammenhang von `/etc/passwd` und `/etc/shadow`
Für denselben Benutzer könnten die Einträge beispielsweise so aussehen:
### `/etc/passwd`
```text
max:x:1001:1001:Max Mustermann:/home/max:/bin/bash
```
### `/etc/shadow`
```text
max:!!:20680:0:99999:7:::
```
Beide Einträge gehören über den Benutzernamen `max` zusammen.
Zusammengefasst:
```text
/etc/passwd
     │
     ├── Benutzername
     ├── UID
     ├── GID
     ├── Home-Verzeichnis
     └── Login-Shell
/etc/shadow
     │
     ├── Benutzername
     ├── Passwort-Hash / Passwortstatus
     ├── Passwortalter
     ├── Warnzeit
     └── Account-Ablauf
```
## Merksatz
> **`/etc/passwd` beschreibt den Benutzer, `/etc/shadow` beschreibt vor allem seinen Passwort- und Ablaufstatus.**
+71 -9
View File
@@ -143,8 +143,6 @@ Das wird das Ergebnis sein:
| Nohlas | 24 | weiblich | | Nohlas | 24 | weiblich |
| Loopa | 18 | weiblich | | Loopa | 18 | weiblich |
###################
## Kombination von Conditions ## Kombination von Conditions
Das Erstellen einer Abfrage mit nur einer Bedingung ist nicht ausreichend. Manchmal möchte man etwas Komplizierteres überprüfen. Dafür haben SQL (und viele andere Programmiersprachen) die AND-, OR- und NOT-Schlüsselwörter, um unsere Fähigkeit zu verbessern, das gewünschte Ergebnis abzurufen. Das Erstellen einer Abfrage mit nur einer Bedingung ist nicht ausreichend. Manchmal möchte man etwas Komplizierteres überprüfen. Dafür haben SQL (und viele andere Programmiersprachen) die AND-, OR- und NOT-Schlüsselwörter, um unsere Fähigkeit zu verbessern, das gewünschte Ergebnis abzurufen.
@@ -520,6 +518,76 @@ Der Rest bei der Division durch 7 ist immer kleiner als 7 und reicht von 0 bis 6
##################################################### #####################################################
Challenge zu modulo
> Verfügbare Tabellen und Spalten:
>
> - `**products**`**:** `**id**`**,** `**price**`, `quantity`
> - | products | | | |
> | -------- | --- | ----- | -------- |
> | | id | price | quantity |
> | 1 | 1 | 154 | 18 |
> | 2 | 2 | 98 | 3 |
> | 3 | 3 | 54 | 15 |
> | 4 | 4 | 142 | 14 |
> | 5 | 5 | 70 | 2 |
> | 6 | 6 | 189 | 7 |
> | 7 | 7 | 44 | 3 |
> | 8 | 8 | 62 | 16 |
> | 9 | 9 | 101 | 8 |
> | 10 | 10 | 192 | 9 |
> | 11 | 11 | 4 | 21 |
> | 12 | 12 | 208 | 3 |
> | 13 | 13 | 144 | 5 |
> | 14 | 14 | 68 | 98 |
> | 15 | 15 | 5 | 14 |
Erstellen Sie eine Abfrage, die:
1. Die Produkt-ID anzeigt
2. Jedes Produkt einem von drei Qualitätskontrollteams (0, 1 oder 2) **basierend auf der Produkt-ID unter Verwendung des Modulo-Operators** zuweist; nennen Sie diese Spalte `quality_control`
3. Nur Produkte einschließt, bei denen die **Spalte quantity eine ungerade Zahl enthält** (z. B. 1, 3, 5, 7...)
Lösung:
```sql
select id, (id % 3) as quality_control from products where quantity % 2 = 1
```
##############################################################
## The ROUND() Function
Die Funktion `ROUND()` wird verwendet, um einen numerischen Wert auf eine bestimmte Anzahl von Nachkommastellen zu runden. Um die Funktion zu verwenden, folge dieser Syntax:
```sql
ROUND(number, decimal_places)
```
- `number`: Die Zahl, die Sie runden möchten
- `decimal_places`: (Optional) Die Anzahl der Nachkommastellen, auf die gerundet werden soll
- Wenn weggelassen, wird auf die nächste ganze Zahl gerundet
- Wenn positiv, wird auf so viele Nachkommastellen gerundet
- Wenn negativ, wird links vom Dezimalpunkt gerundet
Zum Beispiel einfaches Runden auf ganze Zahlen:
```sql
SELECT ROUND(3.7);-- Returns 4.0SELECT ROUND(3.3);-- Returns 3.0SELECT ROUND(3.5);  -- Returns 4.0 (rounds up from .5)
```
**Hinweis:** Die `ROUND()`-Funktion in SQLite gibt immer einen Fließkommawert (REAL) zurück. Aus diesem Grund enthalten die obigen Ergebnisse ein Komma bzw. einen Dezimalpunkt (z. B. 4.0 statt 4).
Runden auf bestimmte Nachkommastellen:
```sql
SELECT ROUND(3.14159, 2);-- Returns 3.14SELECT ROUND(3.14159, 1);-- Returns 3.1SELECT ROUND(3.14159, 0);-- Returns 3.0SELECT ROUND(3.145, 2);-- Returns 3.15 (rounds up because the next digit is 5)
```
**Hinweis:** Wenn die `digit` nach der letzten verbleibenden Nachkommastelle 5 oder größer ist, `rounds` die letzte verbleibende Dezimalstelle auf.
############################################################## ##############################################################
# Kurze SQL-Queries in MariaDB erfassen # Kurze SQL-Queries in MariaDB erfassen
@@ -535,12 +603,6 @@ Prüfen, ob das General Log aktiviert ist:
SHOW VARIABLES LIKE 'general_log'; SHOW VARIABLES LIKE 'general_log';
SHOW VARIABLES LIKE 'log_output' SHOW VARIABLES LIKE 'log_output'
Oder beide Werte gemeinsam anzeigen: Oder beide Werte gemeinsam anzeigen:
```sql ```sql
@@ -648,7 +710,7 @@ Für eine kurzfristige Analyse ist jedoch das **General Log** meist die bessere
> **Fazit:** Für sehr kurze Queries ist `SHOW PROCESSLIST` ungeeignet. Verwende stattdessen das **General Log** oder – falls verfügbar – das **Performance Schema**. > **Fazit:** Für sehr kurze Queries ist `SHOW PROCESSLIST` ungeeignet. Verwende stattdessen das **General Log** oder – falls verfügbar – das **Performance Schema**.
## Suche von Werten die in einer Spalte nur einmal vorkommem # Suche von Werten die in einer Spalte nur einmal vorkommem
```sql ```sql
SELECT * SELECT *
+667
View File
@@ -0,0 +1,667 @@
# Ansible Ad-hoc -- Kurzreferenz
Diese Kurzreferenz fasst die besprochenen Ansible-Ad-hoc-Befehle
zusammen: mehrere Rechner direkt ansprechen, speziellen SSH-User
verwenden, Dateien sichern und kopieren, Rechte setzen, Benutzer mit
Home-Verzeichnis anlegen und per `su` statt `sudo` zu `root` wechseln.
## Rechner direkt ansprechen
Ohne Inventory-Datei können Hosts direkt mit `-i` angegeben werden.
Wichtig ist das abschließende Komma.
```bash
ansible all \
-i "server01,server02,server03," \
-m ping
```
Alternativ mit IP-Adressen:
```bash
ansible all \
-i "10.10.1.20,10.10.1.21,10.10.1.22," \
-m ping
```
## Speziellen SSH-User verwenden
Mit `-u` bzw. `--user` wird festgelegt, mit welchem Benutzer Ansible die
SSH-Verbindung aufbaut.
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-m ping
```
Wenn die SSH-Anmeldung ein Passwort benötigt, zusätzlich `-k` verwenden:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-k \
-m ping
```
`-k` fragt das SSH-Passwort des Login-Users ab.
## Datei kopieren, Rechte setzen und Backup erstellen
Das `copy`-Modul kann die Datei verteilen, Owner/Gruppe/Rechte setzen
und gleichzeitig die vorhandene Zieldatei sichern.
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-m copy \
-a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
Falls für den Zielpfad erhöhte Rechte benötigt werden, muss zusätzlich
Become verwendet werden.
### Mit sudo
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b \
-m copy \
-a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
Falls `sudo` ein Passwort benötigt:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b -K \
-m copy \
-a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
## Vorher prüfen mit `--check`
Viele Änderungen können zunächst im Check-Modus getestet werden:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b \
-m copy \
-a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes" \
--check
```
## Neuen User inklusive Home-Verzeichnis anlegen
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b \
-m user \
-a "name=newuser state=present create_home=yes shell=/bin/bash"
```
Dabei wird `newuser` angelegt und normalerweise `/home/newuser`
erstellt.
Zum vorherigen Test:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b \
-m user \
-a "name=newuser state=present create_home=yes shell=/bin/bash" \
--check
```
## `su` statt `sudo` verwenden
Wenn auf den Zielsystemen nicht `sudo`, sondern `su` für den Wechsel zu
`root` verwendet werden muss:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b \
--become-method=su \
--become-user=root \
-K \
-m user \
-a "name=newuser state=present create_home=yes shell=/bin/bash"
```
Bedeutung:
- `-u deployuser` -- SSH-Login als `deployuser`
- `-b` -- Become/Privilege Escalation aktivieren
- `--become-method=su` -- `su` statt `sudo` verwenden
- `--become-user=root` -- zu `root` wechseln
- `-K` -- Become-/`su`-Passwort interaktiv abfragen
## `su` zunächst testen
Bevor Änderungen durchgeführt werden, kann geprüft werden, ob der
Wechsel zu `root` funktioniert:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-b \
--become-method=su \
--become-user=root \
-K \
-m command \
-a "whoami"
```
Bei erfolgreichem Wechsel sollte jeder Host `root` zurückgeben.
## SSH-Passwort und `su`-Passwort
Wenn sowohl die SSH-Anmeldung als auch `su` ein Passwort benötigen,
müssen `-k` und `-K` verwendet werden:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-k \
-b \
--become-method=su \
--become-user=root \
-K \
-m command \
-a "whoami"
```
Dabei gilt:
Option Bedeutung
---------------------- ---------------------------------------
`-u deployuser` SSH-Login-User
`-k` SSH-Passwort des Login-Users abfragen
`-b` Become aktivieren
`--become-method=su` `su` als Become-Methode
`--become-user=root` Zielbenutzer für Become
`-K` Become-/`su`-Passwort abfragen
Bei Verwendung von `-k` und `-K` fragt Ansible typischerweise nach:
```text
SSH password:
BECOME password:
```
Ohne `-k` kann Ansible beispielsweise einen vorhandenen SSH-Key oder
SSH-Agent verwenden und fragt deshalb nicht nach dem SSH-Passwort.
## Komplettbeispiel: Datei mit `su` verteilen
SSH-Anmeldung als `deployuser` per Passwort, anschließend `su` zu
`root`, vorhandene Datei sichern und neue Datei mit korrekten Rechten
verteilen:
```bash
ansible all \
-i "server01,server02,server03," \
-u deployuser \
-k \
-b \
--become-method=su \
--become-user=root \
-K \
-m copy \
-a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
######################################################################
# Ansible Ad-hoc -- Kurzreferenz
Diese Kurzreferenz fasst die besprochenen Ansible-Ad-hoc-Befehle
zusammen: mehrere Rechner direkt ansprechen, speziellen SSH-User
verwenden, Dateien sichern und kopieren, Rechte setzen, Benutzer mit
Home-Verzeichnis anlegen und per `su` statt `sudo` zu `root` wechseln.
## Rechner direkt ansprechen
Ohne Inventory-Datei können Hosts direkt mit `-i` angegeben werden.
Wichtig ist das abschließende Komma.
```bash
ansible all \
  -i "server01,server02,server03," \
  -m ping
```
Alternativ mit IP-Adressen:
```bash
ansible all \
  -i "10.10.1.20,10.10.1.21,10.10.1.22," \
  -m ping
```
## Speziellen SSH-User verwenden
Mit `-u` bzw. `--user` wird festgelegt, mit welchem Benutzer Ansible die
SSH-Verbindung aufbaut.
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -m ping
```
Wenn die SSH-Anmeldung ein Passwort benötigt, zusätzlich `-k` verwenden:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -k \
  -m ping
```
`-k` fragt das SSH-Passwort des Login-Users ab.
## Datei kopieren, Rechte setzen und Backup erstellen
Das `copy`-Modul kann die Datei verteilen, Owner/Gruppe/Rechte setzen
und gleichzeitig die vorhandene Zieldatei sichern.
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -m copy \
  -a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
Falls für den Zielpfad erhöhte Rechte benötigt werden, muss zusätzlich
Become verwendet werden.
### Mit sudo
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b \
  -m copy \
  -a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
Falls `sudo` ein Passwort benötigt:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b -K \
  -m copy \
  -a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
## Vorher prüfen mit `--check`
Viele Änderungen können zunächst im Check-Modus getestet werden:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b \
  -m copy \
  -a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes" \
  --check
```
## Neuen User inklusive Home-Verzeichnis anlegen
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b \
  -m user \
  -a "name=newuser state=present create_home=yes shell=/bin/bash"
```
Dabei wird `newuser` angelegt und normalerweise `/home/newuser`
erstellt.
Zum vorherigen Test:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b \
  -m user \
  -a "name=newuser state=present create_home=yes shell=/bin/bash" \
  --check
```
## `su` statt `sudo` verwenden
Wenn auf den Zielsystemen nicht `sudo`, sondern `su` für den Wechsel zu
`root` verwendet werden muss:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b \
  --become-method=su \
  --become-user=root \
  -K \
  -m user \
  -a "name=newuser state=present create_home=yes shell=/bin/bash"
```
Bedeutung:
-   `-u deployuser` -- SSH-Login als `deployuser`
-   `-b` -- Become/Privilege Escalation aktivieren
-   `--become-method=su` -- `su` statt `sudo` verwenden
-   `--become-user=root` -- zu `root` wechseln
-   `-K` -- Become-/`su`-Passwort interaktiv abfragen
## `su` zunächst testen
Bevor Änderungen durchgeführt werden, kann geprüft werden, ob der
Wechsel zu `root` funktioniert:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -b \
  --become-method=su \
  --become-user=root \
  -K \
  -m command \
  -a "whoami"
```
Bei erfolgreichem Wechsel sollte jeder Host `root` zurückgeben.
## SSH-Passwort und `su`-Passwort
Wenn sowohl die SSH-Anmeldung als auch `su` ein Passwort benötigen,
müssen `-k` und `-K` verwendet werden:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -k \
  -b \
  --become-method=su \
  --become-user=root \
  -K \
  -m command \
  -a "whoami"
```
Dabei gilt:
  Option                 Bedeutung
  ---------------------- ---------------------------------------
  `-u deployuser`        SSH-Login-User
  `-k`                   SSH-Passwort des Login-Users abfragen
  `-b`                   Become aktivieren
  `--become-method=su`   `su` als Become-Methode
  `--become-user=root`   Zielbenutzer für Become
  `-K`                   Become-/`su`-Passwort abfragen
Bei Verwendung von `-k` und `-K` fragt Ansible typischerweise nach:
```text
SSH password:
BECOME password:
```
Ohne `-k` kann Ansible beispielsweise einen vorhandenen SSH-Key oder
SSH-Agent verwenden und fragt deshalb nicht nach dem SSH-Passwort.
## Komplettbeispiel: Datei mit `su` verteilen
SSH-Anmeldung als `deployuser` per Passwort, anschließend `su` zu
`root`, vorhandene Datei sichern und neue Datei mit korrekten Rechten
verteilen:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -k \
  -b \
  --become-method=su \
  --become-user=root \
  -K \
  -m copy \
  -a "src=./config.conf dest=/etc/myapp/config.conf owner=root group=root mode=0644 backup=yes"
```
## Benutzer ohne nutzbares Passwort (`!!` in `/etc/shadow`)
Mit dem Ansible-`user`-Modul kann das Passwort eines Accounts mit `password_lock=yes` gesperrt werden:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -k \
  -b \
  --become-method=su \
  --become-user=root \
  -K \
  -m user \
  -a "name=newuser state=present create_home=yes shell=/bin/bash password_lock=yes"
```
Auf üblichen Linux-Systemen ist das Passwortfeld damit gesperrt. Bei einem neu angelegten Benutzer kann `/etc/shadow` beispielsweise `newuser:!!:...` enthalten. Das genaue Sperrkennzeichen kann je nach Distribution und Ausgangszustand variieren.
### Bedeutung von `-m user` und `name=newuser`
| Ausdruck | Bedeutung |
|---|---|
| `-m user` | Ansible-Modul `user` verwenden |
| `name=newuser` | Benutzer `newuser` verwalten bzw. anlegen |
| `state=present` | Sicherstellen, dass der Benutzer existiert |
| `create_home=yes` | Home-Verzeichnis anlegen |
| `shell=/bin/bash` | Bash als Login-Shell setzen |
| `password_lock=yes` | Passwort des Accounts sperren |
Wichtig: `-m` bezeichnet bei Ansible das **Modul**. Der Name des neuen Benutzers steht hinter `name=`.
Beispiel für `appuser`:
```bash
ansible all \
  -i "server01,server02,server03," \
  -u deployuser \
  -k \
  -b \
  --become-method=su \
  --become-user=root \
  -K \
  -m user \
  -a "name=appuser state=present create_home=yes shell=/bin/bash password_lock=yes"
```
Nicht mit `useradd` verwechseln: Bei `useradd -m appuser` bedeutet `-m`, dass das Home-Verzeichnis erstellt wird. Bei `ansible ... -m user` wählt `-m` dagegen das Ansible-Modul aus.
## Benutzer ohne Ansible anlegen
Direkt auf Linux:
```bash
useradd -m -s /bin/bash newuser
```
Passwortstatus bzw. Shadow-Eintrag prüfen:
```bash
passwd -S newuser
grep '^newuser:' /etc/shadow
```
Passwort explizit sperren:
```bash
passwd -l newuser
```
`passwd -l` sperrt einen vorhandenen Passwort-Hash durch ein vorangestelltes `!`. Der exakte Inhalt in `/etc/shadow` muss daher nicht zwingend exakt `!!` sein.