Disassembler

Artificial intelligence is no match for natural stupidity.
31srpen2016

Textové protokoly - HTTP (2)


Já vím. Seriál, u kterého vychází jeden díl za půl roku, asi moc pozornosti nepřitáhne. Ale když už jsem si s ním jednou začal, tak by bylo neslušné jej nedokončit. Takže tedy - HyperText Transfer Protokol. V dnešním světě snad nejdůležitější a nejpoužívanější protokol vůbec. Vznikl před více než 25 lety v CERNu a za dobu své existence prošel několika významnými úpravami, bez kterých by dnešní internet snad ani nemohl fungovat. V tomto díle seriálu o textových protokolech shrnu jeho charakteristiky a použití a předvedu, jak je možno si pokecat s HTTP serverem bez použití webového prohlížeče.

Obecně o HTTP


Standardní port pro HTTP je TCP/80 a pro HTTPS (tedy HTTP zabezpečené TLS vrstvou) TCP/443. HTTP samo o sobě neimplementuje žádné šifrování ani ověření integrity dat, takže na něj platí i ty nejjednodušší možné typy kybernetických útoků, jako třeba zachycení dat snifferem a případná následná modifikace nebo podstrčení škodlivého kódu. Právě to je příčinou, proč internetoví inovátoři jako Google nebo Mozilla tlačí a zvýhodňují HTTPS, kde se dá. To, že je HTTP textový protokol vás asi v seriálu o textových protokolech nepřekvapí. Trochu zajímavější už je ale fakt, že HTTP je protokol bezstavový. To jednoduše řečeno znamená, že ani klient, ani server si o sobě vzájemně nic nepamatují a každý požadavek klienta musí obsahovat dostatečné množství informací k tomu, aby mohl být serverem vybaven. Úplně nejdůležitějším kouskem dat je pak název nebo umístění požadovaného dokumentu (URL). Komunikace tedy probíhá tak, že klient se připojí k serveru, řekne si, s jakým dokumentem nebo prostředkem (resource) chce pracovat, co s ním chce dělat a jakou verzi HTTP protokolu chce použít. Pak může ještě přidat nějaké hlavičky (HTTP headers), které mohou obsahovat informace o tom, jak by zhruba chtěl, aby nabízený obsah vypadal (typ souboru, kódování, jazyk, komprese, atd.), případně může sám serveru předat nějaká pracovní data (např. obsah formuláře), v závislosti na tom, o jaký požadavek se jedná. Server si požadavek přechroustá a klientovi pošle odpověď, která vždy obsahuje stavový kód (HTTP status code) a v závislosti na tom, jak je server nakonfigurován a zda byl dotazovaný prostředek nalezen, může obsahovat zase jiné HTTP hlavičky, nastavené serverem, a také samotný obsah dotazovaného dokumentu nebo prostředku. Pak se klient odpojí a server zapomene, že se ho vůbec někdo na něco ptal a že vůbec nějaký klient existoval, takže celá výměna hlaviček a dat musí v následujícím dotazu a odpovědi proběhnout úplně znova.

Připojíte-li se pomocí utilit telnet nebo openssl s_client na HTTP server, můžete mu vyťukat třeba takovýto dotaz

GET /hello.html HTTP/1.1
Host: www.example.com
User-Agent: HastaLaVista/2.0 (T-800, Linux 4.1.15-1.1381_SKYN12nnmp)
Accept: text/html
Accept-Charset: UTF-8,*

GET - Metoda, tj. akce, která se má s prostředkem provést. GET znamená operaci čtení, tedy v tomto případě stažení dokumentu ze zadané URL.

/hello.html - URL požadovaného dokumentu nebo prostředku, se kterým se má zamýšlená akce provádět.

HTTP/1.1 - Použitá verze HTTP protokolu.

Klíč: Hodnota - HTTP hlavičky. Doplňující informace a metadata platná pro daný požadavek, například informace o uživatelově prohlížeči nebo typu souboru, který by rád dostal.

Za předpokladu, že požadovaný dokument existuje, vrátí server v odpovědi zhruba něco takového:

HTTP/1.1 200 OK
Date: Tue, 30 Sep 2016 09:36:25 GMT
Content-Type: text/html; charset=UTF-8

<html>
<head><title>Hello</title></head>
<body>Hello, World!</body>
</html>

HTTP/1.1 - Analogicky opět verze protokolu použitá pro odpověď.

200 OK - Stavový kód. 200 v tomto případě znamená, že dotazovaný dokument existuje a požadavku bylo možno vyhovět.

Klíč: Hodnota - HTTP hlavičky s metadaty náležícími k odpovědi.

<html>...</html> - Tělo odpovědi. V tomto případě požadovaný dokument v HTML formátu.

Rozdíly mezi verzemi


V příkladech výše je vidět, že si klient se serverem vzájemně oznamují, jakou verzí HTTP protokolu se hodlají bavit. To se samozřejmě neděje jen tak pro nic za nic, protože různé verze protokolů implementují různé vlastnosti. Nejznámější a nejčastěji používané jsou tyto:

HTTP/0.9 – Verze 0.9 existuje pouze pro zachování zpětné kompatibility s historickými webovými klienty. A tím myslím jakože fakt starověkými, protože se jedná o vůbec první publikovanou verzi z roku 1991. Umí pouze metodu GET a nepodporuje HTTP hlavičky. Prostě a jednoduše „Naval dokument“ – „Na, tady ho máš“.

HTTP/1.0 – Základní HTTP. Práce na něm byly v plném proudu už v roce 1992, ale oficiálně byl vypuštěn do světa až v RFC 1945 v roce 1996. Tato verze už řeší v podstatě všechno, co je potřeba k provozu world-wide webu, počínaje novými metodami a stavovými kódy přes kódování a kompresi obsahu, autentizaci a autorizaci, až třeba po doplňující informace, které by měl server klientu posílat, ale nemusí. Změn oproti HTTP/0.9 je tolik, že nemá smysl je všechny vypisovat, protože by to bylo asi jako srovnávat vaši první koloběžku s Teslou Model S.

HTTP/1.1 – Verze 1.1 přináší změny, které sice nejsou ohromující co do počtu, ale pro moderní podobu webu jsou naprosto nezbytné. Například umožňuje klientovi poslat Range request ve kterém si může vyžádat jen kousek dokumentu, což například umožňuje přerušit a navázat stažení souboru nebo streamovat přes HTTP. Také přidává podporu keepalive, což je nedocenitelná vlastnost zejména na webech přeplácaných tunou obrázků, stylů nebo skriptů, umožňujících v jednom spojení vybavit několik HTTP požadavků. V odstavci popisujícím obecné chování jsem psal, že se klient odpojí hned po tom, co server vyřídí jeho požadavek. S keepalive v HTTP/1.1 to tedy není až tak úplně pravda.

HTTP/1.0 vs. HTTP/1.1 keepalive

Jak vidíte na obrázku, z celé výměny v jednom TCP spojení se při použití HTTP/1.0 pošle pouze jediný HTTP dotaz a je vrácena jediná HTTP odpověď. Zbytek je režie na straně TCP. V lidském časovém měřítku by zdržení s navázáním a rozvázáním TCP spojení mohlo být celkem zanedbatelné, protože jde řádově o jednotky až desítky milisekund. Ale představte si, že otevřete třeba Facebook, kde jediná stránka bez problému načítá přes 300 prostředků – obrázků, stylů, skriptů, AJAX requestů, trasovacích prvků, reklam a dalšího balastu. A teď na to všechno ještě přihoďte i TLS s celou svou certifikátovou a šifrovací parádou, kterou je třeba také opakovat při každém navázání TCP spojení. Nejen že by použití HTTP/1.0 bylo oproti HTTP/1.1 neporovnatelně pomalejší, ale také by neúměrně zatížilo jak klientský stroj, tak i server. Díky keepalive je ale možno v jednom TCP spojení sekvenčně vyřídit několik HTTP požadavků a tím znatelně zredukovat režii potřebnou k navazování a rozvazování TCP a TLS spojení.

Nakonec bych ještě u HTTP/1.1 vypíchl povinnou hlavičku Host: nutnou pro identifikaci domén hostovaných jako virtualhosty (tj. několik vzájemně nesouvisejících webových prezentacích dostupných na shodné IP a portu). Jelikož HTTP nemá žádnou relační vrstvu a požadavek posílá rovnou po navázání TCP spojení, tato hlavička instruuje server, ze které webové prezentace se má pokusit prostředek vylovit.

HTTP/2 – Horká novinka, publikovaná v květnu 2015 v RFC 7540 postavená na Googlím experimentálním protokolu SPDY. Drobná zrada ovšem je, že tento protokol již není plaintextový, ale binární, díky čemuž sice mimo jiné snižuje režii potřebnou k překladu lidsky čitelného textu na programové objekty, ale již není možné s ním pracovat tak, jak popisuji u příkladů v článku. Je ale asi jen otázkou času, kdy se stane průmyslovým standardem, takže tenhle článek píšu opravdu na poslední chvíli. Existují sice nástroje jako h2c, h2i a taky strý dobrý curl, které nějaké to low-level dráždění serverů skrze HTTP/2 protokol umožňují, ale vytváří tak další vrstvu, kterou je v případě vážných problémů nutno ladit.

HTTP/2 samozřejmě přináší několik velmi užitečných novinek. Namátkou třeba server hints a server push, kdy se na základě konfigurace může server rozhodnout klientovi poslat prostředky, o kterých ještě neví, že je bude potřebovat. Klient tedy může požádat pouze o webovou stránku a server mu kromě dotazované stránky ještě navíc naservíruje obrázky a styly, které stránka používá a o jejichž potřebě by se klient dozvěděl teprve až by začal parsovat kód oné původně požadované stránky. Samozřejmě pokud taková featura bude užita chybně, výkonu to spíše ublíží. Další featura HTTP/2, která ale výkonu pomůže za každé situace, je multiplexing. Dá se o něm uvažovat jako o ještě pokročilejším vylepšení keepalive z HTTP/1.1, které nově umožňuje asynchronní vyřizování požadavků.

HTTP/1.1 vs. HTTP/2 multiplexing

Čím více prostředků ze stejného zdroje stránka vyžaduje, tím více multiplexing jejich stahování urychlí. Jelikož je HTTP/2 už nějakou dobu podporováno ve všech majoritních prohlížečích, můžete si rozdíl v rychlostech načítání vyzkoušet třeba na CloudFlare.

Metody


Sluší se teď zmínit, že HTTP je velice dobře rozšířitelný protokol, takže pokud se vám líbí jeho relativní jednoduchost, můžete si do něj přidat vlastní metody, stavové kódy a hlavičky a používat je ve svých proprietárních aplikacích. Velmi známým a užívaným rozšířením je například WebDAV, který přidává metody pro práci s adresářovými strukturami, takže je skrze něj možno vytvářet, číst, měnit a mazat soubory a podadresáře ve vzdáleném úložišti skrze HTTP protokol, podobně jako by byly uloženy na vašem disku. Další velmi nedoceněné rozšíření HTTP, které prostě nemůžu nezmínit, je HTCPCP, které o rozšiřitelnosti HTTP vypovídá opravdu výmluvně. Posuďte sami. Nejpoužívanější metody, které HTTP standardně implementuje, jsou následující:

GET – Metoda určená pro načítání dat. Instruuje server, aby se pokusil klientovi poskytnout požadovaný prostředek. GET by neměl nikdy být použit pro změnu dat na serveru, takže kdo odesílá formuláře GETem, je čuně. (Tedy za předpokladu, že se nejedná o formulář nastavující parametry obsahu, který má server naservírovat, např. vyhledávací formulář.)

GET /hello.html HTTP/1.1
Host: www.example.com
Accept: text/html
HTTP/1.1 200 OK
Date: Tue, 30 Sep 2016 09:36:25 GMT
Content-Type: text/html; charset=UTF-8

<html>...</html>

HEAD – Dělá víceméně totéž co GET, ale ze serveru se vrátí pouze stavový kód a hlavičky. Samotné tělo dokumentu se nepřenáší. To je užitečné třeba při zjišťování zdraví vytížených serverů. Loadbalancer si na webový server pošle HEAD request a v závislosti na tom jak rychle (a jestli vůbec) webový server odpoví, na něj pošle nebo nepošle nově příchozí spojení.

HEAD /hello.html HTTP/1.1
Host: www.example.com
Accept: text/html
HTTP/1.1 200 OK
Date: Tue, 30 Sep 2016 09:36:25 GMT
Content-Type: text/html; charset=UTF-8

POST – Tato metoda, na rozdíl od dvou výše uvedených, slouží k odesílání dat na server. Typicky se POSTem odesílají formuláře nebo SOAP requesty a od URL, na kterou je takový request směřován, se očekává, že data zpracuje.

POST /someform HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
 
action=addentry&subject=Hello,%20World
HTTP/1.1 200 OK
Date: Tue, 30 Sep 2016 09:36:25 GMT
Content-Type: text/html; charset=UTF-8

<html>...</html>

PUT – Podobně jako POST slouží k odesílání dat na server. Na rozdíl od POSTu ale URL neurčuje název skriptu pro zpracování odesílaných dat, nýbrž název souboru nebo URI, pod kterým se PUTovaná data mají uložit (i přesto je ale možno jej stále přesměrovat nějakému handleru). PUT se běžně nepoužívá, protože při nesprávném zacházení představuje bezpečnostní riziko, takže i upload souborů se obvykle provádí POSTem.

PUT /hello.html HTTP/1.1
Host: www.example.com
Content-Type: text/html

<html>...</html>
HTTP/1.1 201 Created
Date: Tue, 30 Sep 2016 09:36:25 GMT
Location: http://www.example.com/hello.html

DELETE – Dělá přesně to, co byste asi čekali, tedy smaže požadovanou URL. Vcelku nepřekvapivě také na HTTP serverech nebývá ve výchozím stavu zapnut. Společně s PUTem se hodí spíše pro různá REST API, která místo souborů na disku aktualizují a mažou příslušné datové záznamy v databázi.

DELETE /hello.html HTTP/1.1
Host: www.example.com
HTTP/1.1 204 No Content
Date: Tue, 30 Sep 2016 09:36:25 GMT

OPTIONS – Dotáže se serveru, jaké metody je možno na specifikovanou URL použít.

OPTIONS * HTTP/1.1
Host: www.example.com
HTTP/1.1 200 OK
Date: Tue, 30 Sep 2016 09:36:25 GMT
Allow: GET,HEAD,POST,OPTIONS,TRACE

TRACE – Metoda užitečná pro ladění ve složitějších prostředích (např. s proxy servery modifikujícími hlavičky). TRACE instruuje konečný server, aby obdržený požadavek vrátil zpět klientovi jako tělo odpovědi. Tato vlastnost ale může být využita při útoku typu cross-site tracing, takže se jí na slušně zabezpečených produkčních serverech také nedočkáte.

TRACE /hello.html HTTP/1.1
Host: www.example.com
Accept: text/html
HTTP/1.1 200 OK
Date: Tue, 30 Sep 2016 09:36:25 GMT
Content-Type: text/html; charset=UTF-8

TRACE /hello.html HTTP/1.1
Host: www.example.com
Accept: text/html

CONNECT – Touto metodou žádá klient forward proxy servery o zprostředkování spojení. Místo URL se do CONNECT metody zadá pouze hostname nebo IP serveru, kam by klientd rád, aby jej proxy přesměrovala.

CONNECT www.example.com HTTP/1.1
User-Agent: Blabla
HTTP/1.1 200 Connection established
Date: Tue, 30 Sep 2016 09:36:25 GMT

Stavové kódy


V příkladech výše jsou odpovědi serveru uvozeny jakýmisi tajemnými čísly. Tyto číselné kódy označují jednotlivé možné stavy nebo chyby, které mohou nastat. Pomáhají tak klientovi pochopit, co se s jeho požadavkem stalo, případně co musí dál udělat k tomu, aby byl požadavek úspěšně vyřízen. Stavové kódy HTTP je možno rozdělit do skupin podle první číslice.

1xx – Informativní – Stovkové kódy jsou novinka v HTTP/1.1. Slouží k signalizaci, že se od klienta očekává nějaká dodatečná akce. Typickým příkladem je 100 Continue, který posílají proxy servery a říkají tím klientovi, že je spojen se zamýšlenou protistranou a může pokračovat v odesílání požadavku.

2xx – Úspěch – Kódy začínající dvojkou značí, že server v pořádku přijal a vyřídil požadavek klienta. Dvoustovkových kódů je celá řada. Nejčastěji potkáte 200 OK, za kterým bude následovat obsah dokumentu nebo jiná data o která bylo požádáno GET nebo POST metodou. Naopak v případě, že server požadavek úspěšně přijme, ale žádná data nepošle, měl by tuto skutečnost ohlásit kódem 204 No Content. A pokud bude klient pomocí range hlavičky žádat jen o část dokumentu, bude mu doručena pod hlavičkou 206 Partial Content.

3xx – Přesměrování – Třístovkovým kódem server obecně říká něco jako „To, co po mě chceš, sice existuje, ale najdeš to někde jinde“. Typickými zástupci této skupiny jsou 301 Moved Permanently a 302 Found (resp. v HTTP/1.1 303 See Other). Oba pošlou klientovi Location hlavičku s novým umístěním dokumentu. Rozdíl mezi nimi je pouze ten, že 301 je trvalé přesměrování, které si klient může zapamatovat a při budoucích příležitostech přesměrovávat rovnou bez opětovného dotazování serveru, zatímco 302 a 303 jsou dočasná přesměrování a klient se musí pokaždé zeptat serveru, zda přesměrování ještě platí.

Další, celkem zajímavý kód je 304 Not Modified, který má co do činění s cache prohlížeče. Pokud totiž klient stránku nebo prostředek již jednou navštívil a stáhl, může serveru společně s opakovaným požadavkem poslat hlavičky If-Modified-Since a If-None-Match, které server porovná s daty na své straně. Pokud zjistí, že se nic nezměnilo a klient má v cache stále aktuální verzi, pošle mu odpověď s kódem 304 a nepřikládá znovu obsah požadovaného prostředku, protože si jej klient místo toho vysype z cache.

4xx – Chyby klienta – Neexistuje snad nikdo, kdo by neznal HTTP stavový kód 404 Not Found. Tento kód říká, že prostředek, o který klient žádá, na serveru neexistuje. To samozřejmě může být způsobeno i chybou v aplikaci nebo jednoduše tím, že někdo ze serveru dokument odstranil, nicméně webový server sám o sobě funguje korektně a o požadovaném dokumentu prostě nic neví.

Další čtyřstovkové kódy, kterých je mimochodem úplně nejvíc ze všech skupin, a které se hodí znát, jsou třeba 401 Unauthorized a 403 Forbidden. Oba kódy klientovi sdělují, že po serveru požaduje něco, k čemu nemá přístup. V případě 401 ale přístup může dostat, pokud k němu bude mít příslušnou autorizaci. Naproti tomu u 403 server odmítne vydat dokument, i kdybyste byli sám papež.

5xx – Chyby serveru – Konečně také kódy u kterých si můžete zanadávat na mizernou kvalitu poskytovaných služeb. Klasická 500 Internal Server Error znamená, že server sice poslouchá na svých portech, ale je špatně nakonfigurován, takže není schopen přijímat požadavky. Pak se třeba ještě celkem často potkávám s 503 Service Unavailable, kterou HTTP server zafňuká v případě, že je přetížen nebo že nějaký aplikační server v pozadí, kterému dělá reverzní proxy, zrovna odpadl. Mylnou představou, kterou často slýchávám na pohovorech, je, že pětistovkový kód může znamenat, že webový server spadl nebo je vypnut. Ne, to fakt nemůže, protože 5xx je odpověď serveru, kterou byste asi těžko dostali, kdyby vám neměl kdo odpovídat.

Boudo budko...


Na závěr nějaký hezčí a delší příklad konverzace s webovým serverem. Předpokládejme, že na druhé straně naslouchá Apache HTTP Server instalovaný z repozitáře Ubuntu 16.04 s následující konfigurací (zjednodušeno).

<VirtualHost *:80>
    ServerName host.example.com
    RewriteEngine On
    RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName host.example.com
    SSLEngine On
    SSLCertificateFile /srv/tls/host.example.com.crt
    SSLCertificateKeyFile /srv/tls/host.example.com.key

    DocumentRoot /srv/www/example.com/host
    <Directory /srv/www/example.com/host>
        AuthType Basic
        AuthName "Authentication Required"
        AuthUserFile /srv/www/example.com/host/.htpasswd
        Require valid-user
    </Directory>
</VirtualHost>

Klient samozřejmě netuší, jak je server nakonfigurován, ale rád by si stáhl soubor pojmenovaný hello.html ze serveru host.example.com. Protože ale klient četl můj úvod k textovým protokolům, ví, že je možno se na HTTP port připojit třeba pomocí telnetového klienta.

user@clienthost:~$ telnet host.example.com 80
Trying 12.34.56.78...
Connected to 12.34.56.78.
Escape character is '^]'.

TCP spojení bylo úspěšně navázáno a klient může přednést svůj požadavek. Stejně jako v předchozích případech tedy GET metodou požádá o dokument a protože hovoří protokolem HTTP/1.1, přidá povinnou Host hlavičku. Na konec požadavku přidá navíc prázdný řádek, který odděluje hlavičky od těla. Efektivně tedy na konci požadavku stiskne klávesu enter dvakrát, protože tělo je v tomto případě prázdné.

GET /hello.html HTTP/1.1
Host: host.example.com

Server mu na to odvětí

HTTP/1.1 301 Moved Permanently
Date: Wed, 31 Aug 2016 12:10:13 GMT
Server: Apache/2.4.18 (Ubuntu)
Location: https://host.example.com/hello.html
Content-Length: 325
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://host.example.com/hello.html">here</a>.</p>
<hr>
<address>Apache/2.4.18 (Ubuntu) Server at host.example.com Port 80</address>
</body></html>
Connection closed by foreign host.

Což znamená, že požadavek byl sice přijat korektně, ale dokument se nachází v jiném umístění, než klient původně žádal. Server jej tedy vyzývá, aby zaslal nový požadavek na správnou URL. V tomto konkrétním případě server pouze přesměrovává z HTTP na zabezpečené HTTPS a ještě k tomu je tak hodný, že přidává i lidsky čitelný obsah pro případ, že by klientův prohlížeč nezpracoval přesměrování automaticky. Opustíme tedy telnetového klienta a do serveru šťouchneme skrze openssl s_client.

user@clienthost:~$ openssl s_client -connect host.example.com:443
CONNECTED(00000003)
... (spousta informací o TLS spojení)
    Verify return code: 18 (self signed certificate)
---

Zabezpečené spojení je navázáno a nový požadavek může být zaslán. Klient tedy požádá stejném způsobem jako v předchozím případě, a protože je slušný a nepotřebuje, aby jeho HTTP/1.1 spojení použilo keepalive a zbytečně čekalo, přidá hlavičku Connection: close, která instruuje server, aby TCP spojení ukončil hned, jakmile pošle odpověď.

GET /hello.html HTTP/1.1
Host: host.example.com
Connection: close

Server pošle zpět něco nového.

HTTP/1.1 401 Unauthorized
Date: Wed, 31 Aug 2016 11:32:19 GMT
Server: Apache/2.4.18 (Ubuntu)
WWW-Authenticate: Basic realm="Authentication Required"
Content-Length: 464
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Unauthorized</title>
</head><body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache/2.4.18 (Ubuntu) Server at host.example.com Port 443</address>
</body></html>
closed

Stavový kód 401, opět i s lidsky čitelným obsahem odpovědi, říká, že dokument se možná v tomto umístění nachází, ale klient není autorizován k tomu, aby jej získal. Hlavička WWW-Authenticate napovídá, že klient může zkusit požadavek s patřičnou legitimací opakovat. Slůvko Basic znamená, že autentizace je možná obyčejným plaintextovým jménem a heslem. Konkrétně v případě Basic je jméno a heslo odděleno dvojtečkou a zakódováno v base64, takže je možno mít v hesle všelijaké divoké znaky. Převod z plaintextu do base64 a naopak je na moderních linuxech jednoduchý.

user@clienthost:~$ echo -n "someuser:somepass" | base64
c29tZXVzZXI6c29tZXBhc3M=

Ono -n u echa je důležité, jinak by vám tam implicitně prásklo zalomení řádku a výsledná base64 data by se pak lišila a pokusem o autentizaci neprošla. Klient tedy opět může navázat TLS spojení.

user@clienthost:~$ openssl s_client -connect host.example.com:443
CONNECTED(00000003)
... (opět spousta informací o TLS spojení)
    Verify return code: 18 (self signed certificate)
---

A zopakovat svůj požadavek společně s hlavičkou Authorization, kde předá výše uvedeným způsobem zakódované jméno a heslo. Podotýkám, že base64 je reverzibilní kódování, takže v případě, že by požadavek šel přes nezabezpečené HTTP, kdokoliv po cestě si jej může odchytit a jméno a heslo z něj získat.

GET /hello.html HTTP/1.1
Host: host.example.com
Connection: close
Authorization: Basic c29tZXVzZXI6c29tZXBhc3M=

Načež server konečně poskytně požadovaný dokument

HTTP/1.1 200 OK
Date: Wed, 31 Aug 2016 11:51:03 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Wed, 31 Aug 2016 11:28:50 GMT
ETag: "4c-53b5c66c6f372"
Accept-Ranges: bytes
Content-Length: 76
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

<html>
<head><title>Hello</title></head>
<body>Hello, World!</body>
</html>
Closed

Úplně nakonec drobný disclaimer. Článek se rozhodně nesnaží vyčerpat téma podoby a použití HTTP protokolu. Pouze popisuje ty nejobvyklejší věci, které se mohou hodit k přežití v internetové divočině.

Odkazy na další díly seriálu