Protokol HTTP a WWW servery

Jiří Daněk, xdanek7@fi.muni.cz

Obsah

Protokol HTTP

HTTP (HyperText Transfer Protocol) je protokol aplikační vrstvy, sloužící k přenosu dat v systému World Wide Web. World Wide Web (www) sestává dokumentů HTML uložených na webových serverech, které je prostřednictvím HTTP zpřístupňují klientům, webovým prohlížečům.

Historie

Na počátku www stojí Tim Berners-Lee, který systém v roce 1989 navrhl, napsal prvotní specifikaci protokolu HTTP a formátu HTML a naprogramoval první webový server a prohlížeč (zároveň sloužící jako WYSIWYG editor pro HTML). V současnosti vývoj webu zaštituje jím iniciované World Wide Web Consortium (W3C).

Verze protokolu

další relevantní RFC dokumenty

aktualní dění

pracuje se na další revizi HTTP/1.1 a na HTTP/2.0

URI, URL, URN

URI může být URL, URN nebo obojí, podle toho, zda zdroj identifikuje na základě jména nebo lokace. Termíny URI a URL potažmo URN jsou v praxi zaměnitelné. [rfc3305]

V souvislosti s ideálem sémantického webu existovaly myšlenky zavést URC, Uniform Resource Citation. Mělo se jednat o metadata o zdroji, čili vlastně klasické citační informace.

Průběh komunikace

Webový server obvykle poslouchá na TCP portu 80. Po připojení klienta a navázání TCP spojení započne komunikace pomocí HTTP. Nejprve klient odešle na server požadavek, server tento požadavek zpracuje a pošle klientovi odpověď. Server ukončí spojení.

Tento základní scénář se může modifikovat

Ukázky

HTTP/0.9
nc muni.cz 80 | head
GET /
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  …
HTTP/1.1
nc muni.cz 80
GET / HTTP/1.1
Host: muni.cz
 
HTTP/1.1 301 Moved Permanently
Content-Length: 229
Content-Type: text/html
Location: http://www.muni.cz/
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Tue, 26 Mar 2013 11:38:25 GMT
Connection: close
 
<!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="http://www.muni.cz/">here</a>.</p>
</body></html>

Metody

GETpožadavek na HTML stránku na daném URL
HEADpožadavek na hlavičku HTML stránky
POSTpředávání dat na server
PUTnahraje soubor na server
DELETEsmaže soubor na serveru
OPTIONSzjišťení možností spojení a/nebo informací o HTML stránce, aniž bychom na ni přímo vznášeli požadavek (jako je tomu u HEAD)
TRACEsledování dotazu zasílaného na server
CONNECTnavázaní TCP spojení skrze HTTP proxy (potřeba pro HTTPS)
/.*/uživatelem definované metody

Hlavičky

Některé hlavičky zasílané klientem

Host: www.muni.czuvádí plné doménové jméno serveru
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8seznam MIME typů, kterým klient rozumí a jejich preference
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3preferovaný znakové sady
Accept-Encoding: gzip,deflate,sdchpreferované kódování
Accept-Language: cs,en-US;q=0.8,en;q=0.6preferované jazyky
User-Agentidentifikace klienta
Connection: keep-aliveříkáme si o keep-alive
Range: bytes=900-999říkáme si jen o část stránky
Příklad požadavku
GET /~kas/p090/referaty/2003-podzim/skupina10/QOS.html HTTP/1.1
Host: www.fi.muni.cz
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, | like Gecko) Chrome/25.0.1364.160 Safari/537.22
Referer: http://www.fi.muni.cz/~kas/p090/referaty/2003-podzim/skupina10/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: cs,en-US;q=0.8,en;q=0.6
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Ukázka range request
nc fi.muni.cz 80
GET /~kas/ HTTP/1.1
Host: www.fi.muni.cz
Range: bytes=900-999
 
HTTP/1.1 206 Partial Content
Date: Tue, 26 Mar 2013 12:25:29 GMT
Server: Apache
Last-Modified: Wed, 20 Feb 2013 13:22:01 GMT
ETag: "e5b6c-11c0-4d627d7ea3ea4"
Accept-Ranges: bytes
Content-Length: 100
Content-Range: bytes 900-999/4544
Connection: close
Content-Type: text/html; charset=ISO-8859-2
Content-Language: cs
 
 
<BR CLEAR=ALL>
<HR>
<H3>V�uka</H3>
<A HREF="http://www.fi.muni.cz/">
<IMG SRC="fi.gif" ALT=" "

některé hlavičky zasílané serverem

Date: Tue, 15 Nov 1994 08:12:31 GMTv naprostě většíně případů povinná hlavička, udává čas kdy server vyprodukoval odpověď
Server: Apacheidentifikace serveru
Accept-Ranges: bytesserver takto může informovat klienta, že umí range requesty, tj. "navazovat downloady"
Locationpro redirecty (stavové kódy 3xx)
Keep-Alive:timeout=2, max=90Server může seznámit klienta s tím, jak přesně se to KeepAlive provede.
Connection: closepo doručení téhle odpovědi uzavřu spojení (může poslat i klient)

Některé hlavičky vážící se k zasílaným datům

Content-Type: text/html; charset=ISO-8859-2MIME typ zasílaných dat, např. image/png
Content-Encodingkódování zasílaných dat (myslí se komprese, nikoli znaková sada)
Content-Length: 11258velikost dat v bajtech
Content-Language: csjazyk dokumentu

Stavové kódy

WWW servery

Podle společnosti Netcraft, která od roku 1995 zveřejňuje žebříček WWW serverů podle počtu obsluhovaných domén, je Apache stále nejpoužívanějším serverem. Žebříček pro březen 2013 vypadá takto:

Apache

Projekt Apache začal svůj život jako serie patchů pro server NCSA httpd 1.3. Od toho pochází i název, "A PAtCHy sErver". Dnes však Apache svůj název oficialně odvozuje od známého indiánského kmene Apačů pro jejich válečné umění a vytrvalost. Za vývojem serveru v současnosti stojí Apache Software Foundation.

Instalace

V době psaní je na stránce projektu k dispozici server Apache2 ve verzi 2.4 a verze 2.5 je ve vývoji.

souborová struktura serveru je obvykle podobná následujicí

/usr/sbin/binárky httpd, apachectl
/etc/httpd resp. /etc/apache2konfigurační soubory
/var/log/httpdaccess-log, error-log
Kompilace v NetBSD

Kompilace nám dovolí vybrat si MPM (multiprocessing modul), vynechat suExec, naopak zakompilovat podporu pro jazyk Lua.

Lua

jedná se o možnost používat skiripty v jazyce Lua. Jde o experimentální funkci. Skripty v lua jsou v podstatě moduly apache, čili není dobré zpřístupnit tuto funkcionalitu všem uživatelům.

Makefile

další jemější konfiguraci balíčku je možno provádět na začátku souboru Makefile

Multi-Processing Modules (MPMs)

Na unixových systémech jsou k dispozici tři moduly, které v Apache řeší souběžnou obsluhu klientů: event, worker a prefork. Pokud operační systém podporuje vlákna a pooling, použije nejlépe se model event. Pokud vlákna sice podporována jsou, ale pooling ne, použije se model worker. V ostatních případech se použije model prefork. V distribučních balíčcích bývá Apache ve variantě prefork.

prefork — procesy — hlavní proces forkne několik potomků, kteří poslouchají na příchozí spojení. Když se připojí klient, jeden z potomků se ho ujme. Když potomek klienta doobslouží, vrátí se zpět k poslouchání. Problém 1, v závíslosti na konkrétní implementaci: vyhladovění pokud posloucháme na více něž jednom soketu, thundering herd pokud použijeme neblokující accept, funguje docela dobře použijeme-li mutex. Tedy Apache používá mutex. Problém 2: Když zapneme keep-alive, budeme najednou mít spousty potomků, kteří každý jen drží jedno spojení naživu a nic nedělá. Proto má keep-alive obvykle velmi krátký timeout (5 s).

Mutexy (respektive Unixové system V semafory použité serverem jako mutexy) si můžeme vypsat pomocí příkazu ipcs -s . Pokud je server nastavený aby používal jinou implementaci mutexů (direktiva Mutex), pak samozřejmě tenhle příkaz nic neukáže.

worker — procesy a vlákna — hlavní proces forkne několik potomků, každý potomek vytvoří daný počet obslužných vláken a jedno naslouchací vlákno. Když naslouchací vlákno přijme klienta, předá ho jednomu ze svých obslužných vláken. Naslouchací vlákna používají mutex, stejně jako v modelu prefork.

event — vlákna a pooling — server udržuje několik obslužných vláken a jedno naslouchací vlákno. Požadavky jsou obsluhovány obslužnými vlákny. je obsluhován jedním vláknem. Když je požadavek vyřízen, spojení se přesouvá pod naslouchací vlákno. Řeší problém s KeepAlive.

Pozor: mod_cgi funguje pouze s modelem prefork. Pokud používáte jiný model, je potřeba použít modul mod_cgid. Z uživatelského hlediska jsou oba moduly identické, až na direktivu ScriptSock. Stejnětak některé další moduly pracují pouze v modelu prefork, například mod_php je potřeba nahradit za PHP prostřednictvím FastCGI.

Literatura

Apache je modulární software. Při kompilaci je možno si vybrat, které moduly se zakompilují, které budou načítány dynamicky při spuštění serveru a které budou vynechány úplně. Dokonce i webserverová funkcionalita je modularizována a je možné ji vynechat z kompilace ;-) Moduly zakompilované přímo do serveru můžeme vypsat pomocí příkazu

Konfigurace

Obvykle je možné vycházet ze vzorového distribučního konfiguračního souboru

Konfigurace Apache sestává z hlavního souboru, který obsahuje direktivy. Direktivy se dělí na jednoduché a konteinerové. Párové direktivy jsou vyznačeny v lomených závorkách, podobně jako tagy v HTML. Pomocí jednoduché direktivy Include je možno konfiguraci rozdělit do více souborů. Takto "centralizovanou" konfiguraci je ještě možno doplnit soubory .htaccess umístěnými přímo v jednotlivých složkách webové prezentace.

Debian, ubuntu

hlavní soubor konfigurace Apache je /etc/apache2/apache2.conf, který ale includuje /etc/apache2/http.conf a všechny soubory v /etc/apache2/conf.d/ a v /etc/apache2/sites-enabled/; navíc, v každé složce webové prezentace může být soubor nazvaný .htaccess, který může nastavení pro tu danou složku a podsložky dále upravovat, pokud to nění v nějakém z těch předchozích configů zakázáno

NetBSD

Hlavní konfigurační soubor je /usr/pkg/etc/httpd/httpd.conf, který může includovat další soubory /usr/pkg/etc/httpd/httpd-* Samozřejmě se opět uplatnují i .htaccess.

Podle toho, kde je direktiva umístěna, patří do jednoho ze čtyř kontextů.

Ne každá konteinerová direktiva vytváří kontext. Pouze konteinerové direktivy Directory, Files, Location a VirtualHost vytvářejí kontexty. Např. konteinerová direktiva Limit kontext nevytváří.

Vybrané jednoduché direktivy

ServerRoot "/usr/pkg"předřadí se před všechny relativní cesty v konfiguraci (které nezačínají "/")
Listen 80určuje kde (adresa a port) bude server čekat požadavky. Je možno uvést vícekrát
LoadModule rewrite_module lib/httpd/mod_rewrite.sonačtení modulu
ServerName www.example.commatchuje se proti hlavičce Host v požadavku. Důležité pro virtualní servery
ServerTokens OSobsah hlavičky Server. Volba OS pošle přesnou verzi serveru a velmi hrubou identifikaci OS (př.: Unix). Full (defaultní volba) navíc pošle i verze aktivovaných modulů.
DocumentRoot "/usr/pkg/share/httpd/htdocs"kořenový adresář webové prezentace
KeepAlive nopovoluje nebo zakazuje dříve zmíněná perzistentní spojení
Include etc/httpd/httpd-vhosts.confvložení konfigurace z jiného souboru. Smyslem je zpřehlednit konfiguraci. Je možné použít * v cestě.

Vybrané párové direktivy

do uvozujících špičatých závorek se zadává cesta, na kterou se nastavení aplikují

<IfModule unixd_module>
  User www
  Group www
</IfModule>
<Directory "/usr/pkg/share/httpd/htdocs">
  Options Indexes FollowSymLinks
  AllowOverride None
  Require all granted
</Directory>
Options
Nonezakáže všechny
Allpovolí vše vyjma MultiViews
Indexesautomatické generování indexů
ExecCGIspouštění CGI skriptů
MultiViewsautomatické generování type-map podle přípon
AllowOverride

Literatura

Merging

Jednotlivé sekce konfigurace serveru se aplikují v přesně stanoveném pořadí. Pro vypracování úkolu stačí vědět, že direktivy v sekci <VirtualHost> přebíjejí globální direktivy. A poslední direktiva přebijí ty předcházejicí.

Za mergování konfigurace si je odpovědný každý jednotlivý modul, takže je možné mít zde určitou flexibilitu, jako například u direktiv Alias a Redirect v konfiguraci modulu mod_alias. V úkolu ale budeme vytvářet jen jeden redirect, takže žádný problém.

Literatura

Struktura Apache

Z hlediska konfigurace je možno si vnitřní strukturu Apache představit jako soubor vzájemně kooperujících modulů. Moduly poskytují funkcionalitu content generátorů, metadata modulů a filtrů.

Přiklad s filtrem, proměnnou prostředí a handlerem

#Filtry
# Insert filter
SetOutputFilter DEFLATE
 
#Proměnné prostředí
# Don't compress images
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
      
#Handlery
<Location /server-status>
   SetHandler server-status
</Location>

Literatura

Moduly

některé důležité moduly

Používání

/etc/apache2/sites-enabled/

Basic auth

vytvoření souboru s hesly
htpasswd -c /usr/local/apache/passwd/passwords pv090
nakonfigurování složky
<Location /secure>
   AuthType basic
   AuthName "private area"
   AuthBasicProvider  file
   AuthUserFile    /usr/pkg/share/httpd/etc/passwords
   Require            valid-user
</Location>
Literatura

mod_status

ExtendedStatus On
 
<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Location>

Virtualní servery

<VirtualHost *:80>
    ServerAdmin webmaster@proto03-alpha.lab.fi.muni.cz
    DocumentRoot "/usr/pkg/docs/proto03-alpha.lab.fi.muni.cz"
    ServerName dummy-host.example.com
    ServerAlias www.dummy-host.example.com
    ErrorLog "/var/log/httpd/dummy-host.example.com- error_log"
    CustomLog "/var/log/httpd/dummy-host.example.com-access_log" common
</VirtualHost>

Když Apache vyřizuje příchozí spojení, příslušný virtualní server se určí následovně

Literatura

vypsání nakonfigurovaných virtualních serverů je možno dosáhnout příkazem apachectl -S

Content negotiation

AddLanguage cs .cz .cs
AddLanguage en .en
LanguagePriority cs en
ForceLanguagePriority Prefer Fallback
 
AddCharset us-ascii.ascii .us-ascii
AddCharset ISO-8859-1  .iso8859-1  .latin1
AddCharset ISO-8859-2  .iso8859-2  .latin2 .cen
AddCharset UTF-8   .utf8

suEXEC

Pokud nepoužijeme suEXEC, běží všechny CGI skripty pod uživatelem webserver. V případě, že na serveru mají uživatelé svoje webové stránky a mohou spouštět cgi skripty, je to bezpečnostní problém.

Stejnětak ale může být problematické špatně nastavené suEXEC. V krajním případě to může uživateli dovolit spustit proces jako jiný uživatel.

Přesměrování

Můžeme použít mod_alias nebo silnější mod_rewrite

mod_alias

mod_alias používá dvě základní direktivy, Alias a Redirect

pořadí zpracování

v rámci skupiny proběhne zpracování v tom pořadí, v jakém jsou v konfiguračním souvoru. Zpracování končí na první matchující direktivě.

Možnosti typů přesměrování

permanentvrátí kód 301, "moved permanently".
tempkód 302, defaultní hodnota.
seeotherkód 303
gonekód 410
300-399přímo uvedený kód, musí být platný

ScriptAlias, kromě toho, že nastaví Alias, navíc nastaví všem souborům na uvedené adrese handler na cg-skript a přidá Options +ExecCGI

Rozdíl mezi ScriptAlias a ekvivalentním nastavením toho samého, jak je uvedeno dole, je, že jakmile je ScriptAlias nastavený pro určitý podstrom, už ho nejde přebít další konfigurací.

ScriptAlias /cgi-bin/ /web/cgi-bin/
# prakticky odpovídá tomuto
Alias /cgi-bin/ /web/cgi-bin/
<Location /cgi-bin >
    SetHandler cgi-script
    Options +ExecCGI
</Location>

mod_rewrite

Slouží k tomu, abychom mohli mít hezká URL

RewriteEngine on
#Zapneme přepisování URL
RewriteRule ^wiki/.* - [L,QSA]
 
#základní formát RewriteRule: regexp nováURL flagy
#QSA přidat původní query string
#L skončit zpracování
 
RewriteRule ^event/([^/]+)/([^/]+)/([^/]+)/$ /index.php?mode=event&event=$1&source=$2&target=$3 [L,QSA]

SSL

(Transport Layer Security) a jeho předchůdce SSL (Secure Socket Layer) jsou kryptografické protokoly, které umožňují výměnu klíčů, šifrování a autentizaci prostřednictvím certifikátů.

Vygenerování self-signed certifikátu

# cd /etc/httpd/conf
# openssl genrsa -des3 -out server.key 1024
# openssl req -new -key server.key -out server.csr
# cp server.key server.key.org
# openssl rsa -in server.key.org -out server.key
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

nastavení apache

Listen 443
<VirtualHost _default_:443>
  SSLEngine on
  SSLCertificateFile "/usr/pkg/etc/httpd/server.crt"
  SSLCertificateKeyFile "/usr/pkg/etc/httpd/server.key"
</VirtualHost>

Jak testovat

openssl s_client -host proto03 -port 443

Problém s HTTPS a virtualními servery

SSL je v OSI úrovni zařazen mezi TCP a HTTP. Nejprve se ustavuje TCP spojení, pak SSL spojení, teprve potom HTTP. Při ustavování SSL spojení server neví, na jaký virtualní server bude klientův požadavek směřovat. Pokud ke každému virtualnímu serveru přísluší jiný certifikát, není v této fázi možné určit, který se má použít.

Existuje několik možných řešení této situace [podzim2011]

  1. poslat certifikát nejnavštěvovanější domény, tj. první certifikát uvedený v konfiguraci. Najivní řešení, kdy teoreticky většina návštěvníků nezaznamená žádný problém. Nevýhoda je, že návštěvníci jiných domén dostanou špatný certifikát a pravděpodobně je čeká upozornění WWW prohlížeče, že certifikát je pro danou doménu neplatný.
  2. provozovat každou doménu na jiném portě. Nepohodlně pro uživatele.
  3. přidělit každému virtualnímu serveru svou vlastní veřejnou IP adresu. Jenže IPv4 adres je nedostatek a IPv6 zatím není dostatečně rozšířené.
  4. SNI (Server Name Indication) - update SSL/TLS podle RFC 3546. Klient specifikuje doménu hned v prvním kroku SSL handshake (ClientHello). Toto rozšíření musí podporovat klient i server. Podpora v prohlížečích je dobrá.
  5. jeden SAN/UCC certifikát pro vícero domén (subjectAltName/). Problém je, že domény mohou vlastnit různí majitelé. Je potřeba najít Ca, která takový certifikát podepíše. Když je potřeba hostovat novou doménu, která vyžaduje HTTPS, je potřeba nechat si znovu vydat certifikát, rozšířený o další doménové jméno.
  6. Wilcard certificate, pokud všechny virtualní servery jsou poddomény v rámci jedné nadřazené domény.
  7. S-HTTPS. Existuje pouze jako experimentální RFC 2660 (1999), nebylo implementováno v produkčním SW.
  8. Upgrading to TLS Within HTTP/1.1. Vydáno jako RFC 2817, s cílem řešit problém bujících neelegantních "eskových" verzí protokolů. Používá hlavičku Upgrade:. Uvod RFC je poměrně vtipný ("komise se usnesla a všichni na to dlabou"). Webové servery (Apache 2.1+) to podporují, webové prohlížeče tuto funkcionalitu nikdy neimplementovaly a pravděpodobně ani neimplementují.

Literatura

Problém s virtualními servery (PVS)

Common Gateway Interface (CGI)

Standardizovaný protokol, kterým webový server deleguje vygenerování odpovědi na jiný spustitelný program, většinou nějaký skript.

Implementační detaily protokolu jsou platformě specifické, v Unixu se používají proměnné prostředí pro předání hlaviček a dalších proměnných do skriptu, na stdin dostane skript POST data, výstup skript odesílá na stdout

Navíc Apache dovoluje skriptům zapisovat do chybového logu zapsáním dat do stderr.

Konfigurace v Apache

jednoduchý, zato docela dlouhý, CGI skript v Bashi

#!/bin/bash
 
#Chybova hlaseni budou vypisovana na standardni vystup.
exec 2>&1
 
#Zabraneni vytvareni vypisu pameti pri padu procesu.
ulimit -c 0
 
#Generovani hlavicky dokumentu.
echo 'Content-Type: text/html; charset=utf-8'
echo
 
#Generovani stranky.
cat header.inc
 
#echo "nazdar"
#echo "$QUERY_STRING<br/>"
 
echo '<br/>'
echo '<br/>'
echo '<br/>'
 
URL=`param url 2> /dev/null`
 
if [ "x$URL" == "x"  ]; then
    echo "Nezadali jste žádnou adresu"
fi
 
#echo "downloading url = $URL<br/>"
 
wget -q -O tmp/stranka $URL
 
if [ $? != 0 ]; then
    echo "Neexistuje taková stránka"
    exit
fi
 
#echo "stazeno<br/>"
 
#echo "validuji<br/>"
#echo "<code>"
nsgmls < tmp/stranka >tmp/validace | sed -e 's/&/\&/g' \
-e 's/</\</g' \
-e 's/>/\>/g' \
-e 's/"/\"/g' \
-e 's/'\''/\'/g'
#echo "</code>"
 
echo "Stránka $URL "
if [ `tail -n 1 tmp/validace` == "C" ]; then
    echo "je validní."
else
    echo "není validní."
fi
 
echo '<br/>'
echo '<br/>'
echo '<br/>'
echo '<pre>'
cat tmp/validace
echo '</pre>'
 
cat footer.inc

Go

package main
 
import (
  "log"
  
  "html/template"
  
  "net/http"
  "net/http/cgi"
)
 
var tmpl = template.Must(template.New("tmpl").Parse(`Hello World!`))
 
func main() {
  err := cgi.Serve(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    tmpl.Execute(w, nil)
  }))
  if err != nil {
    log.Panic(err)
  }
}
Spuštění mimo webserver
# Minimální nastavení proměnných prostředí,
# aby se program vůbec spustil mimo kontext webserveru
export REQUEST_METHOD=GET
export SERVER_PROTOCOL=HTTP/1.1
export REQUEST_URI=/
 
go run cgi.go
Status: 200 OK
Content-Type: text/html; charset=utf-8
 
Hello World!
Spuštění přes Apache

Apache přidá hlavičku Date a status, pokud ho CGI skript nedodal

Literatura

  • Common Gateway Interface
  • The Common Gateway Interface (CGI) Version 1.1
  • Bash
  • GO
  • nginx

    vyslovuje se [endžinex]

    Server naprogramoval Igor Sysoev, autorem loga je Cliff Wells

    [S]ometimes described as a reverse proxy first and webserver second. It’s insanely fast at serving static files, uses little memory, and configuring it turned out to be easy. Also, who can resist that logo?

    Z hlediska vnitřího fungování je celý server event based.

    Literatura

    vlastní program

    Některé programovací jazyky se vyznačují tím, že je velice jednoduché v nich napsat WWW server. Bývá to dáno podpora standardní knihovny. Jsou to jazyky například Python, JavaScript(NodeJS) nebo GO

    Python

    Výkon

    Dobré rady:

    keep-alive

    HTTP/1.1, možnost znovu použít otevřené spojení k vyslání dalšího požadavku (všechny spojení perzistentní, ale timeout bývá nastaven na několik sekund)

    pipelining

    HTTP/1.1, odeslání několika požadavků zároveň. Na mobilních zařízeních je relativně rozšířený. Z desktopových prohlížečů ve výchozím nastavení používá pipelining pouze Opera.

    Problémem je, že "HTTP forces strict FIFO semantics for all the [pipelined] requests". Čili pokud se první GET na něčem zasekne, musí čekat všechno. Další problém je, že proxy servery pipelining obecně nepodporují

    V každém požadavku se zasílají uložená Cookies

    COMET

    Název pochází od toho, že Comet, stejně jako Ajax, jsou názvy v Americe běžných domácích čisticích prostředků. Ha ha ha.

    HTTP nepodporuje oboustrannou komunikaci. Konkrétně neumí komunikaci iniciovanou serverem.

    Příklad: programujeme webový chat. Chceme uživateli v realném čase ukazovat nově příchozí zprávý. Klasické řešení je na klientu dělat refresh každých 5 sekund. Díky dále popsaným technikám můžeme totéž učinit o něco efektivněji.

    Comet je souhrnné jméno pro techniky, které se snaží tento problém nějak řešit. Déle budou popsány dva základní mechanismy, long pooling a HTTP streaming.

    Long pooling.

    Klient, konkrétně webová stránka pomocí Ajaxu, odešle požadavek na server. Server drží spojení otevřené, a teprve až má pro klienta přípravená data, odešle odpověď a spojení ukončí. Klient ihned připraví nové spojení pro další dávku dat od serveru.

    HTTP streaming

    Podobné jako long pooling, ale server posílá odpověď po částech jako Transfer-Encoding: chunked, čili nemusíme obnovovat spojení po každé odpovědi serveru. Existuje varianta i v prostředí HTTP/1.0, které chunked neumí.

    Na straně klienta je obvyke neviditelný iframe, přezdívaný "forever frame". Jednotlivé chunky vždy obsahují jeden <script></script>. Webový prohlížeč tyto skripty vykonává hned jak přícházejí do iframe.

    WebSocket

    Nejedná se o mechanismus z rodiny Comet, ale o systémové řešení problému novým protokolem.

    Pomocí hlavičky Upgrade provedeme přechod z HTTP/1.1 na nový protokol – WebSocket, který oboustrannou komunikaci zvládá. Hlavička Upgrade je hop-by-hop, tedy pokud používáme HTTP proxy, musíme si vyžádat přímý tunel k serveru pomocí CONNECT. WebSocket patří do rodiny technologií HTML5.

    Domain Sharding

    Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server.A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy. […] These guidelines are intended to improve HTTP response times and avoid congestion. [rfc2616]

    RFC 2616 doporučuje omezit počet souběžných spojení s jedním serverem na dvě. Pokud máme na stránce například spoustu obrázků a chceme dosáhnout většího paralelismu, můžeme obrázky rozhodit na více (dvě, čtyři) doménová jména. Tomu se říká Domain Sharding. Současné webové prohlížeče toto doporučení ignorují a otevírají až 6 spojení, tedy sharding není tak zásadní, jako byl dříve. Výkon může být dokonce ovlivněn negativně, protože každou shardovanou doménu je potřeba přeložit pomocí DNS.

    CDN Content Distribution network

    CDN je specialní hostingová služba pro statický obsah. Výhodou je, že se volí geograficky blízký server, navíc je obsah je na samostatné doméně, takže se nemusí s každým požadavkem znovu a znovu zasílat všechny cookies.

    Obyčejný člověk se s tím v minulosti většinou moc nestkal, pro takové to domácí webování to bývalo moc drahé a vpodstatě zbytečné. Pokud ale používáte Google App Engine nebo Microsoft Azure, pravděpodobné nějaké CDN máte v rámci té cloudové služby.

    Cachování

    Skoro všechno na webu může provozovat nějakou formu cache. Ať už je to webový prohlížeč nebo proxy servery na cestě, čemuž je v následujicím přehledu věnována největší pozornost, ale cachovat může také webový server, respektive webová aplikace.

    Cachování ve webové aplikaci je záležitostí programátora, nikoli administrátora. Dá se použít cachovací server memcached.

    Webový server Apache podporuje cachování obsahu pomocí modulu mod_cache. Tento modul se chová jako cachující reverzní proxy jakoby před webovým serverem.

    Cachování v HTTP/1.1

    Hlavičky dat souvisejicí s cachováním

    Last-Modified: Wed, 17 Dec 2003 08:57:03 GMTdatum poslední změny
    ETag: e6eee-2bfa-3cea94a6415c0jednoznačný hash pro statická data, generovaný webserverem
    Expires: Nastaví datum, po jehož uplynutí musí být stránka vyžádána znovu
    Cache-Control: max-age=Nastaví dobu v sekundách od doručení (hlavička Date), po kterou je odpověď platná. Pokud je uvedeno Expires i Cache-Control: max-age, použije se Cache-Control. Je možné použít i v requestu.

    Hlavičky dat a požadavků souvisejí s cachováním

    If-Matchhodnotou ETag podmíněné PUT requesty, můžeme implementovat něco jako CAS (Compare and Swap)
    Last-Modified/If-Modified-Sinceposlední změna, podmíněný request v závislosti na poslední změně
    ETag/If-None-MatchETag, podmíněný request v závislosti na ETag
    Cache-Control: max-age=0všechny cachující proxy na cestě si musí ověřit, že mají aktualní verzi
    Cache-Control: no-cachevšechny cachujicí proxy si musí stáhnout aktualní verzi.

    ETag

    U Apache v defaultním nastavení se ETag vypočítá na základě inode, času modifikace a velikosti souboru v bajtech. Oproti Last-Modified se může měnit po každém požadavku (Last-Modified má granularitu 1 sekunda)

    Pokud máme víc serverů, každý pravděpodobně pro stejný soubor vypočítá jiný ETag. Řešením je v takovém případě ETag nepoužívat.

    Příklad na ETag a Last-Modified:

    Accept-Ranges:bytes
    Connection:close
    Content-Language:cs
    Content-Length:11258
    Content-Type:text/html; charset=ISO-8859-2
    Date:Tue, 26 Mar 2013 11:19:13 GMT
    ETag:"e6eee-2bfa-3cea94a6415c0"
    Last-Modified:Wed, 17 Dec 2003 08:57:03 GMT
    Server:Apache

    Když browser zjistí, že stránka je neaktualní, může ji buďto normálně stáhnout znovu, nebo udělat range query na hlavičky Last-Modified a/nebo ETag.

    Příklad:

       
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:cs,en-US;q=0.8,en;q=0.6
    Cache-Control:max-age=0
    Connection:keep-alive
    Cookie:***nepovím***
    Host:www.fi.muni.cz
    If-Modified-Since:Wed, 20 Mar 2013 14:48:08 GMT
    If-None-Match:"6df143b-bef3-4d85c4f788d0d"
    User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22

    Literatura

    Domain Sharding

    cachování

    Bezpečnost

    Socialní inženýrství

    Pří tomto typu útoku se útočník se snaží obět zmanipulovat tak, aby útočníkovi vyzradila nějakou informaci (heslo) nebo provedla nějakou akci (nainstalovala si do počítače mallware).

    Literatura

    Cross-Site Request Forgery

    Příklad. Útočník napadne nezabezpečenou stránku, kterou oběť navštěvuje, a vloží do ní následujicí HTML

    <img src="https://is.muni.cz/auth/system/nastaveni.pl?ups_rsvs=0">

    V okamžiku, kdy oběť tu napadenou stránku navštíví, sbalí se jí odkazy na domovské stránce ISu. Profit.

    Pokud uživatel není zrovna přihlášený do ISu, …

    Dá se vylepšovat, před několika lety fungoval css history sniffing (resp. css history hack), dnes už je toto vyřešeno.

    Řešením je přidávat do adres parametr a do formulářů skryté pole s tokenem (input type=hidden name=_ value=xyz). Útočník nemá způsob, jak zjistit token. Pokud má způsob, tak nemusí dělat CSRF, ale může škodit jinak a mnohem víc.

    Cross Domain AJAX

    dovoluje posílat Cross Domain AJAXové požadavky (CORS, Cross-origin resource sharing). Požadavky jsou rozděleny do dvou skupin. Na ty ve skupině "simple" se vztahují výrazně menší restrikce. Je možné například JavaScriptem uploadovat soubor na cizí server.

    Literatura

    Cross Site Scripting (XSS), SQL injection

    XSS, SQL injection a pod. fungují na tom principu, že na webu využíváme spoustu technologí, formátů a jazyků dohromady, a to, co je v jednom kontextu buď neškodné smetí, nebo legitimní text, je v jiném kontextu naprostá katastrofa.

    Takové "rm -rf /" je neškodné HTML, neškodná řetězcová konstanta v JavaScriptu, neškodné SQL, škodný příkaz v shellu. Pokud se ten řetězec nějak dostane do shellu, máme problém

    realný problém: filtrovací funkce v PHP, která nerozuměla UTF-16.

    "And while the filter doesn't understand UTF-16, the underlying framework does, so the content gets normalized and interpreted just the same as anything else, allowing the query to continue unfiltered." [Tyler Larson, security.stackexchange.com]

    Literatura

    Útoky na SSL

    SSL-stripping

    Prohlížení přes HTTPS (skoro) vždy začíná s HTTP. Útok funguje na principu Man-in-the-middle. Fungujeme jako "proxy", která komunikuje se serverem pomocí HTTPS a napadenému uživateli všechen provoz překládá v HTTP.

    Literatura

    Padding Oracle Attack

    Dobré vysvětlení najdete v úvodním textu k úloze 4 ve 4. sadě Korespondenčního semináře z informatiky.

    Lucky Thirteen attack

    Aktualní věc, byl zveřejněn v únoru 2013

    Literatura

    BEAST

    Delší dobu se teoreticky se vědělo, že SSL 3.0 a TLS 1.0 a starší nejsou bezpečné. Autorům tohoto útoku se podařilo prakticky implementovat funkční exploit pro HTTPS.

    "The CBC IV for each record except the first is the previous records' last ciphertext block. Thus the encryption is not secure against adversaries who can adaptively choose plaintexts; see the second e-mail message reproduced below [Date: Fri, 8 Feb 2002]. Note that for most application protocols such attacks are not really feasible."

    Jedná se o Known-plaintext attack, konkrétněji o Choosen boundary atack.

    Nejlepší způsob jak se bránit, je upgradovat na TLS/1.1. Bohužel TLS/1.1 doposud nemá dobrou podporu v prohlížečích. Proto se doporučuje alespoň změnit preferovaný šifrovací algoritmus na RC4, který sice nemá mezi kryptology dobrou pověst (=ruce pryč ;), ale proti BEAST je odolný.

    Literatura

    CRIME

    Další útok na TLS, od stejných lidí jako BEAST, vnějškově je trochu podobný.

    Stejně jako u BEAST předpokládáme, že útočník může odposlouchávat provoz (otevřená WiFi) a může odesílat vlastní požadavky na server (třeba nějaké XSS nebo překonali same origin policy.)

    Na rozdíl od BEAST nevyžadujeme konkrétní verzi TLS, nyní pro změnu předpokládáme, že webový prohlížeč provádí kompresi hlaviček metodou DEFLATE (gzip). Pokud jsou tyto předpoklady splněny, potom útočník může ukrást session cookie relace.

    Útočník bude z našeho prohlížeče přístupovat k různým adresám na HTTPS serveru a bude sledovat, jak se mění velikost hlavičky prohlížečem generovaného požadavku. Z toho může vytušit, jak moc se jím vložená data podobají jiným datům, která už v hlavičce jsou, zejména té naší session cookie. Útočník může hádání systematizovat postupně znak po znaku.

    Poučení: nekomprimovat hlavičky (současnost), případně komprimovat něčím jiným, než DEFLATE (budoucnost, SPPDY a HTTP/2.0)

    Literatura

    Útoky, které TLS obejdou

    Všechny dříve popsané útoky stavěly na slabinách v šifrovacích algoritmech. V praxi se ale většinou útok staví na tom, že správce šifrování nasadí jinak, než jak bylo autory zamýšleno.

    Literatura

    Všechny klasické síťové útoky typu DOS

    Literatura

    Literatura

    HTTP

  • en.Wikipedia Hypertext_Transfer_Protocol
  • The Original HTTP as defined in 1991
  • IETF Documents
  • Apache