Začarované porty 80 a 443
Určitě se vám už nejednou stalo, že jste přišli do sítě, ve které příliš horlivý správce zakázal všechny porty kromě 80 a 443. Typicky se to stává třeba v hotelích. Běžnému uživateli „internet funguje“, takže nemá důvod se zlobit. Pokud ale chcete použít třeba SSH, Jabber nebo OpenVPN, jste nahraní. Na příslušný port se prostě nedostanete.
Pochopitelně je možné se na to předem připravit a některou z těchto služeb si spustit na portu 80 či lépe 443. Ovšem když máte k dispozici jen server (typicky VPS) s jednou IP adresou a chcete na ní provozovat zároveň veřejný HTTPS, nemáte ani ten volný port, a v tu chvíli babo raď.
Yves Rutschle vymyslel pro takové případy velmi elegantní řešení: multiplexer sslh. Ten se posadí na zvolený port (typicky 443) a sám přijímá spojení. Podle úvodního představení klienta pozná požadovaný protokol a postará se o propojení na reálný port konkrétní služby.
Program byl původně vytvořen jako multiplexer protokolů SSH a SSL (odtud jeho název), ale později byl přepsán do obecnější podoby a podporuje podstatně více protokolů. Ve výchozím stavu jde o HTTP, SSL, SSH, OpenVPN, tinc a XMPP, ale do konfigurace je možné připsat další protokol a pomocí regulárních výrazů multiplexer učit.
Manuálová stránka popisuje, jak přesně detekce protokolů funguje:
Detekce protokolů probíhá podle prvních bytů, které klient serveru odešle. SSH spojení začíná identifikací verze, například pomocí řetězce „SSH-2.0“ (podle verze). To je definováno v RFC4253 v sekci 4.2. OpenVPN klient začíná komunikaci „0×00 0×0D 0×38“, tinc začíná s „0 “ a první paket XMPP obsahuje slovo „jabber“.
Příprava web serveru
Abyste mohli začít sslh používat, musíte mu uvolnit port 443 na rozhraní, na kterém bude sám poslouchat. Varianty jsou v zásadě dvě: můžete buďto web server uhnout na jiný port, nebo ho necháte na 443 poslouchat jen na lokálním rozhraní (localhost). Druhá možnost je doporučována dokumentací, když už nic, tak vám nezabere další port na vnějším rozhraní.
Ve výchozím stavu web servery poslouchají na všech rozhraních ( 0.0.0.0:443
), což musíme změnit.
Pokud používáte Apache, upravíte konfiguraci tak, aby sekce mod_ssl
obsahovala
Listen 127.0.0.1:443
Stejně tak je potřeba upravit konfiguraci u jednotlivých virtuálů, kde musíme sekci <VirtualHost *:443>
změnit opět na adresu lokálního rozhraní.
Pokud máte Lighttpd, pak v souboru 10-ssl.conf
nastavíte
$SERVER["socket"] == "127.0.0.1:443" {
Pokud používáte Nginx, změňte nastavení SSL virtuálů na
listen 127.0.0.1:443 ssl;
U jiných web serverů to bude v principu podobné, jen je potřeba najít správnou část konfigurace a nastavit lokální IP adresu.
Samozřejmě musíte server restartovat, aby se změny projevily a port se uvolnil. U ostatních služeb nemusíte dělat vlastně vůbec nic, protože ty pak zůstanou viditelné na svých původních portech, i na multiplexovaném 443. Pokud už třeba nechcete mít SSH na portu 22, můžete ho také nechat poslouchat jen na lokálním rozhraní.
Můžete pro jistotu ověřit funkčnost pomocí
# netstat -tulpn|grep 443 tcp 0 0 127.0.0.1:443 0.0.0.0:* LISTEN 18887/nginx: worker
Vidíte, že Nginx poslouchá jen na localhost rozhraní. Můžeme začít multiplexovat.
Instalujeme a začínáme
Distribuce běžně sslh obsahují, autor zmiňuje Debian, Gentoo a také FreeBSD. K dispozici jsou také binárky zkompilované proti Cygwin, takže program spustíte i na Windows. Pokud chcete sami kompilovat, zdrojové kódy najdete na GitHubu.
Konfigurační soubor je velmi jednoduchý a skládá se vlastně jen ze tří řádků (v Debianu). Na prvním z nich musíme určit, že se má multiplexer zapnout:
RUN=yes
Druhý řádek vybírá, která binárka se má použít. Výchozí volba sslh
způsobuje forkování procesu pro každý příchozí požadavek. To je sice doporučovaná varianta, ale je náročnější na systémové prostředky. Proti tomu sslh-select
běží v jednom vlákně a zpracovává všechna spojení naráz. Jedná se o novější a méně otestovanou variantu, která je ale šetrná k systémovým prostředkům (jen 16 bytů paměti na spojení).
Dokumentace doporučuje první variantu na méně zatížené servery a druhou variantu na ty pod větší zátěží. Volba je na vás, záleží na tom, jak potřebujete šetřit pamětí. Takže třeba:
DAEMON=/usr/sbin/sslh
Poslední řádek určuje parametry samotného multiplexeru, tedy zejména to, na kterém portu a rozhraní poslouchá ta která služba. Může to vypadat třeba takto:
DAEMON_OPTS="--user sslh --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.00.0.1:443 --openvpn 127.0.0.1:1194 --pidfile /var/run/sslh/sslh.pid"
Nastavuje se uživatel pro běh sslh, IP adresa a port multiplexeru a následují jednotlivé služby a jejich adresa a port. Na konci je volba souboru k uložení PID master procesu v případě forkovací varianty sslh.
Teď už stačí jen multiplexer nahodit:
/etc/init.d/sslh start
Pokud je vše nastaveno správně, mělo by fungovat připojení pomocí SSH na sdílený port 443:
$ ssh petr@1.2.3.4 -p 443
Plány do budoucna
Démon sslh je velmi jednoduchý a jednoúčelový, ale podle unixové filosofie dělá tu jednu věc dokonale. Umožňuje vám propojit se se zbytkem internetu i tam, kde to obvykle kvůli firewallu není možné. Většinou stačí jen SSH nebo VPN a máte k dispozici otevřenou bránu do celého světa.
Autor má několik nápadů na vylepšení, chce například umožnit připojení k některým multiplexovaným službám jen z konkrétních rozsahů IP adres nebo chce připravit něco jako port knocking. Démon vám pak zpřístupní cestu třeba k SSH jen v tom případě, že pomocí HTTPS nejprve navštívíte konkrétní URL na serveru. Tak bude pro náhodného kolemjdoucího nemožné zjistit, jaké další protokoly port 443 nabízí.