Zum Inhalt

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

Schnelle Navigation

Die interaktive Auswahl zeigt bis zu 10 Hosts gleichzeitig an. Bei vielen Hosts können Sie mit den Pfeiltasten scrollen.

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

Tab-Completion

Auch bei ssh exec wird der Hostname per Tab-Completion aus dem Inventory vervollständigt.

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

TCP-Forwarding auf dem Server erforderlich

Der SSH-Daemon auf dem Ziel-Node muss TCP-Forwarding erlauben. Falls der Tunnel mit administratively prohibited scheitert, muss in der /etc/ssh/sshd_config des Nodes folgendes gesetzt sein:

AllowTcpForwarding yes
Danach: systemctl reload sshd

  • 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

Keine zusätzlichen Abhängigkeiten

polycrate ssh copy nutzt scp, das Bestandteil jeder OpenSSH-Installation ist — derselbe Paketumfang wie ssh. Auf der Remote-Seite wird das eingebaute sftp-server-Subsystem verwendet; kein separates scp-Binary auf dem Ziel-Host erforderlich.

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)

Workspace erforderlich

Die Host-Completion funktioniert nur in einem gültigen Polycrate-Workspace mit inventory.yml.

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

Sicherheitshinweis

Die Datei ssh-passphrase.poly sollte niemals in Git committet werden! Bei verschlüsselten Workspaces können Sie die Passphrase in artifacts/secrets/ssh-passphrase.poly speichern.

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):

  1. Polycrate startet einen ssh-agent
  2. Der SSH-Key wird mit der Passphrase geladen
  3. Der Agent-Socket wird als SSH_AUTH_SOCK-Umgebungsvariable an den lokalen ssh/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):

  1. Polycrate startet einen ssh-agent
  2. Der SSH-Key wird mit der Passphrase geladen
  3. Der Agent-Socket wird in den Docker-Container gemountet (erfordert --ssh-agent-mount oder config.sshagentmount: true)
  4. 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]

Breaking Change ab CLI 0.37.0: SSH-Agent-Mount ist opt-in

Bis Polycrate CLI 0.36.x wurde der SSH-Agent-Socket des Hosts automatisch in jeden Container gemountet, sobald SSH_AUTH_SOCK gesetzt war. Ab CLI 0.37.0 ist dieses Verhalten invertiert: der Mount erfolgt nur noch auf expliziten Opt-in. Gilt ausschließlich für Container-basierte Actions (polycrate run), nicht für direkte SSH-Operationen. Siehe Abschnitt SSH-Agent-Socket-Mount weiter unten.

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

Nur für Container-Actions relevant

--ssh-agent-mount hat ausschließlich Wirkung bei polycrate run (Ansible-Container). Für direkte SSH-Operationen (polycrate ssh, exec, tunnel, copy) ist der Flag wirkungslos — dort wird der Agent-Socket direkt als Umgebungsvariable an den lokalen SSH-Prozess übergeben, ohne Container-Mount.

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

ssh-agent empfehlenswert

Ohne laufenden Agent wird ~/.ssh gemountet. Für Passphrase-Keys und bessere Performance empfehlen wir: eval $(ssh-agent) und ssh-add ~/.ssh/id_rsa vor der Verwendung.

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"

CLI-Konfiguration


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.

Empfohlen bei sudo

Nutzen Sie -K oder --ask-become-pass, wenn Ihr Ansible-Playbook become: yes verwendet und Sie das sudo-Passwort nicht im Inventory ablegen wollen.


Hinweise

  • SSH-Schlüssel: Polycrate nutzt standardmäßig id_rsa aus dem Workspace-Root oder artifacts/secrets/id_rsa; bei sshkeysource: user den persönlichen Key
  • Port: Standard ist Port 22, kann aber per ansible_ssh_port im Inventory überschrieben werden
  • User: Wird aus ansible_user im Inventory gelesen (Standard: root)
  • Tunnel: Kein ControlMaster/ControlPersist — der lokale Port wird sofort beim Beenden freigegeben
  • exec und copy: Gleiche Key- und Agent-Logik wie die interaktive Session; kein zusätzliches Setup nötig

Schneller Zugriff

Mit polycrate ssh (interaktive Auswahl) oder polycrate ssh <TAB> (Autocompletion) haben Sie blitzschnellen Zugriff auf alle Server!

Ü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

Siehe auch