Files
Snippets/Linux-Sammelsurium.md
2026-09-07 07:54:54 +02:00

1018 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Linux: Projekte ablegen, Dateien suchen/löschen und `xargs`
## Projekte unter Linux organisieren
Es gibt keine feste Vorgabe, aber einige Verzeichnisstrukturen haben sich etabliert.
### Für persönliche Entwicklungsprojekte
Empfohlen:
- `~/Projects/`
- `~/Code/`
- `~/src/` (unter Entwicklern sehr verbreitet)
Beispiel:
```text
/home/max/
├── Documents/
├── Downloads/
├── Projects/
│ ├── website/
│ ├── python-tool/
│ └── homelab/
```
Oder eine nach Git-Hosting strukturierte Variante:
```text
~/src/
├── github.com/
│ └── benutzer/
│ ├── projekt1/
│ └── projekt2/
└── private/
```
Verzeichnis anlegen:
```bash
mkdir -p ~/Projects
```
oder
```bash
mkdir -p ~/src
```
### Für mehrere Benutzer
| Verzeichnis | Zweck |
| ----------------- | ----------------------------------------------------------------- |
| `/srv/` | Gemeinsam genutzte Projekte oder Dienste |
| `/usr/local/src/` | Systemweiter Quellcode |
| `/opt/` | Installierte Drittanbieter-Software (nicht für eigenen Quellcode) |
---
# Dateien mit `find` suchen und löschen
## Dateien nach Namen löschen
Alle `.tmp`-Dateien löschen:
```bash
find . -name "*.tmp" -delete
```
---
## Erst suchen, dann löschen (empfohlen)
Dateien anzeigen:
```bash
find . -name "*.tmp"
```
Anschließend löschen:
```bash
find . -name "*.tmp" -delete
```
---
## Mit Rückfrage löschen
```bash
find . -name "*.tmp" -ok rm {} \;
```
oder
```bash
find . -name "*.tmp" -exec rm -i {} \;
```
---
## Nach Alter löschen
Logdateien, die älter als 30 Tage sind:
```bash
find . -name "*.log" -mtime +30 -delete
```
---
## Leere Verzeichnisse löschen
```bash
find . -type d -empty -delete
```
---
## Achtung
`-delete` löscht Dateien sofort und ohne Papierkorb.
Deshalb empfiehlt sich immer:
1. `find` ohne `-delete`
2. Ergebnisse prüfen
3. `-delete` ergänzen
Beispiel:
```bash
find ~/Downloads -name "*.zip"
find ~/Downloads -name "*.zip" -delete
```
---
# xargs erklärt
## Was macht `xargs`?
`xargs` nimmt Eingaben (meist aus einer Pipe) entgegen und macht daraus Argumente für einen anderen Befehl.
Beispiel:
```bash
echo "a.txt b.txt c.txt" | xargs rm
```
Das entspricht:
```bash
rm a.txt b.txt c.txt
```
---
## Typischer Einsatz mit `find`
Ohne `xargs`:
```bash
find . -name "*.log" -exec rm {} \;
```
Mit `xargs`:
```bash
find . -name "*.log" | xargs rm
```
`xargs` bündelt mehrere Dateinamen zu einem einzigen `rm`-Aufruf und ist dadurch oft effizienter.
---
## Problem mit Leerzeichen
Angenommen, es gibt eine Datei:
```text
Meine Datei.txt
```
Dann liefert:
```bash
find . -name "*.txt" | xargs rm
```
`xargs` trennt standardmäßig an Leerzeichen und Zeilenumbrüchen.
Es interpretiert:
```text
./Meine Datei.txt
```
als zwei Argumente:
- `./Meine`
- `Datei.txt`
Das führt zu Fehlern.
---
## Die sichere Lösung
Deshalb verwendet man fast immer:
```bash
find . -name "*.txt" -print0 | xargs -0 rm
```
### Warum?
- `find -print0` trennt Dateinamen mit einem Nullbyte (`\0`)
- `xargs -0` liest genau dieses Format
Dadurch funktionieren auch Dateinamen mit:
- Leerzeichen
- Tabs
- Zeilenumbrüchen
- Sonderzeichen
---
## Platzhalter mit `-I`
Soll der Dateiname mitten im Befehl stehen:
```bash
find . -name "*.jpg" | xargs -I {} cp {} /backup/
```
Für jede Datei wird ausgeführt:
```bash
cp datei.jpg /backup/
```
---
## Anzahl der Argumente begrenzen
```bash
seq 1 10 | xargs -n 3 echo
```
Ausgabe:
```text
1 2 3
4 5 6
7 8 9
10
```
`-n 3` bedeutet: maximal drei Argumente pro Befehlsaufruf.
---
## Parallelisierung
Mehrere Prozesse gleichzeitig starten:
```bash
find . -name "*.png" | xargs -P 4 -n 1 convert
```
Parameter:
- `-P 4` → bis zu vier Prozesse parallel
- `-n 1` → ein Dateiname pro Prozess
---
## Alternative ohne `xargs`
Viele moderne Befehle unterstützen bereits mehrere Dateien gleichzeitig.
Beispiel:
```bash
find . -name "*.log" -exec rm {} +
```
Das erreicht nahezu denselben Effekt wie:
```bash
find . -name "*.log" -print0 | xargs -0 rm
```
---
# Merksätze
### Projekte
- Eigene Projekte → `~/Projects` oder `~/src`
- Gemeinsame Projekte → `/srv`
- Installierte Software → `/opt`
### `find`
- Dateien suchen:
```bash
find . -name "*.txt"
```
- Direkt löschen:
```bash
find . -name "*.txt" -delete
```
### `xargs`
- Macht aus Pipe-Ausgabe Befehlsargumente.
- Spart viele einzelne Programmaufrufe.
- Immer sicher verwenden mit:
```bash
find . -print0 | xargs -0 <befehl>
```
### Moderne Alternative
Wenn möglich:
```bash
find . -exec <befehl> {} +
```
Diese Variante ist oft einfacher und ebenso effizient.
# SNMP: MIB-Auflösung und OID-Übersetzung mit net-snmp
## OIDs werden trotz eingehängter MIB nicht textuell aufgelöst
### Mögliche Ursachen
**MIB wird nicht geladen**
- 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`.
- net-snmp lädt standardmäßig nur ein Minimalset. `mibs :` deaktiviert alles.
**Dateiname passt nicht zum MIB-Namen**
- net-snmp löst Module über den Dateinamen auf; der interne Modulname (vor `DEFINITIONS ::= BEGIN`) muss stimmen.
**Fehlende IMPORTS / Abhängigkeiten**
- Importierte MIBs (z. B. `SNMPv2-SMI`, `SNMPv2-TC`, herstellereigene Basis-MIBs) fehlen → Parsen schlägt still fehl. Sichtbar machen mit:
```bash
snmptranslate -M+/pfad -m ALL -Dparse-mibs OID
```
**Parse-/Syntaxfehler in der MIB**
- Diagnose:
```bash
snmptranslate -Le -m ALL -M /pfad -On MEIN-MIB::objekt
```
Fehler werden auf stderr ausgegeben.
**Numerische OID gehört zu keinem geladenen Zweig**
- Die abgefragte Enterprise-OID liegt außerhalb dessen, was die MIB definiert (falsche/unvollständige MIB).
### Schneller Prüfweg
1. `snmptranslate -m +MEIN-MIB -IR meinObjekt` → gibt es einen Treffer?
2. `snmptranslate -Le -M /pfad/zu/mibs -m ALL .1.3.6.1.4.1.<enterprise>` → Fehler beim Laden?
3. Fehlende Import-MIBs nachlegen.
Meist ist es eine fehlende Import-Abhängigkeit oder ein falscher Suchpfad/Modulname.
---
## Umgekehrt: von `MIB::objekt` auf die OID schließen
Textuellen Namen statt numerischer OID übergeben (MIB muss geladen sein):
```bash
snmpget -v2c -c public host MEIN-MIB::meinObjekt.0
snmpwalk -v2c -c public host MEIN-MIB::meinObjekt
```
### Vorher ohne Gerät prüfen (Name → OID)
```bash
snmptranslate -On MEIN-MIB::meinObjekt
```
`-On` erzwingt die numerische Ausgabe, also die zugehörige OID.
Umgekehrt (OID → Name):
```
snmptranslate .1.3.6.1.4.1.xxx
```
### Nützliche Varianten
- Objektname allein suchen (ohne `MIB::`-Präfix):
```
snmptranslate -IR -On meinObjekt
```
- Vollständigen symbolischen Pfad anzeigen:
```
snmptranslate -Of MEIN-MIB::meinObjekt
```
- Objektdetails (Typ, Zugriff, Beschreibung):
```
snmptranslate -Td MEIN-MIB::meinObjekt
```
### Hinweise
- Scheitert `snmpget MEIN-MIB::meinObjekt.0` mit „Unknown Object Identifier", ist die MIB nicht geladen → mit `-m +MEIN-MIB` bzw. `-M /pfad` ergänzen.
- Bei skalaren Objekten die `.0`-Instanz nicht vergessen.
# Idoit von 35 auf 38
Test auf Masternode
- kein main-Mode
- ohne ansible
## php8.2 zu 8.4
8.2-Module ermitteln, die Ausgabe listet die entsprechenden 8.4-Paketnamen
```bash
dpkg -l | grep '^ii php8.2' | awk '{print $2}' | sed 's/8.2/8.4/'
```
Update der entsprechenden Pakete
```bash
apt update
apt install -y $(dpkg -l | grep '^ii php8.2' | awk '{print $2}' | sed 's/8.2/8.4/')
```
Umschalten (mod_php/Apache) und CLI
```bash
a2dismod php8.2 && a2enmod php8.4
crm res restart rcapache2
update-alternatives --set php /usr/bin/php8.4
```
# Zertifikate
## Ein CSR (Certificate Signing Request) erstellen (bei vorhandenem )
```bash
openssl req -new -key server.key -out server.csr
```
Hier werden dann einige Daten abgefragt. Daher ist es einfacher mit einem Config-File das man mit übergibt
```bash
openssl req -new -key server.key -out server.csr -config config.req
```
### Muster für ein Config-File
```bash
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
req_extensions = req_cert_ext
prompt = no
default_days = 365
[ req_distinguished_name ]
#
# requested SubjectDN
#
C = DE
O = Bund
OU = Service
CN = cmdb01.adm.ivbb.bund.de
emailAddress = mail@bund.de
[req_cert_ext]
#
subjectAltName = @alt_names
## requested SubjectAlternativeNames (SANs)
[ alt_names ]
DNS.1 = cmdb01.adm.ivbb.bund.de
DNS.2 = mlseazcmd01.adm.ivbb.bund.de
DNS.3 = mlsfazcmd01.adm.ivbb.bund.de
```
## Betrachten des CSR
```bash
openssl req -text -in <csr>
```
#### Notizen zu Zertifikate
##### Private Key erstellen
openssl genrsa -out $HOME/servercrt/dlsea3tim01.server.key 2048
##### Zertifikatsrequest erstellen
openssl req -new -days 1095 -key dlsea3tim01.server.key -out dlsea3tim01.server.csr -config req_config.dlsea3tim01.adm.ivbb.bund.de
##### Zertifikatsrequest ansehen
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.**
###############
Änderungen an Profil-Dateien wie `~/.bashrc` erfordern eine neue Shell-Sitzung oder das explizite Ausführen von `source ~/.bashrc`, damit sie in der aktuellen Sitzung wirksam werden.