Zabezpečujeme HTTP provoz na našich serverech

Jak každý administrátor ví, po příchodu GDPR se hodně tlačí na zabezpečení online aplikací pomocí protokolu HTTPS. Dalším důvodem k přechodu je i fakt, že některé velké vyhledávače upřednostňují provoz na HTTPS a zvyšují danému webu rank. Rozhodl jsem se udělat stručný návod, jak rozběhat HTTPS na vlastním Apache serveru s certifikáty Let´s Encrypt (nebo i jinými).

Konkrétně se koukneme na tyto modelové situace:

  • Zabezpečení webu běžícím na stejné instanci serveru.
  • Zabezpečení webu na jiné instanci stejného serveru.
  • Zabezpečení webu na úplně jiném serveru ve stejné síti.

Zabezpečovat budeme servery Apache 2.4.x běžící na OS Windows (testováno na Windows 2016, 2012R2 a 2008R2 – ale nemělo by záležet na verzi Windows). DOPORUČUJI aktualizovat Váš Apache server na poslední verzi.

Předpoklad pro úspěšnou implementaci je jasný, stažení aktuálního Apache serveru s knihovnou pro provoz SSL. Já osobně často implementuji balíček XAMPP, zde je možné vždy stáhnou předpřipravený komplet s dalšími doplňky (MySQL, PHP, …). Pokud budete aktualizovat, tak pozor na přechod Vašich aplikací z PHP5 na PHP7, nově v PHP7 je zrušená stará funkce na připojení k DB, mohlo by dojít k chybě.

Moduly

Máme tedy nainstalovaný Apache v jeho nejnovější verzi, pro implementaci HTTPS a VirtualProxy je třeba v konfiguračním souboru httpd.conf odkomentovat (odstranit #) načtení těchto modulů:

  • LoadModule proxy_module modules/mod_proxy.so
  • LoadModule proxy_connect_module modules/mod_proxy_connect.so
  • LoadModule proxy_html_module modules/mod_proxy_html.so
  • LoadModule proxy_http_module modules/mod_proxy_http.so
  • LoadModule proxy_http2_module modules/mod_proxy_http2.so
  • LoadModule ssl_module modules/mod_ssl.so
  • LoadModule rewrite_module modules/mod_rewrite.so

Většina z nich by měla být odkomentována ve výchozím nastavení.

Dalším krokem je připravení informací pro takzvané virtuální hosty, tedy oddělit od sebe weby, které chceme zabezpečit.

Ve výchozím nastavení, se všechna data webů ukládají do složky „htdocs“ v adresáři s Apache nebo celého instalovaného balíčku serveru.

Model

Řekněme, že budeme chtít zabezpečovat tyto weby:

  • domena.tld = Web, který běží na lokálním serveru, na stejné instanci Apache.
  • shop.domena.tld = Web, který běží na stejném serveru ale na jiné platformě (Tomcat, IIS, …). Web běží na localhost:8080.
  • blog.domena.tld = Web, který běží na úplně jiném stroji v lokální síti.

Virtuální hosti 1

První co si nastavíme, je soubor „httpd-vhosts.conf“ nachází se v adresáři s Apache instalací, ve složce „\conf\extra\„.

domena.tld

<VirtualHost *:80>
ServerAdmin "webmaster@domena.tld"
ServerName "domena.tld"
DocumentRoot "C:\HTTP\SERVER\htdocs\domena.tld"
<VirtualHost>

Jen ve zkratce:

  • VirtualHost *:80 = Začátek bloku pro VH (virtuálního hosta), značí to, že má server požadavky přijímat z jakékoliv IP adresy (to je ta hvězdička, jedná se o veřejné IP adresy serveru – WAN) a konkrétně na portu 80 – nezabezpečený přenos.
  • ServerAdmin = Kontakt na admina webu. Nepovinné.
  • ServerName = Data pro jakou URL má zpracovat.
  • DocumentRoot = Odkud má čerpat data pro aplikaci.

shop.domena.tld

<VirtualHost *:80>
ServerAdmin "webmaster@domena.tld"
ServerName "shop.domena.tld"
ProxyPreserveHost On
ProxyPass "/.well-known/" !
DocumentRoot "C:\SERVER\HTTP\APACHE\htdocs\shop.domena.tld"
ProxyPass "/" "http://localhost:8080/"
ProxyPassReverse "/" "http://localhost:8080/"
<VirtualHost>

Jen ve zkratce:

  • ProxyPreserveHost On = Zapnutí transparentní proxy.
  • ProxyPass „/.well-known/“ ! = Zde říkáme, že se složka /.well-known/ nemá překládat přes proxy – důležité pro ověření Let´s Encryptem. Způsobí to, že s touto složkou se bude vždy pracovat lokálně v adresáři „DocumentRoot“. Vykřičník toto pravidlo vynucuje (tedy i kdyby na cílovém serveru složka existovala, systém ji bude ignorovat).
  • ProxyPass „/“ „http://localhost:8080/“ = Nastavuje, že veškerý provoz bude tahán z cílového serveru. Tedy vše za shop.domena.tld bude z localhost:8080.
  • ProxyPassReverse = Pravidlo pro reverzní proxy.

blog.domena.tld

<VirtualHost *:80>
ServerAdmin "blogger@domena.tld"
ServerName "blog.domena.tld"
ProxyPreserveHost On
DocumentRoot "C:\HTTP\SERVER\htdocs\blog.domena.tld"
ProxyPass "/.well-known/" !
ProxyPass "/" "http://192.168.1.10:80/"
ProxyPassReverse "/" "http://192.168.1.10:80/"
<VirtualHost>

Zde je to hodně podobné jako nahoře, jen místo localhostu je jiný server.

Po vytvoření tohoto nastavení je nutné restartovat Apache server.

Certifikujeme

Pro zabezpečení potřebujeme mít k dispozici certifikáty pro web. osobně se mi zatím nejvíc osvědčil nástroj PKISharp/win-acme. Jedná se o konzolové All-in-One řešení a to včetně automatického obnovení všech certifikátů. Stažený archiv extrahujte na místo, kde už s ním nebudete manipulovat, na danou UNC cestu se linkuje naplánovaná úloha pro obnovení certifikátů. Později doplním i obrázky, ale pro představu by měl stačit i tento postup na generování certifikátu:

  • Spusťte aplikaci jako správce.
  • V hlavním menu zvolte položku „M“ pro vytvoření nového požadavku na certifikát.
  • Zvolte položku „1“ pro manuální přidání host names.
    • Zde se při prvním spuštění programu zobrazí ještě žádost o potvrzení EULA Let´s Encryptu a zadání mailu kam budou chodit neúspěšná obnovení. Ověření provedete zadáním „y„, jako yes.
  • Zadejte URL adresu webu, například „blog.domena.tld“ bez uvozovek.
  • Zadejte „3“ pro http-01 kontrolu uložením ověřovacího klíče do lokálního prostoru (na disk).
  • Zadejte úplnou UNC cestu k datům webu, proto jsme u vzdáleného serveru také vytvářeli složku „DocumentRoot“, přesně sem směřujte i tuto adresu. Tedy pro naši doménu blog.domena.tld bude UNC cesta stejná jako v „DocumentRoot“, tedy „C:\HTTP\SERVER\htdocs\blog.domena.tld“ (bez uvozovek). Ověření Let´s Encrypt se ukládá do složky /.well-known/, proto jsme tuto služku jmenovitě vyřadili z proxy.
  • V případě, že používáte Apache, dejte v dalším kroku „n„, nechcete totiž do složky kopírovat i nastavovací soubor „web.config“, ten je určen pro platformu IIS. Z mých zkušeností, pokud Vám tento postup v IIS nefunguje, je problém zde.
  • V dalším kroku zadejte „1„. nechcete spouštět po obnovení další skripty.
    • Mělo by proběhnout vygenerování certifikátu a jeho ověření. V textu by mělo být slovíčko „Valid„, případně je v textu uvedeno, kde generování selhalo.
  • V posledním kroku, pokud se Vás systém zeptá (poprvé se nezeptá) zadejte „n„, nechcete přepsat další úlohy pro obnovení (smazat je).

Tímto máte nastavené vše potřebné a vygenerované certifikáty, aplikace se postarala i o vytvoření naplánované úlohy (každý den v 9:00) kdy dojde k obnovení certifikátů. Aplikace se pokouší obnovit všechny certifikáty. Nespouštějte žádosti o obnovu/generování příliš často, jinak dojde k zablokování Vaší IP adresy a nebude možné certifikáty obnovit, mám ozkoušeno, že deset žádostí denně je ještě OK.

  • Všechny Vaše certifikáty a autority se nachází v této složce: „C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\“.

Implementujeme zabezpečení

Implementace se provádí opět v „httpd-vhosts.conf„, ve složce „\conf\extra\“ serveru Apache.

Je potřeba přidat záznamy pro zabezpečený přenos. Je potřeba zkopírovat vytvořené hosty, přepsat porty na *:443 a doplnit informaci o certifikátech. Přidáme tedy tyto informace:

<VirtualHost *:443>
ServerAdmin "webmaster@domena.tld"
ServerName "domena.tld"
DocumentRoot "C:\HTTP\SERVER\htdocs\domena.tld"

SSLEngine on
SSLCertificateFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\domena.tld-crt.pem"
SSLCertificateKeyFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\domena.tld-key.pem"
SSLCertificateChainFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\ca-domena.tld-crt.pem"
<VirtualHost>

<VirtualHost *:443>
ServerAdmin "webmaster@domena.tld"
ServerName "shop.domena.tld"
ProxyPreserveHost On
ProxyPass "/.well-known/" !
DocumentRoot "C:\SERVER\HTTP\APACHE\htdocs\shop.domena.tld"
ProxyPass "/" "http://localhost:8080/"
ProxyPassReverse "/" "http://localhost:8080/"

SSLEngine on
SSLCertificateFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\shop.domena.tld-crt.pem"
SSLCertificateKeyFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\shop.domena.tld-key.pem"
SSLCertificateChainFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\ca-shop.domena.tld-crt.pem"
<VirtualHost>

<VirtualHost *:443>
ServerAdmin "blogger@domena.tld"
ServerName "blog.domena.tld"
ProxyPreserveHost On
DocumentRoot "C:\HTTP\SERVER\htdocs\blog.domena.tld"
ProxyPass "/.well-known/" !
ProxyPass "/" "http://192.168.1.10:80/"
ProxyPassReverse "/" "http://192.168.1.10:80/"

SSLEngine on
SSLCertificateFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\blog.domena.tld-crt.pem"
SSLCertificateKeyFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\blog.domena.tld-key.pem"
SSLCertificateChainFile "C:\ProgramData\win-acme\httpsacme-v01.api.letsencrypt.org\ca-blog.domena.tld-crt.pem"
<VirtualHost>

Po vytvoření tohoto nastavení je nutné restartovat Apache server.

Kontrola posledních nastavení

Poslední věci ke kontrole jsou tyto:

  • Firewall na HTTP serveru musí propouštět port 80.
  • Firewall na HTTP serveru musí propouštět port 443.
  • DNS server domény musí být nastaven, aby posílal data z výše uvedených domén na veřejnou IP adresu HTTP počítače.
  • Firewall sítě (router) musí mít nastavený NAT nebo DMZ pro porty 80 a 443 tak aby směřoval na vnitřní IP adresu HTTP počítače.

Pokud je nastaveno vše správně, tak už funguje adresa https://domena.tld a další, které jsme konfigurovali.

Gratuluji

Máte hotovo a systém by se měl sám starat o obnovu certifikátů :). Takto nastavený server by mělo jít bez problémů rozšířit klidně i o další URL/domény. Pamatujte jen, nestačí zabezpečit jen hlavní doménu, musíte zabezpečit i všechny subdomény – Let´s Encrypt aktuálně neumí tzv. hvězdičkové, neboli WildCard certifikáty. Pokud bude zájem v komentářích, připravím i doplňující krátký článek o tom, jak vynutit přehození z HTTP na HTTPS přímo na proxy serveru.

One Response to Zabezpečujeme HTTP provoz na našich serverech