OpenBSD httpd: jednoduchý a odolný webserver

14. 6. 2017
Doba čtení: 8 minut

Sdílet

Vedle Apache se před lety vyrojily lehké a výkonné servery jako Lighttpd a Nginx, i minimalistické servery bozohttpd nebo Tiny HTTPd. Když ale chcete něco hodně odolného, bezpečného a funkčního, je tu OpenBSD httpd.

Trocha historie z OpenBSD

V základní instalaci OpenBSD je tradičně zabudovaný webserver, který už v ve výchozím stavu běží v chrootu /var/www. Když jsem si nainstaloval první OpenBSD řady 4.x, byl to Apache 1. Když říkám Apache 1, není to úplně přesné. Apache se i tenkrát zdál vývojářům OpenBSD značně rosolovitý a přeplácaný, takže Henning Brauer se na to podíval a to, co vyšlo z jeho dílny, už byl výrazně upravený kód.

OpenBSD Apache, který běžel v chrootu /var/www, byl spíše server postavený na Apache 1.3, než že by šlo jen o portaci tohoto serveru. Když Apache 1 zestárnul a linuxový/unixový svět začal přecházet na Apache 2, shodli se vývojáři OpenBSD, že tenhle moloch do svého kódu nepřijmou. Apache2 tedy poskytli formou portu, ale do základní distribuce hledali něco svižnějšího a lehčího. Zkusili to s Nginxem, který je rozhodně blíže přístupu OpenBSD, a ten se stal výchozím serverem a součástí základní distribuce ve vydání 5.2.

Jenže Apache (v1.3.29) nebylo možno ještě odebrat kvůli absenci dobrého PHP handleru pro Nginx. A tak se do vývoje zapojil Florian Obser a v květnu 2014 importoval FastCGI wrapper. Mezitím se ale začal Nginx vyvíjet a Theovi vývojáři s rostoucími obavami sledovali, jak i on (stejně jako dříve Apache) začal pomalu tučnět a bobtnat. Tehdy se chlapci z OpenBSD ocitli znovu na křižovatce a osobou, která posunula vlak dále, se stal Reyk Floeter.

Na začátku byl relayd

Na hackatonu 2k14 ve slovinské Lublani pracoval Floeter na upgradu Nginxu z 1.4 na 1.6. Jak tak psal patch, která be eliminovala nebezpečná volání, všiml si, že takových nebezpečných míst, která odpovídají schématu malloc(num * size) a nechrání před integer overflow, je poměrně dost. 

Tehdy si uvědomil, že údržba takového nedotaženého kódu bude do budoucna představovat nemalou zátěž. Zároveň ho napadlo, že by teoreticky stačilo upravit kód balanceru relayd jen docela málo a byl by schopen servírovat statické stránky webu. Zkusil to a po několika hodinách práce (ještě ten den) představil velmi základní web server Theovi.

Ten byl velmi mile překvapen. Dal Floeterovi zelenou a k ruce zkušeného vývojáře Boba Becka, a tak se Reyk dal do práce. Web server začal vylepšovat a za relativně krátkou dobu byl server schopen stabilního běhu poskytujícího HTML stránky. To ovšem dnes nestačí, a tak se vývojáři už společnými silami vrhli na implementaci podpory PHP – FastCGI (opět se zapojil Florian Obser) a LibreSSL (Joel Sing) a za krátko to bylo.

Nginx se přesunul do portů a OpenBSD httpd, jak ho jednoduše nazvali, se stal součástí release. V prvním vydání (to bylo OpenBSD 5.6) určitě nebyl ještě to pravé pro produkci, ale pro vývoj bylo nutné, aby se dostal k co největšímu počtu testerů a produkčnímu nasazení. A už v dalším vydání se dal velmi pohodlně použít jako kvalitní webserver.

Nasazení

Velkou devizou OpenBSD httpd je přehlednost kódu a jeho relativní subtilnost, jen cca 10 000 řádek kódu (alias LOC). Pro srovnání httpd balancer relayd má 24 000 řádek kódu a Apache 2.4 má 90 000 řádek kódu (počítáno jako ELOC). Httpd běží už „z továrny“ v chrootu, což je pro bezpečnost zcela zásadní. Je s tím třeba ale počítat, protože to pochopitelně přináší určitá omezení. Například socket pro MySQL je třeba nainstalovat do /var/www, takže v my.cnf  zapíšete:

socket          = /var/www/var/run/mysql/mysql.sock

Tedy nikoli, jak je běžné, do /var/run/mysql. Nebo, pokud chcete sdílet adresáře uživatelů, musíte $HOME pro uživatele nastavit třeba do /var/www/home/franta. Z hlediska konfigurace je také podobný spíše Nginxu a Lighttpd. Stejně jako tyto dva odlehčené web servery, i OpenBSD httpd používá FastCGI nebo SlowCGI pro podporu PHP. Také, stejně jako dva výše jmenované servery neumí pracovat s uživatelským nastavením v .htaccess, což přináší určitá omezení například při nasazení na veřejném hostingu.

Přístup vývojářů a administrátorů se tu vůbec dělí na dva značně odlišně smýšlející tábory. Apachisté poukazují na uživatelsko-praktickou stránku věci, čili na to, že uživatel na veřejném hostingu si může nasadit jakýkoli software (Drupal, WordPress, Nette) a pomocí .htaccess bez zásahu administrátora nastaví, co je třeba pro běh.

Vedle toho nginxteři vysvětlují, že software, který je napsán tak, že potřebuje .htaccess, není dobře napsaný software. Zajímavé jsou tabulky, které počítají, o kolik se navýší I/O zátěž operačního systému při použití souboru .htaccess. Při silném webovém provozu je to opravdu vážná zátěž, takže i zde jsou vývojáři OpenBSD httpd jasně v linii se svou tezí „piš software jednoduchý, bezpečný a přinese to ovoce“.

Ovládání

  • povolení k samozapnutí po startu: rcctl enable httpd
  • test konfigurace: httpd -n
  • spuštění: rcctl start httpd
  • restart: rcctl restart httpd
  • vypnutí: rcctl stop httpd

Pochopitelně, pokud chcete ještě PHP (FastCGI), je třeba nainstalovat PHP a spustit:

  • instalace: pkg_add -v php
  • povolení k samozapnutí po startu: rcctl enable php70_fpm
  • start: rcctl start php70_fpm

Konfigurace

Nastavení OpenBSD httpd je spartánské a sympatické. Konfigurační soubor umístíme do /etc a nazveme httpd.conf. Nebudu tu kopírovat manuál k httpd, ale ukážu pár příkladů, které bývají lepší, než stránky výkladu:

K základnímu běhu stačí tři řádky:

server "www.example.com" {
listen on * port 80
}

Pokud ovšem chcete poněkud komplexnější konfigurační soubor, může vypadat například takhle:

server "192.168.4.1"{
        listen on rl1 port 8080
        directory  index index.php
        location "/*.php" {
        fastcgi socket "/run/php-fpm.sock" }
        root "/htdocs/sites/mysite"
}

To už je konfigurační soubor, který nabídne plně funkční webovou aplikaci s PHP na portu 8080 pouze na rozhraní rl1 na adrese 192.168.4.1 (dejme tomu, že to je intranet). Web „mysite“ pak musíme nahrát do /var/www/htdocs/sites/mysite.

No a následující případ nám ještě ukáže nějaké další možnosti zápisu a volby a také, jak se vypořádat s TLS:

server "www.greatsite.eu" {
        listen on 90.176.119.142 tls port 443
        tls certificate "/etc/ssl/acme/fullchain.pem"
        tls key "/etc/ssl/acme/private/privkey.pem"
        log { access "greatsite-access.log", error "greatsite-error.log" }
        connection { max requests 500, timeout 3600 }
        root "/htdocs/sites/greatsite"
}

Vidíme tu také, jak se nastavuje omezení pro počet spojení a timeout. Všechno to nastavení, všimněte si například definice logování, je nesmírně jednoduché a v podstatě samovysvětlovací. Důležité je, že od doby zavedení Pledge do systému OpenBSD byla „vypnuta“ možnost zadání hesla ke klíči, takže privátní klíč musí být vygenerován bez hesla, jinak httpd nenastartuje, protože žádost o heslo je porušením kompetencí daných v Pledge, a vyhodí hlášku:

 /bsd: httpd(67103): syscall 5 "wpath"

Samozřejmě, nemusíte mít na webserveru pouze jedny stránky. Stejně jako na Nginxu nebo Apachi i v httpd od OpenBSD můžete na jednom serveru rozběhnout několik aplikací. Následující příklad ukazuje, jak na virtualhosty, neboli bloky. Opět je to triviální, prostě se výše uvedené dva příklady zařadí po sobě do jednoho konfiguračního souboru, před bloky vidíte dvě poměrně jasné globální volby:

prefork 3
types { include "/usr/share/misc/mime.types" }
server "192.168.4.1"{
        listen on rl1 port 8080
        directory  index index.php
        location "/*.php" {
        fastcgi socket "/run/php-fpm.sock" }
        root "/htdocs/sites/mysite"
}
server "www.greatsite.eu" {
        listen on 90.176.119.142 tls port 443
        tls certificate "/etc/ssl/acme/fullchain.pem"
        tls key "/etc/ssl/acme/private/privkey.pem"
        log { access "greatsite-access.log", error "greatsite-error.log" }
        connection { max requests 500, timeout 3600 }
        root "/htdocs/sites/greatsite"
}

Mnoho dnešních aplikací používá rewrite, toto také httpd zvládne, ale přepsat nějaké složitější rewrite pravidlo z .htaccess  není úplně jednoduché. Jednak proto, že neexistuje přehledná dokumentace k rewritu, a zároveň proto, že tato část kódu se stále poměrně intenzivně vyvíjí.

Já sám to používám spoře, takže jsem zatím neměl moc šanci to nějak zvlášť ověřit, ale například rewrite přeposílající z běžného webu na zabezpečený by mohl vypadat takto (v globálních proměnných vidíte nastaveno jako síťové zařízení egress, tzn. takové, které je nastaveno jako vnější):

domain="www.mujserver.cz"
ext_if="egress"

server $domain {
        listen on $ext_if port 80
        block return 301 "https://$SERVER_NAME$REQUEST_URI"
}

server $domain {
        listen on $ext_if tls port 443
}

Portabilita

Mnohé, co vyšlo z dílny OpenBSD, a není toho málo (namátkou OpenSSH, LibreSSL nebo PF) je dobře portovatelné (možná s určitými omezeními u PF), takže to je k mání i pro FreeBSD, NetBSD a Linux. U OpenBSD httpd jsem našel port pro FreeBSD, ovšem neobjevil jsem, že by httpd někdo používal na Linuxu. To pochopitelně neznamená, že to nejde, ale spíše to indikuje, že to asi nebude pro Linux masová záležitost (zatím?).

Suma sumárum

Takže co je na tom OpenBSD httpd tak skvělé, že bych se o něj měl zajímat, když už deset let umím konfiguraci Apache a ono to nějak funguje? No, podtrženo a sečteno, dalo by se to říci takto:

Výhody:

  • minimalistický kód → minimum chyb
  • jednoduchá konfigurace → rychlé nastavení, minimum chyb
  • minimální nároky na paměť → menší výdaje na HW, vyšší výkon
  • plná funkcionalita → PHP, TLS, virtual hosts
  • běh v chrootu → bez dalšího nastavování rovnou zavřený a bezpečný

Nevýhody:

ict ve školství 24

  • není příliš rozšířen mimo OpenBSD
  • není to zavedený standard → učení se nové konfiguraci
  • dokumentace k rewrite je strohá → čas nasazení se trochu protáhne

Otázkou zůstává, do které škatulky zařadit fakt, že nepoužívá apachovitý  .htaccess.

Dovětek

Na závěr bych se rád podělil o své vlastní zkušenosti s OpenBSD httpd. Používám httpd od samého začátku pro různé intranetové aplikace a mini-wiki a většinou to běží na nějakém malém bezventilátorovém Soekrisu s architekturou i386, který má procesor 300 MHz a k tomu 256 MB paměti. Nepozoruji absolutně žádný problém ani zpoždění a o těch 256 MB se dělí samozřejmě systém a httpd s FastCGI a MariaDB.

.

Zajímavé odkazy

Autor článku

Petr Topiarz vystudoval angličtinu a pracuje jako systémový administrátor v jedné pražské IT firmě.