SSH
SSH
Polycrate bietet native SSH-Integration für schnellen Zugriff auf Hosts aus dem Ansible-Inventory. Diese Integration ermöglicht direkten SSH-Zugriff ohne manuelle Konfiguration.
Voraussetzungen
Die SSH-Integration funktioniert nur, wenn ein inventory.yml im Workspace vorhanden ist. Polycrate ermittelt automatisch:
- SSH-Host-Adresse (
ansible_host) - SSH-Port (
ansible_ssh_port, default: 22) - SSH-User (
ansible_user) - SSH-Schlüssel aus dem Workspace
Verfügbare Hosts anzeigen
Um alle verfügbaren Hosts im Workspace anzuzeigen:
polycrate ssh list
Ausgabe:
Available SSH hosts:
- web-1 (192.168.1.10)
- web-2 (192.168.1.11)
- db-1 (192.168.1.20)
SSH-Verbindung herstellen
Mit Hostname
Um eine SSH-Verbindung zu einem bestimmten Host herzustellen:
polycrate ssh <hostname>
Beispiel:
polycrate ssh web-1
Interaktive Host-Auswahl
Wenn kein Hostname angegeben wird, zeigt Polycrate eine interaktive Auswahl aller verfügbaren Hosts:
polycrate ssh
Ausgabe:
? Select a host to connect to:
👉 web-1 (ubuntu@192.168.1.10:22)
web-2 (ubuntu@192.168.1.11:22)
db-1 (postgres@192.168.1.20:2222)
--------- Host Details ----------
Name: web-1
Host: 192.168.1.10
User: ubuntu
- Mit Pfeiltasten durch die Hosts navigieren
- Mit Enter die Verbindung herstellen
- Mit Ctrl+C abbrechen
Tab-Completion
Polycrate unterstützt Shell-Autocompletion für den SSH-Befehl. Mit Tab werden alle verfügbaren Hosts angezeigt:
polycrate ssh <TAB>
# Zeigt: web-1 web-2 db-1
Siehe Shell-Autocompletion für die Einrichtung.
Polycrate:
1. Liest das Ansible-Inventory
2. Ermittelt automatisch die Verbindungsinformationen
3. Nutzt den SSH-Schlüssel aus dem Workspace (id_rsa)
4. Stellt die direkte SSH-Verbindung her
Beispiel-Workflow
1. Inventory erstellen
Polycrate unterstützt beide gängigen Ansible-Inventory-Muster:
Muster 1: Variablen pro Host
# inventory.yml im Workspace
all:
hosts:
web-1:
ansible_host: 192.168.1.10
ansible_user: ubuntu
ansible_ssh_port: 22
web-2:
ansible_host: 192.168.1.11
ansible_user: ubuntu
db-1:
ansible_host: 192.168.1.20
ansible_user: postgres
ansible_ssh_port: 2222
Muster 2: Variablen in all.vars (ab 0.30.4)
Gemeinsame Variablen können zentral unter all.vars definiert und an alle Hosts vererbt werden – Ansible-konform. Host-Level-Werte überschreiben die Gruppenvariablen.
# inventory.yml – Variablen in all.vars
all:
vars:
ansible_user: sysops
ansible_ssh_port: 4422
hosts:
cr1:
ansible_host: 10.10.10.101
cr2:
ansible_host: 10.10.10.102
# → polycrate ssh cr1 nutzt sysops@10.10.10.101:4422
2. Verfügbare Hosts anzeigen
polycrate ssh list
3. Verbindung herstellen
polycrate ssh web-1
Ad-hoc Befehle ausführen
Mit polycrate ssh exec wird ein einzelner Befehl non-interaktiv auf einem Remote-Host ausgeführt — ohne eine vollständige Shell-Session zu öffnen. Stdout und Stderr werden direkt auf das lokale Terminal gestreamt; der Exit-Code des Remote-Befehls wird als lokaler Exit-Code propagiert.
polycrate ssh exec <hostname> <befehl...>
Beispiele
# Systemstatus prüfen
polycrate ssh exec web-1 systemctl status nginx
# Disk-Nutzung abfragen
polycrate ssh exec db-1 df -h
# Mehrteiliger Befehl (Shell-Interpreter auf dem Remote-Host)
polycrate ssh exec web-1 -- bash -c "df -h && free -m"
# Prozessliste filtern
polycrate ssh exec web-1 ps aux | grep nginx
Limitierungen
- Kein interaktiver Stdin (kein Pseudo-TTY) — für interaktive Sessions weiterhin
polycrate ssh <hostname>verwenden - Shell-Expansion (Wildcards, Pipes) wird lokal interpretiert; für Remote-Expansion
-- bash -c "..."nutzen
Port-Forwarding Tunnel
Mit polycrate ssh tunnel wird ein SSH Local-Port-Forward aufgebaut. Damit sind Dienste erreichbar, die nur auf dem Remote-Host selbst lauschen — ohne VPN und ohne manuelle ssh -L-Kommandos.
polycrate ssh tunnel <hostname> <lokaler-port>:<remote-host>:<remote-port>
Der Tunnel läuft im Vordergrund und blockiert das Terminal. CTRL+C beendet ihn sauber — der lokale Port wird sofort freigegeben.
Beispiele
# PostgreSQL-Datenbank lokal erreichbar machen
polycrate ssh tunnel db-1 5432:localhost:5432
# → psql -h localhost -p 5432 -U myuser mydb
# Web-UI über Browser erreichbar machen
polycrate ssh tunnel web-1 8080:localhost:80
# → http://localhost:8080
# Dienst im internen Netz via Node als Sprungbrett
polycrate ssh tunnel web-1 6379:10.0.0.5:6379
# → redis-cli -p 6379
Typischer Workflow
# Terminal 1: Tunnel offen halten
polycrate ssh tunnel db-1 5432:localhost:5432
# Terminal 2: Tool gegen localhost verbinden
psql -h localhost -p 5432 -U postgres
Limitierungen
- Nur Local-Forwarding (
-L) — kein Remote- oder Dynamic-Forwarding - Kein Background-Modus — der Prozess blockiert bewusst das Terminal für volle Kontrolle über Lebensdauer
Dateien kopieren
Mit polycrate ssh copy werden Dateien zwischen dem lokalen Rechner und einem Host aus dem Inventory übertragen. Polycrate löst Verbindungsparameter, Key und Port automatisch aus dem Inventory auf — kein manuelles scp mit Key-Pfad nötig.
polycrate ssh copy <quelle> <ziel>
Genau eines der beiden Argumente muss einen Hostnamen aus dem Inventory enthalten, im Format hostname:/pfad.
# Datei vom Remote-Host herunterladen
polycrate ssh copy web-1:/var/log/nginx/access.log ./
# Datei auf den Remote-Host hochladen
polycrate ssh copy ./deploy.sh web-1:/tmp/
# Verzeichnis rekursiv kopieren (-r / --recursive)
polycrate ssh copy -r web-1:/etc/nginx/ ./nginx-backup/
polycrate ssh copy -r ./configs/ web-1:/etc/myapp/
Flags
| Flag | Kurz | Beschreibung |
|---|---|---|
--recursive |
-r |
Verzeichnisse rekursiv kopieren |
--block |
Block für Inventory-Lookup (optional) | |
--workspace |
-w |
Workspace-Pfad |
Limitierungen
- Remote-zu-Remote-Kopie (zwei Hostnamen) wird nicht unterstützt
- Genau eines der Argumente muss einen Hostnamen aus dem Inventory enthalten; lokale Pfade mit
:im Namen sind nicht unterstützt
Verwendung
Direkter Zugriff für Debugging
# Interaktive Shell-Session
polycrate ssh web-1
# Einzelnen Befehl ausführen (non-interaktiv)
polycrate ssh exec web-1 systemctl status nginx
polycrate ssh exec web-1 tail -n 50 /var/log/application.log
Nach Ansible-Deployment
# 1. Server mit Ansible konfigurieren
polycrate run webservers configure
# 2. Einzelne Checks non-interaktiv
polycrate ssh exec web-1 systemctl is-active nginx
# 3. Bei Bedarf interaktive Session für manuelle Inspektion
polycrate ssh web-1
Datenbank-Zugriff via Tunnel
# Tunnel im Hintergrund-Terminal
polycrate ssh tunnel db-1 5432:localhost:5432
# Im anderen Terminal: lokale Tools gegen localhost
psql -h localhost -p 5432 -U postgres
Shell-Autocompletion
Polycrate unterstützt Tab-Completion für alle Commands, einschließlich dynamischer Host-Completion für polycrate ssh.
Zsh
# Einmalig aktivieren
source <(polycrate completion zsh)
# Permanent in ~/.zshrc
echo 'source <(polycrate completion zsh)' >> ~/.zshrc
Bash
# Einmalig aktivieren
source <(polycrate completion bash)
# Permanent in ~/.bashrc
echo 'source <(polycrate completion bash)' >> ~/.bashrc
Fish
polycrate completion fish > ~/.config/fish/completions/polycrate.fish
Nach der Aktivierung:
polycrate ssh <TAB>
# Zeigt alle verfügbaren Hosts aus dem Inventory
polycrate ssh web<TAB>
# Vervollständigt zu passenden Hosts (z.B. web-1, web-2)
SSH Passphrase Support
Polycrate unterstützt SSH-Keys mit Passphrase über einen integrierten ssh-agent.
Aktivierung
# Beim Workspace-Init
polycrate --ssh-use-passphrase workspace init
# Bei Action-Ausführung
polycrate --ssh-use-passphrase run my-block deploy
# Für alle Commands
polycrate --ssh-use-passphrase ssh web-1
Passphrase-Quellen (Priorität)
| Priorität | Quelle | Beschreibung |
|---|---|---|
| 1 | ssh-passphrase.poly |
Datei im Workspace-Root |
| 2 | Interaktiver Prompt | Manuelle Eingabe |
ssh-passphrase.poly:
# Passphrase in Datei speichern (optional)
echo "meine-passphrase" > ssh-passphrase.poly
# Berechtigungen setzen
chmod 600 ssh-passphrase.poly
Funktionsweise
Polycrate startet automatisch einen ssh-agent, lädt den Workspace-Key mit der Passphrase und gibt den Agent-Socket an den jeweiligen SSH-Prozess weiter. Wie das konkret aussieht, hängt davon ab, ob es sich um eine direkte SSH-Operation oder eine Container-basierte Action handelt:
Direkte SSH-Operationen (polycrate ssh, ssh exec, ssh tunnel, ssh copy):
- Polycrate startet einen
ssh-agent - Der SSH-Key wird mit der Passphrase geladen
- Der Agent-Socket wird als
SSH_AUTH_SOCK-Umgebungsvariable an den lokalenssh/scp-Prozess übergeben — kein Docker-Container, kein Mount erforderlich
graph LR
Polycrate[Polycrate CLI] -->|1. Agent starten| Agent[ssh-agent]
Polycrate -->|2. Key laden| Agent
Agent -->|3. SSH_AUTH_SOCK| SSH[ssh / scp]
SSH -->|4. Verbinden| Host[Remote Host]
Container-basierte Actions (polycrate run):
- Polycrate startet einen
ssh-agent - Der SSH-Key wird mit der Passphrase geladen
- Der Agent-Socket wird in den Docker-Container gemountet (erfordert
--ssh-agent-mountoderconfig.sshagentmount: true) - Ansible im Container nutzt den gemounteten Agent
graph LR
Polycrate[Polycrate CLI] -->|1. Agent starten| Agent[ssh-agent]
Polycrate -->|2. Key laden| Agent
Agent -->|3. Socket-Mount| Container[Docker Container]
Container -->|4. SSH-Auth| Ansible[Ansible]
Ansible -->|5. Verbinden| Host[Remote Host]
Troubleshooting
"Permission denied (publickey)":
# Prüfen ob Agent läuft
ssh-add -l
# Key manuell zum Agent hinzufügen
ssh-add artifacts/secrets/id_rsa
# Dann erneut versuchen
polycrate --ssh-use-passphrase run my-block deploy
"Agent refused connection":
# Agent-Socket prüfen
echo $SSH_AUTH_SOCK
# Polycrate mit neuem Agent starten
polycrate --ssh-use-passphrase run my-block deploy
SSH-Agent-Socket-Mount
Ab Polycrate CLI 0.37.0 ist der Mount des Host-SSH-Agent-Sockets (SSH_AUTH_SOCK) in Polycrate-Container per Default deaktiviert. Wer Schlüssel aus einem laufenden ssh-agent verwenden möchte – z. B. für Passphrase-geschützte Keys oder FIDO/U2F-Hardware-Keys – muss den Mount explizit aktivieren.
Warum die Änderung?
- Sicherheit: Der Agent-Socket gibt Container Vollzugriff auf alle im Agent geladenen Keys. Für die meisten Polycrate-Runs (Workspace-Key ohne Passphrase) ist das nicht nötig.
- Portabilität: Auf Systemen ohne laufenden Agent (CI, Fresh-Checkouts) schlug der implizite Mount mit Socket-Fehlern fehl. Opt-in verhindert das.
- macOS/OrbStack: Non-Root-Container auf macOS konnten den nativen Agent-Socket nicht zuverlässig nutzen. Opt-in macht Probleme sichtbar statt stillschweigend zu failen.
Mount aktivieren
CLI-Flag (ad-hoc):
polycrate --ssh-agent-mount run my-block install
polycrate --ssh-use-passphrase --ssh-agent-mount run my-block deploy
Workspace-dauerhaft (workspace.poly):
name: my-workspace
config:
sshagentmount: true
User-global (~/.polycrate/polycrate.yml):
config:
sshagentmount: true
Gilt dann für alle Workspaces, sofern nicht im Workspace überschrieben.
Wann wird der Agent automatisch gemountet?
Auch ohne --ssh-agent-mount mountet Polycrate den Agent in zwei Szenarien automatisch:
| Szenario | Verhalten |
|---|---|
--ssh-use-passphrase mit Workspace-Key |
Interner Agent (Polycrate-gestartet) wird gemountet |
config.sshkeysource: user + laufender Host-Agent |
Host-Agent wird gemountet |
In beiden Fällen ist der Mount zweckgebunden und sicher: ohne diese Flags wird der Socket nicht exponiert.
Migration von ≤0.36.x
Wer unter 0.36.x auf den impliziten Mount gesetzt hat (typisch: gemischte Host-/Workspace-Keys, FIDO-Sticks), trägt einmalig ein:
# workspace.poly
config:
sshagentmount: true
Alternativ pro Run --ssh-agent-mount. Ein Downgrade-Hinweis erscheint nicht – das alte Verhalten ist schlicht nicht mehr Default.
SSH-Schlüssel-Quelle (sshkeysource)
Standardmäßig nutzt Polycrate den Workspace-Key (artifacts/secrets/id_rsa). Mit config.sshkeysource: user können Sie stattdessen Ihren persönlichen SSH-Key verwenden – ideal für einheitliche User-Authentifizierung und Nutzung des ssh-agent.
Aktivierung
# workspace.poly
config:
sshkeysource: user # workspace (Standard) | user
Verhalten bei user
| Bedingung | Verhalten |
|---|---|
Host ssh-agent läuft (SSH_AUTH_SOCK) |
Agent wird in den Container gemountet (automatisch bei sshkeysource: user, unabhängig von config.sshagentmount) – Ansible nutzt die Keys im Agent |
| Kein Agent | ~/.ssh wird gemountet, Key-Datei wird verwendet |
User-Key-Pfad konfigurieren
Der Pfad zum persönlichen Key wird in ~/.polycrate/polycrate.yml festgelegt (nicht im Workspace, da nutzerspezifisch):
# ~/.polycrate/polycrate.yml
ssh:
user_key_path: "~/.ssh/work_ed25519" # optional; Standard: ~/.ssh/id_rsa
user_key_path_by_workspace: # optional; workspace.name → Key-Pfad
laser24: "~/.ssh/laser_ed25519"
archenemy: "~/.ssh/ayedo_work"
Ansible become/sudo Passwort
Für Ansible-Tasks, die become: yes (sudo) verwenden, können Sie vor der Action-Ausführung interaktiv das Passwort abfragen lassen:
polycrate run my-block install --ask-become-pass
# oder kurz:
polycrate run my-block install -K
Der Prompt erscheint vor dem Container-Start. Das Passwort wird als ANSIBLE_BECOME_PASSWORD an Ansible übergeben und nicht im Snapshot oder in Logs gespeichert.
Hinweise
- SSH-Schlüssel: Polycrate nutzt standardmäßig
id_rsaaus dem Workspace-Root oderartifacts/secrets/id_rsa; beisshkeysource: userden persönlichen Key - Port: Standard ist Port 22, kann aber per
ansible_ssh_portim Inventory überschrieben werden - User: Wird aus
ansible_userim Inventory gelesen (Standard:root) - Tunnel: Kein ControlMaster/ControlPersist — der lokale Port wird sofort beim Beenden freigegeben
execundcopy: Gleiche Key- und Agent-Logik wie die interaktive Session; kein zusätzliches Setup nötig
Übersicht aller SSH-Commands
| Command | Beschreibung |
|---|---|
polycrate ssh [hostname] |
Interaktive Shell-Session (TUI-Auswahl wenn kein Hostname) |
polycrate ssh list |
Alle Hosts aus dem Inventory auflisten |
polycrate ssh exec <host> <cmd...> |
Ad-hoc Befehl non-interaktiv ausführen |
polycrate ssh tunnel <host> <lp>:<rh>:<rp> |
SSH Local-Port-Forward aufbauen |
polycrate ssh copy <quelle> <ziel> |
Dateien zu/von einem Host kopieren |