Tmux, bastion, ssh a agent-forwarding
Tmux
Tmux je terminálový multiplexer pro Unix, který umožňuje vytvořit více pseudoterminálů v jednom přihlášeném okně (terminálu). Tmux je vhodný pro uživatele, kteří stráví více času v terminálovém okně a využijí více současně otevřených obrazovek. Toto umožňují i ssh klienti s podporou záložek (tabs), např. Bitvise SSH client či Solar-Putty. Tmux obvykle běží na serveru, kde uživatel otevře více obrazovek pro aplikace a spojení na další servery. Uživatel se může od serveru odpojit aniž by spuštěné aplikace skončily, časově náročné akce dál pokračují. K otevřeným obrazovkách se lze poté připojit i z jiného počítače.
Více informací:
Tmux a ssh
Z notebooku se přihlásíte pomocí ssh na server (bastion), zde spustíte tmux a z něho děláte ssh spojení na další servery.
Na notebooku máte privátní klíč v agentovi (pageant, ssh-agent), na další servery se chcete hlásit také pomocí klíče. Máte dvě možnosti:
- na bastionu máte uložen privátní klíč pro přihlášení na další servery,
- privátní klíč máte na notebooku a ve spojení na bastion máte zapnut ssh agent forwarding - pokud je na bastionu požadavek na operaci s privátním klíčem, tak se přepošle na agentovi na notebooku.
Obě řešení předpokládají, že plně důvěřujete správci bastionu. Starší, ale stále platný popis pro ssh agent forwarding je v článku Security Issues With Key Agents .
Na bastion se nehlaste jako root - pod tímto uživatelem byste nikdy neměli spouštět tmux či mít pod ním aktivní ssh agent forwarding.
Privátní klíč na bastionu
S privátním klíčem na bastionu je potřeba zajistit, aby na každé obrazovce v aplikaci tmux byl odkaz na stejnou instanci ssh-agent, aby se nespustili dvě instance ssh-agent. Nejjednodušším řešením je využít aplikaci keychain, konkrétně do .bashrc
v domovském adresáři doplnit řádek s odkazem na dostupný klíč, např.:
eval $(keychain --quick --eval id_ed25519)
Při přihlášení se zobrazí dotaz na heslo k privátnímu klíči.
Privátní klíč na bastionu by měl být odlišný od privátního klíče na notebooku. Nezapomeňte, že musíte zajistit bezpečné zálohování obou privátních klíčů (na notebooku a na bastionu).
Ssh agent forwarding
Agent forwarding se musí zapnout před vytvořením spojení. V PuTTY nejlépe nadefinovat a uložit příslušné sezení (session): Na MacOS či Unixu nadefinovat v .ssh/config
Host bastion ForwardAgent yes UpdateHostKeys yes
Unixové aplikace komunikují s agentem přes socket, na který odkazuje proměnná SSH_AUTH_SOCK
. Pokud je povolen agent forwarding, tak součástí připojení na bastion je vytvoření speciálního socketu, odkaz na něj uloží do proměnné (pokaždé jiný socket):
SSH_AUTH_SOCK=/tmp/ssh-XXXX9eHVSY/agent.15123
Z bastionu se poté můžete hlásit na další servery pomocí privátního klíče na notebooku, na bastionu můžete podepsat commit pro git, pomocí ssh můžete komunikovat s git serverem.
Tmux, agent forwarding a obnovení spojení
SSH spojení pomocí agent forwarding lze používat i z tmux - na bastionu vytvoříte novou obrazovku, z ní se připojíte na server.
Na problémy narazíte v situaci, kdy začnete využívat možnost odpojení se od terminálu a nového připojení k němu. Při vytvoření nového ssh spojení na bastion se vytvoří nový socket, ale již vytvořené obrazovky v tmux mají nastavenu proměnnou SSH_AUTH_SOCK
na socket z předchozího spojení - nepřihlásíte se na jiný server. Jednoduché ale nepohodlné řešení je ukončit obrazovky (tmux) a znovu ho spustit.
Jiné řešení je do souboru .bashrc v domovského adresáři vložit následující řádky:
function prompt_command() { if [ -n "${TMUX}" ]; then eval "$(tmux show-environment -s)" fi } PROMPT_COMMAND=prompt_command
Příkaz tmux show-environment -s
vypíše vybrané proměnné, které se nastavily při spojení, mezi nimi i SSH_AUTH_SOCK
. eval znamená, že se proměnné mají nastavit.
Při opětovném připojení jsou již nějaké obrazovky vytvořeny, v nich je spuštěn bash. Speciální proměnná PROMPT_COMMAND
obsahuje odkaz na funkci, která se má provést při zobrazení promptu. V .bashrc
do ní nastavíme námi nadefinovanou funkci prompt_command
. Tj. v existujících oknech se aktualizuje proměnná SSH_AUTH_SOCK
, stačí stisknout klávesu enter. A nastaví se i při vytvoření nové obrazovky v tmu.
Další informace:
Git na jiném serveru
Z bastionu se hlásíte na server vyvoj a na něm chcete používat git - komunikovat přes ssh s úložištěm, podepisovat commity pomocí svého ssh klíče. Aplikace git umí používat ssh-agent včetně agent forwarding.
Máte následující možná řešení:
- další privátní klíč na serveru vyvoj
- použít ssh agent forwarding a přesměrovat na privátní klíč na bastionu
- použít ssh agent forwarding a přesměrovat požadavky na privátní klíč na notebooku (řetězení agent forwarding)
Všechny varianty předpokládají, že důvěřujete administrátorovi na serveru vyvoj.
První varianta zvyšuje problémy se správou rozrůstajícího se počtu klíčů, s jejich zálohováním.
Ve druhé i ve třetí variantě je potřeba na bastionu nastavit agent forwarding v konfiguračním souboru .ssh/config
, např.:
Host vyvoj ForwardAgent yes
Ve třetí variantě je potřeba ještě zajistit přepnutí na nový socket pro již otevřené spojení. Tj. pro situaci:
- přihlásíte se na bastion, z bastionu se v tmux přihlásíte na server vyvoj,
- ukončíte spojení na bastion, spojení z bastionu na server vyvoj zůstává aktivní,
- znovu se připojíte na bastion, vytvoří se nový socket,
- přepnete se na obrazovku se spojením na server vyvoj a zde zadáte příkaz git. Program ssh zajišťující spojení mezi bastionem a serverem vyvoj neví o tom, že se na bastionu změnil socket, přes který má požádat o operaci s privátním klíčem umístěném na notebooku.
V článku SSH agent forwarding and tmux done right jsou popsány problémy. Autor nabízí i možné řešení - aplikaci ssh-agent-switcher.
Řešení pomoc ssh-agent-switcher není dostatečně stabilní např. v situaci, kdy pomocí ansible chci udělat úpravu na 100 serverech - často ssh agent přestane ansible odpovídat po několika desítkách serverů. Mohu killnout příslušné ssh procesy, poté se připojí na další servery.
Změna titulku okna v tmux pro ssh
Když zadám v tmux příkaz
ssh abcdef.vse.cz
tak bych uvítal, aby se titulek obrazovky v tmux přejmenoval na abcdef.vse.cz či abcdef.
Nenašel jsem správné řešení. Základem by mohla být úprava popsaná v článku Auto tmux ssh hostname window title that actually works. Jenže nefunguje pro ssh s parametry, např.:
ssh -l test99 bis.vse.cz
Bylo by potřeba parsovat parametry příkazu ssh.