... magic!
This commit is contained in:
153
crumbpage-20-tanz-am-kernel.md
Normal file
153
crumbpage-20-tanz-am-kernel.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# 🐧 Crumbpage 20: Tanz am Kernel (Bashing the Shell)
|
||||
|
||||
**Subtitle:** *Dein Cockpit, deine Regeln.*
|
||||
**Pfad:** 20 von X
|
||||
**Schwierigkeit:** ⭐⭐⭐ (3/5)
|
||||
**Zeit:** Lebenslang
|
||||
**Voraussetzungen:** [Environment](crumbpage-14-environment.md), [Editoren](crumbpage-04-editoren.md)
|
||||
|
||||
> *"Die Shell ist kein Programm. Sie ist eine Lebenseinstellung."*
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Spaceship Lackierung (Der Visual-Mod)
|
||||
|
||||
Wir haben jetzt ein Raumschiff (Debian 13), aber es sieht noch aus wie ein Karton.
|
||||
Lass uns Farben mischen. In der `.bashrc` definieren wir unsere Palette.
|
||||
|
||||
### Die Farb-Masken
|
||||
|
||||
```bash
|
||||
# ~/.bashrc - Color Definitions
|
||||
export RED="\[\033[0;31m\]"
|
||||
export GREEN="\[\033[0;32m\]"
|
||||
export YELLOW="\[\033[1;33m\]"
|
||||
export BLUE="\[\033[0;34m\]"
|
||||
export PURPLE="\[\033[0;35m\]"
|
||||
export CYAN="\[\033[0;36m\]"
|
||||
export NC="\[\033[0m\]" # No Color
|
||||
```
|
||||
|
||||
### Der Prompt (PS1)
|
||||
|
||||
Der String `PS1` bestimmt, was vor dem Cursor steht.
|
||||
Standard: `\u@\h:\w\$` (User@Host:Path$)
|
||||
|
||||
**Admin-Style (Rot bei Root):**
|
||||
```bash
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
PS1="${RED}\u@\h${NC}:${BLUE}\w${NC}# "
|
||||
else
|
||||
PS1="${GREEN}\u@\h${NC}:${BLUE}\w${NC}$ "
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Syntax-Fallen: Warum schreit meine Shell?
|
||||
|
||||
Du hast heute gekämpft. Hier sind die Narben und was wir daraus gelernt haben.
|
||||
|
||||
### 1. Das "Eckige Klammern" Trauma
|
||||
Bash ist extrem pingelig mit Leerzeichen.
|
||||
|
||||
**Falsch (Error: command not found):**
|
||||
```bash
|
||||
if [$a = $b]; then ...
|
||||
```
|
||||
Die Shell sucht nach einem Programm namens `[$a`.
|
||||
|
||||
**Richtig:**
|
||||
```bash
|
||||
if [ "$a" = "$b" ]; then ...
|
||||
```
|
||||
Die Klammer `[` ist tatsächlich ein **Befehl** (Alias für `test`). Und Befehle brauchen Leerzeichen zu ihren Argumenten.
|
||||
|
||||
### 2. Ampersand Roulette: `&` vs. `&&`
|
||||
|
||||
Ein kleiner Unterschied, der Prozesse tötet oder Zombies erschafft.
|
||||
|
||||
- `befehl1 && befehl2`: Mach 2 **nur wenn** 1 erfolgreich war (AND).
|
||||
- `befehl1 & befehl2`: Starte 1 im **Hintergrund** und starte sofort 2 (Parallel).
|
||||
|
||||
**Die Falle:**
|
||||
`script.sh & && ssh-add` -> Syntax Error.
|
||||
Das `&&` erwartet einen Befehl davor, aber das `&` hat den Befehl schon in den Hintergrund geschickt (Ende der Befehlskette).
|
||||
|
||||
**Lösung:**
|
||||
Klammern oder Semikolon.
|
||||
`(script.sh &) && ssh-add` (Subshell)
|
||||
|
||||
### 3. EOF und das "Heredoc"
|
||||
Wenn du Code dynamisch schreibst (`cat << EOF`), darf **kein Leerzeichen** nach dem `EOF` (End Marker) stehen. Sonst wartet Bash für immer auf das "echte" EOF.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Mechanik: Symlinks & /dev/null
|
||||
|
||||
### Das schwarze Loch (`/dev/null`)
|
||||
Alles, was dorthin geht, verschwindet. Perfekt für nervige Fehlermeldungen.
|
||||
|
||||
```bash
|
||||
# Standard Output wegwerfen, Fehler anzeigen
|
||||
befehl > /dev/null
|
||||
|
||||
# Alles wegwerfen (Ruhe im Karton)
|
||||
befehl > /dev/null 2>&1
|
||||
```
|
||||
|
||||
### Symlinks bearbeiten
|
||||
Ein Symlink (`ln -s`) ist nur ein Wegweiser.
|
||||
Wenn du ihn bearbeitest (`nano linkname`), bearbeitest du das **Ziel**.
|
||||
Wenn du das Ziel löschst, zeigt der Link ins Leere ("Dangling Symlink").
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Funktionen vs. Aliases
|
||||
|
||||
Aliases sind gut für Abkürzungen (`aliasll='ls -l'`). Für Logik brauchst du Funktionen.
|
||||
|
||||
### Der Reload-Trick
|
||||
Nach dem Editieren der `.bashrc` musst du dich nicht ausloggen.
|
||||
|
||||
```bash
|
||||
# In ~/.bashrc
|
||||
function reload() {
|
||||
source ~/.bashrc
|
||||
echo "♻️ Umgebung neu geladen."
|
||||
}
|
||||
```
|
||||
Jetzt reicht ein `reload`.
|
||||
|
||||
### Der "Killer" (Prozess-Management)
|
||||
|
||||
Wie vom User heute gefordert: Eine Funktion, um Hintergrund-Scripte gezielt zu stoppen.
|
||||
|
||||
```bash
|
||||
function killscript() {
|
||||
PATTERN="$1"
|
||||
if [ -z "$PATTERN" ]; then echo "Welches Script?"; return; fi
|
||||
|
||||
# pkill -f sucht im vollen Befehlsnamen
|
||||
pkill -f "$PATTERN" && echo "💀 $PATTERN wurde beendet." || echo "Nichts gefunden."
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🦉 Crystal Owl's Weisheit
|
||||
|
||||
> *"Ein guter Admin schreibt keine Befehle, er komponiert sie."*
|
||||
|
||||
Deine `.bashrc` wächst mit dir. Was heute nützlich ist, fliegt morgen raus. Das ist okay. Es ist dein Werkzeugkasten. Halte ihn sauber, aber habe keine Angst vor neuen Tools.
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Ready
|
||||
**Tags:** #Bash #Config #KernelDance #Syntax
|
||||
|
||||
---
|
||||
|
||||
**Navigation:**
|
||||
[← Zurück: Agent Lockdown](crumbpage-19-agent-lockdown.md) | [Startseite](crumbpages-doktor.sh)
|
||||
73
ssh-agent-guard.sh
Normal file
73
ssh-agent-guard.sh
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
# ~/.local/bin/ssh-agent-guard.sh
|
||||
|
||||
LOG_FILE="$HOME/.ssh-agent-screenlock.log"
|
||||
SOCKET_PATH="$HOME/.ssh/agent.sock"
|
||||
PID_FILE="$HOME/.ssh-agent-watchdog.pid"
|
||||
PAUSE_FILE="$HOME/.ssh-agent-watchdog.pause"
|
||||
|
||||
# 1. Singleton Check: Nur ein Wächter erlaubt
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
old_pid=$(cat "$PID_FILE")
|
||||
kill -0 "$old_pid" 2>/dev/null && kill "$old_pid"
|
||||
fi
|
||||
echo $$ > "$PID_FILE"
|
||||
|
||||
# 2. Cleanup Trap (Aufräumen bei Exit)
|
||||
cleanup() { rm -f "$PID_FILE"; exit 0; }
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"; }
|
||||
|
||||
restart_agent() {
|
||||
# "Deep Work" Check: Darf ich töten?
|
||||
if [ -f "$PAUSE_FILE" ]; then
|
||||
log "SKIP: Deep Work Mode aktiv. Agent überlebt."
|
||||
return
|
||||
fi
|
||||
|
||||
log "🔒 LOCK: Killing Agent..."
|
||||
|
||||
# Kill existing agents
|
||||
if [ -n "$SSH_AGENT_PID" ]; then kill "$SSH_AGENT_PID" 2>/dev/null; fi
|
||||
pkill -u "$USER" ssh-agent
|
||||
|
||||
# Clean Environment
|
||||
unset SSH_AUTH_SOCK SSH_AGENT_PID
|
||||
rm -f "$SOCKET_PATH"
|
||||
|
||||
# Respawn & Bind to fixed socket
|
||||
eval "$(ssh-agent -a "$SOCKET_PATH" -s)" >/dev/null
|
||||
|
||||
# Save Environment for others
|
||||
echo "export SSH_AUTH_SOCK=$SOCKET_PATH" > "$HOME/.ssh/agent-environment"
|
||||
echo "export SSH_AGENT_PID=$SSH_AGENT_PID" >> "$HOME/.ssh/agent-environment"
|
||||
|
||||
log "✨ RESPAWN: Neuer Agent (PID: $SSH_AGENT_PID)"
|
||||
}
|
||||
|
||||
# 3. MATE Hardening: Sofort sperren, keine Grace-Period
|
||||
gsettings set org.mate.screensaver lock-enabled true
|
||||
gsettings set org.mate.screensaver lock-delay 0
|
||||
|
||||
# 4. Der DBus Loop
|
||||
dbus-monitor --session "type='signal',interface='org.mate.ScreenSaver',member='ActiveChanged'" 2>/dev/null |
|
||||
while read -r line; do
|
||||
if echo "$line" | grep -q "boolean true"; then
|
||||
# EVENT: Screen Locked -> Kill Agent
|
||||
mate-screensaver-command --lock 2>/dev/null # Double Tap
|
||||
restart_agent
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### Die Integration
|
||||
|
||||
Damit deine Terminals den neuen Agent immer finden, muss das Environment dynamisch geladen werden.
|
||||
In deiner `.bashrc`:
|
||||
|
||||
```bash
|
||||
# Lade Agent-Info, falls vorhanden
|
||||
if [ -f ~/.ssh/agent-environment ]; then
|
||||
source ~/.ssh/agent-environment
|
||||
fi
|
||||
96
ssh-agent-screenlock_v4.sh
Executable file
96
ssh-agent-screenlock_v4.sh
Executable file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# SSH-Agent Neustart beim Bildschirmschoner (MATE Desktop)
|
||||
# Dieses Script startet den ssh-agent neu, wenn der Bildschirm gesperrt wird
|
||||
#
|
||||
|
||||
# Check for existing instance
|
||||
pid_file="$HOME/.ssh-agent-watchdog.pid"
|
||||
if [ -f "$pid_file" ]; then
|
||||
old_pid=$(cat "$pid_file")
|
||||
if kill -0 "$old_pid" 2>/dev/null; then
|
||||
echo "Watchdog läuft bereits (PID: $old_pid). Beende alte Instanz..."
|
||||
kill "$old_pid"
|
||||
fi
|
||||
fi
|
||||
echo $$ > "$pid_file"
|
||||
|
||||
STOP_LOCK="$HOME/.ssh-agent-watchdog.pause"
|
||||
|
||||
log_message() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
restart_ssh_agent() {
|
||||
# Check if we are "paused" for large transfers
|
||||
if [ -f "$STOP_LOCK" ]; then
|
||||
log_message "SKIP: Bildschirm gesperrt, aber 'Deep Work' Modus aktiv (Pause-File gefunden)."
|
||||
return
|
||||
fi
|
||||
|
||||
log_message "Bildschirm gesperrt - SSH-Agent wird neu gestartet"
|
||||
|
||||
# Alte ssh-agent Prozesse beenden
|
||||
if [ -n "$SSH_AGENT_PID" ]; then
|
||||
kill "$SSH_AGENT_PID" 2>/dev/null
|
||||
log_message "SSH-Agent PID $SSH_AGENT_PID beendet"
|
||||
fi
|
||||
|
||||
# Alle ssh-agent Prozesse des aktuellen Users beenden
|
||||
pkill -u "$USER" ssh-agent
|
||||
|
||||
# SSH-Agent Umgebungsvariablen löschen
|
||||
unset SSH_AUTH_SOCK
|
||||
unset SSH_AGENT_PID
|
||||
|
||||
# Alten Socket entfernen, falls vorhanden
|
||||
rm -f "$SOCKET_PATH"
|
||||
|
||||
# Neuen ssh-agent starten und direkt an fixen Pfad binden
|
||||
# -a: bind address (socket path)
|
||||
eval "$(ssh-agent -a "$SOCKET_PATH" -s)" > /dev/null 2>&1
|
||||
|
||||
# Check if agent started successfully
|
||||
if [ -z "$SSH_AGENT_PID" ]; then
|
||||
log_message "FEHLER: SSH-Agent konnte nicht gestartet werden"
|
||||
return
|
||||
fi
|
||||
|
||||
# Umgebungsvariablen in Datei speichern für andere Terminals
|
||||
# Dateiname angepasst an .bashrc des Users: ~/.ssh/agent-environment
|
||||
cat > "$HOME/.ssh/agent-environment" <<EOF
|
||||
export SSH_AUTH_SOCK=$SOCKET_PATH
|
||||
export SSH_AGENT_PID=$SSH_AGENT_PID
|
||||
EOF
|
||||
|
||||
log_message "Neuer SSH-Agent gestartet (PID: $SSH_AGENT_PID, Socket: $SOCKET_PATH)"
|
||||
}
|
||||
|
||||
# Cleanup bei Script-Ende
|
||||
cleanup() {
|
||||
rm -f "$pid_file"
|
||||
log_message "Watchdog beendet."
|
||||
exit 0
|
||||
}
|
||||
trap cleanup SIGINT SIGTERM
|
||||
|
||||
# Sicherstellen, dass der Bildschirmschoner auch wirklich sperrt
|
||||
gsettings set org.mate.screensaver lock-enabled true 2>/dev/null
|
||||
# Grace-Period abschalten (Sofort sperren)
|
||||
gsettings set org.mate.screensaver lock-delay 0 2>/dev/null
|
||||
log_message "Bildschirm-Sperre erzwungen (lock-enabled true, lock-delay 0)"
|
||||
|
||||
log_message "Watchdog gestartet (PID $$)."
|
||||
|
||||
# Auf MATE Screensaver Events hören
|
||||
dbus-monitor --session "type='signal',interface='org.mate.ScreenSaver',member='ActiveChanged'" 2>/dev/null |
|
||||
while read -r line; do
|
||||
if echo "$line" | grep -q "boolean true"; then
|
||||
# Sofort sperren anfordern, falls noch nicht geschehen
|
||||
mate-screensaver-command --lock 2>/dev/null
|
||||
restart_ssh_agent
|
||||
|
||||
# TODO: Idee - Terminal Hintergrund ändern via DBus (sehr spezifisch für Mate Terminal)
|
||||
# Experimentell: gsettings set org.mate.terminal.profile:/org/mate/terminal/profiles/default/ background-color '#000000'
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user