Mosh: trochu jiné SSH

23. 4. 2012
Doba čtení: 7 minut

Sdílet

 Autor: Depositphotos
Už jste někdy používali SSH na GPRS spojení, nebo saturované ADSL lince? Pokud ano, jistě budete souhlasit, že práce po takovém spojení není nic příjemného. Program mosh dokáže nabídnout mobilní připojení ke vzdálenému shellu s výrazně lepším uživatelským zážitkem. Nezastaví se ani, když změníte IP adresu.

Rychlá instalace, neboli TL;DR

  1. Nainstalujte na server i klienta balík mosh
  2. Ujistěte se, že máte SSH přístup na server a nic nebrání provozu na UDP porty z rozsahu 60000 – 61000.
  3. Spojení zahajte zadáním mosh server.example.cz

K čemu další protokol?

Protokol SSH slouží k vzdálenému připojení k terminálu velmi dobře. Při intenzivním používání však uživatel obvykle narazí na jisté nepříjemné vlastnosti, které jsou dány přímo architekturou protokolu a není snadné je opravit:

  • Citlivost na ztrátu paketů. SSH používá transportní protokol TCP, který zajišťuje opakování vysílání v případě ztráty paketu. Ovšem k opakování dojde až v případě, kdy vyprší timeout (často delší než sekunda), nebo bude přijato negativní potvrzení (NACK). Protože se v SSH relaci obvykle přenáší málo dat, na NACK nedojde a i samotný výpadek jednoho paketu dokáže práci na chvíli znepříjemnit.
  • Nemožnost mobility, spánku. Z principu není možné na běžícím spojení změnit IP adresu klienta, například při přechodu z mobilní sítě na WiFi či zpět. Stejně tak ocitne-li se klient bez připojení, nebo se uspí, TCP a tedy i SSH spojení se velmi pravděpodobně rozpadne.
  • Editace příkazového řádku vzdáleným systémem. Je-li SSH použito pro terminálový přístup uživatele ke vzdálenému systému, většinu času uživatel stráví zadáváním a editací příkazového řádku. Ačkoli taková činnost teoreticky nevyžaduje součinnost serveru (v protokolu TELNET dokonce existovala možnost LOCAL ECHO, umožňující tisknout poslané znaky místně), při použití SSH se každý zapsaný znak odesílá na server a zpět obvykle putuje žádost o vytištění stejného znaku. Na linkách s velkým zpožděním a/nebo ztrátovostí je zadávání příkazů utrpení, zvlášť pro lidi, kteří neovládají bravurně počítačovou klávesnici.

Z nástinu problému již mnozí jistě pochopili, kudy se ubírá inovace v programu mosh. Především jde o použití nového protokolu State Synchronization Protocol, postaveného nad transportním protokolem UDP. Ten dokáže po síti synchronizovat stav abstraktních objektů. V programu běží dvě instance tohoto protokolu, jedna synchronizuje stav klávesnice klienta na server, druhá stav displeje serveru na klienta.

Všechny pakety jsou šifrovány 128bitovou symetrickou šifrou AES128-OCB, která zajišťuje i autenticitu přenášených dat. Pakety jsou číslovány a server své odpovědi posílá vždy na tu adresu a port, ze které přišel autentický paket s nejvyšším číslem. Tím je elegantně vyřešena mobilita klienta, který ani nemusí vědět o tom, že změnil adresu (například v autobusu, který za jízdy střídá mobilní operátory).

K řešení problému editace příkazového řádku vyvinuli autoři prediktivní model, kterému říkají intelligent local echo. Model předpokládá, že stisknutí alfanumerické klávesy vyvolá vytištění znaku a posun kurzoru, stisknutí backspace smazání znaku nalevo od kurzoru, a podobně. Po každém stisknutí Enteru a podobných akčních kláves prediktivní model nejprve ověří, zda se v daný okamžik chová server podle předpokladu.

První znak tedy odešle na server a pozoruje, jak se server zachová. Pokud ze serveru přijde příkaz: „Vytisknout znak a posunout kurzor vpravo“, je to důkaz, že model funguje a další editace řádku až do stisknutí akční klávesy může probíhat lokálně, na klientovi. Protokol SSP však stále běží, takže v případě, že se model náhodou splete, ale síť funguje, ani si chyby modelu nevšimnete, protože je ihned opravena aktualizací stavu ze serveru. Je-li výpadek spojení delší, mosh zvýrazňuje predikované znaky podtržením, jak je vidět na screenshotu z domovské stránky projektu:

Díky popsané inteligenci místní odezvy tato nepředstavuje problém ani při zadávání hesla (kde je nežádoucí, aby se zadané znaky tiskly), nebo při používání programů jako je vi, kde v příkazovém režimu alfanumerické znaky slouží k ovládání editoru a netisknou se.

Žádný démon, žádný privilegovaný kód

Dalším zajímavým aspektem programu je skutečnost, že veškerý kód klienta i serveru vystačí s oprávněními uživatele. Na straně serveru neběží žádný démon, který by poslouchal na pevně daném portu a autentizoval přihlašující se uživatele. Uživatel na serveru pouze spustí program mosh-server. Ten začne poslouchat na UDP portu v rozsahu 60000 – 61000. Na konzoli vypíše číslo portu a šifrovací klíč:

$ mosh-server

MOSH CONNECT 60001 bcpSwDC5xEkF3zfS9K9qFA

mosh-server (mosh 1.1.3)
Copyright 2012 Keith Winstein <mosh-devel@mit.edu>
License GPLv3+: GNU GPL version 3 or later .
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

[mosh-server detached, pid = 13842]

Pak je možné kdekoli spustit klienta mosh-client, předat mu adresu a port, na kterém server poslouchá a prostřednictvím proměnné prostředí MOSH_KEY také šifrovací klíč:

MOSH_KEY="bcpSwDC5xEkF3zfS9K9qFA" mosh-client ip.ad.re.sa 60001

Samozřejmě, že v běžné praxi by bylo takovéto spouštění krajně nepraktické, už jen kvůli tomu, že abychom získali přístup ke vzdálenému systému, musíme na něm nejprve spustit server, tedy k němu získat přístup. Problém slepice a vejce má přitom poměrně snadné řešení – ke spuštění serveru se použije starý dobrý protokol SSH. Ten také řeší veškerou autentizaci uživatele, takže mosh se může soustředit pouze na svůj hlavní účel. K tomuto spuštění se používá perlovský skript mosh. Jeho postup je poměrně zajímavý a dovolím si jej rozvést blíže.

Zjednodušený průběh navazování spojení skriptem mosh.

Skript samotný se nejprve rozdělí na dva procesy – rodiče a dítě. Dítě spustí příkazem SSH na vzdálené straně mosh-server. Ovšem pomocí direktivy ProxyCommand (I o této direktivě jsme psali v článku Zavádíme omezení v OpenSSH.) je SSH klient přinucen navázat spojení zavoláním stejného perlovského skriptu mosh s přepínačem --fake-proxy. Skript se při přijetí takového přepínače začne chovat jako netcat, takže transparentně přeposílá SSH komunikaci, mimo to ale na začátku vypíše na svůj chybový výstup IP adresu, ke které se připojuje. To proto, aby druhý proces skriptu měl možnost zjistit adresu, na kterou se SSH spojení navazuje, a navázat na stejnou adresu UDP spojení.

Jak již víme, server spuštěný na vzdálené straně vypíše číslo portu a přejde na pozadí. Tím se SSH spojení ukončí. Druhý proces původního skriptu mosh přečte výpis dětského procesu a vyparsuje z něj IP adresu, číslo portu a šifrovací klíč serveru. Tyto parametry předá klientovi, který na jejich základě naváže spojení se serverem.

Možné problémy

Jediný zásadní problém, který může při zprovozňování programu nastat, je nedostupnost UDP spojení na server. Je-li server za firewallem/NATem, je třeba otevřít/přesměrovat spojení alespoň na jeden UDP port a tento pak vyžádat přepínačem -p skriptu  mosh.

Není-li se serverem navázáno spojení do minuty po jeho spuštění (třeba kvůli problému s firewallem), server se ukončí. Jakmile však server obdrží první paket od klienta, považuje spojení za navázané a neukončí jej ani v případě, že se klient odmlčí. O skončení sezení musí požádat klient. Na to je třeba myslet v případě, kdy například počítač s klientem ztratí napájení. Server v takovém případě zůstane viset a čeká, zda se klient ještě někdy nepřipojí (což je vyloučeno, vzhledem k tomu, že šifrovací klíč je beznadějně zapomenut). Mosh tedy nesupluje funkci terminálových multiplexorů jako screen nebo tmux. Ty je stále potřeba používat, chceme-li jistotu, že o relaci náhodně nepřijdeme.

Vzhledem k tomu, že mosh pracuje s terminálem inteligentně, musí na straně serveru emulovat jeho chování. Autoři rezignovali na snahu emulovat všechny možné typy terminálů, jako to dělá například screen, namísto toho stanovili požadavek, že obě strany spojení musí používat UTF-8, jinak se program odmítne spustit. Vychloubají se však, že implementace UTF-8 v programu mosh je lepší než ve většině emulátorů terminálu. Takže se například nedočkáte hieroglyfického fontu, pokud omylem vypíšete binární soubor.

Mosh také dosud nepodporuje IPv6, byť autoři slibují, že tato podpora bude brzy doplněna. Drobný problém taky představuje připojení na server, kde běží SSH na nestandardním portu. Ten není možné nastavit na příkazovém řádku, ale je možné jej nastavit v konfiguračním souboru SSH klienta. V každém případě je také možné spustit si server i klient ručně.

ict ve školství 24

Závěr

Mosh je rozhodně zajímavý projekt, řešící problém, který v současnosti není příliš častý. Na druhou stranu, v právě nastupující post PC éře začíná být připojování z nevýkonných kapesních zařízení po nekvalitní mobilní síti stále častějším fenoménem. Proto doufám, že se v dohledné době objeví i varianta klienta pro Android, která je plánována. Teprve u té se ukáže pravá výhoda mobilního shellu.

(Za tip děkuji Radomíru Orkáčovi.)

Autor článku

Ondřej Caletka vystudoval obor Telekomunikační technika na ČVUT a dnes pracuje ve vzdělávacím oddělení RIPE NCC, mezinárodní asociaci koordinující internetové sítě.